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

Zuxy Meng zuxy.meng at gmail.com
Mon May 7 08:05:50 CEST 2007


Hi,

2007/3/4, Zuxy Meng <zuxy.meng at gmail.com>:
> 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.

Attached is the patch against current SVN. A similar patch has been
committed for ffmpeg.

Comments?
-- 
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	?????? 23238??
+++ 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 += 8*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;
@@ -460,7 +493,7 @@
         break;
         }
       case ASF_GUID_PREFIX_video_stream: {
-        unsigned int len;
+        unsigned int len, bps = 0;
         float asp_ratio;
         sh_video_t* sh_video=new_sh_video(demuxer,streamh->stream_no & 0x7F);
         mp_msg(MSGT_DEMUX, MSGL_INFO, MSGTR_VideoID, "asfheader", streamh->stream_no & 0x7F);
@@ -481,9 +514,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;
@@ -493,6 +527,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;


More information about the MPlayer-dev-eng mailing list