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 Release() override;
int32_t Reset() override;
bool PrefersLateDecoding() const override { return true; } bool PrefersLateDecoding() const override { return true; }
// rtc::MessageHandler implementation. // rtc::MessageHandler implementation.
@ -805,14 +803,6 @@ int32_t MediaCodecVideoDecoder::RegisterDecodeCompleteCallback(
return WEBRTC_VIDEO_CODEC_OK; 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) { void MediaCodecVideoDecoder::OnMessage(rtc::Message* msg) {
JNIEnv* jni = AttachCurrentThreadIfNeeded(); JNIEnv* jni = AttachCurrentThreadIfNeeded();
ScopedLocalRefFrame local_ref_frame(jni); 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 Release() { return WEBRTC_VIDEO_CODEC_OK; }
virtual int32_t Reset() { return WEBRTC_VIDEO_CODEC_OK; }
int GetNumFramesReceived() const { int GetNumFramesReceived() const {
return num_frames_received_; return num_frames_received_;
} }

View File

@ -114,14 +114,8 @@ int32_t RTPReceiverVideo::InvokeOnInitializeDecoder(
int8_t payload_type, int8_t payload_type,
const char payload_name[RTP_PAYLOAD_NAME_SIZE], const char payload_name[RTP_PAYLOAD_NAME_SIZE],
const PayloadUnion& specific_payload) const { const PayloadUnion& specific_payload) const {
// For video we just go with default values. // TODO(pbos): Remove as soon as audio can handle a changing payload type
if (-1 == // without this callback.
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;
}
return 0; return 0;
} }

View File

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

View File

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

View File

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

View File

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

View File

@ -266,22 +266,4 @@ TEST_F(TestVp8Impl, MAYBE_DecodeWithACompleteKeyFrame) {
EXPECT_GT(I420PSNR(&input_frame_, &decoded_frame_), 36); 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 } // namespace webrtc

View File

@ -1085,15 +1085,6 @@ VP8DecoderImpl::~VP8DecoderImpl() {
Release(); 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 VP8DecoderImpl::InitDecode(const VideoCodec* inst, int number_of_cores) {
int ret_val = Release(); int ret_val = Release();
if (ret_val < 0) { if (ret_val < 0) {

View File

@ -136,7 +136,6 @@ class VP8DecoderImpl : public VP8Decoder {
int RegisterDecodeCompleteCallback(DecodedImageCallback* callback) override; int RegisterDecodeCompleteCallback(DecodedImageCallback* callback) override;
int Release() override; int Release() override;
int Reset() override;
const char* ImplementationName() const 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) { int VP9DecoderImpl::InitDecode(const VideoCodec* inst, int number_of_cores) {
if (inst == NULL) { if (inst == NULL) {
return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;

View File

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

View File

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

View File

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

View File

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

View File

@ -384,12 +384,6 @@ class VideoCodingModule : public Module {
virtual int RegisterRenderBufferSizeCallback( virtual int RegisterRenderBufferSizeCallback(
VCMRenderBufferSizeCallback* callback) = 0; 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. // API to get the codec which is currently used for decoding by the module.
// //
// Input: // Input:

View File

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

View File

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

View File

@ -43,9 +43,10 @@ VideoReceiver::VideoReceiver(Clock* clock, EventFactory* event_factory)
#endif #endif
_frameFromFile(), _frameFromFile(),
_scheduleKeyRequest(false), _scheduleKeyRequest(false),
drop_frames_until_keyframe_(false),
max_nack_list_size_(0), max_nack_list_size_(0),
pre_decode_image_callback_(NULL),
_codecDataBase(nullptr, nullptr), _codecDataBase(nullptr, nullptr),
pre_decode_image_callback_(NULL),
_receiveStatsTimer(1000, clock_), _receiveStatsTimer(1000, clock_),
_retransmissionTimer(10, clock_), _retransmissionTimer(10, clock_),
_keyRequestTimer(500, clock_) { _keyRequestTimer(500, clock_) {
@ -282,6 +283,19 @@ int32_t VideoReceiver::Decode(uint16_t maxWaitTimeMs) {
if (!frame) if (!frame)
return VCM_FRAME_NOT_READY; 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); CriticalSectionScoped cs(_receiveCritSect);
// If this frame was too late, we should adjust the delay accordingly // 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; 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 // Register possible receive codecs, can be called multiple times
int32_t VideoReceiver::RegisterReceiveCodec(const VideoCodec* receiveCodec, int32_t VideoReceiver::RegisterReceiveCodec(const VideoCodec* receiveCodec,
int32_t numberOfCores, 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 // TODO(holmer): Investigate if this somehow should use the key frame
// request scheduling to throttle the requests. // request scheduling to throttle the requests.
if (ret == VCM_FLUSH_INDICATOR) { if (ret == VCM_FLUSH_INDICATOR) {
{
CriticalSectionScoped process_cs(process_crit_sect_.get());
drop_frames_until_keyframe_ = true;
}
RequestKeyFrame(); RequestKeyFrame();
ResetDecoder();
} else if (ret < 0) { } else if (ret < 0) {
return ret; return ret;
} }

View File

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

View File

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

View File

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

View File

@ -49,11 +49,6 @@ class VideoDecoderSoftwareFallbackWrapperTest : public ::testing::Test {
return WEBRTC_VIDEO_CODEC_OK; return WEBRTC_VIDEO_CODEC_OK;
} }
int32_t Reset() override {
++reset_count_;
return WEBRTC_VIDEO_CODEC_OK;
}
const char* ImplementationName() const override { const char* ImplementationName() const override {
return "fake-decoder"; return "fake-decoder";
} }
@ -134,20 +129,6 @@ TEST_F(VideoDecoderSoftwareFallbackWrapperTest, ForwardsReleaseCall) {
EXPECT_EQ(2, fake_decoder_.release_count_); 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 // TODO(pbos): Fake a VP8 frame well enough to actually receive a callback from
// the software decoder. // the software decoder.
TEST_F(VideoDecoderSoftwareFallbackWrapperTest, TEST_F(VideoDecoderSoftwareFallbackWrapperTest,

View File

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

View File

@ -73,7 +73,9 @@ class VideoDecoder {
DecodedImageCallback* callback) = 0; DecodedImageCallback* callback) = 0;
virtual int32_t Release() = 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. // Returns true if the decoder prefer to decode frames late.
// That is, it can not decode infinite number of frames before the decoded // 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; DecodedImageCallback* callback) override;
int32_t Release() override; int32_t Release() override;
int32_t Reset() override;
bool PrefersLateDecoding() const override; bool PrefersLateDecoding() const override;
const char* ImplementationName() const override; const char* ImplementationName() const override;