OSDN Git Service

Merge remote-tracking branch 'qatar/master'
[coroid/ffmpeg_saccubus.git] / libavcodec / mpegaudio_parser.c
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
28 typedef 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 #define SAME_HEADER_MASK \
39    (0xffe00000 | (3 << 17) | (3 << 10) | (3 << 19))
40
41 /* useful helper to get mpeg audio stream infos. Return -1 if error in
42    header, otherwise the coded frame size in bytes */
43 int ff_mpa_decode_header(AVCodecContext *avctx, uint32_t head, int *sample_rate, int *channels, int *frame_size, int *bit_rate)
44 {
45     MPADecodeHeader s1, *s = &s1;
46
47     if (ff_mpa_check_header(head) != 0)
48         return -1;
49
50     if (ff_mpegaudio_decode_header(s, head) != 0) {
51         return -1;
52     }
53
54     switch(s->layer) {
55     case 1:
56         avctx->codec_id = CODEC_ID_MP1;
57         *frame_size = 384;
58         break;
59     case 2:
60         avctx->codec_id = CODEC_ID_MP2;
61         *frame_size = 1152;
62         break;
63     default:
64     case 3:
65         avctx->codec_id = CODEC_ID_MP3;
66         if (s->lsf)
67             *frame_size = 576;
68         else
69             *frame_size = 1152;
70         break;
71     }
72
73     *sample_rate = s->sample_rate;
74     *channels = s->nb_channels;
75     *bit_rate = s->bit_rate;
76     avctx->sub_id = s->layer;
77     return s->frame_size;
78 }
79
80 static int mpegaudio_parse(AVCodecParserContext *s1,
81                            AVCodecContext *avctx,
82                            const uint8_t **poutbuf, int *poutbuf_size,
83                            const uint8_t *buf, int buf_size)
84 {
85     MpegAudioParseContext *s = s1->priv_data;
86     ParseContext *pc = &s->pc;
87     uint32_t state= pc->state;
88     int i;
89     int next= END_NOT_FOUND;
90
91     for(i=0; i<buf_size; ){
92         if(s->frame_size){
93             int inc= FFMIN(buf_size - i, s->frame_size);
94             i += inc;
95             s->frame_size -= inc;
96
97             if(!s->frame_size){
98                 next= i;
99                 break;
100             }
101         }else{
102             while(i<buf_size){
103                 int ret, sr, channels, bit_rate, frame_size;
104
105                 state= (state<<8) + buf[i++];
106
107                 ret = ff_mpa_decode_header(avctx, state, &sr, &channels, &frame_size, &bit_rate);
108                 if (ret < 4) {
109                     s->header_count= -2;
110                 } else {
111                     if((state&SAME_HEADER_MASK) != (s->header&SAME_HEADER_MASK) && s->header)
112                         s->header_count= -3;
113                     s->header= state;
114                     s->header_count++;
115                     s->frame_size = ret-4;
116
117                     if(s->header_count > 1){
118                         avctx->sample_rate= sr;
119                         avctx->channels   = channels;
120                         avctx->frame_size = frame_size;
121                         avctx->bit_rate   = bit_rate;
122                     }
123                     break;
124                 }
125             }
126         }
127     }
128
129     pc->state= state;
130     if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) {
131         *poutbuf = NULL;
132         *poutbuf_size = 0;
133         return buf_size;
134     }
135
136     *poutbuf = buf;
137     *poutbuf_size = buf_size;
138     return next;
139 }
140
141
142 AVCodecParser ff_mpegaudio_parser = {
143     { CODEC_ID_MP1, CODEC_ID_MP2, CODEC_ID_MP3 },
144     sizeof(MpegAudioParseContext),
145     NULL,
146     mpegaudio_parse,
147     ff_parse_close,
148 };