* commit '5e83d9aced2fc2b2e1360452794c58aba55d497c': h264: fully support cropping. Conflicts: doc/APIchanges libavcodec/h264.c libavcodec/h264_ps.c libavcodec/options_table.h libavcodec/version.h
Unified · Split
| @@ -167,6 +167,9 @@ API changes, most recent first: · 166 unmodified lines | |||
| 167 | 2012-03-26 - a67d9cf - lavfi 2.66.100 | 167 | 2012-03-26 - a67d9cf - lavfi 2.66.100 |
| 168 | Add avfilter_fill_frame_from_{audio_,}buffer_ref() functions. | 168 | Add avfilter_fill_frame_from_{audio_,}buffer_ref() functions. |
| 169 | 169 | ||
| 170 | 2013-03-xx - xxxxxxx - lavc 55.2.0 - avcodec.h | ||
| 171 | Add CODEC_FLAG_UNALIGNED to allow decoders to produce unaligned output. | ||
| 172 | |||
| 170 | 2013-xx-xx - lavfi 3.8.0 | 173 | 2013-xx-xx - lavfi 3.8.0 |
| 171 | Move all content from avfiltergraph.h to avfilter.h. Deprecate | 174 | Move all content from avfiltergraph.h to avfilter.h. Deprecate |
| 172 | avfilterhraph.h, user applications should include just avfilter.h | 175 | avfilterhraph.h, user applications should include just avfilter.h |
| @@ -685,6 +685,11 @@ typedef struct RcOverride{ · 684 unmodified lines | |||
| 685 | Note: Not everything is supported yet. | 685 | Note: Not everything is supported yet. |
| 686 | */ | 686 | */ |
| 687 | 687 | ||
| 688 | /** | ||
| 689 | * Allow decoders to produce frames with data planes that are not aligned | ||
| 690 | * to CPU requirements (e.g. due to cropping). | ||
| 691 | */ | ||
| 692 | #define CODEC_FLAG_UNALIGNED 0x0001 | ||
| 688 | #define CODEC_FLAG_QSCALE 0x0002 ///< Use fixed qscale. | 693 | #define CODEC_FLAG_QSCALE 0x0002 ///< Use fixed qscale. |
| 689 | #define CODEC_FLAG_4MV 0x0004 ///< 4 MV per MB allowed / advanced prediction for H.263. | 694 | #define CODEC_FLAG_4MV 0x0004 ///< 4 MV per MB allowed / advanced prediction for H.263. |
| 690 | #define CODEC_FLAG_QPEL 0x0010 ///< Use qpel MC. | 695 | #define CODEC_FLAG_QPEL 0x0010 ///< Use qpel MC. |
| @@ -1459,9 +1459,6 @@ av_cold int ff_h264_decode_init(AVCodecContext *avctx) · 1458 unmodified lines | |||
| 1459 | 1459 | ||
| 1460 | h->avctx = avctx; | 1460 | h->avctx = avctx; |
| 1461 | 1461 | ||
| 1462 | h->width = h->avctx->width; | ||
| 1463 | h->height = h->avctx->height; | ||
| 1464 | |||
| 1465 | h->bit_depth_luma = 8; | 1462 | h->bit_depth_luma = 8; |
| 1466 | h->chroma_format_idc = 1; | 1463 | h->chroma_format_idc = 1; |
| 1467 | 1464 | ||
| @@ -3053,26 +3050,48 @@ static enum AVPixelFormat get_pixel_format(H264Context *h, int force_callback) · 1585 unmodified lines | |||
| 3053 | } | 3050 | } |
| 3054 | } | 3051 | } |
| 3055 | 3052 | ||
| 3053 | /* export coded and cropped frame dimensions to AVCodecContext */ | ||
| 3054 | static int init_dimensions(H264Context *h) | ||
| 3055 | { | ||
| 3056 | int width = h->width - (h->sps.crop_right + h->sps.crop_left); | ||
| 3057 | int height = h->height - (h->sps.crop_top + h->sps.crop_bottom); | ||
| 3058 | |||
| 3059 | /* handle container cropping */ | ||
| 3060 | if (!h->sps.crop && | ||
| 3061 | FFALIGN(h->avctx->width, 16) == h->width && | ||
| 3062 | FFALIGN(h->avctx->height, 16) == h->height) { | ||
| 3063 | width = h->avctx->width; | ||
| 3064 | height = h->avctx->height; | ||
| 3065 | } | ||
| 3066 | |||
| 3067 | if (width <= 0 || height <= 0) { | ||
| 3068 | av_log(h->avctx, AV_LOG_ERROR, "Invalid cropped dimensions: %dx%d.\n", | ||
| 3069 | width, height); | ||
| 3070 | if (h->avctx->err_recognition & AV_EF_EXPLODE) | ||
| 3071 | return AVERROR_INVALIDDATA; | ||
| 3072 | |||
| 3073 | av_log(h->avctx, AV_LOG_WARNING, "Ignoring cropping information.\n"); | ||
| 3074 | h->sps.crop_bottom = h->sps.crop_top = h->sps.crop_right = h->sps.crop_left = 0; | ||
| 3075 | h->sps.crop = 0; | ||
| 3076 | |||
| 3077 | width = h->width; | ||
| 3078 | height = h->height; | ||
| 3079 | } | ||
| 3080 | |||
| 3081 | h->avctx->coded_width = h->width; | ||
| 3082 | h->avctx->coded_height = h->height; | ||
| 3083 | h->avctx->width = width; | ||
| 3084 | h->avctx->height = height; | ||
| 3085 | |||
| 3086 | return 0; | ||
| 3087 | } | ||
| 3088 | |||
| 3056 | static int h264_slice_header_init(H264Context *h, int reinit) | 3089 | static int h264_slice_header_init(H264Context *h, int reinit) |
| 3057 | { | 3090 | { |
| 3058 | int nb_slices = (HAVE_THREADS && | 3091 | int nb_slices = (HAVE_THREADS && |
| 3059 | h->avctx->active_thread_type & FF_THREAD_SLICE) ? | 3092 | h->avctx->active_thread_type & FF_THREAD_SLICE) ? |
| 3060 | h->avctx->thread_count : 1; | 3093 | h->avctx->thread_count : 1; |
| 3061 | int i; | 3094 | int i, ret; |
| 3062 | |||
| 3063 | if( FFALIGN(h->avctx->width , 16 ) == h->width | ||
| 3064 | && FFALIGN(h->avctx->height, 16*(2 - h->sps.frame_mbs_only_flag)) == h->height | ||
| 3065 | && !h->sps.crop_right && !h->sps.crop_bottom | ||
| 3066 | && (h->avctx->width != h->width || h->avctx->height && h->height) | ||
| 3067 | ) { | ||
| 3068 | av_log(h->avctx, AV_LOG_DEBUG, "Using externally provided dimensions\n"); | ||
| 3069 | h->avctx->coded_width = h->width; | ||
| 3070 | h->avctx->coded_height = h->height; | ||
| 3071 | } else{ | ||
| 3072 | avcodec_set_dimensions(h->avctx, h->width, h->height); | ||
| 3073 | h->avctx->width -= (2>>CHROMA444(h))*FFMIN(h->sps.crop_right, (8<<CHROMA444(h))-1); | ||
| 3074 | h->avctx->height -= (1<<h->chroma_y_shift)*FFMIN(h->sps.crop_bottom, (16>>h->chroma_y_shift)-1) * (2 - h->sps.frame_mbs_only_flag); | ||
| 3075 | } | ||
| 3076 | 3095 | ||
| 3077 | h->avctx->sample_aspect_ratio = h->sps.sar; | 3096 | h->avctx->sample_aspect_ratio = h->sps.sar; |
| 3078 | av_assert0(h->avctx->sample_aspect_ratio.den); | 3097 | av_assert0(h->avctx->sample_aspect_ratio.den); |
| @@ -3298,6 +3317,10 @@ static int decode_slice_header(H264Context *h, H264Context *h0) · 219 unmodified lines | |||
| 3298 | h->width = 16 * h->mb_width; | 3317 | h->width = 16 * h->mb_width; |
| 3299 | h->height = 16 * h->mb_height; | 3318 | h->height = 16 * h->mb_height; |
| 3300 | 3319 | ||
| 3320 | ret = init_dimensions(h); | ||
| 3321 | if (ret < 0) | ||
| 3322 | return ret; | ||
| 3323 | |||
| 3301 | if (h->sps.video_signal_type_present_flag) { | 3324 | if (h->sps.video_signal_type_present_flag) { |
| 3302 | h->avctx->color_range = h->sps.full_range>0 ? AVCOL_RANGE_JPEG | 3325 | h->avctx->color_range = h->sps.full_range>0 ? AVCOL_RANGE_JPEG |
| 3303 | : AVCOL_RANGE_MPEG; | 3326 | : AVCOL_RANGE_MPEG; |
| @@ -3311,9 +3334,10 @@ static int decode_slice_header(H264Context *h, H264Context *h0) · 7 unmodified lines | |||
| 3311 | } | 3334 | } |
| 3312 | 3335 | ||
| 3313 | if (h->context_initialized && | 3336 | if (h->context_initialized && |
| 3314 | ( | 3337 | (h->width != h->avctx->coded_width || |
| 3315 | needs_reinit || | 3338 | h->height != h->avctx->coded_height || |
| 3316 | must_reinit)) { | 3339 | must_reinit || |
| 3340 | needs_reinit)) { | ||
| 3317 | 3341 | ||
| 3318 | if (h != h0) { | 3342 | if (h != h0) { |
| 3319 | av_log(h->avctx, AV_LOG_ERROR, "changing width/height on " | 3343 | av_log(h->avctx, AV_LOG_ERROR, "changing width/height on " |
| @@ -4817,6 +4841,26 @@ static int get_consumed_bytes(int pos, int buf_size) · 1497 unmodified lines | |||
| 4817 | return pos; | 4841 | return pos; |
| 4818 | } | 4842 | } |
| 4819 | 4843 | ||
| 4844 | static int output_frame(H264Context *h, AVFrame *dst, AVFrame *src) | ||
| 4845 | { | ||
| 4846 | int i; | ||
| 4847 | int ret = av_frame_ref(dst, src); | ||
| 4848 | if (ret < 0) | ||
| 4849 | return ret; | ||
| 4850 | |||
| 4851 | if (!h->sps.crop) | ||
| 4852 | return 0; | ||
| 4853 | |||
| 4854 | for (i = 0; i < 3; i++) { | ||
| 4855 | int hshift = (i > 0) ? h->chroma_x_shift : 0; | ||
| 4856 | int vshift = (i > 0) ? h->chroma_y_shift : 0; | ||
| 4857 | int off = ((h->sps.crop_left >> hshift) << h->pixel_shift) + | ||
| 4858 | (h->sps.crop_top >> vshift) * dst->linesize[i]; | ||
| 4859 | dst->data[i] += off; | ||
| 4860 | } | ||
| 4861 | return 0; | ||
| 4862 | } | ||
| 4863 | |||
| 4820 | static int decode_frame(AVCodecContext *avctx, void *data, | 4864 | static int decode_frame(AVCodecContext *avctx, void *data, |
| 4821 | int *got_frame, AVPacket *avpkt) | 4865 | int *got_frame, AVPacket *avpkt) |
| 4822 | { | 4866 | { |
| @@ -4856,7 +4900,8 @@ static int decode_frame(AVCodecContext *avctx, void *data, · 33 unmodified lines | |||
| 4856 | 4900 | ||
| 4857 | if (out) { | 4901 | if (out) { |
| 4858 | out->reference &= ~DELAYED_PIC_REF; | 4902 | out->reference &= ~DELAYED_PIC_REF; |
| 4859 | if ((ret = av_frame_ref(pict, &out->f)) < 0) | 4903 | ret = output_frame(h, pict, &out->f); |
| 4904 | if (ret < 0) | ||
| 4860 | return ret; | 4905 | return ret; |
| 4861 | *got_frame = 1; | 4906 | *got_frame = 1; |
| 4862 | } | 4907 | } |
| @@ -4913,7 +4958,8 @@ not_extra: · 50 unmodified lines | |||
| 4913 | /* Wait for second field. */ | 4958 | /* Wait for second field. */ |
| 4914 | *got_frame = 0; | 4959 | *got_frame = 0; |
| 4915 | if (h->next_output_pic && (h->next_output_pic->sync || h->sync>1)) { | 4960 | if (h->next_output_pic && (h->next_output_pic->sync || h->sync>1)) { |
| 4916 | if ((ret = av_frame_ref(pict, &h->next_output_pic->f)) < 0) | 4961 | ret = output_frame(h, pict, &h->next_output_pic->f); |
| 4962 | if (ret < 0) | ||
| 4917 | return ret; | 4963 | return ret; |
| 4918 | *got_frame = 1; | 4964 | *got_frame = 1; |
| 4919 | if (CONFIG_MPEGVIDEO) { | 4965 | if (CONFIG_MPEGVIDEO) { |
| @@ -168,6 +168,8 @@ typedef struct SPS { · 167 unmodified lines | |||
| 168 | int mb_aff; ///< mb_adaptive_frame_field_flag | 168 | int mb_aff; ///< mb_adaptive_frame_field_flag |
| 169 | int direct_8x8_inference_flag; | 169 | int direct_8x8_inference_flag; |
| 170 | int crop; ///< frame_cropping_flag | 170 | int crop; ///< frame_cropping_flag |
| 171 | |||
| 172 | /* those 4 are already in luma samples */ | ||
| 171 | unsigned int crop_left; ///< frame_cropping_rect_left_offset | 173 | unsigned int crop_left; ///< frame_cropping_rect_left_offset |
| 172 | unsigned int crop_right; ///< frame_cropping_rect_right_offset | 174 | unsigned int crop_right; ///< frame_cropping_rect_right_offset |
| 173 | unsigned int crop_top; ///< frame_cropping_rect_top_offset | 175 | unsigned int crop_top; ///< frame_cropping_rect_top_offset |
| @@ -276,6 +278,7 @@ typedef struct H264Context { · 102 unmodified lines | |||
| 276 | 278 | ||
| 277 | int qp_thresh; ///< QP threshold to skip loopfilter | 279 | int qp_thresh; ///< QP threshold to skip loopfilter |
| 278 | 280 | ||
| 281 | /* coded dimensions -- 16 * mb w/h */ | ||
| 279 | int width, height; | 282 | int width, height; |
| 280 | int linesize, uvlinesize; | 283 | int linesize, uvlinesize; |
| 281 | int chroma_x_shift, chroma_y_shift; | 284 | int chroma_x_shift, chroma_y_shift; |
| @@ -459,44 +459,45 @@ int ff_h264_decode_seq_parameter_set(H264Context *h){ · 458 unmodified lines | |||
| 459 | #endif | 459 | #endif |
| 460 | sps->crop= get_bits1(&h->gb); | 460 | sps->crop= get_bits1(&h->gb); |
| 461 | if(sps->crop){ | 461 | if(sps->crop){ |
| 462 | int crop_vertical_limit = sps->chroma_format_idc & 2 ? 16 : 8; | 462 | int crop_left = get_ue_golomb(&h->gb); |
| 463 | int crop_horizontal_limit = sps->chroma_format_idc == 3 ? 16 : 8; | 463 | int crop_right = get_ue_golomb(&h->gb); |
| 464 | sps->crop_left = get_ue_golomb(&h->gb); | 464 | int crop_top = get_ue_golomb(&h->gb); |
| 465 | sps->crop_right = get_ue_golomb(&h->gb); | 465 | int crop_bottom = get_ue_golomb(&h->gb); |
| 466 | sps->crop_top = get_ue_golomb(&h->gb); | 466 | |
| 467 | sps->crop_bottom= get_ue_golomb(&h->gb); | ||
| 468 | if (h->avctx->flags2 & CODEC_FLAG2_IGNORE_CROP) { | 467 | if (h->avctx->flags2 & CODEC_FLAG2_IGNORE_CROP) { |
| 469 | av_log(h->avctx, AV_LOG_DEBUG, | 468 | av_log(h->avctx, AV_LOG_DEBUG, "discarding sps cropping, original " |
| 470 | "discarding sps cropping, " | 469 | "values are l:%u r:%u t:%u b:%u\n", crop_left, crop_right, |
| 471 | "original values are l:%u r:%u t:%u b:%u\n", | 470 | crop_top, crop_bottom); |
| 472 | sps->crop_left, | ||
| 473 | sps->crop_right, | ||
| 474 | sps->crop_top, | ||
| 475 | sps->crop_bottom); | ||
| 476 | 471 | ||
| 477 | sps->crop_left = | 472 | sps->crop_left = |
| 478 | sps->crop_right = | 473 | sps->crop_right = |
| 479 | sps->crop_top = | 474 | sps->crop_top = |
| 480 | sps->crop_bottom = 0; | 475 | sps->crop_bottom = 0; |
| 481 | } | 476 | } else { |
| 482 | if(sps->crop_left || sps->crop_top){ | 477 | int vsub = (sps->chroma_format_idc == 1) ? 1 : 0; |
| 483 | av_log(h->avctx, AV_LOG_ERROR, "insane cropping not completely supported, this could look slightly wrong ... (left: %d, top: %d)\n", sps->crop_left, sps->crop_top); | 478 | int hsub = (sps->chroma_format_idc == 1 || sps->chroma_format_idc == 2) ? 1 : 0; |
| 484 | } | 479 | int step_x = 1 << hsub; |
| 485 | if(sps->crop_right >= crop_horizontal_limit || sps->crop_bottom >= crop_vertical_limit){ | 480 | int step_y = (2 - sps->frame_mbs_only_flag) << vsub; |
| 486 | av_log(h->avctx, AV_LOG_ERROR, "brainfart cropping not supported, cropping disabled (right: %d, bottom: %d)\n", sps->crop_right, sps->crop_bottom); | 481 | |
| 487 | /* It is very unlikely that partial cropping will make anybody happy. | 482 | if (crop_left & (0x1F >> (sps->bit_depth_luma > 8)) && |
| 488 | * Not cropping at all fixes for example playback of Sisvel 3D streams | 483 | !(h->avctx->flags & CODEC_FLAG_UNALIGNED)) { |
| 489 | * in applications supporting Sisvel 3D. */ | 484 | crop_left &= ~(0x1F >> (sps->bit_depth_luma > 8)); |
| 490 | sps->crop_left = | 485 | av_log(h->avctx, AV_LOG_WARNING, "Reducing left cropping to %d " |
| 491 | sps->crop_right = | 486 | "chroma samples to preserve alignment.\n", |
| 492 | sps->crop_top = | 487 | crop_left); |
| 493 | sps->crop_bottom= 0; | 488 | } |
| 489 | |||
| 490 | sps->crop_left = crop_left * step_x; | ||
| 491 | sps->crop_right = crop_right * step_x; | ||
| 492 | sps->crop_top = crop_top * step_y; | ||
| 493 | sps->crop_bottom = crop_bottom * step_y; | ||
| 494 | } | 494 | } |
| 495 | }else{ | 495 | }else{ |
| 496 | sps->crop_left = | 496 | sps->crop_left = |
| 497 | sps->crop_right = | 497 | sps->crop_right = |
| 498 | sps->crop_top = | 498 | sps->crop_top = |
| 499 | sps->crop_bottom= 0; | 499 | sps->crop_bottom= 0; |
| 500 | sps->crop = 0; | ||
| 500 | } | 501 | } |
| 501 | 502 | ||
| 502 | sps->vui_parameters_present_flag= get_bits1(&h->gb); | 503 | sps->vui_parameters_present_flag= get_bits1(&h->gb); |
| @@ -49,6 +49,7 @@ static const AVOption options[]={ · 48 unmodified lines | |||
| 49 | "to minimum/maximum bitrate. Lowering tolerance too much has an adverse effect on quality.", | 49 | "to minimum/maximum bitrate. Lowering tolerance too much has an adverse effect on quality.", |
| 50 | OFFSET(bit_rate_tolerance), AV_OPT_TYPE_INT, {.i64 = AV_CODEC_DEFAULT_BITRATE*20 }, 1, INT_MAX, V|E}, | 50 | OFFSET(bit_rate_tolerance), AV_OPT_TYPE_INT, {.i64 = AV_CODEC_DEFAULT_BITRATE*20 }, 1, INT_MAX, V|E}, |
| 51 | {"flags", NULL, OFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64 = DEFAULT }, 0, UINT_MAX, V|A|S|E|D, "flags"}, | 51 | {"flags", NULL, OFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64 = DEFAULT }, 0, UINT_MAX, V|A|S|E|D, "flags"}, |
| 52 | {"unaligned", "allow decoders to produce unaligned output", 0, AV_OPT_TYPE_CONST, { .i64 = CODEC_FLAG_UNALIGNED }, INT_MIN, INT_MAX, V | D, "flags" }, | ||
| 52 | {"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"}, | 53 | {"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"}, |
| 53 | {"qpel", "use 1/4-pel motion compensation", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_QPEL }, INT_MIN, INT_MAX, V|E, "flags"}, | 54 | {"qpel", "use 1/4-pel motion compensation", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_QPEL }, INT_MIN, INT_MAX, V|E, "flags"}, |
| 54 | {"loop", "use loop filter", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_LOOP_FILTER }, INT_MIN, INT_MAX, V|E, "flags"}, | 55 | {"loop", "use loop filter", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_LOOP_FILTER }, INT_MIN, INT_MAX, V|E, "flags"}, |
| @@ -29,7 +29,7 @@ · 28 unmodified lines | |||
| 29 | #include "libavutil/avutil.h" | 29 | #include "libavutil/avutil.h" |
| 30 | 30 | ||
| 31 | #define LIBAVCODEC_VERSION_MAJOR 55 | 31 | #define LIBAVCODEC_VERSION_MAJOR 55 |
| 32 | #define LIBAVCODEC_VERSION_MINOR 4 | 32 | #define LIBAVCODEC_VERSION_MINOR 5 |
| 33 | #define LIBAVCODEC_VERSION_MICRO 100 | 33 | #define LIBAVCODEC_VERSION_MICRO 100 |
| 34 | 34 | ||
| 35 | #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ | 35 | #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ |