| 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;
|
| }
|
|
|
|
|