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