OLD | NEW |
(Empty) | |
| 1 /* |
| 2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. |
| 3 * |
| 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 |
| 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ |
| 10 |
| 11 #include "webrtc/modules/audio_coding/neteq/tools/rtc_event_log_source.h" |
| 12 |
| 13 #include <assert.h> |
| 14 #include <string.h> |
| 15 #include <iostream> |
| 16 #include <limits> |
| 17 |
| 18 #include "webrtc/base/checks.h" |
| 19 #include "webrtc/modules/audio_coding/neteq/tools/packet.h" |
| 20 #include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h" |
| 21 #include "webrtc/video/rtc_event_log.h" |
| 22 |
| 23 // Files generated at build-time by the protobuf compiler. |
| 24 #ifdef WEBRTC_ANDROID_PLATFORM_BUILD |
| 25 #include "external/webrtc/webrtc/video/rtc_event_log.pb.h" |
| 26 #else |
| 27 #include "webrtc/video/rtc_event_log.pb.h" |
| 28 #endif |
| 29 |
| 30 namespace webrtc { |
| 31 namespace test { |
| 32 |
| 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::DebugEvent* GetAudioOutputEvent(const rtclog::Event& event) { |
| 51 if (!event.has_type() || event.type() != rtclog::Event::DEBUG_EVENT) |
| 52 return nullptr; |
| 53 if (!event.has_timestamp_us() || !event.has_debug_event()) |
| 54 return nullptr; |
| 55 const rtclog::DebugEvent& debug_event = event.debug_event(); |
| 56 if (!debug_event.has_type() || |
| 57 debug_event.type() != rtclog::DebugEvent::AUDIO_PLAYOUT) |
| 58 return nullptr; |
| 59 return &debug_event; |
| 60 } |
| 61 |
| 62 } // namespace |
| 63 |
| 64 RtcEventLogSource* RtcEventLogSource::Create(const std::string& file_name) { |
| 65 RtcEventLogSource* source = new RtcEventLogSource(); |
| 66 CHECK(source->OpenFile(file_name)); |
| 67 return source; |
| 68 } |
| 69 |
| 70 RtcEventLogSource::~RtcEventLogSource() {} |
| 71 |
| 72 bool RtcEventLogSource::RegisterRtpHeaderExtension(RTPExtensionType type, |
| 73 uint8_t id) { |
| 74 CHECK(parser_.get()); |
| 75 return parser_->RegisterRtpHeaderExtension(type, id); |
| 76 } |
| 77 |
| 78 Packet* RtcEventLogSource::NextPacket() { |
| 79 while (rtp_packet_index_ < event_log_->stream_size()) { |
| 80 const rtclog::Event& event = event_log_->stream(rtp_packet_index_); |
| 81 const rtclog::RtpPacket* rtp_packet = GetRtpPacket(event); |
| 82 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 } |
| 104 return nullptr; |
| 105 } |
| 106 |
| 107 int64_t RtcEventLogSource::NextAudioOutputEventMs() { |
| 108 while (audio_output_index_ < event_log_->stream_size()) { |
| 109 const rtclog::Event& event = event_log_->stream(audio_output_index_); |
| 110 const rtclog::DebugEvent* debug_event = GetAudioOutputEvent(event); |
| 111 audio_output_index_++; |
| 112 if (debug_event) |
| 113 return event.timestamp_us() / 1000; |
| 114 } |
| 115 return std::numeric_limits<int64_t>::max(); |
| 116 } |
| 117 |
| 118 RtcEventLogSource::RtcEventLogSource() |
| 119 : PacketSource(), parser_(RtpHeaderParser::Create()) {} |
| 120 |
| 121 bool RtcEventLogSource::OpenFile(const std::string& file_name) { |
| 122 event_log_.reset(new rtclog::EventStream()); |
| 123 return RtcEventLog::ParseRtcEventLog(file_name, event_log_.get()); |
| 124 } |
| 125 |
| 126 } // namespace test |
| 127 } // namespace webrtc |
OLD | NEW |