Deprecate VideoDecoder::Reset() and remove calls.

Removes calls to decoder reset and instead drops delta frames and
requests keyframes until one arrives.

BUG=webrtc:5475
R=stefan@webrtc.org
TBR=mflodman@webrtc.org

Review URL: https://codereview.webrtc.org/1647163002 .

Cr-Commit-Position: refs/heads/master@{#11460}
This commit is contained in:
Peter Boström 2016-02-02 15:40:04 +01:00
parent ce23bee697
commit ed3277bf14
25 changed files with 33 additions and 151 deletions

View File

@ -100,8 +100,6 @@ class MediaCodecVideoDecoder : public webrtc::VideoDecoder,
int32_t Release() override;
int32_t Reset() override;
bool PrefersLateDecoding() const override { return true; }
// rtc::MessageHandler implementation.
@ -805,14 +803,6 @@ int32_t MediaCodecVideoDecoder::RegisterDecodeCompleteCallback(
return WEBRTC_VIDEO_CODEC_OK;
}
int32_t MediaCodecVideoDecoder::Reset() {
ALOGD << "DecoderReset";
if (!inited_) {
return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
}
return InitDecode(&codec_, 1);
}
void MediaCodecVideoDecoder::OnMessage(rtc::Message* msg) {
JNIEnv* jni = AttachCurrentThreadIfNeeded();
ScopedLocalRefFrame local_ref_frame(jni);

View File

@ -84,8 +84,6 @@ class FakeWebRtcVideoDecoder : public webrtc::VideoDecoder {
virtual int32_t Release() { return WEBRTC_VIDEO_CODEC_OK; }
virtual int32_t Reset() { return WEBRTC_VIDEO_CODEC_OK; }
int GetNumFramesReceived() const {
return num_frames_received_;
}

View File

@ -114,14 +114,8 @@ int32_t RTPReceiverVideo::InvokeOnInitializeDecoder(
int8_t payload_type,
const char payload_name[RTP_PAYLOAD_NAME_SIZE],
const PayloadUnion& specific_payload) const {
// For video we just go with default values.
if (-1 ==
callback->OnInitializeDecoder(payload_type, payload_name,
kVideoPayloadTypeFrequency, 1, 0)) {
LOG(LS_ERROR) << "Failed to created decoder for payload type: "
<< static_cast<int>(payload_type);
return -1;
}
// TODO(pbos): Remove as soon as audio can handle a changing payload type
// without this callback.
return 0;
}

View File

@ -529,6 +529,8 @@ VCMGenericDecoder* VCMCodecDataBase::CreateAndInitDecoder(
const VCMEncodedFrame& frame,
VideoCodec* new_codec) const {
uint8_t payload_type = frame.PayloadType();
LOG(LS_INFO) << "Initializing decoder with payload type '"
<< static_cast<int>(payload_type) << "'.";
assert(new_codec);
const VCMDecoderMapItem* decoder_item = FindDecoderItem(payload_type);
if (!decoder_item) {

View File

@ -147,10 +147,6 @@ I420Decoder::~I420Decoder() {
Release();
}
int I420Decoder::Reset() {
return WEBRTC_VIDEO_CODEC_OK;
}
int I420Decoder::InitDecode(const VideoCodec* codecSettings,
int /*numberOfCores */) {
if (codecSettings == NULL) {

View File

@ -131,12 +131,6 @@ class I420Decoder : public VideoDecoder {
// <0 - Error
int Release() override;
// Reset decoder state and prepare for a new call.
//
// Return value : WEBRTC_VIDEO_CODEC_OK.
// <0 - Error
int Reset() override;
private:
static const uint8_t* ExtractHeader(const uint8_t* buffer,
uint16_t* width,

View File

@ -73,7 +73,6 @@ class MockVideoDecoder : public VideoDecoder {
MOCK_METHOD1(RegisterDecodeCompleteCallback,
int32_t(DecodedImageCallback* callback));
MOCK_METHOD0(Release, int32_t());
MOCK_METHOD0(Reset, int32_t());
MOCK_METHOD0(Copy, VideoDecoder*());
};

View File

@ -266,22 +266,4 @@ TEST_F(TestVp8Impl, MAYBE_DecodeWithACompleteKeyFrame) {
EXPECT_GT(I420PSNR(&input_frame_, &decoded_frame_), 36);
}
TEST_F(TestVp8Impl, TestReset) {
SetUpEncodeDecode();
EXPECT_EQ(0, encoder_->Encode(input_frame_, NULL, NULL));
EXPECT_EQ(0, decoder_->Decode(encoded_frame_, false, NULL));
size_t length = CalcBufferSize(kI420, kWidth, kHeight);
rtc::scoped_ptr<uint8_t[]> first_frame_buffer(new uint8_t[length]);
ExtractBuffer(decoded_frame_, length, first_frame_buffer.get());
EXPECT_EQ(0, decoder_->Reset());
EXPECT_EQ(0, decoder_->Decode(encoded_frame_, false, NULL));
rtc::scoped_ptr<uint8_t[]> second_frame_buffer(new uint8_t[length]);
ExtractBuffer(decoded_frame_, length, second_frame_buffer.get());
EXPECT_EQ(
0, memcmp(second_frame_buffer.get(), first_frame_buffer.get(), length));
}
} // namespace webrtc

View File

@ -1085,15 +1085,6 @@ VP8DecoderImpl::~VP8DecoderImpl() {
Release();
}
int VP8DecoderImpl::Reset() {
if (!inited_) {
return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
}
InitDecode(&codec_, 1);
propagation_cnt_ = -1;
return WEBRTC_VIDEO_CODEC_OK;
}
int VP8DecoderImpl::InitDecode(const VideoCodec* inst, int number_of_cores) {
int ret_val = Release();
if (ret_val < 0) {

View File

@ -136,7 +136,6 @@ class VP8DecoderImpl : public VP8Decoder {
int RegisterDecodeCompleteCallback(DecodedImageCallback* callback) override;
int Release() override;
int Reset() override;
const char* ImplementationName() const override;

View File

@ -840,14 +840,6 @@ VP9DecoderImpl::~VP9DecoderImpl() {
}
}
int VP9DecoderImpl::Reset() {
if (!inited_) {
return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
}
InitDecode(&codec_, 1);
return WEBRTC_VIDEO_CODEC_OK;
}
int VP9DecoderImpl::InitDecode(const VideoCodec* inst, int number_of_cores) {
if (inst == NULL) {
return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;

View File

@ -149,8 +149,6 @@ class VP9DecoderImpl : public VP9Decoder {
int Release() override;
int Reset() override;
const char* ImplementationName() const override;
private:

View File

@ -171,10 +171,6 @@ int32_t VCMGenericDecoder::Release() {
return _decoder->Release();
}
int32_t VCMGenericDecoder::Reset() {
return _decoder->Reset();
}
int32_t VCMGenericDecoder::RegisterDecodeCompleteCallback(
VCMDecodedFrameCallback* callback) {
_callback = callback;

View File

@ -83,11 +83,6 @@ class VCMGenericDecoder {
*/
int32_t Release();
/**
* Reset the decoder state, prepare for a new call
*/
int32_t Reset();
/**
* Set decode callback. Deregistering while decoding is illegal.
*/

View File

@ -72,7 +72,6 @@ class MockVideoDecoder : public VideoDecoder {
MOCK_METHOD1(RegisterDecodeCompleteCallback,
int32_t(DecodedImageCallback* callback));
MOCK_METHOD0(Release, int32_t());
MOCK_METHOD0(Reset, int32_t());
MOCK_METHOD0(Copy, VideoDecoder*());
};

View File

@ -384,12 +384,6 @@ class VideoCodingModule : public Module {
virtual int RegisterRenderBufferSizeCallback(
VCMRenderBufferSizeCallback* callback) = 0;
// Reset the decoder state to the initial state.
//
// Return value : VCM_OK, on success.
// < 0, on error.
virtual int32_t ResetDecoder() = 0;
// API to get the codec which is currently used for decoding by the module.
//
// Input:

View File

@ -219,8 +219,6 @@ class VideoCodingModuleImpl : public VideoCodingModule {
return receiver_.Decode(maxWaitTimeMs);
}
int32_t ResetDecoder() override { return receiver_.ResetDecoder(); }
int32_t ReceiveCodec(VideoCodec* currentReceiveCodec) const override {
return receiver_.ReceiveCodec(currentReceiveCodec);
}

View File

@ -149,7 +149,6 @@ class VideoReceiver {
int RegisterRenderBufferSizeCallback(VCMRenderBufferSizeCallback* callback);
int32_t Decode(uint16_t maxWaitTimeMs);
int32_t ResetDecoder();
int32_t ReceiveCodec(VideoCodec* currentReceiveCodec) const;
VideoCodecType ReceiveCodec() const;
@ -208,10 +207,12 @@ class VideoReceiver {
#endif
VCMFrameBuffer _frameFromFile;
bool _scheduleKeyRequest GUARDED_BY(process_crit_sect_);
bool drop_frames_until_keyframe_ GUARDED_BY(process_crit_sect_);
size_t max_nack_list_size_ GUARDED_BY(process_crit_sect_);
EncodedImageCallback* pre_decode_image_callback_ GUARDED_BY(_receiveCritSect);
VCMCodecDataBase _codecDataBase GUARDED_BY(_receiveCritSect);
EncodedImageCallback* pre_decode_image_callback_ GUARDED_BY(_receiveCritSect);
VCMProcessTimer _receiveStatsTimer;
VCMProcessTimer _retransmissionTimer;
VCMProcessTimer _keyRequestTimer;

View File

@ -43,9 +43,10 @@ VideoReceiver::VideoReceiver(Clock* clock, EventFactory* event_factory)
#endif
_frameFromFile(),
_scheduleKeyRequest(false),
drop_frames_until_keyframe_(false),
max_nack_list_size_(0),
pre_decode_image_callback_(NULL),
_codecDataBase(nullptr, nullptr),
pre_decode_image_callback_(NULL),
_receiveStatsTimer(1000, clock_),
_retransmissionTimer(10, clock_),
_keyRequestTimer(500, clock_) {
@ -282,6 +283,19 @@ int32_t VideoReceiver::Decode(uint16_t maxWaitTimeMs) {
if (!frame)
return VCM_FRAME_NOT_READY;
{
CriticalSectionScoped cs(process_crit_sect_.get());
if (drop_frames_until_keyframe_) {
// Still getting delta frames, schedule another keyframe request as if
// decode failed.
if (frame->FrameType() != kVideoFrameKey) {
_scheduleKeyRequest = true;
_receiver.ReleaseFrame(frame);
return VCM_FRAME_NOT_READY;
}
drop_frames_until_keyframe_ = false;
}
}
CriticalSectionScoped cs(_receiveCritSect);
// If this frame was too late, we should adjust the delay accordingly
@ -380,25 +394,6 @@ int32_t VideoReceiver::Decode(const VCMEncodedFrame& frame) {
return ret;
}
// Reset the decoder state
int32_t VideoReceiver::ResetDecoder() {
bool reset_key_request = false;
{
CriticalSectionScoped cs(_receiveCritSect);
if (_decoder != NULL) {
_receiver.Reset();
_timing.Reset();
reset_key_request = true;
_decoder->Reset();
}
}
if (reset_key_request) {
CriticalSectionScoped cs(process_crit_sect_.get());
_scheduleKeyRequest = false;
}
return VCM_OK;
}
// Register possible receive codecs, can be called multiple times
int32_t VideoReceiver::RegisterReceiveCodec(const VideoCodec* receiveCodec,
int32_t numberOfCores,
@ -449,8 +444,11 @@ int32_t VideoReceiver::IncomingPacket(const uint8_t* incomingPayload,
// TODO(holmer): Investigate if this somehow should use the key frame
// request scheduling to throttle the requests.
if (ret == VCM_FLUSH_INDICATOR) {
{
CriticalSectionScoped process_cs(process_crit_sect_.get());
drop_frames_until_keyframe_ = true;
}
RequestKeyFrame();
ResetDecoder();
} else if (ret < 0) {
return ret;
}

View File

@ -54,10 +54,6 @@ int32_t FakeDecoder::Release() {
return WEBRTC_VIDEO_CODEC_OK;
}
int32_t FakeDecoder::Reset() {
return WEBRTC_VIDEO_CODEC_OK;
}
const char* FakeDecoder::kImplementationName = "fake_decoder";
const char* FakeDecoder::ImplementationName() const {
return kImplementationName;

View File

@ -37,7 +37,6 @@ class FakeDecoder : public VideoDecoder {
DecodedImageCallback* callback) override;
int32_t Release() override;
int32_t Reset() override;
const char* ImplementationName() const override;

View File

@ -128,12 +128,6 @@ int32_t VideoDecoderSoftwareFallbackWrapper::Release() {
return decoder_->Release();
}
int32_t VideoDecoderSoftwareFallbackWrapper::Reset() {
if (fallback_decoder_)
fallback_decoder_->Reset();
return decoder_->Reset();
}
bool VideoDecoderSoftwareFallbackWrapper::PrefersLateDecoding() const {
if (fallback_decoder_)
return fallback_decoder_->PrefersLateDecoding();

View File

@ -49,11 +49,6 @@ class VideoDecoderSoftwareFallbackWrapperTest : public ::testing::Test {
return WEBRTC_VIDEO_CODEC_OK;
}
int32_t Reset() override {
++reset_count_;
return WEBRTC_VIDEO_CODEC_OK;
}
const char* ImplementationName() const override {
return "fake-decoder";
}
@ -134,20 +129,6 @@ TEST_F(VideoDecoderSoftwareFallbackWrapperTest, ForwardsReleaseCall) {
EXPECT_EQ(2, fake_decoder_.release_count_);
}
TEST_F(VideoDecoderSoftwareFallbackWrapperTest, ForwardsResetCall) {
VideoCodec codec = {};
fallback_wrapper_.InitDecode(&codec, 2);
fallback_wrapper_.Reset();
EXPECT_EQ(1, fake_decoder_.reset_count_);
fake_decoder_.decode_return_code_ = WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE;
EncodedImage encoded_image;
fallback_wrapper_.Decode(encoded_image, false, nullptr, nullptr, -1);
fallback_wrapper_.Reset();
EXPECT_EQ(2, fake_decoder_.reset_count_)
<< "Reset not forwarded during fallback.";
}
// TODO(pbos): Fake a VP8 frame well enough to actually receive a callback from
// the software decoder.
TEST_F(VideoDecoderSoftwareFallbackWrapperTest,

View File

@ -914,10 +914,8 @@ void ViEChannel::StartReceive() {
void ViEChannel::StopReceive() {
vie_receiver_.StopReceive();
if (!sender_) {
if (!sender_)
StopDecodeThread();
vcm_->ResetDecoder();
}
}
int32_t ViEChannel::ReceivedRTPPacket(const void* rtp_packet,
@ -1166,18 +1164,15 @@ void ViEChannel::RegisterPreDecodeImageCallback(
vcm_->RegisterPreDecodeImageCallback(pre_decode_callback);
}
// TODO(pbos): Remove OnInitializeDecoder which is called from the RTP module,
// any decoder resetting should be handled internally within the VCM.
// TODO(pbos): Remove as soon as audio can handle a changing payload type
// without this callback.
int32_t ViEChannel::OnInitializeDecoder(
const int8_t payload_type,
const char payload_name[RTP_PAYLOAD_NAME_SIZE],
const int frequency,
const size_t channels,
const uint32_t rate) {
LOG(LS_INFO) << "OnInitializeDecoder " << static_cast<int>(payload_type)
<< " " << payload_name;
vcm_->ResetDecoder();
RTC_NOTREACHED();
return 0;
}

View File

@ -73,7 +73,9 @@ class VideoDecoder {
DecodedImageCallback* callback) = 0;
virtual int32_t Release() = 0;
virtual int32_t Reset() = 0;
// TODO(pbos): Remove, this is no longer called. A no-op implementation is
// added here to permit removal elsewhere.
virtual int32_t Reset() { return 0; }
// Returns true if the decoder prefer to decode frames late.
// That is, it can not decode infinite number of frames before the decoded
@ -104,7 +106,6 @@ class VideoDecoderSoftwareFallbackWrapper : public webrtc::VideoDecoder {
DecodedImageCallback* callback) override;
int32_t Release() override;
int32_t Reset() override;
bool PrefersLateDecoding() const override;
const char* ImplementationName() const override;