Mercurial > libavcodec.hg
annotate parser.c @ 4301:b43bd0c56eaa libavcodec
Bug fix for crashes when SSE is used on unaligned arrays.
No measureable change in speed. This gave random crashes on Win32
and BeOS. The cause for this bug is that gcc doesn't align the
stackframe. Linux and glibc always ensure this to be true thus
this never affected Linux.
| author | banan |
|---|---|
| date | Thu, 14 Dec 2006 17:50:23 +0000 |
| parents | 127d84a4c8e0 |
| children | a0c0c7bebd64 |
| rev | line source |
|---|---|
| 1613 | 1 /* |
| 2 * Audio and Video frame extraction | |
| 3 * Copyright (c) 2003 Fabrice Bellard. | |
| 4 * Copyright (c) 2003 Michael Niedermayer. | |
| 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 */ |
| 22 #include "avcodec.h" | |
| 23 #include "mpegvideo.h" | |
| 24 #include "mpegaudio.h" | |
|
4150
2205aefb22b7
move AVCodecParser prototypes and definitions to parser.h, and move mpegvideo parser to mpeg12.c
bcoudurier
parents:
4146
diff
changeset
|
25 #include "parser.h" |
| 1613 | 26 |
| 27 AVCodecParser *av_first_parser = NULL; | |
| 28 | |
| 29 void av_register_codec_parser(AVCodecParser *parser) | |
| 30 { | |
| 31 parser->next = av_first_parser; | |
| 32 av_first_parser = parser; | |
| 33 } | |
| 34 | |
| 35 AVCodecParserContext *av_parser_init(int codec_id) | |
| 36 { | |
| 37 AVCodecParserContext *s; | |
| 38 AVCodecParser *parser; | |
| 39 int ret; | |
| 2967 | 40 |
|
2486
f2a9559db6ac
10l (array gets padded with 0 which is CODEC_ID_NONE -> parsers claim to support CODEC_ID_NONE)
michael
parents:
2480
diff
changeset
|
41 if(codec_id == CODEC_ID_NONE) |
|
f2a9559db6ac
10l (array gets padded with 0 which is CODEC_ID_NONE -> parsers claim to support CODEC_ID_NONE)
michael
parents:
2480
diff
changeset
|
42 return NULL; |
| 1613 | 43 |
| 44 for(parser = av_first_parser; parser != NULL; parser = parser->next) { | |
| 45 if (parser->codec_ids[0] == codec_id || | |
| 46 parser->codec_ids[1] == codec_id || | |
| 2348 | 47 parser->codec_ids[2] == codec_id || |
| 48 parser->codec_ids[3] == codec_id || | |
| 49 parser->codec_ids[4] == codec_id) | |
| 1613 | 50 goto found; |
| 51 } | |
| 52 return NULL; | |
| 53 found: | |
| 54 s = av_mallocz(sizeof(AVCodecParserContext)); | |
| 55 if (!s) | |
| 56 return NULL; | |
| 57 s->parser = parser; | |
| 58 s->priv_data = av_mallocz(parser->priv_data_size); | |
| 59 if (!s->priv_data) { | |
| 60 av_free(s); | |
| 61 return NULL; | |
| 62 } | |
| 63 if (parser->parser_init) { | |
| 64 ret = parser->parser_init(s); | |
| 65 if (ret != 0) { | |
| 66 av_free(s->priv_data); | |
| 67 av_free(s); | |
| 68 return NULL; | |
| 69 } | |
| 70 } | |
| 2030 | 71 s->fetch_timestamp=1; |
| 1613 | 72 return s; |
| 73 } | |
| 74 | |
| 3989 | 75 /** |
| 76 * | |
| 77 * @param buf input | |
| 78 * @param buf_size input length, to signal EOF, this should be 0 (so that the last frame can be output) | |
| 79 * @param pts input presentation timestamp | |
| 80 * @param dts input decoding timestamp | |
| 81 * @param poutbuf will contain a pointer to the first byte of the output frame | |
| 82 * @param poutbuf_size will contain the length of the output frame | |
| 83 * @return the number of bytes of the input bitstream used | |
| 84 * | |
| 85 * Example: | |
| 86 * @code | |
| 87 * while(in_len){ | |
| 88 * len = av_parser_parse(myparser, AVCodecContext, &data, &size, | |
| 89 * in_data, in_len, | |
| 90 * pts, dts); | |
| 91 * in_data += len; | |
| 92 * in_len -= len; | |
| 93 * | |
| 94 * decode_frame(data, size); | |
| 95 * } | |
| 96 * @endcode | |
| 97 */ | |
| 2967 | 98 int av_parser_parse(AVCodecParserContext *s, |
| 1613 | 99 AVCodecContext *avctx, |
| 2967 | 100 uint8_t **poutbuf, int *poutbuf_size, |
| 1696 | 101 const uint8_t *buf, int buf_size, |
| 102 int64_t pts, int64_t dts) | |
| 1613 | 103 { |
| 1696 | 104 int index, i, k; |
|
1694
13169235c306
added End Of File handling to return last picture for MPEG1/2/4
bellard
parents:
1681
diff
changeset
|
105 uint8_t dummy_buf[FF_INPUT_BUFFER_PADDING_SIZE]; |
| 2967 | 106 |
|
1694
13169235c306
added End Of File handling to return last picture for MPEG1/2/4
bellard
parents:
1681
diff
changeset
|
107 if (buf_size == 0) { |
|
13169235c306
added End Of File handling to return last picture for MPEG1/2/4
bellard
parents:
1681
diff
changeset
|
108 /* padding is always necessary even if EOF, so we add it here */ |
|
13169235c306
added End Of File handling to return last picture for MPEG1/2/4
bellard
parents:
1681
diff
changeset
|
109 memset(dummy_buf, 0, sizeof(dummy_buf)); |
|
13169235c306
added End Of File handling to return last picture for MPEG1/2/4
bellard
parents:
1681
diff
changeset
|
110 buf = dummy_buf; |
| 1696 | 111 } else { |
| 112 /* add a new packet descriptor */ | |
| 113 k = (s->cur_frame_start_index + 1) & (AV_PARSER_PTS_NB - 1); | |
| 114 s->cur_frame_start_index = k; | |
| 115 s->cur_frame_offset[k] = s->cur_offset; | |
| 116 s->cur_frame_pts[k] = pts; | |
| 117 s->cur_frame_dts[k] = dts; | |
| 118 | |
| 119 /* fill first PTS/DTS */ | |
| 2030 | 120 if (s->fetch_timestamp){ |
| 121 s->fetch_timestamp=0; | |
| 1696 | 122 s->last_pts = pts; |
| 123 s->last_dts = dts; | |
| 2107 | 124 s->cur_frame_pts[k] = |
| 125 s->cur_frame_dts[k] = AV_NOPTS_VALUE; | |
| 1696 | 126 } |
|
1694
13169235c306
added End Of File handling to return last picture for MPEG1/2/4
bellard
parents:
1681
diff
changeset
|
127 } |
|
13169235c306
added End Of File handling to return last picture for MPEG1/2/4
bellard
parents:
1681
diff
changeset
|
128 |
| 1613 | 129 /* WARNING: the returned index can be negative */ |
| 130 index = s->parser->parser_parse(s, avctx, poutbuf, poutbuf_size, buf, buf_size); | |
|
4122
daae66c03857
Replace most of the %lld and %llx by their (cleaner) PRI*64 counterparts.
diego
parents:
4104
diff
changeset
|
131 //av_log(NULL, AV_LOG_DEBUG, "parser: in:%"PRId64", %"PRId64", out:%"PRId64", %"PRId64", in:%d out:%d id:%d\n", pts, dts, s->last_pts, s->last_dts, buf_size, *poutbuf_size, avctx->codec_id); |
| 1613 | 132 /* update the file pointer */ |
| 133 if (*poutbuf_size) { | |
| 1696 | 134 /* fill the data for the current frame */ |
| 1613 | 135 s->frame_offset = s->last_frame_offset; |
| 1696 | 136 s->pts = s->last_pts; |
| 137 s->dts = s->last_dts; | |
| 2967 | 138 |
| 1696 | 139 /* offset of the next frame */ |
| 1613 | 140 s->last_frame_offset = s->cur_offset + index; |
| 1696 | 141 /* find the packet in which the new frame starts. It |
| 142 is tricky because of MPEG video start codes | |
| 143 which can begin in one packet and finish in | |
| 144 another packet. In the worst case, an MPEG | |
| 145 video start code could be in 4 different | |
| 146 packets. */ | |
| 147 k = s->cur_frame_start_index; | |
| 148 for(i = 0; i < AV_PARSER_PTS_NB; i++) { | |
| 149 if (s->last_frame_offset >= s->cur_frame_offset[k]) | |
| 150 break; | |
| 151 k = (k - 1) & (AV_PARSER_PTS_NB - 1); | |
| 152 } | |
| 2030 | 153 |
| 1696 | 154 s->last_pts = s->cur_frame_pts[k]; |
| 155 s->last_dts = s->cur_frame_dts[k]; | |
| 2967 | 156 |
| 2030 | 157 /* some parsers tell us the packet size even before seeing the first byte of the next packet, |
| 158 so the next pts/dts is in the next chunk */ | |
| 159 if(index == buf_size){ | |
| 160 s->fetch_timestamp=1; | |
| 161 } | |
| 1613 | 162 } |
| 163 if (index < 0) | |
| 164 index = 0; | |
| 165 s->cur_offset += index; | |
| 166 return index; | |
| 167 } | |
| 168 | |
| 2777 | 169 /** |
| 170 * | |
| 171 * @return 0 if the output buffer is a subset of the input, 1 if it is allocated and must be freed | |
|
3421
b7826511f7b6
AVBitStreamFilter (some thingy which can modify the bitstream like add or remove global headers or change the headers or ...)
michael
parents:
3395
diff
changeset
|
172 * @deprecated use AVBitstreamFilter |
| 2777 | 173 */ |
|
2769
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
174 int av_parser_change(AVCodecParserContext *s, |
|
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
175 AVCodecContext *avctx, |
| 2967 | 176 uint8_t **poutbuf, int *poutbuf_size, |
|
2769
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
177 const uint8_t *buf, int buf_size, int keyframe){ |
| 2967 | 178 |
|
2769
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
179 if(s && s->parser->split){ |
| 2777 | 180 if((avctx->flags & CODEC_FLAG_GLOBAL_HEADER) || (avctx->flags2 & CODEC_FLAG2_LOCAL_HEADER)){ |
|
2769
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
181 int i= s->parser->split(avctx, buf, buf_size); |
|
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
182 buf += i; |
|
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
183 buf_size -= i; |
|
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
184 } |
|
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
185 } |
|
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
186 |
|
2864
95bac7109ff0
Kill some compiler warnings. Compiled code verified identical after changes.
mru
parents:
2846
diff
changeset
|
187 /* cast to avoid warning about discarding qualifiers */ |
|
95bac7109ff0
Kill some compiler warnings. Compiled code verified identical after changes.
mru
parents:
2846
diff
changeset
|
188 *poutbuf= (uint8_t *) buf; |
|
2769
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
189 *poutbuf_size= buf_size; |
|
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
190 if(avctx->extradata){ |
|
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
191 if( (keyframe && (avctx->flags2 & CODEC_FLAG2_LOCAL_HEADER)) |
|
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
192 /*||(s->pict_type != I_TYPE && (s->flags & PARSER_FLAG_DUMP_EXTRADATA_AT_NOKEY))*/ |
|
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
193 /*||(? && (s->flags & PARSER_FLAG_DUMP_EXTRADATA_AT_BEGIN)*/){ |
|
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
194 int size= buf_size + avctx->extradata_size; |
|
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
195 *poutbuf_size= size; |
|
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
196 *poutbuf= av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE); |
| 2967 | 197 |
|
2769
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
198 memcpy(*poutbuf, avctx->extradata, avctx->extradata_size); |
| 2777 | 199 memcpy((*poutbuf) + avctx->extradata_size, buf, buf_size + FF_INPUT_BUFFER_PADDING_SIZE); |
|
2769
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
200 return 1; |
|
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
201 } |
|
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
202 } |
|
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
203 |
|
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
204 return 0; |
|
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
205 } |
|
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
206 |
| 1613 | 207 void av_parser_close(AVCodecParserContext *s) |
| 208 { | |
| 209 if (s->parser->parser_close) | |
| 210 s->parser->parser_close(s); | |
| 211 av_free(s->priv_data); | |
| 212 av_free(s); | |
| 213 } | |
| 214 | |
| 215 /*****************************************************/ | |
| 216 | |
| 217 /** | |
| 218 * combines the (truncated) bitstream to a complete frame | |
| 219 * @returns -1 if no complete frame could be created | |
| 220 */ | |
| 1988 | 221 int ff_combine_frame(ParseContext *pc, int next, uint8_t **buf, int *buf_size) |
| 1613 | 222 { |
| 223 #if 0 | |
| 224 if(pc->overread){ | |
| 225 printf("overread %d, state:%X next:%d index:%d o_index:%d\n", pc->overread, pc->state, next, pc->index, pc->overread_index); | |
| 226 printf("%X %X %X %X\n", (*buf)[0], (*buf)[1],(*buf)[2],(*buf)[3]); | |
| 227 } | |
| 228 #endif | |
| 229 | |
| 230 /* copy overreaded bytes from last frame into buffer */ | |
| 231 for(; pc->overread>0; pc->overread--){ | |
| 232 pc->buffer[pc->index++]= pc->buffer[pc->overread_index++]; | |
| 233 } | |
| 2386 | 234 |
| 235 /* flush remaining if EOF */ | |
| 236 if(!*buf_size && next == END_NOT_FOUND){ | |
| 237 next= 0; | |
| 238 } | |
| 239 | |
| 1613 | 240 pc->last_index= pc->index; |
| 241 | |
| 242 /* copy into buffer end return */ | |
| 243 if(next == END_NOT_FOUND){ | |
| 244 pc->buffer= av_fast_realloc(pc->buffer, &pc->buffer_size, (*buf_size) + pc->index + FF_INPUT_BUFFER_PADDING_SIZE); | |
| 245 | |
| 246 memcpy(&pc->buffer[pc->index], *buf, *buf_size); | |
| 247 pc->index += *buf_size; | |
| 248 return -1; | |
| 249 } | |
| 250 | |
| 251 *buf_size= | |
| 252 pc->overread_index= pc->index + next; | |
| 2967 | 253 |
| 1613 | 254 /* append to buffer */ |
| 255 if(pc->index){ | |
| 256 pc->buffer= av_fast_realloc(pc->buffer, &pc->buffer_size, next + pc->index + FF_INPUT_BUFFER_PADDING_SIZE); | |
| 257 | |
| 258 memcpy(&pc->buffer[pc->index], *buf, next + FF_INPUT_BUFFER_PADDING_SIZE ); | |
| 259 pc->index = 0; | |
| 260 *buf= pc->buffer; | |
| 261 } | |
| 262 | |
| 263 /* store overread bytes */ | |
| 264 for(;next < 0; next++){ | |
| 265 pc->state = (pc->state<<8) | pc->buffer[pc->last_index + next]; | |
| 266 pc->overread++; | |
| 267 } | |
| 268 | |
| 269 #if 0 | |
| 270 if(pc->overread){ | |
| 271 printf("overread %d, state:%X next:%d index:%d o_index:%d\n", pc->overread, pc->state, next, pc->index, pc->overread_index); | |
| 272 printf("%X %X %X %X\n", (*buf)[0], (*buf)[1],(*buf)[2],(*buf)[3]); | |
| 273 } | |
| 274 #endif | |
| 275 | |
| 276 return 0; | |
| 277 } | |
| 278 | |
| 1988 | 279 void ff_parse_close(AVCodecParserContext *s) |
| 1613 | 280 { |
| 1988 | 281 ParseContext *pc = s->priv_data; |
| 1613 | 282 |
| 283 av_free(pc->buffer); | |
| 1988 | 284 } |
| 285 | |
|
4150
2205aefb22b7
move AVCodecParser prototypes and definitions to parser.h, and move mpegvideo parser to mpeg12.c
bcoudurier
parents:
4146
diff
changeset
|
286 void ff_parse1_close(AVCodecParserContext *s) |
| 1988 | 287 { |
| 288 ParseContext1 *pc1 = s->priv_data; | |
| 289 | |
| 290 av_free(pc1->pc.buffer); | |
| 291 av_free(pc1->enc); | |
| 1613 | 292 } |
| 293 | |
| 294 /*************************/ | |
| 295 | |
|
3455
cc4b4ea83e29
--enable/disable parsers. Warning: some combinations are broken.
mru
parents:
3432
diff
changeset
|
296 #ifdef CONFIG_MPEG4VIDEO_PARSER |
| 1613 | 297 /* used by parser */ |
| 298 /* XXX: make it use less memory */ | |
| 2967 | 299 static int av_mpeg4_decode_header(AVCodecParserContext *s1, |
| 1613 | 300 AVCodecContext *avctx, |
| 301 const uint8_t *buf, int buf_size) | |
| 302 { | |
| 303 ParseContext1 *pc = s1->priv_data; | |
| 304 MpegEncContext *s = pc->enc; | |
| 305 GetBitContext gb1, *gb = &gb1; | |
| 306 int ret; | |
| 307 | |
| 308 s->avctx = avctx; | |
| 1614 | 309 s->current_picture_ptr = &s->current_picture; |
| 310 | |
| 311 if (avctx->extradata_size && pc->first_picture){ | |
| 312 init_get_bits(gb, avctx->extradata, avctx->extradata_size*8); | |
| 313 ret = ff_mpeg4_decode_picture_header(s, gb); | |
| 314 } | |
| 315 | |
| 1613 | 316 init_get_bits(gb, buf, 8 * buf_size); |
| 317 ret = ff_mpeg4_decode_picture_header(s, gb); | |
| 318 if (s->width) { | |
| 2270 | 319 avcodec_set_dimensions(avctx, s->width, s->height); |
| 1613 | 320 } |
| 2837 | 321 s1->pict_type= s->pict_type; |
| 1614 | 322 pc->first_picture = 0; |
| 1613 | 323 return ret; |
| 324 } | |
| 325 | |
|
2024
f65d87bfdd5a
some of the warning fixes by (Michael Roitzsch <mroi at users dot sourceforge dot net>)
michael
parents:
1988
diff
changeset
|
326 static int mpeg4video_parse_init(AVCodecParserContext *s) |
| 1613 | 327 { |
| 328 ParseContext1 *pc = s->priv_data; | |
| 1614 | 329 |
| 1613 | 330 pc->enc = av_mallocz(sizeof(MpegEncContext)); |
| 331 if (!pc->enc) | |
| 332 return -1; | |
| 1614 | 333 pc->first_picture = 1; |
| 1613 | 334 return 0; |
| 335 } | |
| 336 | |
| 337 static int mpeg4video_parse(AVCodecParserContext *s, | |
| 338 AVCodecContext *avctx, | |
| 2967 | 339 uint8_t **poutbuf, int *poutbuf_size, |
| 1613 | 340 const uint8_t *buf, int buf_size) |
| 341 { | |
| 1988 | 342 ParseContext *pc = s->priv_data; |
| 1613 | 343 int next; |
| 2967 | 344 |
| 2837 | 345 if(s->flags & PARSER_FLAG_COMPLETE_FRAMES){ |
| 346 next= buf_size; | |
| 347 }else{ | |
| 348 next= ff_mpeg4_find_frame_end(pc, buf, buf_size); | |
| 2967 | 349 |
| 2837 | 350 if (ff_combine_frame(pc, next, (uint8_t **)&buf, &buf_size) < 0) { |
| 351 *poutbuf = NULL; | |
| 352 *poutbuf_size = 0; | |
| 353 return buf_size; | |
| 354 } | |
| 1613 | 355 } |
| 356 av_mpeg4_decode_header(s, avctx, buf, buf_size); | |
| 357 | |
| 358 *poutbuf = (uint8_t *)buf; | |
| 359 *poutbuf_size = buf_size; | |
| 360 return next; | |
| 361 } | |
|
3455
cc4b4ea83e29
--enable/disable parsers. Warning: some combinations are broken.
mru
parents:
3432
diff
changeset
|
362 #endif |
| 1613 | 363 |
|
4175
b3328ed50a5e
make mpeg4video_split public as ff_mpeg4video_split
stefang
parents:
4150
diff
changeset
|
364 int ff_mpeg4video_split(AVCodecContext *avctx, |
|
2769
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
365 const uint8_t *buf, int buf_size) |
|
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
366 { |
|
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
367 int i; |
|
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
368 uint32_t state= -1; |
| 2967 | 369 |
|
2769
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
370 for(i=0; i<buf_size; i++){ |
|
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
371 state= (state<<8) | buf[i]; |
|
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
372 if(state == 0x1B3 || state == 0x1B6) |
| 2777 | 373 return i-3; |
|
2769
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
374 } |
|
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
375 return 0; |
|
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
376 } |
|
1394b45a7bf4
support changing in bitstream global headers into extradata style and back
michael
parents:
2637
diff
changeset
|
377 |
| 1613 | 378 /*************************/ |
| 379 | |
|
3455
cc4b4ea83e29
--enable/disable parsers. Warning: some combinations are broken.
mru
parents:
3432
diff
changeset
|
380 #ifdef CONFIG_MPEGAUDIO_PARSER |
| 1613 | 381 typedef struct MpegAudioParseContext { |
| 2979 | 382 uint8_t inbuf[MPA_MAX_CODED_FRAME_SIZE]; /* input buffer */ |
| 1613 | 383 uint8_t *inbuf_ptr; |
| 384 int frame_size; | |
| 385 int free_format_frame_size; | |
| 386 int free_format_next_header; | |
|
2470
06aafb585f69
require a few valid and equal mp3 headers for resync
michael
parents:
2389
diff
changeset
|
387 uint32_t header; |
|
06aafb585f69
require a few valid and equal mp3 headers for resync
michael
parents:
2389
diff
changeset
|
388 int header_count; |
| 1613 | 389 } MpegAudioParseContext; |
| 390 | |
| 391 #define MPA_HEADER_SIZE 4 | |
| 392 | |
| 393 /* header + layer + bitrate + freq + lsf/mpeg25 */ | |
|
2522
e25782262d7d
kill warnings patch by (M?ns Rullg?rd <mru inprovide com>)
michael
parents:
2486
diff
changeset
|
394 #undef SAME_HEADER_MASK /* mpegaudio.h defines different version */ |
| 1613 | 395 #define SAME_HEADER_MASK \ |
| 2480 | 396 (0xffe00000 | (3 << 17) | (3 << 10) | (3 << 19)) |
| 1613 | 397 |
| 398 static int mpegaudio_parse_init(AVCodecParserContext *s1) | |
| 399 { | |
| 400 MpegAudioParseContext *s = s1->priv_data; | |
| 401 s->inbuf_ptr = s->inbuf; | |
| 402 return 0; | |
| 403 } | |
| 404 | |
| 405 static int mpegaudio_parse(AVCodecParserContext *s1, | |
| 406 AVCodecContext *avctx, | |
| 2967 | 407 uint8_t **poutbuf, int *poutbuf_size, |
| 1613 | 408 const uint8_t *buf, int buf_size) |
| 409 { | |
| 410 MpegAudioParseContext *s = s1->priv_data; | |
|
2470
06aafb585f69
require a few valid and equal mp3 headers for resync
michael
parents:
2389
diff
changeset
|
411 int len, ret, sr; |
| 1613 | 412 uint32_t header; |
| 413 const uint8_t *buf_ptr; | |
| 414 | |
| 415 *poutbuf = NULL; | |
| 416 *poutbuf_size = 0; | |
| 417 buf_ptr = buf; | |
| 418 while (buf_size > 0) { | |
| 2979 | 419 len = s->inbuf_ptr - s->inbuf; |
| 420 if (s->frame_size == 0) { | |
| 1613 | 421 /* special case for next header for first frame in free |
| 422 format case (XXX: find a simpler method) */ | |
| 423 if (s->free_format_next_header != 0) { | |
| 424 s->inbuf[0] = s->free_format_next_header >> 24; | |
| 425 s->inbuf[1] = s->free_format_next_header >> 16; | |
| 426 s->inbuf[2] = s->free_format_next_header >> 8; | |
| 427 s->inbuf[3] = s->free_format_next_header; | |
| 428 s->inbuf_ptr = s->inbuf + 4; | |
| 429 s->free_format_next_header = 0; | |
| 430 goto got_header; | |
| 431 } | |
| 2979 | 432 /* no header seen : find one. We need at least MPA_HEADER_SIZE |
| 1613 | 433 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
|
434 len = FFMIN(MPA_HEADER_SIZE - len, buf_size); |
| 2979 | 435 if (len > 0) { |
| 436 memcpy(s->inbuf_ptr, buf_ptr, len); | |
| 437 buf_ptr += len; | |
| 438 buf_size -= len; | |
| 439 s->inbuf_ptr += len; | |
| 440 } | |
| 441 if ((s->inbuf_ptr - s->inbuf) >= MPA_HEADER_SIZE) { | |
| 1613 | 442 got_header: |
| 2979 | 443 header = (s->inbuf[0] << 24) | (s->inbuf[1] << 16) | |
| 444 (s->inbuf[2] << 8) | s->inbuf[3]; | |
| 1613 | 445 |
|
4104
04ff8026d9c0
dont set the sampling rate just because 1 mp3 packet header says so (fixes playback speed on some old mencoder generated avis which where then dumped to mp3)
michael
parents:
3989
diff
changeset
|
446 ret = mpa_decode_header(avctx, header, &sr); |
| 1613 | 447 if (ret < 0) { |
|
2470
06aafb585f69
require a few valid and equal mp3 headers for resync
michael
parents:
2389
diff
changeset
|
448 s->header_count= -2; |
| 2979 | 449 /* no sync found : move by one byte (inefficient, but simple!) */ |
| 450 memmove(s->inbuf, s->inbuf + 1, s->inbuf_ptr - s->inbuf - 1); | |
| 451 s->inbuf_ptr--; | |
| 1613 | 452 dprintf("skip %x\n", header); |
| 453 /* reset free format frame size to give a chance | |
| 454 to get a new bitrate */ | |
| 455 s->free_format_frame_size = 0; | |
| 2979 | 456 } else { |
|
2470
06aafb585f69
require a few valid and equal mp3 headers for resync
michael
parents:
2389
diff
changeset
|
457 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
|
458 s->header_count= -3; |
|
06aafb585f69
require a few valid and equal mp3 headers for resync
michael
parents:
2389
diff
changeset
|
459 s->header= header; |
|
06aafb585f69
require a few valid and equal mp3 headers for resync
michael
parents:
2389
diff
changeset
|
460 s->header_count++; |
| 1613 | 461 s->frame_size = ret; |
| 2967 | 462 |
| 1613 | 463 #if 0 |
| 464 /* free format: prepare to compute frame size */ | |
| 2979 | 465 if (decode_header(s, header) == 1) { |
| 466 s->frame_size = -1; | |
| 1613 | 467 } |
| 468 #endif | |
| 2979 | 469 } |
|
4104
04ff8026d9c0
dont set the sampling rate just because 1 mp3 packet header says so (fixes playback speed on some old mencoder generated avis which where then dumped to mp3)
michael
parents:
3989
diff
changeset
|
470 if(s->header_count > 1) |
|
04ff8026d9c0
dont set the sampling rate just because 1 mp3 packet header says so (fixes playback speed on some old mencoder generated avis which where then dumped to mp3)
michael
parents:
3989
diff
changeset
|
471 avctx->sample_rate= sr; |
| 2979 | 472 } |
| 2967 | 473 } else |
| 1613 | 474 #if 0 |
| 475 if (s->frame_size == -1) { | |
| 476 /* free format : find next sync to compute frame size */ | |
| 2979 | 477 len = MPA_MAX_CODED_FRAME_SIZE - len; |
| 478 if (len > buf_size) | |
| 479 len = buf_size; | |
| 1613 | 480 if (len == 0) { |
| 2979 | 481 /* frame too long: resync */ |
| 1613 | 482 s->frame_size = 0; |
| 2979 | 483 memmove(s->inbuf, s->inbuf + 1, s->inbuf_ptr - s->inbuf - 1); |
| 484 s->inbuf_ptr--; | |
| 1613 | 485 } else { |
| 486 uint8_t *p, *pend; | |
| 487 uint32_t header1; | |
| 488 int padding; | |
| 489 | |
| 490 memcpy(s->inbuf_ptr, buf_ptr, len); | |
| 491 /* check for header */ | |
| 492 p = s->inbuf_ptr - 3; | |
| 493 pend = s->inbuf_ptr + len - 4; | |
| 494 while (p <= pend) { | |
| 495 header = (p[0] << 24) | (p[1] << 16) | | |
| 496 (p[2] << 8) | p[3]; | |
| 497 header1 = (s->inbuf[0] << 24) | (s->inbuf[1] << 16) | | |
| 498 (s->inbuf[2] << 8) | s->inbuf[3]; | |
| 499 /* check with high probability that we have a | |
| 500 valid header */ | |
| 501 if ((header & SAME_HEADER_MASK) == | |
| 502 (header1 & SAME_HEADER_MASK)) { | |
| 503 /* header found: update pointers */ | |
| 504 len = (p + 4) - s->inbuf_ptr; | |
| 505 buf_ptr += len; | |
| 506 buf_size -= len; | |
| 507 s->inbuf_ptr = p; | |
| 508 /* compute frame size */ | |
| 509 s->free_format_next_header = header; | |
| 510 s->free_format_frame_size = s->inbuf_ptr - s->inbuf; | |
| 511 padding = (header1 >> 9) & 1; | |
| 512 if (s->layer == 1) | |
| 513 s->free_format_frame_size -= padding * 4; | |
| 514 else | |
| 515 s->free_format_frame_size -= padding; | |
| 2967 | 516 dprintf("free frame size=%d padding=%d\n", |
| 1613 | 517 s->free_format_frame_size, padding); |
| 518 decode_header(s, header1); | |
| 519 goto next_data; | |
| 520 } | |
| 521 p++; | |
| 522 } | |
| 523 /* not found: simply increase pointers */ | |
| 524 buf_ptr += len; | |
| 525 s->inbuf_ptr += len; | |
| 526 buf_size -= len; | |
| 527 } | |
| 2979 | 528 } else |
| 1613 | 529 #endif |
| 530 if (len < s->frame_size) { | |
| 531 if (s->frame_size > MPA_MAX_CODED_FRAME_SIZE) | |
| 532 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
|
533 len = FFMIN(s->frame_size - len, buf_size); |
| 2979 | 534 memcpy(s->inbuf_ptr, buf_ptr, len); |
| 535 buf_ptr += len; | |
| 536 s->inbuf_ptr += len; | |
| 537 buf_size -= len; | |
| 538 } | |
|
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
|
539 |
|
949bc256f1e3
dont copy frame if the whole mp1/2/3 frame is available in one piece in the input
michael
parents:
3456
diff
changeset
|
540 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
|
541 && 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
|
542 if(s->header_count > 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
|
543 *poutbuf = buf; |
|
949bc256f1e3
dont copy frame if the whole mp1/2/3 frame is available in one piece in the input
michael
parents:
3456
diff
changeset
|
544 *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
|
545 } |
|
949bc256f1e3
dont copy frame if the whole mp1/2/3 frame is available in one piece in the input
michael
parents:
3456
diff
changeset
|
546 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
|
547 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
|
548 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
|
549 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
|
550 } |
|
949bc256f1e3
dont copy frame if the whole mp1/2/3 frame is available in one piece in the input
michael
parents:
3456
diff
changeset
|
551 |
| 1613 | 552 // next_data: |
| 2967 | 553 if (s->frame_size > 0 && |
| 1613 | 554 (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
|
555 if(s->header_count > 0){ |
|
06aafb585f69
require a few valid and equal mp3 headers for resync
michael
parents:
2389
diff
changeset
|
556 *poutbuf = s->inbuf; |
|
06aafb585f69
require a few valid and equal mp3 headers for resync
michael
parents:
2389
diff
changeset
|
557 *poutbuf_size = s->inbuf_ptr - s->inbuf; |
|
06aafb585f69
require a few valid and equal mp3 headers for resync
michael
parents:
2389
diff
changeset
|
558 } |
| 2979 | 559 s->inbuf_ptr = s->inbuf; |
| 560 s->frame_size = 0; | |
| 561 break; | |
| 562 } | |
| 1613 | 563 } |
| 564 return buf_ptr - buf; | |
| 565 } | |
|
3455
cc4b4ea83e29
--enable/disable parsers. Warning: some combinations are broken.
mru
parents:
3432
diff
changeset
|
566 #endif /* CONFIG_MPEGAUDIO_PARSER */ |
| 1613 | 567 |
|
3455
cc4b4ea83e29
--enable/disable parsers. Warning: some combinations are broken.
mru
parents:
3432
diff
changeset
|
568 #if defined(CONFIG_AC3_PARSER) || defined(CONFIG_AAC_PARSER) |
| 3098 | 569 /* also used for ADTS AAC */ |
| 1613 | 570 typedef struct AC3ParseContext { |
| 571 uint8_t *inbuf_ptr; | |
| 572 int frame_size; | |
| 3098 | 573 int header_size; |
| 574 int (*sync)(const uint8_t *buf, int *channels, int *sample_rate, | |
| 575 int *bit_rate, int *samples); | |
|
3344
f9d739057d6c
The AAC frame header uses 13 bits for the frame size, so the buffer should
mru
parents:
3104
diff
changeset
|
576 uint8_t inbuf[8192]; /* input buffer */ |
| 1613 | 577 } AC3ParseContext; |
| 578 | |
| 579 #define AC3_HEADER_SIZE 7 | |
| 3104 | 580 #define AAC_HEADER_SIZE 7 |
| 3059 | 581 |
|
3455
cc4b4ea83e29
--enable/disable parsers. Warning: some combinations are broken.
mru
parents:
3432
diff
changeset
|
582 #ifdef CONFIG_AC3_PARSER |
| 3059 | 583 static const int ac3_sample_rates[4] = { |
| 584 48000, 44100, 32000, 0 | |
| 585 }; | |
| 586 | |
| 587 static const int ac3_frame_sizes[64][3] = { | |
|
3063
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
588 { 64, 69, 96 }, |
|
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
589 { 64, 70, 96 }, |
|
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
590 { 80, 87, 120 }, |
|
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
591 { 80, 88, 120 }, |
|
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
592 { 96, 104, 144 }, |
|
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
593 { 96, 105, 144 }, |
|
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
594 { 112, 121, 168 }, |
|
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
595 { 112, 122, 168 }, |
|
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
596 { 128, 139, 192 }, |
|
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
597 { 128, 140, 192 }, |
|
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
598 { 160, 174, 240 }, |
|
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
599 { 160, 175, 240 }, |
|
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
600 { 192, 208, 288 }, |
|
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
601 { 192, 209, 288 }, |
|
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
602 { 224, 243, 336 }, |
|
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
603 { 224, 244, 336 }, |
|
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
604 { 256, 278, 384 }, |
|
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
605 { 256, 279, 384 }, |
|
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
606 { 320, 348, 480 }, |
|
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
607 { 320, 349, 480 }, |
|
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
608 { 384, 417, 576 }, |
|
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
609 { 384, 418, 576 }, |
|
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
610 { 448, 487, 672 }, |
|
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
611 { 448, 488, 672 }, |
|
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
612 { 512, 557, 768 }, |
|
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
613 { 512, 558, 768 }, |
|
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
614 { 640, 696, 960 }, |
|
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
615 { 640, 697, 960 }, |
|
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
616 { 768, 835, 1152 }, |
|
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
617 { 768, 836, 1152 }, |
|
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
618 { 896, 975, 1344 }, |
|
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
619 { 896, 976, 1344 }, |
| 3059 | 620 { 1024, 1114, 1536 }, |
| 621 { 1024, 1115, 1536 }, | |
| 622 { 1152, 1253, 1728 }, | |
| 623 { 1152, 1254, 1728 }, | |
| 624 { 1280, 1393, 1920 }, | |
| 625 { 1280, 1394, 1920 }, | |
| 626 }; | |
| 627 | |
| 628 static const int ac3_bitrates[64] = { | |
| 629 32, 32, 40, 40, 48, 48, 56, 56, 64, 64, 80, 80, 96, 96, 112, 112, | |
| 630 128, 128, 160, 160, 192, 192, 224, 224, 256, 256, 320, 320, 384, | |
| 631 384, 448, 448, 512, 512, 576, 576, 640, 640, | |
| 632 }; | |
| 633 | |
| 634 static const int ac3_channels[8] = { | |
| 635 2, 1, 2, 3, 3, 4, 4, 5 | |
| 636 }; | |
|
3455
cc4b4ea83e29
--enable/disable parsers. Warning: some combinations are broken.
mru
parents:
3432
diff
changeset
|
637 #endif /* CONFIG_AC3_PARSER */ |
| 3059 | 638 |
|
3455
cc4b4ea83e29
--enable/disable parsers. Warning: some combinations are broken.
mru
parents:
3432
diff
changeset
|
639 #ifdef CONFIG_AAC_PARSER |
| 3456 | 640 static const int aac_sample_rates[16] = { |
| 3098 | 641 96000, 88200, 64000, 48000, 44100, 32000, |
| 642 24000, 22050, 16000, 12000, 11025, 8000, 7350 | |
| 643 }; | |
| 644 | |
| 3456 | 645 static const int aac_channels[8] = { |
| 3098 | 646 0, 1, 2, 3, 4, 5, 6, 8 |
| 647 }; | |
|
3455
cc4b4ea83e29
--enable/disable parsers. Warning: some combinations are broken.
mru
parents:
3432
diff
changeset
|
648 #endif |
| 3098 | 649 |
|
3455
cc4b4ea83e29
--enable/disable parsers. Warning: some combinations are broken.
mru
parents:
3432
diff
changeset
|
650 #ifdef CONFIG_AC3_PARSER |
| 3059 | 651 static int ac3_sync(const uint8_t *buf, int *channels, int *sample_rate, |
| 3098 | 652 int *bit_rate, int *samples) |
| 3059 | 653 { |
| 654 unsigned int fscod, frmsizecod, acmod, bsid, lfeon; | |
| 655 GetBitContext bits; | |
| 656 | |
| 657 init_get_bits(&bits, buf, AC3_HEADER_SIZE * 8); | |
| 658 | |
| 659 if(get_bits(&bits, 16) != 0x0b77) | |
|
3063
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
660 return 0; |
| 3059 | 661 |
| 3104 | 662 skip_bits(&bits, 16); /* crc */ |
| 3059 | 663 fscod = get_bits(&bits, 2); |
| 664 frmsizecod = get_bits(&bits, 6); | |
| 665 | |
| 666 if(!ac3_sample_rates[fscod]) | |
|
3063
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
667 return 0; |
| 3059 | 668 |
| 669 bsid = get_bits(&bits, 5); | |
| 670 if(bsid > 8) | |
|
3063
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
671 return 0; |
| 3104 | 672 skip_bits(&bits, 3); /* bsmod */ |
| 3059 | 673 acmod = get_bits(&bits, 3); |
| 674 if(acmod & 1 && acmod != 1) | |
| 3104 | 675 skip_bits(&bits, 2); /* cmixlev */ |
| 3059 | 676 if(acmod & 4) |
| 3104 | 677 skip_bits(&bits, 2); /* surmixlev */ |
| 3059 | 678 if(acmod & 2) |
| 3104 | 679 skip_bits(&bits, 2); /* dsurmod */ |
| 680 lfeon = get_bits1(&bits); | |
| 3059 | 681 |
| 682 *sample_rate = ac3_sample_rates[fscod]; | |
| 683 *bit_rate = ac3_bitrates[frmsizecod] * 1000; | |
| 684 *channels = ac3_channels[acmod] + lfeon; | |
| 3098 | 685 *samples = 6 * 256; |
| 3059 | 686 |
| 687 return ac3_frame_sizes[frmsizecod][fscod] * 2; | |
| 688 } | |
|
3455
cc4b4ea83e29
--enable/disable parsers. Warning: some combinations are broken.
mru
parents:
3432
diff
changeset
|
689 #endif /* CONFIG_AC3_PARSER */ |
| 1613 | 690 |
|
3455
cc4b4ea83e29
--enable/disable parsers. Warning: some combinations are broken.
mru
parents:
3432
diff
changeset
|
691 #ifdef CONFIG_AAC_PARSER |
| 3098 | 692 static int aac_sync(const uint8_t *buf, int *channels, int *sample_rate, |
| 693 int *bit_rate, int *samples) | |
| 694 { | |
| 695 GetBitContext bits; | |
| 696 int size, rdb, ch, sr; | |
| 697 | |
| 698 init_get_bits(&bits, buf, AAC_HEADER_SIZE * 8); | |
| 699 | |
| 700 if(get_bits(&bits, 12) != 0xfff) | |
| 701 return 0; | |
| 702 | |
| 3104 | 703 skip_bits1(&bits); /* id */ |
| 704 skip_bits(&bits, 2); /* layer */ | |
| 705 skip_bits1(&bits); /* protection_absent */ | |
| 706 skip_bits(&bits, 2); /* profile_objecttype */ | |
| 707 sr = get_bits(&bits, 4); /* sample_frequency_index */ | |
| 3098 | 708 if(!aac_sample_rates[sr]) |
| 709 return 0; | |
| 3104 | 710 skip_bits1(&bits); /* private_bit */ |
| 711 ch = get_bits(&bits, 3); /* channel_configuration */ | |
| 3098 | 712 if(!aac_channels[ch]) |
| 713 return 0; | |
| 3104 | 714 skip_bits1(&bits); /* original/copy */ |
| 715 skip_bits1(&bits); /* home */ | |
| 3098 | 716 |
| 717 /* adts_variable_header */ | |
| 3104 | 718 skip_bits1(&bits); /* copyright_identification_bit */ |
| 719 skip_bits1(&bits); /* copyright_identification_start */ | |
| 720 size = get_bits(&bits, 13); /* aac_frame_length */ | |
| 721 skip_bits(&bits, 11); /* adts_buffer_fullness */ | |
| 722 rdb = get_bits(&bits, 2); /* number_of_raw_data_blocks_in_frame */ | |
| 3098 | 723 |
| 724 *channels = aac_channels[ch]; | |
| 725 *sample_rate = aac_sample_rates[sr]; | |
| 726 *samples = (rdb + 1) * 1024; | |
| 727 *bit_rate = size * 8 * *sample_rate / *samples; | |
| 728 | |
| 729 return size; | |
| 730 } | |
|
3455
cc4b4ea83e29
--enable/disable parsers. Warning: some combinations are broken.
mru
parents:
3432
diff
changeset
|
731 #endif /* CONFIG_AAC_PARSER */ |
| 3098 | 732 |
|
3455
cc4b4ea83e29
--enable/disable parsers. Warning: some combinations are broken.
mru
parents:
3432
diff
changeset
|
733 #ifdef CONFIG_AC3_PARSER |
| 1613 | 734 static int ac3_parse_init(AVCodecParserContext *s1) |
| 735 { | |
| 736 AC3ParseContext *s = s1->priv_data; | |
| 737 s->inbuf_ptr = s->inbuf; | |
| 3098 | 738 s->header_size = AC3_HEADER_SIZE; |
| 739 s->sync = ac3_sync; | |
| 1613 | 740 return 0; |
| 741 } | |
|
3455
cc4b4ea83e29
--enable/disable parsers. Warning: some combinations are broken.
mru
parents:
3432
diff
changeset
|
742 #endif |
| 1613 | 743 |
|
3455
cc4b4ea83e29
--enable/disable parsers. Warning: some combinations are broken.
mru
parents:
3432
diff
changeset
|
744 #ifdef CONFIG_AAC_PARSER |
| 3098 | 745 static int aac_parse_init(AVCodecParserContext *s1) |
| 746 { | |
| 747 AC3ParseContext *s = s1->priv_data; | |
| 748 s->inbuf_ptr = s->inbuf; | |
| 749 s->header_size = AAC_HEADER_SIZE; | |
| 750 s->sync = aac_sync; | |
| 751 return 0; | |
| 752 } | |
|
3455
cc4b4ea83e29
--enable/disable parsers. Warning: some combinations are broken.
mru
parents:
3432
diff
changeset
|
753 #endif |
| 3098 | 754 |
| 755 /* also used for ADTS AAC */ | |
| 1613 | 756 static int ac3_parse(AVCodecParserContext *s1, |
| 757 AVCodecContext *avctx, | |
| 2967 | 758 uint8_t **poutbuf, int *poutbuf_size, |
| 1613 | 759 const uint8_t *buf, int buf_size) |
| 760 { | |
| 761 AC3ParseContext *s = s1->priv_data; | |
| 762 const uint8_t *buf_ptr; | |
| 3098 | 763 int len, sample_rate, bit_rate, channels, samples; |
| 1613 | 764 |
| 765 *poutbuf = NULL; | |
| 766 *poutbuf_size = 0; | |
| 767 | |
| 768 buf_ptr = buf; | |
| 769 while (buf_size > 0) { | |
| 770 len = s->inbuf_ptr - s->inbuf; | |
| 771 if (s->frame_size == 0) { | |
| 3098 | 772 /* no header seen : find one. We need at least s->header_size |
| 773 bytes to parse it */ | |
| 774 len = FFMIN(s->header_size - len, buf_size); | |
| 3082 | 775 |
| 1613 | 776 memcpy(s->inbuf_ptr, buf_ptr, len); |
| 777 buf_ptr += len; | |
| 778 s->inbuf_ptr += len; | |
| 779 buf_size -= len; | |
| 3098 | 780 if ((s->inbuf_ptr - s->inbuf) == s->header_size) { |
| 781 len = s->sync(s->inbuf, &channels, &sample_rate, &bit_rate, | |
| 782 &samples); | |
| 1613 | 783 if (len == 0) { |
| 784 /* no sync found : move by one byte (inefficient, but simple!) */ | |
| 3098 | 785 memmove(s->inbuf, s->inbuf + 1, s->header_size - 1); |
| 1613 | 786 s->inbuf_ptr--; |
| 787 } else { | |
| 2979 | 788 s->frame_size = len; |
| 1613 | 789 /* update codec info */ |
| 790 avctx->sample_rate = sample_rate; | |
| 1987 | 791 /* set channels,except if the user explicitly requests 1 or 2 channels, XXX/FIXME this is a bit ugly */ |
| 3098 | 792 if(avctx->codec_id == CODEC_ID_AC3){ |
| 793 if(avctx->channels!=1 && avctx->channels!=2){ | |
| 794 avctx->channels = channels; | |
| 795 } | |
| 796 } else { | |
|
3063
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3059
diff
changeset
|
797 avctx->channels = channels; |
| 1987 | 798 } |
| 2979 | 799 avctx->bit_rate = bit_rate; |
| 3098 | 800 avctx->frame_size = samples; |
| 1613 | 801 } |
| 802 } | |
| 3082 | 803 } else { |
| 804 len = FFMIN(s->frame_size - len, buf_size); | |
| 1613 | 805 |
| 806 memcpy(s->inbuf_ptr, buf_ptr, len); | |
| 807 buf_ptr += len; | |
| 808 s->inbuf_ptr += len; | |
| 809 buf_size -= len; | |
| 3082 | 810 |
| 811 if(s->inbuf_ptr - s->inbuf == s->frame_size){ | |
| 812 *poutbuf = s->inbuf; | |
| 813 *poutbuf_size = s->frame_size; | |
| 814 s->inbuf_ptr = s->inbuf; | |
| 815 s->frame_size = 0; | |
| 816 break; | |
| 817 } | |
| 1613 | 818 } |
| 819 } | |
| 820 return buf_ptr - buf; | |
| 821 } | |
|
3455
cc4b4ea83e29
--enable/disable parsers. Warning: some combinations are broken.
mru
parents:
3432
diff
changeset
|
822 #endif /* CONFIG_AC3_PARSER || CONFIG_AAC_PARSER */ |
| 1613 | 823 |
|
3455
cc4b4ea83e29
--enable/disable parsers. Warning: some combinations are broken.
mru
parents:
3432
diff
changeset
|
824 #ifdef CONFIG_MPEG4VIDEO_PARSER |
| 1613 | 825 AVCodecParser mpeg4video_parser = { |
| 826 { CODEC_ID_MPEG4 }, | |
| 827 sizeof(ParseContext1), | |
| 828 mpeg4video_parse_init, | |
| 829 mpeg4video_parse, | |
|
4150
2205aefb22b7
move AVCodecParser prototypes and definitions to parser.h, and move mpegvideo parser to mpeg12.c
bcoudurier
parents:
4146
diff
changeset
|
830 ff_parse1_close, |
|
4175
b3328ed50a5e
make mpeg4video_split public as ff_mpeg4video_split
stefang
parents:
4150
diff
changeset
|
831 ff_mpeg4video_split, |
| 1613 | 832 }; |
|
3455
cc4b4ea83e29
--enable/disable parsers. Warning: some combinations are broken.
mru
parents:
3432
diff
changeset
|
833 #endif |
|
cc4b4ea83e29
--enable/disable parsers. Warning: some combinations are broken.
mru
parents:
3432
diff
changeset
|
834 #ifdef CONFIG_MPEGAUDIO_PARSER |
| 1613 | 835 AVCodecParser mpegaudio_parser = { |
| 836 { CODEC_ID_MP2, CODEC_ID_MP3 }, | |
| 837 sizeof(MpegAudioParseContext), | |
| 838 mpegaudio_parse_init, | |
| 839 mpegaudio_parse, | |
| 840 NULL, | |
| 841 }; | |
|
3455
cc4b4ea83e29
--enable/disable parsers. Warning: some combinations are broken.
mru
parents:
3432
diff
changeset
|
842 #endif |
|
cc4b4ea83e29
--enable/disable parsers. Warning: some combinations are broken.
mru
parents:
3432
diff
changeset
|
843 #ifdef CONFIG_AC3_PARSER |
| 1613 | 844 AVCodecParser ac3_parser = { |
| 845 { CODEC_ID_AC3 }, | |
| 846 sizeof(AC3ParseContext), | |
| 847 ac3_parse_init, | |
| 848 ac3_parse, | |
| 849 NULL, | |
| 850 }; | |
|
3455
cc4b4ea83e29
--enable/disable parsers. Warning: some combinations are broken.
mru
parents:
3432
diff
changeset
|
851 #endif |
|
cc4b4ea83e29
--enable/disable parsers. Warning: some combinations are broken.
mru
parents:
3432
diff
changeset
|
852 #ifdef CONFIG_AAC_PARSER |
| 3098 | 853 AVCodecParser aac_parser = { |
| 854 { CODEC_ID_AAC }, | |
| 855 sizeof(AC3ParseContext), | |
| 856 aac_parse_init, | |
| 857 ac3_parse, | |
| 858 NULL, | |
| 859 }; | |
|
3455
cc4b4ea83e29
--enable/disable parsers. Warning: some combinations are broken.
mru
parents:
3432
diff
changeset
|
860 #endif |
