avcodec/h264dec: export cropping information instead of handling it internally
authorJames Almer <jamrial@gmail.com>
Mon, 8 May 2017 18:46:24 +0000 (15:46 -0300)
committerJames Almer <jamrial@gmail.com>
Fri, 26 May 2017 14:15:45 +0000 (11:15 -0300)
This merges commit c3e84820d67cb1d8cfb4196f9b43971308a81571 from libav,
originally written by Anton Khirnov and skipped in
fc63d5ceb357c4b760cb02772de0b50d0557140f.

 libavcodec/h264_picture.c |  3 ---
 libavcodec/h264_ps.c      |  9 ---------
 libavcodec/h264_slice.c   | 25 +++++++++++++++++++------
 libavcodec/h264dec.c      | 13 +------------
 libavcodec/h264dec.h      |  9 +++++----
 5 files changed, 25 insertions(+), 34 deletions(-)

libavcodec/h264_picture.c
libavcodec/h264_ps.c
libavcodec/h264_slice.c
libavcodec/h264dec.c
libavcodec/h264dec.h

index 2dbe5ee..99d9f90 100644 (file)
@@ -113,9 +113,6 @@ int ff_h264_ref_picture(H264Context *h, H264Picture *dst, H264Picture *src)
     dst->mbaff         = src->mbaff;
     dst->field_picture = src->field_picture;
     dst->reference     = src->reference;
-    dst->crop          = src->crop;
-    dst->crop_left     = src->crop_left;
-    dst->crop_top      = src->crop_top;
     dst->recovered     = src->recovered;
     dst->invalid_gap   = src->invalid_gap;
     dst->sei_recovery_frame_cnt = src->sei_recovery_frame_cnt;
index 7858361..b7d5f65 100644 (file)
@@ -533,15 +533,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 (crop_left  > (unsigned)INT_MAX / 4 / step_x ||
                 crop_right > (unsigned)INT_MAX / 4 / step_x ||
                 crop_top   > (unsigned)INT_MAX / 4 / step_y ||
index a7916e0..8ba2371 100644 (file)
@@ -197,10 +197,6 @@ static int alloc_picture(H264Context *h, H264Picture *pic)
     if (ret < 0)
         goto fail;
 
-    pic->crop     = h->ps.sps->crop;
-    pic->crop_top = h->ps.sps->crop_top;
-    pic->crop_left= h->ps.sps->crop_left;
-
     if (h->avctx->hwaccel) {
         const AVHWAccel *hwaccel = h->avctx->hwaccel;
         av_assert0(!pic->hwaccel_picture_private);
@@ -495,6 +491,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 ((ret = alloc_picture(h, pic)) < 0)
         return ret;
     if(!h->frame_recovered && !h->avctx->hwaccel
@@ -870,8 +871,12 @@ static enum AVPixelFormat get_pixel_format(H264Context *h, int force_callback)
 static int init_dimensions(H264Context *h)
 {
     const SPS *sps = (const 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);
     av_assert0(sps->crop_right + sps->crop_left < (unsigned)h->width);
     av_assert0(sps->crop_top + sps->crop_bottom < (unsigned)h->height);
 
@@ -884,6 +889,10 @@ static int init_dimensions(H264Context *h)
         h->height_from_caller <= height) {
         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;
@@ -893,6 +902,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 a8d07df..c7abd9d 100644 (file)
@@ -848,8 +848,6 @@ static int get_consumed_bytes(int pos, int buf_size)
 static int output_frame(H264Context *h, AVFrame *dst, H264Picture *srcp)
 {
     AVFrame *src = srcp->f;
-    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(src->format);
-    int i;
     int ret;
 
     if (src->format == AV_PIX_FMT_VIDEOTOOLBOX && src->buf[0]->size == 1)
@@ -863,16 +861,7 @@ static int output_frame(H264Context *h, AVFrame *dst, H264Picture *srcp)
 
     if (srcp->sei_recovery_frame_cnt == 0)
         dst->key_frame = 1;
-    if (!srcp->crop)
-        return 0;
 
-    for (i = 0; i < desc->nb_components; i++) {
-        int hshift = (i > 0) ? desc->log2_chroma_w : 0;
-        int vshift = (i > 0) ? desc->log2_chroma_h : 0;
-        int off    = ((srcp->crop_left >> hshift) << h->pixel_shift) +
-                      (srcp->crop_top  >> vshift) * dst->linesize[i];
-        dst->data[i] += off;
-    }
     return 0;
 }
 
@@ -1081,7 +1070,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 5e03d55..2106ba0 100644 (file)
@@ -161,10 +161,6 @@ typedef struct H264Picture {
     int recovered;          ///< picture at IDR or recovery point + recovery count
     int invalid_gap;
     int sei_recovery_frame_cnt;
-
-    int crop;
-    int crop_left;
-    int crop_top;
 } H264Picture;
 
 typedef struct H264Ref {
@@ -380,6 +376,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;