Index: talk/app/webrtc/java/jni/androidmediadecoder_jni.cc |
diff --git a/talk/app/webrtc/java/jni/androidmediadecoder_jni.cc b/talk/app/webrtc/java/jni/androidmediadecoder_jni.cc |
index 5322177165d55ed67092ce6a719669c81806d8dd..6fb06d03f3804eb9eb58d861ce3ba19902696132 100644 |
--- a/talk/app/webrtc/java/jni/androidmediadecoder_jni.cc |
+++ b/talk/app/webrtc/java/jni/androidmediadecoder_jni.cc |
@@ -61,16 +61,13 @@ using webrtc::kVideoCodecVP8; |
namespace webrtc_jni { |
-jobject MediaCodecVideoDecoderFactory::render_egl_context_ = NULL; |
- |
class MediaCodecVideoDecoder : public webrtc::VideoDecoder, |
public rtc::MessageHandler { |
public: |
- explicit MediaCodecVideoDecoder(JNIEnv* jni, VideoCodecType codecType); |
+ explicit MediaCodecVideoDecoder( |
+ JNIEnv* jni, VideoCodecType codecType, jobject render_egl_context); |
virtual ~MediaCodecVideoDecoder(); |
- static int SetAndroidObjects(JNIEnv* jni, jobject render_egl_context); |
- |
int32_t InitDecode(const VideoCodec* codecSettings, int32_t numberOfCores) |
override; |
@@ -158,11 +155,16 @@ class MediaCodecVideoDecoder : public webrtc::VideoDecoder, |
std::vector<jobject> input_buffers_; |
jobject surface_texture_; |
jobject previous_surface_texture_; |
+ |
+ // Render EGL context - owned by factory, should not be allocated/destroyed |
+ // by VideoDecoder. |
+ jobject render_egl_context_; |
}; |
MediaCodecVideoDecoder::MediaCodecVideoDecoder( |
- JNIEnv* jni, VideoCodecType codecType) : |
+ JNIEnv* jni, VideoCodecType codecType, jobject render_egl_context) : |
codecType_(codecType), |
+ render_egl_context_(render_egl_context), |
key_frame_required_(true), |
inited_(false), |
sw_fallback_required_(false), |
@@ -233,10 +235,8 @@ MediaCodecVideoDecoder::MediaCodecVideoDecoder( |
jni, j_decoder_output_buffer_info_class, "presentationTimestampUs", "J"); |
CHECK_EXCEPTION(jni) << "MediaCodecVideoDecoder ctor failed"; |
- use_surface_ = true; |
- if (MediaCodecVideoDecoderFactory::render_egl_context_ == NULL) { |
- use_surface_ = false; |
- } |
+ use_surface_ = (render_egl_context_ != NULL) ? true : false; |
+ ALOGD("MediaCodecVideoDecoder ctor. Use surface: %d", use_surface_); |
memset(&codec_, 0, sizeof(codec_)); |
AllowBlockingCalls(); |
} |
@@ -310,7 +310,7 @@ int32_t MediaCodecVideoDecoder::InitDecodeOnCodecThread() { |
codec_.width, |
codec_.height, |
use_surface_, |
- MediaCodecVideoDecoderFactory::render_egl_context_); |
+ render_egl_context_); |
if (CheckException(jni) || !success) { |
ALOGE("Codec initialization error - fallback to SW codec."); |
sw_fallback_required_ = true; |
@@ -745,35 +745,9 @@ void MediaCodecVideoDecoder::OnMessage(rtc::Message* msg) { |
codec_thread_->PostDelayed(kMediaCodecPollMs, this); |
} |
-int MediaCodecVideoDecoderFactory::SetAndroidObjects(JNIEnv* jni, |
- jobject render_egl_context) { |
- ALOGD("SetAndroidObjects for surface decoding."); |
- if (render_egl_context_) { |
- jni->DeleteGlobalRef(render_egl_context_); |
- } |
- if (IsNull(jni, render_egl_context)) { |
- render_egl_context_ = NULL; |
- } else { |
- render_egl_context_ = jni->NewGlobalRef(render_egl_context); |
- if (CheckException(jni)) { |
- ALOGE("error calling NewGlobalRef for EGL Context."); |
- render_egl_context_ = NULL; |
- } else { |
- jclass j_egl_context_class = FindClass(jni, "android/opengl/EGLContext"); |
- if (!jni->IsInstanceOf(render_egl_context_, j_egl_context_class)) { |
- ALOGE("Wrong EGL Context."); |
- jni->DeleteGlobalRef(render_egl_context_); |
- render_egl_context_ = NULL; |
- } |
- } |
- } |
- if (render_egl_context_ == NULL) { |
- ALOGD("NULL VideoDecoder EGL context - HW surface decoding is disabled."); |
- } |
- return 0; |
-} |
- |
-MediaCodecVideoDecoderFactory::MediaCodecVideoDecoderFactory() { |
+MediaCodecVideoDecoderFactory::MediaCodecVideoDecoderFactory() : |
+ render_egl_context_(NULL) { |
+ ALOGD("MediaCodecVideoDecoderFactory ctor"); |
JNIEnv* jni = AttachCurrentThreadIfNeeded(); |
ScopedLocalRefFrame local_ref_frame(jni); |
jclass j_decoder_class = FindClass(jni, "org/webrtc/MediaCodecVideoDecoder"); |
@@ -802,21 +776,55 @@ MediaCodecVideoDecoderFactory::MediaCodecVideoDecoderFactory() { |
} |
} |
-MediaCodecVideoDecoderFactory::~MediaCodecVideoDecoderFactory() {} |
+MediaCodecVideoDecoderFactory::~MediaCodecVideoDecoderFactory() { |
+ ALOGD("MediaCodecVideoDecoderFactory dtor"); |
+ if (render_egl_context_) { |
+ JNIEnv* jni = AttachCurrentThreadIfNeeded(); |
+ jni->DeleteGlobalRef(render_egl_context_); |
+ render_egl_context_ = NULL; |
+ } |
+} |
+ |
+void MediaCodecVideoDecoderFactory::SetEGLContext( |
+ JNIEnv* jni, jobject render_egl_context) { |
+ ALOGD("MediaCodecVideoDecoderFactory::SetEGLContext"); |
+ if (render_egl_context_) { |
+ jni->DeleteGlobalRef(render_egl_context_); |
+ render_egl_context_ = NULL; |
+ } |
+ if (!IsNull(jni, render_egl_context)) { |
+ render_egl_context_ = jni->NewGlobalRef(render_egl_context); |
+ if (CheckException(jni)) { |
+ ALOGE("error calling NewGlobalRef for EGL Context."); |
+ render_egl_context_ = NULL; |
+ } else { |
+ jclass j_egl_context_class = FindClass(jni, "android/opengl/EGLContext"); |
+ if (!jni->IsInstanceOf(render_egl_context_, j_egl_context_class)) { |
+ ALOGE("Wrong EGL Context."); |
+ jni->DeleteGlobalRef(render_egl_context_); |
+ render_egl_context_ = NULL; |
+ } |
+ } |
+ } |
+ if (render_egl_context_ == NULL) { |
+ ALOGW("NULL VideoDecoder EGL context - HW surface decoding is disabled."); |
+ } |
+} |
webrtc::VideoDecoder* MediaCodecVideoDecoderFactory::CreateVideoDecoder( |
VideoCodecType type) { |
if (supported_codec_types_.empty()) { |
+ ALOGE("No HW video decoder for type %d.", (int)type); |
return NULL; |
} |
- for (std::vector<VideoCodecType>::const_iterator it = |
- supported_codec_types_.begin(); it != supported_codec_types_.end(); |
- ++it) { |
- if (*it == type) { |
+ for (VideoCodecType codec_type : supported_codec_types_) { |
+ if (codec_type == type) { |
ALOGD("Create HW video decoder for type %d.", (int)type); |
- return new MediaCodecVideoDecoder(AttachCurrentThreadIfNeeded(), type); |
+ return new MediaCodecVideoDecoder( |
+ AttachCurrentThreadIfNeeded(), type, render_egl_context_); |
} |
} |
+ ALOGE("Can not find HW video decoder for type %d.", (int)type); |
return NULL; |
} |