1/*
2 * MPEG Audio parser
3 * Copyright (c) 2003 Fabrice Bellard
4 * Copyright (c) 2003 Michael Niedermayer
5 *
6 * This file is part of FFmpeg.
7 *
8 * FFmpeg is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * FFmpeg is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with FFmpeg; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23#include "parser.h"
24#include "mpegaudio.h"
25#include "mpegaudiodecheader.h"
26
27
28typedef struct MpegAudioParseContext {
29    ParseContext pc;
30    int frame_size;
31    uint32_t header;
32    int header_count;
33} MpegAudioParseContext;
34
35#define MPA_HEADER_SIZE 4
36
37/* header + layer + bitrate + freq + lsf/mpeg25 */
38#undef SAME_HEADER_MASK /* mpegaudio.h defines different version */
39#define SAME_HEADER_MASK \
40   (0xffe00000 | (3 << 17) | (3 << 10) | (3 << 19))
41
42/* useful helper to get mpeg audio stream infos. Return -1 if error in
43   header, otherwise the coded frame size in bytes */
44int ff_mpa_decode_header(AVCodecContext *avctx, uint32_t head, int *sample_rate, int *channels, int *frame_size, int *bit_rate)
45{
46    MPADecodeHeader s1, *s = &s1;
47
48    if (ff_mpa_check_header(head) != 0)
49        return -1;
50
51    if (ff_mpegaudio_decode_header(s, head) != 0) {
52        return -1;
53    }
54
55    switch(s->layer) {
56    case 1:
57        avctx->codec_id = CODEC_ID_MP1;
58        *frame_size = 384;
59        break;
60    case 2:
61        avctx->codec_id = CODEC_ID_MP2;
62        *frame_size = 1152;
63        break;
64    default:
65    case 3:
66        avctx->codec_id = CODEC_ID_MP3;
67        if (s->lsf)
68            *frame_size = 576;
69        else
70            *frame_size = 1152;
71        break;
72    }
73
74    *sample_rate = s->sample_rate;
75    *channels = s->nb_channels;
76    *bit_rate = s->bit_rate;
77    avctx->sub_id = s->layer;
78    return s->frame_size;
79}
80
81static int mpegaudio_parse(AVCodecParserContext *s1,
82                           AVCodecContext *avctx,
83                           const uint8_t **poutbuf, int *poutbuf_size,
84                           const uint8_t *buf, int buf_size)
85{
86    MpegAudioParseContext *s = s1->priv_data;
87    ParseContext *pc = &s->pc;
88    uint32_t state= pc->state;
89    int i;
90    int next= END_NOT_FOUND;
91
92    for(i=0; i<buf_size; ){
93        if(s->frame_size){
94            int inc= FFMIN(buf_size - i, s->frame_size);
95            i += inc;
96            s->frame_size -= inc;
97
98            if(!s->frame_size){
99                next= i;
100                break;
101            }
102        }else{
103            while(i<buf_size){
104                int ret, sr, channels, bit_rate, frame_size;
105
106                state= (state<<8) + buf[i++];
107
108                ret = ff_mpa_decode_header(avctx, state, &sr, &channels, &frame_size, &bit_rate);
109                if (ret < 4) {
110                    s->header_count= -2;
111                } else {
112                    if((state&SAME_HEADER_MASK) != (s->header&SAME_HEADER_MASK) && s->header)
113                        s->header_count= -3;
114                    s->header= state;
115                    s->header_count++;
116                    s->frame_size = ret-4;
117
118                    if(s->header_count > 1){
119                        avctx->sample_rate= sr;
120                        avctx->channels   = channels;
121                        avctx->frame_size = frame_size;
122                        avctx->bit_rate   = bit_rate;
123                    }
124                    break;
125                }
126            }
127        }
128    }
129
130    pc->state= state;
131    if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) {
132        *poutbuf = NULL;
133        *poutbuf_size = 0;
134        return buf_size;
135    }
136
137    *poutbuf = buf;
138    *poutbuf_size = buf_size;
139    return next;
140}
141
142
143AVCodecParser mpegaudio_parser = {
144    { CODEC_ID_MP1, CODEC_ID_MP2, CODEC_ID_MP3 },
145    sizeof(MpegAudioParseContext),
146    NULL,
147    mpegaudio_parse,
148    ff_parse_close,
149};
150