[vlc-devel] [PATCH 1/1] mediacodec: handle hevc without a valid video size

kaspter at ucheer.org kaspter at ucheer.org
Mon May 30 10:12:03 CEST 2016


From: Kaspter Ju <kaspter at ucheer.org>

---
 modules/codec/omxil/mediacodec.c | 72 ++++++++++++++++++++++++++++++++++++++--
 1 file changed, 70 insertions(+), 2 deletions(-)

diff --git a/modules/codec/omxil/mediacodec.c b/modules/codec/omxil/mediacodec.c
index f006b9a..acc01e4 100644
--- a/modules/codec/omxil/mediacodec.c
+++ b/modules/codec/omxil/mediacodec.c
@@ -359,6 +359,56 @@ static int ParseVideoExtraH264(decoder_t *p_dec, uint8_t *p_extra, int i_extra)
         return H264SetCSD(p_dec, p_extra, i_extra, NULL);
 }
 
+
+
+static int HEVCSizeChanged(decoder_t *p_dec, void *p_buf, size_t i_size,
+                      bool *p_size_changed)
+{
+    decoder_sys_t *p_sys = p_dec->p_sys;
+    uint8_t *p_sps_buf = NULL, *p_pps_buf = NULL;
+    size_t i_sps_size = 0, i_pps_size = 0;
+
+    /* Get NALU type */
+    uint8_t i_nal_type = hevc_getNALType(&p_buf[4]);
+
+    if (i_nal_type == HEVC_NAL_SPS) {
+
+        uint8_t i_id;
+        if (hevc_get_xps_id(p_buf, i_size, &i_id)) {/* also checks id range */
+
+            if (hxxx_strip_AnnexB_startcode( &p_buf, &i_size) ) {
+                /* Create decoded entries */
+                if(i_nal_type == HEVC_NAL_SPS) {
+
+                    hevc_sequence_parameter_set_t *p_sps;
+                    p_sps = hevc_decode_sps(p_buf, i_size, true);
+                    if(!p_sps) {
+                        msg_Err(p_dec, "Failed decoding SPS id %d", i_id);
+                        return VLC_EGENERIC;
+                    }
+
+                    unsigned vsize[4];
+                    (void) hevc_get_picture_size( p_sps, &vsize[0], &vsize[1], &vsize[2], &vsize[3] );
+
+                    if (p_size_changed)
+                        *p_size_changed = (vsize[0] != p_sys->u.video.i_width
+                                        || vsize[1] != p_sys->u.video.i_height);
+
+                    p_sys->u.video.i_width = vsize[0];
+                    p_sys->u.video.i_height = vsize[1];
+
+                    hevc_rbsp_release_sps( p_sps );
+
+                    return VLC_SUCCESS;
+                }
+            }
+        }
+    }
+
+    return VLC_EGENERIC;
+}
+
+
 static int ParseVideoExtraHEVC(decoder_t *p_dec, uint8_t *p_extra, int i_extra)
 {
     decoder_sys_t *p_sys = p_dec->p_sys;
@@ -593,10 +643,17 @@ static int OpenDecoder(vlc_object_t *p_this, pf_MediaCodecApi_init pf_init)
     {
         if (!p_dec->fmt_in.video.i_width || !p_dec->fmt_in.video.i_height)
         {
-            /* We can handle h264 without a valid video size
+            /* We can handle h264/h265 without a valid video size
              * TODO handle VC1 with no size */
-            if (p_dec->fmt_in.i_codec != VLC_CODEC_H264)
+            if (p_dec->fmt_in.i_codec == VLC_CODEC_H264 ||
+                    p_dec->fmt_in.i_codec == VLC_CODEC_HEVC)
             {
+                msg_Dbg(p_dec, "try codec %4.4s with resolution (%dx%d)",
+                            (char *)&p_dec->fmt_in.i_codec,
+                            p_dec->fmt_in.video.i_width,
+                            p_dec->fmt_in.video.i_height);
+
+            } else {
                 msg_Dbg(p_dec, "resolution (%dx%d) not supported",
                         p_dec->fmt_in.video.i_width, p_dec->fmt_in.video.i_height);
                 return VLC_EGENERIC;
@@ -1603,6 +1660,7 @@ static int VideoHEVC_OnNewBlock(decoder_t *p_dec, block_t **pp_block,
 {
     decoder_sys_t *p_sys = p_dec->p_sys;
     block_t *p_block = *pp_block;
+    bool b_size_changed;
 
     assert(p_dec->fmt_in.i_codec == VLC_CODEC_HEVC && p_block);
 
@@ -1610,6 +1668,16 @@ static int VideoHEVC_OnNewBlock(decoder_t *p_dec, block_t **pp_block,
     {
         h264_AVC_to_AnnexB(p_block->p_buffer, p_block->i_buffer,
                                p_sys->u.video.i_nal_length_size);
+    } else if (HEVCSizeChanged(p_dec, p_block->p_buffer, p_block->i_buffer,
+                          &b_size_changed) == VLC_SUCCESS) {
+
+        if (b_size_changed)
+        {
+            msg_Dbg(p_dec, "Video size changed, new (%ux%u)",
+                                p_sys->u.video.i_width,
+                                p_sys->u.video.i_height);
+            *p_flags |= NEWBLOCK_FLAG_RESTART;
+        }
     }
 
     return Video_OnNewBlock(p_dec, pp_block, p_flags);
-- 
2.7.4



More information about the vlc-devel mailing list