OLD | NEW |
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_deserializer.h" | 5 #include "media/cast/logging/log_deserializer.h" |
6 | 6 |
7 #include <map> | 7 #include <map> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/big_endian.h" | 10 #include "base/big_endian.h" |
| 11 #include "base/memory/scoped_ptr.h" |
11 #include "third_party/zlib/zlib.h" | 12 #include "third_party/zlib/zlib.h" |
12 | 13 |
13 using media::cast::FrameEventMap; | 14 using media::cast::FrameEventMap; |
14 using media::cast::PacketEventMap; | 15 using media::cast::PacketEventMap; |
15 using media::cast::RtpTimestamp; | 16 using media::cast::RtpTimestamp; |
16 using media::cast::proto::AggregatedFrameEvent; | 17 using media::cast::proto::AggregatedFrameEvent; |
17 using media::cast::proto::AggregatedPacketEvent; | 18 using media::cast::proto::AggregatedPacketEvent; |
| 19 using media::cast::proto::BasePacketEvent; |
18 using media::cast::proto::LogMetadata; | 20 using media::cast::proto::LogMetadata; |
19 | 21 |
20 namespace { | 22 namespace { |
21 | 23 |
22 // Use 60MB of temp buffer to hold uncompressed data if |compress| is true. | 24 // Use 60MB of temp buffer to hold uncompressed data if |compress| is true. |
23 // This is double the size of temp buffer used during compression (30MB) | 25 // This is double the size of temp buffer used during compression (30MB) |
24 // since the there are two streams in the blob. | 26 // since the there are two streams in the blob. |
25 // Keep in sync with media/cast/logging/log_serializer.cc. | 27 // Keep in sync with media/cast/logging/log_serializer.cc. |
26 const int kMaxUncompressedBytes = 60 * 1000 * 1000; | 28 const int kMaxUncompressedBytes = 60 * 1000 * 1000; |
27 | 29 |
| 30 void MergePacketEvent(const AggregatedPacketEvent& from, |
| 31 linked_ptr<AggregatedPacketEvent> to) { |
| 32 for (int i = 0; i < from.base_packet_event_size(); i++) { |
| 33 const BasePacketEvent& from_base_event = from.base_packet_event(i); |
| 34 bool merged = false; |
| 35 for (int j = 0; j < to->base_packet_event_size(); j++) { |
| 36 BasePacketEvent* to_base_event = to->mutable_base_packet_event(i); |
| 37 if (from_base_event.packet_id() == to_base_event->packet_id()) { |
| 38 to_base_event->MergeFrom(from_base_event); |
| 39 merged = true; |
| 40 break; |
| 41 } |
| 42 } |
| 43 if (!merged) { |
| 44 BasePacketEvent* to_base_event = to->add_base_packet_event(); |
| 45 to_base_event->CopyFrom(from_base_event); |
| 46 } |
| 47 } |
| 48 } |
| 49 |
| 50 void MergeFrameEvent(const AggregatedFrameEvent& from, |
| 51 linked_ptr<AggregatedFrameEvent> to) { |
| 52 to->mutable_event_type()->MergeFrom(from.event_type()); |
| 53 to->mutable_event_timestamp_ms()->MergeFrom(from.event_timestamp_ms()); |
| 54 if (!to->has_encoded_frame_size()) |
| 55 to->set_encoded_frame_size(from.encoded_frame_size()); |
| 56 if (!to->has_delay_millis()) |
| 57 to->set_delay_millis(from.delay_millis()); |
| 58 if (!to->has_key_frame()) |
| 59 to->set_key_frame(from.key_frame()); |
| 60 } |
| 61 |
28 bool PopulateDeserializedLog(base::BigEndianReader* reader, | 62 bool PopulateDeserializedLog(base::BigEndianReader* reader, |
29 media::cast::DeserializedLog* log) { | 63 media::cast::DeserializedLog* log) { |
30 FrameEventMap frame_event_map; | 64 FrameEventMap frame_event_map; |
31 PacketEventMap packet_event_map; | 65 PacketEventMap packet_event_map; |
32 | 66 |
33 int num_frame_events = log->metadata.num_frame_events(); | 67 int num_frame_events = log->metadata.num_frame_events(); |
34 RtpTimestamp relative_rtp_timestamp = 0; | 68 RtpTimestamp relative_rtp_timestamp = 0; |
35 uint16 proto_size = 0; | 69 uint16 proto_size = 0; |
36 for (int i = 0; i < num_frame_events; i++) { | 70 for (int i = 0; i < num_frame_events; i++) { |
37 if (!reader->ReadU16(&proto_size)) | 71 if (!reader->ReadU16(&proto_size)) |
38 return false; | 72 return false; |
39 | 73 |
40 linked_ptr<AggregatedFrameEvent> frame_event(new AggregatedFrameEvent); | 74 linked_ptr<AggregatedFrameEvent> frame_event(new AggregatedFrameEvent); |
41 if (!frame_event->ParseFromArray(reader->ptr(), proto_size)) | 75 if (!frame_event->ParseFromArray(reader->ptr(), proto_size)) |
42 return false; | 76 return false; |
43 if (!reader->Skip(proto_size)) | 77 if (!reader->Skip(proto_size)) |
44 return false; | 78 return false; |
45 | 79 |
46 // During serialization the RTP timestamp in proto is relative to previous | 80 // During serialization the RTP timestamp in proto is relative to previous |
47 // frame. | 81 // frame. |
48 // Adjust RTP timestamp back to value relative to first RTP timestamp. | 82 // Adjust RTP timestamp back to value relative to first RTP timestamp. |
49 frame_event->set_relative_rtp_timestamp( | 83 frame_event->set_relative_rtp_timestamp( |
50 frame_event->relative_rtp_timestamp() + relative_rtp_timestamp); | 84 frame_event->relative_rtp_timestamp() + relative_rtp_timestamp); |
51 relative_rtp_timestamp = frame_event->relative_rtp_timestamp(); | 85 relative_rtp_timestamp = frame_event->relative_rtp_timestamp(); |
52 | 86 |
53 std::pair<FrameEventMap::iterator, bool> result = frame_event_map.insert( | 87 FrameEventMap::iterator it = frame_event_map.find( |
54 std::make_pair(frame_event->relative_rtp_timestamp(), frame_event)); | 88 frame_event->relative_rtp_timestamp()); |
55 if (!result.second) { | 89 if (it == frame_event_map.end()) { |
56 VLOG(1) << "Duplicate frame event entry detected: " | 90 frame_event_map.insert( |
57 << frame_event->relative_rtp_timestamp(); | 91 std::make_pair(frame_event->relative_rtp_timestamp(), frame_event)); |
58 return false; | 92 } else { |
| 93 // Events for the same frame might have been split into more than one |
| 94 // proto. Merge them. |
| 95 MergeFrameEvent(*frame_event, it->second); |
59 } | 96 } |
60 } | 97 } |
61 | 98 |
62 log->frame_events.swap(frame_event_map); | 99 log->frame_events.swap(frame_event_map); |
63 | 100 |
64 int num_packet_events = log->metadata.num_packet_events(); | 101 int num_packet_events = log->metadata.num_packet_events(); |
65 relative_rtp_timestamp = 0; | 102 relative_rtp_timestamp = 0; |
66 for (int i = 0; i < num_packet_events; i++) { | 103 for (int i = 0; i < num_packet_events; i++) { |
67 if (!reader->ReadU16(&proto_size)) | 104 if (!reader->ReadU16(&proto_size)) |
68 return false; | 105 return false; |
69 | 106 |
70 linked_ptr<AggregatedPacketEvent> packet_event(new AggregatedPacketEvent); | 107 linked_ptr<AggregatedPacketEvent> packet_event(new AggregatedPacketEvent); |
71 if (!packet_event->ParseFromArray(reader->ptr(), proto_size)) | 108 if (!packet_event->ParseFromArray(reader->ptr(), proto_size)) |
72 return false; | 109 return false; |
73 if (!reader->Skip(proto_size)) | 110 if (!reader->Skip(proto_size)) |
74 return false; | 111 return false; |
75 | 112 |
76 packet_event->set_relative_rtp_timestamp( | 113 packet_event->set_relative_rtp_timestamp( |
77 packet_event->relative_rtp_timestamp() + relative_rtp_timestamp); | 114 packet_event->relative_rtp_timestamp() + relative_rtp_timestamp); |
78 relative_rtp_timestamp = packet_event->relative_rtp_timestamp(); | 115 relative_rtp_timestamp = packet_event->relative_rtp_timestamp(); |
79 | 116 |
80 std::pair<PacketEventMap::iterator, bool> result = packet_event_map.insert( | 117 PacketEventMap::iterator it = packet_event_map.find( |
81 std::make_pair(packet_event->relative_rtp_timestamp(), packet_event)); | 118 packet_event->relative_rtp_timestamp()); |
82 if (!result.second) { | 119 if (it == packet_event_map.end()) { |
83 VLOG(1) << "Duplicate packet event entry detected: " | 120 packet_event_map.insert( |
84 << packet_event->relative_rtp_timestamp(); | 121 std::make_pair(packet_event->relative_rtp_timestamp(), packet_event)); |
85 return false; | 122 } else { |
| 123 // Events for the same frame might have been split into more than one |
| 124 // proto. Merge them. |
| 125 MergePacketEvent(*packet_event, it->second); |
86 } | 126 } |
87 } | 127 } |
88 | 128 |
89 log->packet_events.swap(packet_event_map); | 129 log->packet_events.swap(packet_event_map); |
90 | 130 |
91 return true; | 131 return true; |
92 } | 132 } |
93 | 133 |
94 bool DoDeserializeEvents(const char* data, | 134 bool DoDeserializeEvents(const char* data, |
95 int data_bytes, | 135 int data_bytes, |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
196 } else { | 236 } else { |
197 return DoDeserializeEvents(data, data_bytes, audio_log, video_log); | 237 return DoDeserializeEvents(data, data_bytes, audio_log, video_log); |
198 } | 238 } |
199 } | 239 } |
200 | 240 |
201 DeserializedLog::DeserializedLog() {} | 241 DeserializedLog::DeserializedLog() {} |
202 DeserializedLog::~DeserializedLog() {} | 242 DeserializedLog::~DeserializedLog() {} |
203 | 243 |
204 } // namespace cast | 244 } // namespace cast |
205 } // namespace media | 245 } // namespace media |
OLD | NEW |