diff options
author | Henrik Kjellander <kjellander@google.com> | 2015-11-18 22:00:21 +0100 |
---|---|---|
committer | Henrik Kjellander <kjellander@google.com> | 2015-11-18 21:00:33 +0000 |
commit | 2557b86e7648ffebc5781df9f093ca5a84efc219 (patch) | |
tree | 9735669a2b265c5f2e65fbe15de13e8981d180ea /webrtc/modules/video_coding/test/vcm_payload_sink_factory.cc | |
parent | 4dd7a653b5011495f4c805461bad33405c1fb1b8 (diff) | |
download | webrtc-2557b86e7648ffebc5781df9f093ca5a84efc219.tar.gz |
modules/video_coding refactorings
The main purpose was the interface-> include rename, but other files
were also moved, eliminating the "main" dir.
To avoid breaking downstream, the "interface" directories were copied
into a new "video_coding/include" dir. The old headers got pragma
warnings added about deprecation (a very short deprecation since I plan
to remove them as soon downstream is updated).
Other files also moved:
video_coding/main/source -> video_coding
video_coding/main/test -> video_coding/test
BUG=webrtc:5095
TESTED=Passing compile-trybots with --clobber flag:
git cl try --clobber --bot=win_compile_rel --bot=linux_compile_rel --bot=android_compile_rel --bot=mac_compile_rel --bot=ios_rel --bot=linux_gn_rel --bot=win_x64_gn_rel --bot=mac_x64_gn_rel --bot=android_gn_rel -m tryserver.webrtc
R=stefan@webrtc.org, tommi@webrtc.org
Review URL: https://codereview.webrtc.org/1417283007 .
Cr-Commit-Position: refs/heads/master@{#10694}
Diffstat (limited to 'webrtc/modules/video_coding/test/vcm_payload_sink_factory.cc')
-rw-r--r-- | webrtc/modules/video_coding/test/vcm_payload_sink_factory.cc | 210 |
1 files changed, 210 insertions, 0 deletions
diff --git a/webrtc/modules/video_coding/test/vcm_payload_sink_factory.cc b/webrtc/modules/video_coding/test/vcm_payload_sink_factory.cc new file mode 100644 index 0000000000..26a0d019bf --- /dev/null +++ b/webrtc/modules/video_coding/test/vcm_payload_sink_factory.cc @@ -0,0 +1,210 @@ +/* + * Copyright (c) 2013 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 "webrtc/modules/video_coding/test/vcm_payload_sink_factory.h" + +#include <assert.h> + +#include <algorithm> + +#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h" +#include "webrtc/modules/video_coding/test/test_util.h" +#include "webrtc/system_wrappers/include/clock.h" +#include "webrtc/system_wrappers/include/critical_section_wrapper.h" + +namespace webrtc { +namespace rtpplayer { + +class VcmPayloadSinkFactory::VcmPayloadSink + : public PayloadSinkInterface, + public VCMPacketRequestCallback { + public: + VcmPayloadSink(VcmPayloadSinkFactory* factory, + RtpStreamInterface* stream, + rtc::scoped_ptr<VideoCodingModule>* vcm, + rtc::scoped_ptr<FileOutputFrameReceiver>* frame_receiver) + : factory_(factory), stream_(stream), vcm_(), frame_receiver_() { + assert(factory); + assert(stream); + assert(vcm); + assert(vcm->get()); + assert(frame_receiver); + assert(frame_receiver->get()); + vcm_.swap(*vcm); + frame_receiver_.swap(*frame_receiver); + vcm_->RegisterPacketRequestCallback(this); + vcm_->RegisterReceiveCallback(frame_receiver_.get()); + } + + virtual ~VcmPayloadSink() { + factory_->Remove(this); + } + + // PayloadSinkInterface + int32_t OnReceivedPayloadData(const uint8_t* payload_data, + const size_t payload_size, + const WebRtcRTPHeader* rtp_header) override { + return vcm_->IncomingPacket(payload_data, payload_size, *rtp_header); + } + + bool OnRecoveredPacket(const uint8_t* packet, size_t packet_length) override { + // We currently don't handle FEC. + return true; + } + + // VCMPacketRequestCallback + int32_t ResendPackets(const uint16_t* sequence_numbers, + uint16_t length) override { + stream_->ResendPackets(sequence_numbers, length); + return 0; + } + + int DecodeAndProcess(bool should_decode, bool decode_dual_frame) { + if (should_decode) { + if (vcm_->Decode() < 0) { + return -1; + } + } + return Process() ? 0 : -1; + } + + bool Process() { + if (vcm_->TimeUntilNextProcess() <= 0) { + if (vcm_->Process() < 0) { + return false; + } + } + return true; + } + + bool Decode() { + vcm_->Decode(10000); + return true; + } + + private: + VcmPayloadSinkFactory* factory_; + RtpStreamInterface* stream_; + rtc::scoped_ptr<VideoCodingModule> vcm_; + rtc::scoped_ptr<FileOutputFrameReceiver> frame_receiver_; + + RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(VcmPayloadSink); +}; + +VcmPayloadSinkFactory::VcmPayloadSinkFactory( + const std::string& base_out_filename, + Clock* clock, + bool protection_enabled, + VCMVideoProtection protection_method, + int64_t rtt_ms, + uint32_t render_delay_ms, + uint32_t min_playout_delay_ms) + : base_out_filename_(base_out_filename), + clock_(clock), + protection_enabled_(protection_enabled), + protection_method_(protection_method), + rtt_ms_(rtt_ms), + render_delay_ms_(render_delay_ms), + min_playout_delay_ms_(min_playout_delay_ms), + null_event_factory_(new NullEventFactory()), + crit_sect_(CriticalSectionWrapper::CreateCriticalSection()), + sinks_() { + assert(clock); + assert(crit_sect_.get()); +} + +VcmPayloadSinkFactory::~VcmPayloadSinkFactory() { + assert(sinks_.empty()); +} + +PayloadSinkInterface* VcmPayloadSinkFactory::Create( + RtpStreamInterface* stream) { + assert(stream); + CriticalSectionScoped cs(crit_sect_.get()); + + rtc::scoped_ptr<VideoCodingModule> vcm( + VideoCodingModule::Create(clock_, null_event_factory_.get())); + if (vcm.get() == NULL) { + return NULL; + } + + const PayloadTypes& plt = stream->payload_types(); + for (PayloadTypesIterator it = plt.begin(); it != plt.end(); + ++it) { + if (it->codec_type() != kVideoCodecULPFEC && + it->codec_type() != kVideoCodecRED) { + VideoCodec codec; + if (VideoCodingModule::Codec(it->codec_type(), &codec) < 0) { + return NULL; + } + codec.plType = it->payload_type(); + if (vcm->RegisterReceiveCodec(&codec, 1) < 0) { + return NULL; + } + } + } + + vcm->SetChannelParameters(0, 0, rtt_ms_); + vcm->SetVideoProtection(protection_method_, protection_enabled_); + vcm->SetRenderDelay(render_delay_ms_); + vcm->SetMinimumPlayoutDelay(min_playout_delay_ms_); + vcm->SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack, 0); + + rtc::scoped_ptr<FileOutputFrameReceiver> frame_receiver( + new FileOutputFrameReceiver(base_out_filename_, stream->ssrc())); + rtc::scoped_ptr<VcmPayloadSink> sink( + new VcmPayloadSink(this, stream, &vcm, &frame_receiver)); + + sinks_.push_back(sink.get()); + return sink.release(); +} + +int VcmPayloadSinkFactory::DecodeAndProcessAll(bool decode_dual_frame) { + CriticalSectionScoped cs(crit_sect_.get()); + assert(clock_); + bool should_decode = (clock_->TimeInMilliseconds() % 5) == 0; + for (Sinks::iterator it = sinks_.begin(); it != sinks_.end(); ++it) { + if ((*it)->DecodeAndProcess(should_decode, decode_dual_frame) < 0) { + return -1; + } + } + return 0; +} + +bool VcmPayloadSinkFactory::ProcessAll() { + CriticalSectionScoped cs(crit_sect_.get()); + for (Sinks::iterator it = sinks_.begin(); it != sinks_.end(); ++it) { + if (!(*it)->Process()) { + return false; + } + } + return true; +} + +bool VcmPayloadSinkFactory::DecodeAll() { + CriticalSectionScoped cs(crit_sect_.get()); + for (Sinks::iterator it = sinks_.begin(); it != sinks_.end(); ++it) { + if (!(*it)->Decode()) { + return false; + } + } + return true; +} + +void VcmPayloadSinkFactory::Remove(VcmPayloadSink* sink) { + assert(sink); + CriticalSectionScoped cs(crit_sect_.get()); + Sinks::iterator it = std::find(sinks_.begin(), sinks_.end(), sink); + assert(it != sinks_.end()); + sinks_.erase(it); +} + +} // namespace rtpplayer +} // namespace webrtc |