Implement NullVideoDecoder to avoid crash on unsupported decoders.

There is a use case with external codec factories that only support
encoding but not decoding for a given type. This leads to a crash
due to null being registered as codec (after a DCHECK).

This CL adds a NullVideoDecoder that is used instead of the null to
not crash but log to LS_ERROR.

BUG=webrtc:5249

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

Cr-Commit-Position: refs/heads/master@{#11475}
This commit is contained in:
jbauch 2016-02-03 05:51:48 -08:00 committed by Commit bot
parent 9dc5928eb2
commit e03ac51aa1
3 changed files with 65 additions and 6 deletions

View File

@ -2226,10 +2226,9 @@ WebRtcVideoChannel2::WebRtcVideoReceiveStream::CreateOrReuseVideoDecoder(
webrtc::VideoDecoder::Create(webrtc::VideoDecoder::kH264), type, false);
}
// This shouldn't happen, we should not be trying to create something we don't
// support.
RTC_DCHECK(false);
return AllocatedDecoder(NULL, webrtc::kVideoCodecUnknown, false);
return AllocatedDecoder(
webrtc::VideoDecoder::Create(webrtc::VideoDecoder::kUnsupportedCodec),
webrtc::kVideoCodecUnknown, false);
}
void WebRtcVideoChannel2::WebRtcVideoReceiveStream::ConfigureCodecs(

View File

@ -27,8 +27,8 @@ VideoDecoder* VideoDecoder::Create(VideoDecoder::DecoderType codec_type) {
case kVp9:
return VP9Decoder::Create();
case kUnsupportedCodec:
RTC_NOTREACHED();
return nullptr;
LOG(LS_ERROR) << "Creating NullVideoDecoder for unsupported codec.";
return new NullVideoDecoder();
}
RTC_NOTREACHED();
return nullptr;
@ -140,4 +140,40 @@ const char* VideoDecoderSoftwareFallbackWrapper::ImplementationName() const {
return decoder_->ImplementationName();
}
NullVideoDecoder::NullVideoDecoder() {}
int32_t NullVideoDecoder::InitDecode(const VideoCodec* codec_settings,
int32_t number_of_cores) {
LOG(LS_ERROR) << "Can't initialize NullVideoDecoder.";
return WEBRTC_VIDEO_CODEC_OK;
}
int32_t NullVideoDecoder::Decode(const EncodedImage& input_image,
bool missing_frames,
const RTPFragmentationHeader* fragmentation,
const CodecSpecificInfo* codec_specific_info,
int64_t render_time_ms) {
LOG(LS_ERROR) << "The NullVideoDecoder doesn't support decoding.";
return WEBRTC_VIDEO_CODEC_OK;
}
int32_t NullVideoDecoder::RegisterDecodeCompleteCallback(
DecodedImageCallback* callback) {
LOG(LS_ERROR)
<< "Can't register decode complete callback on NullVideoDecoder.";
return WEBRTC_VIDEO_CODEC_OK;
}
int32_t NullVideoDecoder::Release() {
return WEBRTC_VIDEO_CODEC_OK;
}
int32_t NullVideoDecoder::Reset() {
return WEBRTC_VIDEO_CODEC_OK;
}
const char* NullVideoDecoder::ImplementationName() const {
return "NullVideoDecoder";
}
} // namespace webrtc

View File

@ -123,6 +123,30 @@ class VideoDecoderSoftwareFallbackWrapper : public webrtc::VideoDecoder {
DecodedImageCallback* callback_;
};
// Video decoder class to be used for unknown codecs. Doesn't support decoding
// but logs messages to LS_ERROR.
class NullVideoDecoder : public VideoDecoder {
public:
NullVideoDecoder();
int32_t InitDecode(const VideoCodec* codec_settings,
int32_t number_of_cores) override;
int32_t Decode(const EncodedImage& input_image,
bool missing_frames,
const RTPFragmentationHeader* fragmentation,
const CodecSpecificInfo* codec_specific_info,
int64_t render_time_ms) override;
int32_t RegisterDecodeCompleteCallback(
DecodedImageCallback* callback) override;
int32_t Release() override;
int32_t Reset() override;
const char* ImplementationName() const override;
};
} // namespace webrtc
#endif // WEBRTC_VIDEO_DECODER_H_