Based on a patch by Vittorio Giovara <vittorio.giovara@gmail.com> Fixes Bug 378.
Unified · Split
| @@ -13,6 +13,9 @@ libavutil: 2012-10-22 · 12 unmodified lines | |||
| 13 | 13 | ||
| 14 | API changes, most recent first: | 14 | API changes, most recent first: |
| 15 | 15 | ||
| 16 | 2013-03-xx - xxxxxxx - lavc 55.2.0 - avcodec.h | ||
| 17 | Add CODEC_FLAG_UNALIGNED to allow decoders to produce unaligned output. | ||
| 18 | |||
| 16 | 2013-xx-xx - lavfi 3.8.0 | 19 | 2013-xx-xx - lavfi 3.8.0 |
| 17 | Move all content from avfiltergraph.h to avfilter.h. Deprecate | 20 | Move all content from avfiltergraph.h to avfilter.h. Deprecate |
| 18 | avfilterhraph.h, user applications should include just avfilter.h | 21 | avfilterhraph.h, user applications should include just avfilter.h |
| @@ -609,6 +609,11 @@ typedef struct RcOverride{ · 608 unmodified lines | |||
| 609 | Note: Not everything is supported yet. | 609 | Note: Not everything is supported yet. |
| 610 | */ | 610 | */ |
| 611 | 611 | ||
| 612 | /** | ||
| 613 | * Allow decoders to produce frames with data planes that are not aligned | ||
| 614 | * to CPU requirements (e.g. due to cropping). | ||
| 615 | */ | ||
| 616 | #define CODEC_FLAG_UNALIGNED 0x0001 | ||
| 612 | #define CODEC_FLAG_QSCALE 0x0002 ///< Use fixed qscale. | 617 | #define CODEC_FLAG_QSCALE 0x0002 ///< Use fixed qscale. |
| 613 | #define CODEC_FLAG_4MV 0x0004 ///< 4 MV per MB allowed / advanced prediction for H.263. | 618 | #define CODEC_FLAG_4MV 0x0004 ///< 4 MV per MB allowed / advanced prediction for H.263. |
| 614 | #define CODEC_FLAG_QPEL 0x0010 ///< Use qpel MC. | 619 | #define CODEC_FLAG_QPEL 0x0010 ///< Use qpel MC. |
| @@ -1426,9 +1426,6 @@ av_cold int ff_h264_decode_init(AVCodecContext *avctx) · 1425 unmodified lines | |||
| 1426 | 1426 | ||
| 1427 | h->avctx = avctx; | 1427 | h->avctx = avctx; |
| 1428 | 1428 | ||
| 1429 | h->width = h->avctx->width; | ||
| 1430 | h->height = h->avctx->height; | ||
| 1431 | |||
| 1432 | h->bit_depth_luma = 8; | 1429 | h->bit_depth_luma = 8; |
| 1433 | h->chroma_format_idc = 1; | 1430 | h->chroma_format_idc = 1; |
| 1434 | 1431 | ||
| @@ -2978,14 +2975,49 @@ static enum AVPixelFormat get_pixel_format(H264Context *h) · 1543 unmodified lines | |||
| 2978 | } | 2975 | } |
| 2979 | } | 2976 | } |
| 2980 | 2977 | ||
| 2978 | /* export coded and cropped frame dimensions to AVCodecContext */ | ||
| 2979 | static int init_dimensions(H264Context *h) | ||
| 2980 | { | ||
| 2981 | int width = h->width - (h->sps.crop_right + h->sps.crop_left); | ||
| 2982 | int height = h->height - (h->sps.crop_top + h->sps.crop_bottom); | ||
| 2983 | |||
| 2984 | /* handle container cropping */ | ||
| 2985 | if (!h->sps.crop && | ||
| 2986 | FFALIGN(h->avctx->width, 16) == h->width && | ||
| 2987 | FFALIGN(h->avctx->height, 16) == h->height) { | ||
| 2988 | width = h->avctx->width; | ||
| 2989 | height = h->avctx->height; | ||
| 2990 | } | ||
| 2991 | |||
| 2992 | if (width <= 0 || height <= 0) { | ||
| 2993 | av_log(h->avctx, AV_LOG_ERROR, "Invalid cropped dimensions: %dx%d.\n", | ||
| 2994 | width, height); | ||
| 2995 | if (h->avctx->err_recognition & AV_EF_EXPLODE) | ||
| 2996 | return AVERROR_INVALIDDATA; | ||
| 2997 | |||
| 2998 | av_log(h->avctx, AV_LOG_WARNING, "Ignoring cropping information.\n"); | ||
| 2999 | h->sps.crop_bottom = h->sps.crop_top = h->sps.crop_right = h->sps.crop_left = 0; | ||
| 3000 | h->sps.crop = 0; | ||
| 3001 | |||
| 3002 | width = h->width; | ||
| 3003 | height = h->height; | ||
| 3004 | } | ||
| 3005 | |||
| 3006 | h->avctx->coded_width = h->width; | ||
| 3007 | h->avctx->coded_height = h->height; | ||
| 3008 | h->avctx->width = width; | ||
| 3009 | h->avctx->height = height; | ||
| 3010 | |||
| 3011 | return 0; | ||
| 3012 | } | ||
| 3013 | |||
| 2981 | static int h264_slice_header_init(H264Context *h, int reinit) | 3014 | static int h264_slice_header_init(H264Context *h, int reinit) |
| 2982 | { | 3015 | { |
| 2983 | int nb_slices = (HAVE_THREADS && | 3016 | int nb_slices = (HAVE_THREADS && |
| 2984 | h->avctx->active_thread_type & FF_THREAD_SLICE) ? | 3017 | h->avctx->active_thread_type & FF_THREAD_SLICE) ? |
| 2985 | h->avctx->thread_count : 1; | 3018 | h->avctx->thread_count : 1; |
| 2986 | int i; | 3019 | int i, ret; |
| 2987 | 3020 | ||
| 2988 | avcodec_set_dimensions(h->avctx, h->width, h->height); | ||
| 2989 | h->avctx->sample_aspect_ratio = h->sps.sar; | 3021 | h->avctx->sample_aspect_ratio = h->sps.sar; |
| 2990 | av_assert0(h->avctx->sample_aspect_ratio.den); | 3022 | av_assert0(h->avctx->sample_aspect_ratio.den); |
| 2991 | av_pix_fmt_get_chroma_sub_sample(h->avctx->pix_fmt, | 3023 | av_pix_fmt_get_chroma_sub_sample(h->avctx->pix_fmt, |
| @@ -3196,17 +3228,12 @@ static int decode_slice_header(H264Context *h, H264Context *h0) · 204 unmodified lines | |||
| 3196 | 3228 | ||
| 3197 | h->chroma_y_shift = h->sps.chroma_format_idc <= 1; // 400 uses yuv420p | 3229 | h->chroma_y_shift = h->sps.chroma_format_idc <= 1; // 400 uses yuv420p |
| 3198 | 3230 | ||
| 3199 | h->width = 16 * h->mb_width - (2 >> CHROMA444(h)) * FFMIN(h->sps.crop_right, (8 << CHROMA444(h)) - 1); | 3231 | h->width = 16 * h->mb_width; |
| 3200 | if (h->sps.frame_mbs_only_flag) | 3232 | h->height = 16 * h->mb_height; |
| 3201 | h->height = 16 * h->mb_height - (1 << h->chroma_y_shift) * FFMIN(h->sps.crop_bottom, (16 >> h->chroma_y_shift) - 1); | ||
| 3202 | else | ||
| 3203 | h->height = 16 * h->mb_height - (2 << h->chroma_y_shift) * FFMIN(h->sps.crop_bottom, (16 >> h->chroma_y_shift) - 1); | ||
| 3204 | 3233 | ||
| 3205 | if (FFALIGN(h->avctx->width, 16) == h->width && | 3234 | ret = init_dimensions(h); |
| 3206 | FFALIGN(h->avctx->height, 16) == h->height) { | 3235 | if (ret < 0) |
| 3207 | h->width = h->avctx->width; | 3236 | return ret; |
| 3208 | h->height = h->avctx->height; | ||
| 3209 | } | ||
| 3210 | 3237 | ||
| 3211 | if (h->sps.video_signal_type_present_flag) { | 3238 | if (h->sps.video_signal_type_present_flag) { |
| 3212 | h->avctx->color_range = h->sps.full_range ? AVCOL_RANGE_JPEG | 3239 | h->avctx->color_range = h->sps.full_range ? AVCOL_RANGE_JPEG |
| @@ -3221,8 +3248,8 @@ static int decode_slice_header(H264Context *h, H264Context *h0) · 8 unmodified lines | |||
| 3221 | } | 3248 | } |
| 3222 | 3249 | ||
| 3223 | if (h->context_initialized && | 3250 | if (h->context_initialized && |
| 3224 | (h->width != h->avctx->width || | 3251 | (h->width != h->avctx->coded_width || |
| 3225 | h->height != h->avctx->height || | 3252 | h->height != h->avctx->coded_height || |
| 3226 | needs_reinit)) { | 3253 | needs_reinit)) { |
| 3227 | 3254 | ||
| 3228 | if (h != h0) { | 3255 | if (h != h0) { |
| @@ -4611,6 +4638,26 @@ static int get_consumed_bytes(int pos, int buf_size) · 1382 unmodified lines | |||
| 4611 | return pos; | 4638 | return pos; |
| 4612 | } | 4639 | } |
| 4613 | 4640 | ||
| 4641 | static int output_frame(H264Context *h, AVFrame *dst, AVFrame *src) | ||
| 4642 | { | ||
| 4643 | int i; | ||
| 4644 | int ret = av_frame_ref(dst, src); | ||
| 4645 | if (ret < 0) | ||
| 4646 | return ret; | ||
| 4647 | |||
| 4648 | if (!h->sps.crop) | ||
| 4649 | return 0; | ||
| 4650 | |||
| 4651 | for (i = 0; i < 3; i++) { | ||
| 4652 | int hshift = (i > 0) ? h->chroma_x_shift : 0; | ||
| 4653 | int vshift = (i > 0) ? h->chroma_y_shift : 0; | ||
| 4654 | int off = ((h->sps.crop_left >> hshift) << h->pixel_shift) + | ||
| 4655 | (h->sps.crop_top >> vshift) * dst->linesize[i]; | ||
| 4656 | dst->data[i] += off; | ||
| 4657 | } | ||
| 4658 | return 0; | ||
| 4659 | } | ||
| 4660 | |||
| 4614 | static int decode_frame(AVCodecContext *avctx, void *data, | 4661 | static int decode_frame(AVCodecContext *avctx, void *data, |
| 4615 | int *got_frame, AVPacket *avpkt) | 4662 | int *got_frame, AVPacket *avpkt) |
| 4616 | { | 4663 | { |
| @@ -4648,7 +4695,8 @@ out: · 31 unmodified lines | |||
| 4648 | h->delayed_pic[i] = h->delayed_pic[i + 1]; | 4695 | h->delayed_pic[i] = h->delayed_pic[i + 1]; |
| 4649 | 4696 | ||
| 4650 | if (out) { | 4697 | if (out) { |
| 4651 | if ((ret = av_frame_ref(pict, &out->f)) < 0) | 4698 | ret = output_frame(h, pict, &out->f); |
| 4699 | if (ret < 0) | ||
| 4652 | return ret; | 4700 | return ret; |
| 4653 | *got_frame = 1; | 4701 | *got_frame = 1; |
| 4654 | } | 4702 | } |
| @@ -4683,7 +4731,8 @@ out: · 28 unmodified lines | |||
| 4683 | /* Wait for second field. */ | 4731 | /* Wait for second field. */ |
| 4684 | *got_frame = 0; | 4732 | *got_frame = 0; |
| 4685 | } else { | 4733 | } else { |
| 4686 | if ((ret = av_frame_ref(pict, &h->next_output_pic->f)) < 0) | 4734 | ret = output_frame(h, pict, &h->next_output_pic->f); |
| 4735 | if (ret < 0) | ||
| 4687 | return ret; | 4736 | return ret; |
| 4688 | *got_frame = 1; | 4737 | *got_frame = 1; |
| 4689 | } | 4738 | } |
| @@ -164,6 +164,8 @@ typedef struct SPS { · 163 unmodified lines | |||
| 164 | int mb_aff; ///< mb_adaptive_frame_field_flag | 164 | int mb_aff; ///< mb_adaptive_frame_field_flag |
| 165 | int direct_8x8_inference_flag; | 165 | int direct_8x8_inference_flag; |
| 166 | int crop; ///< frame_cropping_flag | 166 | int crop; ///< frame_cropping_flag |
| 167 | |||
| 168 | /* those 4 are already in luma samples */ | ||
| 167 | unsigned int crop_left; ///< frame_cropping_rect_left_offset | 169 | unsigned int crop_left; ///< frame_cropping_rect_left_offset |
| 168 | unsigned int crop_right; ///< frame_cropping_rect_right_offset | 170 | unsigned int crop_right; ///< frame_cropping_rect_right_offset |
| 169 | unsigned int crop_top; ///< frame_cropping_rect_top_offset | 171 | unsigned int crop_top; ///< frame_cropping_rect_top_offset |
| @@ -272,6 +274,7 @@ typedef struct H264Context { · 102 unmodified lines | |||
| 272 | 274 | ||
| 273 | int qp_thresh; ///< QP threshold to skip loopfilter | 275 | int qp_thresh; ///< QP threshold to skip loopfilter |
| 274 | 276 | ||
| 277 | /* coded dimensions -- 16 * mb w/h */ | ||
| 275 | int width, height; | 278 | int width, height; |
| 276 | int linesize, uvlinesize; | 279 | int linesize, uvlinesize; |
| 277 | int chroma_x_shift, chroma_y_shift; | 280 | int chroma_x_shift, chroma_y_shift; |
| @@ -413,37 +413,45 @@ int ff_h264_decode_seq_parameter_set(H264Context *h){ · 412 unmodified lines | |||
| 413 | #endif | 413 | #endif |
| 414 | sps->crop= get_bits1(&h->gb); | 414 | sps->crop= get_bits1(&h->gb); |
| 415 | if(sps->crop){ | 415 | if(sps->crop){ |
| 416 | int crop_vertical_limit = sps->chroma_format_idc & 2 ? 16 : 8; | 416 | int crop_left = get_ue_golomb(&h->gb); |
| 417 | int crop_horizontal_limit = sps->chroma_format_idc == 3 ? 16 : 8; | 417 | int crop_right = get_ue_golomb(&h->gb); |
| 418 | sps->crop_left = get_ue_golomb(&h->gb); | 418 | int crop_top = get_ue_golomb(&h->gb); |
| 419 | sps->crop_right = get_ue_golomb(&h->gb); | 419 | int crop_bottom = get_ue_golomb(&h->gb); |
| 420 | sps->crop_top = get_ue_golomb(&h->gb); | 420 | |
| 421 | sps->crop_bottom= get_ue_golomb(&h->gb); | ||
| 422 | if (h->avctx->flags2 & CODEC_FLAG2_IGNORE_CROP) { | 421 | if (h->avctx->flags2 & CODEC_FLAG2_IGNORE_CROP) { |
| 423 | av_log(h->avctx, AV_LOG_DEBUG, | 422 | av_log(h->avctx, AV_LOG_DEBUG, "discarding sps cropping, original " |
| 424 | "discarding sps cropping, " | 423 | "values are l:%u r:%u t:%u b:%u\n", crop_left, crop_right, |
| 425 | "original values are l:%u r:%u t:%u b:%u\n", | 424 | crop_top, crop_bottom); |
| 426 | sps->crop_left, | ||
| 427 | sps->crop_right, | ||
| 428 | sps->crop_top, | ||
| 429 | sps->crop_bottom); | ||
| 430 | 425 | ||
| 431 | sps->crop_left = | 426 | sps->crop_left = |
| 432 | sps->crop_right = | 427 | sps->crop_right = |
| 433 | sps->crop_top = | 428 | sps->crop_top = |
| 434 | sps->crop_bottom = 0; | 429 | sps->crop_bottom = 0; |
| 435 | } | 430 | } else { |
| 436 | if(sps->crop_left || sps->crop_top){ | 431 | int vsub = (sps->chroma_format_idc == 1) ? 1 : 0; |
| 437 | av_log(h->avctx, AV_LOG_ERROR, "insane cropping not completely supported, this could look slightly wrong ...\n"); | 432 | int hsub = (sps->chroma_format_idc == 1 || sps->chroma_format_idc == 2) ? 1 : 0; |
| 438 | } | 433 | int step_x = 1 << hsub; |
| 439 | if(sps->crop_right >= crop_horizontal_limit || sps->crop_bottom >= crop_vertical_limit){ | 434 | int step_y = (2 - sps->frame_mbs_only_flag) << vsub; |
| 440 | av_log(h->avctx, AV_LOG_ERROR, "brainfart cropping not supported, this could look slightly wrong ...\n"); | 435 | |
| 436 | if (crop_left & (0x1F >> (sps->bit_depth_luma > 8)) && | ||
| 437 | !(h->avctx->flags & CODEC_FLAG_UNALIGNED)) { | ||
| 438 | crop_left &= ~(0x1F >> (sps->bit_depth_luma > 8)); | ||
| 439 | av_log(h->avctx, AV_LOG_WARNING, "Reducing left cropping to %d " | ||
| 440 | "chroma samples to preserve alignment.\n", | ||
| 441 | crop_left); | ||
| 442 | } | ||
| 443 | |||
| 444 | sps->crop_left = crop_left * step_x; | ||
| 445 | sps->crop_right = crop_right * step_x; | ||
| 446 | sps->crop_top = crop_top * step_y; | ||
| 447 | sps->crop_bottom = crop_bottom * step_y; | ||
| 441 | } | 448 | } |
| 442 | }else{ | 449 | }else{ |
| 443 | sps->crop_left = | 450 | sps->crop_left = |
| 444 | sps->crop_right = | 451 | sps->crop_right = |
| 445 | sps->crop_top = | 452 | sps->crop_top = |
| 446 | sps->crop_bottom= 0; | 453 | sps->crop_bottom= 0; |
| 454 | sps->crop = 0; | ||
| 447 | } | 455 | } |
| 448 | 456 | ||
| 449 | sps->vui_parameters_present_flag= get_bits1(&h->gb); | 457 | sps->vui_parameters_present_flag= get_bits1(&h->gb); |
| @@ -46,6 +46,7 @@ static const AVOption options[]={ · 45 unmodified lines | |||
| 46 | "to minimum/maximum bitrate. Lowering tolerance too much has an adverse effect on quality.", | 46 | "to minimum/maximum bitrate. Lowering tolerance too much has an adverse effect on quality.", |
| 47 | OFFSET(bit_rate_tolerance), AV_OPT_TYPE_INT, {.i64 = AV_CODEC_DEFAULT_BITRATE*20 }, 1, INT_MAX, V|E}, | 47 | OFFSET(bit_rate_tolerance), AV_OPT_TYPE_INT, {.i64 = AV_CODEC_DEFAULT_BITRATE*20 }, 1, INT_MAX, V|E}, |
| 48 | {"flags", NULL, OFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64 = DEFAULT }, 0, UINT_MAX, V|A|E|D, "flags"}, | 48 | {"flags", NULL, OFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64 = DEFAULT }, 0, UINT_MAX, V|A|E|D, "flags"}, |
| 49 | {"unaligned", "allow decoders to produce unaligned output", 0, AV_OPT_TYPE_CONST, { .i64 = CODEC_FLAG_UNALIGNED }, INT_MIN, INT_MAX, V | D, "flags" }, | ||
| 49 | {"mv4", "use four motion vectors per macroblock (MPEG-4)", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_4MV }, INT_MIN, INT_MAX, V|E, "flags"}, | 50 | {"mv4", "use four motion vectors per macroblock (MPEG-4)", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_4MV }, INT_MIN, INT_MAX, V|E, "flags"}, |
| 50 | {"qpel", "use 1/4-pel motion compensation", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_QPEL }, INT_MIN, INT_MAX, V|E, "flags"}, | 51 | {"qpel", "use 1/4-pel motion compensation", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_QPEL }, INT_MIN, INT_MAX, V|E, "flags"}, |
| 51 | {"loop", "use loop filter", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_LOOP_FILTER }, INT_MIN, INT_MAX, V|E, "flags"}, | 52 | {"loop", "use loop filter", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_LOOP_FILTER }, INT_MIN, INT_MAX, V|E, "flags"}, |
| @@ -27,7 +27,7 @@ · 26 unmodified lines | |||
| 27 | */ | 27 | */ |
| 28 | 28 | ||
| 29 | #define LIBAVCODEC_VERSION_MAJOR 55 | 29 | #define LIBAVCODEC_VERSION_MAJOR 55 |
| 30 | #define LIBAVCODEC_VERSION_MINOR 1 | 30 | #define LIBAVCODEC_VERSION_MINOR 2 |
| 31 | #define LIBAVCODEC_VERSION_MICRO 0 | 31 | #define LIBAVCODEC_VERSION_MICRO 0 |
| 32 | 32 | ||
| 33 | #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ | 33 | #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ |