Improve Java video codec error handling.

FALLBACK_SOFTWARE is now treated as a critical error and results in
immediate fallback to software coding if available. If ERROR is
returned, codec reset is attempted. If that fails, software fallback
is used.

Bug: b/73498933
Change-Id: I7fe163efd09e6f27c72491e9595954ddc59b1448
Reviewed-on: https://webrtc-review.googlesource.com/54901
Reviewed-by: Alex Glaznev <glaznev@webrtc.org>
Commit-Queue: Sami Kalliomäki <sakal@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#22169}
This commit is contained in:
Sami Kalliomäki
2018-02-20 11:35:53 +01:00
committed by Commit Bot
parent 99f52f83e4
commit d60d5c4479
6 changed files with 78 additions and 52 deletions

View File

@ -67,9 +67,10 @@ int32_t VideoDecoderWrapper::InitDecodeInternal(JNIEnv* jni) {
Java_VideoDecoderWrapper_createDecoderCallback(jni,
jlongFromPointer(this));
ScopedJavaLocalRef<jobject> ret =
Java_VideoDecoder_initDecode(jni, decoder_, settings, callback);
if (JavaToNativeVideoCodecStatus(jni, ret) == WEBRTC_VIDEO_CODEC_OK) {
int32_t status = JavaToNativeVideoCodecStatus(
jni, Java_VideoDecoder_initDecode(jni, decoder_, settings, callback));
RTC_LOG(LS_INFO) << "initDecode: " << status;
if (status == WEBRTC_VIDEO_CODEC_OK) {
initialized_ = true;
}
@ -77,7 +78,7 @@ int32_t VideoDecoderWrapper::InitDecodeInternal(JNIEnv* jni) {
// providing QP values.
qp_parsing_enabled_ = true;
return HandleReturnCode(jni, ret);
return status;
}
int32_t VideoDecoderWrapper::Decode(
@ -116,7 +117,7 @@ int32_t VideoDecoderWrapper::Decode(
ScopedJavaLocalRef<jobject> decode_info;
ScopedJavaLocalRef<jobject> ret =
Java_VideoDecoder_decode(env, decoder_, jinput_image, decode_info);
return HandleReturnCode(env, ret);
return HandleReturnCode(env, ret, "decode");
}
int32_t VideoDecoderWrapper::RegisterDecodeCompleteCallback(
@ -128,13 +129,14 @@ int32_t VideoDecoderWrapper::RegisterDecodeCompleteCallback(
int32_t VideoDecoderWrapper::Release() {
JNIEnv* jni = AttachCurrentThreadIfNeeded();
ScopedJavaLocalRef<jobject> ret = Java_VideoDecoder_release(jni, decoder_);
int32_t status = JavaToNativeVideoCodecStatus(
jni, Java_VideoDecoder_release(jni, decoder_));
RTC_LOG(LS_INFO) << "release: " << status;
{
rtc::CritScope cs(&frame_extra_infos_lock_);
frame_extra_infos_.clear();
}
initialized_ = false;
int32_t status = HandleReturnCode(jni, ret);
// It is allowed to reinitialize the codec on a different thread.
decoder_thread_checker_.DetachFromThread();
return status;
@ -193,19 +195,29 @@ void VideoDecoderWrapper::OnDecodedFrame(
}
int32_t VideoDecoderWrapper::HandleReturnCode(JNIEnv* jni,
const JavaRef<jobject>& code) {
int32_t value = JavaToNativeVideoCodecStatus(jni, code);
if (value < 0) { // Any errors are represented by negative values.
// Reset the codec.
if (Release() == WEBRTC_VIDEO_CODEC_OK) {
InitDecodeInternal(jni);
}
RTC_LOG(LS_WARNING) << "Falling back to software decoder.";
return WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE;
} else {
const JavaRef<jobject>& j_value,
const char* method_name) {
int32_t value = JavaToNativeVideoCodecStatus(jni, j_value);
if (value >= 0) { // OK or NO_OUTPUT
return value;
}
RTC_LOG(LS_WARNING) << method_name << ": " << value;
if (value == WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE ||
value == WEBRTC_VIDEO_CODEC_UNINITIALIZED) { // Critical error.
RTC_LOG(LS_WARNING) << "Java decoder requested software fallback.";
return WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE;
}
// Try resetting the codec.
if (Release() == WEBRTC_VIDEO_CODEC_OK &&
InitDecodeInternal(jni) == WEBRTC_VIDEO_CODEC_OK) {
RTC_LOG(LS_WARNING) << "Reset Java decoder.";
return WEBRTC_VIDEO_CODEC_ERROR;
}
RTC_LOG(LS_WARNING) << "Unable to reset Java decoder.";
return WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE;
}
rtc::Optional<uint8_t> VideoDecoderWrapper::ParseQP(