* 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>tags/n2.3
@@ -15,6 +15,9 @@ libavutil: 2012-10-22 | |||||
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. | ||||
@@ -322,6 +322,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); | ||||
@@ -255,6 +255,8 @@ static int decode_frame(AVCodecContext *avctx, | |||||
return AVERROR_PATCHWELCOME; | return AVERROR_PATCHWELCOME; | ||||
} | } | ||||
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) | ||||
return ret; | return ret; | ||||
@@ -37,6 +37,7 @@ | |||||
#include "libavutil/avassert.h" | #include "libavutil/avassert.h" | ||||
#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" | ||||
@@ -348,17 +349,21 @@ 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 ((ret = ff_get_buffer(avctx, s->frame, 0)) < 0) | if ((ret = ff_get_buffer(avctx, s->frame, 0)) < 0) | ||||
return ret; | return ret; | ||||
s->frame->interlaced_frame = 1; | s->frame->interlaced_frame = 1; | ||||
s->frame->top_field_first = 0; | 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 ) { | 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); | s->frame->top_field_first = !(vsc_pack[3] & 0x40); | ||||
} | } | ||||
@@ -1191,8 +1191,8 @@ static int decode_header(EXRContext *s) | |||||
if (!var_size) | if (!var_size) | ||||
return AVERROR_INVALIDDATA; | 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; | continue; | ||||
} else if ((var_size = check_header_variable(s, "compression", | } else if ((var_size = check_header_variable(s, "compression", | ||||
@@ -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.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 }; | |||||
} | |||||
if (fs->version > 3) { | if (fs->version > 3) { | ||||
fs->slice_reset_contexts = get_rac(c, state); | fs->slice_reset_contexts = get_rac(c, state); | ||||
fs->slice_coding_mode = get_symbol(c, state, 0); | fs->slice_coding_mode = get_symbol(c, state, 0); | ||||
@@ -342,6 +351,7 @@ static int decode_slice_header(FFV1Context *f, FFV1Context *fs) | |||||
} | } | ||||
} | } | ||||
} | } | ||||
return 0; | return 0; | ||||
} | } | ||||
@@ -526,6 +526,8 @@ retry: | |||||
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; | ||||
} | } | ||||
@@ -1150,8 +1150,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; | |||||
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, | 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); | ||||
@@ -293,9 +293,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; | ||||
@@ -240,6 +240,12 @@ const uint8_t *avpriv_find_start_code(const uint8_t *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. | ||||
*/ | */ | ||||
@@ -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.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, | ||||
@@ -1347,6 +1347,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); | ||||
setup_hwaccel_for_pixfmt(avctx); | setup_hwaccel_for_pixfmt(avctx); | ||||
@@ -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)); | ||||
if (!s->vert_pred) | if (!s->vert_pred) | ||||
return AVERROR(ENOMEM); | return AVERROR(ENOMEM); | ||||
@@ -255,6 +255,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) | ||||
{ | { | ||||
@@ -803,6 +818,15 @@ int ff_init_buffer_info(AVCodecContext *avctx, AVFrame *frame) | |||||
frame->format = avctx->pix_fmt; | frame->format = avctx->pix_fmt; | ||||
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 }; | |||||
} | |||||
break; | break; | ||||
case AVMEDIA_TYPE_AUDIO: | case AVMEDIA_TYPE_AUDIO: | ||||
if (!frame->sample_rate) | 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); | 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)) | ||||
@@ -471,6 +471,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); | ||||
@@ -2279,6 +2279,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) | ||||
@@ -27,7 +27,9 @@ | |||||
#include "internal.h" | #include "internal.h" | ||||
#include "intreadwrite.h" | #include "intreadwrite.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) | ||||
@@ -239,6 +241,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 | ||||
@@ -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); | 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); | ||||
/** | /** | ||||
@@ -56,7 +56,7 @@ | |||||
*/ | */ | ||||
#define LIBAVUTIL_VERSION_MAJOR 52 | #define LIBAVUTIL_VERSION_MAJOR 52 | ||||
#define LIBAVUTIL_VERSION_MINOR 89 | |||||
#define LIBAVUTIL_VERSION_MINOR 90 | |||||
#define LIBAVUTIL_VERSION_MICRO 100 | #define LIBAVUTIL_VERSION_MICRO 100 | ||||
#define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ | #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ | ||||