OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
11 #include "webrtc/modules/audio_coding/neteq/tools/rtc_event_log_source.h" | 11 #include "webrtc/modules/audio_coding/neteq/tools/rtc_event_log_source.h" |
12 | 12 |
13 #include <assert.h> | 13 #include <assert.h> |
14 #include <string.h> | 14 #include <string.h> |
15 #include <iostream> | 15 #include <iostream> |
16 #include <limits> | 16 #include <limits> |
17 | 17 |
18 #include "webrtc/base/checks.h" | 18 #include "webrtc/base/checks.h" |
| 19 #include "webrtc/call.h" |
19 #include "webrtc/call/rtc_event_log.h" | 20 #include "webrtc/call/rtc_event_log.h" |
20 #include "webrtc/modules/audio_coding/neteq/tools/packet.h" | 21 #include "webrtc/modules/audio_coding/neteq/tools/packet.h" |
21 #include "webrtc/modules/rtp_rtcp/include/rtp_header_parser.h" | 22 #include "webrtc/modules/rtp_rtcp/include/rtp_header_parser.h" |
22 | 23 |
23 // Files generated at build-time by the protobuf compiler. | |
24 #ifdef WEBRTC_ANDROID_PLATFORM_BUILD | |
25 #include "external/webrtc/webrtc/call/rtc_event_log.pb.h" | |
26 #else | |
27 #include "webrtc/call/rtc_event_log.pb.h" | |
28 #endif | |
29 | 24 |
30 namespace webrtc { | 25 namespace webrtc { |
31 namespace test { | 26 namespace test { |
32 | 27 |
33 namespace { | |
34 | |
35 const rtclog::RtpPacket* GetRtpPacket(const rtclog::Event& event) { | |
36 if (!event.has_type() || event.type() != rtclog::Event::RTP_EVENT) | |
37 return nullptr; | |
38 if (!event.has_timestamp_us() || !event.has_rtp_packet()) | |
39 return nullptr; | |
40 const rtclog::RtpPacket& rtp_packet = event.rtp_packet(); | |
41 if (!rtp_packet.has_type() || rtp_packet.type() != rtclog::AUDIO || | |
42 !rtp_packet.has_incoming() || !rtp_packet.incoming() || | |
43 !rtp_packet.has_packet_length() || rtp_packet.packet_length() == 0 || | |
44 !rtp_packet.has_header() || rtp_packet.header().size() == 0 || | |
45 rtp_packet.packet_length() < rtp_packet.header().size()) | |
46 return nullptr; | |
47 return &rtp_packet; | |
48 } | |
49 | |
50 const rtclog::AudioPlayoutEvent* GetAudioPlayoutEvent( | |
51 const rtclog::Event& event) { | |
52 if (!event.has_type() || event.type() != rtclog::Event::AUDIO_PLAYOUT_EVENT) | |
53 return nullptr; | |
54 if (!event.has_timestamp_us() || !event.has_audio_playout_event()) | |
55 return nullptr; | |
56 const rtclog::AudioPlayoutEvent& playout_event = event.audio_playout_event(); | |
57 if (!playout_event.has_local_ssrc()) | |
58 return nullptr; | |
59 return &playout_event; | |
60 } | |
61 | |
62 } // namespace | |
63 | |
64 RtcEventLogSource* RtcEventLogSource::Create(const std::string& file_name) { | 28 RtcEventLogSource* RtcEventLogSource::Create(const std::string& file_name) { |
65 RtcEventLogSource* source = new RtcEventLogSource(); | 29 RtcEventLogSource* source = new RtcEventLogSource(); |
66 RTC_CHECK(source->OpenFile(file_name)); | 30 RTC_CHECK(source->OpenFile(file_name)); |
67 return source; | 31 return source; |
68 } | 32 } |
69 | 33 |
70 RtcEventLogSource::~RtcEventLogSource() {} | 34 RtcEventLogSource::~RtcEventLogSource() {} |
71 | 35 |
72 bool RtcEventLogSource::RegisterRtpHeaderExtension(RTPExtensionType type, | 36 bool RtcEventLogSource::RegisterRtpHeaderExtension(RTPExtensionType type, |
73 uint8_t id) { | 37 uint8_t id) { |
74 RTC_CHECK(parser_.get()); | 38 RTC_CHECK(parser_.get()); |
75 return parser_->RegisterRtpHeaderExtension(type, id); | 39 return parser_->RegisterRtpHeaderExtension(type, id); |
76 } | 40 } |
77 | 41 |
78 Packet* RtcEventLogSource::NextPacket() { | 42 Packet* RtcEventLogSource::NextPacket() { |
79 while (rtp_packet_index_ < event_log_->stream_size()) { | 43 while (rtp_packet_index_ < parsed_stream_.GetNumberOfEvents()) { |
80 const rtclog::Event& event = event_log_->stream(rtp_packet_index_); | 44 if (parsed_stream_.GetEventType(rtp_packet_index_) == |
81 const rtclog::RtpPacket* rtp_packet = GetRtpPacket(event); | 45 ParsedRtcEventLog::RTP_EVENT) { |
| 46 PacketDirection direction; |
| 47 MediaType media_type; |
| 48 size_t header_length; |
| 49 size_t packet_length; |
| 50 uint64_t timestamp_us = parsed_stream_.GetTimestamp(rtp_packet_index_); |
| 51 parsed_stream_.GetRtpHeader(rtp_packet_index_, &direction, &media_type, |
| 52 nullptr, &header_length, &packet_length); |
| 53 if (direction == kIncomingPacket && media_type == MediaType::AUDIO) { |
| 54 uint8_t* packet_header = new uint8_t[header_length]; |
| 55 parsed_stream_.GetRtpHeader(rtp_packet_index_, nullptr, nullptr, |
| 56 packet_header, nullptr, nullptr); |
| 57 Packet* packet = new Packet(packet_header, header_length, packet_length, |
| 58 static_cast<double>(timestamp_us) / 1000, |
| 59 *parser_.get()); |
| 60 if (packet->valid_header()) { |
| 61 // Check if the packet should not be filtered out. |
| 62 if (!filter_.test(packet->header().payloadType) && |
| 63 !(use_ssrc_filter_ && packet->header().ssrc != ssrc_)) { |
| 64 rtp_packet_index_++; |
| 65 return packet; |
| 66 } |
| 67 } else { |
| 68 std::cout << "Warning: Packet with index " << rtp_packet_index_ |
| 69 << " has an invalid header and will be ignored." |
| 70 << std::endl; |
| 71 } |
| 72 // The packet has either an invalid header or needs to be filtered out, |
| 73 // so it can be deleted. |
| 74 delete packet; |
| 75 } |
| 76 } |
82 rtp_packet_index_++; | 77 rtp_packet_index_++; |
83 if (rtp_packet) { | |
84 uint8_t* packet_header = new uint8_t[rtp_packet->header().size()]; | |
85 memcpy(packet_header, rtp_packet->header().data(), | |
86 rtp_packet->header().size()); | |
87 Packet* packet = new Packet(packet_header, rtp_packet->header().size(), | |
88 rtp_packet->packet_length(), | |
89 event.timestamp_us() / 1000, *parser_.get()); | |
90 if (packet->valid_header()) { | |
91 // Check if the packet should not be filtered out. | |
92 if (!filter_.test(packet->header().payloadType) && | |
93 !(use_ssrc_filter_ && packet->header().ssrc != ssrc_)) | |
94 return packet; | |
95 } else { | |
96 std::cout << "Warning: Packet with index " << (rtp_packet_index_ - 1) | |
97 << " has an invalid header and will be ignored." << std::endl; | |
98 } | |
99 // The packet has either an invalid header or needs to be filtered out, so | |
100 // it can be deleted. | |
101 delete packet; | |
102 } | |
103 } | 78 } |
104 return nullptr; | 79 return nullptr; |
105 } | 80 } |
106 | 81 |
107 int64_t RtcEventLogSource::NextAudioOutputEventMs() { | 82 int64_t RtcEventLogSource::NextAudioOutputEventMs() { |
108 while (audio_output_index_ < event_log_->stream_size()) { | 83 while (audio_output_index_ < parsed_stream_.GetNumberOfEvents()) { |
109 const rtclog::Event& event = event_log_->stream(audio_output_index_); | 84 if (parsed_stream_.GetEventType(audio_output_index_) == |
110 const rtclog::AudioPlayoutEvent* playout_event = | 85 ParsedRtcEventLog::AUDIO_PLAYOUT_EVENT) { |
111 GetAudioPlayoutEvent(event); | 86 uint64_t timestamp_us = parsed_stream_.GetTimestamp(audio_output_index_); |
| 87 // We call GetAudioPlayout only to check that the protobuf event is |
| 88 // well-formed. |
| 89 parsed_stream_.GetAudioPlayout(audio_output_index_, nullptr); |
| 90 audio_output_index_++; |
| 91 return timestamp_us / 1000; |
| 92 } |
112 audio_output_index_++; | 93 audio_output_index_++; |
113 if (playout_event) | |
114 return event.timestamp_us() / 1000; | |
115 } | 94 } |
116 return std::numeric_limits<int64_t>::max(); | 95 return std::numeric_limits<int64_t>::max(); |
117 } | 96 } |
118 | 97 |
119 RtcEventLogSource::RtcEventLogSource() | 98 RtcEventLogSource::RtcEventLogSource() |
120 : PacketSource(), parser_(RtpHeaderParser::Create()) {} | 99 : PacketSource(), parser_(RtpHeaderParser::Create()) {} |
121 | 100 |
122 bool RtcEventLogSource::OpenFile(const std::string& file_name) { | 101 bool RtcEventLogSource::OpenFile(const std::string& file_name) { |
123 event_log_.reset(new rtclog::EventStream()); | 102 return parsed_stream_.ParseFile(file_name); |
124 return RtcEventLog::ParseRtcEventLog(file_name, event_log_.get()); | |
125 } | 103 } |
126 | 104 |
127 } // namespace test | 105 } // namespace test |
128 } // namespace webrtc | 106 } // namespace webrtc |
OLD | NEW |