[FFmpeg-soc] [soc]: r4554 - in concat/libavformat: m3u.c playlist.c playlist.h

gkovacs subversion at mplayerhq.hu
Wed Jul 1 02:56:28 CEST 2009


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);


More information about the FFmpeg-soc mailing list