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
167167 2012-03-26 - a67d9cf - lavfi 2.66.100
168168 Add avfilter_fill_frame_from_{audio_,}buffer_ref() functions.
169169
170+2013-03-xx - xxxxxxx - lavc 55.2.0 - avcodec.h
171+ Add CODEC_FLAG_UNALIGNED to allow decoders to produce unaligned output.
172+
170173 2013-xx-xx - lavfi 3.8.0
171174 Move all content from avfiltergraph.h to avfilter.h. Deprecate
172175 avfilterhraph.h, user applications should include just avfilter.h
libavcodec/avcodec.h+5−0
@@ -685,6 +685,11 @@ typedef struct RcOverride{ · 684 unmodified lines
685685 Note: Not everything is supported yet.
686686 */
687687
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
688693 #define CODEC_FLAG_QSCALE 0x0002 ///< Use fixed qscale.
689694 #define CODEC_FLAG_4MV 0x0004 ///< 4 MV per MB allowed / advanced prediction for H.263.
690695 #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
14591459
14601460 h->avctx = avctx;
14611461
1462− h->width = h->avctx->width;
1463− h->height = h->avctx->height;
1464−
14651462 h->bit_depth_luma = 8;
14661463 h->chroma_format_idc = 1;
14671464
@@ -3053,26 +3050,48 @@ static enum AVPixelFormat get_pixel_format(H264Context *h, int force_callback) · 1585 unmodified lines
30533050 }
30543051 }
30553052
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+
30563089 static int h264_slice_header_init(H264Context *h, int reinit)
30573090 {
30583091 int nb_slices = (HAVE_THREADS &&
30593092 h->avctx->active_thread_type & FF_THREAD_SLICE) ?
30603093 h->avctx->thread_count : 1;
3061− int i;
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− }
3094+ int i, ret;
30763095
30773096 h->avctx->sample_aspect_ratio = h->sps.sar;
30783097 av_assert0(h->avctx->sample_aspect_ratio.den);
@@ -3298,6 +3317,10 @@ static int decode_slice_header(H264Context *h, H264Context *h0) · 219 unmodified lines
32983317 h->width = 16 * h->mb_width;
32993318 h->height = 16 * h->mb_height;
33003319
3320+ ret = init_dimensions(h);
3321+ if (ret < 0)
3322+ return ret;
3323+
33013324 if (h->sps.video_signal_type_present_flag) {
33023325 h->avctx->color_range = h->sps.full_range>0 ? AVCOL_RANGE_JPEG
33033326 : AVCOL_RANGE_MPEG;
@@ -3311,9 +3334,10 @@ static int decode_slice_header(H264Context *h, H264Context *h0) · 7 unmodified lines
33113334 }
33123335
33133336 if (h->context_initialized &&
3314− (
3315− needs_reinit ||
3316− must_reinit)) {
3337+ (h->width != h->avctx->coded_width ||
3338+ h->height != h->avctx->coded_height ||
3339+ must_reinit ||
3340+ needs_reinit)) {
33173341
33183342 if (h != h0) {
33193343 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
48174841 return pos;
48184842 }
48194843
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+
48204864 static int decode_frame(AVCodecContext *avctx, void *data,
48214865 int *got_frame, AVPacket *avpkt)
48224866 {
@@ -4856,7 +4900,8 @@ static int decode_frame(AVCodecContext *avctx, void *data, · 33 unmodified lines
48564900
48574901 if (out) {
48584902 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)
48604905 return ret;
48614906 *got_frame = 1;
48624907 }
@@ -4913,7 +4958,8 @@ not_extra: · 50 unmodified lines
49134958 /* Wait for second field. */
49144959 *got_frame = 0;
49154960 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)
49174963 return ret;
49184964 *got_frame = 1;
49194965 if (CONFIG_MPEGVIDEO) {
libavcodec/h264.h+3−0
@@ -168,6 +168,8 @@ typedef struct SPS { · 167 unmodified lines
168168 int mb_aff; ///< mb_adaptive_frame_field_flag
169169 int direct_8x8_inference_flag;
170170 int crop; ///< frame_cropping_flag
171+
172+ /* those 4 are already in luma samples */
171173 unsigned int crop_left; ///< frame_cropping_rect_left_offset
172174 unsigned int crop_right; ///< frame_cropping_rect_right_offset
173175 unsigned int crop_top; ///< frame_cropping_rect_top_offset
@@ -276,6 +278,7 @@ typedef struct H264Context { · 102 unmodified lines
276278
277279 int qp_thresh; ///< QP threshold to skip loopfilter
278280
281+ /* coded dimensions -- 16 * mb w/h */
279282 int width, height;
280283 int linesize, uvlinesize;
281284 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
459459 #endif
460460 sps->crop= get_bits1(&h->gb);
461461 if(sps->crop){
462− int crop_vertical_limit = sps->chroma_format_idc & 2 ? 16 : 8;
463− int crop_horizontal_limit = sps->chroma_format_idc == 3 ? 16 : 8;
464− sps->crop_left = get_ue_golomb(&h->gb);
465− sps->crop_right = get_ue_golomb(&h->gb);
466− sps->crop_top = get_ue_golomb(&h->gb);
467− sps->crop_bottom= get_ue_golomb(&h->gb);
462+ int crop_left = get_ue_golomb(&h->gb);
463+ int crop_right = get_ue_golomb(&h->gb);
464+ int crop_top = get_ue_golomb(&h->gb);
465+ int crop_bottom = get_ue_golomb(&h->gb);
466+
468467 if (h->avctx->flags2 & CODEC_FLAG2_IGNORE_CROP) {
469− av_log(h->avctx, AV_LOG_DEBUG,
470− "discarding sps cropping, "
471− "original values are l:%u r:%u t:%u b:%u\n",
472− sps->crop_left,
473− sps->crop_right,
474− sps->crop_top,
475− sps->crop_bottom);
468+ av_log(h->avctx, AV_LOG_DEBUG, "discarding sps cropping, original "
469+ "values are l:%u r:%u t:%u b:%u\n", crop_left, crop_right,
470+ crop_top, crop_bottom);
476471
477472 sps->crop_left =
478473 sps->crop_right =
479474 sps->crop_top =
480475 sps->crop_bottom = 0;
481− }
482− if(sps->crop_left || sps->crop_top){
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);
484− }
485− if(sps->crop_right >= crop_horizontal_limit || sps->crop_bottom >= crop_vertical_limit){
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);
487− /* It is very unlikely that partial cropping will make anybody happy.
488− * Not cropping at all fixes for example playback of Sisvel 3D streams
489− * in applications supporting Sisvel 3D. */
490− sps->crop_left =
491− sps->crop_right =
492− sps->crop_top =
493− sps->crop_bottom= 0;
476+ } else {
477+ int vsub = (sps->chroma_format_idc == 1) ? 1 : 0;
478+ int hsub = (sps->chroma_format_idc == 1 || sps->chroma_format_idc == 2) ? 1 : 0;
479+ int step_x = 1 << hsub;
480+ int step_y = (2 - sps->frame_mbs_only_flag) << vsub;
481+
482+ if (crop_left & (0x1F >> (sps->bit_depth_luma > 8)) &&
483+ !(h->avctx->flags & CODEC_FLAG_UNALIGNED)) {
484+ crop_left &= ~(0x1F >> (sps->bit_depth_luma > 8));
485+ av_log(h->avctx, AV_LOG_WARNING, "Reducing left cropping to %d "
486+ "chroma samples to preserve alignment.\n",
487+ crop_left);
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;
494494 }
495495 }else{
496496 sps->crop_left =
497497 sps->crop_right =
498498 sps->crop_top =
499499 sps->crop_bottom= 0;
500+ sps->crop = 0;
500501 }
501502
502503 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
4949 "to minimum/maximum bitrate. Lowering tolerance too much has an adverse effect on quality.",
5050 OFFSET(bit_rate_tolerance), AV_OPT_TYPE_INT, {.i64 = AV_CODEC_DEFAULT_BITRATE*20 }, 1, INT_MAX, V|E},
5151 {"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" },
5253 {"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"},
5354 {"qpel", "use 1/4-pel motion compensation", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_QPEL }, INT_MIN, INT_MAX, V|E, "flags"},
5455 {"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
2929 #include "libavutil/avutil.h"
3030
3131 #define LIBAVCODEC_VERSION_MAJOR 55
32−#define LIBAVCODEC_VERSION_MINOR 4
32+#define LIBAVCODEC_VERSION_MINOR 5
3333 #define LIBAVCODEC_VERSION_MICRO 100
3434
3535 #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