[vlc-devel] [PATCH 4/7] mediacodec: don't loop in GetOutput

Thomas Guillem thomas at gllm.fr
Mon Mar 23 18:40:01 CET 2015


DecodeVideo is already looping.
---
 modules/codec/omxil/android_mediacodec.c | 298 ++++++++++++++-----------------
 1 file changed, 138 insertions(+), 160 deletions(-)

diff --git a/modules/codec/omxil/android_mediacodec.c b/modules/codec/omxil/android_mediacodec.c
index ee39832..77b2430 100644
--- a/modules/codec/omxil/android_mediacodec.c
+++ b/modules/codec/omxil/android_mediacodec.c
@@ -849,179 +849,157 @@ static int ReleaseOutputBuffer(decoder_t *p_dec, JNIEnv *env, int i_index,
 static int GetOutput(decoder_t *p_dec, JNIEnv *env, picture_t **pp_pic, jlong timeout)
 {
     decoder_sys_t *p_sys = p_dec->p_sys;
-    while (1) {
-        int index = (*env)->CallIntMethod(env, p_sys->codec, p_sys->dequeue_output_buffer,
-                                          p_sys->buffer_info, timeout);
-        if (CHECK_EXCEPTION()) {
-            msg_Err(p_dec, "Exception in MediaCodec.dequeueOutputBuffer (GetOutput)");
-            return -1;
-        }
-
-        if (index >= 0) {
-            if (!p_sys->pixel_format) {
-                msg_Warn(p_dec, "Buffers returned before output format is set, dropping frame");
-                if (ReleaseOutputBuffer(p_dec, env, index, false) != 0)
-                    return -1;
-                continue;
-            }
-
-            if (!*pp_pic) {
-                *pp_pic = decoder_NewPicture(p_dec);
-            } else if (p_sys->direct_rendering) {
-                picture_t *p_pic = *pp_pic;
-                picture_sys_t *p_picsys = p_pic->p_sys;
-                int i_prev_index = p_picsys->priv.hw.i_index;
-                if (ReleaseOutputBuffer(p_dec, env, i_prev_index, false) != 0)
-                    return -1;
+    int index = (*env)->CallIntMethod(env, p_sys->codec, p_sys->dequeue_output_buffer,
+                                      p_sys->buffer_info, timeout);
+    if (CHECK_EXCEPTION()) {
+        msg_Err(p_dec, "Exception in MediaCodec.dequeueOutputBuffer (GetOutput)");
+        return -1;
+    }
 
-                // No need to lock here since the previous picture was not sent.
-                InsertInflightPicture(p_dec, NULL, i_prev_index);
-            }
-            if (*pp_pic) {
-
-                picture_t *p_pic = *pp_pic;
-                /* If the oldest input block had no PTS, the timestamp
-                 * of the frame returned by MediaCodec might be wrong
-                 * so we overwrite it with the corresponding dts. */
-                int64_t forced_ts = timestamp_FifoGet(p_sys->timestamp_fifo);
-                if (forced_ts == VLC_TS_INVALID)
-                    p_pic->date = (*env)->GetLongField(env, p_sys->buffer_info, p_sys->pts_field);
-                else
-                    p_pic->date = forced_ts;
+    if (index >= 0) {
+        if (!p_sys->pixel_format) {
+            msg_Warn(p_dec, "Buffers returned before output format is set, dropping frame");
+            return ReleaseOutputBuffer(p_dec, env, index, false);
+        }
 
-                if (p_sys->direct_rendering) {
-                    picture_sys_t *p_picsys = p_pic->p_sys;
-                    p_picsys->pf_lock_pic = NULL;
-                    p_picsys->pf_unlock_pic = UnlockPicture;
-                    p_picsys->priv.hw.p_dec = p_dec;
-                    p_picsys->priv.hw.i_index = index;
-                    p_picsys->priv.hw.b_valid = true;
-
-                    vlc_mutex_lock(get_android_opaque_mutex());
-                    InsertInflightPicture(p_dec, p_pic, index);
-                    vlc_mutex_unlock(get_android_opaque_mutex());
-                } else {
-                    jobject buf;
-                    if (p_sys->get_output_buffers)
-                        buf = (*env)->GetObjectArrayElement(env, p_sys->output_buffers, index);
-                    else
-                        buf = (*env)->CallObjectMethod(env, p_sys->codec,
-                                                       p_sys->get_output_buffer, index);
-                    //jsize buf_size = (*env)->GetDirectBufferCapacity(env, buf);
-                    uint8_t *ptr = (*env)->GetDirectBufferAddress(env, buf);
-
-                    //int size = (*env)->GetIntField(env, p_sys->buffer_info, p_sys->size_field);
-                    int offset = (*env)->GetIntField(env, p_sys->buffer_info, p_sys->offset_field);
-                    ptr += offset; // Check the size parameter as well
-
-                    unsigned int chroma_div;
-                    GetVlcChromaSizes(p_dec->fmt_out.i_codec, p_dec->fmt_out.video.i_width,
-                                      p_dec->fmt_out.video.i_height, NULL, NULL, &chroma_div);
-                    CopyOmxPicture(p_sys->pixel_format, p_pic, p_sys->slice_height, p_sys->stride,
-                                   ptr, chroma_div, &p_sys->architecture_specific_data);
-                    (*env)->CallVoidMethod(env, p_sys->codec, p_sys->release_output_buffer, index, false);
-
-                    jthrowable exception = (*env)->ExceptionOccurred(env);
-                    if (exception != NULL) {
-                        jclass illegalStateException = (*env)->FindClass(env, "java/lang/IllegalStateException");
-                        if((*env)->IsInstanceOf(env, exception, illegalStateException)) {
-                            msg_Err(p_dec, "Codec error (IllegalStateException) in MediaCodec.releaseOutputBuffer");
-                            (*env)->ExceptionClear(env);
-                            (*env)->DeleteLocalRef(env, illegalStateException);
-                            (*env)->DeleteLocalRef(env, buf);
-                            return -1;
-                        }
-                    }
+        *pp_pic = decoder_NewPicture(p_dec);
+        if (!*pp_pic) {
+            msg_Warn(p_dec, "NewPicture failed");
+            return ReleaseOutputBuffer(p_dec, env, index, false);
+        }
+        picture_t *p_pic = *pp_pic;
+        /* If the oldest input block had no PTS, the timestamp
+         * of the frame returned by MediaCodec might be wrong
+         * so we overwrite it with the corresponding dts. */
+        int64_t forced_ts = timestamp_FifoGet(p_sys->timestamp_fifo);
+        if (forced_ts == VLC_TS_INVALID)
+            p_pic->date = (*env)->GetLongField(env, p_sys->buffer_info, p_sys->pts_field);
+        else
+            p_pic->date = forced_ts;
+
+        if (p_sys->direct_rendering) {
+            picture_sys_t *p_picsys = p_pic->p_sys;
+            p_picsys->pf_lock_pic = NULL;
+            p_picsys->pf_unlock_pic = UnlockPicture;
+            p_picsys->priv.hw.p_dec = p_dec;
+            p_picsys->priv.hw.i_index = index;
+            p_picsys->priv.hw.b_valid = true;
+
+            vlc_mutex_lock(get_android_opaque_mutex());
+            InsertInflightPicture(p_dec, p_pic, index);
+            vlc_mutex_unlock(get_android_opaque_mutex());
+        } else {
+            jobject buf;
+            if (p_sys->get_output_buffers)
+                buf = (*env)->GetObjectArrayElement(env, p_sys->output_buffers, index);
+            else
+                buf = (*env)->CallObjectMethod(env, p_sys->codec,
+                                               p_sys->get_output_buffer, index);
+            //jsize buf_size = (*env)->GetDirectBufferCapacity(env, buf);
+            uint8_t *ptr = (*env)->GetDirectBufferAddress(env, buf);
+
+            //int size = (*env)->GetIntField(env, p_sys->buffer_info, p_sys->size_field);
+            int offset = (*env)->GetIntField(env, p_sys->buffer_info, p_sys->offset_field);
+            ptr += offset; // Check the size parameter as well
+
+            unsigned int chroma_div;
+            GetVlcChromaSizes(p_dec->fmt_out.i_codec, p_dec->fmt_out.video.i_width,
+                              p_dec->fmt_out.video.i_height, NULL, NULL, &chroma_div);
+            CopyOmxPicture(p_sys->pixel_format, p_pic, p_sys->slice_height, p_sys->stride,
+                           ptr, chroma_div, &p_sys->architecture_specific_data);
+            (*env)->CallVoidMethod(env, p_sys->codec, p_sys->release_output_buffer, index, false);
+
+            jthrowable exception = (*env)->ExceptionOccurred(env);
+            if (exception != NULL) {
+                jclass illegalStateException = (*env)->FindClass(env, "java/lang/IllegalStateException");
+                if((*env)->IsInstanceOf(env, exception, illegalStateException)) {
+                    msg_Err(p_dec, "Codec error (IllegalStateException) in MediaCodec.releaseOutputBuffer");
+                    (*env)->ExceptionClear(env);
+                    (*env)->DeleteLocalRef(env, illegalStateException);
                     (*env)->DeleteLocalRef(env, buf);
-                }
-            } else {
-                msg_Warn(p_dec, "NewPicture failed");
-                if (ReleaseOutputBuffer(p_dec, env, index, false) != 0)
                     return -1;
+                }
             }
+            (*env)->DeleteLocalRef(env, buf);
+        }
+    } else if (index == INFO_OUTPUT_BUFFERS_CHANGED) {
+        msg_Dbg(p_dec, "output buffers changed");
+        if (!p_sys->get_output_buffers)
             return 0;
+        (*env)->DeleteGlobalRef(env, p_sys->output_buffers);
 
-        } else if (index == INFO_OUTPUT_BUFFERS_CHANGED) {
-            msg_Dbg(p_dec, "output buffers changed");
-            if (!p_sys->get_output_buffers)
-                continue;
-            (*env)->DeleteGlobalRef(env, p_sys->output_buffers);
+        p_sys->output_buffers = (*env)->CallObjectMethod(env, p_sys->codec,
+                                                         p_sys->get_output_buffers);
+        if (CHECK_EXCEPTION()) {
+            msg_Err(p_dec, "Exception in MediaCodec.getOutputBuffer (GetOutput)");
+            p_sys->output_buffers = NULL;
+            return -1;
+        }
 
-            p_sys->output_buffers = (*env)->CallObjectMethod(env, p_sys->codec,
-                                                             p_sys->get_output_buffers);
-            if (CHECK_EXCEPTION()) {
-                msg_Err(p_dec, "Exception in MediaCodec.getOutputBuffer (GetOutput)");
-                p_sys->output_buffers = NULL;
-                return -1;
-            }
+        p_sys->output_buffers = (*env)->NewGlobalRef(env, p_sys->output_buffers);
 
-            p_sys->output_buffers = (*env)->NewGlobalRef(env, p_sys->output_buffers);
-        } else if (index == INFO_OUTPUT_FORMAT_CHANGED) {
-            jobject format = (*env)->CallObjectMethod(env, p_sys->codec, p_sys->get_output_format);
-            if (CHECK_EXCEPTION()) {
-                msg_Err(p_dec, "Exception in MediaCodec.getOutputFormat (GetOutput)");
-                return -1;
-            }
+    } else if (index == INFO_OUTPUT_FORMAT_CHANGED) {
+        jobject format = (*env)->CallObjectMethod(env, p_sys->codec, p_sys->get_output_format);
+        if (CHECK_EXCEPTION()) {
+            msg_Err(p_dec, "Exception in MediaCodec.getOutputFormat (GetOutput)");
+            return -1;
+        }
 
-            jobject format_string = (*env)->CallObjectMethod(env, format, p_sys->tostring);
-
-            jsize format_len = (*env)->GetStringUTFLength(env, format_string);
-            const char *format_ptr = (*env)->GetStringUTFChars(env, format_string, NULL);
-            msg_Dbg(p_dec, "output format changed: %.*s", format_len, format_ptr);
-            (*env)->ReleaseStringUTFChars(env, format_string, format_ptr);
-
-            ArchitectureSpecificCopyHooksDestroy(p_sys->pixel_format, &p_sys->architecture_specific_data);
-
-            int width           = GET_INTEGER(format, "width");
-            int height          = GET_INTEGER(format, "height");
-            p_sys->stride       = GET_INTEGER(format, "stride");
-            p_sys->slice_height = GET_INTEGER(format, "slice-height");
-            p_sys->pixel_format = GET_INTEGER(format, "color-format");
-            int crop_left       = GET_INTEGER(format, "crop-left");
-            int crop_top        = GET_INTEGER(format, "crop-top");
-            int crop_right      = GET_INTEGER(format, "crop-right");
-            int crop_bottom     = GET_INTEGER(format, "crop-bottom");
-
-            const char *name = "unknown";
-            if (!p_sys->direct_rendering) {
-                if (!GetVlcChromaFormat(p_sys->pixel_format,
-                                        &p_dec->fmt_out.i_codec, &name)) {
-                    msg_Err(p_dec, "color-format not recognized");
-                    return -1;
-                }
+        jobject format_string = (*env)->CallObjectMethod(env, format, p_sys->tostring);
+
+        jsize format_len = (*env)->GetStringUTFLength(env, format_string);
+        const char *format_ptr = (*env)->GetStringUTFChars(env, format_string, NULL);
+        msg_Dbg(p_dec, "output format changed: %.*s", format_len, format_ptr);
+        (*env)->ReleaseStringUTFChars(env, format_string, format_ptr);
+
+        ArchitectureSpecificCopyHooksDestroy(p_sys->pixel_format, &p_sys->architecture_specific_data);
+
+        int width           = GET_INTEGER(format, "width");
+        int height          = GET_INTEGER(format, "height");
+        p_sys->stride       = GET_INTEGER(format, "stride");
+        p_sys->slice_height = GET_INTEGER(format, "slice-height");
+        p_sys->pixel_format = GET_INTEGER(format, "color-format");
+        int crop_left       = GET_INTEGER(format, "crop-left");
+        int crop_top        = GET_INTEGER(format, "crop-top");
+        int crop_right      = GET_INTEGER(format, "crop-right");
+        int crop_bottom     = GET_INTEGER(format, "crop-bottom");
+
+        const char *name = "unknown";
+        if (!p_sys->direct_rendering) {
+            if (!GetVlcChromaFormat(p_sys->pixel_format,
+                                    &p_dec->fmt_out.i_codec, &name)) {
+                msg_Err(p_dec, "color-format not recognized");
+                return -1;
             }
+        }
 
-            msg_Err(p_dec, "output: %d %s, %dx%d stride %d %d, crop %d %d %d %d",
-                    p_sys->pixel_format, name, width, height, p_sys->stride, p_sys->slice_height,
-                    crop_left, crop_top, crop_right, crop_bottom);
+        msg_Err(p_dec, "output: %d %s, %dx%d stride %d %d, crop %d %d %d %d",
+                p_sys->pixel_format, name, width, height, p_sys->stride, p_sys->slice_height,
+                crop_left, crop_top, crop_right, crop_bottom);
 
-            p_dec->fmt_out.video.i_width = crop_right + 1 - crop_left;
-            p_dec->fmt_out.video.i_height = crop_bottom + 1 - crop_top;
-            if (p_dec->fmt_out.video.i_width <= 1
-                || p_dec->fmt_out.video.i_height <= 1) {
-                p_dec->fmt_out.video.i_width = width;
-                p_dec->fmt_out.video.i_height = height;
-            }
-            p_dec->fmt_out.video.i_visible_width = p_dec->fmt_out.video.i_width;
-            p_dec->fmt_out.video.i_visible_height = p_dec->fmt_out.video.i_height;
-
-            if (p_sys->stride <= 0)
-                p_sys->stride = width;
-            if (p_sys->slice_height <= 0)
-                p_sys->slice_height = height;
-            CHECK_EXCEPTION();
-
-            ArchitectureSpecificCopyHooks(p_dec, p_sys->pixel_format, p_sys->slice_height,
-                                          p_sys->stride, &p_sys->architecture_specific_data);
-            if (p_sys->pixel_format == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar)
-                p_sys->slice_height -= crop_top/2;
-            if (IgnoreOmxDecoderPadding(p_sys->name)) {
-                p_sys->slice_height = 0;
-                p_sys->stride = p_dec->fmt_out.video.i_width;
-            }
-
-        } else {
-            return 0;
+        p_dec->fmt_out.video.i_width = crop_right + 1 - crop_left;
+        p_dec->fmt_out.video.i_height = crop_bottom + 1 - crop_top;
+        if (p_dec->fmt_out.video.i_width <= 1
+            || p_dec->fmt_out.video.i_height <= 1) {
+            p_dec->fmt_out.video.i_width = width;
+            p_dec->fmt_out.video.i_height = height;
+        }
+        p_dec->fmt_out.video.i_visible_width = p_dec->fmt_out.video.i_width;
+        p_dec->fmt_out.video.i_visible_height = p_dec->fmt_out.video.i_height;
+
+        if (p_sys->stride <= 0)
+            p_sys->stride = width;
+        if (p_sys->slice_height <= 0)
+            p_sys->slice_height = height;
+        CHECK_EXCEPTION();
+
+        ArchitectureSpecificCopyHooks(p_dec, p_sys->pixel_format, p_sys->slice_height,
+                                      p_sys->stride, &p_sys->architecture_specific_data);
+        if (p_sys->pixel_format == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar)
+            p_sys->slice_height -= crop_top/2;
+        if (IgnoreOmxDecoderPadding(p_sys->name)) {
+            p_sys->slice_height = 0;
+            p_sys->stride = p_dec->fmt_out.video.i_width;
         }
     }
     return 0;
-- 
2.1.3




More information about the vlc-devel mailing list