# HG changeset patch # User reimar # Date 1122921410 0 # Node ID b5c2254d13f8e84d77448897ea02a51e596f7e18 # Parent 58f47c971d53bcc6d09feca948f98081f6815b18 set i_bps in demux_audio for WAV and MP3 to avoid division by zero before decoder sets it. diff -r 58f47c971d53 -r b5c2254d13f8 libmpdemux/demux_audio.c --- a/libmpdemux/demux_audio.c Mon Aug 01 13:17:28 2005 +0000 +++ b/libmpdemux/demux_audio.c Mon Aug 01 18:36:50 2005 +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); diff -r 58f47c971d53 -r b5c2254d13f8 libmpdemux/mp3_hdr.c --- a/libmpdemux/mp3_hdr.c Mon Aug 01 13:17:28 2005 +0000 +++ b/libmpdemux/mp3_hdr.c Mon Aug 01 18:36:50 2005 +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; } diff -r 58f47c971d53 -r b5c2254d13f8 libmpdemux/mp3_hdr.h --- a/libmpdemux/mp3_hdr.h Mon Aug 01 13:17:28 2005 +0000 +++ b/libmpdemux/mp3_hdr.h Mon Aug 01 18:36:50 2005 +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 || diff -r 58f47c971d53 -r b5c2254d13f8 libmpdemux/muxer_mpeg.c --- a/libmpdemux/muxer_mpeg.c Mon Aug 01 13:17:28 2005 +0000 +++ b/libmpdemux/muxer_mpeg.c Mon Aug 01 18:36:50 2005 +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++;