Commit 78b96be7 authored by James Almer's avatar James Almer

avformat/matroskadec: use AVPacketList to queue packets

It's more robust and efficient.
Signed-off-by: 's avatarJames Almer <jamrial@gmail.com>
parent 58ce4fde
...@@ -338,9 +338,8 @@ typedef struct MatroskaDemuxContext { ...@@ -338,9 +338,8 @@ typedef struct MatroskaDemuxContext {
int64_t segment_start; int64_t segment_start;
/* the packet queue */ /* the packet queue */
AVPacket **packets; AVPacketList *queue;
int num_packets; AVPacketList *queue_end;
AVPacket *prev_pkt;
int done; int done;
...@@ -2722,11 +2721,11 @@ fail: ...@@ -2722,11 +2721,11 @@ fail:
static int matroska_deliver_packet(MatroskaDemuxContext *matroska, static int matroska_deliver_packet(MatroskaDemuxContext *matroska,
AVPacket *pkt) AVPacket *pkt)
{ {
if (matroska->num_packets > 0) { if (matroska->queue) {
MatroskaTrack *tracks = matroska->tracks.elem; MatroskaTrack *tracks = matroska->tracks.elem;
MatroskaTrack *track; MatroskaTrack *track;
memcpy(pkt, matroska->packets[0], sizeof(AVPacket));
av_freep(&matroska->packets[0]); ff_packet_list_get(&matroska->queue, &matroska->queue_end, pkt);
track = &tracks[pkt->stream_index]; track = &tracks[pkt->stream_index];
if (track->has_palette) { if (track->has_palette) {
uint8_t *pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE); uint8_t *pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE);
...@@ -2737,20 +2736,6 @@ static int matroska_deliver_packet(MatroskaDemuxContext *matroska, ...@@ -2737,20 +2736,6 @@ static int matroska_deliver_packet(MatroskaDemuxContext *matroska,
} }
track->has_palette = 0; track->has_palette = 0;
} }
if (matroska->num_packets > 1) {
void *newpackets;
memmove(&matroska->packets[0], &matroska->packets[1],
(matroska->num_packets - 1) * sizeof(AVPacket *));
newpackets = av_realloc(matroska->packets,
(matroska->num_packets - 1) *
sizeof(AVPacket *));
if (newpackets)
matroska->packets = newpackets;
} else {
av_freep(&matroska->packets);
matroska->prev_pkt = NULL;
}
matroska->num_packets--;
return 0; return 0;
} }
...@@ -2762,16 +2747,7 @@ static int matroska_deliver_packet(MatroskaDemuxContext *matroska, ...@@ -2762,16 +2747,7 @@ static int matroska_deliver_packet(MatroskaDemuxContext *matroska,
*/ */
static void matroska_clear_queue(MatroskaDemuxContext *matroska) static void matroska_clear_queue(MatroskaDemuxContext *matroska)
{ {
matroska->prev_pkt = NULL; ff_packet_list_free(&matroska->queue, &matroska->queue_end);
if (matroska->packets) {
int n;
for (n = 0; n < matroska->num_packets; n++) {
av_packet_unref(matroska->packets[n]);
av_freep(&matroska->packets[n]);
}
av_freep(&matroska->packets);
matroska->num_packets = 0;
}
} }
static int matroska_parse_laces(MatroskaDemuxContext *matroska, uint8_t **buf, static int matroska_parse_laces(MatroskaDemuxContext *matroska, uint8_t **buf,
...@@ -2953,7 +2929,11 @@ static int matroska_parse_rm_audio(MatroskaDemuxContext *matroska, ...@@ -2953,7 +2929,11 @@ static int matroska_parse_rm_audio(MatroskaDemuxContext *matroska,
track->audio.buf_timecode = AV_NOPTS_VALUE; track->audio.buf_timecode = AV_NOPTS_VALUE;
pkt->pos = pos; pkt->pos = pos;
pkt->stream_index = st->index; pkt->stream_index = st->index;
dynarray_add(&matroska->packets, &matroska->num_packets, pkt); ret = ff_packet_list_put(&matroska->queue, &matroska->queue_end, pkt, 0);
if (ret < 0) {
av_packet_free(&pkt);
return AVERROR(ENOMEM);
}
} }
return 0; return 0;
...@@ -3152,8 +3132,11 @@ static int matroska_parse_webvtt(MatroskaDemuxContext *matroska, ...@@ -3152,8 +3132,11 @@ static int matroska_parse_webvtt(MatroskaDemuxContext *matroska,
pkt->duration = duration; pkt->duration = duration;
pkt->pos = pos; pkt->pos = pos;
dynarray_add(&matroska->packets, &matroska->num_packets, pkt); err = ff_packet_list_put(&matroska->queue, &matroska->queue_end, pkt, 0);
matroska->prev_pkt = pkt; if (err < 0) {
av_packet_free(&pkt);
return AVERROR(ENOMEM);
}
return 0; return 0;
} }
...@@ -3268,8 +3251,11 @@ FF_DISABLE_DEPRECATION_WARNINGS ...@@ -3268,8 +3251,11 @@ FF_DISABLE_DEPRECATION_WARNINGS
FF_ENABLE_DEPRECATION_WARNINGS FF_ENABLE_DEPRECATION_WARNINGS
#endif #endif
dynarray_add(&matroska->packets, &matroska->num_packets, pkt); res = ff_packet_list_put(&matroska->queue, &matroska->queue_end, pkt, 0);
matroska->prev_pkt = pkt; if (res < 0) {
av_packet_free(&pkt);
return AVERROR(ENOMEM);
}
return 0; return 0;
...@@ -3433,7 +3419,6 @@ static int matroska_parse_cluster_incremental(MatroskaDemuxContext *matroska) ...@@ -3433,7 +3419,6 @@ static int matroska_parse_cluster_incremental(MatroskaDemuxContext *matroska)
memset(&matroska->current_cluster, 0, sizeof(MatroskaCluster)); memset(&matroska->current_cluster, 0, sizeof(MatroskaCluster));
matroska->current_cluster_num_blocks = 0; matroska->current_cluster_num_blocks = 0;
matroska->current_cluster_pos = avio_tell(matroska->ctx->pb); matroska->current_cluster_pos = avio_tell(matroska->ctx->pb);
matroska->prev_pkt = NULL;
/* sizeof the ID which was already read */ /* sizeof the ID which was already read */
if (matroska->current_id) if (matroska->current_id)
matroska->current_cluster_pos -= 4; matroska->current_cluster_pos -= 4;
...@@ -3486,7 +3471,6 @@ static int matroska_parse_cluster(MatroskaDemuxContext *matroska) ...@@ -3486,7 +3471,6 @@ static int matroska_parse_cluster(MatroskaDemuxContext *matroska)
if (!matroska->contains_ssa) if (!matroska->contains_ssa)
return matroska_parse_cluster_incremental(matroska); return matroska_parse_cluster_incremental(matroska);
pos = avio_tell(matroska->ctx->pb); pos = avio_tell(matroska->ctx->pb);
matroska->prev_pkt = NULL;
if (matroska->current_id) if (matroska->current_id)
pos -= 4; /* sizeof the ID which was already read */ pos -= 4; /* sizeof the ID which was already read */
res = ebml_parse(matroska, matroska_clusters, &cluster); res = ebml_parse(matroska, matroska_clusters, &cluster);
...@@ -3671,10 +3655,10 @@ static int webm_clusters_start_with_keyframe(AVFormatContext *s) ...@@ -3671,10 +3655,10 @@ static int webm_clusters_start_with_keyframe(AVFormatContext *s)
matroska->current_id = 0; matroska->current_id = 0;
matroska_clear_queue(matroska); matroska_clear_queue(matroska);
if (matroska_parse_cluster(matroska) < 0 || if (matroska_parse_cluster(matroska) < 0 ||
matroska->num_packets <= 0) { !matroska->queue) {
break; break;
} }
pkt = matroska->packets[0]; pkt = &matroska->queue->pkt;
cluster_pos += cluster_length + 12; // 12 is the offset of the cluster id and length. cluster_pos += cluster_length + 12; // 12 is the offset of the cluster id and length.
if (!(pkt->flags & AV_PKT_FLAG_KEY)) { if (!(pkt->flags & AV_PKT_FLAG_KEY)) {
rv = 0; rv = 0;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment