changeset 19961:9f011e6892e8

interpolate real fps of dvr-ms files using the extended stream properties. Patch by John Donaghy - johnfdonaghy gmail com
author nicodvb
date Sun, 24 Sep 2006 15:19:48 +0000
parents 5928bd5c7f0b
children c76d6a7332e8
files libmpdemux/asf.h libmpdemux/asfheader.c libmpdemux/demux_asf.c
diffstat 3 files changed, 61 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/libmpdemux/asf.h	Sun Sep 24 14:26:31 2006 +0000
+++ b/libmpdemux/asf.h	Sun Sep 24 15:19:48 2006 +0000
@@ -222,9 +222,11 @@
     unsigned packetsize;
     double   packetrate;
     unsigned movielength;
+    double avg_vid_frame_time;
     int asf_is_dvr_ms;
     uint32_t asf_frame_state;
     int asf_frame_start_found;
+    double dvr_last_vid_pts;
 };
 
 #endif
--- a/libmpdemux/asfheader.c	Sun Sep 24 14:26:31 2006 +0000
+++ b/libmpdemux/asfheader.c	Sun Sep 24 15:19:48 2006 +0000
@@ -166,6 +166,43 @@
   return -1;
 }
 
+static int get_ext_stream_properties(char *buf, int buf_len, int stream_num, double* avg_frame_time)
+{
+  // this function currently only gets the average frame time if available
+
+  int pos=0;
+  uint8_t *buffer = &buf[0];
+  uint64_t avg_ft;
+
+  while ((pos = find_asf_guid(buf, asf_ext_stream_header, pos, buf_len)) >= 0) {
+    int this_stream_num, stnamect, payct, i, objlen;
+    buffer = &buf[pos];
+
+    // the following info is available
+    // some of it may be useful but we're skipping it for now
+    // starttime(8 bytes), endtime(8),
+    // leak-datarate(4), bucket-datasize(4), init-bucket-fullness(4),
+    // alt-leak-datarate(4), alt-bucket-datasize(4), alt-init-bucket-fullness(4),
+    // max-object-size(4),
+    // flags(4) (reliable,seekable,no_cleanpoints?,resend-live-cleanpoints, rest of bits reserved)
+
+    buffer +=8+8+4+4+4+4+4+4+4+4;
+    this_stream_num=le2me_16(*(uint16_t*)buffer);buffer+=2;
+
+    if (this_stream_num == stream_num) {
+      buffer+=2; //skip stream-language-id-index
+      avg_ft = le2me_64(*(uint64_t*)buffer); // provided in 100ns units
+      *avg_frame_time = avg_ft/10000000.0f;
+
+      // after this are values for stream-name-count and
+      // payload-extension-system-count
+      // followed by associated info for each
+      return 1;
+    }
+  }
+  return 0;
+}
+
 static int asf_init_audio_stream(demuxer_t *demuxer,struct asf_priv* asf, sh_audio_t* sh_audio, ASF_stream_header_t *streamh, int *ppos, uint8_t** buf, char *hdr, unsigned int hdr_len)
 {
   uint8_t *buffer = *buf;
@@ -305,7 +342,17 @@
           asf->asf_frame_state=-1;
           asf->asf_frame_start_found=0;
           asf->asf_is_dvr_ms=1;
+          asf->dvr_last_vid_pts=0.0;
         } else asf->asf_is_dvr_ms=0;
+        if (get_ext_stream_properties(hdr, hdr_len, streamh->stream_no, &asf->avg_vid_frame_time)) {
+	  sh_video->frametime=(float)asf->avg_vid_frame_time;
+	  sh_video->fps=1.0f/sh_video->frametime; 
+        } else {
+	  asf->avg_vid_frame_time=0.0; // only used for dvr-ms when > 0.0
+	  sh_video->fps=1000.0f;
+	  sh_video->frametime=0.001f;
+        }
+
         if( mp_msg_test(MSGT_DEMUX,MSGL_V) ) print_video_header(sh_video->bih, MSGL_V);
         //asf_video_id=streamh.stream_no & 0x7F;
 	//if(demuxer->video->id==-1) demuxer->video->id=streamh.stream_no & 0x7F;
--- a/libmpdemux/demux_asf.c	Sun Sep 24 14:26:31 2006 +0000
+++ b/libmpdemux/demux_asf.c	Sun Sep 24 15:19:48 2006 +0000
@@ -197,6 +197,15 @@
             len -= frame_end_pos;
           }
           close_seg = 1;
+          if (asf->avg_vid_frame_time > 0.0 ) {
+            // correct the pts for the packet
+            // because dvr-ms files do not contain accurate
+            // pts values but we can deduce them using
+            // the average frame time
+            if (asf->dvr_last_vid_pts > 0.0)
+              dp->pts=asf->dvr_last_vid_pts+asf->avg_vid_frame_time;
+            asf->dvr_last_vid_pts = dp->pts;
+          }
         } else seq = ds->asf_seq;
       } else close_seg = ds->asf_seq!=seq;
 
@@ -487,6 +496,8 @@
 //    printf("\r -- asf: newpos=%d -- \n",newpos);
     stream_seek(demuxer->stream,newpos);
 
+    if (asf->asf_is_dvr_ms) asf->dvr_last_vid_pts = 0.0f;
+
     if (d_video->id >= 0)
     ds_fill_buffer(d_video);
     if(sh_audio){
@@ -556,7 +567,7 @@
             //printf("ASF: missing video stream!? contact the author, it may be a bug :(\n");
         } else {
             sh_video=demuxer->video->sh;sh_video->ds=demuxer->video;
-            sh_video->fps=1000.0f; sh_video->frametime=0.001f; // 1ms
+            //sh_video->fps=1000.0f; sh_video->frametime=0.001f; // 1ms  - now set when reading asf header
             //sh_video->i_bps=10*asf->packetsize; // FIXME!
         }
     }