[vlc-devel] [RFC PATCH 7/7] mediacodec: WIP reopen MediaCodec if sps changes

Thomas Guillem thomas at gllm.fr
Thu Apr 23 19:30:55 CEST 2015


---
 modules/codec/omxil/android_mediacodec.c | 60 ++++++++++++++++++++++++++++++--
 1 file changed, 57 insertions(+), 3 deletions(-)

diff --git a/modules/codec/omxil/android_mediacodec.c b/modules/codec/omxil/android_mediacodec.c
index c988669..bbf3382 100644
--- a/modules/codec/omxil/android_mediacodec.c
+++ b/modules/codec/omxil/android_mediacodec.c
@@ -142,6 +142,9 @@ struct decoder_sys_t
     int stride, slice_height;
     char *name;
 
+    int i_width;
+    int i_height;
+    int i_sps_id;
     void *p_extra_buffer;
     size_t i_extra_buffer;
 
@@ -528,7 +531,7 @@ loopclean:
 
     jobject format = (*env)->CallStaticObjectMethod(env, jfields.media_format_class,
                          jfields.create_video_format, (*env)->NewStringUTF(env, mime),
-                         p_dec->fmt_in.video.i_width, p_dec->fmt_in.video.i_height);
+                         p_dec->p_sys->i_width, p_dec->p_sys->i_height);
 
     if (p_dec->fmt_in.i_extra && !p_sys->p_extra_buffer) {
         uint32_t size = p_dec->fmt_in.i_extra;
@@ -731,6 +734,8 @@ static int OpenDecoder(vlc_object_t *p_this)
 
     switch (p_dec->fmt_in.i_codec) {
     case VLC_CODEC_H264:
+        /* We can handle h264 without a valid video size */
+        break;
     case VLC_CODEC_HEVC:
     case VLC_CODEC_H263:
     case VLC_CODEC_MP4V:
@@ -764,12 +769,24 @@ static int OpenDecoder(vlc_object_t *p_this)
     p_dec->fmt_out.audio = p_dec->fmt_in.audio;
     p_dec->b_need_packetized = true;
 
+    p_dec->p_sys->i_sps_id = -1;
+    p_dec->p_sys->i_width = p_dec->fmt_in.video.i_width;
+    p_dec->p_sys->i_height = p_dec->fmt_in.video.i_height;
+
     p_dec->p_sys->timestamp_fifo = timestamp_FifoNew(32);
     if (!p_dec->p_sys->timestamp_fifo)
         goto error;
 
     switch (p_dec->fmt_in.i_codec)
     {
+    case VLC_CODEC_H264:
+        if (!p_dec->p_sys->i_width || !p_dec->p_sys->i_height)
+        {
+            msg_Warn(p_dec, "waiting for sps/pps for codec %4.4s",
+                     (const char *)&p_dec->fmt_in.i_codec);
+            return VLC_SUCCESS;
+        }
+    case VLC_CODEC_HEVC:
     case VLC_CODEC_VC1:
         if (!p_dec->fmt_in.i_extra)
         {
@@ -1115,6 +1132,7 @@ static picture_t *DecodeVideo(decoder_t *p_dec, block_t **pp_block)
     JNIEnv *env = NULL;
     block_t *p_block = pp_block ? *pp_block : NULL;
     bool b_error = false;
+    bool b_delayed_open = false;
 
     if (p_sys->error_state)
         goto endclean;
@@ -1147,11 +1165,47 @@ static picture_t *DecodeVideo(decoder_t *p_dec, block_t **pp_block)
         goto endclean;
     }
 
+    if (p_dec->fmt_in.i_codec == VLC_CODEC_H264 && p_block)
+    {
+        uint8_t *p_sps, *p_pps;
+        size_t i_sps, i_pps;
+
+        if (h264_get_spspps(p_block->p_buffer, p_block->i_buffer,
+                            &p_sps, &i_sps, &p_pps, &i_pps) == 0)
+        {
+            struct nal_sps sps;
+
+            if (h264_parse_sps(p_sps, i_sps, &sps) == 0)
+            {
+                if (sps.i_id != p_sys->i_sps_id)
+                {
+                    msg_Warn(p_dec, "found a new SPS, restart MediaCodec");
+                    if (p_sys->codec)
+                        CloseMediaCodec(p_dec, env);
+
+                    if (p_sys->p_extra_buffer)
+                        free(p_sys->p_extra_buffer);
+                    p_sys->p_extra_buffer = malloc(i_sps);
+                    if (p_sys->p_extra_buffer)
+                    {
+                        memcpy(p_sys->p_extra_buffer, p_sps, i_sps);
+                        p_sys->i_extra_buffer = i_sps;
+                    }
+
+                    p_sys->i_sps_id = sps.i_id;
+                    p_sys->i_width = sps.i_width;
+                    p_sys->i_height = sps.i_height;
+                    if (p_sys->i_width != 0 && p_sys->i_height != 0)
+                        b_delayed_open = true;
+                }
+            }
+        }
+
+    }
+
     /* try delayed opening if there is a new extra data */
     if (!p_sys->codec)
     {
-        bool b_delayed_open = false;
-
         switch (p_dec->fmt_in.i_codec)
         {
         case VLC_CODEC_VC1:
-- 
2.1.3




More information about the vlc-devel mailing list