mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-11-21 10:55:51 +02:00
matroskadec: split laces parsing
This commit is contained in:
parent
117d8c6d1f
commit
2d0e7713f9
@ -1749,6 +1749,112 @@ static void matroska_clear_queue(MatroskaDemuxContext *matroska)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int matroska_parse_laces(MatroskaDemuxContext *matroska, uint8_t **buf,
|
||||||
|
int size, int type,
|
||||||
|
uint32_t **lace_buf, int *laces)
|
||||||
|
{
|
||||||
|
int res = 0, n;
|
||||||
|
uint8_t *data = *buf;
|
||||||
|
uint32_t *lace_size;
|
||||||
|
|
||||||
|
if (!type) {
|
||||||
|
*laces = 1;
|
||||||
|
*lace_buf = av_mallocz(sizeof(int));
|
||||||
|
if (!*lace_buf)
|
||||||
|
return AVERROR(ENOMEM);
|
||||||
|
|
||||||
|
*lace_buf[0] = size;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(size > 0);
|
||||||
|
*laces = *data + 1;
|
||||||
|
data += 1;
|
||||||
|
size -= 1;
|
||||||
|
lace_size = av_mallocz(*laces * sizeof(int));
|
||||||
|
if (!lace_size)
|
||||||
|
return AVERROR(ENOMEM);
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case 0x1: /* Xiph lacing */ {
|
||||||
|
uint8_t temp;
|
||||||
|
uint32_t total = 0;
|
||||||
|
for (n = 0; res == 0 && n < *laces - 1; n++) {
|
||||||
|
while (1) {
|
||||||
|
if (size == 0) {
|
||||||
|
res = AVERROR_EOF;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
temp = *data;
|
||||||
|
lace_size[n] += temp;
|
||||||
|
data += 1;
|
||||||
|
size -= 1;
|
||||||
|
if (temp != 0xff)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
total += lace_size[n];
|
||||||
|
}
|
||||||
|
if (size <= total) {
|
||||||
|
res = AVERROR_INVALIDDATA;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
lace_size[n] = size - total;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 0x2: /* fixed-size lacing */
|
||||||
|
if (size != (size / *laces) * size) {
|
||||||
|
res = AVERROR_INVALIDDATA;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
for (n = 0; n < *laces; n++)
|
||||||
|
lace_size[n] = size / *laces;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x3: /* EBML lacing */ {
|
||||||
|
uint64_t num;
|
||||||
|
uint32_t total;
|
||||||
|
n = matroska_ebmlnum_uint(matroska, data, size, &num);
|
||||||
|
if (n < 0) {
|
||||||
|
av_log(matroska->ctx, AV_LOG_INFO,
|
||||||
|
"EBML block data error\n");
|
||||||
|
res = n;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
data += n;
|
||||||
|
size -= n;
|
||||||
|
total = lace_size[0] = num;
|
||||||
|
for (n = 1; res == 0 && n < *laces - 1; n++) {
|
||||||
|
int64_t snum;
|
||||||
|
int r;
|
||||||
|
r = matroska_ebmlnum_sint(matroska, data, size, &snum);
|
||||||
|
if (r < 0) {
|
||||||
|
av_log(matroska->ctx, AV_LOG_INFO,
|
||||||
|
"EBML block data error\n");
|
||||||
|
res = r;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
data += r;
|
||||||
|
size -= r;
|
||||||
|
lace_size[n] = lace_size[n - 1] + snum;
|
||||||
|
total += lace_size[n];
|
||||||
|
}
|
||||||
|
if (size <= total) {
|
||||||
|
res = AVERROR_INVALIDDATA;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
lace_size[*laces - 1] = size - total;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*buf = data;
|
||||||
|
*lace_buf = lace_size;
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
static int matroska_parse_block(MatroskaDemuxContext *matroska, uint8_t *data,
|
static int matroska_parse_block(MatroskaDemuxContext *matroska, uint8_t *data,
|
||||||
int size, int64_t pos, uint64_t cluster_time,
|
int size, int64_t pos, uint64_t cluster_time,
|
||||||
uint64_t duration, int is_keyframe,
|
uint64_t duration, int is_keyframe,
|
||||||
@ -1808,95 +1914,8 @@ static int matroska_parse_block(MatroskaDemuxContext *matroska, uint8_t *data,
|
|||||||
matroska->skip_to_keyframe = 0;
|
matroska->skip_to_keyframe = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch ((flags & 0x06) >> 1) {
|
res = matroska_parse_laces(matroska, &data, size, (flags & 0x06) >> 1,
|
||||||
case 0x0: /* no lacing */
|
&lace_size, &laces);
|
||||||
laces = 1;
|
|
||||||
lace_size = av_mallocz(sizeof(int));
|
|
||||||
lace_size[0] = size;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x1: /* Xiph lacing */
|
|
||||||
case 0x2: /* fixed-size lacing */
|
|
||||||
case 0x3: /* EBML lacing */
|
|
||||||
assert(size>0); // size <=3 is checked before size-=3 above
|
|
||||||
laces = (*data) + 1;
|
|
||||||
data += 1;
|
|
||||||
size -= 1;
|
|
||||||
lace_size = av_mallocz(laces * sizeof(int));
|
|
||||||
|
|
||||||
switch ((flags & 0x06) >> 1) {
|
|
||||||
case 0x1: /* Xiph lacing */ {
|
|
||||||
uint8_t temp;
|
|
||||||
uint32_t total = 0;
|
|
||||||
for (n = 0; res == 0 && n < laces - 1; n++) {
|
|
||||||
while (1) {
|
|
||||||
if (size == 0) {
|
|
||||||
res = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
temp = *data;
|
|
||||||
lace_size[n] += temp;
|
|
||||||
data += 1;
|
|
||||||
size -= 1;
|
|
||||||
if (temp != 0xff)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
total += lace_size[n];
|
|
||||||
}
|
|
||||||
if (size <= total) {
|
|
||||||
res = AVERROR_INVALIDDATA;
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
lace_size[n] = size - total;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 0x2: /* fixed-size lacing */
|
|
||||||
if (size != (size / laces) * size) {
|
|
||||||
res = AVERROR_INVALIDDATA;
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
for (n = 0; n < laces; n++)
|
|
||||||
lace_size[n] = size / laces;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x3: /* EBML lacing */ {
|
|
||||||
uint32_t total;
|
|
||||||
n = matroska_ebmlnum_uint(matroska, data, size, &num);
|
|
||||||
if (n < 0) {
|
|
||||||
av_log(matroska->ctx, AV_LOG_INFO,
|
|
||||||
"EBML block data error\n");
|
|
||||||
res = n;
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
data += n;
|
|
||||||
size -= n;
|
|
||||||
total = lace_size[0] = num;
|
|
||||||
for (n = 1; res == 0 && n < laces - 1; n++) {
|
|
||||||
int64_t snum;
|
|
||||||
int r;
|
|
||||||
r = matroska_ebmlnum_sint(matroska, data, size, &snum);
|
|
||||||
if (r < 0) {
|
|
||||||
av_log(matroska->ctx, AV_LOG_INFO,
|
|
||||||
"EBML block data error\n");
|
|
||||||
res = r;
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
data += r;
|
|
||||||
size -= r;
|
|
||||||
lace_size[n] = lace_size[n - 1] + snum;
|
|
||||||
total += lace_size[n];
|
|
||||||
}
|
|
||||||
if (size <= total) {
|
|
||||||
res = AVERROR_INVALIDDATA;
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
lace_size[laces - 1] = size - total;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (res == 0) {
|
if (res == 0) {
|
||||||
for (n = 0; n < laces; n++) {
|
for (n = 0; n < laces; n++) {
|
||||||
|
Loading…
Reference in New Issue
Block a user