Mercurial > libavcodec.hg
comparison parser.c @ 1988:b5753525f9a8 libavcodec
remove duplicated find_frame_end() code
move codec specific code from parser.c -> <codecname>.c as far as its easily possible
| author | michael |
|---|---|
| date | Thu, 29 Apr 2004 14:21:33 +0000 |
| parents | d9e067853051 |
| children | f65d87bfdd5a |
comparison
equal
deleted
inserted
replaced
| 1987:d9e067853051 | 1988:b5753525f9a8 |
|---|---|
| 142 #define EXT_START_CODE 0x000001b5 | 142 #define EXT_START_CODE 0x000001b5 |
| 143 #define SLICE_MIN_START_CODE 0x00000101 | 143 #define SLICE_MIN_START_CODE 0x00000101 |
| 144 #define SLICE_MAX_START_CODE 0x000001af | 144 #define SLICE_MAX_START_CODE 0x000001af |
| 145 | 145 |
| 146 typedef struct ParseContext1{ | 146 typedef struct ParseContext1{ |
| 147 uint8_t *buffer; | 147 ParseContext pc; |
| 148 int index; | 148 /* XXX/FIXME PC1 vs. PC */ |
| 149 int last_index; | |
| 150 int buffer_size; | |
| 151 uint32_t state; ///< contains the last few bytes in MSB order | |
| 152 int frame_start_found; | |
| 153 int overread; ///< the number of bytes which where irreversibly read from the next frame | |
| 154 int overread_index; ///< the index into ParseContext1.buffer of the overreaded bytes | |
| 155 | |
| 156 /* MPEG2 specific */ | 149 /* MPEG2 specific */ |
| 157 int frame_rate; | 150 int frame_rate; |
| 158 int progressive_sequence; | 151 int progressive_sequence; |
| 159 int width, height; | 152 int width, height; |
| 160 | 153 |
| 165 | 158 |
| 166 /** | 159 /** |
| 167 * combines the (truncated) bitstream to a complete frame | 160 * combines the (truncated) bitstream to a complete frame |
| 168 * @returns -1 if no complete frame could be created | 161 * @returns -1 if no complete frame could be created |
| 169 */ | 162 */ |
| 170 static int ff_combine_frame1(ParseContext1 *pc, int next, uint8_t **buf, int *buf_size) | 163 int ff_combine_frame(ParseContext *pc, int next, uint8_t **buf, int *buf_size) |
| 171 { | 164 { |
| 172 #if 0 | 165 #if 0 |
| 173 if(pc->overread){ | 166 if(pc->overread){ |
| 174 printf("overread %d, state:%X next:%d index:%d o_index:%d\n", pc->overread, pc->state, next, pc->index, pc->overread_index); | 167 printf("overread %d, state:%X next:%d index:%d o_index:%d\n", pc->overread, pc->state, next, pc->index, pc->overread_index); |
| 175 printf("%X %X %X %X\n", (*buf)[0], (*buf)[1],(*buf)[2],(*buf)[3]); | 168 printf("%X %X %X %X\n", (*buf)[0], (*buf)[1],(*buf)[2],(*buf)[3]); |
| 216 printf("%X %X %X %X\n", (*buf)[0], (*buf)[1],(*buf)[2],(*buf)[3]); | 209 printf("%X %X %X %X\n", (*buf)[0], (*buf)[1],(*buf)[2],(*buf)[3]); |
| 217 } | 210 } |
| 218 #endif | 211 #endif |
| 219 | 212 |
| 220 return 0; | 213 return 0; |
| 221 } | |
| 222 | |
| 223 /** | |
| 224 * finds the end of the current frame in the bitstream. | |
| 225 * @return the position of the first byte of the next frame, or -1 | |
| 226 */ | |
| 227 static int mpeg1_find_frame_end(ParseContext1 *pc, const uint8_t *buf, int buf_size) | |
| 228 { | |
| 229 int i; | |
| 230 uint32_t state; | |
| 231 | |
| 232 state= pc->state; | |
| 233 | |
| 234 i=0; | |
| 235 if(!pc->frame_start_found){ | |
| 236 for(i=0; i<buf_size; i++){ | |
| 237 state= (state<<8) | buf[i]; | |
| 238 if(state >= SLICE_MIN_START_CODE && state <= SLICE_MAX_START_CODE){ | |
| 239 i++; | |
| 240 pc->frame_start_found=1; | |
| 241 break; | |
| 242 } | |
| 243 } | |
| 244 } | |
| 245 | |
| 246 if(pc->frame_start_found){ | |
| 247 /* EOF considered as end of frame */ | |
| 248 if (buf_size == 0) | |
| 249 return 0; | |
| 250 for(; i<buf_size; i++){ | |
| 251 state= (state<<8) | buf[i]; | |
| 252 if((state&0xFFFFFF00) == 0x100){ | |
| 253 if(state < SLICE_MIN_START_CODE || state > SLICE_MAX_START_CODE){ | |
| 254 pc->frame_start_found=0; | |
| 255 pc->state=-1; | |
| 256 return i-3; | |
| 257 } | |
| 258 } | |
| 259 } | |
| 260 } | |
| 261 pc->state= state; | |
| 262 return END_NOT_FOUND; | |
| 263 } | 214 } |
| 264 | 215 |
| 265 static int find_start_code(const uint8_t **pbuf_ptr, const uint8_t *buf_end) | 216 static int find_start_code(const uint8_t **pbuf_ptr, const uint8_t *buf_end) |
| 266 { | 217 { |
| 267 const uint8_t *buf_ptr; | 218 const uint8_t *buf_ptr; |
| 402 static int mpegvideo_parse(AVCodecParserContext *s, | 353 static int mpegvideo_parse(AVCodecParserContext *s, |
| 403 AVCodecContext *avctx, | 354 AVCodecContext *avctx, |
| 404 uint8_t **poutbuf, int *poutbuf_size, | 355 uint8_t **poutbuf, int *poutbuf_size, |
| 405 const uint8_t *buf, int buf_size) | 356 const uint8_t *buf, int buf_size) |
| 406 { | 357 { |
| 407 ParseContext1 *pc = s->priv_data; | 358 ParseContext1 *pc1 = s->priv_data; |
| 359 ParseContext *pc= &pc1->pc; | |
| 408 int next; | 360 int next; |
| 409 | 361 |
| 410 next= mpeg1_find_frame_end(pc, buf, buf_size); | 362 next= ff_mpeg1_find_frame_end(pc, buf, buf_size); |
| 411 | 363 |
| 412 if (ff_combine_frame1(pc, next, (uint8_t **)&buf, &buf_size) < 0) { | 364 if (ff_combine_frame(pc, next, (uint8_t **)&buf, &buf_size) < 0) { |
| 413 *poutbuf = NULL; | 365 *poutbuf = NULL; |
| 414 *poutbuf_size = 0; | 366 *poutbuf_size = 0; |
| 415 return buf_size; | 367 return buf_size; |
| 416 } | 368 } |
| 417 /* we have a full frame : we just parse the first few MPEG headers | 369 /* we have a full frame : we just parse the first few MPEG headers |
| 426 *poutbuf = (uint8_t *)buf; | 378 *poutbuf = (uint8_t *)buf; |
| 427 *poutbuf_size = buf_size; | 379 *poutbuf_size = buf_size; |
| 428 return next; | 380 return next; |
| 429 } | 381 } |
| 430 | 382 |
| 431 static void mpegvideo_parse_close(AVCodecParserContext *s) | 383 void ff_parse_close(AVCodecParserContext *s) |
| 432 { | 384 { |
| 433 ParseContext1 *pc = s->priv_data; | 385 ParseContext *pc = s->priv_data; |
| 434 | 386 |
| 435 av_free(pc->buffer); | 387 av_free(pc->buffer); |
| 436 av_free(pc->enc); | 388 } |
| 389 | |
| 390 static void parse1_close(AVCodecParserContext *s) | |
| 391 { | |
| 392 ParseContext1 *pc1 = s->priv_data; | |
| 393 | |
| 394 av_free(pc1->pc.buffer); | |
| 395 av_free(pc1->enc); | |
| 437 } | 396 } |
| 438 | 397 |
| 439 /*************************/ | 398 /*************************/ |
| 440 | |
| 441 /** | |
| 442 * finds the end of the current frame in the bitstream. | |
| 443 * @return the position of the first byte of the next frame, or -1 | |
| 444 */ | |
| 445 static int mpeg4_find_frame_end(ParseContext1 *pc, | |
| 446 const uint8_t *buf, int buf_size) | |
| 447 { | |
| 448 int vop_found, i; | |
| 449 uint32_t state; | |
| 450 | |
| 451 vop_found= pc->frame_start_found; | |
| 452 state= pc->state; | |
| 453 | |
| 454 i=0; | |
| 455 if(!vop_found){ | |
| 456 for(i=0; i<buf_size; i++){ | |
| 457 state= (state<<8) | buf[i]; | |
| 458 if(state == 0x1B6){ | |
| 459 i++; | |
| 460 vop_found=1; | |
| 461 break; | |
| 462 } | |
| 463 } | |
| 464 } | |
| 465 | |
| 466 if(vop_found){ | |
| 467 /* EOF considered as end of frame */ | |
| 468 if (buf_size == 0) | |
| 469 return 0; | |
| 470 for(; i<buf_size; i++){ | |
| 471 state= (state<<8) | buf[i]; | |
| 472 if((state&0xFFFFFF00) == 0x100){ | |
| 473 pc->frame_start_found=0; | |
| 474 pc->state=-1; | |
| 475 return i-3; | |
| 476 } | |
| 477 } | |
| 478 } | |
| 479 pc->frame_start_found= vop_found; | |
| 480 pc->state= state; | |
| 481 return END_NOT_FOUND; | |
| 482 } | |
| 483 | 399 |
| 484 /* used by parser */ | 400 /* used by parser */ |
| 485 /* XXX: make it use less memory */ | 401 /* XXX: make it use less memory */ |
| 486 static int av_mpeg4_decode_header(AVCodecParserContext *s1, | 402 static int av_mpeg4_decode_header(AVCodecParserContext *s1, |
| 487 AVCodecContext *avctx, | 403 AVCodecContext *avctx, |
| 524 static int mpeg4video_parse(AVCodecParserContext *s, | 440 static int mpeg4video_parse(AVCodecParserContext *s, |
| 525 AVCodecContext *avctx, | 441 AVCodecContext *avctx, |
| 526 uint8_t **poutbuf, int *poutbuf_size, | 442 uint8_t **poutbuf, int *poutbuf_size, |
| 527 const uint8_t *buf, int buf_size) | 443 const uint8_t *buf, int buf_size) |
| 528 { | 444 { |
| 529 ParseContext1 *pc = s->priv_data; | 445 ParseContext *pc = s->priv_data; |
| 530 int next; | 446 int next; |
| 531 | 447 |
| 532 next= mpeg4_find_frame_end(pc, buf, buf_size); | 448 next= ff_mpeg4_find_frame_end(pc, buf, buf_size); |
| 533 | 449 |
| 534 if (ff_combine_frame1(pc, next, (uint8_t **)&buf, &buf_size) < 0) { | 450 if (ff_combine_frame(pc, next, (uint8_t **)&buf, &buf_size) < 0) { |
| 535 *poutbuf = NULL; | 451 *poutbuf = NULL; |
| 536 *poutbuf_size = 0; | 452 *poutbuf_size = 0; |
| 537 return buf_size; | 453 return buf_size; |
| 538 } | 454 } |
| 539 av_mpeg4_decode_header(s, avctx, buf, buf_size); | 455 av_mpeg4_decode_header(s, avctx, buf, buf_size); |
| 540 | |
| 541 *poutbuf = (uint8_t *)buf; | |
| 542 *poutbuf_size = buf_size; | |
| 543 return next; | |
| 544 } | |
| 545 | |
| 546 /*************************/ | |
| 547 | |
| 548 static int h263_find_frame_end(ParseContext1 *pc, const uint8_t *buf, int buf_size) | |
| 549 { | |
| 550 int vop_found, i; | |
| 551 uint32_t state; | |
| 552 | |
| 553 vop_found= pc->frame_start_found; | |
| 554 state= pc->state; | |
| 555 | |
| 556 i=0; | |
| 557 if(!vop_found){ | |
| 558 for(i=0; i<buf_size; i++){ | |
| 559 state= (state<<8) | buf[i]; | |
| 560 if(state>>(32-22) == 0x20){ | |
| 561 i++; | |
| 562 vop_found=1; | |
| 563 break; | |
| 564 } | |
| 565 } | |
| 566 } | |
| 567 | |
| 568 if(vop_found){ | |
| 569 for(; i<buf_size; i++){ | |
| 570 state= (state<<8) | buf[i]; | |
| 571 if(state>>(32-22) == 0x20){ | |
| 572 pc->frame_start_found=0; | |
| 573 pc->state=-1; | |
| 574 return i-3; | |
| 575 } | |
| 576 } | |
| 577 } | |
| 578 pc->frame_start_found= vop_found; | |
| 579 pc->state= state; | |
| 580 | |
| 581 return END_NOT_FOUND; | |
| 582 } | |
| 583 | |
| 584 static int h263_parse(AVCodecParserContext *s, | |
| 585 AVCodecContext *avctx, | |
| 586 uint8_t **poutbuf, int *poutbuf_size, | |
| 587 const uint8_t *buf, int buf_size) | |
| 588 { | |
| 589 ParseContext1 *pc = s->priv_data; | |
| 590 int next; | |
| 591 | |
| 592 next= h263_find_frame_end(pc, buf, buf_size); | |
| 593 | |
| 594 if (ff_combine_frame1(pc, next, (uint8_t **)&buf, &buf_size) < 0) { | |
| 595 *poutbuf = NULL; | |
| 596 *poutbuf_size = 0; | |
| 597 return buf_size; | |
| 598 } | |
| 599 | |
| 600 *poutbuf = (uint8_t *)buf; | |
| 601 *poutbuf_size = buf_size; | |
| 602 return next; | |
| 603 } | |
| 604 | |
| 605 /*************************/ | |
| 606 | |
| 607 /** | |
| 608 * finds the end of the current frame in the bitstream. | |
| 609 * @return the position of the first byte of the next frame, or -1 | |
| 610 */ | |
| 611 static int h264_find_frame_end(ParseContext1 *pc, const uint8_t *buf, int buf_size) | |
| 612 { | |
| 613 int i; | |
| 614 uint32_t state; | |
| 615 //printf("first %02X%02X%02X%02X\n", buf[0], buf[1],buf[2],buf[3]); | |
| 616 // mb_addr= pc->mb_addr - 1; | |
| 617 state= pc->state; | |
| 618 //FIXME this will fail with slices | |
| 619 for(i=0; i<buf_size; i++){ | |
| 620 state= (state<<8) | buf[i]; | |
| 621 if((state&0xFFFFFF1F) == 0x101 || (state&0xFFFFFF1F) == 0x102 || (state&0xFFFFFF1F) == 0x105){ | |
| 622 if(pc->frame_start_found){ | |
| 623 pc->state=-1; | |
| 624 pc->frame_start_found= 0; | |
| 625 return i-3; | |
| 626 } | |
| 627 pc->frame_start_found= 1; | |
| 628 } | |
| 629 } | |
| 630 | |
| 631 pc->state= state; | |
| 632 return END_NOT_FOUND; | |
| 633 } | |
| 634 | |
| 635 static int h264_parse(AVCodecParserContext *s, | |
| 636 AVCodecContext *avctx, | |
| 637 uint8_t **poutbuf, int *poutbuf_size, | |
| 638 const uint8_t *buf, int buf_size) | |
| 639 { | |
| 640 ParseContext1 *pc = s->priv_data; | |
| 641 int next; | |
| 642 | |
| 643 next= h264_find_frame_end(pc, buf, buf_size); | |
| 644 | |
| 645 if (ff_combine_frame1(pc, next, (uint8_t **)&buf, &buf_size) < 0) { | |
| 646 *poutbuf = NULL; | |
| 647 *poutbuf_size = 0; | |
| 648 return buf_size; | |
| 649 } | |
| 650 | 456 |
| 651 *poutbuf = (uint8_t *)buf; | 457 *poutbuf = (uint8_t *)buf; |
| 652 *poutbuf_size = buf_size; | 458 *poutbuf_size = buf_size; |
| 653 return next; | 459 return next; |
| 654 } | 460 } |
| 911 AVCodecParser mpegvideo_parser = { | 717 AVCodecParser mpegvideo_parser = { |
| 912 { CODEC_ID_MPEG1VIDEO, CODEC_ID_MPEG2VIDEO }, | 718 { CODEC_ID_MPEG1VIDEO, CODEC_ID_MPEG2VIDEO }, |
| 913 sizeof(ParseContext1), | 719 sizeof(ParseContext1), |
| 914 NULL, | 720 NULL, |
| 915 mpegvideo_parse, | 721 mpegvideo_parse, |
| 916 mpegvideo_parse_close, | 722 parse1_close, |
| 917 }; | 723 }; |
| 918 | 724 |
| 919 AVCodecParser mpeg4video_parser = { | 725 AVCodecParser mpeg4video_parser = { |
| 920 { CODEC_ID_MPEG4 }, | 726 { CODEC_ID_MPEG4 }, |
| 921 sizeof(ParseContext1), | 727 sizeof(ParseContext1), |
| 922 mpeg4video_parse_init, | 728 mpeg4video_parse_init, |
| 923 mpeg4video_parse, | 729 mpeg4video_parse, |
| 924 mpegvideo_parse_close, | 730 parse1_close, |
| 925 }; | |
| 926 | |
| 927 AVCodecParser h263_parser = { | |
| 928 { CODEC_ID_H263 }, | |
| 929 sizeof(ParseContext1), | |
| 930 NULL, | |
| 931 h263_parse, | |
| 932 mpegvideo_parse_close, | |
| 933 }; | |
| 934 | |
| 935 AVCodecParser h264_parser = { | |
| 936 { CODEC_ID_H264 }, | |
| 937 sizeof(ParseContext1), | |
| 938 NULL, | |
| 939 h264_parse, | |
| 940 mpegvideo_parse_close, | |
| 941 }; | 731 }; |
| 942 | 732 |
| 943 AVCodecParser mpegaudio_parser = { | 733 AVCodecParser mpegaudio_parser = { |
| 944 { CODEC_ID_MP2, CODEC_ID_MP3 }, | 734 { CODEC_ID_MP2, CODEC_ID_MP3 }, |
| 945 sizeof(MpegAudioParseContext), | 735 sizeof(MpegAudioParseContext), |
