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),