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

Side by Side Diff: media/cast/test/log_encoder.cc

Issue 161593002: Cast: an app to generate log data and do (de)serailization and (de)compression. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@encoding-event-subscriber
Patch Set: Rewrote the encode/decode logic without using internal protobuf APIs, so don't need to add protobuf… Created 6 years, 10 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/test/fake_single_thread_task_runner.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include <algorithm>
6 #include <cstdio>
7 #include <iostream>
8 #include <string>
9 #include <sstream>
10
11 #include "base/rand_util.h"
12 #include "base/time/default_tick_clock.h"
13 #include "media/cast/cast_defines.h"
14 #include "media/cast/logging/logging_defines.h"
15 #include "media/cast/logging/logging_raw.h"
16 #include "media/cast/logging/proto/raw_events.pb.h"
17 #include "media/cast/test/fake_single_thread_task_runner.h"
18 #include "media/cast/logging/encoding_event_subscriber.h"
19 #include "net/base/big_endian.h"
20 #include "third_party/zlib/zlib.h"
21
22 using media::cast::CastLoggingEvent;
23 using media::cast::EncodingEventSubscriber;
24 using media::cast::FrameEvent;
25 using media::cast::FrameEventMap;
26 using media::cast::GenericEventMap;
27 using media::cast::LoggingRaw;
28 using media::cast::PacketEventMap;
29 using media::cast::proto::AggregatedFrameEvent;
30 using media::cast::proto::AggregatedGenericEvent;
31 using media::cast::proto::AggregatedPacketEvent;
32 using media::cast::proto::BasePacketEvent;
33 using media::cast::test::FakeSingleThreadTaskRunner;
34
35 const int kFps = 30;
36 const int kNumSeconds = 60 * 30;
37
38 const int kNumVideoFrames = kFps * kNumSeconds;
39 const CastLoggingEvent kVideoFrameEvents[] = {
40 media::cast::kVideoFrameCaptured,
41 media::cast::kVideoFrameReceived,
42 media::cast::kVideoFrameSentToEncoder,
43 media::cast::kVideoFrameEncoded,
44 media::cast::kVideoFrameDecoded,
45 media::cast::kVideoRenderDelay};
46
47 // Average number of packets per video frame.
48 const int kNumPacketPerVideoFrame = 10;
49
50 const CastLoggingEvent kVideoPacketEvents[] = {
51 media::cast::kPacketSentToPacer,
52 media::cast::kPacketSentToNetwork,
53 media::cast::kVideoPacketReceived};
54
55 const CastLoggingEvent kOtherPacketEvents[] = {
56 media::cast::kPacketRetransmitted,
57 media::cast::kDuplicatePacketReceived};
58
59 // 15 MB.
60 const int kCompressedMaxSize = 10 * 1000 * 1000;
61 // 100 MB.
62 const int kDecompressedMaxSize = 100 * 1000 * 1000;
63
64 // TODO(imcheng): All these should return bool indicating success.
65 void WriteTo(const FrameEventMap& frame_events,
66 const PacketEventMap& packet_events,
67 uint8* out, int out_buf_size, int* out_size);
68 void Compress(uint8* in, int in_buf_size,
69 uint8* out, int out_buf_size, int* out_size);
70 void Decompress(uint8* in, int in_buf_size,
71 uint8* out, int out_buf_size, int* out_size);
72 void ReadFrom(const uint8* in, const int in_size);
73
74 int main(int argc, char** argv) {
75 EncodingEventSubscriber subscriber;
76 LoggingRaw logging_raw;
77
78 logging_raw.AddSubscriber(&subscriber);
79
80 base::DefaultTickClock clock;
81 base::TimeTicks base_now(clock.NowTicks());
82 base_now -= base::TimeDelta::FromSeconds(5400);
83 printf("Time now: %ld\n", base_now.ToInternalValue());
84
85 printf("\n===========\n");
86 printf("Inserting frame events\n");
87 base::TimeTicks now(base_now);
88 for (int i = 0; i < kNumVideoFrames; ++i) {
89 now += base::TimeDelta::FromMilliseconds(33);
90 base::TimeTicks base_now2(now);
91 uint32 rtp_timestamp = media::cast::GetVideoRtpTimestamp(now);
92 if (i < 5) {
93 printf("Inserting first 5 event with RTP timestamp %u\n", rtp_timestamp);
94 }
95 if (kNumVideoFrames - i < 5) {
96 printf("Inserting last 5 event with RTP timestamp %u\n", rtp_timestamp);
97 }
98 // Insert frame events for that frame.
99 for (uint32 event_index = 0; event_index < arraysize(kVideoFrameEvents);
100 ++event_index) {
101 now += base::TimeDelta::FromMilliseconds(5);
102 CastLoggingEvent type = kVideoFrameEvents[event_index];
103 if (type == media::cast::kVideoFrameEncoded) {
104 int size = base::RandInt(32768, 65536);
105 logging_raw.InsertFrameEventWithSize(now, type, rtp_timestamp, i, size);
106 } else if (type == media::cast::kVideoRenderDelay) {
107 base::TimeDelta delay(
108 base::TimeDelta::FromMilliseconds(base::RandInt(0, 100)));
109 logging_raw.InsertFrameEventWithDelay(now, type, rtp_timestamp, i,
110 delay);
111 } else {
112 logging_raw.InsertFrameEvent(now, type, rtp_timestamp, i);
113 }
114 }
115 now = base_now2;
116 }
117
118 printf("Inserting packet events\n");
119 now = base_now;
120 for (int i = 0; i < kNumVideoFrames; ++i) {
121 now += base::TimeDelta::FromMilliseconds(33);
122 base::TimeTicks base_now2(now);
123 uint32 rtp_timestamp = media::cast::GetVideoRtpTimestamp(now);
124
125 // Insert packet events for that frame.
126 for (int packet_id = 0; packet_id < kNumPacketPerVideoFrame; ++packet_id) {
127 int size = base::RandInt(2048, 4096);
128 for (uint32 event_index = 0; event_index < arraysize(kVideoPacketEvents);
129 ++event_index) {
130 now += base::TimeDelta::FromMilliseconds(1);
131 CastLoggingEvent type = kVideoPacketEvents[event_index];
132 logging_raw.InsertPacketEvent(now, type, rtp_timestamp, i, packet_id,
133 kNumPacketPerVideoFrame - 1, size);
134 }
135
136 // Randomly insert additional packet events.
137 int rand = base::RandInt(0, 99);
138 if (rand < 2) {
139 now += base::TimeDelta::FromMilliseconds(1);
140 logging_raw.InsertPacketEvent(now, media::cast::kPacketRetransmitted,
141 rtp_timestamp, i, packet_id,
142 kNumPacketPerVideoFrame - 1, size);
143 }
144 rand = base::RandInt(0, 99);
145 if (rand < 2) {
146 now += base::TimeDelta::FromMilliseconds(1);
147 logging_raw.InsertPacketEvent(
148 now, media::cast::kDuplicatePacketReceived, rtp_timestamp, i,
149 packet_id, kNumPacketPerVideoFrame - 1, size);
150 }
151 }
152
153 now = base_now2;
154 }
155
156 FrameEventMap frame_events;
157 subscriber.GetFrameEventsAndReset(&frame_events);
158
159 PacketEventMap packet_events;
160 subscriber.GetPacketEventsAndReset(&packet_events);
161
162 printf("Frame events map size: %lu\n", frame_events.size());
163 printf("Packet events map size: %lu\n", packet_events.size());
164
165 logging_raw.RemoveSubscriber(&subscriber);
166
167 printf("\n===========\n");
168 printf("Performing serialization\n");
169
170 scoped_ptr<uint8[]> serialized_buf(new uint8[kDecompressedMaxSize]);
171 int serialized_size;
172 WriteTo(frame_events, packet_events, serialized_buf.get(),
173 kDecompressedMaxSize, &serialized_size);
174 printf("Serialized size: %d\n", serialized_size);
175
176 printf("\n===========\n");
177 printf("Performing compression\n");
178 scoped_ptr<uint8[]> compressed_buf(new uint8[kCompressedMaxSize]);
179 int compressed_size;
180 Compress(serialized_buf.get(), serialized_size, compressed_buf.get(),
181 kCompressedMaxSize, &compressed_size);
182 printf("Compressed size: %d\n", compressed_size);
183 serialized_buf.reset();
184
185 printf("\n===========\n");
186 printf("Performing decompression\n");
187 scoped_ptr<uint8[]> decompressed_buf(new uint8[kDecompressedMaxSize]);
188
189 int decompressed_size;
190 Decompress(compressed_buf.get(), compressed_size,
191 decompressed_buf.get(), kDecompressedMaxSize, &decompressed_size);
192 printf("Decompressed size: %d\n", decompressed_size);
193 compressed_buf.reset();
194
195 printf("\n===========\n");
196 printf("Performing deserialization\n");
197 ReadFrom(decompressed_buf.get(), decompressed_size);
198
199 printf("Done\n");
200 return 0;
201 }
202
203 void WriteTo(const FrameEventMap& frame_events,
204 const PacketEventMap& packet_events,
205 uint8* out, int out_buf_size, int* out_size) {
206
207 // int index = 0;
208 net::BigEndianWriter writer(out, out_buf_size);
209
210 // Frame events - write size first, then write entries
211 int frame_events_size = frame_events.size();
212 // memcpy(&out[index], &frame_events_size, sizeof(frame_events_size));
213 // index += sizeof(frame_events_size);
214 bool success;
215 success = writer.WriteU32(frame_events_size);
216 // XXX: instead of DCHECKs, just return false.
217 DCHECK(success);
218 int i = 0;
219 for (FrameEventMap::const_iterator it = frame_events.begin();
220 it != frame_events.end(); ++it) {
221 int proto_size = it->second->ByteSize();
222
223 if (frame_events_size - i < 5) {
224 printf("Serializing last 5 frame events, rtp ts: %u, %u\n", it->first, it- >second->rtp_timestamp());
225 }
226 i++;
227 // Write size of the proto, then write the proto
228 // memcpy(&out[index], &proto_size, sizeof(proto_size));
229 // index += sizeof(proto_size);
230 success = writer.WriteU16(proto_size);
231 DCHECK(success);
232
233 // bool success = it->second->SerializeToArray(&out[index], out_size - index );
234 // DCHECK(success);
235 // index += proto_size;
236 success = it->second->SerializeToArray(writer.ptr(), writer.remaining());
237 DCHECK(success);
238 success = writer.Skip(proto_size);
239 DCHECK(success);
240 }
241
242 int frame_event_serialized_size = (char*)writer.ptr() - (char*)out;
243 printf("Encoded frame events size: %d\n", frame_event_serialized_size);
244
245 // Write packet events
246 int packet_event_size = packet_events.size();
247 // memcpy(&out[index], &packet_event_size, sizeof(packet_event_size));
248 // index += sizeof(packet_event_size);
249 success = writer.WriteU32(packet_event_size);
250 DCHECK(success);
251 i = 0;
252 for (PacketEventMap::const_iterator it = packet_events.begin();
253 it != packet_events.end(); ++it) {
254 int proto_size = it->second->ByteSize();
255 if (packet_event_size - i < 5) {
256 printf("Last 5 encoded packet size: %d, rtp timestamp: %u, %u\n", proto_si ze, it->first, it->second->rtp_timestamp());
257 }
258 i++;
259 // Write size of the proto, then write the proto
260 // memcpy(&out[index], &proto_size, sizeof(proto_size));
261 // index += sizeof(proto_size);
262 success = writer.WriteU16(proto_size);
263 DCHECK(success);
264
265 // bool success = it->second->SerializeToArray(&out[index], out_size - index );
266 // index += proto_size;
267 // DCHECK(success);
268 success = it->second->SerializeToArray(writer.ptr(), writer.remaining());
269 DCHECK(success);
270 success = writer.Skip(proto_size);
271 DCHECK(success);
272 }
273
274 int packet_event_serialized_size =
275 out_buf_size - writer.remaining() - frame_event_serialized_size;
276 printf("Encoded packet events buff count: %d\n",
277 packet_event_serialized_size);
278
279 *out_size = out_buf_size - writer.remaining();
280 }
281
282 void Compress(uint8* in, int in_buf_size,
283 uint8* out, int out_buf_size, int* out_size) {
284 z_stream stream = {0};
285 int result = deflateInit2(&stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED,
286 // 16 is added to produce a gzip header + trailer.
287 MAX_WBITS + 16, 8, // memLevel = 8 is default.
288 Z_DEFAULT_STRATEGY);
289 DCHECK_EQ(Z_OK, result);
290 stream.next_in = in;
291 stream.avail_in = in_buf_size;
292 stream.next_out = out;
293 stream.avail_out = out_buf_size;
294 result = deflate(&stream, Z_FINISH);
295 DCHECK_EQ(Z_STREAM_END, result)
296 << ", maybe the output buffer isn't large enough?";
297 result = deflateEnd(&stream);
298 DCHECK_EQ(Z_OK, result);
299
300 *out_size = out_buf_size - stream.avail_out;
301 }
302
303 void Decompress(uint8* in, int in_buf_size,
304 uint8* out, int out_buf_size, int* out_size) {
305 z_stream stream = {0};
306 // 16 is added to read in gzip format.
307 int result = inflateInit2(&stream, MAX_WBITS + 16);
308 DCHECK_EQ(Z_OK, result);
309 stream.next_in = in;
310 stream.avail_in = in_buf_size;
311 stream.next_out = out;
312 stream.avail_out = out_buf_size;
313 result = inflate(&stream, Z_FINISH);
314 DCHECK_EQ(Z_STREAM_END, result)
315 << ", maybe the output buffer isn't large enough?";
316 result = inflateEnd(&stream);
317 DCHECK_EQ(Z_OK, result);
318
319 // Trim to size.
320 *out_size = out_buf_size - stream.avail_out;
321 }
322
323 void ReadFrom(const uint8* in, const int in_size) {
324 //ArrayInputStream array_input_stream(&decompressed_string[0],
325 // decompressed_string.size());
326 //CodedInputStream in(&array_input_stream);
327
328 // Reserve about 20MB.
329 const int out_size = 20 * 1000 * 1000;
330 scoped_ptr<uint8[]> out(new uint8[out_size]);
331 bool success;
332
333 //success = in.GetDirectBufferPointer(
334 // reinterpret_cast<const void**>(&in_buffer), &buffer_size);
335 //DCHECK(success);
336
337 net::BigEndianReader reader(in, in_size);
338 uint32 num_frame_events;
339 //in_buffer = CodedInputStream::ReadLittleEndian32FromArray(in_buffer,
340 // &num_frame_events) ;
341 success = reader.ReadU32(&num_frame_events);
342 DCHECK(success);
343
344 printf("Read %u frame events\n", num_frame_events);
345
346 for (uint32 i = 0; i < num_frame_events; i++) {
347 uint16 proto_size = 0u;
348 //in_buffer =
349 // CodedInputStream::ReadLittleEndian32FromArray(in_buffer, &proto_size);
350 success = reader.ReadU16(&proto_size);
351
352 AggregatedFrameEvent frame_event;
353 success = frame_event.ParseFromArray(reader.ptr(), proto_size);
354 DCHECK(success) << ", " << i;
355 reader.Skip(proto_size);
356 //in_buffer += proto_size;
357 if (i > num_frame_events - 5) {
358 printf("Last 5 event:\n");
359 printf("RTP timestamp: %u\n",
360 static_cast<uint32>(frame_event.rtp_timestamp()));
361 printf("Event type size: %d\n", frame_event.event_type_size());
362 printf("Event timestamp micros size: %d\n",
363 frame_event.event_timestamp_micros_size());
364 printf("Event encoded frame size: %d\n",
365 frame_event.encoded_frame_size());
366 printf("Event delay millis: %d\n", frame_event.delay_millis());
367 }
368 }
369
370 uint32 num_packet_events = 0u;
371 success = reader.ReadU32(&num_packet_events);
372 DCHECK(success);
373 //in_buffer = CodedInputStream::ReadLittleEndian32FromArray(in_buffer,
374 // &num_packet_events );
375 printf("Read %u packet events\n", num_packet_events);
376
377 for (uint32 i = 0; i < num_packet_events; i++) {
378 uint16 proto_size;
379 //in_buffer =
380 // CodedInputStream::ReadLittleEndian32FromArray(in_buffer, &proto_size);
381 success = reader.ReadU16(&proto_size);
382 DCHECK(success);
383
384 AggregatedPacketEvent packet_event;
385 success = packet_event.ParseFromArray(reader.ptr(), proto_size);
386 DCHECK(success) << ", " << i;
387 reader.Skip(proto_size);
388
389 // in_buffer += proto_size;
390 if (i > num_packet_events - 5) {
391 printf("Last 5 event:\n");
392 printf("RTP timestamp: %u\n", packet_event.rtp_timestamp());
393 int base_size = packet_event.base_packet_event_size();
394 printf("Base packet event size: %d\n", base_size);
395 int base_packet_index = base::RandInt(0, base_size - 1);
396 printf("Getting base packet event %d\n", base_packet_index);
397 BasePacketEvent base_packet_event =
398 packet_event.base_packet_event(base_packet_index);
399 printf("Base Event %d timestamp packet id: %d\n", base_packet_index,
400 base_packet_event.packet_id());
401 printf("Base Event %d event type size: %d\n", base_packet_index,
402 base_packet_event.event_type_size());
403 }
404 }
405 }
OLDNEW
« no previous file with comments | « media/cast/test/fake_single_thread_task_runner.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698