Mercurial > mplayer.hg
view libmpdemux/mp3_hdr.c @ 19619:a83e5b8d2e63
Patch from Karolina Lindqvist <karolina.lindqvist@kramnet.se>
"There is a bug in the zoran -vo zr driver, that makes the output garbled
always. It also probably affects the zrmjpeg filter. This patch takes care of
the problem."
Patch tested and OK. And 10l to me, because this bug probably has existed for a
looong time.
author | rik |
---|---|
date | Fri, 01 Sep 2006 18:49:40 +0000 |
parents | 6ff3379a0862 |
children | d643e4643313 |
line wrap: on
line source
#include <stdio.h> #include "config.h" #include "mp_msg.h" //----------------------- mp3 audio frame header parser ----------------------- static int tabsel_123[2][3][16] = { { {0,32,64,96,128,160,192,224,256,288,320,352,384,416,448,0}, {0,32,48,56, 64, 80, 96,112,128,160,192,224,256,320,384,0}, {0,32,40,48, 56, 64, 80, 96,112,128,160,192,224,256,320,0} }, { {0,32,48,56,64,80,96,112,128,144,160,176,192,224,256,0}, {0,8,16,24,32,40,48,56,64,80,96,112,128,144,160,0}, {0,8,16,24,32,40,48,56,64,80,96,112,128,144,160,0} } }; static long freqs[9] = { 44100, 48000, 32000, // MPEG 1.0 22050, 24000, 16000, // MPEG 2.0 11025, 12000, 8000}; // MPEG 2.5 int mp_mp3_get_lsf(unsigned char* hbuf){ unsigned long newhead = hbuf[0] << 24 | hbuf[1] << 16 | hbuf[2] << 8 | hbuf[3]; if( newhead & ((long)1<<20) ) { return (newhead & ((long)1<<19)) ? 0x0 : 0x1; } return 1; } /* * 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 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 | hbuf[1] << 16 | hbuf[2] << 8 | hbuf[3]; // printf("head=0x%08X\n",newhead); #if 1 // head_check: if( (newhead & 0xffe00000) != 0xffe00000 ){ mp_msg(MSGT_DEMUXER,MSGL_DBG2,"head_check failed\n"); return -1; } #endif layer = 4-((newhead>>17)&3); if(layer==4){ mp_msg(MSGT_DEMUXER,MSGL_DBG2,"not layer-1/2/3\n"); return -1; } sampling_frequency = ((newhead>>10)&0x3); // valid: 0..2 if(sampling_frequency==3){ mp_msg(MSGT_DEMUXER,MSGL_DBG2,"invalid sampling_frequency\n"); return -1; } if( newhead & ((long)1<<20) ) { // MPEG 1.0 (lsf==0) or MPEG 2.0 (lsf==1) lsf = (newhead & ((long)1<<19)) ? 0x0 : 0x1; sampling_frequency += (lsf*3); } else { // MPEG 2.5 lsf = 1; sampling_frequency += 6; } // crc = ((newhead>>16)&0x1)^0x1; bitrate_index = ((newhead>>12)&0xf); // valid: 1..14 padding = ((newhead>>9)&0x1); // fr->extension = ((newhead>>8)&0x1); // fr->mode = ((newhead>>6)&0x3); // fr->mode_ext = ((newhead>>4)&0x3); // fr->copyright = ((newhead>>3)&0x1); // fr->original = ((newhead>>2)&0x1); // fr->emphasis = newhead & 0x3; stereo = ( (((newhead>>6)&0x3)) == 3) ? 1 : 2; // !checked later through tabsel_123[]! // if(!bitrate_index || bitrate_index==15){ // mp_msg(MSGT_DEMUXER,MSGL_DBG2,"Free format not supported.\n"); // return -1; // } if(lsf) ssize = (stereo == 1) ? 9 : 17; else ssize = (stereo == 1) ? 17 : 32; if(!((newhead>>16)&0x1)) ssize += 2; // CRC 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]); if(!framesize){ mp_msg(MSGT_DEMUXER,MSGL_DBG2,"invalid framesize/bitrate_index\n"); return -1; } divisor = (layer == 3 ? (freqs[sampling_frequency] << lsf) : freqs[sampling_frequency]); framesize /= divisor; if(layer==1) framesize = (framesize+padding)*4; else framesize += padding; // if(framesize<=0 || framesize>MAXFRAMESIZE) return FALSE; if(srate) { *srate = freqs[sampling_frequency]; if(spf) { if(layer == 1) *spf = 384; else if(layer == 2) *spf = 1152; else if(*srate < 32000) *spf = 576; else *spf = 1152; } } if(mpa_layer) *mpa_layer = layer; if(chans) *chans = stereo; if(br) *br = bitrate; return framesize; }