Mercurial > libavcodec.hg
comparison parser.c @ 4150:2205aefb22b7 libavcodec
move AVCodecParser prototypes and definitions to parser.h, and move mpegvideo parser to mpeg12.c
| author | bcoudurier |
|---|---|
| date | Mon, 06 Nov 2006 10:43:49 +0000 |
| parents | c09e31f70a30 |
| children | b3328ed50a5e |
comparison
equal
deleted
inserted
replaced
| 4149:3118e8afb8a5 | 4150:2205aefb22b7 |
|---|---|
| 20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | 20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
| 21 */ | 21 */ |
| 22 #include "avcodec.h" | 22 #include "avcodec.h" |
| 23 #include "mpegvideo.h" | 23 #include "mpegvideo.h" |
| 24 #include "mpegaudio.h" | 24 #include "mpegaudio.h" |
| 25 #include "parser.h" | |
| 25 | 26 |
| 26 AVCodecParser *av_first_parser = NULL; | 27 AVCodecParser *av_first_parser = NULL; |
| 27 | 28 |
| 28 void av_register_codec_parser(AVCodecParser *parser) | 29 void av_register_codec_parser(AVCodecParser *parser) |
| 29 { | 30 { |
| 211 av_free(s); | 212 av_free(s); |
| 212 } | 213 } |
| 213 | 214 |
| 214 /*****************************************************/ | 215 /*****************************************************/ |
| 215 | 216 |
| 216 //#define END_NOT_FOUND (-100) | |
| 217 | |
| 218 #define PICTURE_START_CODE 0x00000100 | |
| 219 #define SEQ_START_CODE 0x000001b3 | |
| 220 #define EXT_START_CODE 0x000001b5 | |
| 221 #define SLICE_MIN_START_CODE 0x00000101 | |
| 222 #define SLICE_MAX_START_CODE 0x000001af | |
| 223 | |
| 224 typedef struct ParseContext1{ | |
| 225 ParseContext pc; | |
| 226 /* XXX/FIXME PC1 vs. PC */ | |
| 227 /* MPEG2 specific */ | |
| 228 AVRational frame_rate; | |
| 229 int progressive_sequence; | |
| 230 int width, height; | |
| 231 | |
| 232 /* XXX: suppress that, needed by MPEG4 */ | |
| 233 MpegEncContext *enc; | |
| 234 int first_picture; | |
| 235 } ParseContext1; | |
| 236 | |
| 237 /** | 217 /** |
| 238 * combines the (truncated) bitstream to a complete frame | 218 * combines the (truncated) bitstream to a complete frame |
| 239 * @returns -1 if no complete frame could be created | 219 * @returns -1 if no complete frame could be created |
| 240 */ | 220 */ |
| 241 int ff_combine_frame(ParseContext *pc, int next, uint8_t **buf, int *buf_size) | 221 int ff_combine_frame(ParseContext *pc, int next, uint8_t **buf, int *buf_size) |
| 294 #endif | 274 #endif |
| 295 | 275 |
| 296 return 0; | 276 return 0; |
| 297 } | 277 } |
| 298 | 278 |
| 299 #ifdef CONFIG_MPEGVIDEO_PARSER | |
| 300 | |
| 301 extern const AVRational ff_frame_rate_tab[]; | |
| 302 | |
| 303 //FIXME move into mpeg12.c | |
| 304 static void mpegvideo_extract_headers(AVCodecParserContext *s, | |
| 305 AVCodecContext *avctx, | |
| 306 const uint8_t *buf, int buf_size) | |
| 307 { | |
| 308 ParseContext1 *pc = s->priv_data; | |
| 309 const uint8_t *buf_end; | |
| 310 uint32_t start_code; | |
| 311 int frame_rate_index, ext_type, bytes_left; | |
| 312 int frame_rate_ext_n, frame_rate_ext_d; | |
| 313 int picture_structure, top_field_first, repeat_first_field, progressive_frame; | |
| 314 int horiz_size_ext, vert_size_ext, bit_rate_ext; | |
| 315 //FIXME replace the crap with get_bits() | |
| 316 s->repeat_pict = 0; | |
| 317 buf_end = buf + buf_size; | |
| 318 while (buf < buf_end) { | |
| 319 start_code= -1; | |
| 320 buf= ff_find_start_code(buf, buf_end, &start_code); | |
| 321 bytes_left = buf_end - buf; | |
| 322 switch(start_code) { | |
| 323 case PICTURE_START_CODE: | |
| 324 if (bytes_left >= 2) { | |
| 325 s->pict_type = (buf[1] >> 3) & 7; | |
| 326 } | |
| 327 break; | |
| 328 case SEQ_START_CODE: | |
| 329 if (bytes_left >= 7) { | |
| 330 pc->width = (buf[0] << 4) | (buf[1] >> 4); | |
| 331 pc->height = ((buf[1] & 0x0f) << 8) | buf[2]; | |
| 332 avcodec_set_dimensions(avctx, pc->width, pc->height); | |
| 333 frame_rate_index = buf[3] & 0xf; | |
| 334 pc->frame_rate.den = avctx->time_base.den = ff_frame_rate_tab[frame_rate_index].num; | |
| 335 pc->frame_rate.num = avctx->time_base.num = ff_frame_rate_tab[frame_rate_index].den; | |
| 336 avctx->bit_rate = ((buf[4]<<10) | (buf[5]<<2) | (buf[6]>>6))*400; | |
| 337 avctx->codec_id = CODEC_ID_MPEG1VIDEO; | |
| 338 avctx->sub_id = 1; | |
| 339 } | |
| 340 break; | |
| 341 case EXT_START_CODE: | |
| 342 if (bytes_left >= 1) { | |
| 343 ext_type = (buf[0] >> 4); | |
| 344 switch(ext_type) { | |
| 345 case 0x1: /* sequence extension */ | |
| 346 if (bytes_left >= 6) { | |
| 347 horiz_size_ext = ((buf[1] & 1) << 1) | (buf[2] >> 7); | |
| 348 vert_size_ext = (buf[2] >> 5) & 3; | |
| 349 bit_rate_ext = ((buf[2] & 0x1F)<<7) | (buf[3]>>1); | |
| 350 frame_rate_ext_n = (buf[5] >> 5) & 3; | |
| 351 frame_rate_ext_d = (buf[5] & 0x1f); | |
| 352 pc->progressive_sequence = buf[1] & (1 << 3); | |
| 353 avctx->has_b_frames= !(buf[5] >> 7); | |
| 354 | |
| 355 pc->width |=(horiz_size_ext << 12); | |
| 356 pc->height |=( vert_size_ext << 12); | |
| 357 avctx->bit_rate += (bit_rate_ext << 18) * 400; | |
| 358 avcodec_set_dimensions(avctx, pc->width, pc->height); | |
| 359 avctx->time_base.den = pc->frame_rate.den * (frame_rate_ext_n + 1); | |
| 360 avctx->time_base.num = pc->frame_rate.num * (frame_rate_ext_d + 1); | |
| 361 avctx->codec_id = CODEC_ID_MPEG2VIDEO; | |
| 362 avctx->sub_id = 2; /* forces MPEG2 */ | |
| 363 } | |
| 364 break; | |
| 365 case 0x8: /* picture coding extension */ | |
| 366 if (bytes_left >= 5) { | |
| 367 picture_structure = buf[2]&3; | |
| 368 top_field_first = buf[3] & (1 << 7); | |
| 369 repeat_first_field = buf[3] & (1 << 1); | |
| 370 progressive_frame = buf[4] & (1 << 7); | |
| 371 | |
| 372 /* check if we must repeat the frame */ | |
| 373 if (repeat_first_field) { | |
| 374 if (pc->progressive_sequence) { | |
| 375 if (top_field_first) | |
| 376 s->repeat_pict = 4; | |
| 377 else | |
| 378 s->repeat_pict = 2; | |
| 379 } else if (progressive_frame) { | |
| 380 s->repeat_pict = 1; | |
| 381 } | |
| 382 } | |
| 383 | |
| 384 /* the packet only represents half a frame | |
| 385 XXX,FIXME maybe find a different solution */ | |
| 386 if(picture_structure != 3) | |
| 387 s->repeat_pict = -1; | |
| 388 } | |
| 389 break; | |
| 390 } | |
| 391 } | |
| 392 break; | |
| 393 case -1: | |
| 394 goto the_end; | |
| 395 default: | |
| 396 /* we stop parsing when we encounter a slice. It ensures | |
| 397 that this function takes a negligible amount of time */ | |
| 398 if (start_code >= SLICE_MIN_START_CODE && | |
| 399 start_code <= SLICE_MAX_START_CODE) | |
| 400 goto the_end; | |
| 401 break; | |
| 402 } | |
| 403 } | |
| 404 the_end: ; | |
| 405 } | |
| 406 | |
| 407 static int mpegvideo_parse(AVCodecParserContext *s, | |
| 408 AVCodecContext *avctx, | |
| 409 uint8_t **poutbuf, int *poutbuf_size, | |
| 410 const uint8_t *buf, int buf_size) | |
| 411 { | |
| 412 ParseContext1 *pc1 = s->priv_data; | |
| 413 ParseContext *pc= &pc1->pc; | |
| 414 int next; | |
| 415 | |
| 416 if(s->flags & PARSER_FLAG_COMPLETE_FRAMES){ | |
| 417 next= buf_size; | |
| 418 }else{ | |
| 419 next= ff_mpeg1_find_frame_end(pc, buf, buf_size); | |
| 420 | |
| 421 if (ff_combine_frame(pc, next, (uint8_t **)&buf, &buf_size) < 0) { | |
| 422 *poutbuf = NULL; | |
| 423 *poutbuf_size = 0; | |
| 424 return buf_size; | |
| 425 } | |
| 426 | |
| 427 } | |
| 428 /* we have a full frame : we just parse the first few MPEG headers | |
| 429 to have the full timing information. The time take by this | |
| 430 function should be negligible for uncorrupted streams */ | |
| 431 mpegvideo_extract_headers(s, avctx, buf, buf_size); | |
| 432 #if 0 | |
| 433 printf("pict_type=%d frame_rate=%0.3f repeat_pict=%d\n", | |
| 434 s->pict_type, (double)avctx->time_base.den / avctx->time_base.num, s->repeat_pict); | |
| 435 #endif | |
| 436 | |
| 437 *poutbuf = (uint8_t *)buf; | |
| 438 *poutbuf_size = buf_size; | |
| 439 return next; | |
| 440 } | |
| 441 | |
| 442 static int mpegvideo_split(AVCodecContext *avctx, | |
| 443 const uint8_t *buf, int buf_size) | |
| 444 { | |
| 445 int i; | |
| 446 uint32_t state= -1; | |
| 447 | |
| 448 for(i=0; i<buf_size; i++){ | |
| 449 state= (state<<8) | buf[i]; | |
| 450 if(state != 0x1B3 && state != 0x1B5 && state < 0x200 && state >= 0x100) | |
| 451 return i-3; | |
| 452 } | |
| 453 return 0; | |
| 454 } | |
| 455 #endif /* CONFIG_MPEGVIDEO_PARSER */ | |
| 456 | |
| 457 void ff_parse_close(AVCodecParserContext *s) | 279 void ff_parse_close(AVCodecParserContext *s) |
| 458 { | 280 { |
| 459 ParseContext *pc = s->priv_data; | 281 ParseContext *pc = s->priv_data; |
| 460 | 282 |
| 461 av_free(pc->buffer); | 283 av_free(pc->buffer); |
| 462 } | 284 } |
| 463 | 285 |
| 464 static void parse1_close(AVCodecParserContext *s) | 286 void ff_parse1_close(AVCodecParserContext *s) |
| 465 { | 287 { |
| 466 ParseContext1 *pc1 = s->priv_data; | 288 ParseContext1 *pc1 = s->priv_data; |
| 467 | 289 |
| 468 av_free(pc1->pc.buffer); | 290 av_free(pc1->pc.buffer); |
| 469 av_free(pc1->enc); | 291 av_free(pc1->enc); |
| 1023 } | 845 } |
| 1024 return buf_ptr - buf; | 846 return buf_ptr - buf; |
| 1025 } | 847 } |
| 1026 #endif /* CONFIG_AC3_PARSER || CONFIG_AAC_PARSER */ | 848 #endif /* CONFIG_AC3_PARSER || CONFIG_AAC_PARSER */ |
| 1027 | 849 |
| 1028 #ifdef CONFIG_MPEGVIDEO_PARSER | |
| 1029 AVCodecParser mpegvideo_parser = { | |
| 1030 { CODEC_ID_MPEG1VIDEO, CODEC_ID_MPEG2VIDEO }, | |
| 1031 sizeof(ParseContext1), | |
| 1032 NULL, | |
| 1033 mpegvideo_parse, | |
| 1034 parse1_close, | |
| 1035 mpegvideo_split, | |
| 1036 }; | |
| 1037 #endif | |
| 1038 #ifdef CONFIG_MPEG4VIDEO_PARSER | 850 #ifdef CONFIG_MPEG4VIDEO_PARSER |
| 1039 AVCodecParser mpeg4video_parser = { | 851 AVCodecParser mpeg4video_parser = { |
| 1040 { CODEC_ID_MPEG4 }, | 852 { CODEC_ID_MPEG4 }, |
| 1041 sizeof(ParseContext1), | 853 sizeof(ParseContext1), |
| 1042 mpeg4video_parse_init, | 854 mpeg4video_parse_init, |
| 1043 mpeg4video_parse, | 855 mpeg4video_parse, |
| 1044 parse1_close, | 856 ff_parse1_close, |
| 1045 mpeg4video_split, | 857 mpeg4video_split, |
| 1046 }; | 858 }; |
| 1047 #endif | 859 #endif |
| 1048 #ifdef CONFIG_CAVSVIDEO_PARSER | 860 #ifdef CONFIG_CAVSVIDEO_PARSER |
| 1049 AVCodecParser cavsvideo_parser = { | 861 AVCodecParser cavsvideo_parser = { |
| 1050 { CODEC_ID_CAVS }, | 862 { CODEC_ID_CAVS }, |
| 1051 sizeof(ParseContext1), | 863 sizeof(ParseContext1), |
| 1052 NULL, | 864 NULL, |
| 1053 cavsvideo_parse, | 865 cavsvideo_parse, |
| 1054 parse1_close, | 866 ff_parse1_close, |
| 1055 mpeg4video_split, | 867 mpeg4video_split, |
| 1056 }; | 868 }; |
| 1057 #endif | 869 #endif |
| 1058 #ifdef CONFIG_MPEGAUDIO_PARSER | 870 #ifdef CONFIG_MPEGAUDIO_PARSER |
| 1059 AVCodecParser mpegaudio_parser = { | 871 AVCodecParser mpegaudio_parser = { |
