annotate mpegaudio_parser.c @ 9473:e38284cd69dc libavcodec

Use memcpy instead of the very inefficient bytecopy where both are correct (i.e. no overlap of src and dst is possible).
author reimar
date Fri, 17 Apr 2009 17:20:48 +0000
parents 043574c5c153
children 407470044819
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 {
2979
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
29 uint8_t inbuf[MPA_MAX_CODED_FRAME_SIZE]; /* input buffer */
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
30 uint8_t *inbuf_ptr;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
31 int frame_size;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
32 int free_format_frame_size;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
33 int free_format_next_header;
2470
06aafb585f69 require a few valid and equal mp3 headers for resync
michael
parents: 2389
diff changeset
34 uint32_t header;
06aafb585f69 require a few valid and equal mp3 headers for resync
michael
parents: 2389
diff changeset
35 int header_count;
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
36 } MpegAudioParseContext;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
37
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
38 #define MPA_HEADER_SIZE 4
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
39
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
40 /* header + layer + bitrate + freq + lsf/mpeg25 */
2522
e25782262d7d kill warnings patch by (Mns Rullgrd <mru inprovide com>)
michael
parents: 2486
diff changeset
41 #undef SAME_HEADER_MASK /* mpegaudio.h defines different version */
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
42 #define SAME_HEADER_MASK \
2480
5252700f61df 10000l vbr mp3 fix
michael
parents: 2470
diff changeset
43 (0xffe00000 | (3 << 17) | (3 << 10) | (3 << 19))
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
44
5050
a5f6fbc9fa66 loosen dependencies over mpegaudiodec
aurel
parents: 4931
diff changeset
45 /* useful helper to get mpeg audio stream infos. Return -1 if error in
a5f6fbc9fa66 loosen dependencies over mpegaudiodec
aurel
parents: 4931
diff changeset
46 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
47 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
48 {
8641
54e2916c25a5 Avoid allocating MPADecodeContext on stack.
andoma
parents: 8629
diff changeset
49 MPADecodeHeader s1, *s = &s1;
5050
a5f6fbc9fa66 loosen dependencies over mpegaudiodec
aurel
parents: 4931
diff changeset
50
a5f6fbc9fa66 loosen dependencies over mpegaudiodec
aurel
parents: 4931
diff changeset
51 if (ff_mpa_check_header(head) != 0)
a5f6fbc9fa66 loosen dependencies over mpegaudiodec
aurel
parents: 4931
diff changeset
52 return -1;
a5f6fbc9fa66 loosen dependencies over mpegaudiodec
aurel
parents: 4931
diff changeset
53
5051
b908c67063c8 add a ff_ prefix to some mpegaudio funcs
aurel
parents: 5050
diff changeset
54 if (ff_mpegaudio_decode_header(s, head) != 0) {
5050
a5f6fbc9fa66 loosen dependencies over mpegaudiodec
aurel
parents: 4931
diff changeset
55 return -1;
a5f6fbc9fa66 loosen dependencies over mpegaudiodec
aurel
parents: 4931
diff changeset
56 }
a5f6fbc9fa66 loosen dependencies over mpegaudiodec
aurel
parents: 4931
diff changeset
57
a5f6fbc9fa66 loosen dependencies over mpegaudiodec
aurel
parents: 4931
diff changeset
58 switch(s->layer) {
a5f6fbc9fa66 loosen dependencies over mpegaudiodec
aurel
parents: 4931
diff changeset
59 case 1:
8587
b3f3d9ffab1c Let the mpeg audio parser correct the codec_id.
michael
parents: 8586
diff changeset
60 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
61 *frame_size = 384;
5050
a5f6fbc9fa66 loosen dependencies over mpegaudiodec
aurel
parents: 4931
diff changeset
62 break;
a5f6fbc9fa66 loosen dependencies over mpegaudiodec
aurel
parents: 4931
diff changeset
63 case 2:
8587
b3f3d9ffab1c Let the mpeg audio parser correct the codec_id.
michael
parents: 8586
diff changeset
64 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
65 *frame_size = 1152;
5050
a5f6fbc9fa66 loosen dependencies over mpegaudiodec
aurel
parents: 4931
diff changeset
66 break;
a5f6fbc9fa66 loosen dependencies over mpegaudiodec
aurel
parents: 4931
diff changeset
67 default:
a5f6fbc9fa66 loosen dependencies over mpegaudiodec
aurel
parents: 4931
diff changeset
68 case 3:
8587
b3f3d9ffab1c Let the mpeg audio parser correct the codec_id.
michael
parents: 8586
diff changeset
69 avctx->codec_id = CODEC_ID_MP3;
5050
a5f6fbc9fa66 loosen dependencies over mpegaudiodec
aurel
parents: 4931
diff changeset
70 if (s->lsf)
8420
2b0d01be134f Change mpeg audio parser so it only sets frame_size, channels and bit_rate
michael
parents: 5260
diff changeset
71 *frame_size = 576;
5050
a5f6fbc9fa66 loosen dependencies over mpegaudiodec
aurel
parents: 4931
diff changeset
72 else
8420
2b0d01be134f Change mpeg audio parser so it only sets frame_size, channels and bit_rate
michael
parents: 5260
diff changeset
73 *frame_size = 1152;
5050
a5f6fbc9fa66 loosen dependencies over mpegaudiodec
aurel
parents: 4931
diff changeset
74 break;
a5f6fbc9fa66 loosen dependencies over mpegaudiodec
aurel
parents: 4931
diff changeset
75 }
a5f6fbc9fa66 loosen dependencies over mpegaudiodec
aurel
parents: 4931
diff changeset
76
a5f6fbc9fa66 loosen dependencies over mpegaudiodec
aurel
parents: 4931
diff changeset
77 *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
78 *channels = s->nb_channels;
2b0d01be134f Change mpeg audio parser so it only sets frame_size, channels and bit_rate
michael
parents: 5260
diff changeset
79 *bit_rate = s->bit_rate;
5050
a5f6fbc9fa66 loosen dependencies over mpegaudiodec
aurel
parents: 4931
diff changeset
80 avctx->sub_id = s->layer;
a5f6fbc9fa66 loosen dependencies over mpegaudiodec
aurel
parents: 4931
diff changeset
81 return s->frame_size;
a5f6fbc9fa66 loosen dependencies over mpegaudiodec
aurel
parents: 4931
diff changeset
82 }
a5f6fbc9fa66 loosen dependencies over mpegaudiodec
aurel
parents: 4931
diff changeset
83
9007
043574c5c153 Add missing av_cold in static init/close functions.
stefano
parents: 8641
diff changeset
84 static av_cold int mpegaudio_parse_init(AVCodecParserContext *s1)
1613
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;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
87 s->inbuf_ptr = s->inbuf;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
88 return 0;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
89 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
90
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
91 static int mpegaudio_parse(AVCodecParserContext *s1,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
92 AVCodecContext *avctx,
4931
0d1cc37d9430 make some parser parameters const to avoid casting const to non-const
aurel
parents: 4914
diff changeset
93 const uint8_t **poutbuf, int *poutbuf_size,
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
94 const uint8_t *buf, int buf_size)
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
95 {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
96 MpegAudioParseContext *s = s1->priv_data;
8420
2b0d01be134f Change mpeg audio parser so it only sets frame_size, channels and bit_rate
michael
parents: 5260
diff changeset
97 int len, ret, sr, channels, bit_rate, frame_size;
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
98 uint32_t header;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
99 const uint8_t *buf_ptr;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
100
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
101 *poutbuf = NULL;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
102 *poutbuf_size = 0;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
103 buf_ptr = buf;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
104 while (buf_size > 0) {
2979
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
105 len = s->inbuf_ptr - s->inbuf;
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
106 if (s->frame_size == 0) {
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
107 /* special case for next header for first frame in free
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
108 format case (XXX: find a simpler method) */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
109 if (s->free_format_next_header != 0) {
5089
bff60ecc02f9 Use AV_xx throughout libavcodec
ramiro
parents: 5051
diff changeset
110 AV_WB32(s->inbuf, s->free_format_next_header);
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
111 s->inbuf_ptr = s->inbuf + 4;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
112 s->free_format_next_header = 0;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
113 goto got_header;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
114 }
2979
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
115 /* no header seen : find one. We need at least MPA_HEADER_SIZE
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
116 bytes to parse it */
3639
949bc256f1e3 dont copy frame if the whole mp1/2/3 frame is available in one piece in the input
michael
parents: 3456
diff changeset
117 len = FFMIN(MPA_HEADER_SIZE - len, buf_size);
2979
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
118 if (len > 0) {
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
119 memcpy(s->inbuf_ptr, buf_ptr, len);
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
120 buf_ptr += len;
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
121 buf_size -= len;
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
122 s->inbuf_ptr += len;
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
123 }
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
124 if ((s->inbuf_ptr - s->inbuf) >= MPA_HEADER_SIZE) {
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
125 got_header:
5089
bff60ecc02f9 Use AV_xx throughout libavcodec
ramiro
parents: 5051
diff changeset
126 header = AV_RB32(s->inbuf);
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
127
8420
2b0d01be134f Change mpeg audio parser so it only sets frame_size, channels and bit_rate
michael
parents: 5260
diff changeset
128 ret = ff_mpa_decode_header(avctx, header, &sr, &channels, &frame_size, &bit_rate);
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
129 if (ret < 0) {
2470
06aafb585f69 require a few valid and equal mp3 headers for resync
michael
parents: 2389
diff changeset
130 s->header_count= -2;
2979
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
131 /* no sync found : move by one byte (inefficient, but simple!) */
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
132 memmove(s->inbuf, s->inbuf + 1, s->inbuf_ptr - s->inbuf - 1);
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
133 s->inbuf_ptr--;
4652
6679d37a3338 Give context to dprintf
mbardiaux
parents: 4648
diff changeset
134 dprintf(avctx, "skip %x\n", header);
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
135 /* reset free format frame size to give a chance
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
136 to get a new bitrate */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
137 s->free_format_frame_size = 0;
2979
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
138 } else {
2470
06aafb585f69 require a few valid and equal mp3 headers for resync
michael
parents: 2389
diff changeset
139 if((header&SAME_HEADER_MASK) != (s->header&SAME_HEADER_MASK) && s->header)
06aafb585f69 require a few valid and equal mp3 headers for resync
michael
parents: 2389
diff changeset
140 s->header_count= -3;
06aafb585f69 require a few valid and equal mp3 headers for resync
michael
parents: 2389
diff changeset
141 s->header= header;
06aafb585f69 require a few valid and equal mp3 headers for resync
michael
parents: 2389
diff changeset
142 s->header_count++;
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
143 s->frame_size = ret;
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2864
diff changeset
144
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
145 #if 0
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
146 /* free format: prepare to compute frame size */
8641
54e2916c25a5 Avoid allocating MPADecodeContext on stack.
andoma
parents: 8629
diff changeset
147 if (ff_mpegaudio_decode_header((MPADecodeHeader *)s, header) == 1) {
2979
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
148 s->frame_size = -1;
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
149 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
150 #endif
8420
2b0d01be134f Change mpeg audio parser so it only sets frame_size, channels and bit_rate
michael
parents: 5260
diff changeset
151 if(s->header_count > 1){
5260
mru
parents: 5259
diff changeset
152 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
153 avctx->channels = channels;
2b0d01be134f Change mpeg audio parser so it only sets frame_size, channels and bit_rate
michael
parents: 5260
diff changeset
154 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
155 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
156 }
5259
3f48ee403351 set sample rate in more logical place, kill warning
mru
parents: 5089
diff changeset
157 }
2979
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
158 }
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2864
diff changeset
159 } else
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
160 #if 0
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
161 if (s->frame_size == -1) {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
162 /* free format : find next sync to compute frame size */
2979
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
163 len = MPA_MAX_CODED_FRAME_SIZE - len;
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
164 if (len > buf_size)
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
165 len = buf_size;
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
166 if (len == 0) {
2979
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
167 /* frame too long: resync */
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
168 s->frame_size = 0;
2979
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
169 memmove(s->inbuf, s->inbuf + 1, s->inbuf_ptr - s->inbuf - 1);
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
170 s->inbuf_ptr--;
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
171 } else {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
172 uint8_t *p, *pend;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
173 uint32_t header1;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
174 int padding;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
175
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
176 memcpy(s->inbuf_ptr, buf_ptr, len);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
177 /* check for header */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
178 p = s->inbuf_ptr - 3;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
179 pend = s->inbuf_ptr + len - 4;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
180 while (p <= pend) {
5089
bff60ecc02f9 Use AV_xx throughout libavcodec
ramiro
parents: 5051
diff changeset
181 header = AV_RB32(p);
bff60ecc02f9 Use AV_xx throughout libavcodec
ramiro
parents: 5051
diff changeset
182 header1 = AV_RB32(s->inbuf);
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
183 /* check with high probability that we have a
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
184 valid header */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
185 if ((header & SAME_HEADER_MASK) ==
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
186 (header1 & SAME_HEADER_MASK)) {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
187 /* header found: update pointers */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
188 len = (p + 4) - s->inbuf_ptr;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
189 buf_ptr += len;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
190 buf_size -= len;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
191 s->inbuf_ptr = p;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
192 /* compute frame size */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
193 s->free_format_next_header = header;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
194 s->free_format_frame_size = s->inbuf_ptr - s->inbuf;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
195 padding = (header1 >> 9) & 1;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
196 if (s->layer == 1)
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
197 s->free_format_frame_size -= padding * 4;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
198 else
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
199 s->free_format_frame_size -= padding;
4652
6679d37a3338 Give context to dprintf
mbardiaux
parents: 4648
diff changeset
200 dprintf(avctx, "free frame size=%d padding=%d\n",
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
201 s->free_format_frame_size, padding);
8641
54e2916c25a5 Avoid allocating MPADecodeContext on stack.
andoma
parents: 8629
diff changeset
202 ff_mpegaudio_decode_header((MPADecodeHeader *)s, header1);
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
203 goto next_data;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
204 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
205 p++;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
206 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
207 /* not found: simply increase pointers */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
208 buf_ptr += len;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
209 s->inbuf_ptr += len;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
210 buf_size -= len;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
211 }
2979
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
212 } else
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
213 #endif
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
214 if (len < s->frame_size) {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
215 if (s->frame_size > MPA_MAX_CODED_FRAME_SIZE)
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
216 s->frame_size = MPA_MAX_CODED_FRAME_SIZE;
3639
949bc256f1e3 dont copy frame if the whole mp1/2/3 frame is available in one piece in the input
michael
parents: 3456
diff changeset
217 len = FFMIN(s->frame_size - len, buf_size);
2979
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
218 memcpy(s->inbuf_ptr, buf_ptr, len);
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
219 buf_ptr += len;
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
220 s->inbuf_ptr += len;
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
221 buf_size -= len;
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
222 }
3639
949bc256f1e3 dont copy frame if the whole mp1/2/3 frame is available in one piece in the input
michael
parents: 3456
diff changeset
223
949bc256f1e3 dont copy frame if the whole mp1/2/3 frame is available in one piece in the input
michael
parents: 3456
diff changeset
224 if(s->frame_size > 0 && buf_ptr - buf == s->inbuf_ptr - s->inbuf
949bc256f1e3 dont copy frame if the whole mp1/2/3 frame is available in one piece in the input
michael
parents: 3456
diff changeset
225 && buf_size + buf_ptr - buf >= s->frame_size){
949bc256f1e3 dont copy frame if the whole mp1/2/3 frame is available in one piece in the input
michael
parents: 3456
diff changeset
226 if(s->header_count > 0){
4931
0d1cc37d9430 make some parser parameters const to avoid casting const to non-const
aurel
parents: 4914
diff changeset
227 *poutbuf = buf;
3639
949bc256f1e3 dont copy frame if the whole mp1/2/3 frame is available in one piece in the input
michael
parents: 3456
diff changeset
228 *poutbuf_size = s->frame_size;
949bc256f1e3 dont copy frame if the whole mp1/2/3 frame is available in one piece in the input
michael
parents: 3456
diff changeset
229 }
949bc256f1e3 dont copy frame if the whole mp1/2/3 frame is available in one piece in the input
michael
parents: 3456
diff changeset
230 buf_ptr = buf + s->frame_size;
949bc256f1e3 dont copy frame if the whole mp1/2/3 frame is available in one piece in the input
michael
parents: 3456
diff changeset
231 s->inbuf_ptr = s->inbuf;
949bc256f1e3 dont copy frame if the whole mp1/2/3 frame is available in one piece in the input
michael
parents: 3456
diff changeset
232 s->frame_size = 0;
949bc256f1e3 dont copy frame if the whole mp1/2/3 frame is available in one piece in the input
michael
parents: 3456
diff changeset
233 break;
949bc256f1e3 dont copy frame if the whole mp1/2/3 frame is available in one piece in the input
michael
parents: 3456
diff changeset
234 }
949bc256f1e3 dont copy frame if the whole mp1/2/3 frame is available in one piece in the input
michael
parents: 3456
diff changeset
235
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
236 // next_data:
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2864
diff changeset
237 if (s->frame_size > 0 &&
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
238 (s->inbuf_ptr - s->inbuf) >= s->frame_size) {
2470
06aafb585f69 require a few valid and equal mp3 headers for resync
michael
parents: 2389
diff changeset
239 if(s->header_count > 0){
06aafb585f69 require a few valid and equal mp3 headers for resync
michael
parents: 2389
diff changeset
240 *poutbuf = s->inbuf;
06aafb585f69 require a few valid and equal mp3 headers for resync
michael
parents: 2389
diff changeset
241 *poutbuf_size = s->inbuf_ptr - s->inbuf;
06aafb585f69 require a few valid and equal mp3 headers for resync
michael
parents: 2389
diff changeset
242 }
2979
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
243 s->inbuf_ptr = s->inbuf;
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
244 s->frame_size = 0;
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
245 break;
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
246 }
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
247 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
248 return buf_ptr - buf;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
249 }
4397
acb9faabab8d Allows the AC3 parser to read the frame size and codec parameters from E-AC3 streams,
gpoirier
parents: 4310
diff changeset
250
acb9faabab8d Allows the AC3 parser to read the frame size and codec parameters from E-AC3 streams,
gpoirier
parents: 4310
diff changeset
251
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
252 AVCodecParser mpegaudio_parser = {
8586
d7d0cde5f308 Add dummy mp1_decoder to complement the existing dummy mp2/mp3 decoders.
michael
parents: 8420
diff changeset
253 { CODEC_ID_MP1, CODEC_ID_MP2, CODEC_ID_MP3 },
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
254 sizeof(MpegAudioParseContext),
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
255 mpegaudio_parse_init,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
256 mpegaudio_parse,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
257 NULL,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
258 };