Mercurial > libavcodec.hg
annotate mpegaudio_parser.c @ 10314:ab687351bfef libavcodec
WMA: store level_table as floats, use type punning for sign flip in decode
author | mru |
---|---|
date | Tue, 29 Sep 2009 10:38:34 +0000 |
parents | 30dad2d5e7fe |
children |
rev | line source |
---|---|
1613 | 1 /* |
4913 | 2 * MPEG Audio parser |
8629
04423b2f6e0b
cosmetics: Remove pointless period after copyright statement non-sentences.
diego
parents:
8587
diff
changeset
|
3 * Copyright (c) 2003 Fabrice Bellard |
04423b2f6e0b
cosmetics: Remove pointless period after copyright statement non-sentences.
diego
parents:
8587
diff
changeset
|
4 * Copyright (c) 2003 Michael Niedermayer |
1613 | 5 * |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3776
diff
changeset
|
6 * This file is part of FFmpeg. |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3776
diff
changeset
|
7 * |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3776
diff
changeset
|
8 * FFmpeg is free software; you can redistribute it and/or |
1613 | 9 * modify it under the terms of the GNU Lesser General Public |
10 * License as published by the Free Software Foundation; either | |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3776
diff
changeset
|
11 * version 2.1 of the License, or (at your option) any later version. |
1613 | 12 * |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3776
diff
changeset
|
13 * FFmpeg is distributed in the hope that it will be useful, |
1613 | 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 | |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3776
diff
changeset
|
19 * License along with FFmpeg; if not, write to the Free Software |
3036
0b546eab515d
Update licensing information: The FSF changed postal address.
diego
parents:
2979
diff
changeset
|
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
1613 | 21 */ |
2967 | 22 |
4913 | 23 #include "parser.h" |
24 #include "mpegaudio.h" | |
5050 | 25 #include "mpegaudiodecheader.h" |
2386 | 26 |
27 | |
1613 | 28 typedef struct MpegAudioParseContext { |
9894
78b2fc137c27
Rewrite mp3 parser. New code is much simpler and does not drop
michael
parents:
9599
diff
changeset
|
29 ParseContext pc; |
1613 | 30 int frame_size; |
2470
06aafb585f69
require a few valid and equal mp3 headers for resync
michael
parents:
2389
diff
changeset
|
31 uint32_t header; |
06aafb585f69
require a few valid and equal mp3 headers for resync
michael
parents:
2389
diff
changeset
|
32 int header_count; |
1613 | 33 } MpegAudioParseContext; |
34 | |
35 #define MPA_HEADER_SIZE 4 | |
36 | |
37 /* header + layer + bitrate + freq + lsf/mpeg25 */ | |
2522
e25782262d7d
kill warnings patch by (Mns Rullgrd <mru inprovide com>)
michael
parents:
2486
diff
changeset
|
38 #undef SAME_HEADER_MASK /* mpegaudio.h defines different version */ |
1613 | 39 #define SAME_HEADER_MASK \ |
2480 | 40 (0xffe00000 | (3 << 17) | (3 << 10) | (3 << 19)) |
1613 | 41 |
5050 | 42 /* useful helper to get mpeg audio stream infos. Return -1 if error in |
43 header, otherwise the coded frame size in bytes */ | |
8420
2b0d01be134f
Change mpeg audio parser so it only sets frame_size, channels and bit_rate
michael
parents:
5260
diff
changeset
|
44 int ff_mpa_decode_header(AVCodecContext *avctx, uint32_t head, int *sample_rate, int *channels, int *frame_size, int *bit_rate) |
5050 | 45 { |
8641 | 46 MPADecodeHeader s1, *s = &s1; |
5050 | 47 |
48 if (ff_mpa_check_header(head) != 0) | |
49 return -1; | |
50 | |
5051 | 51 if (ff_mpegaudio_decode_header(s, head) != 0) { |
5050 | 52 return -1; |
53 } | |
54 | |
55 switch(s->layer) { | |
56 case 1: | |
8587 | 57 avctx->codec_id = CODEC_ID_MP1; |
8420
2b0d01be134f
Change mpeg audio parser so it only sets frame_size, channels and bit_rate
michael
parents:
5260
diff
changeset
|
58 *frame_size = 384; |
5050 | 59 break; |
60 case 2: | |
8587 | 61 avctx->codec_id = CODEC_ID_MP2; |
8420
2b0d01be134f
Change mpeg audio parser so it only sets frame_size, channels and bit_rate
michael
parents:
5260
diff
changeset
|
62 *frame_size = 1152; |
5050 | 63 break; |
64 default: | |
65 case 3: | |
8587 | 66 avctx->codec_id = CODEC_ID_MP3; |
5050 | 67 if (s->lsf) |
8420
2b0d01be134f
Change mpeg audio parser so it only sets frame_size, channels and bit_rate
michael
parents:
5260
diff
changeset
|
68 *frame_size = 576; |
5050 | 69 else |
8420
2b0d01be134f
Change mpeg audio parser so it only sets frame_size, channels and bit_rate
michael
parents:
5260
diff
changeset
|
70 *frame_size = 1152; |
5050 | 71 break; |
72 } | |
73 | |
74 *sample_rate = s->sample_rate; | |
8420
2b0d01be134f
Change mpeg audio parser so it only sets frame_size, channels and bit_rate
michael
parents:
5260
diff
changeset
|
75 *channels = s->nb_channels; |
2b0d01be134f
Change mpeg audio parser so it only sets frame_size, channels and bit_rate
michael
parents:
5260
diff
changeset
|
76 *bit_rate = s->bit_rate; |
5050 | 77 avctx->sub_id = s->layer; |
78 return s->frame_size; | |
79 } | |
80 | |
1613 | 81 static int mpegaudio_parse(AVCodecParserContext *s1, |
82 AVCodecContext *avctx, | |
4931
0d1cc37d9430
make some parser parameters const to avoid casting const to non-const
aurel
parents:
4914
diff
changeset
|
83 const uint8_t **poutbuf, int *poutbuf_size, |
1613 | 84 const uint8_t *buf, int buf_size) |
85 { | |
86 MpegAudioParseContext *s = s1->priv_data; | |
9894
78b2fc137c27
Rewrite mp3 parser. New code is much simpler and does not drop
michael
parents:
9599
diff
changeset
|
87 ParseContext *pc = &s->pc; |
78b2fc137c27
Rewrite mp3 parser. New code is much simpler and does not drop
michael
parents:
9599
diff
changeset
|
88 uint32_t state= pc->state; |
78b2fc137c27
Rewrite mp3 parser. New code is much simpler and does not drop
michael
parents:
9599
diff
changeset
|
89 int i; |
78b2fc137c27
Rewrite mp3 parser. New code is much simpler and does not drop
michael
parents:
9599
diff
changeset
|
90 int next= END_NOT_FOUND; |
1613 | 91 |
9894
78b2fc137c27
Rewrite mp3 parser. New code is much simpler and does not drop
michael
parents:
9599
diff
changeset
|
92 for(i=0; i<buf_size; ){ |
78b2fc137c27
Rewrite mp3 parser. New code is much simpler and does not drop
michael
parents:
9599
diff
changeset
|
93 if(s->frame_size){ |
78b2fc137c27
Rewrite mp3 parser. New code is much simpler and does not drop
michael
parents:
9599
diff
changeset
|
94 int inc= FFMIN(buf_size - i, s->frame_size); |
78b2fc137c27
Rewrite mp3 parser. New code is much simpler and does not drop
michael
parents:
9599
diff
changeset
|
95 i += inc; |
78b2fc137c27
Rewrite mp3 parser. New code is much simpler and does not drop
michael
parents:
9599
diff
changeset
|
96 s->frame_size -= inc; |
78b2fc137c27
Rewrite mp3 parser. New code is much simpler and does not drop
michael
parents:
9599
diff
changeset
|
97 |
78b2fc137c27
Rewrite mp3 parser. New code is much simpler and does not drop
michael
parents:
9599
diff
changeset
|
98 if(!s->frame_size){ |
78b2fc137c27
Rewrite mp3 parser. New code is much simpler and does not drop
michael
parents:
9599
diff
changeset
|
99 next= i; |
78b2fc137c27
Rewrite mp3 parser. New code is much simpler and does not drop
michael
parents:
9599
diff
changeset
|
100 break; |
2979 | 101 } |
9894
78b2fc137c27
Rewrite mp3 parser. New code is much simpler and does not drop
michael
parents:
9599
diff
changeset
|
102 }else{ |
78b2fc137c27
Rewrite mp3 parser. New code is much simpler and does not drop
michael
parents:
9599
diff
changeset
|
103 while(i<buf_size){ |
78b2fc137c27
Rewrite mp3 parser. New code is much simpler and does not drop
michael
parents:
9599
diff
changeset
|
104 int ret, sr, channels, bit_rate, frame_size; |
1613 | 105 |
9894
78b2fc137c27
Rewrite mp3 parser. New code is much simpler and does not drop
michael
parents:
9599
diff
changeset
|
106 state= (state<<8) + buf[i++]; |
78b2fc137c27
Rewrite mp3 parser. New code is much simpler and does not drop
michael
parents:
9599
diff
changeset
|
107 |
78b2fc137c27
Rewrite mp3 parser. New code is much simpler and does not drop
michael
parents:
9599
diff
changeset
|
108 ret = ff_mpa_decode_header(avctx, state, &sr, &channels, &frame_size, &bit_rate); |
78b2fc137c27
Rewrite mp3 parser. New code is much simpler and does not drop
michael
parents:
9599
diff
changeset
|
109 if (ret < 4) { |
2470
06aafb585f69
require a few valid and equal mp3 headers for resync
michael
parents:
2389
diff
changeset
|
110 s->header_count= -2; |
2979 | 111 } else { |
9894
78b2fc137c27
Rewrite mp3 parser. New code is much simpler and does not drop
michael
parents:
9599
diff
changeset
|
112 if((state&SAME_HEADER_MASK) != (s->header&SAME_HEADER_MASK) && s->header) |
2470
06aafb585f69
require a few valid and equal mp3 headers for resync
michael
parents:
2389
diff
changeset
|
113 s->header_count= -3; |
9894
78b2fc137c27
Rewrite mp3 parser. New code is much simpler and does not drop
michael
parents:
9599
diff
changeset
|
114 s->header= state; |
2470
06aafb585f69
require a few valid and equal mp3 headers for resync
michael
parents:
2389
diff
changeset
|
115 s->header_count++; |
9894
78b2fc137c27
Rewrite mp3 parser. New code is much simpler and does not drop
michael
parents:
9599
diff
changeset
|
116 s->frame_size = ret-4; |
2967 | 117 |
8420
2b0d01be134f
Change mpeg audio parser so it only sets frame_size, channels and bit_rate
michael
parents:
5260
diff
changeset
|
118 if(s->header_count > 1){ |
5260 | 119 avctx->sample_rate= sr; |
8420
2b0d01be134f
Change mpeg audio parser so it only sets frame_size, channels and bit_rate
michael
parents:
5260
diff
changeset
|
120 avctx->channels = channels; |
2b0d01be134f
Change mpeg audio parser so it only sets frame_size, channels and bit_rate
michael
parents:
5260
diff
changeset
|
121 avctx->frame_size = frame_size; |
2b0d01be134f
Change mpeg audio parser so it only sets frame_size, channels and bit_rate
michael
parents:
5260
diff
changeset
|
122 avctx->bit_rate = bit_rate; |
2b0d01be134f
Change mpeg audio parser so it only sets frame_size, channels and bit_rate
michael
parents:
5260
diff
changeset
|
123 } |
9894
78b2fc137c27
Rewrite mp3 parser. New code is much simpler and does not drop
michael
parents:
9599
diff
changeset
|
124 break; |
5259 | 125 } |
2979 | 126 } |
127 } | |
1613 | 128 } |
9894
78b2fc137c27
Rewrite mp3 parser. New code is much simpler and does not drop
michael
parents:
9599
diff
changeset
|
129 |
78b2fc137c27
Rewrite mp3 parser. New code is much simpler and does not drop
michael
parents:
9599
diff
changeset
|
130 pc->state= state; |
78b2fc137c27
Rewrite mp3 parser. New code is much simpler and does not drop
michael
parents:
9599
diff
changeset
|
131 if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) { |
78b2fc137c27
Rewrite mp3 parser. New code is much simpler and does not drop
michael
parents:
9599
diff
changeset
|
132 *poutbuf = NULL; |
78b2fc137c27
Rewrite mp3 parser. New code is much simpler and does not drop
michael
parents:
9599
diff
changeset
|
133 *poutbuf_size = 0; |
78b2fc137c27
Rewrite mp3 parser. New code is much simpler and does not drop
michael
parents:
9599
diff
changeset
|
134 return buf_size; |
78b2fc137c27
Rewrite mp3 parser. New code is much simpler and does not drop
michael
parents:
9599
diff
changeset
|
135 } |
78b2fc137c27
Rewrite mp3 parser. New code is much simpler and does not drop
michael
parents:
9599
diff
changeset
|
136 |
78b2fc137c27
Rewrite mp3 parser. New code is much simpler and does not drop
michael
parents:
9599
diff
changeset
|
137 *poutbuf = buf; |
78b2fc137c27
Rewrite mp3 parser. New code is much simpler and does not drop
michael
parents:
9599
diff
changeset
|
138 *poutbuf_size = buf_size; |
78b2fc137c27
Rewrite mp3 parser. New code is much simpler and does not drop
michael
parents:
9599
diff
changeset
|
139 return next; |
1613 | 140 } |
4397
acb9faabab8d
Allows the AC3 parser to read the frame size and codec parameters from E-AC3 streams,
gpoirier
parents:
4310
diff
changeset
|
141 |
acb9faabab8d
Allows the AC3 parser to read the frame size and codec parameters from E-AC3 streams,
gpoirier
parents:
4310
diff
changeset
|
142 |
1613 | 143 AVCodecParser mpegaudio_parser = { |
8586
d7d0cde5f308
Add dummy mp1_decoder to complement the existing dummy mp2/mp3 decoders.
michael
parents:
8420
diff
changeset
|
144 { CODEC_ID_MP1, CODEC_ID_MP2, CODEC_ID_MP3 }, |
1613 | 145 sizeof(MpegAudioParseContext), |
9894
78b2fc137c27
Rewrite mp3 parser. New code is much simpler and does not drop
michael
parents:
9599
diff
changeset
|
146 NULL, |
1613 | 147 mpegaudio_parse, |
9909
30dad2d5e7fe
Cleanup properly at the end of MPEG Audio parsing.
jai_menon
parents:
9894
diff
changeset
|
148 ff_parse_close, |
1613 | 149 }; |