[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