h264dec: export cropping information instead of handling it internally
authorAnton Khirnov <anton@khirnov.net>
Sun, 18 Dec 2016 20:11:47 +0000 (21:11 +0100)
committerAnton Khirnov <anton@khirnov.net>
Thu, 12 Jan 2017 15:29:12 +0000 (16:29 +0100)
libavcodec/h264_ps.c
libavcodec/h264_slice.c
libavcodec/h264dec.c
libavcodec/h264dec.h

index 8a64a33..7ee3876 100644 (file)
@@ -498,15 +498,6 @@ int ff_h264_decode_seq_parameter_set(GetBitContext *gb, AVCodecContext *avctx,
             int step_x = 1 << hsub;
             int step_y = (2 - sps->frame_mbs_only_flag) << vsub;
 
-            if (crop_left & (0x1F >> (sps->bit_depth_luma > 8)) &&
-                !(avctx->flags & AV_CODEC_FLAG_UNALIGNED)) {
-                crop_left &= ~(0x1F >> (sps->bit_depth_luma > 8));
-                av_log(avctx, AV_LOG_WARNING,
-                       "Reducing left cropping to %d "
-                       "chroma samples to preserve alignment.\n",
-                       crop_left);
-            }
-
             if (INT_MAX / step_x             <= crop_left               ||
                 INT_MAX / step_x - crop_left <= crop_right              ||
                 16 * sps->mb_width <= step_x * (crop_left + crop_right) ||
index a54d381..3749d1f 100644 (file)
@@ -473,6 +473,11 @@ static int h264_frame_start(H264Context *h)
 
     pic->f->pict_type = h->slice_ctx[0].slice_type;
 
+    pic->f->crop_left   = h->crop_left;
+    pic->f->crop_right  = h->crop_right;
+    pic->f->crop_top    = h->crop_top;
+    pic->f->crop_bottom = h->crop_bottom;
+
     if (CONFIG_ERROR_RESILIENCE && h->enable_er)
         ff_er_frame_start(&h->slice_ctx[0].er);
 
@@ -795,8 +800,12 @@ static enum AVPixelFormat get_pixel_format(H264Context *h)
 static int init_dimensions(H264Context *h)
 {
     SPS *sps = h->ps.sps;
-    int width  = h->width  - (sps->crop_right + sps->crop_left);
-    int height = h->height - (sps->crop_top   + sps->crop_bottom);
+    int cr = sps->crop_right;
+    int cl = sps->crop_left;
+    int ct = sps->crop_top;
+    int cb = sps->crop_bottom;
+    int width  = h->width  - (cr + cl);
+    int height = h->height - (ct + cb);
 
     /* handle container cropping */
     if (h->width_from_caller > 0 && h->height_from_caller > 0     &&
@@ -805,6 +814,10 @@ static int init_dimensions(H264Context *h)
         FFALIGN(h->height_from_caller, 16) == FFALIGN(height, 16)) {
         width  = h->width_from_caller;
         height = h->height_from_caller;
+        cl = 0;
+        ct = 0;
+        cr = h->width - width;
+        cb = h->height - height;
     } else {
         h->width_from_caller  = 0;
         h->height_from_caller = 0;
@@ -814,6 +827,10 @@ static int init_dimensions(H264Context *h)
     h->avctx->coded_height = h->height;
     h->avctx->width        = width;
     h->avctx->height       = height;
+    h->crop_right          = cr;
+    h->crop_left           = cl;
+    h->crop_top            = ct;
+    h->crop_bottom         = cb;
 
     return 0;
 }
index 3209c1d..834c60c 100644 (file)
@@ -661,26 +661,6 @@ static int get_consumed_bytes(int pos, int buf_size)
     return pos;
 }
 
-static int output_frame(H264Context *h, AVFrame *dst, AVFrame *src)
-{
-    int i;
-    int ret = av_frame_ref(dst, src);
-    if (ret < 0)
-        return ret;
-
-    if (!h->ps.sps || !h->ps.sps->crop)
-        return 0;
-
-    for (i = 0; i < 3; i++) {
-        int hshift = (i > 0) ? h->chroma_x_shift : 0;
-        int vshift = (i > 0) ? h->chroma_y_shift : 0;
-        int off    = ((h->ps.sps->crop_left >> hshift) << h->pixel_shift) +
-                     (h->ps.sps->crop_top >> vshift) * dst->linesize[i];
-        dst->data[i] += off;
-    }
-    return 0;
-}
-
 static int h264_decode_frame(AVCodecContext *avctx, void *data,
                              int *got_frame, AVPacket *avpkt)
 {
@@ -722,7 +702,7 @@ out:
             h->delayed_pic[i] = h->delayed_pic[i + 1];
 
         if (out) {
-            ret = output_frame(h, pict, out->f);
+            ret = av_frame_ref(pict, out->f);
             if (ret < 0)
                 return ret;
             *got_frame = 1;
@@ -765,7 +745,7 @@ out:
 
         *got_frame = 0;
         if (h->output_frame->buf[0]) {
-            ret = output_frame(h, pict, h->output_frame) ;
+            ret = av_frame_ref(pict, h->output_frame);
             av_frame_unref(h->output_frame);
             if (ret < 0)
                 return ret;
@@ -804,7 +784,7 @@ AVCodec ff_h264_decoder = {
     .capabilities          = /*AV_CODEC_CAP_DRAW_HORIZ_BAND |*/ AV_CODEC_CAP_DR1 |
                              AV_CODEC_CAP_DELAY | AV_CODEC_CAP_SLICE_THREADS |
                              AV_CODEC_CAP_FRAME_THREADS,
-    .caps_internal         = FF_CODEC_CAP_INIT_THREADSAFE,
+    .caps_internal         = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_EXPORTS_CROPPING,
     .flush                 = flush_dpb,
     .init_thread_copy      = ONLY_IF_THREADS_ENABLED(decode_init_thread_copy),
     .update_thread_context = ONLY_IF_THREADS_ENABLED(ff_h264_update_thread_context),
index 0a9896a..fc7beeb 100644 (file)
@@ -372,6 +372,11 @@ typedef struct H264Context {
      */
     int picture_idr;
 
+    int crop_left;
+    int crop_right;
+    int crop_top;
+    int crop_bottom;
+
     int8_t(*intra4x4_pred_mode);
     H264PredContext hpc;