typedef struct EbmlList {
int nb_elem;
+ unsigned int alloc_elem_size;
void *elem;
} EbmlList;
};
static EbmlSyntax matroska_blockmore[] = {
- { MATROSKA_ID_BLOCKADDID, EBML_UINT, 0, offsetof(MatroskaBlock,additional_id) },
+ { MATROSKA_ID_BLOCKADDID, EBML_UINT, 0, offsetof(MatroskaBlock,additional_id), { .u = 1 } },
{ MATROSKA_ID_BLOCKADDITIONAL, EBML_BIN, 0, offsetof(MatroskaBlock,additional) },
CHILD_OF(matroska_blockadditions)
};
id == MATROSKA_ID_CLUSTER || id == MATROSKA_ID_CHAPTERS) {
/* Prepare the context for parsing of a level 1 element. */
matroska_reset_status(matroska, id, -1);
- /* Given that we are here means that an error has occured,
+ /* Given that we are here means that an error has occurred,
* so treat the segment as unknown length in order not to
* discard valid data that happens to be beyond the designated
* end of the segment. */
data = (char *) data + syntax->data_offset;
if (syntax->list_elem_size) {
EbmlList *list = data;
- void *newelem = av_realloc_array(list->elem, list->nb_elem + 1,
- syntax->list_elem_size);
+ void *newelem;
+
+ if ((unsigned)list->nb_elem + 1 >= UINT_MAX / syntax->list_elem_size)
+ return AVERROR(ENOMEM);
+ newelem = av_fast_realloc(list->elem,
+ &list->alloc_elem_size,
+ (list->nb_elem + 1) * syntax->list_elem_size);
if (!newelem)
return AVERROR(ENOMEM);
list->elem = newelem;
// current element (i.e. how much would be skipped); if there were
// more than a few skipped elements in a row and skipping the current
// element would lead us more than SKIP_THRESHOLD away from the last
- // known good position, then it is inferred that an error occured.
+ // known good position, then it is inferred that an error occurred.
// The dependency on the number of unknown elements in a row exists
// because the distance to the last known good position is
// automatically big if the last parsed element was big.
ebml_free(syntax[i].def.n, ptr);
av_freep(&list->elem);
list->nb_elem = 0;
+ list->alloc_elem_size = 0;
} else
ebml_free(syntax[i].def.n, data_off);
default:
}
if (has_mastering_primaries || has_mastering_luminance) {
- // Use similar rationals as other standards.
- const int chroma_den = 50000;
- const int luma_den = 10000;
AVMasteringDisplayMetadata *metadata =
(AVMasteringDisplayMetadata*) av_stream_new_side_data(
st, AV_PKT_DATA_MASTERING_DISPLAY_METADATA,
}
memset(metadata, 0, sizeof(AVMasteringDisplayMetadata));
if (has_mastering_primaries) {
- metadata->display_primaries[0][0] = av_make_q(
- round(mastering_meta->r_x * chroma_den), chroma_den);
- metadata->display_primaries[0][1] = av_make_q(
- round(mastering_meta->r_y * chroma_den), chroma_den);
- metadata->display_primaries[1][0] = av_make_q(
- round(mastering_meta->g_x * chroma_den), chroma_den);
- metadata->display_primaries[1][1] = av_make_q(
- round(mastering_meta->g_y * chroma_den), chroma_den);
- metadata->display_primaries[2][0] = av_make_q(
- round(mastering_meta->b_x * chroma_den), chroma_den);
- metadata->display_primaries[2][1] = av_make_q(
- round(mastering_meta->b_y * chroma_den), chroma_den);
- metadata->white_point[0] = av_make_q(
- round(mastering_meta->white_x * chroma_den), chroma_den);
- metadata->white_point[1] = av_make_q(
- round(mastering_meta->white_y * chroma_den), chroma_den);
+ metadata->display_primaries[0][0] = av_d2q(mastering_meta->r_x, INT_MAX);
+ metadata->display_primaries[0][1] = av_d2q(mastering_meta->r_y, INT_MAX);
+ metadata->display_primaries[1][0] = av_d2q(mastering_meta->g_x, INT_MAX);
+ metadata->display_primaries[1][1] = av_d2q(mastering_meta->g_y, INT_MAX);
+ metadata->display_primaries[2][0] = av_d2q(mastering_meta->b_x, INT_MAX);
+ metadata->display_primaries[2][1] = av_d2q(mastering_meta->b_y, INT_MAX);
+ metadata->white_point[0] = av_d2q(mastering_meta->white_x, INT_MAX);
+ metadata->white_point[1] = av_d2q(mastering_meta->white_y, INT_MAX);
metadata->has_primaries = 1;
}
if (has_mastering_luminance) {
- metadata->max_luminance = av_make_q(
- round(mastering_meta->max_luminance * luma_den), luma_den);
- metadata->min_luminance = av_make_q(
- round(mastering_meta->min_luminance * luma_den), luma_den);
+ metadata->max_luminance = av_d2q(mastering_meta->max_luminance, INT_MAX);
+ metadata->min_luminance = av_d2q(mastering_meta->min_luminance, INT_MAX);
metadata->has_luminance = 1;
}
}
memcpy(&extradata[12], track->codec_priv.data,
track->codec_priv.size);
} else if (codec_id == AV_CODEC_ID_TTA) {
- extradata_size = 30;
- extradata = av_mallocz(extradata_size + AV_INPUT_BUFFER_PADDING_SIZE);
- if (!extradata)
- return AVERROR(ENOMEM);
- ffio_init_context(&b, extradata, extradata_size, 1,
- NULL, NULL, NULL, NULL);
- avio_write(&b, "TTA1", 4);
- avio_wl16(&b, 1);
+ uint8_t *ptr;
if (track->audio.channels > UINT16_MAX ||
track->audio.bitdepth > UINT16_MAX) {
av_log(matroska->ctx, AV_LOG_WARNING,
"Too large audio channel number %"PRIu64
" or bitdepth %"PRIu64". Skipping track.\n",
track->audio.channels, track->audio.bitdepth);
- av_freep(&extradata);
if (matroska->ctx->error_recognition & AV_EF_EXPLODE)
return AVERROR_INVALIDDATA;
else
continue;
}
- avio_wl16(&b, track->audio.channels);
- avio_wl16(&b, track->audio.bitdepth);
if (track->audio.out_samplerate < 0 || track->audio.out_samplerate > INT_MAX)
return AVERROR_INVALIDDATA;
- avio_wl32(&b, track->audio.out_samplerate);
- avio_wl32(&b, av_rescale((matroska->duration * matroska->time_scale),
- track->audio.out_samplerate,
- AV_TIME_BASE * 1000));
+ extradata_size = 22;
+ extradata = av_mallocz(extradata_size + AV_INPUT_BUFFER_PADDING_SIZE);
+ if (!extradata)
+ return AVERROR(ENOMEM);
+ ptr = extradata;
+ bytestream_put_be32(&ptr, AV_RB32("TTA1"));
+ bytestream_put_le16(&ptr, 1);
+ bytestream_put_le16(&ptr, track->audio.channels);
+ bytestream_put_le16(&ptr, track->audio.bitdepth);
+ bytestream_put_le32(&ptr, track->audio.out_samplerate);
+ bytestream_put_le32(&ptr, av_rescale(matroska->duration * matroska->time_scale,
+ track->audio.out_samplerate,
+ AV_TIME_BASE * 1000));
} else if (codec_id == AV_CODEC_ID_RV10 ||
codec_id == AV_CODEC_ID_RV20 ||
codec_id == AV_CODEC_ID_RV30 ||
static int matroska_parse_laces(MatroskaDemuxContext *matroska, uint8_t **buf,
int *buf_size, int type,
- uint32_t **lace_buf, int *laces)
+ uint32_t lace_size[256], int *laces)
{
int res = 0, n, size = *buf_size;
uint8_t *data = *buf;
- uint32_t *lace_size;
if (!type) {
*laces = 1;
- *lace_buf = av_malloc(sizeof(**lace_buf));
- if (!*lace_buf)
- return AVERROR(ENOMEM);
-
- *lace_buf[0] = size;
+ lace_size[0] = size;
return 0;
}
*laces = *data + 1;
data += 1;
size -= 1;
- lace_size = av_malloc_array(*laces, sizeof(*lace_size));
- if (!lace_size)
- return AVERROR(ENOMEM);
switch (type) {
case 0x1: /* Xiph lacing */
}
*buf = data;
- *lace_buf = lace_size;
*buf_size = size;
return res;
int dstlen = *size;
if (AV_RB32(&src[4]) != MKBETAG('i', 'c', 'p', 'f')) {
- dst = av_malloc(dstlen + 8 + AV_INPUT_BUFFER_PADDING_SIZE);
+ dstlen += 8;
+
+ dst = av_malloc(dstlen + AV_INPUT_BUFFER_PADDING_SIZE);
if (!dst)
return AVERROR(ENOMEM);
AV_WB32(dst, dstlen);
AV_WB32(dst + 4, MKBETAG('i', 'c', 'p', 'f'));
- memcpy(dst + 8, src, dstlen);
- memset(dst + 8 + dstlen, 0, AV_INPUT_BUFFER_PADDING_SIZE);
- dstlen += 8;
+ memcpy(dst + 8, src, dstlen - 8);
+ memset(dst + dstlen, 0, AV_INPUT_BUFFER_PADDING_SIZE);
}
*pdst = dst;
int res = 0;
AVStream *st;
int16_t block_time;
- uint32_t *lace_size = NULL;
+ uint32_t lace_size[256];
int n, flags, laces = 0;
uint64_t num;
int trust_default_duration = 1;
}
res = matroska_parse_laces(matroska, &data, &size, (flags & 0x06) >> 1,
- &lace_size, &laces);
-
- if (res)
- goto end;
+ lace_size, &laces);
+ if (res < 0)
+ return res;
if (track->audio.samplerate == 8000) {
// If this is needed for more codecs, then add them here
lace_size[n],
timecode, pos);
if (res)
- goto end;
+ return res;
} else if (st->codecpar->codec_id == AV_CODEC_ID_WEBVTT) {
res = matroska_parse_webvtt(matroska, track, st,
timecode, lace_duration,
pos);
if (res)
- goto end;
+ return res;
} else {
res = matroska_parse_frame(matroska, track, st, buf, data, lace_size[n],
timecode, lace_duration, pos,
additional, additional_id, additional_size,
discard_padding);
if (res)
- goto end;
+ return res;
}
if (timecode != AV_NOPTS_VALUE)
size -= lace_size[n];
}
-end:
- av_free(lace_size);
- return res;
+ return 0;
}
static int matroska_parse_cluster(MatroskaDemuxContext *matroska)