Mercurial > libavcodec.hg
comparison truemotion1.c @ 5514:e2dbd1623e1d libavcodec
use reget_buffer and remove internal copying of buffer - codec works again
author | alex |
---|---|
date | Thu, 09 Aug 2007 00:16:27 +0000 |
parents | f99e40a7155b |
children | 68d4853b5fae |
comparison
equal
deleted
inserted
replaced
5513:9f8219a3b86f | 5514:e2dbd1623e1d |
---|---|
40 #include "truemotion1data.h" | 40 #include "truemotion1data.h" |
41 | 41 |
42 typedef struct TrueMotion1Context { | 42 typedef struct TrueMotion1Context { |
43 AVCodecContext *avctx; | 43 AVCodecContext *avctx; |
44 AVFrame frame; | 44 AVFrame frame; |
45 AVFrame prev_frame; | |
46 | 45 |
47 uint8_t *buf; | 46 uint8_t *buf; |
48 int size; | 47 int size; |
49 | 48 |
50 uint8_t *mb_change_bits; | 49 uint8_t *mb_change_bits; |
472 // if (avctx->bits_per_sample == 24) | 471 // if (avctx->bits_per_sample == 24) |
473 // avctx->pix_fmt = PIX_FMT_RGB24; | 472 // avctx->pix_fmt = PIX_FMT_RGB24; |
474 // else | 473 // else |
475 // avctx->pix_fmt = PIX_FMT_RGB555; | 474 // avctx->pix_fmt = PIX_FMT_RGB555; |
476 | 475 |
477 s->frame.data[0] = s->prev_frame.data[0] = NULL; | 476 s->frame.data[0] = NULL; |
478 | 477 |
479 /* there is a vertical predictor for each pixel in a line; each vertical | 478 /* there is a vertical predictor for each pixel in a line; each vertical |
480 * predictor is 0 to start with */ | 479 * predictor is 0 to start with */ |
481 s->vert_pred = | 480 s->vert_pred = |
482 (unsigned int *)av_malloc(s->avctx->width * sizeof(unsigned int)); | 481 (unsigned int *)av_malloc(s->avctx->width * sizeof(unsigned int)); |
588 } else \ | 587 } else \ |
589 index++; | 588 index++; |
590 | 589 |
591 #define OUTPUT_PIXEL_PAIR() \ | 590 #define OUTPUT_PIXEL_PAIR() \ |
592 *current_pixel_pair = *vert_pred + horiz_pred; \ | 591 *current_pixel_pair = *vert_pred + horiz_pred; \ |
593 *vert_pred++ = *current_pixel_pair++; \ | 592 *vert_pred++ = *current_pixel_pair++; |
594 prev_pixel_pair++; | |
595 | 593 |
596 static void truemotion1_decode_16bit(TrueMotion1Context *s) | 594 static void truemotion1_decode_16bit(TrueMotion1Context *s) |
597 { | 595 { |
598 int y; | 596 int y; |
599 int pixels_left; /* remaining pixels on this line */ | 597 int pixels_left; /* remaining pixels on this line */ |
600 unsigned int predictor_pair; | 598 unsigned int predictor_pair; |
601 unsigned int horiz_pred; | 599 unsigned int horiz_pred; |
602 unsigned int *vert_pred; | 600 unsigned int *vert_pred; |
603 unsigned int *current_pixel_pair; | 601 unsigned int *current_pixel_pair; |
604 unsigned int *prev_pixel_pair; | |
605 unsigned char *current_line = s->frame.data[0]; | 602 unsigned char *current_line = s->frame.data[0]; |
606 unsigned char *prev_line = s->prev_frame.data[0]; | |
607 int keyframe = s->flags & FLAG_KEYFRAME; | 603 int keyframe = s->flags & FLAG_KEYFRAME; |
608 | 604 |
609 /* these variables are for managing the stream of macroblock change bits */ | 605 /* these variables are for managing the stream of macroblock change bits */ |
610 unsigned char *mb_change_bits = s->mb_change_bits; | 606 unsigned char *mb_change_bits = s->mb_change_bits; |
611 unsigned char mb_change_byte; | 607 unsigned char mb_change_byte; |
624 for (y = 0; y < s->avctx->height; y++) { | 620 for (y = 0; y < s->avctx->height; y++) { |
625 | 621 |
626 /* re-init variables for the next line iteration */ | 622 /* re-init variables for the next line iteration */ |
627 horiz_pred = 0; | 623 horiz_pred = 0; |
628 current_pixel_pair = (unsigned int *)current_line; | 624 current_pixel_pair = (unsigned int *)current_line; |
629 prev_pixel_pair = (unsigned int *)prev_line; | |
630 vert_pred = s->vert_pred; | 625 vert_pred = s->vert_pred; |
631 mb_change_index = 0; | 626 mb_change_index = 0; |
632 mb_change_byte = mb_change_bits[mb_change_index++]; | 627 mb_change_byte = mb_change_bits[mb_change_index++]; |
633 mb_change_byte_mask = 0x01; | 628 mb_change_byte_mask = 0x01; |
634 pixels_left = s->avctx->width; | 629 pixels_left = s->avctx->width; |
693 | 688 |
694 } else { | 689 } else { |
695 | 690 |
696 /* skip (copy) four pixels, but reassign the horizontal | 691 /* skip (copy) four pixels, but reassign the horizontal |
697 * predictor */ | 692 * predictor */ |
698 *current_pixel_pair = *prev_pixel_pair++; | |
699 *vert_pred++ = *current_pixel_pair++; | 693 *vert_pred++ = *current_pixel_pair++; |
700 *current_pixel_pair = *prev_pixel_pair++; | |
701 horiz_pred = *current_pixel_pair - *vert_pred; | 694 horiz_pred = *current_pixel_pair - *vert_pred; |
702 *vert_pred++ = *current_pixel_pair++; | 695 *vert_pred++ = *current_pixel_pair++; |
703 | 696 |
704 } | 697 } |
705 | 698 |
719 /* next change row */ | 712 /* next change row */ |
720 if (((y + 1) & 3) == 0) | 713 if (((y + 1) & 3) == 0) |
721 mb_change_bits += s->mb_change_bits_row_size; | 714 mb_change_bits += s->mb_change_bits_row_size; |
722 | 715 |
723 current_line += s->frame.linesize[0]; | 716 current_line += s->frame.linesize[0]; |
724 prev_line += s->prev_frame.linesize[0]; | |
725 } | 717 } |
726 } | 718 } |
727 | 719 |
728 static void truemotion1_decode_24bit(TrueMotion1Context *s) | 720 static void truemotion1_decode_24bit(TrueMotion1Context *s) |
729 { | 721 { |
731 int pixels_left; /* remaining pixels on this line */ | 723 int pixels_left; /* remaining pixels on this line */ |
732 unsigned int predictor_pair; | 724 unsigned int predictor_pair; |
733 unsigned int horiz_pred; | 725 unsigned int horiz_pred; |
734 unsigned int *vert_pred; | 726 unsigned int *vert_pred; |
735 unsigned int *current_pixel_pair; | 727 unsigned int *current_pixel_pair; |
736 unsigned int *prev_pixel_pair; | |
737 unsigned char *current_line = s->frame.data[0]; | 728 unsigned char *current_line = s->frame.data[0]; |
738 unsigned char *prev_line = s->prev_frame.data[0]; | |
739 int keyframe = s->flags & FLAG_KEYFRAME; | 729 int keyframe = s->flags & FLAG_KEYFRAME; |
740 | 730 |
741 /* these variables are for managing the stream of macroblock change bits */ | 731 /* these variables are for managing the stream of macroblock change bits */ |
742 unsigned char *mb_change_bits = s->mb_change_bits; | 732 unsigned char *mb_change_bits = s->mb_change_bits; |
743 unsigned char mb_change_byte; | 733 unsigned char mb_change_byte; |
756 for (y = 0; y < s->avctx->height; y++) { | 746 for (y = 0; y < s->avctx->height; y++) { |
757 | 747 |
758 /* re-init variables for the next line iteration */ | 748 /* re-init variables for the next line iteration */ |
759 horiz_pred = 0; | 749 horiz_pred = 0; |
760 current_pixel_pair = (unsigned int *)current_line; | 750 current_pixel_pair = (unsigned int *)current_line; |
761 prev_pixel_pair = (unsigned int *)prev_line; | |
762 vert_pred = s->vert_pred; | 751 vert_pred = s->vert_pred; |
763 mb_change_index = 0; | 752 mb_change_index = 0; |
764 mb_change_byte = mb_change_bits[mb_change_index++]; | 753 mb_change_byte = mb_change_bits[mb_change_index++]; |
765 mb_change_byte_mask = 0x01; | 754 mb_change_byte_mask = 0x01; |
766 pixels_left = s->avctx->width; | 755 pixels_left = s->avctx->width; |
825 | 814 |
826 } else { | 815 } else { |
827 | 816 |
828 /* skip (copy) four pixels, but reassign the horizontal | 817 /* skip (copy) four pixels, but reassign the horizontal |
829 * predictor */ | 818 * predictor */ |
830 *current_pixel_pair = *prev_pixel_pair++; | |
831 *vert_pred++ = *current_pixel_pair++; | 819 *vert_pred++ = *current_pixel_pair++; |
832 *current_pixel_pair = *prev_pixel_pair++; | |
833 horiz_pred = *current_pixel_pair - *vert_pred; | 820 horiz_pred = *current_pixel_pair - *vert_pred; |
834 *vert_pred++ = *current_pixel_pair++; | 821 *vert_pred++ = *current_pixel_pair++; |
835 | 822 |
836 } | 823 } |
837 | 824 |
851 /* next change row */ | 838 /* next change row */ |
852 if (((y + 1) & 3) == 0) | 839 if (((y + 1) & 3) == 0) |
853 mb_change_bits += s->mb_change_bits_row_size; | 840 mb_change_bits += s->mb_change_bits_row_size; |
854 | 841 |
855 current_line += s->frame.linesize[0]; | 842 current_line += s->frame.linesize[0]; |
856 prev_line += s->prev_frame.linesize[0]; | |
857 } | 843 } |
858 } | 844 } |
859 | 845 |
860 | 846 |
861 static int truemotion1_decode_frame(AVCodecContext *avctx, | 847 static int truemotion1_decode_frame(AVCodecContext *avctx, |
869 | 855 |
870 if (truemotion1_decode_header(s) == -1) | 856 if (truemotion1_decode_header(s) == -1) |
871 return -1; | 857 return -1; |
872 | 858 |
873 s->frame.reference = 1; | 859 s->frame.reference = 1; |
874 if (avctx->get_buffer(avctx, &s->frame) < 0) { | 860 s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | |
861 FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; | |
862 if (avctx->reget_buffer(avctx, &s->frame) < 0) { | |
875 av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n"); | 863 av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n"); |
876 return -1; | 864 return -1; |
877 } | 865 } |
878 | 866 |
879 /* check for a do-nothing frame and copy the previous frame */ | 867 if (compression_types[s->compression].algorithm == ALGO_RGB24H) { |
880 if (compression_types[s->compression].algorithm == ALGO_NOP) | |
881 { | |
882 memcpy(s->frame.data[0], s->prev_frame.data[0], | |
883 s->frame.linesize[0] * s->avctx->height); | |
884 } else if (compression_types[s->compression].algorithm == ALGO_RGB24H) { | |
885 truemotion1_decode_24bit(s); | 868 truemotion1_decode_24bit(s); |
886 } else { | 869 } else if (compression_types[s->compression].algorithm != ALGO_NOP) { |
887 truemotion1_decode_16bit(s); | 870 truemotion1_decode_16bit(s); |
888 } | 871 } |
889 | |
890 if (s->prev_frame.data[0]) | |
891 avctx->release_buffer(avctx, &s->prev_frame); | |
892 | |
893 /* shuffle frames */ | |
894 s->prev_frame = s->frame; | |
895 | 872 |
896 *data_size = sizeof(AVFrame); | 873 *data_size = sizeof(AVFrame); |
897 *(AVFrame*)data = s->frame; | 874 *(AVFrame*)data = s->frame; |
898 | 875 |
899 /* report that the buffer was completely consumed */ | 876 /* report that the buffer was completely consumed */ |
902 | 879 |
903 static int truemotion1_decode_end(AVCodecContext *avctx) | 880 static int truemotion1_decode_end(AVCodecContext *avctx) |
904 { | 881 { |
905 TrueMotion1Context *s = avctx->priv_data; | 882 TrueMotion1Context *s = avctx->priv_data; |
906 | 883 |
907 /* release the last frame */ | 884 if (s->frame.data[0]) |
908 if (s->prev_frame.data[0]) | 885 avctx->release_buffer(avctx, &s->frame); |
909 avctx->release_buffer(avctx, &s->prev_frame); | |
910 | 886 |
911 av_free(s->vert_pred); | 887 av_free(s->vert_pred); |
912 | 888 |
913 return 0; | 889 return 0; |
914 } | 890 } |