2 * huffyuv codec for libavcodec
4 * Copyright (c) 2002-2003 Michael Niedermayer <michaelni@gmx.at>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 * see http://www.pcisys.net/~melanson/codecs/huffyuv.txt for a description of
26 * huffyuv codec for libavcodec.
34 #define INT64_MAX 9223372036854775807LL
39 typedef enum Predictor{
45 typedef struct HYuvContext{
46 AVCodecContext *avctx;
54 int yuy2; //use yuy2 instead of 422P
55 int bgr32; //use bgr32 instead of bgr24
60 uint8_t __align8 temp[3][2500];
61 uint64_t stats[3][256];
63 uint32_t bits[3][256];
66 uint8_t __align8 bitstream_buffer[1024*1024*3]; //FIXME dynamic alloc or some other solution
70 static const unsigned char classic_shift_luma[] = {
71 34,36,35,69,135,232,9,16,10,24,11,23,12,16,13,10,14,8,15,8,
72 16,8,17,20,16,10,207,206,205,236,11,8,10,21,9,23,8,8,199,70,
76 static const unsigned char classic_shift_chroma[] = {
77 66,36,37,38,39,40,41,75,76,77,110,239,144,81,82,83,84,85,118,183,
78 56,57,88,89,56,89,154,57,58,57,26,141,57,56,58,57,58,57,184,119,
79 214,245,116,83,82,49,80,79,78,77,44,75,41,40,39,38,37,36,34, 0
82 static const unsigned char classic_add_luma[256] = {
83 3, 9, 5, 12, 10, 35, 32, 29, 27, 50, 48, 45, 44, 41, 39, 37,
84 73, 70, 68, 65, 64, 61, 58, 56, 53, 50, 49, 46, 44, 41, 38, 36,
85 68, 65, 63, 61, 58, 55, 53, 51, 48, 46, 45, 43, 41, 39, 38, 36,
86 35, 33, 32, 30, 29, 27, 26, 25, 48, 47, 46, 44, 43, 41, 40, 39,
87 37, 36, 35, 34, 32, 31, 30, 28, 27, 26, 24, 23, 22, 20, 19, 37,
88 35, 34, 33, 31, 30, 29, 27, 26, 24, 23, 21, 20, 18, 17, 15, 29,
89 27, 26, 24, 22, 21, 19, 17, 16, 14, 26, 25, 23, 21, 19, 18, 16,
90 15, 27, 25, 23, 21, 19, 17, 16, 14, 26, 25, 23, 21, 18, 17, 14,
91 12, 17, 19, 13, 4, 9, 2, 11, 1, 7, 8, 0, 16, 3, 14, 6,
92 12, 10, 5, 15, 18, 11, 10, 13, 15, 16, 19, 20, 22, 24, 27, 15,
93 18, 20, 22, 24, 26, 14, 17, 20, 22, 24, 27, 15, 18, 20, 23, 25,
94 28, 16, 19, 22, 25, 28, 32, 36, 21, 25, 29, 33, 38, 42, 45, 49,
95 28, 31, 34, 37, 40, 42, 44, 47, 49, 50, 52, 54, 56, 57, 59, 60,
96 62, 64, 66, 67, 69, 35, 37, 39, 40, 42, 43, 45, 47, 48, 51, 52,
97 54, 55, 57, 59, 60, 62, 63, 66, 67, 69, 71, 72, 38, 40, 42, 43,
98 46, 47, 49, 51, 26, 28, 30, 31, 33, 34, 18, 19, 11, 13, 7, 8,
101 static const unsigned char classic_add_chroma[256] = {
102 3, 1, 2, 2, 2, 2, 3, 3, 7, 5, 7, 5, 8, 6, 11, 9,
103 7, 13, 11, 10, 9, 8, 7, 5, 9, 7, 6, 4, 7, 5, 8, 7,
104 11, 8, 13, 11, 19, 15, 22, 23, 20, 33, 32, 28, 27, 29, 51, 77,
105 43, 45, 76, 81, 46, 82, 75, 55, 56,144, 58, 80, 60, 74,147, 63,
106 143, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
107 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 27, 30, 21, 22,
108 17, 14, 5, 6,100, 54, 47, 50, 51, 53,106,107,108,109,110,111,
109 112,113,114,115, 4,117,118, 92, 94,121,122, 3,124,103, 2, 1,
110 0,129,130,131,120,119,126,125,136,137,138,139,140,141,142,134,
111 135,132,133,104, 64,101, 62, 57,102, 95, 93, 59, 61, 28, 97, 96,
112 52, 49, 48, 29, 32, 25, 24, 46, 23, 98, 45, 44, 43, 20, 42, 41,
113 19, 18, 99, 40, 15, 39, 38, 16, 13, 12, 11, 37, 10, 9, 8, 36,
114 7,128,127,105,123,116, 35, 34, 33,145, 31, 79, 42,146, 78, 26,
115 83, 48, 49, 50, 44, 47, 26, 31, 30, 18, 17, 19, 21, 24, 25, 13,
116 14, 16, 17, 18, 20, 21, 12, 14, 15, 9, 10, 6, 9, 6, 5, 8,
117 6, 12, 8, 10, 7, 9, 6, 4, 6, 2, 2, 3, 3, 3, 3, 2,
120 static inline void bswap_buf(uint32_t *dst, uint32_t *src, int w){
123 for(i=0; i+8<=w; i+=8){
124 dst[i+0]= bswap_32(src[i+0]);
125 dst[i+1]= bswap_32(src[i+1]);
126 dst[i+2]= bswap_32(src[i+2]);
127 dst[i+3]= bswap_32(src[i+3]);
128 dst[i+4]= bswap_32(src[i+4]);
129 dst[i+5]= bswap_32(src[i+5]);
130 dst[i+6]= bswap_32(src[i+6]);
131 dst[i+7]= bswap_32(src[i+7]);
134 dst[i+0]= bswap_32(src[i+0]);
138 static inline int add_left_prediction(uint8_t *dst, uint8_t *src, int w, int acc){
141 for(i=0; i<w-1; i++){
157 static inline void add_median_prediction(uint8_t *dst, uint8_t *src1, uint8_t *diff, int w, int *left, int *left_top){
165 l= mid_pred(l, src1[i], (l + src1[i] - lt)&0xFF) + diff[i];
174 #ifdef CONFIG_ENCODERS
176 static inline void sub_median_prediction(uint8_t *dst, uint8_t *src1, uint8_t *src2, int w, int *left, int *left_top){
184 const int pred= mid_pred(l, src1[i], (l + src1[i] - lt)&0xFF);
194 #endif //CONFIG_ENCODERS
196 static inline void add_left_prediction_bgr32(uint8_t *dst, uint8_t *src, int w, int *red, int *green, int *blue){
218 #ifdef CONFIG_ENCODERS
219 static inline int sub_left_prediction(HYuvContext *s, uint8_t *dst, uint8_t *src, int w, int left){
223 const int temp= src[i];
230 const int temp= src[i];
234 s->dsp.diff_bytes(dst+16, src+16, src+15, w-16);
238 #endif //CONFIG_ENCODERS
239 static void read_len_table(uint8_t *dst, GetBitContext *gb){
243 repeat= get_bits(gb, 3);
244 val = get_bits(gb, 5);
246 repeat= get_bits(gb, 8);
247 //printf("%d %d\n", val, repeat);
253 static int generate_bits_table(uint32_t *dst, uint8_t *len_table){
257 for(len=32; len>0; len--){
258 int bit= 1<<(32-len);
259 for(index=0; index<256; index++){
260 if(len_table[index]==len){
262 fprintf(stderr, "Error generating huffman table\n");
265 dst[index]= bits>>(32-len);
273 #ifdef CONFIG_ENCODERS
275 static void generate_len_table(uint8_t *dst, uint64_t *stats, int size){
276 uint64_t counts[2*size];
280 for(offset=1; ; offset<<=1){
281 for(i=0; i<size; i++){
282 counts[i]= stats[i] + offset - 1;
285 for(next=size; next<size*2; next++){
289 min1=min2= INT64_MAX;
292 for(i=0; i<next; i++){
293 if(min2 > counts[i]){
294 if(min1 > counts[i]){
306 if(min2==INT64_MAX) break;
308 counts[next]= min1 + min2;
310 counts[min2_i]= INT64_MAX;
316 for(i=0; i<size; i++){
320 for(len=0; up[index] != -1; len++)
331 #endif //CONFIG_ENCODERS
333 static int read_huffman_tables(HYuvContext *s, uint8_t *src, int length){
337 init_get_bits(&gb, src, length*8);
340 read_len_table(s->len[i], &gb);
342 if(generate_bits_table(s->bits[i], s->len[i])<0){
346 for(j=0; j<256; j++){
347 printf("%6X, %2d, %3d\n", s->bits[i][j], s->len[i][j], j);
350 init_vlc(&s->vlc[i], VLC_BITS, 256, s->len[i], 1, 1, s->bits[i], 4, 4);
356 static int read_old_huffman_tables(HYuvContext *s){
361 init_get_bits(&gb, classic_shift_luma, sizeof(classic_shift_luma)*8);
362 read_len_table(s->len[0], &gb);
363 init_get_bits(&gb, classic_shift_chroma, sizeof(classic_shift_chroma)*8);
364 read_len_table(s->len[1], &gb);
366 for(i=0; i<256; i++) s->bits[0][i] = classic_add_luma [i];
367 for(i=0; i<256; i++) s->bits[1][i] = classic_add_chroma[i];
369 if(s->bitstream_bpp >= 24){
370 memcpy(s->bits[1], s->bits[0], 256*sizeof(uint32_t));
371 memcpy(s->len[1] , s->len [0], 256*sizeof(uint8_t));
373 memcpy(s->bits[2], s->bits[1], 256*sizeof(uint32_t));
374 memcpy(s->len[2] , s->len [1], 256*sizeof(uint8_t));
377 init_vlc(&s->vlc[i], VLC_BITS, 256, s->len[i], 1, 1, s->bits[i], 4, 4);
381 fprintf(stderr, "v1 huffyuv is not supported \n");
386 static int decode_init(AVCodecContext *avctx)
388 HYuvContext *s = avctx->priv_data;
392 s->flags= avctx->flags;
394 dsputil_init(&s->dsp, avctx);
396 width= s->width= avctx->width;
397 height= s->height= avctx->height;
398 avctx->coded_frame= &s->picture;
401 assert(width && height);
402 //if(avctx->extradata)
403 // printf("extradata:%X, extradata_size:%d\n", *(uint32_t*)avctx->extradata, avctx->extradata_size);
404 if(avctx->extradata_size){
405 if((avctx->bits_per_sample&7) && avctx->bits_per_sample != 12)
406 s->version=1; // do such files exist at all?
415 method= ((uint8_t*)avctx->extradata)[0];
416 s->decorrelate= method&64 ? 1 : 0;
417 s->predictor= method&63;
418 s->bitstream_bpp= ((uint8_t*)avctx->extradata)[1];
419 if(s->bitstream_bpp==0)
420 s->bitstream_bpp= avctx->bits_per_sample&~7;
422 if(read_huffman_tables(s, ((uint8_t*)avctx->extradata)+4, avctx->extradata_size) < 0)
425 switch(avctx->bits_per_sample&7){
436 s->decorrelate= avctx->bits_per_sample >= 24;
439 s->predictor= MEDIAN;
443 s->predictor= LEFT; //OLD
447 s->bitstream_bpp= avctx->bits_per_sample & ~7;
449 if(read_old_huffman_tables(s) < 0)
453 s->interlaced= height > 288;
455 switch(s->bitstream_bpp){
457 avctx->pix_fmt = PIX_FMT_YUV420P;
461 avctx->pix_fmt = PIX_FMT_YUV422;
463 avctx->pix_fmt = PIX_FMT_YUV422P;
469 avctx->pix_fmt = PIX_FMT_RGBA32;
471 avctx->pix_fmt = PIX_FMT_BGR24;
478 // printf("pred:%d bpp:%d hbpp:%d il:%d\n", s->predictor, s->bitstream_bpp, avctx->bits_per_sample, s->interlaced);
483 #ifdef CONFIG_ENCODERS
485 static void store_table(HYuvContext *s, uint8_t *len){
487 int index= s->avctx->extradata_size;
494 for(; i<256 && len[i]==val; i++);
499 ((uint8_t*)s->avctx->extradata)[index++]= val;
500 ((uint8_t*)s->avctx->extradata)[index++]= repeat;
502 ((uint8_t*)s->avctx->extradata)[index++]= val | (repeat<<5);
506 s->avctx->extradata_size= index;
509 static int encode_init(AVCodecContext *avctx)
511 HYuvContext *s = avctx->priv_data;
512 int i, j, width, height;
515 s->flags= avctx->flags;
517 dsputil_init(&s->dsp, avctx);
519 width= s->width= avctx->width;
520 height= s->height= avctx->height;
522 assert(width && height);
524 avctx->extradata= av_mallocz(1024*10);
525 avctx->stats_out= av_mallocz(1024*10);
528 avctx->coded_frame= &s->picture;
530 switch(avctx->pix_fmt){
531 case PIX_FMT_YUV420P:
532 if(avctx->strict_std_compliance>=0){
533 fprintf(stderr, "YV12-huffyuv is experimental, there WILL be no compatbility! (use (v)strict=-1)\n");
536 s->bitstream_bpp= 12;
538 case PIX_FMT_YUV422P:
539 s->bitstream_bpp= 16;
542 fprintf(stderr, "format not supported\n");
545 avctx->bits_per_sample= s->bitstream_bpp;
546 s->decorrelate= s->bitstream_bpp >= 24;
547 s->predictor= avctx->prediction_method;
549 ((uint8_t*)avctx->extradata)[0]= s->predictor;
550 ((uint8_t*)avctx->extradata)[1]= s->bitstream_bpp;
551 ((uint8_t*)avctx->extradata)[2]=
552 ((uint8_t*)avctx->extradata)[3]= 0;
553 s->avctx->extradata_size= 4;
556 char *p= avctx->stats_in;
566 for(j=0; j<256; j++){
567 s->stats[i][j]+= strtol(p, &next, 0);
568 if(next==p) return -1;
572 if(p[0]==0 || p[1]==0 || p[2]==0) break;
576 for(j=0; j<256; j++){
577 int d= FFMIN(j, 256-j);
579 s->stats[i][j]= 100000000/(d+1);
584 generate_len_table(s->len[i], s->stats[i], 256);
586 if(generate_bits_table(s->bits[i], s->len[i])<0){
590 store_table(s, s->len[i]);
597 s->interlaced= height > 288;
599 // printf("pred:%d bpp:%d hbpp:%d il:%d\n", s->predictor, s->bitstream_bpp, avctx->bits_per_sample, s->interlaced);
606 #endif //CONFIG_ENCODERS
608 static void decode_422_bitstream(HYuvContext *s, int count){
613 for(i=0; i<count; i++){
614 s->temp[0][2*i ]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3);
615 s->temp[1][ i ]= get_vlc2(&s->gb, s->vlc[1].table, VLC_BITS, 3);
616 s->temp[0][2*i+1]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3);
617 s->temp[2][ i ]= get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3);
621 static void decode_gray_bitstream(HYuvContext *s, int count){
626 for(i=0; i<count; i++){
627 s->temp[0][2*i ]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3);
628 s->temp[0][2*i+1]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3);
632 #ifdef CONFIG_ENCODERS
634 static void encode_422_bitstream(HYuvContext *s, int count){
638 if(s->flags&CODEC_FLAG_PASS1){
639 for(i=0; i<count; i++){
640 s->stats[0][ s->temp[0][2*i ] ]++;
641 s->stats[1][ s->temp[1][ i ] ]++;
642 s->stats[0][ s->temp[0][2*i+1] ]++;
643 s->stats[2][ s->temp[2][ i ] ]++;
646 for(i=0; i<count; i++){
647 put_bits(&s->pb, s->len[0][ s->temp[0][2*i ] ], s->bits[0][ s->temp[0][2*i ] ]);
648 put_bits(&s->pb, s->len[1][ s->temp[1][ i ] ], s->bits[1][ s->temp[1][ i ] ]);
649 put_bits(&s->pb, s->len[0][ s->temp[0][2*i+1] ], s->bits[0][ s->temp[0][2*i+1] ]);
650 put_bits(&s->pb, s->len[2][ s->temp[2][ i ] ], s->bits[2][ s->temp[2][ i ] ]);
655 static void encode_gray_bitstream(HYuvContext *s, int count){
659 if(s->flags&CODEC_FLAG_PASS1){
660 for(i=0; i<count; i++){
661 s->stats[0][ s->temp[0][2*i ] ]++;
662 s->stats[0][ s->temp[0][2*i+1] ]++;
665 for(i=0; i<count; i++){
666 put_bits(&s->pb, s->len[0][ s->temp[0][2*i ] ], s->bits[0][ s->temp[0][2*i ] ]);
667 put_bits(&s->pb, s->len[0][ s->temp[0][2*i+1] ], s->bits[0][ s->temp[0][2*i+1] ]);
672 #endif //CONFIG_ENCODERS
674 static void decode_bgr_bitstream(HYuvContext *s, int count){
678 if(s->bitstream_bpp==24){
679 for(i=0; i<count; i++){
680 s->temp[0][4*i+1]= get_vlc2(&s->gb, s->vlc[1].table, VLC_BITS, 3);
681 s->temp[0][4*i ]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3) + s->temp[0][4*i+1];
682 s->temp[0][4*i+2]= get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3) + s->temp[0][4*i+1];
685 for(i=0; i<count; i++){
686 s->temp[0][4*i+1]= get_vlc2(&s->gb, s->vlc[1].table, VLC_BITS, 3);
687 s->temp[0][4*i ]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3) + s->temp[0][4*i+1];
688 s->temp[0][4*i+2]= get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3) + s->temp[0][4*i+1];
689 get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3); //?!
693 if(s->bitstream_bpp==24){
694 for(i=0; i<count; i++){
695 s->temp[0][4*i ]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3);
696 s->temp[0][4*i+1]= get_vlc2(&s->gb, s->vlc[1].table, VLC_BITS, 3);
697 s->temp[0][4*i+2]= get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3);
700 for(i=0; i<count; i++){
701 s->temp[0][4*i ]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3);
702 s->temp[0][4*i+1]= get_vlc2(&s->gb, s->vlc[1].table, VLC_BITS, 3);
703 s->temp[0][4*i+2]= get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3);
704 get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3); //?!
710 static void draw_slice(HYuvContext *s, int y){
714 if(s->avctx->draw_horiz_band==NULL)
717 h= y - s->last_slice_end;
720 if(s->bitstream_bpp==12){
726 src_ptr[0] = s->picture.data[0] + s->picture.linesize[0]*y;
727 src_ptr[1] = s->picture.data[1] + s->picture.linesize[1]*cy;
728 src_ptr[2] = s->picture.data[2] + s->picture.linesize[2]*cy;
731 s->avctx->draw_horiz_band(s->avctx, src_ptr, s->picture.linesize[0], y, s->width, h);
733 s->last_slice_end= y + h;
736 static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8_t *buf, int buf_size){
737 HYuvContext *s = avctx->priv_data;
738 const int width= s->width;
739 const int width2= s->width>>1;
740 const int height= s->height;
741 int fake_ystride, fake_ustride, fake_vstride;
742 AVFrame * const p= &s->picture;
744 AVFrame *picture = data;
748 /* no supplementary picture */
752 bswap_buf((uint32_t*)s->bitstream_buffer, (uint32_t*)buf, buf_size/4);
754 init_get_bits(&s->gb, s->bitstream_buffer, buf_size*8);
757 avctx->release_buffer(avctx, p);
760 if(avctx->get_buffer(avctx, p) < 0){
761 fprintf(stderr, "get_buffer() failed\n");
765 fake_ystride= s->interlaced ? p->linesize[0]*2 : p->linesize[0];
766 fake_ustride= s->interlaced ? p->linesize[1]*2 : p->linesize[1];
767 fake_vstride= s->interlaced ? p->linesize[2]*2 : p->linesize[2];
769 s->last_slice_end= 0;
771 if(s->bitstream_bpp<24){
773 int lefty, leftu, leftv;
774 int lefttopy, lefttopu, lefttopv;
777 p->data[0][3]= get_bits(&s->gb, 8);
778 p->data[0][2]= get_bits(&s->gb, 8);
779 p->data[0][1]= get_bits(&s->gb, 8);
780 p->data[0][0]= get_bits(&s->gb, 8);
782 fprintf(stderr, "YUY2 output isnt implemenetd yet\n");
786 leftv= p->data[2][0]= get_bits(&s->gb, 8);
787 lefty= p->data[0][1]= get_bits(&s->gb, 8);
788 leftu= p->data[1][0]= get_bits(&s->gb, 8);
789 p->data[0][0]= get_bits(&s->gb, 8);
791 switch(s->predictor){
794 decode_422_bitstream(s, width-2);
795 lefty= add_left_prediction(p->data[0] + 2, s->temp[0], width-2, lefty);
796 if(!(s->flags&CODEC_FLAG_GRAY)){
797 leftu= add_left_prediction(p->data[1] + 1, s->temp[1], width2-1, leftu);
798 leftv= add_left_prediction(p->data[2] + 1, s->temp[2], width2-1, leftv);
801 for(cy=y=1; y<s->height; y++,cy++){
802 uint8_t *ydst, *udst, *vdst;
804 if(s->bitstream_bpp==12){
805 decode_gray_bitstream(s, width);
807 ydst= p->data[0] + p->linesize[0]*y;
809 lefty= add_left_prediction(ydst, s->temp[0], width, lefty);
810 if(s->predictor == PLANE){
812 s->dsp.add_bytes(ydst, ydst - fake_ystride, width);
815 if(y>=s->height) break;
820 ydst= p->data[0] + p->linesize[0]*y;
821 udst= p->data[1] + p->linesize[1]*cy;
822 vdst= p->data[2] + p->linesize[2]*cy;
824 decode_422_bitstream(s, width);
825 lefty= add_left_prediction(ydst, s->temp[0], width, lefty);
826 if(!(s->flags&CODEC_FLAG_GRAY)){
827 leftu= add_left_prediction(udst, s->temp[1], width2, leftu);
828 leftv= add_left_prediction(vdst, s->temp[2], width2, leftv);
830 if(s->predictor == PLANE){
831 if(cy>s->interlaced){
832 s->dsp.add_bytes(ydst, ydst - fake_ystride, width);
833 if(!(s->flags&CODEC_FLAG_GRAY)){
834 s->dsp.add_bytes(udst, udst - fake_ustride, width2);
835 s->dsp.add_bytes(vdst, vdst - fake_vstride, width2);
840 draw_slice(s, height);
844 /* first line except first 2 pixels is left predicted */
845 decode_422_bitstream(s, width-2);
846 lefty= add_left_prediction(p->data[0] + 2, s->temp[0], width-2, lefty);
847 if(!(s->flags&CODEC_FLAG_GRAY)){
848 leftu= add_left_prediction(p->data[1] + 1, s->temp[1], width2-1, leftu);
849 leftv= add_left_prediction(p->data[2] + 1, s->temp[2], width2-1, leftv);
854 /* second line is left predicted for interlaced case */
856 decode_422_bitstream(s, width);
857 lefty= add_left_prediction(p->data[0] + p->linesize[0], s->temp[0], width, lefty);
858 if(!(s->flags&CODEC_FLAG_GRAY)){
859 leftu= add_left_prediction(p->data[1] + p->linesize[2], s->temp[1], width2, leftu);
860 leftv= add_left_prediction(p->data[2] + p->linesize[1], s->temp[2], width2, leftv);
865 /* next 4 pixels are left predicted too */
866 decode_422_bitstream(s, 4);
867 lefty= add_left_prediction(p->data[0] + fake_ystride, s->temp[0], 4, lefty);
868 if(!(s->flags&CODEC_FLAG_GRAY)){
869 leftu= add_left_prediction(p->data[1] + fake_ustride, s->temp[1], 2, leftu);
870 leftv= add_left_prediction(p->data[2] + fake_vstride, s->temp[2], 2, leftv);
873 /* next line except the first 4 pixels is median predicted */
874 lefttopy= p->data[0][3];
875 decode_422_bitstream(s, width-4);
876 add_median_prediction(p->data[0] + fake_ystride+4, p->data[0]+4, s->temp[0], width-4, &lefty, &lefttopy);
877 if(!(s->flags&CODEC_FLAG_GRAY)){
878 lefttopu= p->data[1][1];
879 lefttopv= p->data[2][1];
880 add_median_prediction(p->data[1] + fake_ustride+2, p->data[1]+2, s->temp[1], width2-2, &leftu, &lefttopu);
881 add_median_prediction(p->data[2] + fake_vstride+2, p->data[2]+2, s->temp[2], width2-2, &leftv, &lefttopv);
885 for(; y<height; y++,cy++){
886 uint8_t *ydst, *udst, *vdst;
888 if(s->bitstream_bpp==12){
890 decode_gray_bitstream(s, width);
891 ydst= p->data[0] + p->linesize[0]*y;
892 add_median_prediction(ydst, ydst - fake_ystride, s->temp[0], width, &lefty, &lefttopy);
899 decode_422_bitstream(s, width);
901 ydst= p->data[0] + p->linesize[0]*y;
902 udst= p->data[1] + p->linesize[1]*cy;
903 vdst= p->data[2] + p->linesize[2]*cy;
905 add_median_prediction(ydst, ydst - fake_ystride, s->temp[0], width, &lefty, &lefttopy);
906 if(!(s->flags&CODEC_FLAG_GRAY)){
907 add_median_prediction(udst, udst - fake_ustride, s->temp[1], width2, &leftu, &lefttopu);
908 add_median_prediction(vdst, vdst - fake_vstride, s->temp[2], width2, &leftv, &lefttopv);
912 draw_slice(s, height);
918 int leftr, leftg, leftb;
919 const int last_line= (height-1)*p->linesize[0];
921 if(s->bitstream_bpp==32){
922 p->data[0][last_line+3]= get_bits(&s->gb, 8);
923 leftr= p->data[0][last_line+2]= get_bits(&s->gb, 8);
924 leftg= p->data[0][last_line+1]= get_bits(&s->gb, 8);
925 leftb= p->data[0][last_line+0]= get_bits(&s->gb, 8);
927 leftr= p->data[0][last_line+2]= get_bits(&s->gb, 8);
928 leftg= p->data[0][last_line+1]= get_bits(&s->gb, 8);
929 leftb= p->data[0][last_line+0]= get_bits(&s->gb, 8);
930 skip_bits(&s->gb, 8);
934 switch(s->predictor){
937 decode_bgr_bitstream(s, width-1);
938 add_left_prediction_bgr32(p->data[0] + last_line+4, s->temp[0], width-1, &leftr, &leftg, &leftb);
940 for(y=s->height-2; y>=0; y--){ //yes its stored upside down
941 decode_bgr_bitstream(s, width);
943 add_left_prediction_bgr32(p->data[0] + p->linesize[0]*y, s->temp[0], width, &leftr, &leftg, &leftb);
944 if(s->predictor == PLANE){
945 if((y&s->interlaced)==0){
946 s->dsp.add_bytes(p->data[0] + p->linesize[0]*y,
947 p->data[0] + p->linesize[0]*y + fake_ystride, fake_ystride);
951 draw_slice(s, height); // just 1 large slice as this isnt possible in reverse order
954 fprintf(stderr, "prediction type not supported!\n");
958 fprintf(stderr, "BGR24 output isnt implemenetd yet\n");
965 *data_size = sizeof(AVFrame);
967 return (get_bits_count(&s->gb)+31)/32*4;
970 static int decode_end(AVCodecContext *avctx)
972 HYuvContext *s = avctx->priv_data;
976 free_vlc(&s->vlc[i]);
979 avcodec_default_free_buffers(avctx);
984 #ifdef CONFIG_ENCODERS
986 static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){
987 HYuvContext *s = avctx->priv_data;
988 AVFrame *pict = data;
989 const int width= s->width;
990 const int width2= s->width>>1;
991 const int height= s->height;
992 const int fake_ystride= s->interlaced ? pict->linesize[0]*2 : pict->linesize[0];
993 const int fake_ustride= s->interlaced ? pict->linesize[1]*2 : pict->linesize[1];
994 const int fake_vstride= s->interlaced ? pict->linesize[2]*2 : pict->linesize[2];
995 AVFrame * const p= &s->picture;
998 init_put_bits(&s->pb, buf, buf_size, NULL, NULL);
1001 p->pict_type= FF_I_TYPE;
1004 if(avctx->pix_fmt == PIX_FMT_YUV422P || avctx->pix_fmt == PIX_FMT_YUV420P){
1005 int lefty, leftu, leftv, y, cy;
1007 put_bits(&s->pb, 8, leftv= p->data[2][0]);
1008 put_bits(&s->pb, 8, lefty= p->data[0][1]);
1009 put_bits(&s->pb, 8, leftu= p->data[1][0]);
1010 put_bits(&s->pb, 8, p->data[0][0]);
1012 lefty= sub_left_prediction(s, s->temp[0], p->data[0]+2, width-2 , lefty);
1013 leftu= sub_left_prediction(s, s->temp[1], p->data[1]+1, width2-1, leftu);
1014 leftv= sub_left_prediction(s, s->temp[2], p->data[2]+1, width2-1, leftv);
1016 encode_422_bitstream(s, width-2);
1018 if(s->predictor==MEDIAN){
1019 int lefttopy, lefttopu, lefttopv;
1022 lefty= sub_left_prediction(s, s->temp[0], p->data[0]+p->linesize[0], width , lefty);
1023 leftu= sub_left_prediction(s, s->temp[1], p->data[1]+p->linesize[1], width2, leftu);
1024 leftv= sub_left_prediction(s, s->temp[2], p->data[2]+p->linesize[2], width2, leftv);
1026 encode_422_bitstream(s, width);
1030 lefty= sub_left_prediction(s, s->temp[0], p->data[0]+fake_ystride, 4, lefty);
1031 leftu= sub_left_prediction(s, s->temp[1], p->data[1]+fake_ystride, 2, leftu);
1032 leftv= sub_left_prediction(s, s->temp[2], p->data[2]+fake_ystride, 2, leftv);
1034 encode_422_bitstream(s, 4);
1036 lefttopy= p->data[0][3];
1037 lefttopu= p->data[1][1];
1038 lefttopv= p->data[2][1];
1039 sub_median_prediction(s->temp[0], p->data[0]+4, p->data[0] + fake_ystride+4, width-4 , &lefty, &lefttopy);
1040 sub_median_prediction(s->temp[1], p->data[1]+2, p->data[1] + fake_ustride+2, width2-2, &leftu, &lefttopu);
1041 sub_median_prediction(s->temp[2], p->data[2]+2, p->data[2] + fake_vstride+2, width2-2, &leftv, &lefttopv);
1042 encode_422_bitstream(s, width-4);
1045 for(; y<height; y++,cy++){
1046 uint8_t *ydst, *udst, *vdst;
1048 if(s->bitstream_bpp==12){
1050 ydst= p->data[0] + p->linesize[0]*y;
1051 sub_median_prediction(s->temp[0], ydst - fake_ystride, ydst, width , &lefty, &lefttopy);
1052 encode_gray_bitstream(s, width);
1055 if(y>=height) break;
1057 ydst= p->data[0] + p->linesize[0]*y;
1058 udst= p->data[1] + p->linesize[1]*cy;
1059 vdst= p->data[2] + p->linesize[2]*cy;
1061 sub_median_prediction(s->temp[0], ydst - fake_ystride, ydst, width , &lefty, &lefttopy);
1062 sub_median_prediction(s->temp[1], udst - fake_ustride, udst, width2, &leftu, &lefttopu);
1063 sub_median_prediction(s->temp[2], vdst - fake_vstride, vdst, width2, &leftv, &lefttopv);
1065 encode_422_bitstream(s, width);
1068 for(cy=y=1; y<height; y++,cy++){
1069 uint8_t *ydst, *udst, *vdst;
1071 /* encode a luma only line & y++ */
1072 if(s->bitstream_bpp==12){
1073 ydst= p->data[0] + p->linesize[0]*y;
1075 if(s->predictor == PLANE && s->interlaced < y){
1076 s->dsp.diff_bytes(s->temp[1], ydst, ydst - fake_ystride, width);
1078 lefty= sub_left_prediction(s, s->temp[0], s->temp[1], width , lefty);
1080 lefty= sub_left_prediction(s, s->temp[0], ydst, width , lefty);
1082 encode_gray_bitstream(s, width);
1084 if(y>=height) break;
1087 ydst= p->data[0] + p->linesize[0]*y;
1088 udst= p->data[1] + p->linesize[1]*cy;
1089 vdst= p->data[2] + p->linesize[2]*cy;
1091 if(s->predictor == PLANE && s->interlaced < cy){
1092 s->dsp.diff_bytes(s->temp[1], ydst, ydst - fake_ystride, width);
1093 s->dsp.diff_bytes(s->temp[2], udst, udst - fake_ustride, width2);
1094 s->dsp.diff_bytes(s->temp[3], vdst, vdst - fake_vstride, width2);
1096 lefty= sub_left_prediction(s, s->temp[0], s->temp[1], width , lefty);
1097 leftu= sub_left_prediction(s, s->temp[1], s->temp[2], width2, leftu);
1098 leftv= sub_left_prediction(s, s->temp[2], s->temp[3], width2, leftv);
1100 lefty= sub_left_prediction(s, s->temp[0], ydst, width , lefty);
1101 leftu= sub_left_prediction(s, s->temp[1], udst, width2, leftu);
1102 leftv= sub_left_prediction(s, s->temp[2], vdst, width2, leftv);
1105 encode_422_bitstream(s, width);
1109 fprintf(stderr, "Format not supported!\n");
1113 size= (get_bit_count(&s->pb)+31)/32;
1115 if((s->flags&CODEC_FLAG_PASS1) && (s->picture_number&31)==0){
1117 char *p= avctx->stats_out;
1119 for(j=0; j<256; j++){
1120 sprintf(p, "%Ld ", s->stats[i][j]);
1128 flush_put_bits(&s->pb);
1129 bswap_buf((uint32_t*)buf, (uint32_t*)buf, size);
1132 s->picture_number++;
1137 static int encode_end(AVCodecContext *avctx)
1139 // HYuvContext *s = avctx->priv_data;
1141 av_freep(&avctx->extradata);
1142 av_freep(&avctx->stats_out);
1147 #endif //CONFIG_ENCODERS
1149 static const AVOption huffyuv_options[] =
1151 AVOPTION_CODEC_INT("prediction_method", "prediction_method", prediction_method, 0, 2, 0),
1155 AVCodec huffyuv_decoder = {
1159 sizeof(HYuvContext),
1164 CODEC_CAP_DR1 | CODEC_CAP_DRAW_HORIZ_BAND,
1168 #ifdef CONFIG_ENCODERS
1170 AVCodec huffyuv_encoder = {
1174 sizeof(HYuvContext),
1178 .options = huffyuv_options,
1181 #endif //CONFIG_ENCODERS