[soc]: r4554 - in concat/libavformat: m3u.c playlist.c playlist.h
Author: gkovacs Date: Wed Jul 1 02:56:28 2009 New Revision: 4554 Log: fix timestamp issues with streams of different time bases Modified: concat/libavformat/m3u.c concat/libavformat/playlist.c concat/libavformat/playlist.h Modified: concat/libavformat/m3u.c ============================================================================== --- concat/libavformat/m3u.c Tue Jun 30 21:28:59 2009 (r4553) +++ concat/libavformat/m3u.c Wed Jul 1 02:56:28 2009 (r4554) @@ -102,6 +102,7 @@ static int m3u_read_header(AVFormatConte static int m3u_read_packet(AVFormatContext *s, AVPacket *pkt) { + int i; int ret; PlaylistD *playld; AVFormatContext *ic; @@ -110,18 +111,8 @@ static int m3u_read_packet(AVFormatConte ic = playld->pelist[playld->pe_curidx]->ic; ret = ic->iformat->read_packet(ic, pkt); if (ret >= 0) { - // TODO storing previous packet pts/dts is ugly hack - // ic->stream[]->cur_dts correct - // ic->strea[]->duration correct - // pkt->pts incorrect (huge negative) - // pkt->dts correct, depended on by ffmpeg (need to change) - // ic->stream[]->pts incorrect (0) - // ic->start_time always 0 - // changing ic->start_time has no effect - // ic->duration correct, divide by AV_TIME_BASE to get seconds if (pkt) { - playld->dts_prevpacket = pkt->dts; - pkt->dts += playld->dts_offset; + pkt->dts += ff_conv_stream_time(ic, pkt->stream_index, playld->time_offsets[pkt->stream_index]); } } // TODO switch from AVERROR_EOF to AVERROR_EOS @@ -131,7 +122,11 @@ static int m3u_read_packet(AVFormatConte // playld->dts_offset += ic->streams[0]->duration; // using streams[]->cur_dts slightly overestimates offset // playld->dts_offset += ic->streams[0]->cur_dts; - playld->dts_offset += playld->dts_prevpacket; +// playld->dts_offset += playld->dts_prevpacket; + for (i = 0; i < ic->nb_streams && i < playld->time_offsets_size; ++i) { + playld->time_offsets[i] += ff_get_duration(ic, i); + } +// playld->dts_offset += ff_get_duration(ic, pkt->stream_index); ++playld->pe_curidx; // pkt->destruct(pkt); pkt = av_malloc(sizeof(AVPacket)); Modified: concat/libavformat/playlist.c ============================================================================== --- concat/libavformat/playlist.c Tue Jun 30 21:28:59 2009 (r4553) +++ concat/libavformat/playlist.c Wed Jul 1 02:56:28 2009 (r4554) @@ -79,11 +79,12 @@ PlayElem* ff_make_playelem(char *filenam PlaylistD* ff_make_playlistd(char *filename) { + int i; PlaylistD *playld = av_malloc(sizeof(PlaylistD)); -// playld->pts_offset = 0; - playld->dts_offset = 0; -// playld->pts_prevpacket = 0; - playld->dts_prevpacket = 0; + playld->time_offsets_size = 2; // TODO don't assume we have just 2 streams + playld->time_offsets = av_malloc(sizeof(playld->time_offsets) * playld->time_offsets_size); + for (i = 0; i < playld->time_offsets_size; ++i) + playld->time_offsets[i] = 0; playld->pe_curidx = 0; ff_split_wd_fn(filename, &playld->workingdir, @@ -241,3 +242,38 @@ unsigned int ff_get_stream_offset(AVForm return snum; } +// converts duration to stream base +int64_t ff_conv_stream_time(AVFormatContext *ic, int stream_index, int64_t avt_duration) +{ + int64_t durn; + durn = (int64_t)( + avt_duration / + AV_TIME_BASE * + ic->streams[stream_index]->time_base.den / + ic->streams[stream_index]->time_base.num) + ; + printf("conv stream time from %ld to %ld/%ld is %ld\n", avt_duration, ic->streams[stream_index]->time_base.num, ic->streams[stream_index]->time_base.den, durn); + return durn; +} + +// returns duration in seconds * AV_TIME_BASE +int64_t ff_get_duration(AVFormatContext *ic, int stream_index) +{ +// TODO storing previous packet pts/dts is ugly hack +// ic->stream[]->cur_dts correct +// ic->strea[]->duration correct +// pkt->pts incorrect (huge negative) +// pkt->dts correct, depended on by ffmpeg (need to change) +// ic->stream[]->pts incorrect (0) +// ic->start_time always 0 +// changing ic->start_time has no effect +// ic->duration correct, divide by AV_TIME_BASE to get seconds +// h264 and mpeg1: pkt->dts values incorrect + int64_t durn; + durn = ic->duration; +// durn = (ic->duration / ic->streams[stream_index]->time_base.den) * +// (ic->streams[stream_index]->time_base.num / AV_TIME_BASE); + printf("duration is %ld\n", durn); + return durn; +} + Modified: concat/libavformat/playlist.h ============================================================================== --- concat/libavformat/playlist.h Tue Jun 30 21:28:59 2009 (r4553) +++ concat/libavformat/playlist.h Wed Jul 1 02:56:28 2009 (r4554) @@ -41,10 +41,12 @@ typedef struct PlaylistD { int ch_curidx; char *workingdir; char *filename; + int64_t *time_offsets; + int time_offsets_size; // int64_t pts_offset; - int64_t dts_offset; +// int64_t dts_offset; // int64_t pts_prevpacket; - int64_t dts_prevpacket; +// int64_t dts_prevpacket; } PlaylistD; PlayElem* ff_make_playelem(char *filename); @@ -60,3 +62,7 @@ char* ff_buf_getline(ByteIOContext *s); void ff_split_wd_fn(char *filepath, char **workingdir, char **filename); unsigned int ff_get_stream_offset(AVFormatContext *s); + +int64_t ff_conv_stream_time(AVFormatContext *ic, int stream_index, int64_t avt_duration); + +int64_t ff_get_duration(AVFormatContext *ic, int stream_index);
participants (1)
-
gkovacs