Add av_image_check_sar() and use it to validate SAR

pull/76/merge
Justin Ruggles 11 years ago
parent d349afb07b
commit 9e500efdbe
  1. 3
      doc/APIchanges
  2. 2
      libavcodec/dirac.c
  3. 2
      libavcodec/dpx.c
  4. 17
      libavcodec/dvdec.c
  5. 4
      libavcodec/exr.c
  6. 8
      libavcodec/ffv1dec.c
  7. 2
      libavcodec/h263dec.c
  8. 3
      libavcodec/h264_slice.c
  9. 3
      libavcodec/hevc.c
  10. 6
      libavcodec/internal.h
  11. 1
      libavcodec/mjpegdec.c
  12. 2
      libavcodec/mpeg12dec.c
  13. 2
      libavcodec/truemotion1.c
  14. 33
      libavcodec/utils.c
  15. 1
      libavcodec/vc1.c
  16. 1
      libavcodec/vp3.c
  17. 23
      libavutil/imgutils.c
  18. 15
      libavutil/imgutils.h
  19. 2
      libavutil/version.h

@ -13,6 +13,9 @@ libavutil: 2013-12-xx
API changes, most recent first: 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 2014-06-xx - xxxxxxx - lavc 55.55.0 - avcodec.h
Add av_packet_rescale_ts() to simplify timestamp conversion. Add av_packet_rescale_ts() to simplify timestamp conversion.

