typedef struct EbmlBin {
int size;
+ AVBufferRef *buf;
uint8_t *data;
int64_t pos;
} EbmlBin;
*/
static int ebml_read_binary(AVIOContext *pb, int length, EbmlBin *bin)
{
- av_fast_padded_malloc(&bin->data, &bin->size, length);
- if (!bin->data)
- return AVERROR(ENOMEM);
+ int ret;
+
+ ret = av_buffer_realloc(&bin->buf, length + AV_INPUT_BUFFER_PADDING_SIZE);
+ if (ret < 0)
+ return ret;
+ memset(bin->buf->data + length, 0, AV_INPUT_BUFFER_PADDING_SIZE);
+ bin->data = bin->buf->data;
bin->size = length;
bin->pos = avio_tell(pb);
if (avio_read(pb, bin->data, length) != length) {
- av_freep(&bin->data);
+ av_buffer_unref(&bin->buf);
+ bin->data = NULL;
bin->size = 0;
return AVERROR(EIO);
}
av_freep(data_off);
break;
case EBML_BIN:
- av_freep(&((EbmlBin *) data_off)->data);
+ av_buffer_unref(&((EbmlBin *) data_off)->buf);
break;
case EBML_LEVEL1:
case EBML_NEST:
return 0;
pkt_size = isize + header_size;
- pkt_data = av_malloc(pkt_size);
+ pkt_data = av_malloc(pkt_size + AV_INPUT_BUFFER_PADDING_SIZE);
if (!pkt_data)
return AVERROR(ENOMEM);
case MATROSKA_TRACK_ENCODING_COMP_LZO:
do {
olen = pkt_size *= 3;
- newpktdata = av_realloc(pkt_data, pkt_size + AV_LZO_OUTPUT_PADDING);
+ newpktdata = av_realloc(pkt_data, pkt_size + AV_LZO_OUTPUT_PADDING
+ + AV_INPUT_BUFFER_PADDING_SIZE);
if (!newpktdata) {
result = AVERROR(ENOMEM);
goto failed;
zstream.avail_in = isize;
do {
pkt_size *= 3;
- newpktdata = av_realloc(pkt_data, pkt_size);
+ newpktdata = av_realloc(pkt_data, pkt_size + AV_INPUT_BUFFER_PADDING_SIZE);
if (!newpktdata) {
inflateEnd(&zstream);
result = AVERROR(ENOMEM);
bzstream.avail_in = isize;
do {
pkt_size *= 3;
- newpktdata = av_realloc(pkt_data, pkt_size);
+ newpktdata = av_realloc(pkt_data, pkt_size + AV_INPUT_BUFFER_PADDING_SIZE);
if (!newpktdata) {
BZ2_bzDecompressEnd(&bzstream);
result = AVERROR(ENOMEM);
return AVERROR_INVALIDDATA;
}
+ memset(pkt_data + pkt_size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
+
*buf = pkt_data;
*buf_size = pkt_size;
return 0;
* by expanding/shifting the data by 4 bytes and storing the data
* size at the start. */
if (ff_codec_get_id(codec_tags, AV_RL32(track->codec_priv.data))) {
- uint8_t *p = av_realloc(track->codec_priv.data,
- track->codec_priv.size + 4);
- if (!p)
- return AVERROR(ENOMEM);
- memmove(p + 4, p, track->codec_priv.size);
- track->codec_priv.data = p;
+ int ret = av_buffer_realloc(&track->codec_priv.buf,
+ track->codec_priv.size + 4 + AV_INPUT_BUFFER_PADDING_SIZE);
+ if (ret < 0)
+ return ret;
+
+ track->codec_priv.data = track->codec_priv.buf->data;
+ memmove(track->codec_priv.data + 4, track->codec_priv.data, track->codec_priv.size);
track->codec_priv.size += 4;
AV_WB32(track->codec_priv.data, track->codec_priv.size);
}
"Failed to decode codec private data\n");
}
- if (codec_priv != track->codec_priv.data)
- av_free(codec_priv);
+ if (codec_priv != track->codec_priv.data) {
+ av_buffer_unref(&track->codec_priv.buf);
+ if (track->codec_priv.data) {
+ track->codec_priv.buf = av_buffer_create(track->codec_priv.data,
+ track->codec_priv.size + AV_INPUT_BUFFER_PADDING_SIZE,
+ NULL, NULL, 0);
+ if (!track->codec_priv.buf) {
+ av_freep(&track->codec_priv.data);
+ track->codec_priv.size = 0;
+ return AVERROR(ENOMEM);
+ }
+ }
+ }
}
}
/* we don't need any value stored in CodecPrivate.
make sure that it's not exported as extradata. */
track->codec_priv.size = 0;
+ } else if (codec_id == AV_CODEC_ID_AV1 && track->codec_priv.size) {
+ /* For now, propagate only the OBUs, if any. Once libavcodec is
+ updated to handle isobmff style extradata this can be removed. */
+ extradata_offset = 4;
}
track->codec_priv.size -= extradata_offset;
while (track->audio.pkt_cnt) {
int ret;
- AVPacket *pkt = av_mallocz(sizeof(AVPacket));
- if (!pkt)
- return AVERROR(ENOMEM);
+ AVPacket pktl, *pkt = &pktl;
ret = av_new_packet(pkt, a);
if (ret < 0) {
- av_free(pkt);
return ret;
}
memcpy(pkt->data,
pkt->stream_index = st->index;
ret = ff_packet_list_put(&matroska->queue, &matroska->queue_end, pkt, 0);
if (ret < 0) {
- av_packet_free(&pkt);
+ av_packet_unref(pkt);
return AVERROR(ENOMEM);
}
}
goto fail;
}
- tmp = av_realloc(dst, dstlen + blocksize + 32);
+ tmp = av_realloc(dst, dstlen + blocksize + 32 + AV_INPUT_BUFFER_PADDING_SIZE);
if (!tmp) {
ret = AVERROR(ENOMEM);
goto fail;
offset += blocksize + 32;
}
+ memset(dst + dstlen, 0, AV_INPUT_BUFFER_PADDING_SIZE);
+
*pdst = dst;
*size = dstlen;
return ret;
}
+static int matroska_parse_prores(MatroskaTrack *track, uint8_t *src,
+ uint8_t **pdst, int *size)
+{
+ uint8_t *dst = src;
+ int dstlen = *size;
+
+ if (AV_RB32(&src[4]) != MKBETAG('i', 'c', 'p', 'f')) {
+ dst = av_malloc(dstlen + 8 + 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;
+ }
+
+ *pdst = dst;
+ *size = dstlen;
+
+ return 0;
+}
+
static int matroska_parse_webvtt(MatroskaDemuxContext *matroska,
MatroskaTrack *track,
AVStream *st,
uint64_t duration,
int64_t pos)
{
- AVPacket *pkt;
+ AVPacket pktl, *pkt = &pktl;
uint8_t *id, *settings, *text, *buf;
int id_len, settings_len, text_len;
uint8_t *p, *q;
if (text_len <= 0)
return AVERROR_INVALIDDATA;
- pkt = av_mallocz(sizeof(*pkt));
- if (!pkt)
- return AVERROR(ENOMEM);
err = av_new_packet(pkt, text_len);
if (err < 0) {
- av_free(pkt);
return err;
}
id_len);
if (!buf) {
av_packet_unref(pkt);
- av_free(pkt);
return AVERROR(ENOMEM);
}
memcpy(buf, id, id_len);
settings_len);
if (!buf) {
av_packet_unref(pkt);
- av_free(pkt);
return AVERROR(ENOMEM);
}
memcpy(buf, settings, settings_len);
err = ff_packet_list_put(&matroska->queue, &matroska->queue_end, pkt, 0);
if (err < 0) {
- av_packet_free(&pkt);
+ av_packet_unref(pkt);
return AVERROR(ENOMEM);
}
static int matroska_parse_frame(MatroskaDemuxContext *matroska,
MatroskaTrack *track, AVStream *st,
- uint8_t *data, int pkt_size,
+ AVBufferRef *buf, uint8_t *data, int pkt_size,
uint64_t timecode, uint64_t lace_duration,
int64_t pos, int is_keyframe,
uint8_t *additional, uint64_t additional_id, int additional_size,
{
MatroskaTrackEncoding *encodings = track->encodings.elem;
uint8_t *pkt_data = data;
- int offset = 0, res;
+ int res;
AVPacket pktl, *pkt = &pktl;
if (encodings && !encodings->type && encodings->scope & 1) {
pkt_data = wv_data;
}
- if (st->codecpar->codec_id == AV_CODEC_ID_PRORES &&
- AV_RB32(&data[4]) != MKBETAG('i', 'c', 'p', 'f'))
- offset = 8;
+ if (st->codecpar->codec_id == AV_CODEC_ID_PRORES) {
+ uint8_t *pr_data;
+ res = matroska_parse_prores(track, pkt_data, &pr_data, &pkt_size);
+ if (res < 0) {
+ av_log(matroska->ctx, AV_LOG_ERROR,
+ "Error parsing a prores block.\n");
+ goto fail;
+ }
+ if (pkt_data != data)
+ av_freep(&pkt_data);
+ pkt_data = pr_data;
+ }
+
+ av_init_packet(pkt);
+ if (pkt_data != data)
+ pkt->buf = av_buffer_create(pkt_data, pkt_size + AV_INPUT_BUFFER_PADDING_SIZE,
+ NULL, NULL, 0);
+ else
+ pkt->buf = av_buffer_ref(buf);
- /* XXX: prevent data copy... */
- if (av_new_packet(pkt, pkt_size + offset) < 0) {
+ if (!pkt->buf) {
res = AVERROR(ENOMEM);
goto fail;
}
- if (st->codecpar->codec_id == AV_CODEC_ID_PRORES && offset == 8) {
- uint8_t *buf = pkt->data;
- bytestream_put_be32(&buf, pkt_size);
- bytestream_put_be32(&buf, MKBETAG('i', 'c', 'p', 'f'));
- }
-
- memcpy(pkt->data + offset, pkt_data, pkt_size);
-
- if (pkt_data != data)
- av_freep(&pkt_data);
-
+ pkt->data = pkt_data;
+ pkt->size = pkt_size;
pkt->flags = is_keyframe;
pkt->stream_index = st->index;
return res;
}
-static int matroska_parse_block(MatroskaDemuxContext *matroska, uint8_t *data,
+static int matroska_parse_block(MatroskaDemuxContext *matroska, AVBufferRef *buf, uint8_t *data,
int size, int64_t pos, uint64_t cluster_time,
uint64_t block_duration, int is_keyframe,
uint8_t *additional, uint64_t additional_id, int additional_size,
if (res)
goto end;
} else {
- res = matroska_parse_frame(matroska, track, st, data, lace_size[n],
+ res = matroska_parse_frame(matroska, track, st, buf, data, lace_size[n],
timecode, lace_duration, pos,
!n ? is_keyframe : 0,
additional, additional_id, additional_size,
blocks[i].additional.data : NULL;
if (!blocks[i].non_simple)
blocks[i].duration = 0;
- res = matroska_parse_block(matroska, blocks[i].bin.data,
+ res = matroska_parse_block(matroska, blocks[i].bin.buf, blocks[i].bin.data,
blocks[i].bin.size, blocks[i].bin.pos,
matroska->current_cluster.timecode,
blocks[i].duration, is_keyframe,
for (i = 0; i < blocks_list->nb_elem; i++)
if (blocks[i].bin.size > 0 && blocks[i].bin.data) {
int is_keyframe = blocks[i].non_simple ? blocks[i].reference == INT64_MIN : -1;
- res = matroska_parse_block(matroska, blocks[i].bin.data,
+ res = matroska_parse_block(matroska, blocks[i].bin.buf, blocks[i].bin.data,
blocks[i].bin.size, blocks[i].bin.pos,
cluster.timecode, blocks[i].duration,
is_keyframe, NULL, 0, 0, pos,