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

Kaspter Ju kaspter at ucheer.org
Mon May 30 10:25:11 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