Mercurial > libavformat.hg
changeset 1904:df5fe029a504 libavformat
reorder pts of packets from tracks using V_MPEG* codecs
author | aurel |
---|---|
date | Sun, 11 Mar 2007 23:40:57 +0000 |
parents | 0f2186d1cc19 |
children | 54d1bdcb47e2 |
files | matroska.c |
diffstat | 1 files changed, 60 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/matroska.c Sun Mar 11 23:19:27 2007 +0000 +++ b/matroska.c Sun Mar 11 23:40:57 2007 +0000 @@ -178,6 +178,7 @@ MATROSKA_TRACK_DEFAULT = (1<<1), MATROSKA_TRACK_LACING = (1<<2), MATROSKA_TRACK_REAL_V = (1<<4), + MATROSKA_TRACK_REORDER = (1<<8), MATROSKA_TRACK_SHIFT = (1<<16) } MatroskaTrackFlags; @@ -336,6 +337,10 @@ /* The packet queue. */ AVPacket **packets; int num_packets; + /* Second packet queue used to reorder pts of some video track. */ + AVPacket **packets_reorder; + int num_packets_reorder; + uint64_t reorder_max_pts; /* have we already parse metadata/cues/clusters? */ int metadata_parsed, @@ -1021,6 +1026,43 @@ } /* + * Put a packet into our internal reordering queue. Will be moved to the + * main packet queue when enough packets are available to reorder pts. + */ + +static void +matroska_queue_packet_reordered (MatroskaDemuxContext *matroska, + AVPacket *pkt, + int is_bframe) +{ + if (matroska->num_packets_reorder && !is_bframe + && pkt->pts > matroska->reorder_max_pts) { + /* reorder pts */ + int i, j, k = 1; + for (j=matroska->num_packets_reorder-1; j && k; j--) { + k = 0; + for (i=0; i<j; i++) { + if (matroska->packets_reorder[i]->pts > matroska->packets_reorder[i+1]->pts) { + FFSWAP(uint64_t, matroska->packets_reorder[i]->pts, matroska->packets_reorder[i+1]->pts); + k = 1; + } + } + } + /* then really queue the packets */ + for (i=0; i<matroska->num_packets_reorder; i++) + matroska_queue_packet (matroska, matroska->packets_reorder[i]); + matroska->num_packets_reorder = 0; + } + matroska->packets_reorder = + av_realloc(matroska->packets_reorder, + (matroska->num_packets_reorder + 1) * sizeof(AVPacket *)); + matroska->packets_reorder[matroska->num_packets_reorder++] = pkt; + if (pkt->pts > matroska->reorder_max_pts) + matroska->reorder_max_pts = pkt->pts; +} + + +/* * Autodetecting... */ @@ -2245,6 +2287,14 @@ } + else if (codec_id == CODEC_ID_MPEG1VIDEO || + codec_id == CODEC_ID_MPEG2VIDEO || + codec_id == CODEC_ID_MPEG4 || + codec_id == CODEC_ID_MSMPEG4V3 || + codec_id == CODEC_ID_H264) { + track->flags |= MATROSKA_TRACK_REORDER; + } + else if (codec_id == CODEC_ID_AAC && !track->codec_priv_size) { MatroskaAudioTrack *audiotrack = (MatroskaAudioTrack *) track; int profile = matroska_aac_profile(track->codec_id); @@ -2541,6 +2591,9 @@ pkt->pts = timecode; pkt->pos = pos; + if (matroska->tracks[track]->flags & MATROSKA_TRACK_REORDER) + matroska_queue_packet_reordered(matroska, pkt, is_bframe); + else matroska_queue_packet(matroska, pkt); } data += lace_size[n]; @@ -2775,6 +2828,13 @@ } av_free(matroska->packets); } + if (matroska->packets_reorder) { + for (n = 0; n < matroska->num_packets_reorder; n++) { + av_free_packet(matroska->packets_reorder[n]); + av_free(matroska->packets_reorder[n]); + } + av_free(matroska->packets_reorder); + } for (n = 0; n < matroska->num_tracks; n++) { MatroskaTrack *track = matroska->tracks[n];