Merge commit '5c54fc6195e52c329b88cf5a56d18628f0ee0029' into release/1.1
* commit '5c54fc6195e52c329b88cf5a56d18628f0ee0029': Prepare for 9.8 RELEASE update Changelog smacker: check frame size validity smacker: pad the extradata allocation smacker: check the return value of smacker_decode_tree smacker: fix an off by one in huff.length computation 4xm: do not overread the prestream buffer 4xm: validate the buffer size before parsing it 4xm: reject frames not compatible with the declared version 4xm: drop pointless assert 4xm: forward errors from decode_p_block 4xm: fold last_picture lazy allocation in decode_p_frame 4xm: do not overread while parsing header 4xm: refactor fourxm_read_header 4xm: K&R formatting cosmetics 4xm: use the correct logging context Conflicts: Changelog RELEASE libavcodec/4xm.c libavcodec/smacker.c libavformat/4xm.c libavformat/smacker.c Merged-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
21
Changelog
21
Changelog
@@ -2,6 +2,27 @@ Entries are sorted chronologically from oldest to youngest within each release,
|
|||||||
releases are sorted from youngest to oldest.
|
releases are sorted from youngest to oldest.
|
||||||
|
|
||||||
version <next>:
|
version <next>:
|
||||||
|
|
||||||
|
Most of the following fixes resulted from test samples that the Google
|
||||||
|
Security Team has kindly made available to us:
|
||||||
|
|
||||||
|
- 4xm: fix several programming errors to avoid crashes, etc.
|
||||||
|
- apetag: use int64_t for filesize
|
||||||
|
- jpegls: Fix invalid writes to memory
|
||||||
|
- ljpeg: use the correct number of components in YUV
|
||||||
|
- mjpeg: Validate sampling factors
|
||||||
|
- mjpegdec: properly report unsupported disabled features
|
||||||
|
- mjpegdec: validate parameters in mjpeg_decode_scan_progressive_ac
|
||||||
|
- mpegvideo: allocate sufficiently large scratch buffer for interlaced vid
|
||||||
|
- pixdesc: mark gray8 as pseudopal
|
||||||
|
- smacker: fix several programming errors to avoid crashes, etc.
|
||||||
|
- tiff: do not overread the source buffer
|
||||||
|
- vmd: drop incomplete chunks and spurious samples
|
||||||
|
- vmdav: convert to bytestream2 to avoid invalid reads and writes
|
||||||
|
- wavpack: check packet size early
|
||||||
|
- wavpack: use bytestream2 in wavpack_decode_block
|
||||||
|
- wavpack: validate samples size parsed in wavpack_decode_block
|
||||||
|
|
||||||
- aac: check the maximum number of channels to avoid invalid writes
|
- aac: check the maximum number of channels to avoid invalid writes
|
||||||
- indeo3: fix off by one in MV validity check
|
- indeo3: fix off by one in MV validity check
|
||||||
- id3v2: check for end of file while unescaping tags to avoid invalid
|
- id3v2: check for end of file while unescaping tags to avoid invalid
|
||||||
|
|||||||
112
libavcodec/4xm.c
112
libavcodec/4xm.c
@@ -328,12 +328,12 @@ static inline void mcdc(uint16_t *dst, const uint16_t *src, int log2w,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
av_assert2(0);
|
av_assert0(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void decode_p_block(FourXContext *f, uint16_t *dst, uint16_t *src,
|
static int decode_p_block(FourXContext *f, uint16_t *dst, uint16_t *src,
|
||||||
int log2w, int log2h, int stride)
|
int log2w, int log2h, int stride)
|
||||||
{
|
{
|
||||||
const int index = size2index[log2h][log2w];
|
const int index = size2index[log2h][log2w];
|
||||||
const int h = 1 << log2h;
|
const int h = 1 << log2h;
|
||||||
@@ -342,57 +342,64 @@ static void decode_p_block(FourXContext *f, uint16_t *dst, uint16_t *src,
|
|||||||
BLOCK_TYPE_VLC_BITS, 1);
|
BLOCK_TYPE_VLC_BITS, 1);
|
||||||
uint16_t *start = (uint16_t *)f->last_picture.data[0];
|
uint16_t *start = (uint16_t *)f->last_picture.data[0];
|
||||||
uint16_t *end = start + stride * (f->avctx->height - h + 1) - (1 << log2w);
|
uint16_t *end = start + stride * (f->avctx->height - h + 1) - (1 << log2w);
|
||||||
|
int ret;
|
||||||
|
|
||||||
av_assert2(code >= 0 && code <= 6);
|
av_assert0(code >= 0 && code <= 6 && log2w >= 0);
|
||||||
|
|
||||||
if (code == 0) {
|
if (code == 0) {
|
||||||
if (bytestream2_get_bytes_left(&f->g) < 1) {
|
if (bytestream2_get_bytes_left(&f->g) < 1) {
|
||||||
av_log(f->avctx, AV_LOG_ERROR, "bytestream overread\n");
|
av_log(f->avctx, AV_LOG_ERROR, "bytestream overread\n");
|
||||||
return;
|
return AVERROR_INVALIDDATA;
|
||||||
}
|
}
|
||||||
src += f->mv[bytestream2_get_byteu(&f->g)];
|
src += f->mv[bytestream2_get_byteu(&f->g)];
|
||||||
if (start > src || src > end) {
|
if (start > src || src > end) {
|
||||||
av_log(f->avctx, AV_LOG_ERROR, "mv out of pic\n");
|
av_log(f->avctx, AV_LOG_ERROR, "mv out of pic\n");
|
||||||
return;
|
return AVERROR_INVALIDDATA;
|
||||||
}
|
}
|
||||||
mcdc(dst, src, log2w, h, stride, 1, 0);
|
mcdc(dst, src, log2w, h, stride, 1, 0);
|
||||||
} else if (code == 1) {
|
} else if (code == 1) {
|
||||||
log2h--;
|
log2h--;
|
||||||
decode_p_block(f, dst, src, log2w, log2h, stride);
|
if ((ret = decode_p_block(f, dst, src, log2w, log2h, stride)) < 0)
|
||||||
decode_p_block(f, dst + (stride << log2h),
|
return ret;
|
||||||
src + (stride << log2h), log2w, log2h, stride);
|
if ((ret = decode_p_block(f, dst + (stride << log2h),
|
||||||
|
src + (stride << log2h),
|
||||||
|
log2w, log2h, stride)) < 0)
|
||||||
|
return ret;
|
||||||
} else if (code == 2) {
|
} else if (code == 2) {
|
||||||
log2w--;
|
log2w--;
|
||||||
decode_p_block(f, dst , src, log2w, log2h, stride);
|
if ((ret = decode_p_block(f, dst , src, log2w, log2h, stride)) < 0)
|
||||||
decode_p_block(f, dst + (1 << log2w),
|
return ret;
|
||||||
src + (1 << log2w), log2w, log2h, stride);
|
if ((ret = decode_p_block(f, dst + (1 << log2w),
|
||||||
|
src + (1 << log2w),
|
||||||
|
log2w, log2h, stride)) < 0)
|
||||||
|
return ret;
|
||||||
} else if (code == 3 && f->version < 2) {
|
} else if (code == 3 && f->version < 2) {
|
||||||
mcdc(dst, src, log2w, h, stride, 1, 0);
|
mcdc(dst, src, log2w, h, stride, 1, 0);
|
||||||
} else if (code == 4) {
|
} else if (code == 4) {
|
||||||
if (bytestream2_get_bytes_left(&f->g) < 1) {
|
if (bytestream2_get_bytes_left(&f->g) < 1) {
|
||||||
av_log(f->avctx, AV_LOG_ERROR, "bytestream overread\n");
|
av_log(f->avctx, AV_LOG_ERROR, "bytestream overread\n");
|
||||||
return;
|
return AVERROR_INVALIDDATA;
|
||||||
}
|
}
|
||||||
src += f->mv[bytestream2_get_byteu(&f->g)];
|
src += f->mv[bytestream2_get_byteu(&f->g)];
|
||||||
if (start > src || src > end) {
|
if (start > src || src > end) {
|
||||||
av_log(f->avctx, AV_LOG_ERROR, "mv out of pic\n");
|
av_log(f->avctx, AV_LOG_ERROR, "mv out of pic\n");
|
||||||
return;
|
return AVERROR_INVALIDDATA;
|
||||||
}
|
}
|
||||||
if (bytestream2_get_bytes_left(&f->g2) < 2){
|
if (bytestream2_get_bytes_left(&f->g2) < 2){
|
||||||
av_log(f->avctx, AV_LOG_ERROR, "wordstream overread\n");
|
av_log(f->avctx, AV_LOG_ERROR, "wordstream overread\n");
|
||||||
return;
|
return AVERROR_INVALIDDATA;
|
||||||
}
|
}
|
||||||
mcdc(dst, src, log2w, h, stride, 1, bytestream2_get_le16u(&f->g2));
|
mcdc(dst, src, log2w, h, stride, 1, bytestream2_get_le16u(&f->g2));
|
||||||
} else if (code == 5) {
|
} else if (code == 5) {
|
||||||
if (bytestream2_get_bytes_left(&f->g2) < 2) {
|
if (bytestream2_get_bytes_left(&f->g2) < 2) {
|
||||||
av_log(f->avctx, AV_LOG_ERROR, "wordstream overread\n");
|
av_log(f->avctx, AV_LOG_ERROR, "wordstream overread\n");
|
||||||
return;
|
return AVERROR_INVALIDDATA;
|
||||||
}
|
}
|
||||||
mcdc(dst, src, log2w, h, stride, 0, bytestream2_get_le16u(&f->g2));
|
mcdc(dst, src, log2w, h, stride, 0, bytestream2_get_le16u(&f->g2));
|
||||||
} else if (code == 6) {
|
} else if (code == 6) {
|
||||||
if (bytestream2_get_bytes_left(&f->g2) < 4) {
|
if (bytestream2_get_bytes_left(&f->g2) < 4) {
|
||||||
av_log(f->avctx, AV_LOG_ERROR, "wordstream overread\n");
|
av_log(f->avctx, AV_LOG_ERROR, "wordstream overread\n");
|
||||||
return;
|
return AVERROR_INVALIDDATA;
|
||||||
}
|
}
|
||||||
if (log2w) {
|
if (log2w) {
|
||||||
dst[0] = bytestream2_get_le16u(&f->g2);
|
dst[0] = bytestream2_get_le16u(&f->g2);
|
||||||
@@ -402,6 +409,7 @@ static void decode_p_block(FourXContext *f, uint16_t *dst, uint16_t *src,
|
|||||||
dst[stride] = bytestream2_get_le16u(&f->g2);
|
dst[stride] = bytestream2_get_le16u(&f->g2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int decode_p_frame(FourXContext *f, const uint8_t *buf, int length)
|
static int decode_p_frame(FourXContext *f, const uint8_t *buf, int length)
|
||||||
@@ -414,8 +422,20 @@ static int decode_p_frame(FourXContext *f, const uint8_t *buf, int length)
|
|||||||
const int stride = f->current_picture.linesize[0] >> 1;
|
const int stride = f->current_picture.linesize[0] >> 1;
|
||||||
unsigned int bitstream_size, bytestream_size, wordstream_size, extra,
|
unsigned int bitstream_size, bytestream_size, wordstream_size, extra,
|
||||||
bytestream_offset, wordstream_offset;
|
bytestream_offset, wordstream_offset;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (!f->last_picture.data[0]) {
|
||||||
|
if ((ret = ff_get_buffer(f->avctx, &f->last_picture)) < 0) {
|
||||||
|
av_log(f->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
for (y=0; y<f->avctx->height; y++)
|
||||||
|
memset(f->last_picture.data[0] + y*f->last_picture.linesize[0], 0, 2*f->avctx->width);
|
||||||
|
}
|
||||||
|
|
||||||
if (f->version > 1) {
|
if (f->version > 1) {
|
||||||
|
if (length < 20)
|
||||||
|
return AVERROR_INVALIDDATA;
|
||||||
extra = 20;
|
extra = 20;
|
||||||
if (length < extra)
|
if (length < extra)
|
||||||
return -1;
|
return -1;
|
||||||
@@ -459,7 +479,8 @@ static int decode_p_frame(FourXContext *f, const uint8_t *buf, int length)
|
|||||||
|
|
||||||
for (y = 0; y < height; y += 8) {
|
for (y = 0; y < height; y += 8) {
|
||||||
for (x = 0; x < width; x += 8)
|
for (x = 0; x < width; x += 8)
|
||||||
decode_p_block(f, dst + x, src + x, 3, 3, stride);
|
if ((ret = decode_p_block(f, dst + x, src + x, 3, 3, stride)) < 0)
|
||||||
|
return ret;
|
||||||
src += 8 * stride;
|
src += 8 * stride;
|
||||||
dst += 8 * stride;
|
dst += 8 * stride;
|
||||||
}
|
}
|
||||||
@@ -579,7 +600,8 @@ static int decode_i_mb(FourXContext *f)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static const uint8_t *read_huffman_tables(FourXContext *f,
|
static const uint8_t *read_huffman_tables(FourXContext *f,
|
||||||
const uint8_t * const buf, int buf_size)
|
const uint8_t * const buf,
|
||||||
|
int buf_size)
|
||||||
{
|
{
|
||||||
int frequency[512] = { 0 };
|
int frequency[512] = { 0 };
|
||||||
uint8_t flag[512];
|
uint8_t flag[512];
|
||||||
@@ -598,8 +620,11 @@ static const uint8_t *read_huffman_tables(FourXContext *f,
|
|||||||
for (;;) {
|
for (;;) {
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (start <= end && ptr_end - ptr < end - start + 1 + 1)
|
if (ptr_end - ptr < FFMAX(end - start + 1, 0) + 1) {
|
||||||
|
av_log(f->avctx, AV_LOG_ERROR, "invalid data in read_huffman_tables\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = start; i <= end; i++)
|
for (i = start; i <= end; i++)
|
||||||
frequency[i] = *ptr++;
|
frequency[i] = *ptr++;
|
||||||
start = *ptr++;
|
start = *ptr++;
|
||||||
@@ -701,9 +726,9 @@ static int decode_i2_frame(FourXContext *f, const uint8_t *buf, int length)
|
|||||||
color[1] = bytestream2_get_le16u(&g3);
|
color[1] = bytestream2_get_le16u(&g3);
|
||||||
|
|
||||||
if (color[0] & 0x8000)
|
if (color[0] & 0x8000)
|
||||||
av_log(NULL, AV_LOG_ERROR, "unk bit 1\n");
|
av_log(f->avctx, AV_LOG_ERROR, "unk bit 1\n");
|
||||||
if (color[1] & 0x8000)
|
if (color[1] & 0x8000)
|
||||||
av_log(NULL, AV_LOG_ERROR, "unk bit 2\n");
|
av_log(f->avctx, AV_LOG_ERROR, "unk bit 2\n");
|
||||||
|
|
||||||
color[2] = mix(color[0], color[1]);
|
color[2] = mix(color[0], color[1]);
|
||||||
color[3] = mix(color[1], color[0]);
|
color[3] = mix(color[1], color[0]);
|
||||||
@@ -748,7 +773,7 @@ static int decode_i_frame(FourXContext *f, const uint8_t *buf, int length)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
prestream = read_huffman_tables(f, prestream, buf + length - prestream);
|
prestream = read_huffman_tables(f, prestream, prestream_size);
|
||||||
if (!prestream) {
|
if (!prestream) {
|
||||||
av_log(f->avctx, AV_LOG_ERROR, "Error reading Huffman tables.\n");
|
av_log(f->avctx, AV_LOG_ERROR, "Error reading Huffman tables.\n");
|
||||||
return AVERROR_INVALIDDATA;
|
return AVERROR_INVALIDDATA;
|
||||||
@@ -795,30 +820,38 @@ static int decode_frame(AVCodecContext *avctx, void *data,
|
|||||||
AVFrame *p, temp;
|
AVFrame *p, temp;
|
||||||
int i, frame_4cc, frame_size;
|
int i, frame_4cc, frame_size;
|
||||||
|
|
||||||
if (buf_size < 12)
|
if (buf_size < 20)
|
||||||
return AVERROR_INVALIDDATA;
|
return AVERROR_INVALIDDATA;
|
||||||
frame_4cc = AV_RL32(buf);
|
|
||||||
if (buf_size != AV_RL32(buf + 4) + 8 || buf_size < 20)
|
av_assert0(avctx->width % 16 == 0 && avctx->height % 16 == 0);
|
||||||
|
|
||||||
|
if (buf_size < AV_RL32(buf + 4) + 8) {
|
||||||
av_log(f->avctx, AV_LOG_ERROR, "size mismatch %d %d\n",
|
av_log(f->avctx, AV_LOG_ERROR, "size mismatch %d %d\n",
|
||||||
buf_size, AV_RL32(buf + 4));
|
buf_size, AV_RL32(buf + 4));
|
||||||
|
return AVERROR_INVALIDDATA;
|
||||||
|
}
|
||||||
|
|
||||||
|
frame_4cc = AV_RL32(buf);
|
||||||
|
|
||||||
if (frame_4cc == AV_RL32("cfrm")) {
|
if (frame_4cc == AV_RL32("cfrm")) {
|
||||||
int free_index = -1;
|
int free_index = -1;
|
||||||
|
int id, whole_size;
|
||||||
const int data_size = buf_size - 20;
|
const int data_size = buf_size - 20;
|
||||||
const int id = AV_RL32(buf + 12);
|
|
||||||
const int whole_size = AV_RL32(buf + 16);
|
|
||||||
CFrameBuffer *cfrm;
|
CFrameBuffer *cfrm;
|
||||||
|
|
||||||
if (data_size < 0 || whole_size < 0) {
|
|
||||||
av_log(f->avctx, AV_LOG_ERROR, "sizes invalid\n");
|
|
||||||
return AVERROR_INVALIDDATA;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (f->version <= 1) {
|
if (f->version <= 1) {
|
||||||
av_log(f->avctx, AV_LOG_ERROR, "cfrm in version %d\n", f->version);
|
av_log(f->avctx, AV_LOG_ERROR, "cfrm in version %d\n", f->version);
|
||||||
return AVERROR_INVALIDDATA;
|
return AVERROR_INVALIDDATA;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
id = AV_RL32(buf + 12);
|
||||||
|
whole_size = AV_RL32(buf + 16);
|
||||||
|
|
||||||
|
if (data_size < 0 || whole_size < 0) {
|
||||||
|
av_log(f->avctx, AV_LOG_ERROR, "sizes invalid\n");
|
||||||
|
return AVERROR_INVALIDDATA;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < CFRAME_BUFFER_COUNT; i++)
|
for (i = 0; i < CFRAME_BUFFER_COUNT; i++)
|
||||||
if (f->cfrm[i].id && f->cfrm[i].id < avctx->frame_number)
|
if (f->cfrm[i].id && f->cfrm[i].id < avctx->frame_number)
|
||||||
av_log(f->avctx, AV_LOG_ERROR, "lost c frame %d\n",
|
av_log(f->avctx, AV_LOG_ERROR, "lost c frame %d\n",
|
||||||
@@ -859,6 +892,9 @@ static int decode_frame(AVCodecContext *avctx, void *data,
|
|||||||
av_log(f->avctx, AV_LOG_ERROR, "cframe id mismatch %d %d\n",
|
av_log(f->avctx, AV_LOG_ERROR, "cframe id mismatch %d %d\n",
|
||||||
id, avctx->frame_number);
|
id, avctx->frame_number);
|
||||||
|
|
||||||
|
if (f->version <= 1)
|
||||||
|
return AVERROR_INVALIDDATA;
|
||||||
|
|
||||||
cfrm->size = cfrm->id = 0;
|
cfrm->size = cfrm->id = 0;
|
||||||
frame_4cc = AV_RL32("pfrm");
|
frame_4cc = AV_RL32("pfrm");
|
||||||
} else
|
} else
|
||||||
@@ -897,16 +933,6 @@ static int decode_frame(AVCodecContext *avctx, void *data,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
} else if (frame_4cc == AV_RL32("pfrm") || frame_4cc == AV_RL32("pfr2")) {
|
} else if (frame_4cc == AV_RL32("pfrm") || frame_4cc == AV_RL32("pfr2")) {
|
||||||
if (!f->last_picture.data[0]) {
|
|
||||||
f->last_picture.reference = 3;
|
|
||||||
if (ff_get_buffer(avctx, &f->last_picture) < 0) {
|
|
||||||
av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
for (i=0; i<avctx->height; i++)
|
|
||||||
memset(f->last_picture.data[0] + i*f->last_picture.linesize[0], 0, 2*avctx->width);
|
|
||||||
}
|
|
||||||
|
|
||||||
p->pict_type = AV_PICTURE_TYPE_P;
|
p->pict_type = AV_PICTURE_TYPE_P;
|
||||||
if (decode_p_frame(f, buf, frame_size) < 0) {
|
if (decode_p_frame(f, buf, frame_size) < 0) {
|
||||||
av_log(f->avctx, AV_LOG_ERROR, "decode p frame failed\n");
|
av_log(f->avctx, AV_LOG_ERROR, "decode p frame failed\n");
|
||||||
|
|||||||
@@ -257,7 +257,7 @@ static int smacker_decode_header_tree(SmackVContext *smk, GetBitContext *gb, int
|
|||||||
ctx.recode2 = tmp2.values;
|
ctx.recode2 = tmp2.values;
|
||||||
ctx.last = last;
|
ctx.last = last;
|
||||||
|
|
||||||
huff.length = ((size + 3) >> 2) + 3;
|
huff.length = ((size + 3) >> 2) + 4;
|
||||||
huff.maxlength = 0;
|
huff.maxlength = 0;
|
||||||
huff.current = 0;
|
huff.current = 0;
|
||||||
huff.values = av_mallocz(huff.length * sizeof(int));
|
huff.values = av_mallocz(huff.length * sizeof(int));
|
||||||
@@ -661,9 +661,16 @@ static int smka_decode_frame(AVCodecContext *avctx, void *data,
|
|||||||
h[i].lengths = av_mallocz(256 * sizeof(int));
|
h[i].lengths = av_mallocz(256 * sizeof(int));
|
||||||
h[i].values = av_mallocz(256 * sizeof(int));
|
h[i].values = av_mallocz(256 * sizeof(int));
|
||||||
skip_bits1(&gb);
|
skip_bits1(&gb);
|
||||||
res = smacker_decode_tree(&gb, &h[i], 0, 0);
|
if (smacker_decode_tree(&gb, &h[i], 0, 0) < 0) {
|
||||||
if (res < 0)
|
for (; i >= 0; i--) {
|
||||||
return res;
|
if (vlc[i].table)
|
||||||
|
ff_free_vlc(&vlc[i]);
|
||||||
|
av_free(h[i].bits);
|
||||||
|
av_free(h[i].lengths);
|
||||||
|
av_free(h[i].values);
|
||||||
|
}
|
||||||
|
return AVERROR_INVALIDDATA;
|
||||||
|
}
|
||||||
skip_bits1(&gb);
|
skip_bits1(&gb);
|
||||||
if(h[i].current > 1) {
|
if(h[i].current > 1) {
|
||||||
res = init_vlc(&vlc[i], SMKTREE_BITS, h[i].length,
|
res = init_vlc(&vlc[i], SMKTREE_BITS, h[i].length,
|
||||||
|
|||||||
@@ -57,7 +57,7 @@
|
|||||||
|
|
||||||
#define GET_LIST_HEADER() \
|
#define GET_LIST_HEADER() \
|
||||||
fourcc_tag = avio_rl32(pb); \
|
fourcc_tag = avio_rl32(pb); \
|
||||||
size = avio_rl32(pb); \
|
size = avio_rl32(pb); \
|
||||||
if (fourcc_tag != LIST_TAG) \
|
if (fourcc_tag != LIST_TAG) \
|
||||||
return AVERROR_INVALIDDATA; \
|
return AVERROR_INVALIDDATA; \
|
||||||
fourcc_tag = avio_rl32(pb);
|
fourcc_tag = avio_rl32(pb);
|
||||||
@@ -72,8 +72,6 @@ typedef struct AudioTrack {
|
|||||||
} AudioTrack;
|
} AudioTrack;
|
||||||
|
|
||||||
typedef struct FourxmDemuxContext {
|
typedef struct FourxmDemuxContext {
|
||||||
int width;
|
|
||||||
int height;
|
|
||||||
int video_stream_index;
|
int video_stream_index;
|
||||||
int track_count;
|
int track_count;
|
||||||
AudioTrack *tracks;
|
AudioTrack *tracks;
|
||||||
@@ -91,6 +89,108 @@ static int fourxm_probe(AVProbeData *p)
|
|||||||
return AVPROBE_SCORE_MAX;
|
return AVPROBE_SCORE_MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int parse_vtrk(AVFormatContext *s,
|
||||||
|
FourxmDemuxContext *fourxm, uint8_t *buf, int size,
|
||||||
|
int left)
|
||||||
|
{
|
||||||
|
AVStream *st;
|
||||||
|
/* check that there is enough data */
|
||||||
|
if (size != vtrk_SIZE || left < size + 8) {
|
||||||
|
return AVERROR_INVALIDDATA;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* allocate a new AVStream */
|
||||||
|
st = avformat_new_stream(s, NULL);
|
||||||
|
if (!st)
|
||||||
|
return AVERROR(ENOMEM);
|
||||||
|
|
||||||
|
avpriv_set_pts_info(st, 60, 1, fourxm->fps);
|
||||||
|
|
||||||
|
fourxm->video_stream_index = st->index;
|
||||||
|
|
||||||
|
st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
|
||||||
|
st->codec->codec_id = AV_CODEC_ID_4XM;
|
||||||
|
st->codec->extradata_size = 4;
|
||||||
|
st->codec->extradata = av_malloc(4);
|
||||||
|
AV_WL32(st->codec->extradata, AV_RL32(buf + 16));
|
||||||
|
st->codec->width = AV_RL32(buf + 36);
|
||||||
|
st->codec->height = AV_RL32(buf + 40);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int parse_strk(AVFormatContext *s,
|
||||||
|
FourxmDemuxContext *fourxm, uint8_t *buf, int size,
|
||||||
|
int left)
|
||||||
|
{
|
||||||
|
AVStream *st;
|
||||||
|
int track;
|
||||||
|
/* check that there is enough data */
|
||||||
|
if (size != strk_SIZE || left < size + 8)
|
||||||
|
return AVERROR_INVALIDDATA;
|
||||||
|
|
||||||
|
track = AV_RL32(buf + 8);
|
||||||
|
if ((unsigned)track >= UINT_MAX / sizeof(AudioTrack) - 1) {
|
||||||
|
av_log(s, AV_LOG_ERROR, "current_track too large\n");
|
||||||
|
return AVERROR_INVALIDDATA;
|
||||||
|
}
|
||||||
|
if (track + 1 > fourxm->track_count) {
|
||||||
|
fourxm->tracks = av_realloc_f(fourxm->tracks, track + 1, sizeof(AudioTrack));
|
||||||
|
if (!fourxm->tracks)
|
||||||
|
return AVERROR(ENOMEM);
|
||||||
|
memset(&fourxm->tracks[fourxm->track_count], 0,
|
||||||
|
sizeof(AudioTrack) * (track + 1 - fourxm->track_count));
|
||||||
|
fourxm->track_count = track + 1;
|
||||||
|
}
|
||||||
|
fourxm->tracks[track].adpcm = AV_RL32(buf + 12);
|
||||||
|
fourxm->tracks[track].channels = AV_RL32(buf + 36);
|
||||||
|
fourxm->tracks[track].sample_rate = AV_RL32(buf + 40);
|
||||||
|
fourxm->tracks[track].bits = AV_RL32(buf + 44);
|
||||||
|
fourxm->tracks[track].audio_pts = 0;
|
||||||
|
|
||||||
|
if (fourxm->tracks[track].channels <= 0 ||
|
||||||
|
fourxm->tracks[track].sample_rate <= 0 ||
|
||||||
|
fourxm->tracks[track].bits < 0) {
|
||||||
|
av_log(s, AV_LOG_ERROR, "audio header invalid\n");
|
||||||
|
return AVERROR_INVALIDDATA;
|
||||||
|
}
|
||||||
|
if (!fourxm->tracks[track].adpcm && fourxm->tracks[track].bits<8) {
|
||||||
|
av_log(s, AV_LOG_ERROR, "bits unspecified for non ADPCM\n");
|
||||||
|
return AVERROR_INVALIDDATA;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* allocate a new AVStream */
|
||||||
|
st = avformat_new_stream(s, NULL);
|
||||||
|
if (!st)
|
||||||
|
return AVERROR(ENOMEM);
|
||||||
|
|
||||||
|
st->id = track;
|
||||||
|
avpriv_set_pts_info(st, 60, 1, fourxm->tracks[track].sample_rate);
|
||||||
|
|
||||||
|
fourxm->tracks[track].stream_index = st->index;
|
||||||
|
|
||||||
|
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
|
||||||
|
st->codec->codec_tag = 0;
|
||||||
|
st->codec->channels = fourxm->tracks[track].channels;
|
||||||
|
st->codec->sample_rate = fourxm->tracks[track].sample_rate;
|
||||||
|
st->codec->bits_per_coded_sample = fourxm->tracks[track].bits;
|
||||||
|
st->codec->bit_rate = st->codec->channels *
|
||||||
|
st->codec->sample_rate *
|
||||||
|
st->codec->bits_per_coded_sample;
|
||||||
|
st->codec->block_align = st->codec->channels *
|
||||||
|
st->codec->bits_per_coded_sample;
|
||||||
|
|
||||||
|
if (fourxm->tracks[track].adpcm){
|
||||||
|
st->codec->codec_id = AV_CODEC_ID_ADPCM_4XM;
|
||||||
|
} else if (st->codec->bits_per_coded_sample == 8) {
|
||||||
|
st->codec->codec_id = AV_CODEC_ID_PCM_U8;
|
||||||
|
} else
|
||||||
|
st->codec->codec_id = AV_CODEC_ID_PCM_S16LE;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int fourxm_read_header(AVFormatContext *s)
|
static int fourxm_read_header(AVFormatContext *s)
|
||||||
{
|
{
|
||||||
AVIOContext *pb = s->pb;
|
AVIOContext *pb = s->pb;
|
||||||
@@ -100,11 +200,10 @@ static int fourxm_read_header(AVFormatContext *s)
|
|||||||
FourxmDemuxContext *fourxm = s->priv_data;
|
FourxmDemuxContext *fourxm = s->priv_data;
|
||||||
unsigned char *header;
|
unsigned char *header;
|
||||||
int i, ret;
|
int i, ret;
|
||||||
AVStream *st;
|
|
||||||
|
|
||||||
fourxm->track_count = 0;
|
fourxm->track_count = 0;
|
||||||
fourxm->tracks = NULL;
|
fourxm->tracks = NULL;
|
||||||
fourxm->fps = 1.0;
|
fourxm->fps = 1.0;
|
||||||
|
|
||||||
/* skip the first 3 32-bit numbers */
|
/* skip the first 3 32-bit numbers */
|
||||||
avio_skip(pb, 12);
|
avio_skip(pb, 12);
|
||||||
@@ -119,7 +218,7 @@ static int fourxm_read_header(AVFormatContext *s)
|
|||||||
header = av_malloc(header_size);
|
header = av_malloc(header_size);
|
||||||
if (!header)
|
if (!header)
|
||||||
return AVERROR(ENOMEM);
|
return AVERROR(ENOMEM);
|
||||||
if (avio_read(pb, header, header_size) != header_size){
|
if (avio_read(pb, header, header_size) != header_size) {
|
||||||
av_free(header);
|
av_free(header);
|
||||||
return AVERROR(EIO);
|
return AVERROR(EIO);
|
||||||
}
|
}
|
||||||
@@ -127,123 +226,38 @@ static int fourxm_read_header(AVFormatContext *s)
|
|||||||
/* take the lazy approach and search for any and all vtrk and strk chunks */
|
/* take the lazy approach and search for any and all vtrk and strk chunks */
|
||||||
for (i = 0; i < header_size - 8; i++) {
|
for (i = 0; i < header_size - 8; i++) {
|
||||||
fourcc_tag = AV_RL32(&header[i]);
|
fourcc_tag = AV_RL32(&header[i]);
|
||||||
size = AV_RL32(&header[i + 4]);
|
size = AV_RL32(&header[i + 4]);
|
||||||
if (size > header_size - i - 8 && (fourcc_tag == vtrk_TAG || fourcc_tag == strk_TAG)) {
|
if (size > header_size - i - 8 && (fourcc_tag == vtrk_TAG || fourcc_tag == strk_TAG)) {
|
||||||
av_log(s, AV_LOG_ERROR, "chunk larger than array %d>%d\n", size, header_size - i - 8);
|
av_log(s, AV_LOG_ERROR, "chunk larger than array %d>%d\n", size, header_size - i - 8);
|
||||||
return AVERROR_INVALIDDATA;
|
return AVERROR_INVALIDDATA;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fourcc_tag == std__TAG) {
|
if (fourcc_tag == std__TAG) {
|
||||||
if (header_size < i + 16) {
|
if (header_size - i < 16) {
|
||||||
av_log(s, AV_LOG_ERROR, "std TAG truncated\n");
|
av_log(s, AV_LOG_ERROR, "std TAG truncated\n");
|
||||||
return AVERROR_INVALIDDATA;
|
ret = AVERROR_INVALIDDATA;
|
||||||
|
goto fail;
|
||||||
}
|
}
|
||||||
fourxm->fps = av_int2float(AV_RL32(&header[i + 12]));
|
fourxm->fps = av_int2float(AV_RL32(&header[i + 12]));
|
||||||
} else if (fourcc_tag == vtrk_TAG) {
|
} else if (fourcc_tag == vtrk_TAG) {
|
||||||
/* check that there is enough data */
|
if ((ret = parse_vtrk(s, fourxm, header + i, size,
|
||||||
if (size != vtrk_SIZE) {
|
header_size - i)) < 0)
|
||||||
ret= AVERROR_INVALIDDATA;
|
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
|
||||||
fourxm->width = AV_RL32(&header[i + 36]);
|
|
||||||
fourxm->height = AV_RL32(&header[i + 40]);
|
|
||||||
|
|
||||||
/* allocate a new AVStream */
|
|
||||||
st = avformat_new_stream(s, NULL);
|
|
||||||
if (!st){
|
|
||||||
ret= AVERROR(ENOMEM);
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
avpriv_set_pts_info(st, 60, 1, fourxm->fps);
|
|
||||||
|
|
||||||
fourxm->video_stream_index = st->index;
|
|
||||||
|
|
||||||
st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
|
|
||||||
st->codec->codec_id = AV_CODEC_ID_4XM;
|
|
||||||
st->codec->extradata_size = 4;
|
|
||||||
st->codec->extradata = av_malloc(4);
|
|
||||||
AV_WL32(st->codec->extradata, AV_RL32(&header[i + 16]));
|
|
||||||
st->codec->width = fourxm->width;
|
|
||||||
st->codec->height = fourxm->height;
|
|
||||||
|
|
||||||
i += 8 + size;
|
i += 8 + size;
|
||||||
} else if (fourcc_tag == strk_TAG) {
|
} else if (fourcc_tag == strk_TAG) {
|
||||||
int current_track;
|
if ((ret = parse_strk(s, fourxm, header + i, size,
|
||||||
/* check that there is enough data */
|
header_size - i)) < 0)
|
||||||
if (size != strk_SIZE) {
|
|
||||||
ret= AVERROR_INVALIDDATA;
|
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
|
||||||
current_track = AV_RL32(&header[i + 8]);
|
|
||||||
if((unsigned)current_track >= UINT_MAX / sizeof(AudioTrack) - 1){
|
|
||||||
av_log(s, AV_LOG_ERROR, "current_track too large\n");
|
|
||||||
ret = AVERROR_INVALIDDATA;
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
if (current_track + 1 > fourxm->track_count) {
|
|
||||||
fourxm->tracks = av_realloc_f(fourxm->tracks,
|
|
||||||
sizeof(AudioTrack),
|
|
||||||
current_track + 1);
|
|
||||||
if (!fourxm->tracks) {
|
|
||||||
ret = AVERROR(ENOMEM);
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
memset(&fourxm->tracks[fourxm->track_count], 0,
|
|
||||||
sizeof(AudioTrack) * (current_track + 1 - fourxm->track_count));
|
|
||||||
fourxm->track_count = current_track + 1;
|
|
||||||
}
|
|
||||||
fourxm->tracks[current_track].adpcm = AV_RL32(&header[i + 12]);
|
|
||||||
fourxm->tracks[current_track].channels = AV_RL32(&header[i + 36]);
|
|
||||||
fourxm->tracks[current_track].sample_rate = AV_RL32(&header[i + 40]);
|
|
||||||
fourxm->tracks[current_track].bits = AV_RL32(&header[i + 44]);
|
|
||||||
fourxm->tracks[current_track].audio_pts = 0;
|
|
||||||
if( fourxm->tracks[current_track].channels <= 0
|
|
||||||
|| fourxm->tracks[current_track].sample_rate <= 0
|
|
||||||
|| fourxm->tracks[current_track].bits < 0){
|
|
||||||
av_log(s, AV_LOG_ERROR, "audio header invalid\n");
|
|
||||||
ret = AVERROR_INVALIDDATA;
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
if(!fourxm->tracks[current_track].adpcm && fourxm->tracks[current_track].bits<8){
|
|
||||||
av_log(s, AV_LOG_ERROR, "bits unspecified for non ADPCM\n");
|
|
||||||
ret = AVERROR_INVALIDDATA;
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
i += 8 + size;
|
i += 8 + size;
|
||||||
|
|
||||||
/* allocate a new AVStream */
|
|
||||||
st = avformat_new_stream(s, NULL);
|
|
||||||
if (!st){
|
|
||||||
ret= AVERROR(ENOMEM);
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
st->id = current_track;
|
|
||||||
avpriv_set_pts_info(st, 60, 1, fourxm->tracks[current_track].sample_rate);
|
|
||||||
|
|
||||||
fourxm->tracks[current_track].stream_index = st->index;
|
|
||||||
|
|
||||||
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
|
|
||||||
st->codec->codec_tag = 0;
|
|
||||||
st->codec->channels = fourxm->tracks[current_track].channels;
|
|
||||||
st->codec->sample_rate = fourxm->tracks[current_track].sample_rate;
|
|
||||||
st->codec->bits_per_coded_sample = fourxm->tracks[current_track].bits;
|
|
||||||
st->codec->bit_rate = st->codec->channels * st->codec->sample_rate *
|
|
||||||
st->codec->bits_per_coded_sample;
|
|
||||||
st->codec->block_align = st->codec->channels * st->codec->bits_per_coded_sample;
|
|
||||||
if (fourxm->tracks[current_track].adpcm){
|
|
||||||
st->codec->codec_id = AV_CODEC_ID_ADPCM_4XM;
|
|
||||||
}else if (st->codec->bits_per_coded_sample == 8){
|
|
||||||
st->codec->codec_id = AV_CODEC_ID_PCM_U8;
|
|
||||||
}else
|
|
||||||
st->codec->codec_id = AV_CODEC_ID_PCM_S16LE;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* skip over the LIST-MOVI chunk (which is where the stream should be */
|
/* skip over the LIST-MOVI chunk (which is where the stream should be */
|
||||||
GET_LIST_HEADER();
|
GET_LIST_HEADER();
|
||||||
if (fourcc_tag != MOVI_TAG){
|
if (fourcc_tag != MOVI_TAG) {
|
||||||
ret= AVERROR_INVALIDDATA;
|
ret = AVERROR_INVALIDDATA;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -262,7 +276,7 @@ static int fourxm_read_packet(AVFormatContext *s,
|
|||||||
AVPacket *pkt)
|
AVPacket *pkt)
|
||||||
{
|
{
|
||||||
FourxmDemuxContext *fourxm = s->priv_data;
|
FourxmDemuxContext *fourxm = s->priv_data;
|
||||||
AVIOContext *pb = s->pb;
|
AVIOContext *pb = s->pb;
|
||||||
unsigned int fourcc_tag;
|
unsigned int fourcc_tag;
|
||||||
unsigned int size;
|
unsigned int size;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
@@ -272,18 +286,16 @@ static int fourxm_read_packet(AVFormatContext *s,
|
|||||||
int audio_frame_count;
|
int audio_frame_count;
|
||||||
|
|
||||||
while (!packet_read) {
|
while (!packet_read) {
|
||||||
|
|
||||||
if ((ret = avio_read(s->pb, header, 8)) < 0)
|
if ((ret = avio_read(s->pb, header, 8)) < 0)
|
||||||
return ret;
|
return ret;
|
||||||
fourcc_tag = AV_RL32(&header[0]);
|
fourcc_tag = AV_RL32(&header[0]);
|
||||||
size = AV_RL32(&header[4]);
|
size = AV_RL32(&header[4]);
|
||||||
if (url_feof(pb))
|
if (url_feof(pb))
|
||||||
return AVERROR(EIO);
|
return AVERROR(EIO);
|
||||||
switch (fourcc_tag) {
|
switch (fourcc_tag) {
|
||||||
|
|
||||||
case LIST_TAG:
|
case LIST_TAG:
|
||||||
/* this is a good time to bump the video pts */
|
/* this is a good time to bump the video pts */
|
||||||
fourxm->video_pts ++;
|
fourxm->video_pts++;
|
||||||
|
|
||||||
/* skip the LIST-* tag and move on to the next fourcc */
|
/* skip the LIST-* tag and move on to the next fourcc */
|
||||||
avio_rl32(pb);
|
avio_rl32(pb);
|
||||||
@@ -300,45 +312,43 @@ static int fourxm_read_packet(AVFormatContext *s,
|
|||||||
if (size + 8 < size || av_new_packet(pkt, size + 8))
|
if (size + 8 < size || av_new_packet(pkt, size + 8))
|
||||||
return AVERROR(EIO);
|
return AVERROR(EIO);
|
||||||
pkt->stream_index = fourxm->video_stream_index;
|
pkt->stream_index = fourxm->video_stream_index;
|
||||||
pkt->pts = fourxm->video_pts;
|
pkt->pts = fourxm->video_pts;
|
||||||
pkt->pos = avio_tell(s->pb);
|
pkt->pos = avio_tell(s->pb);
|
||||||
memcpy(pkt->data, header, 8);
|
memcpy(pkt->data, header, 8);
|
||||||
ret = avio_read(s->pb, &pkt->data[8], size);
|
ret = avio_read(s->pb, &pkt->data[8], size);
|
||||||
|
|
||||||
if (ret < 0){
|
if (ret < 0) {
|
||||||
av_free_packet(pkt);
|
av_free_packet(pkt);
|
||||||
}else
|
} else
|
||||||
packet_read = 1;
|
packet_read = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case snd__TAG:
|
case snd__TAG:
|
||||||
track_number = avio_rl32(pb);
|
track_number = avio_rl32(pb);
|
||||||
avio_skip(pb, 4);
|
avio_skip(pb, 4);
|
||||||
size-=8;
|
size -= 8;
|
||||||
|
|
||||||
if (track_number < fourxm->track_count && fourxm->tracks[track_number].channels>0) {
|
if (track_number < fourxm->track_count &&
|
||||||
ret= av_get_packet(s->pb, pkt, size);
|
fourxm->tracks[track_number].channels > 0) {
|
||||||
if(ret<0)
|
ret = av_get_packet(s->pb, pkt, size);
|
||||||
|
if (ret < 0)
|
||||||
return AVERROR(EIO);
|
return AVERROR(EIO);
|
||||||
pkt->stream_index =
|
pkt->stream_index =
|
||||||
fourxm->tracks[track_number].stream_index;
|
fourxm->tracks[track_number].stream_index;
|
||||||
pkt->pts = fourxm->tracks[track_number].audio_pts;
|
pkt->pts = fourxm->tracks[track_number].audio_pts;
|
||||||
packet_read = 1;
|
packet_read = 1;
|
||||||
|
|
||||||
/* pts accounting */
|
/* pts accounting */
|
||||||
audio_frame_count = size;
|
audio_frame_count = size;
|
||||||
if (fourxm->tracks[track_number].adpcm)
|
if (fourxm->tracks[track_number].adpcm)
|
||||||
audio_frame_count -=
|
audio_frame_count -= 2 * (fourxm->tracks[track_number].channels);
|
||||||
2 * (fourxm->tracks[track_number].channels);
|
audio_frame_count /= fourxm->tracks[track_number].channels;
|
||||||
audio_frame_count /=
|
if (fourxm->tracks[track_number].adpcm) {
|
||||||
fourxm->tracks[track_number].channels;
|
|
||||||
if (fourxm->tracks[track_number].adpcm){
|
|
||||||
audio_frame_count *= 2;
|
audio_frame_count *= 2;
|
||||||
}else
|
} else
|
||||||
audio_frame_count /=
|
audio_frame_count /=
|
||||||
(fourxm->tracks[track_number].bits / 8);
|
(fourxm->tracks[track_number].bits / 8);
|
||||||
fourxm->tracks[track_number].audio_pts += audio_frame_count;
|
fourxm->tracks[track_number].audio_pts += audio_frame_count;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
avio_skip(pb, size);
|
avio_skip(pb, size);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -210,7 +210,8 @@ static int smacker_read_header(AVFormatContext *s)
|
|||||||
|
|
||||||
|
|
||||||
/* load trees to extradata, they will be unpacked by decoder */
|
/* load trees to extradata, they will be unpacked by decoder */
|
||||||
st->codec->extradata = av_malloc(smk->treesize + 16 + FF_INPUT_BUFFER_PADDING_SIZE);
|
st->codec->extradata = av_mallocz(smk->treesize + 16 +
|
||||||
|
FF_INPUT_BUFFER_PADDING_SIZE);
|
||||||
st->codec->extradata_size = smk->treesize + 16;
|
st->codec->extradata_size = smk->treesize + 16;
|
||||||
if(!st->codec->extradata){
|
if(!st->codec->extradata){
|
||||||
av_log(s, AV_LOG_ERROR, "Cannot allocate %i bytes of extradata\n", smk->treesize + 16);
|
av_log(s, AV_LOG_ERROR, "Cannot allocate %i bytes of extradata\n", smk->treesize + 16);
|
||||||
@@ -305,12 +306,14 @@ static int smacker_read_packet(AVFormatContext *s, AVPacket *pkt)
|
|||||||
/* if audio chunks are present, put them to stack and retrieve later */
|
/* if audio chunks are present, put them to stack and retrieve later */
|
||||||
for(i = 0; i < 7; i++) {
|
for(i = 0; i < 7; i++) {
|
||||||
if(flags & 1) {
|
if(flags & 1) {
|
||||||
unsigned int size;
|
uint32_t size;
|
||||||
uint8_t *tmpbuf;
|
uint8_t *tmpbuf;
|
||||||
|
|
||||||
size = avio_rl32(s->pb) - 4;
|
size = avio_rl32(s->pb) - 4;
|
||||||
if(size + 4L > frame_size)
|
if (!size || size + 4L > frame_size) {
|
||||||
|
av_log(s, AV_LOG_ERROR, "Invalid audio part size\n");
|
||||||
return AVERROR_INVALIDDATA;
|
return AVERROR_INVALIDDATA;
|
||||||
|
}
|
||||||
frame_size -= size;
|
frame_size -= size;
|
||||||
frame_size -= 4;
|
frame_size -= 4;
|
||||||
smk->curstream++;
|
smk->curstream++;
|
||||||
|
|||||||
Reference in New Issue
Block a user