@ -316,6 +316,8 @@ int avpriv_dirac_parse_sequence_header(AVCodecContext *avctx, GetBitContext *gb,
if (ret < 0) if (ret < 0)
return ret; return ret;
ff_set_sar(avctx, avctx->sample_aspect_ratio);
/* [DIRAC_STD] picture_coding_mode shall be 0 for fields and 1 for frames /* [DIRAC_STD] picture_coding_mode shall be 0 for fields and 1 for frames
* currently only used to signal field coding */ * currently only used to signal field coding */
picture_coding_mode = svq3_get_ue_golomb(gb); picture_coding_mode = svq3_get_ue_golomb(gb);

@ -150,6 +150,8 @@ static int decode_frame(AVCodecContext *avctx,
if ((ret = ff_set_dimensions(avctx, w, h)) < 0) if ((ret = ff_set_dimensions(avctx, w, h)) < 0)
return ret; return ret;
ff_set_sar(avctx, avctx->sample_aspect_ratio);
if ((ret = ff_get_buffer(avctx, p, 0)) < 0) { if ((ret = ff_get_buffer(avctx, p, 0)) < 0) {
av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
return ret; return ret;

@ -36,6 +36,7 @@
*/ */
#include "libavutil/internal.h" #include "libavutil/internal.h"
#include "libavutil/imgutils.h"
#include "libavutil/pixdesc.h" #include "libavutil/pixdesc.h"
#include "avcodec.h" #include "avcodec.h"
#include "internal.h" #include "internal.h"
@ -347,6 +348,14 @@ static int dvvideo_decode_frame(AVCodecContext *avctx,
if (ret < 0) if (ret < 0)
return ret; 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 (ff_get_buffer(avctx, s->frame, 0) < 0) { if (ff_get_buffer(avctx, s->frame, 0) < 0) {
av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
return -1; return -1;
@ -363,14 +372,6 @@ static int dvvideo_decode_frame(AVCodecContext *avctx,
/* return image */ /* return image */
*got_frame = 1; *got_frame = 1;
/* 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)));
avctx->sample_aspect_ratio = s->sys->sar[is16_9];
}
return s->sys->frame_size; return s->sys->frame_size;
} }

@ -1107,8 +1107,8 @@ static int decode_header(EXRContext *s)
if (!var_size) if (!var_size)
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
s->avctx->sample_aspect_ratio = ff_set_sar(s->avctx,
av_d2q(av_int2float(bytestream2_get_le32(&s->gb)), 255); av_d2q(av_int2float(bytestream2_get_le32(&s->gb)), 255));
continue; continue;
} else if ((var_size = check_header_variable(s, "compression", } else if ((var_size = check_header_variable(s, "compression",

@ -328,6 +328,14 @@ 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.num = get_symbol(c, state, 0);
f->cur->sample_aspect_ratio.den = 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 };
}
return 0; return 0;
} }

@ -497,6 +497,8 @@ int ff_h263_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
if (ret < 0) if (ret < 0)
return ret; return ret;
ff_set_sar(avctx, avctx->sample_aspect_ratio);
if ((ret = ff_MPV_common_frame_size_change(s))) if ((ret = ff_MPV_common_frame_size_change(s)))
return ret; return ret;
} }

@ -1067,8 +1067,7 @@ static int h264_slice_header_init(H264Context *h, int reinit)
h->avctx->thread_count : 1; h->avctx->thread_count : 1;
int i, ret; int i, ret;
h->avctx->sample_aspect_ratio = h->sps.sar; ff_set_sar(h->avctx, h->sps.sar);
av_assert0(h->avctx->sample_aspect_ratio.den);
av_pix_fmt_get_chroma_sub_sample(h->avctx->pix_fmt, av_pix_fmt_get_chroma_sub_sample(h->avctx->pix_fmt,
&h->chroma_x_shift, &h->chroma_y_shift); &h->chroma_x_shift, &h->chroma_y_shift);

@ -400,9 +400,10 @@ static int set_sps(HEVCContext *s, const HEVCSPS *sps)
s->avctx->width = sps->output_width; s->avctx->width = sps->output_width;
s->avctx->height = sps->output_height; s->avctx->height = sps->output_height;
s->avctx->pix_fmt = sps->pix_fmt; 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; 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) if (sps->vui.video_signal_type_present_flag)
s->avctx->color_range = sps->vui.video_full_range_flag ? AVCOL_RANGE_JPEG s->avctx->color_range = sps->vui.video_full_range_flag ? AVCOL_RANGE_JPEG
: AVCOL_RANGE_MPEG; : AVCOL_RANGE_MPEG;

@ -176,6 +176,12 @@ const uint8_t *avpriv_find_start_code(const uint8_t *restrict p,
*/ */
int ff_set_dimensions(AVCodecContext *s, int width, int height); 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. * Add or update AV_FRAME_DATA_MATRIXENCODING side data.
*/ */

@ -1222,6 +1222,7 @@ static int mjpeg_decode_app(MJpegDecodeContext *s)
s->avctx->sample_aspect_ratio.num = get_bits(&s->gb, 16); s->avctx->sample_aspect_ratio.num = get_bits(&s->gb, 16);
s->avctx->sample_aspect_ratio.den = 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) if (s->avctx->debug & FF_DEBUG_PICT_INFO)
av_log(s->avctx, AV_LOG_INFO, av_log(s->avctx, AV_LOG_INFO,

@ -1294,6 +1294,8 @@ static int mpeg_decode_postinit(AVCodecContext *avctx)
} }
} // MPEG-2 } // MPEG-2
ff_set_sar(s->avctx, s->avctx->sample_aspect_ratio);
avctx->pix_fmt = mpeg_get_pixelformat(avctx); avctx->pix_fmt = mpeg_get_pixelformat(avctx);
// until then pix_fmt may be changed right after codec init // until then pix_fmt may be changed right after codec init
#if FF_API_XVMC #if FF_API_XVMC

@ -412,6 +412,8 @@ static int truemotion1_decode_header(TrueMotion1Context *s)
if ((ret = ff_set_dimensions(s->avctx, s->w, s->h)) < 0) if ((ret = ff_set_dimensions(s->avctx, s->w, s->h)) < 0)
return ret; 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)); av_fast_malloc(&s->vert_pred, &s->vert_pred_size, s->avctx->width * sizeof(unsigned int));
} }

@ -153,6 +153,21 @@ int ff_set_dimensions(AVCodecContext *s, int width, int height)
return ret; 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, int ff_side_data_update_matrix_encoding(AVFrame *frame,
enum AVMatrixEncoding matrix_encoding) enum AVMatrixEncoding matrix_encoding)
{ {
@ -636,6 +651,14 @@ int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
if (!frame->sample_aspect_ratio.num) if (!frame->sample_aspect_ratio.num)
frame->sample_aspect_ratio = avctx->sample_aspect_ratio; 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 };
}
if ((ret = av_image_check_size(avctx->width, avctx->height, 0, avctx)) < 0) if ((ret = av_image_check_size(avctx->width, avctx->height, 0, avctx)) < 0)
return ret; return ret;
break; break;
@ -1071,6 +1094,16 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *code
ff_set_dimensions(avctx, 0, 0); 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, /* if the decoder init function was already called previously,
* free the already allocated subtitle_header before overwriting it */ * free the already allocated subtitle_header before overwriting it */
if (av_codec_is_decoder(codec)) if (av_codec_is_decoder(codec))

@ -478,6 +478,7 @@ static int decode_sequence_header_adv(VC1Context *v, GetBitContext *gb)
v->s.avctx->width * h, v->s.avctx->width * h,
1 << 30); 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", 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.num,
v->s.avctx->sample_aspect_ratio.den); v->s.avctx->sample_aspect_ratio.den);

