diff --git a/libavcodec/h264_ps.c b/libavcodec/h264_ps.c index 8a64a33780..7ee3876c8b 100644 --- a/libavcodec/h264_ps.c +++ b/libavcodec/h264_ps.c @@ -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) || diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c index a54d3816e4..3749d1f2ca 100644 --- a/libavcodec/h264_slice.c +++ b/libavcodec/h264_slice.c @@ -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; } diff --git a/libavcodec/h264dec.c b/libavcodec/h264dec.c index 3209c1d4df..834c60c38c 100644 --- a/libavcodec/h264dec.c +++ b/libavcodec/h264dec.c @@ -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), diff --git a/libavcodec/h264dec.h b/libavcodec/h264dec.h index 0a9896ac8a..fc7beeb994 100644 --- a/libavcodec/h264dec.h +++ b/libavcodec/h264dec.h @@ -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;