diff options
author | Anton Khirnov <anton@khirnov.net> | 2013-02-18 16:32:18 +0100 |
---|---|---|
committer | Anton Khirnov <anton@khirnov.net> | 2013-04-19 09:28:08 +0200 |
commit | 5e83d9aced2fc2b2e1360452794c58aba55d497c (patch) | |
tree | 8504e1b7e82eae9ff30a42db618bbfa73610a049 /libavcodec/h264_ps.c | |
parent | a7f46586bf47174b5fa00a905b767b1781ec8b72 (diff) | |
download | ffmpeg-5e83d9aced2fc2b2e1360452794c58aba55d497c.tar.gz |
h264: fully support cropping.
Based on a patch by Vittorio Giovara <vittorio.giovara@gmail.com>
Fixes Bug 378.
Diffstat (limited to 'libavcodec/h264_ps.c')
-rw-r--r-- | libavcodec/h264_ps.c | 46 |
1 files changed, 27 insertions, 19 deletions
diff --git a/libavcodec/h264_ps.c b/libavcodec/h264_ps.c index 6c895a46ea..c6587c791b 100644 --- a/libavcodec/h264_ps.c +++ b/libavcodec/h264_ps.c @@ -413,37 +413,45 @@ int ff_h264_decode_seq_parameter_set(H264Context *h){ #endif sps->crop= get_bits1(&h->gb); if(sps->crop){ - int crop_vertical_limit = sps->chroma_format_idc & 2 ? 16 : 8; - int crop_horizontal_limit = sps->chroma_format_idc == 3 ? 16 : 8; - sps->crop_left = get_ue_golomb(&h->gb); - sps->crop_right = get_ue_golomb(&h->gb); - sps->crop_top = get_ue_golomb(&h->gb); - sps->crop_bottom= get_ue_golomb(&h->gb); + int crop_left = get_ue_golomb(&h->gb); + int crop_right = get_ue_golomb(&h->gb); + int crop_top = get_ue_golomb(&h->gb); + int crop_bottom = get_ue_golomb(&h->gb); + if (h->avctx->flags2 & CODEC_FLAG2_IGNORE_CROP) { - av_log(h->avctx, AV_LOG_DEBUG, - "discarding sps cropping, " - "original values are l:%u r:%u t:%u b:%u\n", - sps->crop_left, - sps->crop_right, - sps->crop_top, - sps->crop_bottom); + av_log(h->avctx, AV_LOG_DEBUG, "discarding sps cropping, original " + "values are l:%u r:%u t:%u b:%u\n", crop_left, crop_right, + crop_top, crop_bottom); sps->crop_left = sps->crop_right = sps->crop_top = sps->crop_bottom = 0; - } - if(sps->crop_left || sps->crop_top){ - av_log(h->avctx, AV_LOG_ERROR, "insane cropping not completely supported, this could look slightly wrong ...\n"); - } - if(sps->crop_right >= crop_horizontal_limit || sps->crop_bottom >= crop_vertical_limit){ - av_log(h->avctx, AV_LOG_ERROR, "brainfart cropping not supported, this could look slightly wrong ...\n"); + } else { + int vsub = (sps->chroma_format_idc == 1) ? 1 : 0; + int hsub = (sps->chroma_format_idc == 1 || sps->chroma_format_idc == 2) ? 1 : 0; + int step_x = 1 << hsub; + int step_y = (2 - sps->frame_mbs_only_flag) << vsub; + + if (crop_left & (0x1F >> (sps->bit_depth_luma > 8)) && + !(h->avctx->flags & CODEC_FLAG_UNALIGNED)) { + crop_left &= ~(0x1F >> (sps->bit_depth_luma > 8)); + av_log(h->avctx, AV_LOG_WARNING, "Reducing left cropping to %d " + "chroma samples to preserve alignment.\n", + crop_left); + } + + sps->crop_left = crop_left * step_x; + sps->crop_right = crop_right * step_x; + sps->crop_top = crop_top * step_y; + sps->crop_bottom = crop_bottom * step_y; } }else{ sps->crop_left = sps->crop_right = sps->crop_top = sps->crop_bottom= 0; + sps->crop = 0; } sps->vui_parameters_present_flag= get_bits1(&h->gb); |