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][2560];
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 int add_left_prediction(uint8_t *dst, uint8_t *src, int w, int acc){
123 for(i=0; i<w-1; i++){
139 static inline void add_median_prediction(uint8_t *dst, uint8_t *src1, uint8_t *diff, int w, int *left, int *left_top){
147 l= mid_pred(l, src1[i], (l + src1[i] - lt)&0xFF) + diff[i];
156 static inline void add_left_prediction_bgr32(uint8_t *dst, uint8_t *src, int w, int *red, int *green, int *blue){
178 static inline int sub_left_prediction(HYuvContext *s, uint8_t *dst, uint8_t *src, int w, int left){
182 const int temp= src[i];
189 const int temp= src[i];
193 s->dsp.diff_bytes(dst+16, src+16, src+15, w-16);
198 static void read_len_table(uint8_t *dst, GetBitContext *gb){
202 repeat= get_bits(gb, 3);
203 val = get_bits(gb, 5);
205 repeat= get_bits(gb, 8);
206 //printf("%d %d\n", val, repeat);
212 static int generate_bits_table(uint32_t *dst, uint8_t *len_table){
216 for(len=32; len>0; len--){
217 for(index=0; index<256; index++){
218 if(len_table[index]==len)
222 av_log(NULL, AV_LOG_ERROR, "Error generating huffman table\n");
230 static void generate_len_table(uint8_t *dst, uint64_t *stats, int size){
231 uint64_t counts[2*size];
235 for(offset=1; ; offset<<=1){
236 for(i=0; i<size; i++){
237 counts[i]= stats[i] + offset - 1;
240 for(next=size; next<size*2; next++){
244 min1=min2= INT64_MAX;
247 for(i=0; i<next; i++){
248 if(min2 > counts[i]){
249 if(min1 > counts[i]){
261 if(min2==INT64_MAX) break;
263 counts[next]= min1 + min2;
265 counts[min2_i]= INT64_MAX;
271 for(i=0; i<size; i++){
275 for(len=0; up[index] != -1; len++)
286 static int read_huffman_tables(HYuvContext *s, uint8_t *src, int length){
290 init_get_bits(&gb, src, length*8);
293 read_len_table(s->len[i], &gb);
295 if(generate_bits_table(s->bits[i], s->len[i])<0){
299 for(j=0; j<256; j++){
300 printf("%6X, %2d, %3d\n", s->bits[i][j], s->len[i][j], j);
303 init_vlc(&s->vlc[i], VLC_BITS, 256, s->len[i], 1, 1, s->bits[i], 4, 4);
309 static int read_old_huffman_tables(HYuvContext *s){
314 init_get_bits(&gb, classic_shift_luma, sizeof(classic_shift_luma)*8);
315 read_len_table(s->len[0], &gb);
316 init_get_bits(&gb, classic_shift_chroma, sizeof(classic_shift_chroma)*8);
317 read_len_table(s->len[1], &gb);
319 for(i=0; i<256; i++) s->bits[0][i] = classic_add_luma [i];
320 for(i=0; i<256; i++) s->bits[1][i] = classic_add_chroma[i];
322 if(s->bitstream_bpp >= 24){
323 memcpy(s->bits[1], s->bits[0], 256*sizeof(uint32_t));
324 memcpy(s->len[1] , s->len [0], 256*sizeof(uint8_t));
326 memcpy(s->bits[2], s->bits[1], 256*sizeof(uint32_t));
327 memcpy(s->len[2] , s->len [1], 256*sizeof(uint8_t));
330 init_vlc(&s->vlc[i], VLC_BITS, 256, s->len[i], 1, 1, s->bits[i], 4, 4);
334 fprintf(stderr, "v1 huffyuv is not supported \n");
339 static int decode_init(AVCodecContext *avctx)
341 HYuvContext *s = avctx->priv_data;
345 s->flags= avctx->flags;
347 dsputil_init(&s->dsp, avctx);
349 width= s->width= avctx->width;
350 height= s->height= avctx->height;
351 avctx->coded_frame= &s->picture;
354 assert(width && height);
355 //if(avctx->extradata)
356 // printf("extradata:%X, extradata_size:%d\n", *(uint32_t*)avctx->extradata, avctx->extradata_size);
357 if(avctx->extradata_size){
358 if((avctx->bits_per_sample&7) && avctx->bits_per_sample != 12)
359 s->version=1; // do such files exist at all?
368 method= ((uint8_t*)avctx->extradata)[0];
369 s->decorrelate= method&64 ? 1 : 0;
370 s->predictor= method&63;
371 s->bitstream_bpp= ((uint8_t*)avctx->extradata)[1];
372 if(s->bitstream_bpp==0)
373 s->bitstream_bpp= avctx->bits_per_sample&~7;
375 if(read_huffman_tables(s, ((uint8_t*)avctx->extradata)+4, avctx->extradata_size) < 0)
378 switch(avctx->bits_per_sample&7){
389 s->decorrelate= avctx->bits_per_sample >= 24;
392 s->predictor= MEDIAN;
396 s->predictor= LEFT; //OLD
400 s->bitstream_bpp= avctx->bits_per_sample & ~7;
402 if(read_old_huffman_tables(s) < 0)
406 s->interlaced= height > 288;
408 switch(s->bitstream_bpp){
410 avctx->pix_fmt = PIX_FMT_YUV420P;
414 avctx->pix_fmt = PIX_FMT_YUV422;
416 avctx->pix_fmt = PIX_FMT_YUV422P;
422 avctx->pix_fmt = PIX_FMT_RGBA32;
424 avctx->pix_fmt = PIX_FMT_BGR24;
431 // printf("pred:%d bpp:%d hbpp:%d il:%d\n", s->predictor, s->bitstream_bpp, avctx->bits_per_sample, s->interlaced);
436 static void store_table(HYuvContext *s, uint8_t *len){
438 int index= s->avctx->extradata_size;
444 for(; i<256 && len[i]==val && repeat<255; i++)
447 assert(val < 32 && val >0 && repeat<256 && repeat>0);
449 ((uint8_t*)s->avctx->extradata)[index++]= val;
450 ((uint8_t*)s->avctx->extradata)[index++]= repeat;
452 ((uint8_t*)s->avctx->extradata)[index++]= val | (repeat<<5);
456 s->avctx->extradata_size= index;
459 static int encode_init(AVCodecContext *avctx)
461 HYuvContext *s = avctx->priv_data;
462 int i, j, width, height;
465 s->flags= avctx->flags;
467 dsputil_init(&s->dsp, avctx);
469 width= s->width= avctx->width;
470 height= s->height= avctx->height;
472 assert(width && height);
474 avctx->extradata= av_mallocz(1024*30);
475 avctx->stats_out= av_mallocz(1024*30);
478 avctx->coded_frame= &s->picture;
480 switch(avctx->pix_fmt){
481 case PIX_FMT_YUV420P:
482 if(avctx->strict_std_compliance>=0){
483 av_log(avctx, AV_LOG_ERROR, "YV12-huffyuv is experimental, there WILL be no compatbility! (use (v)strict=-1)\n");
486 s->bitstream_bpp= 12;
488 case PIX_FMT_YUV422P:
489 s->bitstream_bpp= 16;
492 av_log(avctx, AV_LOG_ERROR, "format not supported\n");
495 avctx->bits_per_sample= s->bitstream_bpp;
496 s->decorrelate= s->bitstream_bpp >= 24;
497 s->predictor= avctx->prediction_method;
499 ((uint8_t*)avctx->extradata)[0]= s->predictor;
500 ((uint8_t*)avctx->extradata)[1]= s->bitstream_bpp;
501 ((uint8_t*)avctx->extradata)[2]=
502 ((uint8_t*)avctx->extradata)[3]= 0;
503 s->avctx->extradata_size= 4;
506 char *p= avctx->stats_in;
516 for(j=0; j<256; j++){
517 s->stats[i][j]+= strtol(p, &next, 0);
518 if(next==p) return -1;
522 if(p[0]==0 || p[1]==0 || p[2]==0) break;
526 for(j=0; j<256; j++){
527 int d= FFMIN(j, 256-j);
529 s->stats[i][j]= 100000000/(d+1);
534 generate_len_table(s->len[i], s->stats[i], 256);
536 if(generate_bits_table(s->bits[i], s->len[i])<0){
540 store_table(s, s->len[i]);
547 s->interlaced= height > 288;
549 // printf("pred:%d bpp:%d hbpp:%d il:%d\n", s->predictor, s->bitstream_bpp, avctx->bits_per_sample, s->interlaced);
556 static void decode_422_bitstream(HYuvContext *s, int count){
561 for(i=0; i<count; i++){
562 s->temp[0][2*i ]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3);
563 s->temp[1][ i ]= get_vlc2(&s->gb, s->vlc[1].table, VLC_BITS, 3);
564 s->temp[0][2*i+1]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3);
565 s->temp[2][ i ]= get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3);
569 static void decode_gray_bitstream(HYuvContext *s, int count){
574 for(i=0; i<count; i++){
575 s->temp[0][2*i ]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3);
576 s->temp[0][2*i+1]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3);
580 static void encode_422_bitstream(HYuvContext *s, int count){
584 if(s->flags&CODEC_FLAG_PASS1){
585 for(i=0; i<count; i++){
586 s->stats[0][ s->temp[0][2*i ] ]++;
587 s->stats[1][ s->temp[1][ i ] ]++;
588 s->stats[0][ s->temp[0][2*i+1] ]++;
589 s->stats[2][ s->temp[2][ i ] ]++;
592 for(i=0; i<count; i++){
593 put_bits(&s->pb, s->len[0][ s->temp[0][2*i ] ], s->bits[0][ s->temp[0][2*i ] ]);
594 put_bits(&s->pb, s->len[1][ s->temp[1][ i ] ], s->bits[1][ s->temp[1][ i ] ]);
595 put_bits(&s->pb, s->len[0][ s->temp[0][2*i+1] ], s->bits[0][ s->temp[0][2*i+1] ]);
596 put_bits(&s->pb, s->len[2][ s->temp[2][ i ] ], s->bits[2][ s->temp[2][ i ] ]);
601 static void encode_gray_bitstream(HYuvContext *s, int count){
605 if(s->flags&CODEC_FLAG_PASS1){
606 for(i=0; i<count; i++){
607 s->stats[0][ s->temp[0][2*i ] ]++;
608 s->stats[0][ s->temp[0][2*i+1] ]++;
611 for(i=0; i<count; i++){
612 put_bits(&s->pb, s->len[0][ s->temp[0][2*i ] ], s->bits[0][ s->temp[0][2*i ] ]);
613 put_bits(&s->pb, s->len[0][ s->temp[0][2*i+1] ], s->bits[0][ s->temp[0][2*i+1] ]);
618 static void decode_bgr_bitstream(HYuvContext *s, int count){
622 if(s->bitstream_bpp==24){
623 for(i=0; i<count; i++){
624 s->temp[0][4*i+1]= get_vlc2(&s->gb, s->vlc[1].table, VLC_BITS, 3);
625 s->temp[0][4*i ]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3) + s->temp[0][4*i+1];
626 s->temp[0][4*i+2]= get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3) + s->temp[0][4*i+1];
629 for(i=0; i<count; i++){
630 s->temp[0][4*i+1]= get_vlc2(&s->gb, s->vlc[1].table, VLC_BITS, 3);
631 s->temp[0][4*i ]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3) + s->temp[0][4*i+1];
632 s->temp[0][4*i+2]= get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3) + s->temp[0][4*i+1];
633 get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3); //?!
637 if(s->bitstream_bpp==24){
638 for(i=0; i<count; i++){
639 s->temp[0][4*i ]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3);
640 s->temp[0][4*i+1]= get_vlc2(&s->gb, s->vlc[1].table, VLC_BITS, 3);
641 s->temp[0][4*i+2]= get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3);
644 for(i=0; i<count; i++){
645 s->temp[0][4*i ]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3);
646 s->temp[0][4*i+1]= get_vlc2(&s->gb, s->vlc[1].table, VLC_BITS, 3);
647 s->temp[0][4*i+2]= get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3);
648 get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3); //?!
654 static void draw_slice(HYuvContext *s, int y){
658 if(s->avctx->draw_horiz_band==NULL)
661 h= y - s->last_slice_end;
664 if(s->bitstream_bpp==12){
670 offset[0] = s->picture.linesize[0]*y;
671 offset[1] = s->picture.linesize[1]*cy;
672 offset[2] = s->picture.linesize[2]*cy;
676 s->avctx->draw_horiz_band(s->avctx, &s->picture, offset, y, 3, h);
678 s->last_slice_end= y + h;
681 static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8_t *buf, int buf_size){
682 HYuvContext *s = avctx->priv_data;
683 const int width= s->width;
684 const int width2= s->width>>1;
685 const int height= s->height;
686 int fake_ystride, fake_ustride, fake_vstride;
687 AVFrame * const p= &s->picture;
689 AVFrame *picture = data;
693 /* no supplementary picture */
697 s->dsp.bswap_buf((uint32_t*)s->bitstream_buffer, (uint32_t*)buf, buf_size/4);
699 init_get_bits(&s->gb, s->bitstream_buffer, buf_size*8);
702 avctx->release_buffer(avctx, p);
705 if(avctx->get_buffer(avctx, p) < 0){
706 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
710 fake_ystride= s->interlaced ? p->linesize[0]*2 : p->linesize[0];
711 fake_ustride= s->interlaced ? p->linesize[1]*2 : p->linesize[1];
712 fake_vstride= s->interlaced ? p->linesize[2]*2 : p->linesize[2];
714 s->last_slice_end= 0;
716 if(s->bitstream_bpp<24){
718 int lefty, leftu, leftv;
719 int lefttopy, lefttopu, lefttopv;
722 p->data[0][3]= get_bits(&s->gb, 8);
723 p->data[0][2]= get_bits(&s->gb, 8);
724 p->data[0][1]= get_bits(&s->gb, 8);
725 p->data[0][0]= get_bits(&s->gb, 8);
727 av_log(avctx, AV_LOG_ERROR, "YUY2 output isnt implemenetd yet\n");
731 leftv= p->data[2][0]= get_bits(&s->gb, 8);
732 lefty= p->data[0][1]= get_bits(&s->gb, 8);
733 leftu= p->data[1][0]= get_bits(&s->gb, 8);
734 p->data[0][0]= get_bits(&s->gb, 8);
736 switch(s->predictor){
739 decode_422_bitstream(s, width-2);
740 lefty= add_left_prediction(p->data[0] + 2, s->temp[0], width-2, lefty);
741 if(!(s->flags&CODEC_FLAG_GRAY)){
742 leftu= add_left_prediction(p->data[1] + 1, s->temp[1], width2-1, leftu);
743 leftv= add_left_prediction(p->data[2] + 1, s->temp[2], width2-1, leftv);
746 for(cy=y=1; y<s->height; y++,cy++){
747 uint8_t *ydst, *udst, *vdst;
749 if(s->bitstream_bpp==12){
750 decode_gray_bitstream(s, width);
752 ydst= p->data[0] + p->linesize[0]*y;
754 lefty= add_left_prediction(ydst, s->temp[0], width, lefty);
755 if(s->predictor == PLANE){
757 s->dsp.add_bytes(ydst, ydst - fake_ystride, width);
760 if(y>=s->height) break;
765 ydst= p->data[0] + p->linesize[0]*y;
766 udst= p->data[1] + p->linesize[1]*cy;
767 vdst= p->data[2] + p->linesize[2]*cy;
769 decode_422_bitstream(s, width);
770 lefty= add_left_prediction(ydst, s->temp[0], width, lefty);
771 if(!(s->flags&CODEC_FLAG_GRAY)){
772 leftu= add_left_prediction(udst, s->temp[1], width2, leftu);
773 leftv= add_left_prediction(vdst, s->temp[2], width2, leftv);
775 if(s->predictor == PLANE){
776 if(cy>s->interlaced){
777 s->dsp.add_bytes(ydst, ydst - fake_ystride, width);
778 if(!(s->flags&CODEC_FLAG_GRAY)){
779 s->dsp.add_bytes(udst, udst - fake_ustride, width2);
780 s->dsp.add_bytes(vdst, vdst - fake_vstride, width2);
785 draw_slice(s, height);
789 /* first line except first 2 pixels is left predicted */
790 decode_422_bitstream(s, width-2);
791 lefty= add_left_prediction(p->data[0] + 2, s->temp[0], width-2, lefty);
792 if(!(s->flags&CODEC_FLAG_GRAY)){
793 leftu= add_left_prediction(p->data[1] + 1, s->temp[1], width2-1, leftu);
794 leftv= add_left_prediction(p->data[2] + 1, s->temp[2], width2-1, leftv);
799 /* second line is left predicted for interlaced case */
801 decode_422_bitstream(s, width);
802 lefty= add_left_prediction(p->data[0] + p->linesize[0], s->temp[0], width, lefty);
803 if(!(s->flags&CODEC_FLAG_GRAY)){
804 leftu= add_left_prediction(p->data[1] + p->linesize[2], s->temp[1], width2, leftu);
805 leftv= add_left_prediction(p->data[2] + p->linesize[1], s->temp[2], width2, leftv);
810 /* next 4 pixels are left predicted too */
811 decode_422_bitstream(s, 4);
812 lefty= add_left_prediction(p->data[0] + fake_ystride, s->temp[0], 4, lefty);
813 if(!(s->flags&CODEC_FLAG_GRAY)){
814 leftu= add_left_prediction(p->data[1] + fake_ustride, s->temp[1], 2, leftu);
815 leftv= add_left_prediction(p->data[2] + fake_vstride, s->temp[2], 2, leftv);
818 /* next line except the first 4 pixels is median predicted */
819 lefttopy= p->data[0][3];
820 decode_422_bitstream(s, width-4);
821 add_median_prediction(p->data[0] + fake_ystride+4, p->data[0]+4, s->temp[0], width-4, &lefty, &lefttopy);
822 if(!(s->flags&CODEC_FLAG_GRAY)){
823 lefttopu= p->data[1][1];
824 lefttopv= p->data[2][1];
825 add_median_prediction(p->data[1] + fake_ustride+2, p->data[1]+2, s->temp[1], width2-2, &leftu, &lefttopu);
826 add_median_prediction(p->data[2] + fake_vstride+2, p->data[2]+2, s->temp[2], width2-2, &leftv, &lefttopv);
830 for(; y<height; y++,cy++){
831 uint8_t *ydst, *udst, *vdst;
833 if(s->bitstream_bpp==12){
835 decode_gray_bitstream(s, width);
836 ydst= p->data[0] + p->linesize[0]*y;
837 add_median_prediction(ydst, ydst - fake_ystride, s->temp[0], width, &lefty, &lefttopy);
844 decode_422_bitstream(s, width);
846 ydst= p->data[0] + p->linesize[0]*y;
847 udst= p->data[1] + p->linesize[1]*cy;
848 vdst= p->data[2] + p->linesize[2]*cy;
850 add_median_prediction(ydst, ydst - fake_ystride, s->temp[0], width, &lefty, &lefttopy);
851 if(!(s->flags&CODEC_FLAG_GRAY)){
852 add_median_prediction(udst, udst - fake_ustride, s->temp[1], width2, &leftu, &lefttopu);
853 add_median_prediction(vdst, vdst - fake_vstride, s->temp[2], width2, &leftv, &lefttopv);
857 draw_slice(s, height);
863 int leftr, leftg, leftb;
864 const int last_line= (height-1)*p->linesize[0];
866 if(s->bitstream_bpp==32){
867 p->data[0][last_line+3]= get_bits(&s->gb, 8);
868 leftr= p->data[0][last_line+2]= get_bits(&s->gb, 8);
869 leftg= p->data[0][last_line+1]= get_bits(&s->gb, 8);
870 leftb= p->data[0][last_line+0]= get_bits(&s->gb, 8);
872 leftr= p->data[0][last_line+2]= get_bits(&s->gb, 8);
873 leftg= p->data[0][last_line+1]= get_bits(&s->gb, 8);
874 leftb= p->data[0][last_line+0]= get_bits(&s->gb, 8);
875 skip_bits(&s->gb, 8);
879 switch(s->predictor){
882 decode_bgr_bitstream(s, width-1);
883 add_left_prediction_bgr32(p->data[0] + last_line+4, s->temp[0], width-1, &leftr, &leftg, &leftb);
885 for(y=s->height-2; y>=0; y--){ //yes its stored upside down
886 decode_bgr_bitstream(s, width);
888 add_left_prediction_bgr32(p->data[0] + p->linesize[0]*y, s->temp[0], width, &leftr, &leftg, &leftb);
889 if(s->predictor == PLANE){
890 if((y&s->interlaced)==0){
891 s->dsp.add_bytes(p->data[0] + p->linesize[0]*y,
892 p->data[0] + p->linesize[0]*y + fake_ystride, fake_ystride);
896 draw_slice(s, height); // just 1 large slice as this isnt possible in reverse order
899 av_log(avctx, AV_LOG_ERROR, "prediction type not supported!\n");
903 av_log(avctx, AV_LOG_ERROR, "BGR24 output isnt implemenetd yet\n");
910 *data_size = sizeof(AVFrame);
912 return (get_bits_count(&s->gb)+31)/32*4;
915 static int decode_end(AVCodecContext *avctx)
917 HYuvContext *s = avctx->priv_data;
921 free_vlc(&s->vlc[i]);
924 avcodec_default_free_buffers(avctx);
929 static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){
930 HYuvContext *s = avctx->priv_data;
931 AVFrame *pict = data;
932 const int width= s->width;
933 const int width2= s->width>>1;
934 const int height= s->height;
935 const int fake_ystride= s->interlaced ? pict->linesize[0]*2 : pict->linesize[0];
936 const int fake_ustride= s->interlaced ? pict->linesize[1]*2 : pict->linesize[1];
937 const int fake_vstride= s->interlaced ? pict->linesize[2]*2 : pict->linesize[2];
938 AVFrame * const p= &s->picture;
941 init_put_bits(&s->pb, buf, buf_size);
944 p->pict_type= FF_I_TYPE;
947 if(avctx->pix_fmt == PIX_FMT_YUV422P || avctx->pix_fmt == PIX_FMT_YUV420P){
948 int lefty, leftu, leftv, y, cy;
950 put_bits(&s->pb, 8, leftv= p->data[2][0]);
951 put_bits(&s->pb, 8, lefty= p->data[0][1]);
952 put_bits(&s->pb, 8, leftu= p->data[1][0]);
953 put_bits(&s->pb, 8, p->data[0][0]);
955 lefty= sub_left_prediction(s, s->temp[0], p->data[0]+2, width-2 , lefty);
956 leftu= sub_left_prediction(s, s->temp[1], p->data[1]+1, width2-1, leftu);
957 leftv= sub_left_prediction(s, s->temp[2], p->data[2]+1, width2-1, leftv);
959 encode_422_bitstream(s, width-2);
961 if(s->predictor==MEDIAN){
962 int lefttopy, lefttopu, lefttopv;
965 lefty= sub_left_prediction(s, s->temp[0], p->data[0]+p->linesize[0], width , lefty);
966 leftu= sub_left_prediction(s, s->temp[1], p->data[1]+p->linesize[1], width2, leftu);
967 leftv= sub_left_prediction(s, s->temp[2], p->data[2]+p->linesize[2], width2, leftv);
969 encode_422_bitstream(s, width);
973 lefty= sub_left_prediction(s, s->temp[0], p->data[0]+fake_ystride, 4, lefty);
974 leftu= sub_left_prediction(s, s->temp[1], p->data[1]+fake_ystride, 2, leftu);
975 leftv= sub_left_prediction(s, s->temp[2], p->data[2]+fake_ystride, 2, leftv);
977 encode_422_bitstream(s, 4);
979 lefttopy= p->data[0][3];
980 lefttopu= p->data[1][1];
981 lefttopv= p->data[2][1];
982 s->dsp.sub_hfyu_median_prediction(s->temp[0], p->data[0]+4, p->data[0] + fake_ystride+4, width-4 , &lefty, &lefttopy);
983 s->dsp.sub_hfyu_median_prediction(s->temp[1], p->data[1]+2, p->data[1] + fake_ustride+2, width2-2, &leftu, &lefttopu);
984 s->dsp.sub_hfyu_median_prediction(s->temp[2], p->data[2]+2, p->data[2] + fake_vstride+2, width2-2, &leftv, &lefttopv);
985 encode_422_bitstream(s, width-4);
988 for(; y<height; y++,cy++){
989 uint8_t *ydst, *udst, *vdst;
991 if(s->bitstream_bpp==12){
993 ydst= p->data[0] + p->linesize[0]*y;
994 s->dsp.sub_hfyu_median_prediction(s->temp[0], ydst - fake_ystride, ydst, width , &lefty, &lefttopy);
995 encode_gray_bitstream(s, width);
1000 ydst= p->data[0] + p->linesize[0]*y;
1001 udst= p->data[1] + p->linesize[1]*cy;
1002 vdst= p->data[2] + p->linesize[2]*cy;
1004 s->dsp.sub_hfyu_median_prediction(s->temp[0], ydst - fake_ystride, ydst, width , &lefty, &lefttopy);
1005 s->dsp.sub_hfyu_median_prediction(s->temp[1], udst - fake_ustride, udst, width2, &leftu, &lefttopu);
1006 s->dsp.sub_hfyu_median_prediction(s->temp[2], vdst - fake_vstride, vdst, width2, &leftv, &lefttopv);
1008 encode_422_bitstream(s, width);
1011 for(cy=y=1; y<height; y++,cy++){
1012 uint8_t *ydst, *udst, *vdst;
1014 /* encode a luma only line & y++ */
1015 if(s->bitstream_bpp==12){
1016 ydst= p->data[0] + p->linesize[0]*y;
1018 if(s->predictor == PLANE && s->interlaced < y){
1019 s->dsp.diff_bytes(s->temp[1], ydst, ydst - fake_ystride, width);
1021 lefty= sub_left_prediction(s, s->temp[0], s->temp[1], width , lefty);
1023 lefty= sub_left_prediction(s, s->temp[0], ydst, width , lefty);
1025 encode_gray_bitstream(s, width);
1027 if(y>=height) break;
1030 ydst= p->data[0] + p->linesize[0]*y;
1031 udst= p->data[1] + p->linesize[1]*cy;
1032 vdst= p->data[2] + p->linesize[2]*cy;
1034 if(s->predictor == PLANE && s->interlaced < cy){
1035 s->dsp.diff_bytes(s->temp[1], ydst, ydst - fake_ystride, width);
1036 s->dsp.diff_bytes(s->temp[2], udst, udst - fake_ustride, width2);
1037 s->dsp.diff_bytes(s->temp[2] + 1250, vdst, vdst - fake_vstride, width2);
1039 lefty= sub_left_prediction(s, s->temp[0], s->temp[1], width , lefty);
1040 leftu= sub_left_prediction(s, s->temp[1], s->temp[2], width2, leftu);
1041 leftv= sub_left_prediction(s, s->temp[2], s->temp[2] + 1250, width2, leftv);
1043 lefty= sub_left_prediction(s, s->temp[0], ydst, width , lefty);
1044 leftu= sub_left_prediction(s, s->temp[1], udst, width2, leftu);
1045 leftv= sub_left_prediction(s, s->temp[2], vdst, width2, leftv);
1048 encode_422_bitstream(s, width);
1052 av_log(avctx, AV_LOG_ERROR, "Format not supported!\n");
1056 size= (get_bit_count(&s->pb)+31)/32;
1058 if((s->flags&CODEC_FLAG_PASS1) && (s->picture_number&31)==0){
1060 char *p= avctx->stats_out;
1062 for(j=0; j<256; j++){
1063 sprintf(p, "%llu ", s->stats[i][j]);
1071 flush_put_bits(&s->pb);
1072 s->dsp.bswap_buf((uint32_t*)buf, (uint32_t*)buf, size);
1075 s->picture_number++;
1080 static int encode_end(AVCodecContext *avctx)
1082 // HYuvContext *s = avctx->priv_data;
1084 av_freep(&avctx->extradata);
1085 av_freep(&avctx->stats_out);
1090 static const AVOption huffyuv_options[] =
1092 AVOPTION_CODEC_INT("prediction_method", "prediction_method", prediction_method, 0, 2, 0),
1096 AVCodec huffyuv_decoder = {
1100 sizeof(HYuvContext),
1105 CODEC_CAP_DR1 | CODEC_CAP_DRAW_HORIZ_BAND,
1109 #ifdef CONFIG_ENCODERS
1111 AVCodec huffyuv_encoder = {
1115 sizeof(HYuvContext),
1119 .options = huffyuv_options,
1122 #endif //CONFIG_ENCODERS