Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(210)

Side by Side Diff: media/cast/logging/log_serializer.cc

Issue 189583004: Cast: Implement log compression and (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « media/cast/logging/log_serializer.h ('k') | media/cast/logging/serialize_deserialize_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4 //
5 #include "media/cast/logging/log_serializer.h" 5 // The serialization format is as follows:
6 6 // 8-bit integer describing |is_audio|.
7 #include "base/big_endian.h" 7 // 32-bit integer describing |first_rtp_timestamp|.
8 8 // 32-bit integer describing number of frame events.
9 namespace media {
10 namespace cast {
11
12 LogSerializer::LogSerializer(const int max_serialized_bytes)
13 : index_so_far_(0), max_serialized_bytes_(max_serialized_bytes) {
14 DCHECK_GT(max_serialized_bytes_, 0);
15 }
16
17 LogSerializer::~LogSerializer() {}
18
19 // The format is as follows:
20 // 16-bit integer describing the folowing LogMetadata proto size in bytes.
21 // The LogMetadata proto.
22 // (The following repeated for number of frame events): 9 // (The following repeated for number of frame events):
23 // 16-bit integer describing the following AggregatedFrameEvent proto size 10 // 16-bit integer describing the following AggregatedFrameEvent proto size
24 // in bytes. 11 // in bytes.
25 // The AggregatedFrameEvent proto. 12 // The AggregatedFrameEvent proto.
26 // 32-bit integer describing number of packet events. 13 // 32-bit integer describing number of packet events.
27 // (The following repeated for number of packet events): 14 // (The following repeated for number of packet events):
28 // 16-bit integer describing the following AggregatedPacketEvent proto 15 // 16-bit integer describing the following AggregatedPacketEvent proto
29 // size in bytes. 16 // size in bytes.
30 // The AggregatedPacketEvent proto. 17 // The AggregatedPacketEvent proto.
31 bool LogSerializer::SerializeEventsForStream(
32 const media::cast::proto::LogMetadata& metadata,
33 const FrameEventMap& frame_events,
34 const PacketEventMap& packet_events) {
35 if (!serialized_log_so_far_) {
36 serialized_log_so_far_.reset(new std::string(max_serialized_bytes_, 0));
37 }
38 18
39 int remaining_space = serialized_log_so_far_->size() - index_so_far_; 19 #include "media/cast/logging/log_serializer.h"
40 if (remaining_space <= 0)
41 return false;
42 20
43 base::BigEndianWriter writer(&(*serialized_log_so_far_)[index_so_far_], 21 #include "base/big_endian.h"
44 remaining_space); 22 #include "third_party/zlib/zlib.h"
23
24 namespace media {
25 namespace cast {
26
27 namespace {
28
29 using media::cast::proto::AggregatedFrameEvent;
30 using media::cast::proto::AggregatedPacketEvent;
31 using media::cast::proto::LogMetadata;
32
33 // Use 30MB of temp buffer to hold uncompressed data if |compress| is true.
34 const int kMaxUncompressedBytes = 30 * 1000 * 1000;
35
36 bool DoSerializeEvents(const LogMetadata& metadata,
37 const FrameEventMap& frame_events,
38 const PacketEventMap& packet_events,
39 const int max_output_bytes,
40 char* output,
41 int* output_bytes) {
42 base::BigEndianWriter writer(output, max_output_bytes);
45 43
46 int proto_size = metadata.ByteSize(); 44 int proto_size = metadata.ByteSize();
47 if (!writer.WriteU16(proto_size)) 45 if (!writer.WriteU16(proto_size))
48 return false; 46 return false;
49 if (!metadata.SerializeToArray(writer.ptr(), writer.remaining())) 47 if (!metadata.SerializeToArray(writer.ptr(), writer.remaining()))
50 return false; 48 return false;
51 if (!writer.Skip(proto_size)) 49 if (!writer.Skip(proto_size))
52 return false; 50 return false;
53 51
54 for (media::cast::FrameEventMap::const_iterator it = frame_events.begin(); 52 for (media::cast::FrameEventMap::const_iterator it = frame_events.begin();
55 it != frame_events.end(); 53 it != frame_events.end();
56 ++it) { 54 ++it) {
57 proto_size = it->second->ByteSize(); 55 proto_size = it->second->ByteSize();
56
58 // Write size of the proto, then write the proto. 57 // Write size of the proto, then write the proto.
59 if (!writer.WriteU16(proto_size)) 58 if (!writer.WriteU16(proto_size))
60 return false; 59 return false;
61 if (!it->second->SerializeToArray(writer.ptr(), writer.remaining())) 60 if (!it->second->SerializeToArray(writer.ptr(), writer.remaining()))
62 return false; 61 return false;
63 if (!writer.Skip(proto_size)) 62 if (!writer.Skip(proto_size))
64 return false; 63 return false;
65 } 64 }
66 65
67 // Write packet events. 66 // Write packet events.
68 for (media::cast::PacketEventMap::const_iterator it = packet_events.begin(); 67 for (media::cast::PacketEventMap::const_iterator it = packet_events.begin();
69 it != packet_events.end(); 68 it != packet_events.end();
70 ++it) { 69 ++it) {
71 proto_size = it->second->ByteSize(); 70 proto_size = it->second->ByteSize();
71
72 // Write size of the proto, then write the proto. 72 // Write size of the proto, then write the proto.
73 if (!writer.WriteU16(proto_size)) 73 if (!writer.WriteU16(proto_size))
74 return false; 74 return false;
75 if (!it->second->SerializeToArray(writer.ptr(), writer.remaining())) 75 if (!it->second->SerializeToArray(writer.ptr(), writer.remaining()))
76 return false; 76 return false;
77 if (!writer.Skip(proto_size)) 77 if (!writer.Skip(proto_size))
78 return false; 78 return false;
79 } 79 }
80 80
81 index_so_far_ = serialized_log_so_far_->size() - writer.remaining(); 81 *output_bytes = max_output_bytes - writer.remaining();
82 return true; 82 return true;
83 } 83 }
84 84
85 scoped_ptr<std::string> LogSerializer::GetSerializedLogAndReset() { 85 bool Compress(char* uncompressed_buffer,
86 serialized_log_so_far_->resize(index_so_far_); 86 int uncompressed_bytes,
87 index_so_far_ = 0; 87 int max_output_bytes,
88 return serialized_log_so_far_.Pass(); 88 char* output,
89 int* output_bytes) {
90 z_stream stream = {0};
91 int result = deflateInit2(&stream,
92 Z_DEFAULT_COMPRESSION,
93 Z_DEFLATED,
94 // 16 is added to produce a gzip header + trailer.
95 MAX_WBITS + 16,
96 8, // memLevel = 8 is default.
97 Z_DEFAULT_STRATEGY);
98 DCHECK_EQ(Z_OK, result);
99
100 stream.next_in = reinterpret_cast<uint8*>(uncompressed_buffer);
101 stream.avail_in = uncompressed_bytes;
102 stream.next_out = reinterpret_cast<uint8*>(output);
103 stream.avail_out = max_output_bytes;
104
105 // Do a one-shot compression. This will return Z_STREAM_END only if |output|
106 // is large enough to hold all compressed data.
107 result = deflate(&stream, Z_FINISH);
108 bool success = (result == Z_STREAM_END);
109
110 if (!success)
111 DVLOG(2) << "deflate() failed. Result: " << result;
112
113 result = deflateEnd(&stream);
114 DCHECK(result == Z_OK || result == Z_DATA_ERROR);
115
116 if (success)
117 *output_bytes = max_output_bytes - stream.avail_out;
118
119 return success;
89 } 120 }
90 121
91 int LogSerializer::GetSerializedLength() const { return index_so_far_; } 122 } // namespace
123
124 bool SerializeEvents(const LogMetadata& log_metadata,
125 const FrameEventMap& frame_events,
126 const PacketEventMap& packet_events,
127 bool compress,
128 int max_output_bytes,
129 char* output,
130 int* output_bytes) {
131 DCHECK_GT(max_output_bytes, 0);
132 DCHECK(output);
133 DCHECK(output_bytes);
134
135 if (compress) {
136 // Allocate a reasonably large temp buffer to hold uncompressed data.
137 scoped_ptr<char[]> uncompressed_buffer(new char[kMaxUncompressedBytes]);
138 int uncompressed_bytes;
139 bool success = DoSerializeEvents(log_metadata,
140 frame_events,
141 packet_events,
142 kMaxUncompressedBytes,
143 uncompressed_buffer.get(),
144 &uncompressed_bytes);
145 if (!success)
146 return false;
147 return Compress(uncompressed_buffer.get(),
148 uncompressed_bytes,
149 max_output_bytes,
150 output,
151 output_bytes);
152 } else {
153 return DoSerializeEvents(log_metadata,
154 frame_events,
155 packet_events,
156 max_output_bytes,
157 output,
158 output_bytes);
159 }
160 }
92 161
93 } // namespace cast 162 } // namespace cast
94 } // namespace media 163 } // namespace media
OLDNEW
« no previous file with comments | « media/cast/logging/log_serializer.h ('k') | media/cast/logging/serialize_deserialize_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698