Mercurial > libavcodec.hg
annotate mpegaudio_parser.c @ 12408:ae72506d4c2a libavcodec
acenc: LAME-inspired window decision
This performs quite a bit better than the current 3GPP-inspired window decision
on all the samples I have tested. On the castanets.wav sample it performs very
similar to iTunes window selection, and seems to perform better than Nero.
On fatboy.wav, it seems to perform at least as good as iTunes, if not better.
Nero performs horribly on this sample.
Patch by: Nathan Caldwell <saintdev@gmail.com>
author | alexc |
---|---|
date | Mon, 23 Aug 2010 20:00:03 +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 }; |