@ -2243,6 +2243,7 @@ static int theora_decode_header(AVCodecContext *avctx, GetBitContext *gb)
av_reduce(&avctx->sample_aspect_ratio.num, av_reduce(&avctx->sample_aspect_ratio.num,
&avctx->sample_aspect_ratio.den, &avctx->sample_aspect_ratio.den,
aspect.num, aspect.den, 1 << 30); aspect.num, aspect.den, 1 << 30);
ff_set_sar(avctx, avctx->sample_aspect_ratio);
} }
if (s->theora < 0x030200) if (s->theora < 0x030200)

@ -25,7 +25,9 @@
#include "imgutils.h" #include "imgutils.h"
#include "internal.h" #include "internal.h"
#include "log.h" #include "log.h"
#include "mathematics.h"
#include "pixdesc.h" #include "pixdesc.h"
#include "rational.h"
void av_image_fill_max_pixsteps(int max_pixsteps[4], int max_pixstep_comps[4], void av_image_fill_max_pixsteps(int max_pixsteps[4], int max_pixstep_comps[4],
const AVPixFmtDescriptor *pixdesc) const AVPixFmtDescriptor *pixdesc)
@ -228,6 +230,27 @@ int av_image_check_size(unsigned int w, unsigned int h, int log_offset, void *lo
return AVERROR(EINVAL); 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, void av_image_copy_plane(uint8_t *dst, int dst_linesize,
const uint8_t *src, int src_linesize, const uint8_t *src, int src_linesize,
int bytewidth, int height) int bytewidth, int height)

@ -29,6 +29,7 @@
#include "avutil.h" #include "avutil.h"
#include "pixdesc.h" #include "pixdesc.h"
#include "rational.h"
/** /**
* Compute the max pixel step for each plane of an image with a * Compute the max pixel step for each plane of an image with a
@ -128,6 +129,20 @@ void av_image_copy(uint8_t *dst_data[4], int dst_linesizes[4],
*/ */
int av_image_check_size(unsigned int w, unsigned int h, int log_offset, void *log_ctx); 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); int avpriv_set_systematic_pal2(uint32_t pal[256], enum AVPixelFormat pix_fmt);
/** /**

@ -54,7 +54,7 @@
*/ */
#define LIBAVUTIL_VERSION_MAJOR 53 #define LIBAVUTIL_VERSION_MAJOR 53
#define LIBAVUTIL_VERSION_MINOR 16 #define LIBAVUTIL_VERSION_MINOR 17
#define LIBAVUTIL_VERSION_MICRO 0 #define LIBAVUTIL_VERSION_MICRO 0
#define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \

Loading…
Cancel
Save