Mercurial > libavcodec.hg
annotate mpegaudio_parser.c @ 12490:e1a4ceb96a07 libavcodec
Add R10k decoder.
Original patch by Zhou Zongyi, zhouzy A os pku edu cn, resubmitted by
James Darnley, james.darnley gmail, changes by me.
| author | cehoyos |
|---|---|
| date | Mon, 13 Sep 2010 22:08:51 +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 (M?ns Rullg?rd <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 }; |
