History

Merge commit '5e83d9aced2fc2b2e1360452794c58aba55d497c'

* commit '5e83d9aced2fc2b2e1360452794c58aba55d497c': h264: fully support cropping. Conflicts: doc/APIchanges libavcodec/h264.c libavcodec/h264_ps.c libavcodec/options_table.h libavcodec/version.h

Michael Niedermayer committed 13 years ago

Commit f4b05cd2 parents 05b2c99 5e83d9a7 files · +109 −50Browse files

Unified · Split

7 files
  1. doc/APIchanges +3 −0
  2. libavcodec/avcodec.h +5 −0
  3. libavcodec/h264.c +69 −23
  4. libavcodec/h264.h +3 −0
  5. libavcodec/h264_ps.c +27 −26
  6. libavcodec/options_table.h +1 −0
  7. libavcodec/version.h +1 −1
doc/APIchanges+3−0
@@ -167,6 +167,9 @@ API changes, most recent first: · 166 unmodified lines
1672012-03-26 - a67d9cf - lavfi 2.66.1001672012-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
1702013-03-xx - xxxxxxx - lavc 55.2.0 - avcodec.h
171 Add CODEC_FLAG_UNALIGNED to allow decoders to produce unaligned output.
172
1702013-xx-xx - lavfi 3.8.01732013-xx-xx - lavfi 3.8.0
171 Move all content from avfiltergraph.h to avfilter.h. Deprecate174 Move all content from avfiltergraph.h to avfilter.h. Deprecate
172 avfilterhraph.h, user applications should include just avfilter.h175 avfilterhraph.h, user applications should include just avfilter.h
libavcodec/avcodec.h+5−0
@@ -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.
libavcodec/h264.c+69−23
@@ -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 */
3054static 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
3056static int h264_slice_header_init(H264Context *h, int reinit)3089static 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_JPEG3325 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
4844static 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
4820static int decode_frame(AVCodecContext *avctx, void *data,4864static 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) {
libavcodec/h264.h+3−0
@@ -168,6 +168,8 @@ typedef struct SPS { · 167 unmodified lines
168 int mb_aff; ///< mb_adaptive_frame_field_flag168 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_flag170 int crop; ///< frame_cropping_flag
171
172 /* those 4 are already in luma samples */
171 unsigned int crop_left; ///< frame_cropping_rect_left_offset173 unsigned int crop_left; ///< frame_cropping_rect_left_offset
172 unsigned int crop_right; ///< frame_cropping_rect_right_offset174 unsigned int crop_right; ///< frame_cropping_rect_right_offset
173 unsigned int crop_top; ///< frame_cropping_rect_top_offset175 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 loopfilter279 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;
libavcodec/h264_ps.c+27−26
@@ -459,44 +459,45 @@ int ff_h264_decode_seq_parameter_set(H264Context *h){ · 458 unmodified lines
459#endif459#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 streams483 !(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);
libavcodec/options_table.h+1−0
@@ -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"},
libavcodec/version.h+1−1
@@ -29,7 +29,7 @@ · 28 unmodified lines
29#include "libavutil/avutil.h"29#include "libavutil/avutil.h"
30 30
31#define LIBAVCODEC_VERSION_MAJOR 5531#define LIBAVCODEC_VERSION_MAJOR 55
32#define LIBAVCODEC_VERSION_MINOR 432#define LIBAVCODEC_VERSION_MINOR 5
33#define LIBAVCODEC_VERSION_MICRO 10033#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, \

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t