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:
@ -60,6 +60,12 @@ std::unique_ptr<NetEqInput::PacketData> NetEqPacketSourceInput::PopPacket() {
|
||||
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,
|
||||
const RtpHeaderExtensionMap& hdr_ext_map)
|
||||
: source_(RtpFileSource::Create(file_name)) {
|
||||
|
||||
@ -33,6 +33,7 @@ class NetEqPacketSourceInput : public NetEqInput {
|
||||
std::unique_ptr<PacketData> PopPacket() override;
|
||||
rtc::Optional<RTPHeader> NextHeader() const override;
|
||||
bool ended() const override { return !next_output_event_ms_; }
|
||||
void SelectSsrc(uint32_t);
|
||||
|
||||
protected:
|
||||
virtual PacketSource* source() = 0;
|
||||
|
||||
@ -226,56 +226,6 @@ rtc::Optional<int> CodecSampleRate(uint8_t payload_type) {
|
||||
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
|
||||
// the SSRC.
|
||||
class SsrcSwitchDetector : public NetEqPostInsertPacket {
|
||||
@ -386,14 +336,13 @@ int RunTest(int argc, char* argv[]) {
|
||||
if (strlen(FLAG_ssrc) > 0) {
|
||||
uint32_t ssrc;
|
||||
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.
|
||||
rtc::Optional<int> sample_rate_hz;
|
||||
std::set<std::pair<int, uint32_t>> discarded_pt_and_ssrc;
|
||||
while (input->NextHeader()) {
|
||||
rtc::Optional<RTPHeader> first_rtp_header = input->NextHeader();
|
||||
while (rtc::Optional<RTPHeader> first_rtp_header = input->NextHeader()) {
|
||||
RTC_DCHECK(first_rtp_header);
|
||||
sample_rate_hz = CodecSampleRate(first_rtp_header->payloadType);
|
||||
if (sample_rate_hz) {
|
||||
|
||||
@ -87,8 +87,10 @@ int64_t RtcEventLogSource::NextAudioOutputEventMs() {
|
||||
ParsedRtcEventLogNew::AUDIO_PLAYOUT_EVENT) {
|
||||
LoggedAudioPlayoutEvent playout_event =
|
||||
parsed_stream_.GetAudioPlayout(audio_output_index_);
|
||||
audio_output_index_++;
|
||||
return playout_event.timestamp_us / 1000;
|
||||
if (!(use_ssrc_filter_ && playout_event.ssrc != ssrc_)) {
|
||||
audio_output_index_++;
|
||||
return playout_event.timestamp_us / 1000;
|
||||
}
|
||||
}
|
||||
audio_output_index_++;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user