MPlayer-1.0rc1 和 MPlayer-1.0rc2 的VBR patch【已修复mad播放VBR MP3播放总时长显示问题】
patch使用注意事项:
1.对于MPlayer-1.0rc2 的用此配置:
./configure –prefix=/usr –confdir=/etc –target=arm-linux –host-cc=/usr/bin/gcc –cc=/root/buildroot/buildroot/build_arm/staging_dir/usr/bin/arm-linux-uclibc-gcc –as=/root/buildroot/buildroot/build_arm/staging_dir/usr/bin/arm-linux-uclibc-as –with-extraincdir=/root/buildroot/buildroot/build_arm/staging_dir/usr/include –with-extralibdir=/root/buildroot/buildroot/build_arm/staging_dir/lib –enable-mad –enable-fbdev –disable-big-endian –disable-tv –enable-dynamic-plugins –disable-armv5te
对于MPlayer-1.0rc1 的配置,我这里是buildroot中加了mplayer,其自己编译的,是在源码基础上,打了两个patch: mplayer/mplayer-1.0rc1-atmel.3.patch 和 mplayer-1.0rc1-index.patch
然后再用上面rc2的配置,或者是如下的配置:
./configure –prefix=/usr –confdir=/etc –target=arm-linux –host-cc=/usr/bin/gcc –cc=/root/buildroot/buildroot/build_arm/staging_dir/usr/bin/arm-linux-uclibc-gcc –as=/root/buildroot/buildroot/build_arm/staging_dir/usr/bin/arm-linux-uclibc-as –with-extraincdir=/root/buildroot/buildroot/build_arm/staging_dir/usr/include –with-extralibdir=/root/buildroot/buildroot/build_arm/staging_dir/lib –enable-mad –enable-fbdev –disable-big-endian –disable-mpdvdkit –enable-largefiles –disable-tv –enable-dynamic-plugins –disable-armv5te
编译即可。
说明:第二种的rc1的配置,比rc2多了–disable-mpdvdkit 和–enable-largefiles,原因是如果用了–disable-mpdvdkit,会使得off_t类型定义变成4字节的int(long也是4字节),此时会导致demux_audio.c工作不正常,所以加上–enable-largefiles,使得off_t类型定义为long long,sizeof(off_t)为8,然后所有输入才正常。
——————————————————————————————-
MPlayer-1.0rc1_VBR_Mad.patch:mplayer_1.0rc1_vbr_fixedMad.patch
diff -ruNa MPlayer-1.0rc1_orig/libmpcodecs/ad_hwmpa.c MPlayer-1.0rc1/libmpcodecs/ad_hwmpa.c
— MPlayer-1.0rc1_orig/libmpcodecs/ad_hwmpa.c 2009-09-10 12:23:05.000000000 +0800
+++ MPlayer-1.0rc1/libmpcodecs/ad_hwmpa.c 2009-09-10 12:24:25.000000000 +0800
@@ -35,7 +35,7 @@
{
while(cnt + 4 < sh->a_in_buffer_len)
{
– x = mp_get_mp3_header(&(sh->a_in_buffer[cnt]), chans, srate, spf, mpa_layer, br);
+ x = mp_get_mp3_header(&(sh->a_in_buffer[cnt]), chans, srate, spf, mpa_layer, br, NULL);
if(x > 0)
{
frames_count++;
diff -ruNa MPlayer-1.0rc1_orig/libmpcodecs/ad_libmad.c MPlayer-1.0rc1/libmpcodecs/ad_libmad.c
— MPlayer-1.0rc1_orig/libmpcodecs/ad_libmad.c 2009-09-10 12:23:05.000000000 +0800
+++ MPlayer-1.0rc1/libmpcodecs/ad_libmad.c 2009-09-10 12:24:30.000000000 +0800
@@ -85,7 +85,11 @@
sh->channels=(this->frame.header.mode == MAD_MODE_SINGLE_CHANNEL) ? 1 : 2;
sh->samplerate=this->frame.header.samplerate;
– sh->i_bps=this->frame.header.bitrate/8;
+ /* only recaculate the i_bps if the Mplayer don’t calc it
+ when VBR the i_bsp is already calculated by Mplayer */
+ if(sh->i_bps < 0)
+ sh->i_bps=this->frame.header.bitrate/8;
+
#ifdef WORDS_BIGENDIAN
sh->sample_format = AF_FORMAT_S16_BE;
#else
diff -ruNa MPlayer-1.0rc1_orig/libmpcodecs/ad_mp3lib.c MPlayer-1.0rc1/libmpcodecs/ad_mp3lib.c
— MPlayer-1.0rc1_orig/libmpcodecs/ad_mp3lib.c 2009-09-10 12:23:05.000000000 +0800
+++ MPlayer-1.0rc1/libmpcodecs/ad_mp3lib.c 2009-09-10 12:24:35.000000000 +0800
@@ -47,10 +47,10 @@
MP3_samplerate=MP3_channels=0;
sh->a_buffer_len=MP3_DecodeFrame(sh->a_buffer,-1);
if(!sh->a_buffer_len) return 0; // unsupported layer/format
– sh->channels=2; // hack
+ sh->channels=sh->wf->nChannels;
sh->samplesize=2;
sh->samplerate=MP3_samplerate;
– sh->i_bps=MP3_bitrate*(1000/8);
+ sh->i_bps=sh->wf->nAvgBytesPerSec;
MP3_PrintHeader();
return 1;
}
diff -ruNa MPlayer-1.0rc1_orig/libmpdemux/demux_audio.c MPlayer-1.0rc1/libmpdemux/demux_audio.c
— MPlayer-1.0rc1_orig/libmpdemux/demux_audio.c 2009-09-10 12:23:05.000000000 +0800
+++ MPlayer-1.0rc1/libmpdemux/demux_audio.c 2009-09-10 12:27:51.000000000 +0800
@@ -43,6 +43,7 @@
int mpa_spf;
int mpa_layer;
int mpa_br;
+ int mpa_ssize;
int cons_hdrs; // if this reaches MIN_MP3_HDRS we accept as MP3 file
struct mp3_hdr *next;
} mp3_hdr_t;
@@ -88,7 +89,7 @@
*/
static mp3_hdr_t *add_mp3_hdr(mp3_hdr_t **list, off_t st_pos,
int mp3_chans, int mp3_freq, int mpa_spf,
– int mpa_layer, int mpa_br, int mp3_flen) {
+ int mpa_layer, int mpa_br, int mp3_flen, int mpa_ssize) {
mp3_hdr_t *tmp;
int in_list = 0;
while (*list && (*list)->next_frame_pos <= st_pos) {
@@ -125,6 +126,7 @@
tmp->mp3_freq = mp3_freq;
tmp->mpa_spf = mpa_spf;
tmp->mpa_layer = mpa_layer;
+ tmp->mpa_ssize = mpa_ssize;
tmp->mpa_br = mpa_br;
tmp->cons_hdrs = 1;
tmp->next = *list;
@@ -282,6 +284,7 @@
sh_audio_t* sh_audio;
uint8_t hdr[HDR_SIZE];
int frmt = 0, n = 0, step;
+ int mpeghdr_pos;
off_t st_pos = 0, next_frame_pos = 0;
// mp3_hdrs list is sorted first by next_frame_pos and then by frame_pos
mp3_hdr_t *mp3_hdrs = NULL, *mp3_found = NULL;
@@ -293,16 +296,15 @@
s = demuxer->stream;
+ mpeghdr_pos = stream_tell(s);
stream_read(s, hdr, HDR_SIZE);
while(n < 30000 && !s->eof) {
– int mp3_freq, mp3_chans, mp3_flen, mpa_layer, mpa_spf, mpa_br;
+ int mp3_freq, mp3_chans, mp3_flen, mpa_layer, mpa_spf, mpa_br, mpa_ssize;
st_pos = stream_tell(s) – HDR_SIZE;
step = 1;
if( hdr[0] == ‘R’ && hdr[1] == ‘I’ && hdr[2] == ‘F’ && hdr[3] == ‘F’ ) {
stream_skip(s,4);
– if(s->eof)
– break;
stream_read(s,hdr,4);
if(s->eof)
break;
@@ -316,16 +318,19 @@
int len;
stream_skip(s,2);
stream_read(s,hdr,4);
+ if(s->eof)
+ break;
len = (hdr[0]<<21) | (hdr[1]<<14) | (hdr[2]<<7) | hdr[3];
stream_skip(s,len);
+ mpeghdr_pos = stream_tell(s);
step = 4;
} else if( hdr[0] == ‘f’ && hdr[1] == ‘m’ && hdr[2] == ‘t’ && hdr[3] == ‘ ‘ ) {
frmt = WAV;
break;
} else if((mp3_flen = mp_get_mp3_header(hdr, &mp3_chans, &mp3_freq,
– &mpa_spf, &mpa_layer, &mpa_br)) > 0) {
+ &mpa_spf, &mpa_layer, &mpa_br, &mpa_ssize)) > 0) {
mp3_found = add_mp3_hdr(&mp3_hdrs, st_pos, mp3_chans, mp3_freq,
– mpa_spf, mpa_layer, mpa_br, mp3_flen);
+ mpa_spf, mpa_layer, mpa_br, mp3_flen, mpa_ssize);
if (mp3_found) {
frmt = MP3;
break;
@@ -349,7 +354,42 @@
sh_audio = new_sh_audio(demuxer,0);
switch(frmt) {
– case MP3:
+ case MP3: {
+ // Search for VBR header and compute correct bitrate if necessary
+ uint8_t vbrhdr[4];
+ uint8_t framesnb_hdr[4];
+ int frames_nb = -1;
+ uint8_t frames_field;
+
+ stream_seek(s,mpeghdr_pos+4+mp3_found->mpa_ssize);
+ stream_read(s,vbrhdr,4);
+
+ if(!s->eof)
+ if( (vbrhdr[0] == ‘X’ && vbrhdr[1] == ‘i’ && vbrhdr[2] == ‘n’ && vbrhdr[3] == ‘g’)
+ || (vbrhdr[0] == ‘I’ && vbrhdr[1] == ‘n’ && vbrhdr[2] == ‘f’ && vbrhdr[3] == ‘o’) ) { // We found a XING header
+ stream_seek(s,mpeghdr_pos+11+mp3_found->mpa_ssize);
+ stream_read(s,&frames_field,1);
+ if( frames_field & 1 ) {
+ stream_seek(s,mpeghdr_pos+12+mp3_found->mpa_ssize); // We jump to Frames number
+ stream_read(s,framesnb_hdr,4);
+ if(s->eof)
+ break;
+ frames_nb = (framesnb_hdr[0]<<24) | (framesnb_hdr[1]<<16) | (framesnb_hdr[2]<<8) | (framesnb_hdr[3]);
+ }
+ }
+ else {
+ stream_seek(s,mpeghdr_pos+36);
+ stream_read(s,vbrhdr,4);
+
+ if( vbrhdr[0] == ‘V’ && vbrhdr[1] == ‘B’ && vbrhdr[2] == ‘R’ && vbrhdr[3] == ‘I’ ) { // We found a VBRI header
+ stream_seek(s,mpeghdr_pos+50); // We jump to Frames number
+ stream_read(s,framesnb_hdr,4);
+ if(s->eof)
+ break;
+ frames_nb = (framesnb_hdr[0]<<24) | (framesnb_hdr[1]<<16) | (framesnb_hdr[2]<<8) | (framesnb_hdr[3]);
+ }
+ }
+
sh_audio->format = (mp3_found->mpa_layer < 3 ? 0x50 : 0x55);
demuxer->movi_start = mp3_found->frame_pos;
next_frame_pos = mp3_found->next_frame_pos;
@@ -360,7 +400,12 @@
sh_audio->wf->wFormatTag = sh_audio->format;
sh_audio->wf->nChannels = mp3_found->mp3_chans;
sh_audio->wf->nSamplesPerSec = mp3_found->mp3_freq;
– sh_audio->wf->nAvgBytesPerSec = mp3_found->mpa_br * (1000 / 8);
+ if (frames_nb > 0)
+ {
+ sh_audio->wf->nAvgBytesPerSec = ((demuxer->movi_end-demuxer->movi_start)*mp3_found->mp3_freq)/(frames_nb*mp3_found->mpa_spf);
+ }
+ else
+ sh_audio->wf->nAvgBytesPerSec = mp3_found->mpa_br * (1000 / 8);
sh_audio->wf->nBlockAlign = mp3_found->mpa_spf;
sh_audio->wf->wBitsPerSample = 16;
sh_audio->wf->cbSize = 0;
@@ -402,7 +447,7 @@
demux_info_add(demuxer,"Genre",genres[g]);
}
}
– break;
+ } break;
case WAV: {
unsigned int chunk_type;
unsigned int chunk_size;
@@ -703,13 +748,13 @@
static int demux_audio_control(demuxer_t *demuxer,int cmd, void *arg){
sh_audio_t *sh_audio=demuxer->audio->sh;
– int audio_length = demuxer->movi_end / sh_audio->i_bps;
+ double audio_length = (double)(demuxer->movi_end-demuxer->movi_start) / (double)sh_audio->i_bps;
da_priv_t* priv = demuxer->priv;
switch(cmd) {
case DEMUXER_CTRL_GET_TIME_LENGTH:
if (audio_length<=0) return DEMUXER_CTRL_DONTKNOW;
– *((double *)arg)=(double)audio_length;
+ *((double *)arg)=audio_length;
return DEMUXER_CTRL_GUESS;
case DEMUXER_CTRL_GET_PERCENT_POS:
diff -ruNa MPlayer-1.0rc1_orig/libmpdemux/mp3_hdr.c MPlayer-1.0rc1/libmpdemux/mp3_hdr.c
— MPlayer-1.0rc1_orig/libmpdemux/mp3_hdr.c 2009-09-10 12:23:05.000000000 +0800
+++ MPlayer-1.0rc1/libmpdemux/mp3_hdr.c 2009-09-10 12:28:31.000000000 +0800
@@ -34,7 +34,7 @@
/*
* return frame size or -1 (bad frame)
*/
-int mp_get_mp3_header(unsigned char* hbuf,int* chans, int* srate, int* spf, int* mpa_layer, int* br){
+int mp_get_mp3_header(unsigned char* hbuf,int* chans, int* srate, int* spf, int* mpa_layer, int* br, int* side_info_size){
int stereo,ssize,lsf,framesize,padding,bitrate_index,sampling_frequency, divisor;
int bitrate;
int layer, mult[3] = { 12000, 144000, 144000 };
@@ -99,6 +99,7 @@
else
ssize = (stereo == 1) ? 17 : 32;
if(!((newhead>>16)&0x1)) ssize += 2; // CRC
+ if(side_info_size) *side_info_size = ssize;
bitrate = tabsel_123[lsf][layer-1][bitrate_index];
framesize = bitrate * mult[layer-1];
diff -ruNa MPlayer-1.0rc1_orig/libmpdemux/mp3_hdr.h MPlayer-1.0rc1/libmpdemux/mp3_hdr.h
— MPlayer-1.0rc1_orig/libmpdemux/mp3_hdr.h 2009-09-10 12:23:05.000000000 +0800
+++ MPlayer-1.0rc1/libmpdemux/mp3_hdr.h 2009-09-10 12:28:40.000000000 +0800
@@ -1,7 +1,7 @@
-int mp_get_mp3_header(unsigned char* hbuf,int* chans, int* freq, int* spf, int* mpa_layer, int* br);
+int mp_get_mp3_header(unsigned char* hbuf,int* chans, int* freq, int* spf, int* mpa_layer, int* br, int* side_info_size);
-#define mp_decode_mp3_header(hbuf) mp_get_mp3_header(hbuf,NULL,NULL,NULL,NULL,NULL)
+#define mp_decode_mp3_header(hbuf) mp_get_mp3_header(hbuf,NULL,NULL,NULL,NULL,NULL,NULL)
static inline int mp_check_mp3_header(unsigned int head){
if( (head & 0x0000e0ff) != 0x0000e0ff ||
diff -ruNa MPlayer-1.0rc1_orig/libmpdemux/muxer_mpeg.c MPlayer-1.0rc1/libmpdemux/muxer_mpeg.c
— MPlayer-1.0rc1_orig/libmpdemux/muxer_mpeg.c 2009-09-10 12:23:05.000000000 +0800
+++ MPlayer-1.0rc1/libmpdemux/muxer_mpeg.c 2009-09-10 12:28:48.000000000 +0800
@@ -2079,7 +2079,7 @@
{
if(s->b_buffer[i] == 0xFF && ((s->b_buffer[i+1] & 0xE0) == 0xE0))
{
– len = mp_get_mp3_header(&(s->b_buffer[i]), &chans, &srate, &spf, &layer, NULL);
+ len = mp_get_mp3_header(&(s->b_buffer[i]), &chans, &srate, &spf, &layer, NULL, NULL);
if(len > 0 && (srate == s->wf->nSamplesPerSec) && (i + len <= s->b_buffer_len))
{
score[layer]++;
@@ -2132,7 +2132,7 @@
if(s->b_buffer[i] == 0xFF && ((s->b_buffer[i+1] & 0xE0) == 0xE0))
{
– len = mp_get_mp3_header(&(s->b_buffer[i]), &chans, &srate, &spf, &layer, NULL);
+ len = mp_get_mp3_header(&(s->b_buffer[i]), &chans, &srate, &spf, &layer, NULL, NULL);
if(len > 0 && (srate == s->wf->nSamplesPerSec) && (i + len <= s->b_buffer_len)
&& layer == spriv->mpa_layer)
{
————————————————-无敌分割线—————————————-
MPlayer-1.0rc2的VBR MP3的patch:mplayer_1.0rc2_vbr_fixedMad.patch
diff -ruNa MPlayer-1.0rc2/libmpcodecs/ad_hwmpa.c MPlayer-1.0rc2_VBR/libmpcodecs/ad_hwmpa.c
— MPlayer-1.0rc2/libmpcodecs/ad_hwmpa.c 2009-09-02 18:00:08.000000000 +0800
+++ MPlayer-1.0rc2_VBR/libmpcodecs/ad_hwmpa.c 2009-09-02 17:59:40.000000000 +0800
@@ -35,7 +35,7 @@
{
while(cnt + 4 < sh->a_in_buffer_len)
{
– x = mp_get_mp3_header(&(sh->a_in_buffer[cnt]), chans, srate, spf, mpa_layer, br);
+ x = mp_get_mp3_header(&(sh->a_in_buffer[cnt]), chans, srate, spf, mpa_layer, br, NULL);
if(x > 0)
{
frames_count++;
diff -ruNa MPlayer-1.0rc2/libmpcodecs/ad_libmad.c MPlayer-1.0rc2_VBR/libmpcodecs/ad_libmad.c
— MPlayer-1.0rc2/libmpcodecs/ad_libmad.c 2009-09-02 18:00:07.000000000 +0800
+++ MPlayer-1.0rc2_VBR/libmpcodecs/ad_libmad.c 2009-09-02 17:59:39.000000000 +0800
@@ -85,7 +85,10 @@
sh->channels=(this->frame.header.mode == MAD_MODE_SINGLE_CHANNEL) ? 1 : 2;
sh->samplerate=this->frame.header.samplerate;
– sh->i_bps=this->frame.header.bitrate/8;
+ /* only recaculate the i_bps if the Mplayer don’t calc it
+ when VBR the i_bsp is already calculated by Mplayer */
+ if(sh->i_bps < 0)
+ sh->i_bps=this->frame.header.bitrate/8;
sh->samplesize=2;
return 1;
diff -ruNa MPlayer-1.0rc2/libmpcodecs/ad_mp3lib.c MPlayer-1.0rc2_VBR/libmpcodecs/ad_mp3lib.c
— MPlayer-1.0rc2/libmpcodecs/ad_mp3lib.c 2009-09-02 18:00:08.000000000 +0800
+++ MPlayer-1.0rc2_VBR/libmpcodecs/ad_mp3lib.c 2009-09-02 17:59:40.000000000 +0800
@@ -47,10 +47,10 @@
MP3_samplerate=MP3_channels=0;
sh->a_buffer_len=MP3_DecodeFrame(sh->a_buffer,-1);
if(!sh->a_buffer_len) return 0; // unsupported layer/format
– sh->channels=2; // hack
+ sh->channels=sh->wf->nChannels;
sh->samplesize=2;
sh->samplerate=MP3_samplerate;
– sh->i_bps=MP3_bitrate*(1000/8);
+ sh->i_bps=sh->wf->nAvgBytesPerSec;
MP3_PrintHeader();
return 1;
}
diff -ruNa MPlayer-1.0rc2/libmpdemux/demux_audio.c MPlayer-1.0rc2_VBR/libmpdemux/demux_audio.c
— MPlayer-1.0rc2/libmpdemux/demux_audio.c 2009-09-02 18:00:04.000000000 +0800
+++ MPlayer-1.0rc2_VBR/libmpdemux/demux_audio.c 2009-09-10 11:58:44.000000000 +0800
@@ -41,6 +41,7 @@
int mpa_spf;
int mpa_layer;
int mpa_br;
+ int mpa_ssize;
int cons_hdrs; // if this reaches MIN_MP3_HDRS we accept as MP3 file
struct mp3_hdr *next;
} mp3_hdr_t;
@@ -86,7 +87,7 @@
*/
static mp3_hdr_t *add_mp3_hdr(mp3_hdr_t **list, off_t st_pos,
int mp3_chans, int mp3_freq, int mpa_spf,
– int mpa_layer, int mpa_br, int mp3_flen) {
+ int mpa_layer, int mpa_br, int mp3_flen, int mpa_ssize) {
mp3_hdr_t *tmp;
int in_list = 0;
while (*list && (*list)->next_frame_pos <= st_pos) {
@@ -123,6 +124,7 @@
tmp->mp3_freq = mp3_freq;
tmp->mpa_spf = mpa_spf;
tmp->mpa_layer = mpa_layer;
+ tmp->mpa_ssize = mpa_ssize;
tmp->mpa_br = mpa_br;
tmp->cons_hdrs = 1;
tmp->next = *list;
@@ -277,6 +279,7 @@
sh_audio_t* sh_audio;
uint8_t hdr[HDR_SIZE];
int frmt = 0, n = 0, step;
+ int mpeghdr_pos;
off_t st_pos = 0, next_frame_pos = 0;
// mp3_hdrs list is sorted first by next_frame_pos and then by frame_pos
mp3_hdr_t *mp3_hdrs = NULL, *mp3_found = NULL;
@@ -284,16 +287,15 @@
s = demuxer->stream;
+ mpeghdr_pos = stream_tell(s);
stream_read(s, hdr, HDR_SIZE);
while(n < 30000 && !s->eof) {
– int mp3_freq, mp3_chans, mp3_flen, mpa_layer, mpa_spf, mpa_br;
+ int mp3_freq, mp3_chans, mp3_flen, mpa_layer, mpa_spf, mpa_br, mpa_ssize;
st_pos = stream_tell(s) – HDR_SIZE;
step = 1;
if( hdr[0] == ‘R’ && hdr[1] == ‘I’ && hdr[2] == ‘F’ && hdr[3] == ‘F’ ) {
stream_skip(s,4);
– if(s->eof)
– break;
stream_read(s,hdr,4);
if(s->eof)
break;
@@ -307,16 +309,19 @@
int len;
stream_skip(s,2);
stream_read(s,hdr,4);
+ if(s->eof)
+ break;
len = (hdr[0]<<21) | (hdr[1]<<14) | (hdr[2]<<7) | hdr[3];
stream_skip(s,len);
+ mpeghdr_pos = stream_tell(s);
step = 4;
} else if( hdr[0] == ‘f’ && hdr[1] == ‘m’ && hdr[2] == ‘t’ && hdr[3] == ‘ ‘ ) {
frmt = WAV;
break;
} else if((mp3_flen = mp_get_mp3_header(hdr, &mp3_chans, &mp3_freq,
– &mpa_spf, &mpa_layer, &mpa_br)) > 0) {
+ &mpa_spf, &mpa_layer, &mpa_br, &mpa_ssize)) > 0) {
mp3_found = add_mp3_hdr(&mp3_hdrs, st_pos, mp3_chans, mp3_freq,
– mpa_spf, mpa_layer, mpa_br, mp3_flen);
+ mpa_spf, mpa_layer, mpa_br, mp3_flen, mpa_ssize);
if (mp3_found) {
frmt = MP3;
break;
@@ -340,7 +345,40 @@
sh_audio = new_sh_audio(demuxer,0);
switch(frmt) {
– case MP3:
+ case MP3: {
+ // Search for VBR header and compute correct bitrate if necessary
+ uint8_t vbrhdr[4];
+ uint8_t framesnb_hdr[4];
+ int frames_nb = -1;
+ uint8_t frames_field;
+ stream_seek(s,mpeghdr_pos+4+mp3_found->mpa_ssize);
+ stream_read(s,vbrhdr,4);
+ if(!s->eof)
+ if( (vbrhdr[0] == ‘X’ && vbrhdr[1] == ‘i’ && vbrhdr[2] == ‘n’ && vbrhdr[3] == ‘g’)
+ || (vbrhdr[0] == ‘I’ && vbrhdr[1] == ‘n’ && vbrhdr[2] == ‘f’ && vbrhdr[3] == ‘o’) ) { // We found a XING header
+ stream_seek(s,mpeghdr_pos+11+mp3_found->mpa_ssize);
+ stream_read(s,&frames_field,1);
+ if( frames_field & 1 ) {
+ stream_seek(s,mpeghdr_pos+12+mp3_found->mpa_ssize); // We jump to Frames number
+ stream_read(s,framesnb_hdr,4);
+ if(s->eof)
+ break;
+ frames_nb = (framesnb_hdr[0]<<24) | (framesnb_hdr[1]<<16) | (framesnb_hdr[2]<<8) | (framesnb_hdr[3]);
+ }
+ }
+ else {
+ stream_seek(s,mpeghdr_pos+36);
+ stream_read(s,vbrhdr,4);
+
+ if( vbrhdr[0] == ‘V’ && vbrhdr[1] == ‘B’ && vbrhdr[2] == ‘R’ && vbrhdr[3] == ‘I’ ) { // We found a VBRI header
+ stream_seek(s,mpeghdr_pos+50); // We jump to Frames number
+ stream_read(s,framesnb_hdr,4);
+ if(s->eof)
+ break;
+ frames_nb = (framesnb_hdr[0]<<24) | (framesnb_hdr[1]<<16) | (framesnb_hdr[2]<<8) | (framesnb_hdr[3]);
+ }
+ }
+
sh_audio->format = (mp3_found->mpa_layer < 3 ? 0x50 : 0x55);
demuxer->movi_start = mp3_found->frame_pos;
next_frame_pos = mp3_found->next_frame_pos;
@@ -351,7 +389,12 @@
sh_audio->wf->wFormatTag = sh_audio->format;
sh_audio->wf->nChannels = mp3_found->mp3_chans;
sh_audio->wf->nSamplesPerSec = mp3_found->mp3_freq;
– sh_audio->wf->nAvgBytesPerSec = mp3_found->mpa_br * (1000 / 8);
+ if (frames_nb > 0)
+ {
+ sh_audio->wf->nAvgBytesPerSec = ((demuxer->movi_end-demuxer->movi_start)*mp3_found->mp3_freq)/(frames_nb*mp3_found->mpa_spf);
+ }
+ else
+ sh_audio->wf->nAvgBytesPerSec = mp3_found->mpa_br * (1000 / 8);
sh_audio->wf->nBlockAlign = mp3_found->mpa_spf;
sh_audio->wf->wBitsPerSample = 16;
sh_audio->wf->cbSize = 0;
@@ -393,7 +436,7 @@
demux_info_add(demuxer,"Genre",genres[g]);
}
}
– break;
+ } break;
case WAV: {
unsigned int chunk_type;
unsigned int chunk_size;
@@ -691,13 +734,13 @@
static int demux_audio_control(demuxer_t *demuxer,int cmd, void *arg){
sh_audio_t *sh_audio=demuxer->audio->sh;
– int audio_length = demuxer->movi_end / sh_audio->i_bps;
+ double audio_length = (double)(demuxer->movi_end-demuxer->movi_start) / (double)sh_audio->i_bps;
da_priv_t* priv = demuxer->priv;
–
+
switch(cmd) {
case DEMUXER_CTRL_GET_TIME_LENGTH:
if (audio_length<=0) return DEMUXER_CTRL_DONTKNOW;
– *((double *)arg)=(double)audio_length;
+ *((double *)arg)=audio_length;
return DEMUXER_CTRL_GUESS;
case DEMUXER_CTRL_GET_PERCENT_POS:
diff -ruNa MPlayer-1.0rc2/libmpdemux/mp3_hdr.c MPlayer-1.0rc2_VBR/libmpdemux/mp3_hdr.c
— MPlayer-1.0rc2/libmpdemux/mp3_hdr.c 2009-09-02 18:00:04.000000000 +0800
+++ MPlayer-1.0rc2_VBR/libmpdemux/mp3_hdr.c 2009-09-10 11:56:24.000000000 +0800
@@ -34,7 +34,7 @@
/*
* return frame size or -1 (bad frame)
*/
-int mp_get_mp3_header(unsigned char* hbuf,int* chans, int* srate, int* spf, int* mpa_layer, int* br){
+int mp_get_mp3_header(unsigned char* hbuf,int* chans, int* srate, int* spf, int* mpa_layer, int* br, int* side_info_size){
int stereo,ssize,lsf,framesize,padding,bitrate_index,sampling_frequency, divisor;
int bitrate;
int layer, mult[3] = { 12000, 144000, 144000 };
@@ -99,6 +99,7 @@
else
ssize = (stereo == 1) ? 17 : 32;
if(!((newhead>>16)&0x1)) ssize += 2; // CRC
+ if(side_info_size) *side_info_size = ssize;
bitrate = tabsel_123[lsf][layer-1][bitrate_index];
framesize = bitrate * mult[layer-1];
diff -ruNa MPlayer-1.0rc2/libmpdemux/mp3_hdr.h MPlayer-1.0rc2_VBR/libmpdemux/mp3_hdr.h
— MPlayer-1.0rc2/libmpdemux/mp3_hdr.h 2009-09-02 18:00:04.000000000 +0800
+++ MPlayer-1.0rc2_VBR/libmpdemux/mp3_hdr.h 2009-09-02 17:59:38.000000000 +0800
@@ -1,7 +1,7 @@
-int mp_get_mp3_header(unsigned char* hbuf,int* chans, int* freq, int* spf, int* mpa_layer, int* br);
+int mp_get_mp3_header(unsigned char* hbuf,int* chans, int* freq, int* spf, int* mpa_layer, int* br, int* side_info_size);
-#define mp_decode_mp3_header(hbuf) mp_get_mp3_header(hbuf,NULL,NULL,NULL,NULL,NULL)
+#define mp_decode_mp3_header(hbuf) mp_get_mp3_header(hbuf,NULL,NULL,NULL,NULL,NULL,NULL)
static inline int mp_check_mp3_header(unsigned int head){
if( (head & 0x0000e0ff) != 0x0000e0ff ||
diff -ruNa MPlayer-1.0rc2/libmpdemux/muxer_mpeg.c MPlayer-1.0rc2_VBR/libmpdemux/muxer_mpeg.c
— MPlayer-1.0rc2/libmpdemux/muxer_mpeg.c 2009-09-02 18:00:03.000000000 +0800
+++ MPlayer-1.0rc2_VBR/libmpdemux/muxer_mpeg.c 2009-09-02 17:59:37.000000000 +0800
@@ -2028,7 +2028,7 @@
{
if(s->b_buffer[i] == 0xFF && ((s->b_buffer[i+1] & 0xE0) == 0xE0))
{
– len = mp_get_mp3_header(&(s->b_buffer[i]), &chans, &srate, &spf, &layer, NULL);
+ len = mp_get_mp3_header(&(s->b_buffer[i]), &chans, &srate, &spf, &layer, NULL, NULL);
if(len > 0 && (srate == s->wf->nSamplesPerSec) && (i + len <= s->b_buffer_len))
{
score[layer]++;
@@ -2081,7 +2081,7 @@
if(s->b_buffer[i] == 0xFF && ((s->b_buffer[i+1] & 0xE0) == 0xE0))
{
– len = mp_get_mp3_header(&(s->b_buffer[i]), &chans, &srate, &spf, &layer, NULL);
+ len = mp_get_mp3_header(&(s->b_buffer[i]), &chans, &srate, &spf, &layer, NULL, NULL);
if(len > 0 && (srate == s->wf->nSamplesPerSec) && (i + len <= s->b_buffer_len)
&& layer == spriv->mpa_layer)
{
转载请注明:在路上 » MPlayer-1.0rc1 和 MPlayer-1.0rc2 的VBR patch【已修复mad播放VBR MP3播放总时长显示问题】