[SCM] libav/experimental: Imported Upstream version 9.5
siretart at users.alioth.debian.org
siretart at users.alioth.debian.org
Mon May 27 20:38:49 UTC 2013
The following commit has been merged in the experimental branch:
commit 58df3eb21f8fb5cf3aebe6b544eeac8e8339e8b4
Author: Reinhard Tartler <siretart at tauware.de>
Date: Thu Apr 25 22:30:11 2013 +0200
Imported Upstream version 9.5
diff --git a/Changelog b/Changelog
index b7f7e94..ca9db5a 100644
--- a/Changelog
+++ b/Changelog
@@ -1,6 +1,36 @@
Entries are sorted chronologically from oldest to youngest within each release,
releases are sorted from youngest to oldest.
+version 9.5:
+
+Most of the following fixes resulted from test samples that the Google
+Security Team has kindly made available to us:
+
+- af_channelmap: sanity check input channel indices in all cases
+- avfiltergraph: check for sws opts being non-NULL before using them
+- bmv: check for len being valid in bmv_decode_frame()
+- configure: Enable hwaccels without external dependencies by default
+- dfa: check for invalid access in decode_wdlt()
+- id3v2: pad the APIC packets as required by lavc
+- indeo3: check motion vectors
+- indeo3: fix data size check
+- indeo3: switch parsing the header to bytestream2
+- lavf: make sure stream probe data gets freed
+- matroska: Update the available size after lace parsing
+- matroska: fix a corner case in ebml-lace parsing
+- matroska: pass the lace size to the matroska_parse_rm_audio
+- mp3dec: fallback to generic seeking when a TOC is not present
+- oggdec: fix faulty cleanup prototype
+- oma: Validate sample rates
+- qdm2: check that the FFT size is a power of 2
+- riff: check for eof if chunk size and code are 0 to prevent an infinite loop
+- rv10: check that extradata is large enough
+- svq1dec: check that the reference frame has the same dimensions as the current one
+- svq1dec: clip motion vectors to the frame size
+- xmv: check audio track parameters validity
+- xmv: do not leak memory in the error paths in xmv_read_header()
+
+
version 9.4:
- atrac3: avoid oversized shifting in decode_bytes()
- eamad: allocate a dummy reference frame when the real one is missing
diff --git a/RELEASE b/RELEASE
index 0359f24..592f36e 100644
--- a/RELEASE
+++ b/RELEASE
@@ -1 +1 @@
-9.4
+9.5
diff --git a/VERSION b/VERSION
index 0359f24..592f36e 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-9.4
+9.5
diff --git a/configure b/configure
index aa31ea0..6ab04ae 100755
--- a/configure
+++ b/configure
@@ -1604,25 +1604,26 @@ zmbv_decoder_select="zlib"
zmbv_encoder_select="zlib"
# hardware accelerators
+dxva2_deps="dxva2api_h"
vaapi_deps="va_va_h"
vda_deps="VideoDecodeAcceleration_VDADecoder_h pthreads"
vdpau_deps="vdpau_vdpau_h vdpau_vdpau_x11_h"
h263_vaapi_hwaccel_select="vaapi h263_decoder"
-h264_dxva2_hwaccel_deps="dxva2api_h"
-h264_dxva2_hwaccel_select="dxva2 h264_decoder"
+h264_dxva2_hwaccel_deps="dxva2"
+h264_dxva2_hwaccel_select="h264_decoder"
h264_vaapi_hwaccel_select="vaapi h264_decoder"
h264_vda_hwaccel_select="vda h264_decoder"
h264_vdpau_decoder_select="vdpau h264_decoder"
mpeg_vdpau_decoder_select="vdpau mpegvideo_decoder"
mpeg1_vdpau_decoder_select="vdpau mpeg1video_decoder"
-mpeg2_dxva2_hwaccel_deps="dxva2api_h"
-mpeg2_dxva2_hwaccel_select="dxva2 mpeg2video_decoder"
+mpeg2_dxva2_hwaccel_deps="dxva2"
+mpeg2_dxva2_hwaccel_select="mpeg2video_decoder"
mpeg2_vaapi_hwaccel_select="vaapi mpeg2video_decoder"
mpeg4_vaapi_hwaccel_select="vaapi mpeg4_decoder"
mpeg4_vdpau_decoder_select="vdpau mpeg4_decoder"
-vc1_dxva2_hwaccel_deps="dxva2api_h"
-vc1_dxva2_hwaccel_select="dxva2 vc1_decoder"
+vc1_dxva2_hwaccel_deps="dxva2"
+vc1_dxva2_hwaccel_select="vc1_decoder"
vc1_vaapi_hwaccel_select="vaapi vc1_decoder"
vc1_vdpau_decoder_select="vdpau vc1_decoder"
wmv3_dxva2_hwaccel_select="vc1_dxva2_hwaccel"
@@ -1844,6 +1845,9 @@ enable safe_bitstream_reader
enable static
enable swscale_alpha
+# By default, enable only those hwaccels that have no external dependencies.
+enable dxva2 vdpau
+
# build settings
SHFLAGS='-shared -Wl,-soname,$$(@F)'
AVSERVERLDFLAGS=-Wl,-E
diff --git a/libavcodec/bmv.c b/libavcodec/bmv.c
index a7f21ec..bcb1380 100644
--- a/libavcodec/bmv.c
+++ b/libavcodec/bmv.c
@@ -136,7 +136,7 @@ static int decode_bmv_frame(const uint8_t *source, int src_len, uint8_t *frame,
mode += 1 + advance_mode;
if (mode >= 4)
mode -= 3;
- if (FFABS(dst_end - dst) < len)
+ if (len <= 0 || FFABS(dst_end - dst) < len)
return -1;
switch (mode) {
case 1:
diff --git a/libavcodec/dfa.c b/libavcodec/dfa.c
index 119be70..332a53e 100644
--- a/libavcodec/dfa.c
+++ b/libavcodec/dfa.c
@@ -257,6 +257,8 @@ static int decode_wdlt(GetByteContext *gb, uint8_t *frame, int width, int height
segments = bytestream2_get_le16(gb);
}
line_ptr = frame;
+ if (frame_end - frame < width)
+ return AVERROR_INVALIDDATA;
frame += width;
y++;
while (segments--) {
diff --git a/libavcodec/indeo3.c b/libavcodec/indeo3.c
index 261c651..eacd150 100644
--- a/libavcodec/indeo3.c
+++ b/libavcodec/indeo3.c
@@ -223,7 +223,7 @@ static av_cold void free_frame_buffers(Indeo3DecodeContext *ctx)
* @param plane pointer to the plane descriptor
* @param cell pointer to the cell descriptor
*/
-static void copy_cell(Indeo3DecodeContext *ctx, Plane *plane, Cell *cell)
+static int copy_cell(Indeo3DecodeContext *ctx, Plane *plane, Cell *cell)
{
int h, w, mv_x, mv_y, offset, offset_dst;
uint8_t *src, *dst;
@@ -233,6 +233,16 @@ static void copy_cell(Indeo3DecodeContext *ctx, Plane *plane, Cell *cell)
dst = plane->pixels[ctx->buf_sel] + offset_dst;
mv_y = cell->mv_ptr[0];
mv_x = cell->mv_ptr[1];
+
+ /* -1 because there is an extra line on top for prediction */
+ if ((cell->ypos << 2) + mv_y < -1 || (cell->xpos << 2) + mv_x < 0 ||
+ ((cell->ypos + cell->height) << 2) + mv_y >= plane->height ||
+ ((cell->xpos + cell->width) << 2) + mv_x >= plane->width) {
+ av_log(ctx->avctx, AV_LOG_ERROR,
+ "Motion vectors point out of the frame.\n");
+ return AVERROR_INVALIDDATA;
+ }
+
offset = offset_dst + mv_y * plane->pitch + mv_x;
src = plane->pixels[ctx->buf_sel ^ 1] + offset;
@@ -260,6 +270,8 @@ static void copy_cell(Indeo3DecodeContext *ctx, Plane *plane, Cell *cell)
dst += 4;
}
}
+
+ return 0;
}
@@ -585,11 +597,23 @@ static int decode_cell(Indeo3DecodeContext *ctx, AVCodecContext *avctx,
} else if (mode >= 10) {
/* for mode 10 and 11 INTER first copy the predicted cell into the current one */
/* so we don't need to do data copying for each RLE code later */
- copy_cell(ctx, plane, cell);
+ int ret = copy_cell(ctx, plane, cell);
+ if (ret < 0)
+ return ret;
} else {
/* set the pointer to the reference pixels for modes 0-4 INTER */
mv_y = cell->mv_ptr[0];
mv_x = cell->mv_ptr[1];
+
+ /* -1 because there is an extra line on top for prediction */
+ if ((cell->ypos << 2) + mv_y < -1 || (cell->xpos << 2) + mv_x < 0 ||
+ ((cell->ypos + cell->height) << 2) + mv_y >= plane->height ||
+ ((cell->xpos + cell->width) << 2) + mv_x >= plane->width) {
+ av_log(ctx->avctx, AV_LOG_ERROR,
+ "Motion vectors point out of the frame.\n");
+ return AVERROR_INVALIDDATA;
+ }
+
offset += mv_y * plane->pitch + mv_x;
ref_block = plane->pixels[ctx->buf_sel ^ 1] + offset;
}
@@ -721,7 +745,7 @@ static int parse_bintree(Indeo3DecodeContext *ctx, AVCodecContext *avctx,
const int depth, const int strip_width)
{
Cell curr_cell;
- int bytes_used;
+ int bytes_used, ret;
if (depth <= 0) {
av_log(avctx, AV_LOG_ERROR, "Stack overflow (corrupted binary tree)!\n");
@@ -772,8 +796,8 @@ static int parse_bintree(Indeo3DecodeContext *ctx, AVCodecContext *avctx,
CHECK_CELL
if (!curr_cell.mv_ptr)
return AVERROR_INVALIDDATA;
- copy_cell(ctx, plane, &curr_cell);
- return 0;
+ ret = copy_cell(ctx, plane, &curr_cell);
+ return ret;
}
break;
case INTER_DATA:
@@ -856,17 +880,20 @@ static int decode_plane(Indeo3DecodeContext *ctx, AVCodecContext *avctx,
static int decode_frame_headers(Indeo3DecodeContext *ctx, AVCodecContext *avctx,
const uint8_t *buf, int buf_size)
{
- const uint8_t *buf_ptr = buf, *bs_hdr;
+ GetByteContext gb;
+ const uint8_t *bs_hdr;
uint32_t frame_num, word2, check_sum, data_size;
uint32_t y_offset, u_offset, v_offset, starts[3], ends[3];
uint16_t height, width;
int i, j;
+ bytestream2_init(&gb, buf, buf_size);
+
/* parse and check the OS header */
- frame_num = bytestream_get_le32(&buf_ptr);
- word2 = bytestream_get_le32(&buf_ptr);
- check_sum = bytestream_get_le32(&buf_ptr);
- data_size = bytestream_get_le32(&buf_ptr);
+ frame_num = bytestream2_get_le32(&gb);
+ word2 = bytestream2_get_le32(&gb);
+ check_sum = bytestream2_get_le32(&gb);
+ data_size = bytestream2_get_le32(&gb);
if ((frame_num ^ word2 ^ data_size ^ OS_HDR_ID) != check_sum) {
av_log(avctx, AV_LOG_ERROR, "OS header checksum mismatch!\n");
@@ -874,28 +901,27 @@ static int decode_frame_headers(Indeo3DecodeContext *ctx, AVCodecContext *avctx,
}
/* parse the bitstream header */
- bs_hdr = buf_ptr;
+ bs_hdr = gb.buffer;
- if (bytestream_get_le16(&buf_ptr) != 32) {
+ if (bytestream2_get_le16(&gb) != 32) {
av_log(avctx, AV_LOG_ERROR, "Unsupported codec version!\n");
return AVERROR_INVALIDDATA;
}
ctx->frame_num = frame_num;
- ctx->frame_flags = bytestream_get_le16(&buf_ptr);
- ctx->data_size = (bytestream_get_le32(&buf_ptr) + 7) >> 3;
- ctx->cb_offset = *buf_ptr++;
+ ctx->frame_flags = bytestream2_get_le16(&gb);
+ ctx->data_size = (bytestream2_get_le32(&gb) + 7) >> 3;
+ ctx->cb_offset = bytestream2_get_byte(&gb);
if (ctx->data_size == 16)
return 4;
- if (ctx->data_size > buf_size)
- ctx->data_size = buf_size;
+ ctx->data_size = FFMIN(ctx->data_size, buf_size - 16);
- buf_ptr += 3; // skip reserved byte and checksum
+ bytestream2_skip(&gb, 3); // skip reserved byte and checksum
/* check frame dimensions */
- height = bytestream_get_le16(&buf_ptr);
- width = bytestream_get_le16(&buf_ptr);
+ height = bytestream2_get_le16(&gb);
+ width = bytestream2_get_le16(&gb);
if (av_image_check_size(width, height, 0, avctx))
return AVERROR_INVALIDDATA;
@@ -921,9 +947,10 @@ static int decode_frame_headers(Indeo3DecodeContext *ctx, AVCodecContext *avctx,
avcodec_set_dimensions(avctx, width, height);
}
- y_offset = bytestream_get_le32(&buf_ptr);
- v_offset = bytestream_get_le32(&buf_ptr);
- u_offset = bytestream_get_le32(&buf_ptr);
+ y_offset = bytestream2_get_le32(&gb);
+ v_offset = bytestream2_get_le32(&gb);
+ u_offset = bytestream2_get_le32(&gb);
+ bytestream2_skip(&gb, 4);
/* unfortunately there is no common order of planes in the buffer */
/* so we use that sorting algo for determining planes data sizes */
@@ -942,6 +969,7 @@ static int decode_frame_headers(Indeo3DecodeContext *ctx, AVCodecContext *avctx,
ctx->v_data_size = ends[1] - starts[1];
ctx->u_data_size = ends[2] - starts[2];
if (FFMAX3(y_offset, v_offset, u_offset) >= ctx->data_size - 16 ||
+ FFMIN3(y_offset, v_offset, u_offset) < gb.buffer - bs_hdr + 16 ||
FFMIN3(ctx->y_data_size, ctx->v_data_size, ctx->u_data_size) <= 0) {
av_log(avctx, AV_LOG_ERROR, "One of the y/u/v offsets is invalid\n");
return AVERROR_INVALIDDATA;
@@ -950,7 +978,7 @@ static int decode_frame_headers(Indeo3DecodeContext *ctx, AVCodecContext *avctx,
ctx->y_data_ptr = bs_hdr + y_offset;
ctx->v_data_ptr = bs_hdr + v_offset;
ctx->u_data_ptr = bs_hdr + u_offset;
- ctx->alt_quant = buf_ptr + sizeof(uint32_t);
+ ctx->alt_quant = gb.buffer;
if (ctx->data_size == 16) {
av_log(avctx, AV_LOG_DEBUG, "Sync frame encountered!\n");
diff --git a/libavcodec/qdm2.c b/libavcodec/qdm2.c
index cfae824..17729d1 100644
--- a/libavcodec/qdm2.c
+++ b/libavcodec/qdm2.c
@@ -1838,6 +1838,10 @@ static av_cold int qdm2_decode_init(AVCodecContext *avctx)
av_log(avctx, AV_LOG_ERROR, "Unknown FFT order (%d), contact the developers!\n", s->fft_order);
return -1;
}
+ if (s->fft_size != (1 << (s->fft_order - 1))) {
+ av_log(avctx, AV_LOG_ERROR, "FFT size %d not power of 2.\n", s->fft_size);
+ return AVERROR_INVALIDDATA;
+ }
ff_rdft_init(&s->rdft_ctx, s->fft_order, IDFT_C2R);
ff_mpadsp_init(&s->mpadsp);
diff --git a/libavcodec/rv10.c b/libavcodec/rv10.c
index 9239cf7..26af29f 100644
--- a/libavcodec/rv10.c
+++ b/libavcodec/rv10.c
@@ -347,6 +347,11 @@ static int rv20_decode_picture_header(RVDecContext *rv)
f = get_bits(&s->gb, rpr_bits);
if(f){
+ if (s->avctx->extradata_size < 8 + 2 * f) {
+ av_log(s->avctx, AV_LOG_ERROR, "Extradata too small.\n");
+ return AVERROR_INVALIDDATA;
+ }
+
new_w= 4*((uint8_t*)s->avctx->extradata)[6+2*f];
new_h= 4*((uint8_t*)s->avctx->extradata)[7+2*f];
}else{
diff --git a/libavcodec/svq1dec.c b/libavcodec/svq1dec.c
index 5156042..82f9301 100644
--- a/libavcodec/svq1dec.c
+++ b/libavcodec/svq1dec.c
@@ -322,7 +322,8 @@ static void svq1_skip_block(uint8_t *current, uint8_t *previous,
static int svq1_motion_inter_block(DSPContext *dsp, GetBitContext *bitbuf,
uint8_t *current, uint8_t *previous,
- int pitch, svq1_pmv *motion, int x, int y)
+ int pitch, svq1_pmv *motion, int x, int y,
+ int width, int height)
{
uint8_t *src;
uint8_t *dst;
@@ -352,10 +353,8 @@ static int svq1_motion_inter_block(DSPContext *dsp, GetBitContext *bitbuf,
motion[x / 8 + 2].y =
motion[x / 8 + 3].y = mv.y;
- if (y + (mv.y >> 1) < 0)
- mv.y = 0;
- if (x + (mv.x >> 1) < 0)
- mv.x = 0;
+ mv.x = av_clip(mv.x, -2 * x, 2 * (width - x - 16));
+ mv.y = av_clip(mv.y, -2 * y, 2 * (height - y - 16));
src = &previous[(x + (mv.x >> 1)) + (y + (mv.y >> 1)) * pitch];
dst = current;
@@ -367,7 +366,8 @@ static int svq1_motion_inter_block(DSPContext *dsp, GetBitContext *bitbuf,
static int svq1_motion_inter_4v_block(DSPContext *dsp, GetBitContext *bitbuf,
uint8_t *current, uint8_t *previous,
- int pitch, svq1_pmv *motion, int x, int y)
+ int pitch, svq1_pmv *motion, int x, int y,
+ int width, int height)
{
uint8_t *src;
uint8_t *dst;
@@ -427,10 +427,8 @@ static int svq1_motion_inter_4v_block(DSPContext *dsp, GetBitContext *bitbuf,
int mvy = pmv[i]->y + (i >> 1) * 16;
// FIXME: clipping or padding?
- if (y + (mvy >> 1) < 0)
- mvy = 0;
- if (x + (mvx >> 1) < 0)
- mvx = 0;
+ mvx = av_clip(mvx, -2 * x, 2 * (width - x - 8));
+ mvy = av_clip(mvy, -2 * y, 2 * (height - y - 8));
src = &previous[(x + (mvx >> 1)) + (y + (mvy >> 1)) * pitch];
dst = current;
@@ -450,7 +448,8 @@ static int svq1_motion_inter_4v_block(DSPContext *dsp, GetBitContext *bitbuf,
static int svq1_decode_delta_block(AVCodecContext *avctx, DSPContext *dsp,
GetBitContext *bitbuf,
uint8_t *current, uint8_t *previous,
- int pitch, svq1_pmv *motion, int x, int y)
+ int pitch, svq1_pmv *motion, int x, int y,
+ int width, int height)
{
uint32_t block_type;
int result = 0;
@@ -475,7 +474,7 @@ static int svq1_decode_delta_block(AVCodecContext *avctx, DSPContext *dsp,
case SVQ1_BLOCK_INTER:
result = svq1_motion_inter_block(dsp, bitbuf, current, previous,
- pitch, motion, x, y);
+ pitch, motion, x, y, width, height);
if (result != 0) {
av_dlog(avctx, "Error in svq1_motion_inter_block %i\n", result);
@@ -486,7 +485,7 @@ static int svq1_decode_delta_block(AVCodecContext *avctx, DSPContext *dsp,
case SVQ1_BLOCK_INTER_4V:
result = svq1_motion_inter_4v_block(dsp, bitbuf, current, previous,
- pitch, motion, x, y);
+ pitch, motion, x, y, width, height);
if (result != 0) {
av_dlog(avctx, "Error in svq1_motion_inter_4v_block %i\n", result);
@@ -692,7 +691,8 @@ static int svq1_decode_frame(AVCodecContext *avctx, void *data,
} else {
/* delta frame */
uint8_t *previous = s->prev->data[i];
- if (!previous) {
+ if (!previous ||
+ s->prev->width != s->width || s->prev->height != s->height) {
av_log(avctx, AV_LOG_ERROR, "Missing reference frame.\n");
result = AVERROR_INVALIDDATA;
goto err;
@@ -705,7 +705,7 @@ static int svq1_decode_frame(AVCodecContext *avctx, void *data,
result = svq1_decode_delta_block(avctx, &s->dsp,
&s->gb, ¤t[x],
previous, linesize,
- pmv, x, y);
+ pmv, x, y, width, height);
if (result != 0) {
av_dlog(avctx,
"Error in svq1_decode_delta_block %i\n",
diff --git a/libavcodec/vp8.c b/libavcodec/vp8.c
index 3b8f7d2..deb5015 100644
--- a/libavcodec/vp8.c
+++ b/libavcodec/vp8.c
@@ -40,6 +40,10 @@ static void free_buffers(VP8Context *s)
int i;
if (s->thread_data)
for (i = 0; i < MAX_THREADS; i++) {
+#if HAVE_THREADS
+ pthread_cond_destroy(&s->thread_data[i].cond);
+ pthread_mutex_destroy(&s->thread_data[i].lock);
+#endif
av_freep(&s->thread_data[i].filter_strength);
av_freep(&s->thread_data[i].edge_emu_buffer);
}
diff --git a/libavfilter/af_channelmap.c b/libavfilter/af_channelmap.c
index 8b72d5b..c4b87da 100644
--- a/libavfilter/af_channelmap.c
+++ b/libavfilter/af_channelmap.c
@@ -362,23 +362,32 @@ static int channelmap_config_input(AVFilterLink *inlink)
{
AVFilterContext *ctx = inlink->dst;
ChannelMapContext *s = ctx->priv;
+ int nb_channels = av_get_channel_layout_nb_channels(inlink->channel_layout);
int i, err = 0;
const char *channel_name;
char layout_name[256];
- if (s->mode == MAP_PAIR_STR_INT || s->mode == MAP_PAIR_STR_STR) {
- for (i = 0; i < s->nch; i++) {
+ for (i = 0; i < s->nch; i++) {
+ if (s->mode == MAP_PAIR_STR_INT || s->mode == MAP_PAIR_STR_STR) {
s->map[i].in_channel_idx = av_get_channel_layout_channel_index(
inlink->channel_layout, s->map[i].in_channel);
- if (s->map[i].in_channel_idx < 0) {
+ }
+
+ if (s->map[i].in_channel_idx < 0 ||
+ s->map[i].in_channel_idx >= nb_channels) {
+ av_get_channel_layout_string(layout_name, sizeof(layout_name),
+ 0, inlink->channel_layout);
+ if (s->map[i].in_channel) {
channel_name = av_get_channel_name(s->map[i].in_channel);
- av_get_channel_layout_string(layout_name, sizeof(layout_name),
- 0, inlink->channel_layout);
av_log(ctx, AV_LOG_ERROR,
"input channel '%s' not available from input layout '%s'\n",
channel_name, layout_name);
- err = AVERROR(EINVAL);
+ } else {
+ av_log(ctx, AV_LOG_ERROR,
+ "input channel #%d not available from input layout '%s'\n",
+ s->map[i].in_channel_idx, layout_name);
}
+ err = AVERROR(EINVAL);
}
}
diff --git a/libavfilter/avfiltergraph.c b/libavfilter/avfiltergraph.c
index f5c9984..d27b1b2 100644
--- a/libavfilter/avfiltergraph.c
+++ b/libavfilter/avfiltergraph.c
@@ -24,6 +24,7 @@
#include <string.h>
#include "libavutil/avassert.h"
+#include "libavutil/avstring.h"
#include "libavutil/channel_layout.h"
#include "libavutil/common.h"
#include "libavutil/log.h"
@@ -220,7 +221,11 @@ static int query_formats(AVFilterGraph *graph, AVClass *log_ctx)
snprintf(inst_name, sizeof(inst_name), "auto-inserted scaler %d",
scaler_count++);
- snprintf(scale_args, sizeof(scale_args), "0:0:%s", graph->scale_sws_opts);
+ av_strlcpy(scale_args, "0:0", sizeof(scale_args));
+ if (graph->scale_sws_opts) {
+ av_strlcat(scale_args, ":", sizeof(scale_args));
+ av_strlcat(scale_args, graph->scale_sws_opts, sizeof(scale_args));
+ }
if ((ret = avfilter_graph_create_filter(&convert, filter,
inst_name, scale_args, NULL,
graph)) < 0)
diff --git a/libavfilter/graphparser.c b/libavfilter/graphparser.c
index 04339c8..7ce60c1 100644
--- a/libavfilter/graphparser.c
+++ b/libavfilter/graphparser.c
@@ -123,7 +123,8 @@ static int create_filter(AVFilterContext **filt_ctx, AVFilterGraph *ctx, int ind
return ret;
}
- if (!strcmp(filt_name, "scale") && args && !strstr(args, "flags")) {
+ if (!strcmp(filt_name, "scale") && args && !strstr(args, "flags") &&
+ ctx->scale_sws_opts) {
snprintf(tmp_args, sizeof(tmp_args), "%s:%s",
args, ctx->scale_sws_opts);
args = tmp_args;
diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c
index 403a9b5..2f68653 100644
--- a/libavformat/flvdec.c
+++ b/libavformat/flvdec.c
@@ -400,7 +400,7 @@ static int amf_parse_object(AVFormatContext *s, AVStream *astream, AVStream *vst
acodec = astream ? astream->codec : NULL;
vcodec = vstream ? vstream->codec : NULL;
- if (amf_type == AMF_DATA_TYPE_NUMBER) {
+ if (amf_type == AMF_DATA_TYPE_NUMBER || amf_type == AMF_DATA_TYPE_BOOL) {
if (!strcmp(key, "duration"))
s->duration = num_val * AV_TIME_BASE;
else if (!strcmp(key, "videodatarate") && vcodec && 0 <= (int)(num_val * 1024.0))
@@ -417,10 +417,18 @@ static int amf_parse_object(AVFormatContext *s, AVStream *astream, AVStream *vst
flv_set_video_codec(s, vstream, num_val, 0);
} else
if (!strcmp(key, "audiocodecid") && acodec) {
- flv_set_audio_codec(s, astream, acodec, num_val);
+ int id = ((int)num_val) << FLV_AUDIO_CODECID_OFFSET;
+ flv_set_audio_codec(s, astream, acodec, id);
} else
if (!strcmp(key, "audiosamplerate") && acodec) {
acodec->sample_rate = num_val;
+ } else if (!strcmp(key, "audiosamplesize") && acodec) {
+ acodec->bits_per_coded_sample = num_val;
+ } else if (!strcmp(key, "stereo") && acodec) {
+ acodec->channels = num_val + 1;
+ acodec->channel_layout = acodec->channels == 2 ?
+ AV_CH_LAYOUT_STEREO :
+ AV_CH_LAYOUT_MONO;
} else
if (!strcmp(key, "width") && vcodec) {
vcodec->width = num_val;
diff --git a/libavformat/id3v2.c b/libavformat/id3v2.c
index 4516ac7..7f39a47 100644
--- a/libavformat/id3v2.c
+++ b/libavformat/id3v2.c
@@ -477,9 +477,10 @@ static void read_apic(AVFormatContext *s, AVIOContext *pb, int taglen, char *tag
}
apic->len = taglen;
- apic->data = av_malloc(taglen);
+ apic->data = av_malloc(taglen + FF_INPUT_BUFFER_PADDING_SIZE);
if (!apic->data || avio_read(pb, apic->data, taglen) != taglen)
goto fail;
+ memset(apic->data + taglen, 0, FF_INPUT_BUFFER_PADDING_SIZE);
new_extra->tag = "APIC";
new_extra->data = apic;
diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c
index 86ff477..147c24c 100644
--- a/libavformat/matroskadec.c
+++ b/libavformat/matroskadec.c
@@ -1757,10 +1757,10 @@ static void matroska_clear_queue(MatroskaDemuxContext *matroska)
}
static int matroska_parse_laces(MatroskaDemuxContext *matroska, uint8_t **buf,
- int size, int type,
+ int* buf_size, int type,
uint32_t **lace_buf, int *laces)
{
- int res = 0, n;
+ int res = 0, n, size = *buf_size;
uint8_t *data = *buf;
uint32_t *lace_size;
@@ -1821,7 +1821,7 @@ static int matroska_parse_laces(MatroskaDemuxContext *matroska, uint8_t **buf,
case 0x3: /* EBML lacing */ {
uint64_t num;
- uint32_t total;
+ uint64_t total;
n = matroska_ebmlnum_uint(matroska, data, size, &num);
if (n < 0) {
av_log(matroska->ctx, AV_LOG_INFO,
@@ -1858,6 +1858,7 @@ static int matroska_parse_laces(MatroskaDemuxContext *matroska, uint8_t **buf,
*buf = data;
*lace_buf = lace_size;
+ *buf_size = size;
return res;
}
@@ -2052,7 +2053,7 @@ static int matroska_parse_block(MatroskaDemuxContext *matroska, uint8_t *data,
matroska->skip_to_keyframe = 0;
}
- res = matroska_parse_laces(matroska, &data, size, (flags & 0x06) >> 1,
+ res = matroska_parse_laces(matroska, &data, &size, (flags & 0x06) >> 1,
&lace_size, &laces);
if (res)
@@ -2080,7 +2081,8 @@ static int matroska_parse_block(MatroskaDemuxContext *matroska, uint8_t *data,
st->codec->codec_id == AV_CODEC_ID_ATRAC3) &&
st->codec->block_align && track->audio.sub_packet_size) {
- res = matroska_parse_rm_audio(matroska, track, st, data, size,
+ res = matroska_parse_rm_audio(matroska, track, st, data,
+ lace_size[n],
timecode, duration, pos);
if (res)
goto end;
@@ -2096,7 +2098,6 @@ static int matroska_parse_block(MatroskaDemuxContext *matroska, uint8_t *data,
if (timecode != AV_NOPTS_VALUE)
timecode = duration ? timecode + duration : AV_NOPTS_VALUE;
data += lace_size[n];
- size -= lace_size[n];
}
end:
diff --git a/libavformat/mp3dec.c b/libavformat/mp3dec.c
index 48deefd..9da9aa8 100644
--- a/libavformat/mp3dec.c
+++ b/libavformat/mp3dec.c
@@ -35,6 +35,10 @@
#define XING_TOC_COUNT 100
+typedef struct MP3DecContext {
+ int xing_toc;
+} MP3DecContext;
+
/* mp3 read */
static int mp3_read_probe(AVProbeData *p)
@@ -100,6 +104,7 @@ static int mp3_read_probe(AVProbeData *p)
static void read_xing_toc(AVFormatContext *s, int64_t filesize, int64_t duration)
{
int i;
+ MP3DecContext *mp3 = s->priv_data;
if (!filesize &&
!(filesize = avio_size(s->pb))) {
@@ -115,6 +120,7 @@ static void read_xing_toc(AVFormatContext *s, int64_t filesize, int64_t duration
av_rescale(i, duration, XING_TOC_COUNT),
0, 0, AVINDEX_KEYFRAME);
}
+ mp3->xing_toc = 1;
}
/**
@@ -238,11 +244,15 @@ static int mp3_read_packet(AVFormatContext *s, AVPacket *pkt)
static int mp3_seek(AVFormatContext *s, int stream_index, int64_t timestamp,
int flags)
{
+ MP3DecContext *mp3 = s->priv_data;
AVIndexEntry *ie;
AVStream *st = s->streams[0];
int64_t ret = av_index_search_timestamp(st, timestamp, flags);
uint32_t header = 0;
+ if (!mp3->xing_toc)
+ return AVERROR(ENOSYS);
+
if (ret < 0)
return ret;
@@ -270,6 +280,7 @@ AVInputFormat ff_mp3_demuxer = {
.read_header = mp3_read_header,
.read_packet = mp3_read_packet,
.read_seek = mp3_seek,
+ .priv_data_size = sizeof(MP3DecContext),
.flags = AVFMT_GENERIC_INDEX,
.extensions = "mp2,mp3,m2a", /* XXX: use probe */
};
diff --git a/libavformat/oggparsevorbis.c b/libavformat/oggparsevorbis.c
index fbe6c4f..bb41b52 100644
--- a/libavformat/oggparsevorbis.c
+++ b/libavformat/oggparsevorbis.c
@@ -192,7 +192,7 @@ fixup_vorbis_headers(AVFormatContext * as, struct oggvorbis_private *priv,
return offset;
}
-static int vorbis_cleanup(AVFormatContext *s, int idx)
+static void vorbis_cleanup(AVFormatContext *s, int idx)
{
struct ogg *ogg = s->priv_data;
struct ogg_stream *os = ogg->streams + idx;
diff --git a/libavformat/oma.c b/libavformat/oma.c
index f6454d9..aaaf0b2 100644
--- a/libavformat/oma.c
+++ b/libavformat/oma.c
@@ -22,7 +22,7 @@
#include "oma.h"
#include "libavcodec/avcodec.h"
-const uint16_t ff_oma_srate_tab[6] = { 320, 441, 480, 882, 960, 0 };
+const uint16_t ff_oma_srate_tab[8] = { 320, 441, 480, 882, 960, 0 };
const AVCodecTag ff_oma_codec_tags[] = {
{ AV_CODEC_ID_ATRAC3, OMA_CODECID_ATRAC3 },
diff --git a/libavformat/oma.h b/libavformat/oma.h
index bac8bcb..1f0ddf9 100644
--- a/libavformat/oma.h
+++ b/libavformat/oma.h
@@ -37,7 +37,7 @@ enum {
OMA_CODECID_WMA = 5,
};
-extern const uint16_t ff_oma_srate_tab[6];
+extern const uint16_t ff_oma_srate_tab[8];
extern const AVCodecTag ff_oma_codec_tags[];
diff --git a/libavformat/omadec.c b/libavformat/omadec.c
index 2e565c1..f6b6f13 100644
--- a/libavformat/omadec.c
+++ b/libavformat/omadec.c
@@ -304,7 +304,11 @@ static int oma_read_header(AVFormatContext *s)
switch (buf[32]) {
case OMA_CODECID_ATRAC3:
- samplerate = ff_oma_srate_tab[(codec_params >> 13) & 7]*100;
+ samplerate = ff_oma_srate_tab[(codec_params >> 13) & 7] * 100;
+ if (!samplerate) {
+ av_log(s, AV_LOG_ERROR, "Unsupported sample rate\n");
+ return AVERROR_INVALIDDATA;
+ }
if (samplerate != 44100)
av_log_ask_for_sample(s, "Unsupported sample rate: %d\n",
samplerate);
@@ -335,9 +339,14 @@ static int oma_read_header(AVFormatContext *s)
case OMA_CODECID_ATRAC3P:
st->codec->channels = (codec_params >> 10) & 7;
framesize = ((codec_params & 0x3FF) * 8) + 8;
- st->codec->sample_rate = ff_oma_srate_tab[(codec_params >> 13) & 7]*100;
- st->codec->bit_rate = st->codec->sample_rate * framesize * 8 / 1024;
- avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
+ samplerate = ff_oma_srate_tab[(codec_params >> 13) & 7] * 100;
+ if (!samplerate) {
+ av_log(s, AV_LOG_ERROR, "Unsupported sample rate\n");
+ return AVERROR_INVALIDDATA;
+ }
+ st->codec->sample_rate = samplerate;
+ st->codec->bit_rate = samplerate * framesize * 8 / 1024;
+ avpriv_set_pts_info(st, 64, 1, samplerate);
av_log(s, AV_LOG_ERROR, "Unsupported codec ATRAC3+!\n");
break;
case OMA_CODECID_MP3:
diff --git a/libavformat/riff.c b/libavformat/riff.c
index 79b2670..e9463c0 100644
--- a/libavformat/riff.c
+++ b/libavformat/riff.c
@@ -728,6 +728,10 @@ int ff_read_riff_info(AVFormatContext *s, int64_t size)
if (!chunk_code) {
if (chunk_size)
avio_skip(pb, chunk_size);
+ else if (pb->eof_reached) {
+ av_log(s, AV_LOG_WARNING, "truncated file\n");
+ return AVERROR_EOF;
+ }
continue;
}
diff --git a/libavformat/utils.c b/libavformat/utils.c
index cd46caf..085ae83 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -2671,6 +2671,7 @@ void avformat_free_context(AVFormatContext *s)
if (st->attached_pic.data)
av_free_packet(&st->attached_pic);
av_dict_free(&st->metadata);
+ av_freep(&st->probe_data.buf);
av_free(st->index_entries);
av_free(st->codec->extradata);
av_free(st->codec->subtitle_header);
diff --git a/libavformat/xmv.c b/libavformat/xmv.c
index 3f926ef..d491dec 100644
--- a/libavformat/xmv.c
+++ b/libavformat/xmv.c
@@ -126,6 +126,16 @@ static int xmv_probe(AVProbeData *p)
return 0;
}
+static int xmv_read_close(AVFormatContext *s)
+{
+ XMVDemuxContext *xmv = s->priv_data;
+
+ av_free(xmv->audio);
+ av_free(xmv->audio_tracks);
+
+ return 0;
+}
+
static int xmv_read_header(AVFormatContext *s)
{
XMVDemuxContext *xmv = s->priv_data;
@@ -135,6 +145,7 @@ static int xmv_read_header(AVFormatContext *s)
uint32_t file_version;
uint32_t this_packet_size;
uint16_t audio_track;
+ int ret;
avio_skip(pb, 4); /* Next packet size */
@@ -177,8 +188,10 @@ static int xmv_read_header(AVFormatContext *s)
return AVERROR(ENOMEM);
xmv->audio = av_malloc(xmv->audio_track_count * sizeof(XMVAudioPacket));
- if (!xmv->audio)
- return AVERROR(ENOMEM);
+ if (!xmv->audio) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
for (audio_track = 0; audio_track < xmv->audio_track_count; audio_track++) {
XMVAudioTrack *track = &xmv->audio_tracks[audio_track];
@@ -211,9 +224,18 @@ static int xmv_read_header(AVFormatContext *s)
av_log(s, AV_LOG_WARNING, "Unsupported 5.1 ADPCM audio stream "
"(0x%04X)\n", track->flags);
+ if (!track->channels || !track->sample_rate) {
+ av_log(s, AV_LOG_ERROR, "Invalid parameters for audio track %d.\n",
+ audio_track);
+ ret = AVERROR_INVALIDDATA;
+ goto fail;
+ }
+
ast = avformat_new_stream(s, NULL);
- if (!ast)
- return AVERROR(ENOMEM);
+ if (!ast) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
ast->codec->codec_type = AVMEDIA_TYPE_AUDIO;
ast->codec->codec_id = track->codec_id;
@@ -239,6 +261,10 @@ static int xmv_read_header(AVFormatContext *s)
xmv->stream_count = xmv->audio_track_count + 1;
return 0;
+
+fail:
+ xmv_read_close(s);
+ return ret;
}
static void xmv_read_extradata(uint8_t *extradata, AVIOContext *pb)
@@ -546,16 +572,6 @@ static int xmv_read_packet(AVFormatContext *s,
return 0;
}
-static int xmv_read_close(AVFormatContext *s)
-{
- XMVDemuxContext *xmv = s->priv_data;
-
- av_free(xmv->audio);
- av_free(xmv->audio_tracks);
-
- return 0;
-}
-
AVInputFormat ff_xmv_demuxer = {
.name = "xmv",
.long_name = NULL_IF_CONFIG_SMALL("Microsoft XMV"),
--
Libav/FFmpeg packaging
More information about the pkg-multimedia-commits
mailing list