annotate mpegaudio_parser.c @ 12530:63edd10ad4bc libavcodec tip

Try to fix crashes introduced by r25218 r25218 made assumptions about the existence of past reference frames that weren't necessarily true.
author darkshikari
date Tue, 28 Sep 2010 09:06:22 +0000
parents 30dad2d5e7fe
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
1 /*
4913
b7bde71aa752 move mpegaudio_parser in it's own file
aurel
parents: 4912
diff changeset
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
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
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
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
9 * modify it under the terms of the GNU Lesser General Public
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
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
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
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
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
16 * Lesser General Public License for more details.
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
17 *
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
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
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
21 */
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2864
diff changeset
22
4913
b7bde71aa752 move mpegaudio_parser in it's own file
aurel
parents: 4912
diff changeset
23 #include "parser.h"
b7bde71aa752 move mpegaudio_parser in it's own file
aurel
parents: 4912
diff changeset
24 #include "mpegaudio.h"
5050
a5f6fbc9fa66 loosen dependencies over mpegaudiodec
aurel
parents: 4931
diff changeset
25 #include "mpegaudiodecheader.h"
2386
8d1983254e28 flush remaining data from parser at EOF
michael
parents: 2348
diff changeset
26
8d1983254e28 flush remaining data from parser at EOF
michael
parents: 2348
diff changeset
27
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
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
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
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
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
33 } MpegAudioParseContext;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
34
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
35 #define MPA_HEADER_SIZE 4
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
36
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
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
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
39 #define SAME_HEADER_MASK \
2480
5252700f61df 10000l vbr mp3 fix
michael
parents: 2470
diff changeset
40 (0xffe00000 | (3 << 17) | (3 << 10) | (3 << 19))
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
41
5050
a5f6fbc9fa66 loosen dependencies over mpegaudiodec
aurel
parents: 4931
diff changeset
42 /* useful helper to get mpeg audio stream infos. Return -1 if error in
a5f6fbc9fa66 loosen dependencies over mpegaudiodec
aurel
parents: 4931
diff changeset
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
a5f6fbc9fa66 loosen dependencies over mpegaudiodec
aurel
parents: 4931
diff changeset
45 {
8641
54e2916c25a5 Avoid allocating MPADecodeContext on stack.
andoma
parents: 8629
diff changeset
46 MPADecodeHeader s1, *s = &s1;
5050
a5f6fbc9fa66 loosen dependencies over mpegaudiodec
aurel
parents: 4931
diff changeset
47
a5f6fbc9fa66 loosen dependencies over mpegaudiodec
aurel
parents: 4931
diff changeset
48 if (ff_mpa_check_header(head) != 0)
a5f6fbc9fa66 loosen dependencies over mpegaudiodec
aurel
parents: 4931
diff changeset
49 return -1;
a5f6fbc9fa66 loosen dependencies over mpegaudiodec
aurel
parents: 4931
diff changeset
50
5051
b908c67063c8 add a ff_ prefix to some mpegaudio funcs
aurel
parents: 5050
diff changeset
51 if (ff_mpegaudio_decode_header(s, head) != 0) {
5050
a5f6fbc9fa66 loosen dependencies over mpegaudiodec
aurel
parents: 4931
diff changeset
52 return -1;
a5f6fbc9fa66 loosen dependencies over mpegaudiodec
aurel
parents: 4931
diff changeset
53 }
a5f6fbc9fa66 loosen dependencies over mpegaudiodec
aurel
parents: 4931
diff changeset
54
a5f6fbc9fa66 loosen dependencies over mpegaudiodec
aurel
parents: 4931
diff changeset
55 switch(s->layer) {
a5f6fbc9fa66 loosen dependencies over mpegaudiodec
aurel
parents: 4931
diff changeset
56 case 1:
8587
b3f3d9ffab1c Let the mpeg audio parser correct the codec_id.
michael
parents: 8586
diff changeset
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
a5f6fbc9fa66 loosen dependencies over mpegaudiodec
aurel
parents: 4931
diff changeset
59 break;
a5f6fbc9fa66 loosen dependencies over mpegaudiodec
aurel
parents: 4931
diff changeset
60 case 2:
8587
b3f3d9ffab1c Let the mpeg audio parser correct the codec_id.
michael
parents: 8586
diff changeset
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
a5f6fbc9fa66 loosen dependencies over mpegaudiodec
aurel
parents: 4931
diff changeset
63 break;
a5f6fbc9fa66 loosen dependencies over mpegaudiodec
aurel
parents: 4931
diff changeset
64 default:
a5f6fbc9fa66 loosen dependencies over mpegaudiodec
aurel
parents: 4931
diff changeset
65 case 3:
8587
b3f3d9ffab1c Let the mpeg audio parser correct the codec_id.
michael
parents: 8586
diff changeset
66 avctx->codec_id = CODEC_ID_MP3;
5050
a5f6fbc9fa66 loosen dependencies over mpegaudiodec
aurel
parents: 4931
diff changeset
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
a5f6fbc9fa66 loosen dependencies over mpegaudiodec
aurel
parents: 4931
diff changeset
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
a5f6fbc9fa66 loosen dependencies over mpegaudiodec
aurel
parents: 4931
diff changeset
71 break;
a5f6fbc9fa66 loosen dependencies over mpegaudiodec
aurel
parents: 4931
diff changeset
72 }
a5f6fbc9fa66 loosen dependencies over mpegaudiodec
aurel
parents: 4931
diff changeset
73
a5f6fbc9fa66 loosen dependencies over mpegaudiodec
aurel
parents: 4931
diff changeset
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
a5f6fbc9fa66 loosen dependencies over mpegaudiodec
aurel
parents: 4931
diff changeset
77 avctx->sub_id = s->layer;
a5f6fbc9fa66 loosen dependencies over mpegaudiodec
aurel
parents: 4931
diff changeset
78 return s->frame_size;
a5f6fbc9fa66 loosen dependencies over mpegaudiodec
aurel
parents: 4931
diff changeset
79 }
a5f6fbc9fa66 loosen dependencies over mpegaudiodec
aurel
parents: 4931
diff changeset
80
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
81 static int mpegaudio_parse(AVCodecParserContext *s1,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
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
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
84 const uint8_t *buf, int buf_size)
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
85 {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
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
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
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
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
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
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
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
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
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
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2864
diff changeset
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
mru
parents: 5259
diff changeset
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
3f48ee403351 set sample rate in more logical place, kill warning
mru
parents: 5089
diff changeset
125 }
2979
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
126 }
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
127 }
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
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
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
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
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
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
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
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
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
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
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
149 };