/* * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source * tree. An additional intellectual property rights grant can be found * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree. */ #include "modules/audio_coding/neteq/tools/rtc_event_log_source.h" #include #include #include #include #include "call/call.h" #include "modules/audio_coding/neteq/tools/packet.h" #include "modules/rtp_rtcp/include/rtp_header_parser.h" #include "rtc_base/checks.h" namespace webrtc { namespace test { RtcEventLogSource* RtcEventLogSource::Create(const std::string& file_name) { RtcEventLogSource* source = new RtcEventLogSource(); RTC_CHECK(source->OpenFile(file_name)); return source; } RtcEventLogSource::~RtcEventLogSource() {} bool RtcEventLogSource::RegisterRtpHeaderExtension(RTPExtensionType type, uint8_t id) { RTC_CHECK(parser_.get()); return parser_->RegisterRtpHeaderExtension(type, id); } std::unique_ptr RtcEventLogSource::NextPacket() { for (; rtp_packet_index_ < parsed_stream_.GetNumberOfEvents(); rtp_packet_index_++) { if (parsed_stream_.GetEventType(rtp_packet_index_) == ParsedRtcEventLog::RTP_EVENT) { PacketDirection direction; size_t header_length; size_t packet_length; uint64_t timestamp_us = parsed_stream_.GetTimestamp(rtp_packet_index_); parsed_stream_.GetRtpHeader(rtp_packet_index_, &direction, nullptr, &header_length, &packet_length); if (direction != kIncomingPacket) { continue; } uint8_t* packet_header = new uint8_t[header_length]; parsed_stream_.GetRtpHeader(rtp_packet_index_, nullptr, packet_header, nullptr, nullptr); std::unique_ptr packet( new Packet(packet_header, header_length, packet_length, static_cast(timestamp_us) / 1000, *parser_.get())); if (!packet->valid_header()) { std::cout << "Warning: Packet with index " << rtp_packet_index_ << " has an invalid header and will be ignored." << std::endl; continue; } if (parsed_stream_.GetMediaType(packet->header().ssrc, direction) != webrtc::ParsedRtcEventLog::MediaType::AUDIO) { continue; } // Check if the packet should not be filtered out. if (!filter_.test(packet->header().payloadType) && !(use_ssrc_filter_ && packet->header().ssrc != ssrc_)) { ++rtp_packet_index_; return packet; } } } return nullptr; } int64_t RtcEventLogSource::NextAudioOutputEventMs() { while (audio_output_index_ < parsed_stream_.GetNumberOfEvents()) { if (parsed_stream_.GetEventType(audio_output_index_) == ParsedRtcEventLog::AUDIO_PLAYOUT_EVENT) { uint64_t timestamp_us = parsed_stream_.GetTimestamp(audio_output_index_); // We call GetAudioPlayout only to check that the protobuf event is // well-formed. parsed_stream_.GetAudioPlayout(audio_output_index_, nullptr); audio_output_index_++; return timestamp_us / 1000; } audio_output_index_++; } return std::numeric_limits::max(); } RtcEventLogSource::RtcEventLogSource() : PacketSource(), parser_(RtpHeaderParser::Create()) {} bool RtcEventLogSource::OpenFile(const std::string& file_name) { return parsed_stream_.ParseFile(file_name); } } // namespace test } // namespace webrtc