diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2014-06-20 22:20:28 +0200 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2014-06-20 22:20:28 +0200 |
commit | 0dceefc5fa81a6c851b51acab695a8c149ec8e3b (patch) | |
tree | d26bf3f752e6fa622d14f44e091930004b2d12de | |
parent | 329898aa45f5f8e8b89386ecd40b8db96746d53c (diff) | |
parent | 9e500efdbe0deeff1602500ebc229a0a6b6bb1a2 (diff) | |
download | ffmpeg-0dceefc5fa81a6c851b51acab695a8c149ec8e3b.tar.gz |
Merge commit '9e500efdbe0deeff1602500ebc229a0a6b6bb1a2'
* commit '9e500efdbe0deeff1602500ebc229a0a6b6bb1a2':
Add av_image_check_sar() and use it to validate SAR
Conflicts:
libavcodec/dpx.c
libavcodec/dvdec.c
libavcodec/ffv1dec.c
libavcodec/utils.c
libavutil/version.h
Merged-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r-- | doc/APIchanges | 3 | ||||
-rw-r--r-- | libavcodec/dirac.c | 2 | ||||
-rw-r--r-- | libavcodec/dpx.c | 2 | ||||
-rw-r--r-- | libavcodec/dvdec.c | 15 | ||||
-rw-r--r-- | libavcodec/exr.c | 4 | ||||
-rw-r--r-- | libavcodec/ffv1dec.c | 10 | ||||
-rw-r--r-- | libavcodec/h263dec.c | 2 | ||||
-rw-r--r-- | libavcodec/h264_slice.c | 3 | ||||
-rw-r--r-- | libavcodec/hevc.c | 3 | ||||
-rw-r--r-- | libavcodec/internal.h | 6 | ||||
-rw-r--r-- | libavcodec/mjpegdec.c | 1 | ||||
-rw-r--r-- | libavcodec/mpeg12dec.c | 2 | ||||
-rw-r--r-- | libavcodec/truemotion1.c | 2 | ||||
-rw-r--r-- | libavcodec/utils.c | 34 | ||||
-rw-r--r-- | libavcodec/vc1.c | 1 | ||||
-rw-r--r-- | libavcodec/vp3.c | 1 | ||||
-rw-r--r-- | libavutil/imgutils.c | 23 | ||||
-rw-r--r-- | libavutil/imgutils.h | 15 | ||||
-rw-r--r-- | libavutil/version.h | 2 |
19 files changed, 120 insertions, 11 deletions
diff --git a/doc/APIchanges b/doc/APIchanges index ed9820b55c..3e594eeaa9 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -15,6 +15,9 @@ libavutil: 2012-10-22 API changes, most recent first: +2014-06-xx - xxxxxxx - lavu 53.17.0 - imgutils.h + Add av_image_check_sar(). + 2014-06-xx - xxxxxxx - lavc 55.55.0 - avcodec.h Add av_packet_rescale_ts() to simplify timestamp conversion. diff --git a/libavcodec/dirac.c b/libavcodec/dirac.c index 3dad75a30c..55553d67ee 100644 --- a/libavcodec/dirac.c +++ b/libavcodec/dirac.c @@ -322,6 +322,8 @@ int avpriv_dirac_parse_sequence_header(AVCodecContext *avctx, GetBitContext *gb, if (ret < 0) return ret; + ff_set_sar(avctx, avctx->sample_aspect_ratio); + /* [DIRAC_STD] picture_coding_mode shall be 0 for fields and 1 for frames * currently only used to signal field coding */ picture_coding_mode = svq3_get_ue_golomb(gb); diff --git a/libavcodec/dpx.c b/libavcodec/dpx.c index a21362eb11..5f05cd81be 100644 --- a/libavcodec/dpx.c +++ b/libavcodec/dpx.c @@ -255,6 +255,8 @@ static int decode_frame(AVCodecContext *avctx, return AVERROR_PATCHWELCOME; } + ff_set_sar(avctx, avctx->sample_aspect_ratio); + if ((ret = ff_get_buffer(avctx, p, 0)) < 0) return ret; diff --git a/libavcodec/dvdec.c b/libavcodec/dvdec.c index e555f31edf..d7aaa5f0f2 100644 --- a/libavcodec/dvdec.c +++ b/libavcodec/dvdec.c @@ -37,6 +37,7 @@ #include "libavutil/avassert.h" #include "libavutil/internal.h" +#include "libavutil/imgutils.h" #include "libavutil/pixdesc.h" #include "avcodec.h" #include "internal.h" @@ -348,17 +349,21 @@ static int dvvideo_decode_frame(AVCodecContext *avctx, if (ret < 0) return ret; + /* Determine the codec's sample_aspect ratio from the packet */ + vsc_pack = buf + 80*5 + 48 + 5; + if ( *vsc_pack == dv_video_control ) { + apt = buf[4] & 0x07; + is16_9 = (vsc_pack && ((vsc_pack[2] & 0x07) == 0x02 || (!apt && (vsc_pack[2] & 0x07) == 0x07))); + ff_set_sar(avctx, s->sys->sar[is16_9]); + } + if ((ret = ff_get_buffer(avctx, s->frame, 0)) < 0) return ret; s->frame->interlaced_frame = 1; s->frame->top_field_first = 0; - /* Determine the codec's sample_aspect ratio and field order from the packet */ - vsc_pack = buf + 80*5 + 48 + 5; + /* Determine the codec's field order from the packet */ if ( *vsc_pack == dv_video_control ) { - apt = buf[4] & 0x07; - is16_9 = (vsc_pack[2] & 0x07) == 0x02 || (!apt && (vsc_pack[2] & 0x07) == 0x07); - avctx->sample_aspect_ratio = s->sys->sar[is16_9]; s->frame->top_field_first = !(vsc_pack[3] & 0x40); } diff --git a/libavcodec/exr.c b/libavcodec/exr.c index 6ade66cb39..62e8521adc 100644 --- a/libavcodec/exr.c +++ b/libavcodec/exr.c @@ -1191,8 +1191,8 @@ static int decode_header(EXRContext *s) if (!var_size) return AVERROR_INVALIDDATA; - s->avctx->sample_aspect_ratio = - av_d2q(av_int2float(bytestream2_get_le32(&s->gb)), 255); + ff_set_sar(s->avctx, + av_d2q(av_int2float(bytestream2_get_le32(&s->gb)), 255)); continue; } else if ((var_size = check_header_variable(s, "compression", diff --git a/libavcodec/ffv1dec.c b/libavcodec/ffv1dec.c index a0a50abed4..b10e212ce5 100644 --- a/libavcodec/ffv1dec.c +++ b/libavcodec/ffv1dec.c @@ -330,6 +330,15 @@ static int decode_slice_header(FFV1Context *f, FFV1Context *fs) } f->cur->sample_aspect_ratio.num = get_symbol(c, state, 0); f->cur->sample_aspect_ratio.den = get_symbol(c, state, 0); + + if (av_image_check_sar(f->width, f->height, + f->cur->sample_aspect_ratio) < 0) { + av_log(f->avctx, AV_LOG_WARNING, "ignoring invalid SAR: %u/%u\n", + f->cur->sample_aspect_ratio.num, + f->cur->sample_aspect_ratio.den); + f->cur->sample_aspect_ratio = (AVRational){ 0, 1 }; + } + if (fs->version > 3) { fs->slice_reset_contexts = get_rac(c, state); fs->slice_coding_mode = get_symbol(c, state, 0); @@ -342,6 +351,7 @@ static int decode_slice_header(FFV1Context *f, FFV1Context *fs) } } } + return 0; } diff --git a/libavcodec/h263dec.c b/libavcodec/h263dec.c index 5186042ab0..7266cc7a37 100644 --- a/libavcodec/h263dec.c +++ b/libavcodec/h263dec.c @@ -526,6 +526,8 @@ retry: if (ret < 0) return ret; + ff_set_sar(avctx, avctx->sample_aspect_ratio); + if ((ret = ff_MPV_common_frame_size_change(s))) return ret; } diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c index e6645e8dc9..ded26f8465 100644 --- a/libavcodec/h264_slice.c +++ b/libavcodec/h264_slice.c @@ -1150,8 +1150,7 @@ static int h264_slice_header_init(H264Context *h, int reinit) h->avctx->thread_count : 1; int i, ret; - h->avctx->sample_aspect_ratio = h->sps.sar; - av_assert0(h->avctx->sample_aspect_ratio.den); + ff_set_sar(h->avctx, h->sps.sar); av_pix_fmt_get_chroma_sub_sample(h->avctx->pix_fmt, &h->chroma_x_shift, &h->chroma_y_shift); diff --git a/libavcodec/hevc.c b/libavcodec/hevc.c index b14ed117b9..b687b1fb52 100644 --- a/libavcodec/hevc.c +++ b/libavcodec/hevc.c @@ -293,9 +293,10 @@ static int set_sps(HEVCContext *s, const HEVCSPS *sps) s->avctx->width = sps->output_width; s->avctx->height = sps->output_height; s->avctx->pix_fmt = sps->pix_fmt; - s->avctx->sample_aspect_ratio = sps->vui.sar; s->avctx->has_b_frames = sps->temporal_layer[sps->max_sub_layers - 1].num_reorder_pics; + ff_set_sar(s->avctx, sps->vui.sar); + if (sps->vui.video_signal_type_present_flag) s->avctx->color_range = sps->vui.video_full_range_flag ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG; diff --git a/libavcodec/internal.h b/libavcodec/internal.h index 9afbba7b44..e00aad9431 100644 --- a/libavcodec/internal.h +++ b/libavcodec/internal.h @@ -241,6 +241,12 @@ const uint8_t *avpriv_find_start_code(const uint8_t *p, int ff_set_dimensions(AVCodecContext *s, int width, int height); /** + * Check that the provided sample aspect ratio is valid and set it on the codec + * context. + */ +int ff_set_sar(AVCodecContext *avctx, AVRational sar); + +/** * Add or update AV_FRAME_DATA_MATRIXENCODING side data. */ int ff_side_data_update_matrix_encoding(AVFrame *frame, diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c index 6909a1af06..c5ebb7705d 100644 --- a/libavcodec/mjpegdec.c +++ b/libavcodec/mjpegdec.c @@ -1551,6 +1551,7 @@ static int mjpeg_decode_app(MJpegDecodeContext *s) s->avctx->sample_aspect_ratio.num = get_bits(&s->gb, 16); s->avctx->sample_aspect_ratio.den = get_bits(&s->gb, 16); + ff_set_sar(s->avctx, s->avctx->sample_aspect_ratio); if (s->avctx->debug & FF_DEBUG_PICT_INFO) av_log(s->avctx, AV_LOG_INFO, diff --git a/libavcodec/mpeg12dec.c b/libavcodec/mpeg12dec.c index e353e56bf1..0e8bcb02ec 100644 --- a/libavcodec/mpeg12dec.c +++ b/libavcodec/mpeg12dec.c @@ -1347,6 +1347,8 @@ static int mpeg_decode_postinit(AVCodecContext *avctx) } } // MPEG-2 + ff_set_sar(s->avctx, s->avctx->sample_aspect_ratio); + avctx->pix_fmt = mpeg_get_pixelformat(avctx); setup_hwaccel_for_pixfmt(avctx); diff --git a/libavcodec/truemotion1.c b/libavcodec/truemotion1.c index ed79959240..660ecf5413 100644 --- a/libavcodec/truemotion1.c +++ b/libavcodec/truemotion1.c @@ -412,6 +412,8 @@ static int truemotion1_decode_header(TrueMotion1Context *s) if ((ret = ff_set_dimensions(s->avctx, s->w, s->h)) < 0) return ret; + ff_set_sar(s->avctx, s->avctx->sample_aspect_ratio); + av_fast_malloc(&s->vert_pred, &s->vert_pred_size, s->avctx->width * sizeof(unsigned int)); if (!s->vert_pred) return AVERROR(ENOMEM); diff --git a/libavcodec/utils.c b/libavcodec/utils.c index f06d1a62cd..9005f27bde 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -255,6 +255,21 @@ int ff_set_dimensions(AVCodecContext *s, int width, int height) return ret; } +int ff_set_sar(AVCodecContext *avctx, AVRational sar) +{ + int ret = av_image_check_sar(avctx->width, avctx->height, sar); + + if (ret < 0) { + av_log(avctx, AV_LOG_WARNING, "ignoring invalid SAR: %u/%u\n", + sar.num, sar.den); + avctx->sample_aspect_ratio = (AVRational){ 0, 1 }; + return ret; + } else { + avctx->sample_aspect_ratio = sar; + } + return 0; +} + int ff_side_data_update_matrix_encoding(AVFrame *frame, enum AVMatrixEncoding matrix_encoding) { @@ -803,6 +818,15 @@ int ff_init_buffer_info(AVCodecContext *avctx, AVFrame *frame) frame->format = avctx->pix_fmt; if (!frame->sample_aspect_ratio.num) frame->sample_aspect_ratio = avctx->sample_aspect_ratio; + + if (av_image_check_sar(frame->width, frame->height, + frame->sample_aspect_ratio) < 0) { + av_log(avctx, AV_LOG_WARNING, "ignoring invalid SAR: %u/%u\n", + frame->sample_aspect_ratio.num, + frame->sample_aspect_ratio.den); + frame->sample_aspect_ratio = (AVRational){ 0, 1 }; + } + break; case AVMEDIA_TYPE_AUDIO: if (!frame->sample_rate) @@ -1365,6 +1389,16 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *code ff_set_dimensions(avctx, 0, 0); } + if (avctx->width > 0 && avctx->height > 0) { + if (av_image_check_sar(avctx->width, avctx->height, + avctx->sample_aspect_ratio) < 0) { + av_log(avctx, AV_LOG_WARNING, "ignoring invalid SAR: %u/%u\n", + avctx->sample_aspect_ratio.num, + avctx->sample_aspect_ratio.den); + avctx->sample_aspect_ratio = (AVRational){ 0, 1 }; + } + } + /* if the decoder init function was already called previously, * free the already allocated subtitle_header before overwriting it */ if (av_codec_is_decoder(codec)) diff --git a/libavcodec/vc1.c b/libavcodec/vc1.c index c7f3561cbc..d23efecc16 100644 --- a/libavcodec/vc1.c +++ b/libavcodec/vc1.c @@ -471,6 +471,7 @@ static int decode_sequence_header_adv(VC1Context *v, GetBitContext *gb) v->s.avctx->width * h, 1 << 30); } + ff_set_sar(v->s.avctx, v->s.avctx->sample_aspect_ratio); av_log(v->s.avctx, AV_LOG_DEBUG, "Aspect: %i:%i\n", v->s.avctx->sample_aspect_ratio.num, v->s.avctx->sample_aspect_ratio.den); diff --git a/libavcodec/vp3.c b/libavcodec/vp3.c index 354be087ba..1df168bd50 100644 --- a/libavcodec/vp3.c +++ b/libavcodec/vp3.c @@ -2279,6 +2279,7 @@ static int theora_decode_header(AVCodecContext *avctx, GetBitContext *gb) av_reduce(&avctx->sample_aspect_ratio.num, &avctx->sample_aspect_ratio.den, aspect.num, aspect.den, 1 << 30); + ff_set_sar(avctx, avctx->sample_aspect_ratio); } if (s->theora < 0x030200) diff --git a/libavutil/imgutils.c b/libavutil/imgutils.c index 274099b75f..00b203182b 100644 --- a/libavutil/imgutils.c +++ b/libavutil/imgutils.c @@ -27,7 +27,9 @@ #include "internal.h" #include "intreadwrite.h" #include "log.h" +#include "mathematics.h" #include "pixdesc.h" +#include "rational.h" void av_image_fill_max_pixsteps(int max_pixsteps[4], int max_pixstep_comps[4], const AVPixFmtDescriptor *pixdesc) @@ -239,6 +241,27 @@ int av_image_check_size(unsigned int w, unsigned int h, int log_offset, void *lo return AVERROR(EINVAL); } +int av_image_check_sar(unsigned int w, unsigned int h, AVRational sar) +{ + int64_t scaled_dim; + + if (!sar.den) + return AVERROR(EINVAL); + + if (!sar.num || sar.num == sar.den) + return 0; + + if (sar.num < sar.den) + scaled_dim = av_rescale_rnd(w, sar.num, sar.den, AV_ROUND_ZERO); + else + scaled_dim = av_rescale_rnd(h, sar.den, sar.num, AV_ROUND_ZERO); + + if (scaled_dim > 0) + return 0; + + return AVERROR(EINVAL); +} + void av_image_copy_plane(uint8_t *dst, int dst_linesize, const uint8_t *src, int src_linesize, int bytewidth, int height) diff --git a/libavutil/imgutils.h b/libavutil/imgutils.h index ab32d667d3..775baaa3b7 100644 --- a/libavutil/imgutils.h +++ b/libavutil/imgutils.h @@ -29,6 +29,7 @@ #include "avutil.h" #include "pixdesc.h" +#include "rational.h" /** * Compute the max pixel step for each plane of an image with a @@ -190,6 +191,20 @@ int av_image_copy_to_buffer(uint8_t *dst, int dst_size, */ int av_image_check_size(unsigned int w, unsigned int h, int log_offset, void *log_ctx); +/** + * Check if the given sample aspect ratio of an image is valid. + * + * It is considered invalid if the denominator is 0 or if applying the ratio + * to the image size would make the smaller dimension less than 1. If the + * sar numerator is 0, it is considered unknown and will return as valid. + * + * @param w width of the image + * @param h height of the image + * @param sar sample aspect ratio of the image + * @return 0 if valid, a negative AVERROR code otherwise + */ +int av_image_check_sar(unsigned int w, unsigned int h, AVRational sar); + int avpriv_set_systematic_pal2(uint32_t pal[256], enum AVPixelFormat pix_fmt); /** diff --git a/libavutil/version.h b/libavutil/version.h index 1b6053cfaf..b5dfc97f7b 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -56,7 +56,7 @@ */ #define LIBAVUTIL_VERSION_MAJOR 52 -#define LIBAVUTIL_VERSION_MINOR 89 +#define LIBAVUTIL_VERSION_MINOR 90 #define LIBAVUTIL_VERSION_MICRO 100 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ |