Mercurial > libavcodec.hg
annotate parser.c @ 2071:41d30bae5019 libavcodec
attempt to create some separation in the FLAC system with respect to
demuxer and decoder layers by enabling the FLAC decoder to decode data
without needing the entire file, from start to finish
| author | melanson |
|---|---|
| date | Thu, 10 Jun 2004 04:13:43 +0000 |
| parents | f796043935f3 |
| children | bec4623c2201 |
| rev | line source |
|---|---|
| 1613 | 1 /* |
| 2 * Audio and Video frame extraction | |
| 3 * Copyright (c) 2003 Fabrice Bellard. | |
| 4 * Copyright (c) 2003 Michael Niedermayer. | |
| 5 * | |
| 6 * This library is free software; you can redistribute it and/or | |
| 7 * modify it under the terms of the GNU Lesser General Public | |
| 8 * License as published by the Free Software Foundation; either | |
| 9 * version 2 of the License, or (at your option) any later version. | |
| 10 * | |
| 11 * This library is distributed in the hope that it will be useful, | |
| 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| 14 * Lesser General Public License for more details. | |
| 15 * | |
| 16 * You should have received a copy of the GNU Lesser General Public | |
| 17 * License along with this library; if not, write to the Free Software | |
| 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
| 19 */ | |
| 20 #include "avcodec.h" | |
| 21 #include "mpegvideo.h" | |
| 22 #include "mpegaudio.h" | |
| 23 | |
| 24 AVCodecParser *av_first_parser = NULL; | |
| 25 | |
| 26 void av_register_codec_parser(AVCodecParser *parser) | |
| 27 { | |
| 28 parser->next = av_first_parser; | |
| 29 av_first_parser = parser; | |
| 30 } | |
| 31 | |
| 32 AVCodecParserContext *av_parser_init(int codec_id) | |
| 33 { | |
| 34 AVCodecParserContext *s; | |
| 35 AVCodecParser *parser; | |
| 36 int ret; | |
| 37 | |
| 38 for(parser = av_first_parser; parser != NULL; parser = parser->next) { | |
| 39 if (parser->codec_ids[0] == codec_id || | |
| 40 parser->codec_ids[1] == codec_id || | |
| 41 parser->codec_ids[2] == codec_id) | |
| 42 goto found; | |
| 43 } | |
| 44 return NULL; | |
| 45 found: | |
| 46 s = av_mallocz(sizeof(AVCodecParserContext)); | |
| 47 if (!s) | |
| 48 return NULL; | |
| 49 s->parser = parser; | |
| 50 s->priv_data = av_mallocz(parser->priv_data_size); | |
| 51 if (!s->priv_data) { | |
| 52 av_free(s); | |
| 53 return NULL; | |
| 54 } | |
| 55 if (parser->parser_init) { | |
| 56 ret = parser->parser_init(s); | |
| 57 if (ret != 0) { | |
| 58 av_free(s->priv_data); | |
| 59 av_free(s); | |
| 60 return NULL; | |
| 61 } | |
| 62 } | |
| 2030 | 63 s->fetch_timestamp=1; |
| 1613 | 64 return s; |
| 65 } | |
| 66 | |
|
1694
13169235c306
added End Of File handling to return last picture for MPEG1/2/4
bellard
parents:
1681
diff
changeset
|
67 /* NOTE: buf_size == 0 is used to signal EOF so that the last frame |
|
13169235c306
added End Of File handling to return last picture for MPEG1/2/4
bellard
parents:
1681
diff
changeset
|
68 can be returned if necessary */ |
| 1613 | 69 int av_parser_parse(AVCodecParserContext *s, |
| 70 AVCodecContext *avctx, | |
| 71 uint8_t **poutbuf, int *poutbuf_size, | |
| 1696 | 72 const uint8_t *buf, int buf_size, |
| 73 int64_t pts, int64_t dts) | |
| 1613 | 74 { |
| 1696 | 75 int index, i, k; |
|
1694
13169235c306
added End Of File handling to return last picture for MPEG1/2/4
bellard
parents:
1681
diff
changeset
|
76 uint8_t dummy_buf[FF_INPUT_BUFFER_PADDING_SIZE]; |
|
13169235c306
added End Of File handling to return last picture for MPEG1/2/4
bellard
parents:
1681
diff
changeset
|
77 |
|
13169235c306
added End Of File handling to return last picture for MPEG1/2/4
bellard
parents:
1681
diff
changeset
|
78 if (buf_size == 0) { |
|
13169235c306
added End Of File handling to return last picture for MPEG1/2/4
bellard
parents:
1681
diff
changeset
|
79 /* 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
|
80 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
|
81 buf = dummy_buf; |
| 1696 | 82 } else { |
| 83 /* add a new packet descriptor */ | |
| 84 k = (s->cur_frame_start_index + 1) & (AV_PARSER_PTS_NB - 1); | |
| 85 s->cur_frame_start_index = k; | |
| 86 s->cur_frame_offset[k] = s->cur_offset; | |
| 87 s->cur_frame_pts[k] = pts; | |
| 88 s->cur_frame_dts[k] = dts; | |
| 89 | |
| 90 /* fill first PTS/DTS */ | |
| 2030 | 91 if (s->fetch_timestamp){ |
| 92 s->fetch_timestamp=0; | |
| 1696 | 93 s->last_pts = pts; |
| 94 s->last_dts = dts; | |
| 95 } | |
|
1694
13169235c306
added End Of File handling to return last picture for MPEG1/2/4
bellard
parents:
1681
diff
changeset
|
96 } |
|
13169235c306
added End Of File handling to return last picture for MPEG1/2/4
bellard
parents:
1681
diff
changeset
|
97 |
| 1613 | 98 /* WARNING: the returned index can be negative */ |
| 99 index = s->parser->parser_parse(s, avctx, poutbuf, poutbuf_size, buf, buf_size); | |
| 2030 | 100 //av_log(NULL, AV_LOG_DEBUG, "parser: in:%lld, %lld, out:%lld, %lld, in:%d out:%d %d\n", pts, dts, s->last_pts, s->last_dts, buf_size, *poutbuf_size, avctx->codec_id); |
| 1613 | 101 /* update the file pointer */ |
| 102 if (*poutbuf_size) { | |
| 1696 | 103 /* fill the data for the current frame */ |
| 1613 | 104 s->frame_offset = s->last_frame_offset; |
| 1696 | 105 s->pts = s->last_pts; |
| 106 s->dts = s->last_dts; | |
| 107 | |
| 108 /* offset of the next frame */ | |
| 1613 | 109 s->last_frame_offset = s->cur_offset + index; |
| 1696 | 110 /* find the packet in which the new frame starts. It |
| 111 is tricky because of MPEG video start codes | |
| 112 which can begin in one packet and finish in | |
| 113 another packet. In the worst case, an MPEG | |
| 114 video start code could be in 4 different | |
| 115 packets. */ | |
| 116 k = s->cur_frame_start_index; | |
| 117 for(i = 0; i < AV_PARSER_PTS_NB; i++) { | |
| 118 if (s->last_frame_offset >= s->cur_frame_offset[k]) | |
| 119 break; | |
| 120 k = (k - 1) & (AV_PARSER_PTS_NB - 1); | |
| 121 } | |
| 2030 | 122 |
| 1696 | 123 s->last_pts = s->cur_frame_pts[k]; |
| 124 s->last_dts = s->cur_frame_dts[k]; | |
| 2030 | 125 |
| 126 /* some parsers tell us the packet size even before seeing the first byte of the next packet, | |
| 127 so the next pts/dts is in the next chunk */ | |
| 128 if(index == buf_size){ | |
| 129 s->fetch_timestamp=1; | |
| 130 } | |
| 1613 | 131 } |
| 132 if (index < 0) | |
| 133 index = 0; | |
| 134 s->cur_offset += index; | |
| 135 return index; | |
| 136 } | |
| 137 | |
| 138 void av_parser_close(AVCodecParserContext *s) | |
| 139 { | |
| 140 if (s->parser->parser_close) | |
| 141 s->parser->parser_close(s); | |
| 142 av_free(s->priv_data); | |
| 143 av_free(s); | |
| 144 } | |
| 145 | |
| 146 /*****************************************************/ | |
| 147 | |
| 148 //#define END_NOT_FOUND (-100) | |
| 149 | |
| 150 #define PICTURE_START_CODE 0x00000100 | |
| 151 #define SEQ_START_CODE 0x000001b3 | |
| 152 #define EXT_START_CODE 0x000001b5 | |
| 153 #define SLICE_MIN_START_CODE 0x00000101 | |
| 154 #define SLICE_MAX_START_CODE 0x000001af | |
| 155 | |
| 156 typedef struct ParseContext1{ | |
| 1988 | 157 ParseContext pc; |
| 158 /* XXX/FIXME PC1 vs. PC */ | |
| 1613 | 159 /* MPEG2 specific */ |
| 160 int frame_rate; | |
| 161 int progressive_sequence; | |
| 162 int width, height; | |
| 1614 | 163 |
| 1613 | 164 /* XXX: suppress that, needed by MPEG4 */ |
| 165 MpegEncContext *enc; | |
| 1614 | 166 int first_picture; |
| 1613 | 167 } ParseContext1; |
| 168 | |
| 169 /** | |
| 170 * combines the (truncated) bitstream to a complete frame | |
| 171 * @returns -1 if no complete frame could be created | |
| 172 */ | |
| 1988 | 173 int ff_combine_frame(ParseContext *pc, int next, uint8_t **buf, int *buf_size) |
| 1613 | 174 { |
| 175 #if 0 | |
| 176 if(pc->overread){ | |
| 177 printf("overread %d, state:%X next:%d index:%d o_index:%d\n", pc->overread, pc->state, next, pc->index, pc->overread_index); | |
| 178 printf("%X %X %X %X\n", (*buf)[0], (*buf)[1],(*buf)[2],(*buf)[3]); | |
| 179 } | |
| 180 #endif | |
| 181 | |
| 182 /* copy overreaded bytes from last frame into buffer */ | |
| 183 for(; pc->overread>0; pc->overread--){ | |
| 184 pc->buffer[pc->index++]= pc->buffer[pc->overread_index++]; | |
| 185 } | |
| 186 | |
| 187 pc->last_index= pc->index; | |
| 188 | |
| 189 /* copy into buffer end return */ | |
| 190 if(next == END_NOT_FOUND){ | |
| 191 pc->buffer= av_fast_realloc(pc->buffer, &pc->buffer_size, (*buf_size) + pc->index + FF_INPUT_BUFFER_PADDING_SIZE); | |
| 192 | |
| 193 memcpy(&pc->buffer[pc->index], *buf, *buf_size); | |
| 194 pc->index += *buf_size; | |
| 195 return -1; | |
| 196 } | |
| 197 | |
| 198 *buf_size= | |
| 199 pc->overread_index= pc->index + next; | |
| 200 | |
| 201 /* append to buffer */ | |
| 202 if(pc->index){ | |
| 203 pc->buffer= av_fast_realloc(pc->buffer, &pc->buffer_size, next + pc->index + FF_INPUT_BUFFER_PADDING_SIZE); | |
| 204 | |
| 205 memcpy(&pc->buffer[pc->index], *buf, next + FF_INPUT_BUFFER_PADDING_SIZE ); | |
| 206 pc->index = 0; | |
| 207 *buf= pc->buffer; | |
| 208 } | |
| 209 | |
| 210 /* store overread bytes */ | |
| 211 for(;next < 0; next++){ | |
| 212 pc->state = (pc->state<<8) | pc->buffer[pc->last_index + next]; | |
| 213 pc->overread++; | |
| 214 } | |
| 215 | |
| 216 #if 0 | |
| 217 if(pc->overread){ | |
| 218 printf("overread %d, state:%X next:%d index:%d o_index:%d\n", pc->overread, pc->state, next, pc->index, pc->overread_index); | |
| 219 printf("%X %X %X %X\n", (*buf)[0], (*buf)[1],(*buf)[2],(*buf)[3]); | |
| 220 } | |
| 221 #endif | |
| 222 | |
| 223 return 0; | |
| 224 } | |
| 225 | |
| 226 static int find_start_code(const uint8_t **pbuf_ptr, const uint8_t *buf_end) | |
| 227 { | |
| 228 const uint8_t *buf_ptr; | |
| 229 unsigned int state=0xFFFFFFFF, v; | |
| 230 int val; | |
| 231 | |
| 232 buf_ptr = *pbuf_ptr; | |
| 233 while (buf_ptr < buf_end) { | |
| 234 v = *buf_ptr++; | |
| 235 if (state == 0x000001) { | |
| 236 state = ((state << 8) | v) & 0xffffff; | |
| 237 val = state; | |
| 238 goto found; | |
| 239 } | |
| 240 state = ((state << 8) | v) & 0xffffff; | |
| 241 } | |
| 242 val = -1; | |
| 243 found: | |
| 244 *pbuf_ptr = buf_ptr; | |
| 245 return val; | |
| 246 } | |
| 247 | |
| 248 /* XXX: merge with libavcodec ? */ | |
| 249 #define MPEG1_FRAME_RATE_BASE 1001 | |
| 250 | |
| 251 static const int frame_rate_tab[16] = { | |
| 252 0, | |
| 253 24000, | |
| 254 24024, | |
| 255 25025, | |
| 256 30000, | |
| 257 30030, | |
| 258 50050, | |
| 259 60000, | |
| 260 60060, | |
| 261 // Xing's 15fps: (9) | |
| 262 15015, | |
| 263 // libmpeg3's "Unofficial economy rates": (10-13) | |
| 264 5005, | |
| 265 10010, | |
| 266 12012, | |
| 267 15015, | |
| 268 // random, just to avoid segfault !never encode these | |
| 269 25025, | |
| 270 25025, | |
| 271 }; | |
| 272 | |
| 273 static void mpegvideo_extract_headers(AVCodecParserContext *s, | |
| 274 AVCodecContext *avctx, | |
| 275 const uint8_t *buf, int buf_size) | |
| 276 { | |
| 277 ParseContext1 *pc = s->priv_data; | |
| 278 const uint8_t *buf_end; | |
| 279 int32_t start_code; | |
| 280 int frame_rate_index, ext_type, bytes_left; | |
| 281 int frame_rate_ext_n, frame_rate_ext_d; | |
| 282 int top_field_first, repeat_first_field, progressive_frame; | |
| 283 int horiz_size_ext, vert_size_ext; | |
| 284 | |
| 285 s->repeat_pict = 0; | |
| 286 buf_end = buf + buf_size; | |
| 287 while (buf < buf_end) { | |
| 288 start_code = find_start_code(&buf, buf_end); | |
| 289 bytes_left = buf_end - buf; | |
| 290 switch(start_code) { | |
| 291 case PICTURE_START_CODE: | |
| 292 if (bytes_left >= 2) { | |
| 293 s->pict_type = (buf[1] >> 3) & 7; | |
| 294 } | |
| 295 break; | |
| 296 case SEQ_START_CODE: | |
| 297 if (bytes_left >= 4) { | |
| 298 pc->width = avctx->width = (buf[0] << 4) | (buf[1] >> 4); | |
| 299 pc->height = avctx->height = ((buf[1] & 0x0f) << 8) | buf[2]; | |
| 300 frame_rate_index = buf[3] & 0xf; | |
| 301 pc->frame_rate = avctx->frame_rate = frame_rate_tab[frame_rate_index]; | |
| 302 avctx->frame_rate_base = MPEG1_FRAME_RATE_BASE; | |
| 1681 | 303 avctx->codec_id = CODEC_ID_MPEG1VIDEO; |
| 304 avctx->sub_id = 1; | |
| 1613 | 305 } |
| 306 break; | |
| 307 case EXT_START_CODE: | |
| 308 if (bytes_left >= 1) { | |
| 309 ext_type = (buf[0] >> 4); | |
| 310 switch(ext_type) { | |
| 311 case 0x1: /* sequence extension */ | |
| 312 if (bytes_left >= 6) { | |
| 313 horiz_size_ext = ((buf[1] & 1) << 1) | (buf[2] >> 7); | |
| 314 vert_size_ext = (buf[2] >> 5) & 3; | |
| 315 frame_rate_ext_n = (buf[5] >> 5) & 3; | |
| 316 frame_rate_ext_d = (buf[5] & 0x1f); | |
| 317 pc->progressive_sequence = buf[1] & (1 << 3); | |
| 318 | |
| 319 avctx->width = pc->width | (horiz_size_ext << 12); | |
| 320 avctx->height = pc->height | (vert_size_ext << 12); | |
| 321 avctx->frame_rate = pc->frame_rate * (frame_rate_ext_n + 1); | |
| 322 avctx->frame_rate_base = MPEG1_FRAME_RATE_BASE * (frame_rate_ext_d + 1); | |
| 1681 | 323 avctx->codec_id = CODEC_ID_MPEG2VIDEO; |
| 1613 | 324 avctx->sub_id = 2; /* forces MPEG2 */ |
| 325 } | |
| 326 break; | |
| 327 case 0x8: /* picture coding extension */ | |
| 328 if (bytes_left >= 5) { | |
| 329 top_field_first = buf[3] & (1 << 7); | |
| 330 repeat_first_field = buf[3] & (1 << 1); | |
| 331 progressive_frame = buf[4] & (1 << 7); | |
| 332 | |
| 333 /* check if we must repeat the frame */ | |
| 334 if (repeat_first_field) { | |
| 335 if (pc->progressive_sequence) { | |
| 336 if (top_field_first) | |
| 337 s->repeat_pict = 4; | |
| 338 else | |
| 339 s->repeat_pict = 2; | |
| 340 } else if (progressive_frame) { | |
| 341 s->repeat_pict = 1; | |
| 342 } | |
| 343 } | |
| 344 } | |
| 345 break; | |
| 346 } | |
| 347 } | |
| 348 break; | |
| 349 case -1: | |
| 350 goto the_end; | |
| 351 default: | |
| 352 /* we stop parsing when we encounter a slice. It ensures | |
| 353 that this function takes a negligible amount of time */ | |
| 354 if (start_code >= SLICE_MIN_START_CODE && | |
| 355 start_code <= SLICE_MAX_START_CODE) | |
| 356 goto the_end; | |
| 357 break; | |
| 358 } | |
| 359 } | |
| 360 the_end: ; | |
| 361 } | |
| 362 | |
| 363 static int mpegvideo_parse(AVCodecParserContext *s, | |
| 364 AVCodecContext *avctx, | |
| 365 uint8_t **poutbuf, int *poutbuf_size, | |
| 366 const uint8_t *buf, int buf_size) | |
| 367 { | |
| 1988 | 368 ParseContext1 *pc1 = s->priv_data; |
| 369 ParseContext *pc= &pc1->pc; | |
| 1613 | 370 int next; |
| 371 | |
| 1988 | 372 next= ff_mpeg1_find_frame_end(pc, buf, buf_size); |
| 1613 | 373 |
| 1988 | 374 if (ff_combine_frame(pc, next, (uint8_t **)&buf, &buf_size) < 0) { |
| 1613 | 375 *poutbuf = NULL; |
| 376 *poutbuf_size = 0; | |
| 377 return buf_size; | |
| 378 } | |
| 379 /* we have a full frame : we just parse the first few MPEG headers | |
| 380 to have the full timing information. The time take by this | |
| 381 function should be negligible for uncorrupted streams */ | |
| 382 mpegvideo_extract_headers(s, avctx, buf, buf_size); | |
| 383 #if 0 | |
| 384 printf("pict_type=%d frame_rate=%0.3f repeat_pict=%d\n", | |
| 385 s->pict_type, (double)avctx->frame_rate / avctx->frame_rate_base, s->repeat_pict); | |
| 386 #endif | |
| 387 | |
| 388 *poutbuf = (uint8_t *)buf; | |
| 389 *poutbuf_size = buf_size; | |
| 390 return next; | |
| 391 } | |
| 392 | |
| 1988 | 393 void ff_parse_close(AVCodecParserContext *s) |
| 1613 | 394 { |
| 1988 | 395 ParseContext *pc = s->priv_data; |
| 1613 | 396 |
| 397 av_free(pc->buffer); | |
| 1988 | 398 } |
| 399 | |
| 400 static void parse1_close(AVCodecParserContext *s) | |
| 401 { | |
| 402 ParseContext1 *pc1 = s->priv_data; | |
| 403 | |
| 404 av_free(pc1->pc.buffer); | |
| 405 av_free(pc1->enc); | |
| 1613 | 406 } |
| 407 | |
| 408 /*************************/ | |
| 409 | |
| 410 /* used by parser */ | |
| 411 /* XXX: make it use less memory */ | |
| 412 static int av_mpeg4_decode_header(AVCodecParserContext *s1, | |
| 413 AVCodecContext *avctx, | |
| 414 const uint8_t *buf, int buf_size) | |
| 415 { | |
| 416 ParseContext1 *pc = s1->priv_data; | |
| 417 MpegEncContext *s = pc->enc; | |
| 418 GetBitContext gb1, *gb = &gb1; | |
| 419 int ret; | |
| 420 | |
| 421 s->avctx = avctx; | |
| 1614 | 422 s->current_picture_ptr = &s->current_picture; |
| 423 | |
| 424 if (avctx->extradata_size && pc->first_picture){ | |
| 425 init_get_bits(gb, avctx->extradata, avctx->extradata_size*8); | |
| 426 ret = ff_mpeg4_decode_picture_header(s, gb); | |
| 427 } | |
| 428 | |
| 1613 | 429 init_get_bits(gb, buf, 8 * buf_size); |
| 430 ret = ff_mpeg4_decode_picture_header(s, gb); | |
| 431 if (s->width) { | |
| 432 avctx->width = s->width; | |
| 433 avctx->height = s->height; | |
| 434 } | |
| 1614 | 435 pc->first_picture = 0; |
| 1613 | 436 return ret; |
| 437 } | |
| 438 | |
|
2024
f65d87bfdd5a
some of the warning fixes by (Michael Roitzsch <mroi at users dot sourceforge dot net>)
michael
parents:
1988
diff
changeset
|
439 static int mpeg4video_parse_init(AVCodecParserContext *s) |
| 1613 | 440 { |
| 441 ParseContext1 *pc = s->priv_data; | |
| 1614 | 442 |
| 1613 | 443 pc->enc = av_mallocz(sizeof(MpegEncContext)); |
| 444 if (!pc->enc) | |
| 445 return -1; | |
| 1614 | 446 pc->first_picture = 1; |
| 1613 | 447 return 0; |
| 448 } | |
| 449 | |
| 450 static int mpeg4video_parse(AVCodecParserContext *s, | |
| 451 AVCodecContext *avctx, | |
| 452 uint8_t **poutbuf, int *poutbuf_size, | |
| 453 const uint8_t *buf, int buf_size) | |
| 454 { | |
| 1988 | 455 ParseContext *pc = s->priv_data; |
| 1613 | 456 int next; |
| 457 | |
| 1988 | 458 next= ff_mpeg4_find_frame_end(pc, buf, buf_size); |
| 1613 | 459 |
| 1988 | 460 if (ff_combine_frame(pc, next, (uint8_t **)&buf, &buf_size) < 0) { |
| 1613 | 461 *poutbuf = NULL; |
| 462 *poutbuf_size = 0; | |
| 463 return buf_size; | |
| 464 } | |
| 465 av_mpeg4_decode_header(s, avctx, buf, buf_size); | |
| 466 | |
| 467 *poutbuf = (uint8_t *)buf; | |
| 468 *poutbuf_size = buf_size; | |
| 469 return next; | |
| 470 } | |
| 471 | |
| 472 /*************************/ | |
| 473 | |
| 474 typedef struct MpegAudioParseContext { | |
| 475 uint8_t inbuf[MPA_MAX_CODED_FRAME_SIZE]; /* input buffer */ | |
| 476 uint8_t *inbuf_ptr; | |
| 477 int frame_size; | |
| 478 int free_format_frame_size; | |
| 479 int free_format_next_header; | |
| 480 } MpegAudioParseContext; | |
| 481 | |
| 482 #define MPA_HEADER_SIZE 4 | |
| 483 | |
| 484 /* header + layer + bitrate + freq + lsf/mpeg25 */ | |
| 485 #define SAME_HEADER_MASK \ | |
| 486 (0xffe00000 | (3 << 17) | (0xf << 12) | (3 << 10) | (3 << 19)) | |
| 487 | |
| 488 static int mpegaudio_parse_init(AVCodecParserContext *s1) | |
| 489 { | |
| 490 MpegAudioParseContext *s = s1->priv_data; | |
| 491 s->inbuf_ptr = s->inbuf; | |
| 492 return 0; | |
| 493 } | |
| 494 | |
| 495 static int mpegaudio_parse(AVCodecParserContext *s1, | |
| 496 AVCodecContext *avctx, | |
| 497 uint8_t **poutbuf, int *poutbuf_size, | |
| 498 const uint8_t *buf, int buf_size) | |
| 499 { | |
| 500 MpegAudioParseContext *s = s1->priv_data; | |
| 501 int len, ret; | |
| 502 uint32_t header; | |
| 503 const uint8_t *buf_ptr; | |
| 504 | |
| 505 *poutbuf = NULL; | |
| 506 *poutbuf_size = 0; | |
| 507 buf_ptr = buf; | |
| 508 while (buf_size > 0) { | |
| 509 len = s->inbuf_ptr - s->inbuf; | |
| 510 if (s->frame_size == 0) { | |
| 511 /* special case for next header for first frame in free | |
| 512 format case (XXX: find a simpler method) */ | |
| 513 if (s->free_format_next_header != 0) { | |
| 514 s->inbuf[0] = s->free_format_next_header >> 24; | |
| 515 s->inbuf[1] = s->free_format_next_header >> 16; | |
| 516 s->inbuf[2] = s->free_format_next_header >> 8; | |
| 517 s->inbuf[3] = s->free_format_next_header; | |
| 518 s->inbuf_ptr = s->inbuf + 4; | |
| 519 s->free_format_next_header = 0; | |
| 520 goto got_header; | |
| 521 } | |
| 522 /* no header seen : find one. We need at least MPA_HEADER_SIZE | |
| 523 bytes to parse it */ | |
| 524 len = MPA_HEADER_SIZE - len; | |
| 525 if (len > buf_size) | |
| 526 len = buf_size; | |
| 527 if (len > 0) { | |
| 528 memcpy(s->inbuf_ptr, buf_ptr, len); | |
| 529 buf_ptr += len; | |
| 530 buf_size -= len; | |
| 531 s->inbuf_ptr += len; | |
| 532 } | |
| 533 if ((s->inbuf_ptr - s->inbuf) >= MPA_HEADER_SIZE) { | |
| 534 got_header: | |
| 535 header = (s->inbuf[0] << 24) | (s->inbuf[1] << 16) | | |
| 536 (s->inbuf[2] << 8) | s->inbuf[3]; | |
| 537 | |
| 538 ret = mpa_decode_header(avctx, header); | |
| 539 if (ret < 0) { | |
| 540 /* no sync found : move by one byte (inefficient, but simple!) */ | |
| 541 memmove(s->inbuf, s->inbuf + 1, s->inbuf_ptr - s->inbuf - 1); | |
| 542 s->inbuf_ptr--; | |
| 543 dprintf("skip %x\n", header); | |
| 544 /* reset free format frame size to give a chance | |
| 545 to get a new bitrate */ | |
| 546 s->free_format_frame_size = 0; | |
| 547 } else { | |
| 548 s->frame_size = ret; | |
| 549 #if 0 | |
| 550 /* free format: prepare to compute frame size */ | |
| 551 if (decode_header(s, header) == 1) { | |
| 552 s->frame_size = -1; | |
| 553 } | |
| 554 #endif | |
| 555 } | |
| 556 } | |
| 557 } else | |
| 558 #if 0 | |
| 559 if (s->frame_size == -1) { | |
| 560 /* free format : find next sync to compute frame size */ | |
| 561 len = MPA_MAX_CODED_FRAME_SIZE - len; | |
| 562 if (len > buf_size) | |
| 563 len = buf_size; | |
| 564 if (len == 0) { | |
| 565 /* frame too long: resync */ | |
| 566 s->frame_size = 0; | |
| 567 memmove(s->inbuf, s->inbuf + 1, s->inbuf_ptr - s->inbuf - 1); | |
| 568 s->inbuf_ptr--; | |
| 569 } else { | |
| 570 uint8_t *p, *pend; | |
| 571 uint32_t header1; | |
| 572 int padding; | |
| 573 | |
| 574 memcpy(s->inbuf_ptr, buf_ptr, len); | |
| 575 /* check for header */ | |
| 576 p = s->inbuf_ptr - 3; | |
| 577 pend = s->inbuf_ptr + len - 4; | |
| 578 while (p <= pend) { | |
| 579 header = (p[0] << 24) | (p[1] << 16) | | |
| 580 (p[2] << 8) | p[3]; | |
| 581 header1 = (s->inbuf[0] << 24) | (s->inbuf[1] << 16) | | |
| 582 (s->inbuf[2] << 8) | s->inbuf[3]; | |
| 583 /* check with high probability that we have a | |
| 584 valid header */ | |
| 585 if ((header & SAME_HEADER_MASK) == | |
| 586 (header1 & SAME_HEADER_MASK)) { | |
| 587 /* header found: update pointers */ | |
| 588 len = (p + 4) - s->inbuf_ptr; | |
| 589 buf_ptr += len; | |
| 590 buf_size -= len; | |
| 591 s->inbuf_ptr = p; | |
| 592 /* compute frame size */ | |
| 593 s->free_format_next_header = header; | |
| 594 s->free_format_frame_size = s->inbuf_ptr - s->inbuf; | |
| 595 padding = (header1 >> 9) & 1; | |
| 596 if (s->layer == 1) | |
| 597 s->free_format_frame_size -= padding * 4; | |
| 598 else | |
| 599 s->free_format_frame_size -= padding; | |
| 600 dprintf("free frame size=%d padding=%d\n", | |
| 601 s->free_format_frame_size, padding); | |
| 602 decode_header(s, header1); | |
| 603 goto next_data; | |
| 604 } | |
| 605 p++; | |
| 606 } | |
| 607 /* not found: simply increase pointers */ | |
| 608 buf_ptr += len; | |
| 609 s->inbuf_ptr += len; | |
| 610 buf_size -= len; | |
| 611 } | |
| 612 } else | |
| 613 #endif | |
| 614 if (len < s->frame_size) { | |
| 615 if (s->frame_size > MPA_MAX_CODED_FRAME_SIZE) | |
| 616 s->frame_size = MPA_MAX_CODED_FRAME_SIZE; | |
| 617 len = s->frame_size - len; | |
| 618 if (len > buf_size) | |
| 619 len = buf_size; | |
| 620 memcpy(s->inbuf_ptr, buf_ptr, len); | |
| 621 buf_ptr += len; | |
| 622 s->inbuf_ptr += len; | |
| 623 buf_size -= len; | |
| 624 } | |
| 625 // next_data: | |
| 626 if (s->frame_size > 0 && | |
| 627 (s->inbuf_ptr - s->inbuf) >= s->frame_size) { | |
| 628 *poutbuf = s->inbuf; | |
| 629 *poutbuf_size = s->inbuf_ptr - s->inbuf; | |
| 630 s->inbuf_ptr = s->inbuf; | |
| 631 s->frame_size = 0; | |
| 632 break; | |
| 633 } | |
| 634 } | |
| 635 return buf_ptr - buf; | |
| 636 } | |
| 637 | |
| 638 #ifdef CONFIG_AC3 | |
| 639 extern int a52_syncinfo (const uint8_t * buf, int * flags, | |
| 640 int * sample_rate, int * bit_rate); | |
| 641 | |
| 642 typedef struct AC3ParseContext { | |
| 643 uint8_t inbuf[4096]; /* input buffer */ | |
| 644 uint8_t *inbuf_ptr; | |
| 645 int frame_size; | |
| 646 int flags; | |
| 647 } AC3ParseContext; | |
| 648 | |
| 649 #define AC3_HEADER_SIZE 7 | |
| 650 #define A52_LFE 16 | |
| 651 | |
| 652 static int ac3_parse_init(AVCodecParserContext *s1) | |
| 653 { | |
| 654 AC3ParseContext *s = s1->priv_data; | |
| 655 s->inbuf_ptr = s->inbuf; | |
| 656 return 0; | |
| 657 } | |
| 658 | |
| 659 static int ac3_parse(AVCodecParserContext *s1, | |
| 660 AVCodecContext *avctx, | |
| 661 uint8_t **poutbuf, int *poutbuf_size, | |
| 662 const uint8_t *buf, int buf_size) | |
| 663 { | |
| 664 AC3ParseContext *s = s1->priv_data; | |
| 665 const uint8_t *buf_ptr; | |
| 666 int len, sample_rate, bit_rate; | |
| 667 static const int ac3_channels[8] = { | |
| 668 2, 1, 2, 3, 3, 4, 4, 5 | |
| 669 }; | |
| 670 | |
| 671 *poutbuf = NULL; | |
| 672 *poutbuf_size = 0; | |
| 673 | |
| 674 buf_ptr = buf; | |
| 675 while (buf_size > 0) { | |
| 676 len = s->inbuf_ptr - s->inbuf; | |
| 677 if (s->frame_size == 0) { | |
| 678 /* no header seen : find one. We need at least 7 bytes to parse it */ | |
| 679 len = AC3_HEADER_SIZE - len; | |
| 680 if (len > buf_size) | |
| 681 len = buf_size; | |
| 682 memcpy(s->inbuf_ptr, buf_ptr, len); | |
| 683 buf_ptr += len; | |
| 684 s->inbuf_ptr += len; | |
| 685 buf_size -= len; | |
| 686 if ((s->inbuf_ptr - s->inbuf) == AC3_HEADER_SIZE) { | |
| 687 len = a52_syncinfo(s->inbuf, &s->flags, &sample_rate, &bit_rate); | |
| 688 if (len == 0) { | |
| 689 /* no sync found : move by one byte (inefficient, but simple!) */ | |
| 690 memmove(s->inbuf, s->inbuf + 1, AC3_HEADER_SIZE - 1); | |
| 691 s->inbuf_ptr--; | |
| 692 } else { | |
| 693 s->frame_size = len; | |
| 694 /* update codec info */ | |
| 695 avctx->sample_rate = sample_rate; | |
| 1987 | 696 /* set channels,except if the user explicitly requests 1 or 2 channels, XXX/FIXME this is a bit ugly */ |
| 697 if(avctx->channels!=1 && avctx->channels!=2){ | |
| 698 avctx->channels = ac3_channels[s->flags & 7]; | |
| 699 if (s->flags & A52_LFE) | |
| 700 avctx->channels++; | |
| 701 } | |
| 1613 | 702 avctx->bit_rate = bit_rate; |
| 703 avctx->frame_size = 6 * 256; | |
| 704 } | |
| 705 } | |
| 706 } else if (len < s->frame_size) { | |
| 707 len = s->frame_size - len; | |
| 708 if (len > buf_size) | |
| 709 len = buf_size; | |
| 710 | |
| 711 memcpy(s->inbuf_ptr, buf_ptr, len); | |
| 712 buf_ptr += len; | |
| 713 s->inbuf_ptr += len; | |
| 714 buf_size -= len; | |
| 715 } else { | |
| 716 *poutbuf = s->inbuf; | |
| 717 *poutbuf_size = s->frame_size; | |
| 718 s->inbuf_ptr = s->inbuf; | |
| 719 s->frame_size = 0; | |
| 720 break; | |
| 721 } | |
| 722 } | |
| 723 return buf_ptr - buf; | |
| 724 } | |
| 725 #endif | |
| 726 | |
| 727 AVCodecParser mpegvideo_parser = { | |
| 728 { CODEC_ID_MPEG1VIDEO, CODEC_ID_MPEG2VIDEO }, | |
| 729 sizeof(ParseContext1), | |
| 730 NULL, | |
| 731 mpegvideo_parse, | |
| 1988 | 732 parse1_close, |
| 1613 | 733 }; |
| 734 | |
| 735 AVCodecParser mpeg4video_parser = { | |
| 736 { CODEC_ID_MPEG4 }, | |
| 737 sizeof(ParseContext1), | |
| 738 mpeg4video_parse_init, | |
| 739 mpeg4video_parse, | |
| 1988 | 740 parse1_close, |
| 1613 | 741 }; |
| 742 | |
| 743 AVCodecParser mpegaudio_parser = { | |
| 744 { CODEC_ID_MP2, CODEC_ID_MP3 }, | |
| 745 sizeof(MpegAudioParseContext), | |
| 746 mpegaudio_parse_init, | |
| 747 mpegaudio_parse, | |
| 748 NULL, | |
| 749 }; | |
| 750 | |
| 751 #ifdef CONFIG_AC3 | |
| 752 AVCodecParser ac3_parser = { | |
| 753 { CODEC_ID_AC3 }, | |
| 754 sizeof(AC3ParseContext), | |
| 755 ac3_parse_init, | |
| 756 ac3_parse, | |
| 757 NULL, | |
| 758 }; | |
| 759 #endif |
