[FFmpeg-cvslog] hevc: refactor pic_arrays and set_sps

Anton Khirnov git at videolan.org
Mon Oct 28 10:45:45 CET 2013


ffmpeg | branch: master | Anton Khirnov <anton at khirnov.net> | Mon Oct 28 00:40:34 2013 +0100| [cb148e56dc1573fdccb5dc3d2c3748f59f6b0fd5] | committer: Michael Niedermayer

hevc: refactor pic_arrays and set_sps
(cherry picked from commit a6686c6d83b50c0962269f2c487f4f0c57e0df79)

Signed-off-by: Michael Niedermayer <michaelni at gmx.at>

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=cb148e56dc1573fdccb5dc3d2c3748f59f6b0fd5
---

 libavcodec/hevc.c |  111 ++++++++++++++++++++++++++++-------------------------
 1 file changed, 59 insertions(+), 52 deletions(-)

diff --git a/libavcodec/hevc.c b/libavcodec/hevc.c
index 6d6f6fd..aaf319f 100644
--- a/libavcodec/hevc.c
+++ b/libavcodec/hevc.c
@@ -80,20 +80,16 @@ static void pic_arrays_free(HEVCContext *s)
 }
 
 /* allocate arrays that depend on frame dimensions */
-static int pic_arrays_init(HEVCContext *s)
+static int pic_arrays_init(HEVCContext *s, const HEVCSPS *sps)
 {
-    int log2_min_cb_size     = s->sps->log2_min_cb_size;
-    int width                = s->sps->width;
-    int height               = s->sps->height;
-    int pic_size             = width * height;
-    int pic_size_in_ctb      = ((width  >> log2_min_cb_size) + 1) *
-                               ((height >> log2_min_cb_size) + 1);
-    int ctb_count            = s->sps->ctb_width * s->sps->ctb_height;
-    int min_pu_width  = width  >> s->sps->log2_min_pu_size;
-    int pic_height_in_min_pu = height >> s->sps->log2_min_pu_size;
-    int min_pu_size   = min_pu_width * pic_height_in_min_pu;
-    int pic_width_in_min_tu  = width  >> s->sps->log2_min_tb_size;
-    int pic_height_in_min_tu = height >> s->sps->log2_min_tb_size;
+    int log2_min_cb_size = sps->log2_min_cb_size;
+    int width            = sps->width;
+    int height           = sps->height;
+    int pic_size         = width * height;
+    int pic_size_in_ctb  = ((width  >> log2_min_cb_size) + 1) *
+                           ((height >> log2_min_cb_size) + 1);
+    int ctb_count        = sps->ctb_width * sps->ctb_height;
+    int min_pu_size      = sps->min_pu_width * sps->min_pu_height;
 
     s->bs_width  = width  >> 3;
     s->bs_height = height >> 3;
@@ -105,11 +101,11 @@ static int pic_arrays_init(HEVCContext *s)
         goto fail;
 
     s->skip_flag    = av_malloc(pic_size_in_ctb);
-    s->tab_ct_depth = av_malloc(s->sps->min_cb_height * s->sps->min_cb_width);
+    s->tab_ct_depth = av_malloc(sps->min_cb_height * sps->min_cb_width);
     if (!s->skip_flag || !s->tab_ct_depth)
         goto fail;
 
-    s->cbf_luma = av_malloc(pic_width_in_min_tu * pic_height_in_min_tu);
+    s->cbf_luma = av_malloc(sps->min_tb_width * sps->min_tb_height);
     s->tab_ipm  = av_malloc(min_pu_size);
     s->is_pcm   = av_malloc(min_pu_size);
     if (!s->tab_ipm || !s->cbf_luma || !s->is_pcm)
@@ -280,10 +276,48 @@ static int decode_lt_rps(HEVCContext *s, LongTermRPS *rps, GetBitContext *gb)
     return 0;
 }
 
