[SCM] ffmpeg/upstream: Imported Upstream version 0.7.3
siretart at users.alioth.debian.org
siretart at users.alioth.debian.org
Sun Dec 25 20:51:34 UTC 2011
The following commit has been merged in the upstream branch:
commit fa99e4dbc5d7ccf38cecb264423afcb590da1286
Author: Reinhard Tartler <siretart at tauware.de>
Date: Sun Dec 25 21:50:50 2011 +0100
Imported Upstream version 0.7.3
diff --git a/Changelog b/Changelog
index ab02a02..e8fcf82 100644
--- a/Changelog
+++ b/Changelog
@@ -1,6 +1,15 @@
Entries are sorted chronologically from oldest to youngest within each release,
releases are sorted from youngest to oldest.
+version 0.7.3:
+
+- check buffer and input values in various parts of the code:
+ vmd (CVE-2011-4364), qdm2 (CVE-2011-4351), imgutils (several codecs),
+ vp6 (CVE-2011-4353), svq1 (CVE-2011-4579), vp3 (CVE-2011-4352), wma, 4xm
+- backport avcodec_open2() as a replacement for avcodec_open()
+- backport avformat_find_stream_info()
+
+
version 0.7.2:
- check buffer and input values in various parts of the code:
diff --git a/RELEASE b/RELEASE
index 7486fdb..f38fc53 100644
--- a/RELEASE
+++ b/RELEASE
@@ -1 +1 @@
-0.7.2
+0.7.3
diff --git a/VERSION b/VERSION
index 7486fdb..f38fc53 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-0.7.2
+0.7.3
diff --git a/doc/APIchanges b/doc/APIchanges
index 79d9749..165ea98 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -13,6 +13,12 @@ libavutil: 2011-04-18
API changes, most recent first:
+2011-07-10 - xxxxxxx - lavf 53.3.0
+ Add avformat_find_stream_info(), deprecate av_find_stream_info().
+
+2011-07-10 - xxxxxxx - lavc 53.6.0
+ Add avcodec_open2(), deprecate avcodec_open().
+
2011-06-xx - xxxxxxx - lavf 53.2.0 - avformat.h
Add avformat_open_input and avformat_write_header().
Deprecate av_open_input_stream, av_open_input_file,
diff --git a/ffprobe.c b/ffprobe.c
index edda454..cb4a4c3 100644
--- a/ffprobe.c
+++ b/ffprobe.c
@@ -291,7 +291,7 @@ static int open_input_file(AVFormatContext **fmt_ctx_ptr, const char *filename)
if (!(codec = avcodec_find_decoder(stream->codec->codec_id))) {
fprintf(stderr, "Unsupported codec with id %d for input stream %d\n",
stream->codec->codec_id, stream->index);
- } else if (avcodec_open(stream->codec, codec) < 0) {
+ } else if (avcodec_open2(stream->codec, codec, NULL) < 0) {
fprintf(stderr, "Error while opening codec for input stream %d\n",
stream->index);
}
diff --git a/ffserver.c b/ffserver.c
index 65a97b2..179cac4 100644
--- a/ffserver.c
+++ b/ffserver.c
@@ -2116,7 +2116,7 @@ static void open_parser(AVFormatContext *s, int i)
codec = avcodec_find_decoder(st->codec->codec_id);
if (codec && (codec->capabilities & CODEC_CAP_PARSE_ONLY)) {
st->codec->parse_only = 1;
- if (avcodec_open(st->codec, codec) < 0)
+ if (avcodec_open2(st->codec, codec, NULL) < 0)
st->codec->parse_only = 0;
}
}
diff --git a/libavcodec/4xm.c b/libavcodec/4xm.c
index 176feb9..ed83259 100644
--- a/libavcodec/4xm.c
+++ b/libavcodec/4xm.c
@@ -658,9 +658,18 @@ static int decode_i_frame(FourXContext *f, const uint8_t *buf, int length){
uint16_t *dst= (uint16_t*)f->current_picture.data[0];
const int stride= f->current_picture.linesize[0]>>1;
const unsigned int bitstream_size= AV_RL32(buf);
- const int token_count av_unused = AV_RL32(buf + bitstream_size + 8);
- unsigned int prestream_size= 4*AV_RL32(buf + bitstream_size + 4);
- const uint8_t *prestream= buf + bitstream_size + 12;
+ int token_count av_unused;
+ unsigned int prestream_size;
+ const uint8_t *prestream;
+
+ if (length < bitstream_size + 12) {
+ av_log(f->avctx, AV_LOG_ERROR, "packet size too small\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ token_count = AV_RL32(buf + bitstream_size + 8);
+ prestream_size = 4 * AV_RL32(buf + bitstream_size + 4);
+ prestream = buf + bitstream_size + 12;
if(prestream_size + bitstream_size + 12 != length
|| bitstream_size > (1<<26)
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 0269892..2dbdc86 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -30,6 +30,7 @@
#include "libavutil/samplefmt.h"
#include "libavutil/avutil.h"
#include "libavutil/cpu.h"
+#include "libavutil/dict.h"
#include "libavcodec/version.h"
@@ -3615,6 +3616,7 @@ int avcodec_default_execute(AVCodecContext *c, int (*func)(AVCodecContext *c2, v
int avcodec_default_execute2(AVCodecContext *c, int (*func)(AVCodecContext *c2, void *arg2, int, int),void *arg, int *ret, int count);
//FIXME func typedef
+#if FF_API_AVCODEC_OPEN
/**
* Initialize the AVCodecContext to use the given AVCodec. Prior to using this
* function the context has to be allocated.
@@ -3641,8 +3643,45 @@ int avcodec_default_execute2(AVCodecContext *c, int (*func)(AVCodecContext *c2,
* @param codec The codec to use within the context.
* @return zero on success, a negative value on error
* @see avcodec_alloc_context, avcodec_find_decoder, avcodec_find_encoder, avcodec_close
+ *
+ * @deprecated use avcodec_open2
*/
+attribute_deprecated
int avcodec_open(AVCodecContext *avctx, AVCodec *codec);
+#endif
+
+/**
+ * Initialize the AVCodecContext to use the given AVCodec. Prior to using this
+ * function the context has to be allocated with avcodec_alloc_context().
+ *
+ * The functions avcodec_find_decoder_by_name(), avcodec_find_encoder_by_name(),
+ * avcodec_find_decoder() and avcodec_find_encoder() provide an easy way for
+ * retrieving a codec.
+ *
+ * @warning This function is not thread safe!
+ *
+ * @code
+ * avcodec_register_all();
+ * av_dict_set(&opts, "b", "2.5M", 0);
+ * codec = avcodec_find_decoder(CODEC_ID_H264);
+ * if (!codec)
+ * exit(1);
+ *
+ * context = avcodec_alloc_context();
+ *
+ * if (avcodec_open(context, codec, opts) < 0)
+ * exit(1);
+ * @endcode
+ *
+ * @param avctx The context to initialize.
+ * @param options A dictionary filled with AVCodecContext and codec-private options.
+ * On return this object will be filled with options that were not found.
+ *
+ * @return zero on success, a negative value on error
+ * @see avcodec_alloc_context3(), avcodec_find_decoder(), avcodec_find_encoder(),
+ * av_dict_set(), av_opt_find().
+ */
+int avcodec_open2(AVCodecContext *avctx, AVCodec *codec, AVDictionary **options);
/**
* Decode the audio frame of size avpkt->size from avpkt->data into samples.
diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index b5a1872..51713a2 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -972,7 +972,7 @@ static int estimate_best_b_count(MpegEncContext *s){
c->time_base= s->avctx->time_base;
c->max_b_frames= s->max_b_frames;
- if (avcodec_open(c, codec) < 0)
+ if (avcodec_open2(c, codec, NULL) < 0)
return -1;
for(i=0; i<s->max_b_frames+2; i++){
diff --git a/libavcodec/qdm2.c b/libavcodec/qdm2.c
index 86847ad..7e7051f 100644
--- a/libavcodec/qdm2.c
+++ b/libavcodec/qdm2.c
@@ -76,6 +76,7 @@ do { \
#define SAMPLES_NEEDED_2(why) \
av_log (NULL,AV_LOG_INFO,"This file triggers some missing code. Please contact the developers.\nPosition: %s\n",why);
+#define QDM2_MAX_FRAME_SIZE 512
typedef int8_t sb_int8_array[2][30][64];
@@ -168,7 +169,7 @@ typedef struct {
/// I/O data
const uint8_t *compressed_data;
int compressed_size;
- float output_buffer[1024];
+ float output_buffer[QDM2_MAX_FRAME_SIZE * 2];
/// Synthesis filter
MPADSPContext mpadsp;
@@ -1353,6 +1354,8 @@ static void qdm2_fft_decode_tones (QDM2Context *q, int duration, GetBitContext *
return;
local_int_14 = (offset >> local_int_8);
+ if (local_int_14 >= FF_ARRAY_ELEMS(fft_level_index_table))
+ return;
if (q->nb_channels > 1) {
channel = get_bits1(gb);
@@ -1797,6 +1800,8 @@ static av_cold int qdm2_decode_init(AVCodecContext *avctx)
avctx->channels = s->nb_channels = s->channels = AV_RB32(extradata);
extradata += 4;
+ if (s->channels > MPA_MAX_CHANNELS)
+ return AVERROR_INVALIDDATA;
avctx->sample_rate = AV_RB32(extradata);
extradata += 4;
@@ -1818,6 +1823,8 @@ static av_cold int qdm2_decode_init(AVCodecContext *avctx)
// something like max decodable tones
s->group_order = av_log2(s->group_size) + 1;
s->frame_size = s->group_size / 16; // 16 iterations per super block
+ if (s->frame_size > QDM2_MAX_FRAME_SIZE)
+ return AVERROR_INVALIDDATA;
s->sub_sampling = s->fft_order - 7;
s->frequency_range = 255 / (1 << (2 - s->sub_sampling));
@@ -1952,13 +1959,20 @@ static int qdm2_decode_frame(AVCodecContext *avctx,
int buf_size = avpkt->size;
QDM2Context *s = avctx->priv_data;
int16_t *out = data;
- int i;
+ int i, out_size;
if(!buf)
return 0;
if(buf_size < s->checksum_size)
return -1;
+ out_size = 16 * s->channels * s->frame_size *
+ av_get_bytes_per_sample(avctx->sample_fmt);
+ if (*data_size < out_size) {
+ av_log(avctx, AV_LOG_ERROR, "Output buffer is too small\n");
+ return AVERROR(EINVAL);
+ }
+
av_log(avctx, AV_LOG_DEBUG, "decode(%d): %p[%d] -> %p[%d]\n",
buf_size, buf, s->checksum_size, data, *data_size);
@@ -1968,7 +1982,7 @@ static int qdm2_decode_frame(AVCodecContext *avctx,
out += s->channels * s->frame_size;
}
- *data_size = (uint8_t*)out - (uint8_t*)data;
+ *data_size = out_size;
return s->checksum_size;
}
diff --git a/libavcodec/svq1dec.c b/libavcodec/svq1dec.c
index 2a80374..325cc12 100644
--- a/libavcodec/svq1dec.c
+++ b/libavcodec/svq1dec.c
@@ -658,6 +658,7 @@ static int svq1_decode_frame(AVCodecContext *avctx,
av_dlog(s->avctx, "Error in svq1_decode_frame_header %i\n",result);
return result;
}
+ avcodec_set_dimensions(avctx, s->width, s->height);
//FIXME this avoids some confusion for "B frames" without 2 references
//this should be removed after libavcodec can handle more flexible picture types & ordering
diff --git a/libavcodec/utils.c b/libavcodec/utils.c
index bbed726..5c19dd7 100644
--- a/libavcodec/utils.c
+++ b/libavcodec/utils.c
@@ -32,6 +32,7 @@
#include "libavutil/audioconvert.h"
#include "libavutil/imgutils.h"
#include "libavutil/samplefmt.h"
+#include "libavutil/dict.h"
#include "avcodec.h"
#include "dsputil.h"
#include "libavutil/opt.h"
@@ -467,9 +468,20 @@ AVFrame *avcodec_alloc_frame(void){
return pic;
}
+#if FF_API_AVCODEC_OPEN
int attribute_align_arg avcodec_open(AVCodecContext *avctx, AVCodec *codec)
{
+ return avcodec_open2(avctx, codec, NULL);
+}
+#endif
+
+int attribute_align_arg avcodec_open2(AVCodecContext *avctx, AVCodec *codec, AVDictionary **options)
+{
int ret = 0;
+ AVDictionary *tmp = NULL;
+
+ if (options)
+ av_dict_copy(&tmp, *options, 0);
/* If there is a user-supplied mutex locking routine, call it. */
if (ff_lockmgr_cb) {
@@ -496,14 +508,18 @@ int attribute_align_arg avcodec_open(AVCodecContext *avctx, AVCodec *codec)
ret = AVERROR(ENOMEM);
goto end;
}
- if(codec->priv_class){ //this can be droped once all user apps use avcodec_get_context_defaults3()
+ if (codec->priv_class) {
*(AVClass**)avctx->priv_data= codec->priv_class;
av_opt_set_defaults(avctx->priv_data);
}
}
+ if (codec->priv_class && (ret = av_opt_set_dict(avctx->priv_data, &tmp)) < 0)
+ goto free_and_end;
} else {
avctx->priv_data = NULL;
}
+ if ((ret = av_opt_set_dict(avctx, &tmp)) < 0)
+ goto free_and_end;
if(avctx->coded_width && avctx->coded_height)
avcodec_set_dimensions(avctx, avctx->coded_width, avctx->coded_height);
@@ -615,8 +631,14 @@ end:
if (ff_lockmgr_cb) {
(*ff_lockmgr_cb)(&codec_mutex, AV_LOCK_RELEASE);
}
+ if (options) {
+ av_dict_free(options);
+ *options = tmp;
+ }
+
return ret;
free_and_end:
+ av_dict_free(&tmp);
av_freep(&avctx->priv_data);
avctx->codec= NULL;
goto end;
diff --git a/libavcodec/version.h b/libavcodec/version.h
index aded68e..44c9198 100644
--- a/libavcodec/version.h
+++ b/libavcodec/version.h
@@ -21,7 +21,7 @@
#define AVCODEC_VERSION_H
#define LIBAVCODEC_VERSION_MAJOR 53
-#define LIBAVCODEC_VERSION_MINOR 5
+#define LIBAVCODEC_VERSION_MINOR 6
#define LIBAVCODEC_VERSION_MICRO 0
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
@@ -68,5 +68,8 @@
#ifndef FF_API_GET_PIX_FMT_NAME
#define FF_API_GET_PIX_FMT_NAME (LIBAVCODEC_VERSION_MAJOR < 54)
#endif
+#ifndef FF_API_AVCODEC_OPEN
+#define FF_API_AVCODEC_OPEN (LIBAVCODEC_VERSION_MAJOR < 54)
+#endif
#endif /* AVCODEC_VERSION_H */
diff --git a/libavcodec/vmdav.c b/libavcodec/vmdav.c
index d258252..500adcb 100644
--- a/libavcodec/vmdav.c
+++ b/libavcodec/vmdav.c
@@ -72,9 +72,11 @@ typedef struct VmdVideoContext {
#define QUEUE_SIZE 0x1000
#define QUEUE_MASK 0x0FFF
-static void lz_unpack(const unsigned char *src, unsigned char *dest, int dest_len)
+static void lz_unpack(const unsigned char *src, int src_len,
+ unsigned char *dest, int dest_len)
{
const unsigned char *s;
+ unsigned int s_len;
unsigned char *d;
unsigned char *d_end;
unsigned char queue[QUEUE_SIZE];
@@ -87,13 +89,16 @@ static void lz_unpack(const unsigned char *src, unsigned char *dest, int dest_le
unsigned int i, j;
s = src;
+ s_len = src_len;
d = dest;
d_end = d + dest_len;
dataleft = AV_RL32(s);
- s += 4;
+ s += 4; s_len -= 4;
memset(queue, 0x20, QUEUE_SIZE);
+ if (s_len < 4)
+ return;
if (AV_RL32(s) == 0x56781234) {
- s += 4;
+ s += 4; s_len -= 4;
qpos = 0x111;
speclen = 0xF + 3;
} else {
@@ -101,32 +106,41 @@ static void lz_unpack(const unsigned char *src, unsigned char *dest, int dest_le
speclen = 100; /* no speclen */
}
- while (dataleft > 0) {
- tag = *s++;
+ while (dataleft > 0 && s_len > 0) {
+ tag = *s++; s_len--;
if ((tag == 0xFF) && (dataleft > 8)) {
- if (d + 8 > d_end)
+ if (d + 8 > d_end || s_len < 8)
return;
for (i = 0; i < 8; i++) {
queue[qpos++] = *d++ = *s++;
qpos &= QUEUE_MASK;
}
+ s_len -= 8;
dataleft -= 8;
} else {
for (i = 0; i < 8; i++) {
if (dataleft == 0)
break;
if (tag & 0x01) {
- if (d + 1 > d_end)
+ if (d + 1 > d_end || s_len < 1)
return;
queue[qpos++] = *d++ = *s++;
qpos &= QUEUE_MASK;
dataleft--;
+ s_len--;
} else {
+ if (s_len < 2)
+ return;
chainofs = *s++;
chainofs |= ((*s & 0xF0) << 4);
chainlen = (*s++ & 0x0F) + 3;
- if (chainlen == speclen)
+ s_len -= 2;
+ if (chainlen == speclen) {
+ if (s_len < 1)
+ return;
chainlen = *s++ + 0xF + 3;
+ s_len--;
+ }
if (d + chainlen > d_end)
return;
for (j = 0; j < chainlen; j++) {
@@ -143,7 +157,7 @@ static void lz_unpack(const unsigned char *src, unsigned char *dest, int dest_le
}
static int rle_unpack(const unsigned char *src, unsigned char *dest,
- int src_len, int dest_len)
+ int src_count, int src_size, int dest_len)
{
const unsigned char *ps;
unsigned char *pd;
@@ -152,31 +166,40 @@ static int rle_unpack(const unsigned char *src, unsigned char *dest,
ps = src;
pd = dest;
- if (src_len & 1)
+ if (src_count & 1) {
+ if (src_size < 1)
+ return 0;
*pd++ = *ps++;
+ src_size--;
+ }
- src_len >>= 1;
+ src_count >>= 1;
i = 0;
do {
+ if (src_size < 1)
+ break;
l = *ps++;
+ src_size--;
if (l & 0x80) {
l = (l & 0x7F) * 2;
- if (pd + l > dest_end)
+ if (pd + l > dest_end || src_size < l)
return ps - src;
memcpy(pd, ps, l);
ps += l;
+ src_size -= l;
pd += l;
} else {
- if (pd + i > dest_end)
+ if (pd + i > dest_end || src_size < 2)
return ps - src;
for (i = 0; i < l; i++) {
*pd++ = ps[0];
*pd++ = ps[1];
}
ps += 2;
+ src_size -= 2;
}
i += l;
- } while (i < src_len);
+ } while (i < src_count);
return ps - src;
}
@@ -191,6 +214,7 @@ static void vmd_decode(VmdVideoContext *s)
const unsigned char *p = s->buf + 16;
const unsigned char *pb;
+ unsigned int pb_size;
unsigned char meth;
unsigned char *dp; /* pointer to current frame */
unsigned char *pp; /* pointer to previous frame */
@@ -204,6 +228,16 @@ static void vmd_decode(VmdVideoContext *s)
frame_y = AV_RL16(&s->buf[8]);
frame_width = AV_RL16(&s->buf[10]) - frame_x + 1;
frame_height = AV_RL16(&s->buf[12]) - frame_y + 1;
+ if (frame_x < 0 || frame_width < 0 ||
+ frame_x >= s->avctx->width ||
+ frame_width > s->avctx->width ||
+ frame_x + frame_width > s->avctx->width)
+ return;
+ if (frame_y < 0 || frame_height < 0 ||
+ frame_y >= s->avctx->height ||
+ frame_height > s->avctx->height ||
+ frame_y + frame_height > s->avctx->height)
+ return;
if ((frame_width == s->avctx->width && frame_height == s->avctx->height) &&
(frame_x || frame_y)) {
@@ -216,8 +250,9 @@ static void vmd_decode(VmdVideoContext *s)
/* if only a certain region will be updated, copy the entire previous
* frame before the decode */
- if (frame_x || frame_y || (frame_width != s->avctx->width) ||
- (frame_height != s->avctx->height)) {
+ if (s->prev_frame.data[0] &&
+ (frame_x || frame_y || (frame_width != s->avctx->width) ||
+ (frame_height != s->avctx->height))) {
memcpy(s->frame.data[0], s->prev_frame.data[0],
s->avctx->height * s->frame.linesize[0]);
@@ -235,14 +270,19 @@ static void vmd_decode(VmdVideoContext *s)
}
s->size -= (256 * 3 + 2);
}
- if (s->size >= 0) {
+ if (s->size > 0) {
/* originally UnpackFrame in VAG's code */
pb = p;
- meth = *pb++;
+ pb_size = s->buf + s->size - pb;
+ if (pb_size < 1)
+ return;
+ meth = *pb++; pb_size--;
if (meth & 0x80) {
- lz_unpack(pb, s->unpack_buffer, s->unpack_buffer_size);
+ lz_unpack(pb, pb_size,
+ s->unpack_buffer, s->unpack_buffer_size);
meth &= 0x7F;
pb = s->unpack_buffer;
+ pb_size = s->unpack_buffer_size;
}
dp = &s->frame.data[0][frame_y * s->frame.linesize[0] + frame_x];
@@ -252,17 +292,21 @@ static void vmd_decode(VmdVideoContext *s)
for (i = 0; i < frame_height; i++) {
ofs = 0;
do {
+ if (pb_size < 1)
+ return;
len = *pb++;
+ pb_size--;
if (len & 0x80) {
len = (len & 0x7F) + 1;
- if (ofs + len > frame_width)
+ if (ofs + len > frame_width || pb_size < len)
return;
memcpy(&dp[ofs], pb, len);
pb += len;
+ pb_size -= len;
ofs += len;
} else {
/* interframe pixel copy */
- if (ofs + len + 1 > frame_width)
+ if (ofs + len + 1 > frame_width || !s->prev_frame.data[0])
return;
memcpy(&dp[ofs], &pp[ofs], len + 1);
ofs += len + 1;
@@ -280,8 +324,11 @@ static void vmd_decode(VmdVideoContext *s)
case 2:
for (i = 0; i < frame_height; i++) {
+ if (pb_size < frame_width)
+ return;
memcpy(dp, pb, frame_width);
pb += frame_width;
+ pb_size -= frame_width;
dp += s->frame.linesize[0];
pp += s->prev_frame.linesize[0];
}
@@ -291,18 +338,27 @@ static void vmd_decode(VmdVideoContext *s)
for (i = 0; i < frame_height; i++) {
ofs = 0;
do {
+ if (pb_size < 1)
+ return;
len = *pb++;
+ pb_size--;
if (len & 0x80) {
len = (len & 0x7F) + 1;
+ if (pb_size < 1)
+ return;
if (*pb++ == 0xFF)
- len = rle_unpack(pb, &dp[ofs], len, frame_width - ofs);
- else
+ len = rle_unpack(pb, &dp[ofs], len, pb_size, frame_width - ofs);
+ else {
+ if (pb_size < len)
+ return;
memcpy(&dp[ofs], pb, len);
+ }
pb += len;
+ pb_size -= 1 + len;
ofs += len;
} else {
/* interframe pixel copy */
- if (ofs + len + 1 > frame_width)
+ if (ofs + len + 1 > frame_width || !s->prev_frame.data[0])
return;
memcpy(&dp[ofs], &pp[ofs], len + 1);
ofs += len + 1;
diff --git a/libavcodec/vp3.c b/libavcodec/vp3.c
index c117a64..890db5c 100644
--- a/libavcodec/vp3.c
+++ b/libavcodec/vp3.c
@@ -1291,6 +1291,10 @@ static inline int vp3_dequant(Vp3DecodeContext *s, Vp3Fragment *frag,
case 1: // zero run
s->dct_tokens[plane][i]++;
i += (token >> 2) & 0x7f;
+ if (i > 63) {
+ av_log(s->avctx, AV_LOG_ERROR, "Coefficient index overflow\n");
+ return i;
+ }
block[perm[i]] = (token >> 9) * dequantizer[perm[i]];
i++;
break;
@@ -1493,7 +1497,10 @@ static void render_slice(Vp3DecodeContext *s, int slice)
/* invert DCT and place (or add) in final output */
if (s->all_fragments[i].coding_method == MODE_INTRA) {
- vp3_dequant(s, s->all_fragments + i, plane, 0, block);
+ int index;
+ index = vp3_dequant(s, s->all_fragments + i, plane, 0, block);
+ if (index > 63)
+ continue;
if(s->avctx->idct_algo!=FF_IDCT_VP3)
block[0] += 128<<3;
s->dsp.idct_put(
@@ -1501,7 +1508,10 @@ static void render_slice(Vp3DecodeContext *s, int slice)
stride,
block);
} else {
- if (vp3_dequant(s, s->all_fragments + i, plane, 1, block)) {
+ int index = vp3_dequant(s, s->all_fragments + i, plane, 1, block);
+ if (index > 63)
+ continue;
+ if (index > 0) {
s->dsp.idct_add(
output_plane + first_pixel,
stride,
diff --git a/libavcodec/vp5.c b/libavcodec/vp5.c
index 807309f..d61163e 100644
--- a/libavcodec/vp5.c
+++ b/libavcodec/vp5.c
@@ -116,7 +116,7 @@ static void vp5_parse_vector_models(VP56Context *s)
model->vector_pdv[comp][node] = vp56_rac_gets_nn(c, 7);
}
-static void vp5_parse_coeff_models(VP56Context *s)
+static int vp5_parse_coeff_models(VP56Context *s)
{
VP56RangeCoder *c = &s->c;
VP56Model *model = s->modelp;
@@ -160,6 +160,7 @@ static void vp5_parse_coeff_models(VP56Context *s)
for (ctx=0; ctx<6; ctx++)
for (node=0; node<5; node++)
model->coeff_acct[pt][ct][cg][ctx][node] = av_clip(((model->coeff_ract[pt][ct][cg][node] * vp5_ract_lc[ct][cg][node][ctx][0] + 128) >> 8) + vp5_ract_lc[ct][cg][node][ctx][1], 1, 254);
+ return 0;
}
static void vp5_parse_coeff(VP56Context *s)
diff --git a/libavcodec/vp56.c b/libavcodec/vp56.c
index a181978..a6b2014 100644
--- a/libavcodec/vp56.c
+++ b/libavcodec/vp56.c
@@ -537,7 +537,8 @@ int ff_vp56_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
s->mb_type = VP56_MB_INTER_NOVEC_PF;
}
- s->parse_coeff_models(s);
+ if (s->parse_coeff_models(s))
+ goto next;
memset(s->prev_dc, 0, sizeof(s->prev_dc));
s->prev_dc[1][VP56_FRAME_CURRENT] = 128;
@@ -601,6 +602,7 @@ int ff_vp56_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
}
}
+ next:
if (p->key_frame || golden_frame) {
if (s->framep[VP56_FRAME_GOLDEN]->data[0] &&
s->framep[VP56_FRAME_GOLDEN] != s->framep[VP56_FRAME_GOLDEN2])
diff --git a/libavcodec/vp56.h b/libavcodec/vp56.h
index 5a55f7d..0c34438 100644
--- a/libavcodec/vp56.h
+++ b/libavcodec/vp56.h
@@ -46,7 +46,7 @@ typedef void (*VP56Filter)(VP56Context *s, uint8_t *dst, uint8_t *src,
typedef void (*VP56ParseCoeff)(VP56Context *s);
typedef void (*VP56DefaultModelsInit)(VP56Context *s);
typedef void (*VP56ParseVectorModels)(VP56Context *s);
-typedef void (*VP56ParseCoeffModels)(VP56Context *s);
+typedef int (*VP56ParseCoeffModels)(VP56Context *s);
typedef int (*VP56ParseHeader)(VP56Context *s, const uint8_t *buf,
int buf_size, int *golden_frame);
diff --git a/libavcodec/vp6.c b/libavcodec/vp6.c
index 4f3f402..02fe70b 100644
--- a/libavcodec/vp6.c
+++ b/libavcodec/vp6.c
@@ -137,8 +137,11 @@ static int vp6_parse_header(VP56Context *s, const uint8_t *buf, int buf_size,
if (coeff_offset) {
buf += coeff_offset;
buf_size -= coeff_offset;
- if (buf_size < 0)
+ if (buf_size < 0) {
+ if (s->framep[VP56_FRAME_CURRENT]->key_frame)
+ avcodec_set_dimensions(s->avctx, 0, 0);
return 0;
+ }
if (s->use_huffman) {
s->parse_coeff = vp6_parse_coeff_huffman;
init_get_bits(&s->gb, buf, buf_size<<3);
@@ -213,8 +216,8 @@ static int vp6_huff_cmp(const void *va, const void *vb)
return (a->count - b->count)*16 + (b->sym - a->sym);
}
-static void vp6_build_huff_tree(VP56Context *s, uint8_t coeff_model[],
- const uint8_t *map, unsigned size, VLC *vlc)
+static int vp6_build_huff_tree(VP56Context *s, uint8_t coeff_model[],
+ const uint8_t *map, unsigned size, VLC *vlc)
{
Node nodes[2*VP6_MAX_HUFF_SIZE], *tmp = &nodes[size];
int a, b, i;
@@ -229,12 +232,12 @@ static void vp6_build_huff_tree(VP56Context *s, uint8_t coeff_model[],
}
free_vlc(vlc);
- /* then build the huffman tree accodring to probabilities */
- ff_huff_build_tree(s->avctx, vlc, size, nodes, vp6_huff_cmp,
- FF_HUFFMAN_FLAG_HNODE_FIRST);
+ /* then build the huffman tree according to probabilities */
+ return ff_huff_build_tree(s->avctx, vlc, size, nodes, vp6_huff_cmp,
+ FF_HUFFMAN_FLAG_HNODE_FIRST);
}
-static void vp6_parse_coeff_models(VP56Context *s)
+static int vp6_parse_coeff_models(VP56Context *s)
{
VP56RangeCoder *c = &s->c;
VP56Model *model = s->modelp;
@@ -279,15 +282,18 @@ static void vp6_parse_coeff_models(VP56Context *s)
if (s->use_huffman) {
for (pt=0; pt<2; pt++) {
- vp6_build_huff_tree(s, model->coeff_dccv[pt],
- vp6_huff_coeff_map, 12, &s->dccv_vlc[pt]);
- vp6_build_huff_tree(s, model->coeff_runv[pt],
- vp6_huff_run_map, 9, &s->runv_vlc[pt]);
+ if (vp6_build_huff_tree(s, model->coeff_dccv[pt],
+ vp6_huff_coeff_map, 12, &s->dccv_vlc[pt]))
+ return -1;
+ if (vp6_build_huff_tree(s, model->coeff_runv[pt],
+ vp6_huff_run_map, 9, &s->runv_vlc[pt]))
+ return -1;
for (ct=0; ct<3; ct++)
for (cg = 0; cg < 6; cg++)
- vp6_build_huff_tree(s, model->coeff_ract[pt][ct][cg],
- vp6_huff_coeff_map, 12,
- &s->ract_vlc[pt][ct][cg]);
+ if (vp6_build_huff_tree(s, model->coeff_ract[pt][ct][cg],
+ vp6_huff_coeff_map, 12,
+ &s->ract_vlc[pt][ct][cg]))
+ return -1;
}
memset(s->nb_null, 0, sizeof(s->nb_null));
} else {
@@ -297,6 +303,7 @@ static void vp6_parse_coeff_models(VP56Context *s)
for (node=0; node<5; node++)
model->coeff_dcct[pt][ctx][node] = av_clip(((model->coeff_dccv[pt][node] * vp6_dccv_lc[ctx][node][0] + 128) >> 8) + vp6_dccv_lc[ctx][node][1], 1, 255);
}
+ return 0;
}
static void vp6_parse_vector_adjustment(VP56Context *s, VP56mv *vect)
@@ -367,7 +374,7 @@ static void vp6_parse_coeff_huffman(VP56Context *s)
if (b > 3) pt = 1;
vlc_coeff = &s->dccv_vlc[pt];
- for (coeff_idx=0; coeff_idx<64; ) {
+ for (coeff_idx = 0;;) {
int run = 1;
if (coeff_idx<2 && s->nb_null[coeff_idx][pt]) {
s->nb_null[coeff_idx][pt]--;
@@ -404,6 +411,8 @@ static void vp6_parse_coeff_huffman(VP56Context *s)
}
}
coeff_idx+=run;
+ if (coeff_idx >= 64)
+ break;
cg = FFMIN(vp6_coeff_groups[coeff_idx], 3);
vlc_coeff = &s->ract_vlc[pt][ct][cg];
}
@@ -431,7 +440,8 @@ static void vp6_parse_coeff(VP56Context *s)
model1 = model->coeff_dccv[pt];
model2 = model->coeff_dcct[pt][ctx];
- for (coeff_idx=0; coeff_idx<64; ) {
+ coeff_idx = 0;
+ for (;;) {
if ((coeff_idx>1 && ct==0) || vp56_rac_get_prob(c, model2[0])) {
/* parse a coeff */
if (vp56_rac_get_prob(c, model2[2])) {
@@ -472,8 +482,10 @@ static void vp6_parse_coeff(VP56Context *s)
run += vp56_rac_get_prob(c, model3[i+8]) << i;
}
}
-
- cg = vp6_coeff_groups[coeff_idx+=run];
+ coeff_idx += run;
+ if (coeff_idx >= 64)
+ break;
+ cg = vp6_coeff_groups[coeff_idx];
model1 = model2 = model->coeff_ract[pt][ct][cg];
}
diff --git a/libavcodec/wma.c b/libavcodec/wma.c
index bed47ec..4cdffcd 100644
--- a/libavcodec/wma.c
+++ b/libavcodec/wma.c
@@ -137,6 +137,9 @@ int ff_wma_init(AVCodecContext *avctx, int flags2)
/* compute MDCT block size */
s->frame_len_bits = ff_wma_get_frame_len_bits(s->sample_rate, s->version, 0);
+ s->next_block_len_bits = s->frame_len_bits;
+ s->prev_block_len_bits = s->frame_len_bits;
+ s->block_len_bits = s->frame_len_bits;
s->frame_len = 1 << s->frame_len_bits;
if (s->use_variable_block_len) {
diff --git a/libavfilter/vsrc_movie.c b/libavfilter/vsrc_movie.c
index 7556fa2..b018ba7 100644
--- a/libavfilter/vsrc_movie.c
+++ b/libavfilter/vsrc_movie.c
@@ -96,7 +96,7 @@ static int movie_init(AVFilterContext *ctx)
"Failed to avformat_open_input '%s'\n", movie->file_name);
return ret;
}
- if ((ret = av_find_stream_info(movie->format_ctx)) < 0)
+ if ((ret = avformat_find_stream_info(movie->format_ctx, NULL)) < 0)
av_log(ctx, AV_LOG_WARNING, "Failed to find stream info\n");
// if seeking requested, we execute it
@@ -139,7 +139,7 @@ static int movie_init(AVFilterContext *ctx)
return AVERROR(EINVAL);
}
- if ((ret = avcodec_open(movie->codec_ctx, codec)) < 0) {
+ if ((ret = avcodec_open2(movie->codec_ctx, codec, NULL)) < 0) {
av_log(ctx, AV_LOG_ERROR, "Failed to open codec\n");
return ret;
}
diff --git a/libavformat/avformat.h b/libavformat/avformat.h
index 8561a50..c11d650 100644
--- a/libavformat/avformat.h
+++ b/libavformat/avformat.h
@@ -1081,6 +1081,7 @@ int avformat_open_input(AVFormatContext **ps, const char *filename, AVInputForma
*/
AVFormatContext *avformat_alloc_context(void);
+#if FF_API_FORMAT_PARAMETERS
/**
* Read packets of a media file to get stream information. This
* is useful for file formats with no headers such as MPEG. This
@@ -1093,8 +1094,34 @@ AVFormatContext *avformat_alloc_context(void);
* @return >=0 if OK, AVERROR_xxx on error
* @todo Let the user decide somehow what information is needed so that
* we do not waste time getting stuff the user does not need.
+ *
+ * @deprecated use avformat_find_stream_info.
*/
int av_find_stream_info(AVFormatContext *ic);
+#endif
+
+/**
+ * Read packets of a media file to get stream information. This
+ * is useful for file formats with no headers such as MPEG. This
+ * function also computes the real framerate in case of MPEG-2 repeat
+ * frame mode.
+ * The logical file position is not changed by this function;
+ * examined packets may be buffered for later processing.
+ *
+ * @param ic media file handle
+ * @param options If non-NULL, an ic.nb_streams long array of pointers to
+ * dictionaries, where i-th member contains options for
+ * codec corresponding to i-th stream.
+ * On return each dictionary will be filled with options that were not found.
+ * @return >=0 if OK, AVERROR_xxx on error
+ *
+ * @note this function isn't guaranteed to open all the codecs, so
+ * options being non-empty at return is a perfectly normal behavior.
+ *
+ * @todo Let the user decide somehow what information is needed so that
+ * we do not waste time getting stuff the user does not need.
+ */
+int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options);
/**
* Find the "best" stream in the file.
diff --git a/libavformat/utils.c b/libavformat/utils.c
index e3c7d4a..aa3ca59 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -2074,7 +2074,7 @@ static int has_decode_delay_been_guessed(AVStream *st)
st->codec_info_nb_frames >= 6 + st->codec->has_b_frames;
}
-static int try_decode_frame(AVStream *st, AVPacket *avpkt)
+static int try_decode_frame(AVStream *st, AVPacket *avpkt, AVDictionary **options)
{
int16_t *samples;
AVCodec *codec;
@@ -2085,7 +2085,7 @@ static int try_decode_frame(AVStream *st, AVPacket *avpkt)
codec = avcodec_find_decoder(st->codec->codec_id);
if (!codec)
return -1;
- ret = avcodec_open(st->codec, codec);
+ ret = avcodec_open2(st->codec, codec, options);
if (ret < 0)
return ret;
}
@@ -2204,12 +2204,20 @@ static int tb_unreliable(AVCodecContext *c){
return 0;
}
+#if FF_API_FORMAT_PARAMETERS
int av_find_stream_info(AVFormatContext *ic)
{
+ return avformat_find_stream_info(ic, NULL);
+}
+#endif
+
+int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
+{
int i, count, ret, read_size, j;
AVStream *st;
AVPacket pkt1, *pkt;
int64_t old_offset = avio_tell(ic->pb);
+ int orig_nb_streams = ic->nb_streams; // new streams might appear, no options for those
for(i=0;i<ic->nb_streams;i++) {
AVCodec *codec;
@@ -2246,12 +2254,12 @@ int av_find_stream_info(AVFormatContext *ic)
/* Ensure that subtitle_header is properly set. */
if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE
&& codec && !st->codec->codec)
- avcodec_open(st->codec, codec);
+ avcodec_open2(st->codec, codec, options ? &options[i] : NULL);
//try to just open decoders, in case this is enough to get parameters
if(!has_codec_parameters(st->codec)){
if (codec && !st->codec->codec)
- avcodec_open(st->codec, codec);
+ avcodec_open2(st->codec, codec, options ? &options[i] : NULL);
}
}
@@ -2360,7 +2368,7 @@ int av_find_stream_info(AVFormatContext *ic)
for (i=1; i<FF_ARRAY_ELEMS(st->info->duration_error); i++) {
int framerate= get_std_framerate(i);
int ticks= lrintf(dur*framerate/(1001*12));
- double error= dur - ticks*1001*12/(double)framerate;
+ double error = dur - (double)ticks*1001*12 / framerate;
st->info->duration_error[i] += error*error;
}
st->info->duration_count++;
@@ -2386,7 +2394,7 @@ int av_find_stream_info(AVFormatContext *ic)
it takes longer and uses more memory. For MPEG-4, we need to
decompress for QuickTime. */
if (!has_codec_parameters(st->codec) || !has_decode_delay_been_guessed(st))
- try_decode_frame(st, pkt);
+ try_decode_frame(st, pkt, (options && i < orig_nb_streams )? &options[i] : NULL);
st->codec_info_nb_frames++;
count++;
diff --git a/libavformat/version.h b/libavformat/version.h
index 3cc1718..635b582 100644
--- a/libavformat/version.h
+++ b/libavformat/version.h
@@ -24,7 +24,7 @@
#include "libavutil/avutil.h"
#define LIBAVFORMAT_VERSION_MAJOR 53
-#define LIBAVFORMAT_VERSION_MINOR 2
+#define LIBAVFORMAT_VERSION_MINOR 3
#define LIBAVFORMAT_VERSION_MICRO 0
#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
diff --git a/libavutil/imgutils.c b/libavutil/imgutils.c
index 46853ca..9dc4f01 100644
--- a/libavutil/imgutils.c
+++ b/libavutil/imgutils.c
@@ -117,7 +117,7 @@ int av_image_fill_pointers(uint8_t *data[4], enum PixelFormat pix_fmt, int heigh
has_plane[desc->comp[i].plane] = 1;
total_size = size[0];
- for (i = 1; has_plane[i] && i < 4; i++) {
+ for (i = 1; i < 4 && has_plane[i]; i++) {
int h, s = (i == 1 || i == 2) ? desc->log2_chroma_h : 0;
data[i] = data[i-1] + size[i-1];
h = (height + (1 << s) - 1) >> s;
diff --git a/libswscale/utils.c b/libswscale/utils.c
index d048b22..ac22dfe 100644
--- a/libswscale/utils.c
+++ b/libswscale/utils.c
@@ -18,6 +18,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#define _SVID_SOURCE //needed for MAP_ANONYMOUS
#include <inttypes.h>
#include <string.h>
#include <math.h>
@@ -42,6 +43,7 @@
#include "libavutil/cpu.h"
#include "libavutil/avutil.h"
#include "libavutil/bswap.h"
+#include "libavutil/mathematics.h"
#include "libavutil/opt.h"
#include "libavutil/pixdesc.h"
--
Libav/FFmpeg packaging
More information about the pkg-multimedia-commits
mailing list