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 | 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 | 19 | 2013-xx-xx - lavfi 3.8.0 |
| 17 | 20 | Move all content from avfiltergraph.h to avfilter.h. Deprecate |
| 18 | 21 | avfilterhraph.h, user applications should include just avfilter.h |
| @@ -609,6 +609,11 @@ typedef struct RcOverride{ · 608 unmodified lines | ||
| 609 | 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 | 617 | #define CODEC_FLAG_QSCALE 0x0002 ///< Use fixed qscale. |
| 613 | 618 | #define CODEC_FLAG_4MV 0x0004 ///< 4 MV per MB allowed / advanced prediction for H.263. |
| 614 | 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 | 1427 | h->avctx = avctx; |
| 1428 | 1428 | |
| 1429 | − h->width = h->avctx->width; | |
| 1430 | − h->height = h->avctx->height; | |
| 1431 | − | |
| 1432 | 1429 | h->bit_depth_luma = 8; |
| 1433 | 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 | 3014 | static int h264_slice_header_init(H264Context *h, int reinit) |
| 2982 | 3015 | { |
| 2983 | 3016 | int nb_slices = (HAVE_THREADS && |
| 2984 | 3017 | h->avctx->active_thread_type & FF_THREAD_SLICE) ? |
| 2985 | 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 | 3021 | h->avctx->sample_aspect_ratio = h->sps.sar; |
| 2990 | 3022 | av_assert0(h->avctx->sample_aspect_ratio.den); |
| 2991 | 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 | 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); | |
| 3200 | − if (h->sps.frame_mbs_only_flag) | |
| 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); | |
| 3231 | + h->width = 16 * h->mb_width; | |
| 3232 | + h->height = 16 * h->mb_height; | |
| 3204 | 3233 | |
| 3205 | − if (FFALIGN(h->avctx->width, 16) == h->width && | |
| 3206 | − FFALIGN(h->avctx->height, 16) == h->height) { | |
| 3207 | − h->width = h->avctx->width; | |
| 3208 | − h->height = h->avctx->height; | |
| 3209 | − } | |
| 3234 | + ret = init_dimensions(h); | |
| 3235 | + if (ret < 0) | |
| 3236 | + return ret; | |
| 3210 | 3237 | |
| 3211 | 3238 | if (h->sps.video_signal_type_present_flag) { |
| 3212 | 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 | 3250 | if (h->context_initialized && |
| 3224 | − (h->width != h->avctx->width || | |
| 3225 | − h->height != h->avctx->height || | |
| 3251 | + (h->width != h->avctx->coded_width || | |
| 3252 | + h->height != h->avctx->coded_height || | |
| 3226 | 3253 | needs_reinit)) { |
| 3227 | 3254 | |
| 3228 | 3255 | if (h != h0) { |
| @@ -4611,6 +4638,26 @@ static int get_consumed_bytes(int pos, int buf_size) · 1382 unmodified lines | ||
| 4611 | 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 | 4661 | static int decode_frame(AVCodecContext *avctx, void *data, |
| 4615 | 4662 | int *got_frame, AVPacket *avpkt) |
| 4616 | 4663 | { |
| @@ -4648,7 +4695,8 @@ out: · 31 unmodified lines | ||
| 4648 | 4695 | h->delayed_pic[i] = h->delayed_pic[i + 1]; |
| 4649 | 4696 | |
| 4650 | 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 | 4700 | return ret; |
| 4653 | 4701 | *got_frame = 1; |
| 4654 | 4702 | } |
| @@ -4683,7 +4731,8 @@ out: · 28 unmodified lines | ||
| 4683 | 4731 | /* Wait for second field. */ |
| 4684 | 4732 | *got_frame = 0; |
| 4685 | 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 | 4736 | return ret; |
| 4688 | 4737 | *got_frame = 1; |
| 4689 | 4738 | } |
| @@ -164,6 +164,8 @@ typedef struct SPS { · 163 unmodified lines | ||
| 164 | 164 | int mb_aff; ///< mb_adaptive_frame_field_flag |
| 165 | 165 | int direct_8x8_inference_flag; |
| 166 | 166 | int crop; ///< frame_cropping_flag |
| 167 | + | |
| 168 | + /* those 4 are already in luma samples */ | |
| 167 | 169 | unsigned int crop_left; ///< frame_cropping_rect_left_offset |
| 168 | 170 | unsigned int crop_right; ///< frame_cropping_rect_right_offset |
| 169 | 171 | unsigned int crop_top; ///< frame_cropping_rect_top_offset |
| @@ -272,6 +274,7 @@ typedef struct H264Context { · 102 unmodified lines | ||
| 272 | 274 | |
| 273 | 275 | int qp_thresh; ///< QP threshold to skip loopfilter |
| 274 | 276 | |
| 277 | + /* coded dimensions -- 16 * mb w/h */ | |
| 275 | 278 | int width, height; |
| 276 | 279 | int linesize, uvlinesize; |
| 277 | 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 | 413 | #endif |
| 414 | 414 | sps->crop= get_bits1(&h->gb); |
| 415 | 415 | if(sps->crop){ |
| 416 | − int crop_vertical_limit = sps->chroma_format_idc & 2 ? 16 : 8; | |
| 417 | − int crop_horizontal_limit = sps->chroma_format_idc == 3 ? 16 : 8; | |
| 418 | − sps->crop_left = get_ue_golomb(&h->gb); | |
| 419 | − sps->crop_right = get_ue_golomb(&h->gb); | |
| 420 | − sps->crop_top = get_ue_golomb(&h->gb); | |
| 421 | − sps->crop_bottom= get_ue_golomb(&h->gb); | |
| 416 | + int crop_left = get_ue_golomb(&h->gb); | |
| 417 | + int crop_right = get_ue_golomb(&h->gb); | |
| 418 | + int crop_top = get_ue_golomb(&h->gb); | |
| 419 | + int crop_bottom = get_ue_golomb(&h->gb); | |
| 420 | + | |
| 422 | 421 | if (h->avctx->flags2 & CODEC_FLAG2_IGNORE_CROP) { |
| 423 | − av_log(h->avctx, AV_LOG_DEBUG, | |
| 424 | − "discarding sps cropping, " | |
| 425 | − "original values are l:%u r:%u t:%u b:%u\n", | |
| 426 | − sps->crop_left, | |
| 427 | − sps->crop_right, | |
| 428 | − sps->crop_top, | |
| 429 | − sps->crop_bottom); | |
| 422 | + av_log(h->avctx, AV_LOG_DEBUG, "discarding sps cropping, original " | |
| 423 | + "values are l:%u r:%u t:%u b:%u\n", crop_left, crop_right, | |
| 424 | + crop_top, crop_bottom); | |
| 430 | 425 | |
| 431 | 426 | sps->crop_left = |
| 432 | 427 | sps->crop_right = |
| 433 | 428 | sps->crop_top = |
| 434 | 429 | sps->crop_bottom = 0; |
| 435 | − } | |
| 436 | − if(sps->crop_left || sps->crop_top){ | |
| 437 | − av_log(h->avctx, AV_LOG_ERROR, "insane cropping not completely supported, this could look slightly wrong ...\n"); | |
| 438 | − } | |
| 439 | − if(sps->crop_right >= crop_horizontal_limit || sps->crop_bottom >= crop_vertical_limit){ | |
| 440 | − av_log(h->avctx, AV_LOG_ERROR, "brainfart cropping not supported, this could look slightly wrong ...\n"); | |
| 430 | + } else { | |
| 431 | + int vsub = (sps->chroma_format_idc == 1) ? 1 : 0; | |
| 432 | + int hsub = (sps->chroma_format_idc == 1 || sps->chroma_format_idc == 2) ? 1 : 0; | |
| 433 | + int step_x = 1 << hsub; | |
| 434 | + int step_y = (2 - sps->frame_mbs_only_flag) << vsub; | |
| 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 | 449 | }else{ |
| 443 | 450 | sps->crop_left = |
| 444 | 451 | sps->crop_right = |
| 445 | 452 | sps->crop_top = |
| 446 | 453 | sps->crop_bottom= 0; |
| 454 | + sps->crop = 0; | |
| 447 | 455 | } |
| 448 | 456 | |
| 449 | 457 | sps->vui_parameters_present_flag= get_bits1(&h->gb); |
| @@ -46,6 +46,7 @@ static const AVOption options[]={ · 45 unmodified lines | ||
| 46 | 46 | "to minimum/maximum bitrate. Lowering tolerance too much has an adverse effect on quality.", |
| 47 | 47 | OFFSET(bit_rate_tolerance), AV_OPT_TYPE_INT, {.i64 = AV_CODEC_DEFAULT_BITRATE*20 }, 1, INT_MAX, V|E}, |
| 48 | 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 | 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 | 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 | 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 | 29 | #define LIBAVCODEC_VERSION_MAJOR 55 |
| 30 | −#define LIBAVCODEC_VERSION_MINOR 1 | |
| 30 | +#define LIBAVCODEC_VERSION_MINOR 2 | |
| 31 | 31 | #define LIBAVCODEC_VERSION_MICRO 0 |
| 32 | 32 | |
| 33 | 33 | #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ |