[MPlayer-dev-eng] [PATCH] set i_bps in demux_audio, other fixes
Reimar Döffinger
Reimar.Doeffinger at stud.uni-karlsruhe.de
Fri Jul 29 14:18:50 CEST 2005
Hi,
the attached patch sets sh_audio->i_bps for MP3 and WAV files, avoiding
a division by zero (since the decoder can only set it _after_ the first
call to demux_audio_fill_buffer)
It also fixes that bug that the format field for MP3 is set according to
the last MPEG-Audio like header, instead of the one we decided is the
right one (mp3_found).
Please comment (and esp. test).
Greetings,
Reimar Döffinger
-------------- next part --------------
Index: libmpdemux/demux_audio.c
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdemux/demux_audio.c,v
retrieving revision 1.35
diff -u -r1.35 demux_audio.c
--- libmpdemux/demux_audio.c 18 Apr 2005 20:51:34 -0000 1.35
+++ libmpdemux/demux_audio.c 29 Jul 2005 12:11:07 -0000
@@ -36,6 +36,9 @@
off_t next_frame_pos; // here we expect the next header with same parameters
int mp3_chans;
int mp3_freq;
+ int mpa_spf;
+ int mpa_layer;
+ int mpa_br;
int cons_hdrs; // if this reaches MIN_MP3_HDRS we accept as MP3 file
struct mp3_hdr *next;
} mp3_hdr_t;
@@ -69,26 +72,35 @@
* and when those are equal by frame_pos.
* \param list pointer to the head-of-list pointer
* \param st_pos stream position where the described header starts
- * \param mp3_chans number of channels as specified by the header
- * \param mp3_freq sampling frequency as specified by the header
+ * \param mp3_chans number of channels as specified by the header (*)
+ * \param mp3_freq sampling frequency as specified by the header (*)
+ * \param mpa_spf frame size as specified by the header
+ * \param mpa_layer layer type ("version") as specified by the header (*)
+ * \param mpa_br bitrate as specified by the header
* \param mp3_flen length of the frame as specified by the header
* \return If non-null the current file is accepted as MP3 and the
* mp3_hdr struct describing the valid chain is returned. Must be
* freed independent of the list.
+ *
+ * parameters marked by (*) must be the same for all headers in the same chain
*/
static mp3_hdr_t *add_mp3_hdr(mp3_hdr_t **list, off_t st_pos,
- int mp3_chans, int mp3_freq, int mp3_flen) {
+ int mp3_chans, int mp3_freq, int mpa_spf,
+ int mpa_layer, int mpa_br, int mp3_flen) {
mp3_hdr_t *tmp;
int in_list = 0;
while (*list && (*list)->next_frame_pos <= st_pos) {
if (((*list)->next_frame_pos < st_pos) || ((*list)->mp3_chans != mp3_chans)
- || ((*list)->mp3_freq != mp3_freq)) { // wasn't valid!
+ || ((*list)->mp3_freq != mp3_freq) || ((*list)->mpa_layer != mpa_layer) ) {
+ // wasn't valid!
tmp = (*list)->next;
free(*list);
*list = tmp;
} else {
(*list)->cons_hdrs++;
(*list)->next_frame_pos = st_pos + mp3_flen;
+ (*list)->mpa_spf = mpa_spf;
+ (*list)->mpa_br = mpa_br;
if ((*list)->cons_hdrs >= MIN_MP3_HDRS) {
// copy the valid entry, so that the list can be easily freed
tmp = malloc(sizeof(mp3_hdr_t));
@@ -109,6 +121,9 @@
tmp->next_frame_pos = st_pos + mp3_flen;
tmp->mp3_chans = mp3_chans;
tmp->mp3_freq = mp3_freq;
+ tmp->mpa_spf = mpa_spf;
+ tmp->mpa_layer = mpa_layer;
+ tmp->mpa_br = mpa_br;
tmp->cons_hdrs = 1;
tmp->next = *list;
*list = tmp;
@@ -120,7 +135,7 @@
stream_t *s;
sh_audio_t* sh_audio;
uint8_t hdr[HDR_SIZE];
- int frmt = 0, n = 0, step, mp3_freq, mp3_chans, mp3_flen, mpa_layer = 3, mpa_spf = 1152;
+ int frmt = 0, n = 0, step;
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;
@@ -134,6 +149,7 @@
stream_read(s, hdr, HDR_SIZE);
while(n < 30000 && !s->eof) {
+ int mp3_freq, mp3_chans, mp3_flen, mpa_layer, mpa_spf, mpa_br;
st_pos = stream_tell(s) - HDR_SIZE;
step = 1;
@@ -160,8 +176,10 @@
} 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)) > 0) {
- mp3_found = add_mp3_hdr(&mp3_hdrs, st_pos, mp3_chans, mp3_freq, mp3_flen);
+ } else if((mp3_flen = mp_get_mp3_header(hdr, &mp3_chans, &mp3_freq,
+ &mpa_spf, &mpa_layer, &mpa_br)) > 0) {
+ mp3_found = add_mp3_hdr(&mp3_hdrs, st_pos, mp3_chans, mp3_freq,
+ mpa_spf, mpa_layer, mpa_br, mp3_flen);
if (mp3_found) {
frmt = MP3;
break;
@@ -187,19 +205,21 @@
switch(frmt) {
case MP3:
- sh_audio->format = (mpa_layer < 3 ? 0x50 : 0x55);
+ 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;
sh_audio->audio.dwSampleSize= 0;
- sh_audio->audio.dwScale = mpa_spf;
+ sh_audio->audio.dwScale = mp3_found->mpa_spf;
sh_audio->audio.dwRate = mp3_found->mp3_freq;
sh_audio->wf = malloc(sizeof(WAVEFORMATEX));
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->nBlockAlign = mpa_spf;
+ 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;
+ sh_audio->i_bps = sh_audio->wf->nAvgBytesPerSec;
free(mp3_found);
mp3_found = NULL;
if(s->end_pos) {
@@ -257,6 +277,7 @@
w->nBlockAlign = stream_read_word_le(s);
w->wBitsPerSample = sh_audio->samplesize = stream_read_word_le(s);
w->cbSize = 0;
+ sh_audio->i_bps = sh_audio->wf->nAvgBytesPerSec;
l -= 16;
if (l > 0) {
w->cbSize = stream_read_word_le(s);
Index: libmpdemux/mp3_hdr.c
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdemux/mp3_hdr.c,v
retrieving revision 1.11
diff -u -r1.11 mp3_hdr.c
--- libmpdemux/mp3_hdr.c 24 Apr 2005 08:41:45 -0000 1.11
+++ libmpdemux/mp3_hdr.c 29 Jul 2005 12:11:19 -0000
@@ -34,8 +34,9 @@
/*
* 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 mp_get_mp3_header(unsigned char* hbuf,int* chans, int* srate, int* spf, int* mpa_layer, int* br){
int stereo,ssize,lsf,framesize,padding,bitrate_index,sampling_frequency, divisor;
+ int bitrate;
int layer, mult[3] = { 12000, 144000, 144000 };
unsigned long newhead =
hbuf[0] << 24 |
@@ -99,7 +100,8 @@
ssize = (stereo == 1) ? 17 : 32;
if(!((newhead>>16)&0x1)) ssize += 2; // CRC
- framesize = tabsel_123[lsf][layer-1][bitrate_index] * mult[layer-1];
+ bitrate = tabsel_123[lsf][layer-1][bitrate_index];
+ framesize = bitrate * mult[layer-1];
mp_msg(MSGT_DEMUXER,MSGL_DBG2,"FRAMESIZE: %d, layer: %d, bitrate: %d, mult: %d\n",
framesize, layer, tabsel_123[lsf][layer-1][bitrate_index], mult[layer-1]);
@@ -131,6 +133,7 @@
}
if(mpa_layer) *mpa_layer = layer;
if(chans) *chans = stereo;
+ if(br) *br = bitrate;
return framesize;
}
Index: libmpdemux/mp3_hdr.h
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdemux/mp3_hdr.h,v
retrieving revision 1.3
diff -u -r1.3 mp3_hdr.h
--- libmpdemux/mp3_hdr.h 17 Apr 2005 09:42:51 -0000 1.3
+++ libmpdemux/mp3_hdr.h 29 Jul 2005 12:11:19 -0000
@@ -1,7 +1,7 @@
-int mp_get_mp3_header(unsigned char* hbuf,int* chans, int* freq, int* spf, int* mpa_layer);
+int mp_get_mp3_header(unsigned char* hbuf,int* chans, int* freq, int* spf, int* mpa_layer, int* br);
-#define mp_decode_mp3_header(hbuf) mp_get_mp3_header(hbuf,NULL,NULL,NULL,NULL)
+#define mp_decode_mp3_header(hbuf) mp_get_mp3_header(hbuf,NULL,NULL,NULL,NULL,NULL)
static inline int mp_check_mp3_header(unsigned int head){
if( (head & 0x0000e0ff) != 0x0000e0ff ||
Index: libmpdemux/muxer_mpeg.c
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdemux/muxer_mpeg.c,v
retrieving revision 1.18
diff -u -r1.18 muxer_mpeg.c
--- libmpdemux/muxer_mpeg.c 10 Jul 2005 08:36:39 -0000 1.18
+++ libmpdemux/muxer_mpeg.c 29 Jul 2005 12:11:32 -0000
@@ -2312,7 +2312,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);
+ len = mp_get_mp3_header(&(s->b_buffer[i]), &chans, &srate, &spf, &layer, NULL);
if(len > 0 && (srate == s->wf->nSamplesPerSec) && (i + len <= s->b_buffer_len))
{
frames++;
More information about the MPlayer-dev-eng
mailing list