Message ID | 20230324155213.3493-1-jamrial@gmail.com |
---|---|
State | New |
Headers | show |
Series | [FFmpeg-devel,v2,1/7] avformat/matroskadec: support parsing more than one BlockMore element | expand |
Context | Check | Description |
---|---|---|
andriy/make_x86 | success | Make finished |
andriy/make_fate_x86 | success | Make fate finished |
James Almer: > Signed-off-by: James Almer <jamrial@gmail.com> > --- > No changes since v1. > > libavformat/matroskadec.c | 60 ++++++++++++++++++++++++++------------- > 1 file changed, 40 insertions(+), 20 deletions(-) > > diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c > index 3a888e3ada..60f9a78fe8 100644 > --- a/libavformat/matroskadec.c > +++ b/libavformat/matroskadec.c > @@ -349,13 +349,17 @@ typedef struct MatroskaLevel { > uint64_t length; > } MatroskaLevel; > > +typedef struct MatroskaBlockMore { > + uint64_t additional_id; > + EbmlBin additional; > +} MatroskaBlockMore; > + > typedef struct MatroskaBlock { > uint64_t duration; > CountedElement reference; > uint64_t non_simple; > EbmlBin bin; > - uint64_t additional_id; > - EbmlBin additional; > + EbmlList blockmore; > int64_t discard_padding; > } MatroskaBlock; > > @@ -759,13 +763,13 @@ static EbmlSyntax matroska_segments[] = { > }; > > static EbmlSyntax matroska_blockmore[] = { > - { MATROSKA_ID_BLOCKADDID, EBML_UINT, 0, 0, offsetof(MatroskaBlock,additional_id), { .u = 1 } }, > - { MATROSKA_ID_BLOCKADDITIONAL, EBML_BIN, 0, 0, offsetof(MatroskaBlock,additional) }, > + { MATROSKA_ID_BLOCKADDID, EBML_UINT, 0, 0, offsetof(MatroskaBlockMore,additional_id), { .u = 1 } }, > + { MATROSKA_ID_BLOCKADDITIONAL, EBML_BIN, 0, 0, offsetof(MatroskaBlockMore,additional) }, > CHILD_OF(matroska_blockadditions) > }; > > static EbmlSyntax matroska_blockadditions[] = { > - { MATROSKA_ID_BLOCKMORE, EBML_NEST, 0, 0, 0, {.n = matroska_blockmore} }, > + { MATROSKA_ID_BLOCKMORE, EBML_NEST, 0, sizeof(MatroskaBlockMore), offsetof(MatroskaBlock, blockmore), { .n = matroska_blockmore } }, > CHILD_OF(matroska_blockgroup) > }; > > @@ -3610,12 +3614,28 @@ static int matroska_parse_webvtt(MatroskaDemuxContext *matroska, > return 0; > } > > +static int matroska_parse_block_additional(MatroskaDemuxContext *matroska, > + AVPacket *pkt, > + const uint8_t *data, int size, uint64_t id) > +{ > + uint8_t *side_data = av_packet_new_side_data(pkt, > + AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL, > + size + 8); size + (size_t)8 > + if (!side_data) > + return AVERROR(ENOMEM); > + > + AV_WB64(side_data, id); > + memcpy(side_data + 8, data, size); > + > + return 0; > +} > + > static int matroska_parse_frame(MatroskaDemuxContext *matroska, > MatroskaTrack *track, AVStream *st, > 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, > + MatroskaBlockMore *blockmore, int nb_blockmore, > int64_t discard_padding) > { > uint8_t *pkt_data = data; > @@ -3647,7 +3667,7 @@ static int matroska_parse_frame(MatroskaDemuxContext *matroska, > buf = NULL; > } > > - if (!pkt_size && !additional_size) > + if (!pkt_size && !nb_blockmore) > goto no_output; > > if (!buf) > @@ -3666,16 +3686,18 @@ static int matroska_parse_frame(MatroskaDemuxContext *matroska, > pkt->flags = is_keyframe; > pkt->stream_index = st->index; > > - if (additional_size > 0) { > - uint8_t *side_data = av_packet_new_side_data(pkt, > - AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL, > - additional_size + 8); > - if (!side_data) { > + for (int i = 0; i < nb_blockmore; i++) { > + MatroskaBlockMore *more = &blockmore[i]; > + > + if (!more->additional.size) > + continue; > + > + res = matroska_parse_block_additional(matroska, pkt, more->additional.data, > + more->additional.size, more->additional_id); > + if (res < 0) { > av_packet_unref(pkt); > return AVERROR(ENOMEM); return res; > } > - AV_WB64(side_data, additional_id); > - memcpy(side_data + 8, additional, additional_size); > } > > if (discard_padding) { > @@ -3721,7 +3743,7 @@ fail: > 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, > + MatroskaBlockMore *blockmore, int nb_blockmore, > int64_t cluster_pos, int64_t discard_padding) > { > uint64_t timecode = AV_NOPTS_VALUE; > @@ -3856,7 +3878,7 @@ static int matroska_parse_block(MatroskaDemuxContext *matroska, AVBufferRef *buf > res = matroska_parse_frame(matroska, track, st, buf, out_data, > out_size, timecode, lace_duration, > pos, !n ? is_keyframe : 0, > - additional, additional_id, additional_size, > + blockmore, nb_blockmore, > discard_padding); > if (res) > return res; > @@ -3897,14 +3919,12 @@ static int matroska_parse_cluster(MatroskaDemuxContext *matroska) > > if (res >= 0 && block->bin.size > 0) { > int is_keyframe = block->non_simple ? block->reference.count == 0 : -1; > - uint8_t* additional = block->additional.size > 0 ? > - block->additional.data : NULL; > > res = matroska_parse_block(matroska, block->bin.buf, block->bin.data, > block->bin.size, block->bin.pos, > cluster->timecode, block->duration, > - is_keyframe, additional, block->additional_id, > - block->additional.size, cluster->pos, > + is_keyframe, block->blockmore.elem, > + block->blockmore.nb_elem, cluster->pos, > block->discard_padding); > } >
On 3/29/2023 9:43 PM, Andreas Rheinhardt wrote: >> @@ -3610,12 +3614,28 @@ static int matroska_parse_webvtt(MatroskaDemuxContext *matroska, >> return 0; >> } >> >> +static int matroska_parse_block_additional(MatroskaDemuxContext *matroska, >> + AVPacket *pkt, >> + const uint8_t *data, int size, uint64_t id) >> +{ >> + uint8_t *side_data = av_packet_new_side_data(pkt, >> + AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL, >> + size + 8); > size + (size_t)8 Seems out of scope for this patch as it's not changing the existing behavior, but ok, will change.
diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c index 3a888e3ada..60f9a78fe8 100644 --- a/libavformat/matroskadec.c +++ b/libavformat/matroskadec.c @@ -349,13 +349,17 @@ typedef struct MatroskaLevel { uint64_t length; } MatroskaLevel; +typedef struct MatroskaBlockMore { + uint64_t additional_id; + EbmlBin additional; +} MatroskaBlockMore; + typedef struct MatroskaBlock { uint64_t duration; CountedElement reference; uint64_t non_simple; EbmlBin bin; - uint64_t additional_id; - EbmlBin additional; + EbmlList blockmore; int64_t discard_padding; } MatroskaBlock; @@ -759,13 +763,13 @@ static EbmlSyntax matroska_segments[] = { }; static EbmlSyntax matroska_blockmore[] = { - { MATROSKA_ID_BLOCKADDID, EBML_UINT, 0, 0, offsetof(MatroskaBlock,additional_id), { .u = 1 } }, - { MATROSKA_ID_BLOCKADDITIONAL, EBML_BIN, 0, 0, offsetof(MatroskaBlock,additional) }, + { MATROSKA_ID_BLOCKADDID, EBML_UINT, 0, 0, offsetof(MatroskaBlockMore,additional_id), { .u = 1 } }, + { MATROSKA_ID_BLOCKADDITIONAL, EBML_BIN, 0, 0, offsetof(MatroskaBlockMore,additional) }, CHILD_OF(matroska_blockadditions) }; static EbmlSyntax matroska_blockadditions[] = { - { MATROSKA_ID_BLOCKMORE, EBML_NEST, 0, 0, 0, {.n = matroska_blockmore} }, + { MATROSKA_ID_BLOCKMORE, EBML_NEST, 0, sizeof(MatroskaBlockMore), offsetof(MatroskaBlock, blockmore), { .n = matroska_blockmore } }, CHILD_OF(matroska_blockgroup) }; @@ -3610,12 +3614,28 @@ static int matroska_parse_webvtt(MatroskaDemuxContext *matroska, return 0; } +static int matroska_parse_block_additional(MatroskaDemuxContext *matroska, + AVPacket *pkt, + const uint8_t *data, int size, uint64_t id) +{ + uint8_t *side_data = av_packet_new_side_data(pkt, + AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL, + size + 8); + if (!side_data) + return AVERROR(ENOMEM); + + AV_WB64(side_data, id); + memcpy(side_data + 8, data, size); + + return 0; +} + static int matroska_parse_frame(MatroskaDemuxContext *matroska, MatroskaTrack *track, AVStream *st, 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, + MatroskaBlockMore *blockmore, int nb_blockmore, int64_t discard_padding) { uint8_t *pkt_data = data; @@ -3647,7 +3667,7 @@ static int matroska_parse_frame(MatroskaDemuxContext *matroska, buf = NULL; } - if (!pkt_size && !additional_size) + if (!pkt_size && !nb_blockmore) goto no_output; if (!buf) @@ -3666,16 +3686,18 @@ static int matroska_parse_frame(MatroskaDemuxContext *matroska, pkt->flags = is_keyframe; pkt->stream_index = st->index; - if (additional_size > 0) { - uint8_t *side_data = av_packet_new_side_data(pkt, - AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL, - additional_size + 8); - if (!side_data) { + for (int i = 0; i < nb_blockmore; i++) { + MatroskaBlockMore *more = &blockmore[i]; + + if (!more->additional.size) + continue; + + res = matroska_parse_block_additional(matroska, pkt, more->additional.data, + more->additional.size, more->additional_id); + if (res < 0) { av_packet_unref(pkt); return AVERROR(ENOMEM); } - AV_WB64(side_data, additional_id); - memcpy(side_data + 8, additional, additional_size); } if (discard_padding) { @@ -3721,7 +3743,7 @@ fail: 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, + MatroskaBlockMore *blockmore, int nb_blockmore, int64_t cluster_pos, int64_t discard_padding) { uint64_t timecode = AV_NOPTS_VALUE; @@ -3856,7 +3878,7 @@ static int matroska_parse_block(MatroskaDemuxContext *matroska, AVBufferRef *buf res = matroska_parse_frame(matroska, track, st, buf, out_data, out_size, timecode, lace_duration, pos, !n ? is_keyframe : 0, - additional, additional_id, additional_size, + blockmore, nb_blockmore, discard_padding); if (res) return res; @@ -3897,14 +3919,12 @@ static int matroska_parse_cluster(MatroskaDemuxContext *matroska) if (res >= 0 && block->bin.size > 0) { int is_keyframe = block->non_simple ? block->reference.count == 0 : -1; - uint8_t* additional = block->additional.size > 0 ? - block->additional.data : NULL; res = matroska_parse_block(matroska, block->bin.buf, block->bin.data, block->bin.size, block->bin.pos, cluster->timecode, block->duration, - is_keyframe, additional, block->additional_id, - block->additional.size, cluster->pos, + is_keyframe, block->blockmore.elem, + block->blockmore.nb_elem, cluster->pos, block->discard_padding); }
Signed-off-by: James Almer <jamrial@gmail.com> --- No changes since v1. libavformat/matroskadec.c | 60 ++++++++++++++++++++++++++------------- 1 file changed, 40 insertions(+), 20 deletions(-)