[MPlayer-dev-eng] [PATCH] Set i_bps for ASF files

Zuxy Meng zuxy.meng at gmail.com
Sun Mar 4 13:07:26 CET 2007


Hi,

The patch sets i_bps for asf files, according either to their extended
stream property or (if the former isn't available) the stream bitrate
object. Extended stream property gives bitrate for raw data (without
overhead) i.e. data that is actually sent out to network when streamed
and is the same as what WMP reports as bitrate.

-- 
Zuxy
Beauty is truth,
While truth is beauty.
PGP KeyID: E8555ED6
-------------- next part --------------
Index: libmpdemux/demux_asf.c
===================================================================
--- libmpdemux/demux_asf.c	?????? 22434??
+++ libmpdemux/demux_asf.c	????????????
@@ -571,7 +571,6 @@
         } else {
             sh_video=demuxer->video->sh;sh_video->ds=demuxer->video;
             //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!
 
             if (asf->asf_is_dvr_ms) {
                 sh_video->bih->biWidth = 0;
Index: libmpdemux/asfheader.c
===================================================================
--- libmpdemux/asfheader.c	?????? 22434??
+++ libmpdemux/asfheader.c	????????????
@@ -64,6 +64,8 @@
   0xaf, 0x5b, 0x77, 0x48, 0x84, 0x67, 0xaa, 0x8c, 0x44, 0xfa, 0x4c, 0xca};
 const char asf_content_encryption[16] = {0xfb, 0xb3, 0x11, 0x22,
   0x23, 0xbd, 0xd2, 0x11, 0xb4, 0xb7, 0x00, 0xa0, 0xc9, 0x55, 0xfc, 0x6e};
+const char asf_stream_bitrate[16] = {0xce, 0x75, 0xf8, 0x7b,
+  0x8d, 0x46, 0xd1, 0x11, 0x8d, 0x82, 0x00, 0x60, 0x97, 0xc9, 0xa2, 0xb2};
 
 typedef struct {
   // must be 0 for metadata record, might be non-zero for metadata lib record
@@ -183,13 +185,15 @@
   return -1;
 }
 
-static int get_ext_stream_properties(char *buf, int buf_len, int stream_num, double* avg_frame_time)
+static int get_ext_stream_properties(char *buf, int buf_len, int stream_num,
+    double* avg_frame_time, unsigned* bps)
 {
   // this function currently only gets the average frame time if available
 
   int pos=0;
   uint8_t *buffer = &buf[0];
   uint64_t avg_ft;
+  unsigned bitrate;
 
   while ((pos = find_asf_guid(buf, asf_ext_stream_header, pos, buf_len)) >= 0) {
     int this_stream_num, stnamect, payct, i, objlen;
@@ -203,13 +207,16 @@
     // 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;
+    buffer += 8+8;
+    bitrate = AV_RL32(buffer);
+    buffer += 4+4+4+4+4+4+4+4;
     this_stream_num=AV_RL16(buffer);buffer+=2;
 
     if (this_stream_num == stream_num) {
       buffer+=2; //skip stream-language-id-index
       avg_ft = AV_RL32(buffer) | (uint64_t)AV_RL32(buffer + 4) << 32; // provided in 100ns units
       *avg_frame_time = avg_ft/10000000.0f;
+      *bps = bitrate / 8;
 
       // after this are values for stream-name-count and
       // payload-extension-system-count
@@ -326,6 +333,32 @@
   return 1;
 } 
 
+static int get_bitrate(char *buf, int buf_len, int this_stream_num,
+    unsigned* bps)
+{
+  int pos = find_asf_guid(buf, asf_stream_bitrate, 0, buf_len);
+  unsigned count, i;
+
+  if (pos < 0)
+    return 0;
+
+  buf += pos;
+  count = AV_RL16(buf);
+  buf += 2;
+
+  for (i = 0; i < count; i++) {
+    unsigned bitrate, flags = AV_RL16(buf);
+    buf += 2;
+    bitrate = AV_RL32(buf);
+    buf += 4;
+    if (flags == this_stream_num) {
+      *bps = bitrate / 8;
+      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;
@@ -459,7 +492,7 @@
         }
       case ASF_GUID_PREFIX_video_stream: {
         sh_video_t* sh_video=new_sh_video(demuxer,streamh->stream_no & 0x7F);
-        unsigned int len=streamh->type_size-(4+4+1+2);
+        unsigned int len=streamh->type_size-(4+4+1+2), bps = 0;
         float asp_ratio;
 	++video_streams;
 //        sh_video->bih=malloc(chunksize); memset(sh_video->bih,0,chunksize);
@@ -477,9 +510,10 @@
           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)) {
+        if (get_ext_stream_properties(hdr, hdr_len, streamh->stream_no, &asf->avg_vid_frame_time, &bps)) {
 	  sh_video->frametime=(float)asf->avg_vid_frame_time;
 	  sh_video->fps=1.0f/sh_video->frametime; 
+	  sh_video->i_bps = bps; // bps for raw data
         } else {
 	  asf->avg_vid_frame_time=0.0; // only used for dvr-ms when > 0.0
 	  sh_video->fps=1000.0f;
@@ -489,6 +523,8 @@
           sh_video->aspect = asp_ratio * sh_video->bih->biWidth /
             sh_video->bih->biHeight;
         }
+	if (bps == 0 && get_bitrate(hdr, hdr_len, streamh->stream_no, &bps))
+	  sh_video->i_bps = bps; // bps with overhead
 
         if( mp_msg_test(MSGT_DEMUX,MSGL_V) ) print_video_header(sh_video->bih, MSGL_V);
         //asf_video_id=streamh.stream_no & 0x7F;
@@ -516,7 +552,7 @@
       asf->packetsize=fileh->max_packet_size;
       asf->packet=malloc(asf->packetsize); // !!!
       asf->packetrate=fileh->max_bitrate/8.0/(double)asf->packetsize;
-      asf->movielength=fileh->send_duration/10000000LL;
+      asf->movielength=(fileh->play_duration-fileh->preroll)/10000000LL;
   }
 
   // find content header


More information about the MPlayer-dev-eng mailing list