diff options
-rw-r--r-- | src/demuxers/demux_mpgaudio.c | 193 |
1 files changed, 99 insertions, 94 deletions
diff --git a/src/demuxers/demux_mpgaudio.c b/src/demuxers/demux_mpgaudio.c index 884c66dba..29a0de95b 100644 --- a/src/demuxers/demux_mpgaudio.c +++ b/src/demuxers/demux_mpgaudio.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: demux_mpgaudio.c,v 1.153 2007/03/26 21:52:12 dgp85 Exp $ + * $Id: demux_mpgaudio.c,v 1.154 2007/03/29 16:01:30 dgp85 Exp $ * * demultiplexer for mpeg audio (i.e. mp3) streams * @@ -79,28 +79,16 @@ /* mp3 frame struct */ typedef struct { /* header */ - uint16_t frame_sync; - uint8_t layer; - uint32_t mpeg25_bit:1; - uint32_t lsf_bit:1; - uint32_t bitrate_idx:4; - uint32_t freq_idx:3; - uint32_t protection_bit:1; - uint32_t padding_bit:1; - uint32_t private_bit:1; - uint32_t channel_mode:3; - uint32_t mode_extension:3; - uint32_t copyright:1; - uint32_t original:1; - uint32_t emphasis:3; - - uint32_t version_idx:2; /* 0: mpeg1, 1: mpeg2, 2: mpeg2.5 */ - int bitrate; /* in bit per second */ - int freq; /* in Hz */ - int samples; /* samples per frame */ - int padding; /* padding bytes (0, 1 or 4)*/ - int size; /* in bytes */ - double duration; /* in xine pts */ + double duration; + uint32_t size; /* in bytes */ + uint16_t freq; /* in Hz */ + uint16_t bitrate; /* in bit per second */ + + uint8_t layer; + + uint8_t version_idx:2; /* 0: mpeg1, 1: mpeg2, 2: mpeg2.5 */ + uint8_t lsf_bit:1; + uint8_t channel_mode:3; } mpg_audio_frame_t; /* Xing Vbr Header struct */ @@ -163,61 +151,72 @@ typedef struct { } demux_mpgaudio_class_t; -/* bitrate table[mpeg version][layer][bitrate index] - * values stored in kbps - */ -static const int mp3_bitrates[3][3][16] = { - { {0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448,}, - {0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384,}, - {0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320,} }, - { {0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256,}, - {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160,}, - {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160,} }, - { {0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256,}, - {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160,}, - {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160,} } -}; - -/* frequency table[mpeg version][frequence index] (in KHz) */ -static const int mp3_freqs[3][3] = { - { 44100, 48000, 32000 }, - { 22050, 24000, 16000 }, - { 11025, 12000, 8000 } -}; - -/* samples per frame table[mpeg version][layer] */ -static const int mp3_samples[3][3] = { - { 384, 1152, 1152 }, - { 384, 1152, 576 }, - { 384, 1152, 576 } -}; - -/* samples per frame table[layer][padding bit] */ -static const int mp3_paddings[3][2] = { - { 0, 4 }, - { 0, 1 }, - { 0, 1 } -}; - /* * Parse a mp3 frame * return 1 on success */ -static int parse_frame_header(mpg_audio_frame_t *frame, uint8_t *buf) { - uint32_t head; +static int parse_frame_header(mpg_audio_frame_t *const frame, const uint8_t *const buf) { + /* bitrate table[mpeg version][layer][bitrate index] + * values stored in kbps + */ + static const uint16_t mp3_bitrates[3][3][16] = { + { {0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448,}, + {0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384,}, + {0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320,} }, + { {0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256,}, + {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160,}, + {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160,} }, + { {0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256,}, + {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160,}, + {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160,} } + }; + + /* frequency table[mpeg version][frequence index] (in KHz) */ + static const uint16_t mp3_freqs[3][3] = { + { 44100, 48000, 32000 }, + { 22050, 24000, 16000 }, + { 11025, 12000, 8000 } + }; + + /* samples per frame table[mpeg version][layer] */ + static const uint16_t mp3_samples[3][3] = { + { 384, 1152, 1152 }, + { 384, 1152, 576 }, + { 384, 1152, 576 } + }; + + struct { + uint16_t mpeg25_bit:1; + uint16_t bitrate_idx:4; + uint16_t freq_idx:3; + uint16_t padding_bit:1; + uint16_t channel_mode:3; + +#if 0 /* Unused */ + uint16_t protection_bit:1; + uint16_t private_bit:1; + uint16_t mode_extension:3; + uint16_t copyright:1; + uint16_t original:1; +#endif - head = BE_32(buf); +#if defined(OPT_STRICT) + uint16_t emphasis:3; +#endif + } frame_header; + + const uint32_t head = BE_32(buf); + const uint16_t frame_sync = head >> 21; lprintf("header: %08X\n", head); - frame->frame_sync = head >> 21; - if (frame->frame_sync != 0x7ff) { + if (frame_sync != 0x7ff) { lprintf("invalid frame sync\n"); return 0; } - frame->mpeg25_bit = (head >> 20) & 0x1; + frame_header.mpeg25_bit = (head >> 20) & 0x1; frame->lsf_bit = (head >> 19) & 0x1; - if (!frame->mpeg25_bit) { + if (!frame_header.mpeg25_bit) { if (frame->lsf_bit) { lprintf("reserved mpeg25 lsf combination\n"); return 0; @@ -236,54 +235,60 @@ static int parse_frame_header(mpg_audio_frame_t *frame, uint8_t *buf) { return 0; } - frame->protection_bit = (head >> 16) & 0x1; - frame->bitrate_idx = (head >> 12) & 0xf; - if ((frame->bitrate_idx == 0) || (frame->bitrate_idx == 15)) { + frame_header.bitrate_idx = (head >> 12) & 0xf; + if ((frame_header.bitrate_idx == 0) || (frame_header.bitrate_idx == 15)) { lprintf("invalid bitrate index\n"); return 0; } - frame->freq_idx = (head >> 10) & 0x3; - if (frame->freq_idx == 3) { + frame_header.freq_idx = (head >> 10) & 0x3; + if (frame_header.freq_idx == 3) { lprintf("invalid frequence index\n"); return 0; } - frame->padding_bit = (head >> 9) & 0x1; - frame->private_bit = (head >> 8) & 0x1; - frame->channel_mode = (head >> 6) & 0x3; - frame->mode_extension = (head >> 4) & 0x3; - frame->copyright = (head >> 3) & 0x1; - frame->original = (head >> 2) & 0x1; - frame->emphasis = head & 0x3; + frame_header.padding_bit = (head >> 9) & 0x1; + frame_header.channel_mode = (head >> 6) & 0x3; + +#if 0 /* Unused */ + frame_header.protection_bit = (head >> 16) & 0x1; + frame_header.private_bit = (head >> 8) & 0x1; + frame_header.mode_extension = (head >> 4) & 0x3; + frame_header.copyright = (head >> 3) & 0x1; + frame_header.original = (head >> 2) & 0x1; +#endif #if defined(OPT_STRICT) + frame_header.emphasis = head & 0x3; + /* * ISO/IEC 11172-3 says this is a reserved emphasis value, but * streams exist which use it anyway. Since the value is not important * to the decoder proper, we allow it unless OPT_STRICT is defined. */ - if (frame->emphasis == 2) { + if (frame_header.emphasis == 2) { lprintf("reserved emphasis\n"); return 0; } #endif - frame->bitrate = mp3_bitrates[frame->version_idx][frame->layer - 1][frame->bitrate_idx] * 1000; - frame->freq = mp3_freqs[frame->version_idx][frame->freq_idx]; - frame->samples = mp3_samples[frame->version_idx][frame->layer - 1]; - frame->padding = mp3_paddings[frame->layer - 1][frame->padding_bit]; + { + const uint16_t samples = mp3_samples[frame->version_idx][frame->layer - 1]; + frame->bitrate = mp3_bitrates[frame->version_idx][frame->layer - 1][frame_header.bitrate_idx] * 1000; + frame->freq = mp3_freqs[frame->version_idx][frame_header.freq_idx]; - frame->size = frame->samples * (frame->bitrate / 8); - frame->size /= frame->freq; - frame->size += frame->padding; + frame->size = samples * (frame->bitrate / 8); + frame->size /= frame->freq; + /* Padding: only if padding_bit is set; 4 bytes for Layer 1 and 1 byte for others */ + frame->size += ( frame_header.padding_bit ? ( frame->layer == 1 ? 4 : 1 ) : 0 ); - frame->duration = 1000.0f * (double)frame->samples / (double)frame->freq; + frame->duration = 1000.0f * (double)samples / (double)frame->freq; + } lprintf("mpeg %d, layer %d\n", frame->version_idx + 1, frame->layer); lprintf("bitrate: %d bps, samplerate: %d Hz\n", frame->bitrate, frame->freq); lprintf("length: %d bytes, %f ms\n", frame->size, frame->duration); - lprintf("padding: %d bytes\n", frame->padding); + lprintf("padding: %d bytes\n", ( frame_header.padding_bit ? ( frame->layer == 1 ? 4 : 1 ) : 0 )); return 1; } @@ -294,7 +299,9 @@ static int parse_frame_header(mpg_audio_frame_t *frame, uint8_t *buf) { static xing_header_t* parse_xing_header(mpg_audio_frame_t *frame, uint8_t *buf, int bufsize) { +#ifdef LOG int i; +#endif uint8_t *ptr = buf; xing_header_t *xing; @@ -338,14 +345,12 @@ static xing_header_t* parse_xing_header(mpg_audio_frame_t *frame, lprintf("toc found\n"); if (ptr >= (buf + bufsize - XING_TOC_LENGTH)) return 0; - for (i = 0; i < XING_TOC_LENGTH; i++) { - xing->toc[i] = *(ptr + i); + memcpy(xing->toc, ptr, XING_TOC_LENGTH); #ifdef LOG - printf("%d ", xing->toc[i]); -#endif + for (i = 0; i < XING_TOC_LENGTH; i++) { + lprintf("%d ", xing->toc[i]); } -#ifdef LOG - printf("\n"); + lprintf("\n"); #endif ptr += XING_TOC_LENGTH; } |