+static int set_sps(HEVCContext *s, const HEVCSPS *sps)
+{
+    int ret;
+
+    pic_arrays_free(s);
+    ret = pic_arrays_init(s, sps);
+    if (ret < 0)
+        goto fail;
+
+    s->avctx->coded_width         = sps->width;
+    s->avctx->coded_height        = sps->height;
+    s->avctx->width               = sps->output_width;
+    s->avctx->height              = sps->output_height;
+    s->avctx->pix_fmt             = sps->pix_fmt;
+    s->avctx->sample_aspect_ratio = sps->vui.sar;
+    s->avctx->has_b_frames        = sps->temporal_layer[sps->max_sub_layers - 1].num_reorder_pics;
+
+    ff_hevc_pred_init(&s->hpc,     sps->bit_depth);
+    ff_hevc_dsp_init (&s->hevcdsp, sps->bit_depth);
+    ff_videodsp_init (&s->vdsp,    sps->bit_depth);
+
+    if (sps->sao_enabled) {
+        av_frame_unref(s->tmp_frame);
+        ret = ff_get_buffer(s->avctx, s->tmp_frame, AV_GET_BUFFER_FLAG_REF);
+        if (ret < 0)
+            goto fail;
+        s->frame = s->tmp_frame;
+    }
+
+    s->sps = sps;
+    s->vps = s->vps_list[s->sps->vps_id];
+    return 0;
+fail:
+    pic_arrays_free(s);
+    s->sps = NULL;
+    return ret;
+}
+
 static int hls_slice_header(HEVCContext *s)
 {
     GetBitContext *gb = &s->HEVClc->gb;
-    SliceHeader   *sh = &s->sh;
+    SliceHeader *sh   = &s->sh;
     int i, j, ret;
 
     // Coded parameters
@@ -311,44 +345,14 @@ static int hls_slice_header(HEVCContext *s)
 
     if (s->sps != (HEVCSPS*)s->sps_list[s->pps->sps_id]->data) {
         s->sps = (HEVCSPS*)s->sps_list[s->pps->sps_id]->data;
-        s->vps = s->vps_list[s->sps->vps_id];
 
-        pic_arrays_free(s);
-        ret = pic_arrays_init(s);
-        if (ret < 0) {
-            s->sps = NULL;
-            return AVERROR(ENOMEM);
-        }
-
-        s->width  = s->sps->width;
-        s->height = s->sps->height;
-
-        s->avctx->coded_width  = s->sps->width;
-        s->avctx->coded_height = s->sps->height;
-        s->avctx->width        = s->sps->output_width;
-        s->avctx->height       = s->sps->output_height;
-        s->avctx->pix_fmt      = s->sps->pix_fmt;
-        s->avctx->sample_aspect_ratio = s->sps->vui.sar;
-        s->avctx->has_b_frames = s->sps->temporal_layer[s->sps->max_sub_layers - 1].num_reorder_pics;
-
-        if (s->sps->chroma_format_idc == 0 || s->sps->separate_colour_plane_flag) {
-            av_log(s->avctx, AV_LOG_ERROR,
-                   "TODO: s->sps->chroma_format_idc == 0 || "
-                   "s->sps->separate_colour_plane_flag\n");
-            return AVERROR_PATCHWELCOME;
-        }
-
-        ff_hevc_pred_init(&s->hpc,     s->sps->bit_depth);
-        ff_hevc_dsp_init (&s->hevcdsp, s->sps->bit_depth);
-        ff_videodsp_init (&s->vdsp,    s->sps->bit_depth);
+        ff_hevc_clear_refs(s);
+        ret = set_sps(s, s->sps);
+        if (ret < 0)
+            return ret;
 
-        if (s->sps->sao_enabled) {
-            av_frame_unref(s->tmp_frame);
-            ret = ff_get_buffer(s->avctx, s->tmp_frame, 0);
-            if (ret < 0)
-                return ret;
-            s->frame = s->tmp_frame;
-        }
+        s->seq_decode = (s->seq_decode + 1) & 0xff;
+        s->max_ra     = INT_MAX;
     }
 
     sh->dependent_slice_segment_flag = 0;
@@ -2731,6 +2735,9 @@ static int hevc_update_thread_context(AVCodecContext *dst,
         }
     }
 
+    if (s->sps != s0->sps)
+        ret = set_sps(s, s0->sps);
+
     s->seq_decode = s0->seq_decode;
     s->seq_output = s0->seq_output;
     s->pocTid0    = s0->pocTid0;



More information about the ffmpeg-cvslog mailing list