Filtering audio playout events with SSRC in NetEq RTP player.

Bug: webrtc:9259
Change-Id: I0b88aa6a7b49bd786637c7ffd9b94c92c608c841
Reviewed-on: https://webrtc-review.googlesource.com/76141
Reviewed-by: Henrik Lundin <henrik.lundin@webrtc.org>
Commit-Queue: Minyue Li <minyue@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#23414}
This commit is contained in:
Minyue Li
2018-05-11 16:49:38 +02:00
committed by Commit Bot
parent 92f83cec12
commit b563f3db59
4 changed files with 13 additions and 55 deletions

View File

@ -60,6 +60,12 @@ std::unique_ptr<NetEqInput::PacketData> NetEqPacketSourceInput::PopPacket() {
return packet_data; return packet_data;
} }
void NetEqPacketSourceInput::SelectSsrc(uint32_t ssrc) {
source()->SelectSsrc(ssrc);
if (packet_ && packet_->header().ssrc != ssrc)
LoadNextPacket();
}
NetEqRtpDumpInput::NetEqRtpDumpInput(const std::string& file_name, NetEqRtpDumpInput::NetEqRtpDumpInput(const std::string& file_name,
const RtpHeaderExtensionMap& hdr_ext_map) const RtpHeaderExtensionMap& hdr_ext_map)
: source_(RtpFileSource::Create(file_name)) { : source_(RtpFileSource::Create(file_name)) {

View File

@ -33,6 +33,7 @@ class NetEqPacketSourceInput : public NetEqInput {
std::unique_ptr<PacketData> PopPacket() override; std::unique_ptr<PacketData> PopPacket() override;
rtc::Optional<RTPHeader> NextHeader() const override; rtc::Optional<RTPHeader> NextHeader() const override;
bool ended() const override { return !next_output_event_ms_; } bool ended() const override { return !next_output_event_ms_; }
void SelectSsrc(uint32_t);
protected: protected:
virtual PacketSource* source() = 0; virtual PacketSource* source() = 0;

View File

@ -226,56 +226,6 @@ rtc::Optional<int> CodecSampleRate(uint8_t payload_type) {
return rtc::nullopt; return rtc::nullopt;
} }
// Class to let through only the packets with a given SSRC. Should be used as an
// outer layer on another NetEqInput object.
class FilterSsrcInput : public NetEqInput {
public:
FilterSsrcInput(std::unique_ptr<NetEqInput> source, uint32_t ssrc)
: source_(std::move(source)), ssrc_(ssrc) {
FindNextWithCorrectSsrc();
RTC_CHECK(source_->NextHeader()) << "Found no packet with SSRC = 0x"
<< std::hex << ssrc_;
}
// All methods but PopPacket() simply relay to the |source_| object.
rtc::Optional<int64_t> NextPacketTime() const override {
return source_->NextPacketTime();
}
rtc::Optional<int64_t> NextOutputEventTime() const override {
return source_->NextOutputEventTime();
}
// Returns the next packet, and throws away upcoming packets that do not match
// the desired SSRC.
std::unique_ptr<PacketData> PopPacket() override {
std::unique_ptr<PacketData> packet_to_return = source_->PopPacket();
RTC_DCHECK(!packet_to_return || packet_to_return->header.ssrc == ssrc_);
// Pre-fetch the next packet with correct SSRC. Hence, |source_| will always
// be have a valid packet (or empty if no more packets are available) when
// this method returns.
FindNextWithCorrectSsrc();
return packet_to_return;
}
void AdvanceOutputEvent() override { source_->AdvanceOutputEvent(); }
bool ended() const override { return source_->ended(); }
rtc::Optional<RTPHeader> NextHeader() const override {
return source_->NextHeader();
}
private:
void FindNextWithCorrectSsrc() {
while (source_->NextHeader() && source_->NextHeader()->ssrc != ssrc_) {
source_->PopPacket();
}
}
std::unique_ptr<NetEqInput> source_;
uint32_t ssrc_;
};
// A callback class which prints whenver the inserted packet stream changes // A callback class which prints whenver the inserted packet stream changes
// the SSRC. // the SSRC.
class SsrcSwitchDetector : public NetEqPostInsertPacket { class SsrcSwitchDetector : public NetEqPostInsertPacket {
@ -386,14 +336,13 @@ int RunTest(int argc, char* argv[]) {
if (strlen(FLAG_ssrc) > 0) { if (strlen(FLAG_ssrc) > 0) {
uint32_t ssrc; uint32_t ssrc;
RTC_CHECK(ParseSsrc(FLAG_ssrc, &ssrc)) << "Flag verification has failed."; RTC_CHECK(ParseSsrc(FLAG_ssrc, &ssrc)) << "Flag verification has failed.";
input.reset(new FilterSsrcInput(std::move(input), ssrc)); static_cast<NetEqPacketSourceInput*>(input.get())->SelectSsrc(ssrc);
} }
// Check the sample rate. // Check the sample rate.
rtc::Optional<int> sample_rate_hz; rtc::Optional<int> sample_rate_hz;
std::set<std::pair<int, uint32_t>> discarded_pt_and_ssrc; std::set<std::pair<int, uint32_t>> discarded_pt_and_ssrc;
while (input->NextHeader()) { while (rtc::Optional<RTPHeader> first_rtp_header = input->NextHeader()) {
rtc::Optional<RTPHeader> first_rtp_header = input->NextHeader();
RTC_DCHECK(first_rtp_header); RTC_DCHECK(first_rtp_header);
sample_rate_hz = CodecSampleRate(first_rtp_header->payloadType); sample_rate_hz = CodecSampleRate(first_rtp_header->payloadType);
if (sample_rate_hz) { if (sample_rate_hz) {

View File

@ -87,9 +87,11 @@ int64_t RtcEventLogSource::NextAudioOutputEventMs() {
ParsedRtcEventLogNew::AUDIO_PLAYOUT_EVENT) { ParsedRtcEventLogNew::AUDIO_PLAYOUT_EVENT) {
LoggedAudioPlayoutEvent playout_event = LoggedAudioPlayoutEvent playout_event =
parsed_stream_.GetAudioPlayout(audio_output_index_); parsed_stream_.GetAudioPlayout(audio_output_index_);
if (!(use_ssrc_filter_ && playout_event.ssrc != ssrc_)) {
audio_output_index_++; audio_output_index_++;
return playout_event.timestamp_us / 1000; return playout_event.timestamp_us / 1000;
} }
}
audio_output_index_++; audio_output_index_++;
} }
return std::numeric_limits<int64_t>::max(); return std::numeric_limits<int64_t>::max();