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;
|
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)) {
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
@ -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) {
|
||||||
|
|||||||
@ -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();
|
||||||
|
|||||||
Reference in New Issue
Block a user