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
29 #define INT64_MAX 9223372036854775807LL
34 typedef enum Predictor{
40 typedef struct HYuvContext{
41 AVCodecContext *avctx;
49 int yuy2; //use yuy2 instead of 422P
50 int bgr32; //use bgr32 instead of bgr24
55 uint8_t __align8 temp[3][2500];
56 uint64_t stats[3][256];
58 uint32_t bits[3][256];
61 uint8_t __align8 bitstream_buffer[1024*1024*3]; //FIXME dynamic alloc or some other solution
65 static inline void bswap_buf(uint32_t *dst, uint32_t *src, int w){
68 for(i=0; i+8<=w; i+=8){
69 dst[i+0]= bswap_32(src[i+0]);
70 dst[i+1]= bswap_32(src[i+1]);
71 dst[i+2]= bswap_32(src[i+2]);
72 dst[i+3]= bswap_32(src[i+3]);
73 dst[i+4]= bswap_32(src[i+4]);
74 dst[i+5]= bswap_32(src[i+5]);
75 dst[i+6]= bswap_32(src[i+6]);
76 dst[i+7]= bswap_32(src[i+7]);
79 dst[i+0]= bswap_32(src[i+0]);
83 static inline int add_left_prediction(uint8_t *dst, uint8_t *src, int w, int acc){
102 static inline void add_median_prediction(uint8_t *dst, uint8_t *src1, uint8_t *diff, int w, int *left, int *left_top){
110 l= mid_pred(l, src1[i], (l + src1[i] - lt)&0xFF) + diff[i];
119 static inline void sub_median_prediction(uint8_t *dst, uint8_t *src1, uint8_t *src2, int w, int *left, int *left_top){
127 const int pred= mid_pred(l, src1[i], (l + src1[i] - lt)&0xFF);
138 static inline void add_left_prediction_bgr32(uint8_t *dst, uint8_t *src, int w, int *red, int *green, int *blue){
160 static inline int sub_left_prediction(HYuvContext *s, uint8_t *dst, uint8_t *src, int w, int left){
164 const int temp= src[i];
171 const int temp= src[i];
175 s->dsp.diff_bytes(dst+16, src+16, src+15, w-16);
180 static void read_len_table(uint8_t *dst, GetBitContext *gb){
184 repeat= get_bits(gb, 3);
185 val = get_bits(gb, 5);
187 repeat= get_bits(gb, 8);
188 //printf("%d %d\n", val, repeat);
194 static int generate_bits_table(uint32_t *dst, uint8_t *len_table){
198 for(len=32; len>0; len--){
199 int bit= 1<<(32-len);
200 for(index=0; index<256; index++){
201 if(len_table[index]==len){
203 fprintf(stderr, "Error generating huffman table\n");
206 dst[index]= bits>>(32-len);
214 static void generate_len_table(uint8_t *dst, uint64_t *stats, int size){
215 uint64_t counts[2*size];
219 for(offset=1; ; offset<<=1){
220 for(i=0; i<size; i++){
221 counts[i]= stats[i] + offset - 1;
224 for(next=size; next<size*2; next++){
228 min1=min2= INT64_MAX;
231 for(i=0; i<next; i++){
232 if(min2 > counts[i]){
233 if(min1 > counts[i]){
245 if(min2==INT64_MAX) break;
247 counts[next]= min1 + min2;
249 counts[min2_i]= INT64_MAX;
255 for(i=0; i<size; i++){
259 for(len=0; up[index] != -1; len++)
270 static int read_huffman_tables(HYuvContext *s, uint8_t *src, int length){
274 init_get_bits(&gb, src, length*8);
277 read_len_table(s->len[i], &gb);
279 if(generate_bits_table(s->bits[i], s->len[i])<0){
283 for(j=0; j<256; j++){
284 printf("%6X, %2d, %3d\n", s->bits[i][j], s->len[i][j], j);
287 init_vlc(&s->vlc[i], VLC_BITS, 256, s->len[i], 1, 1, s->bits[i], 4, 4);
293 static int read_old_huffman_tables(HYuvContext *s){
298 init_get_bits(&gb, classic_shift_luma, sizeof(classic_shift_luma)*8);
299 read_len_table(s->len[0], &gb);
300 init_get_bits(&gb, classic_shift_chroma, sizeof(classic_shift_chroma)*8);
301 read_len_table(s->len[1], &gb);
303 for(i=0; i<256; i++) s->bits[0][i] = classic_add_luma [i];
304 for(i=0; i<256; i++) s->bits[1][i] = classic_add_chroma[i];
306 if(s->bitstream_bpp >= 24){
307 memcpy(s->bits[1], s->bits[0], 256*sizeof(uint32_t));
308 memcpy(s->len[1] , s->len [0], 256*sizeof(uint8_t));
310 memcpy(s->bits[2], s->bits[1], 256*sizeof(uint32_t));
311 memcpy(s->len[2] , s->len [1], 256*sizeof(uint8_t));
314 init_vlc(&s->vlc[i], VLC_BITS, 256, s->len[i], 1, 1, s->bits[i], 4, 4);
318 fprintf(stderr, "v1 huffyuv is not supported \n");
323 static int decode_init(AVCodecContext *avctx)
325 HYuvContext *s = avctx->priv_data;
329 s->flags= avctx->flags;
331 dsputil_init(&s->dsp, avctx->dsp_mask);
333 width= s->width= avctx->width;
334 height= s->height= avctx->height;
335 avctx->coded_frame= &s->picture;
338 assert(width && height);
339 //if(avctx->extradata)
340 // printf("extradata:%X, extradata_size:%d\n", *(uint32_t*)avctx->extradata, avctx->extradata_size);
341 if(avctx->extradata_size){
342 if((avctx->bits_per_sample&7) && avctx->bits_per_sample != 12)
343 s->version=1; // do such files exist at all?
352 method= ((uint8_t*)avctx->extradata)[0];
353 s->decorrelate= method&64 ? 1 : 0;
354 s->predictor= method&63;
355 s->bitstream_bpp= ((uint8_t*)avctx->extradata)[1];
356 if(s->bitstream_bpp==0)
357 s->bitstream_bpp= avctx->bits_per_sample&~7;
359 if(read_huffman_tables(s, ((uint8_t*)avctx->extradata)+4, avctx->extradata_size) < 0)
362 switch(avctx->bits_per_sample&7){
373 s->decorrelate= avctx->bits_per_sample >= 24;
376 s->predictor= MEDIAN;
380 s->predictor= LEFT; //OLD
384 s->bitstream_bpp= avctx->bits_per_sample & ~7;
386 if(read_old_huffman_tables(s) < 0)
390 s->interlaced= height > 288;
392 switch(s->bitstream_bpp){
394 avctx->pix_fmt = PIX_FMT_YUV420P;
398 avctx->pix_fmt = PIX_FMT_YUV422;
400 avctx->pix_fmt = PIX_FMT_YUV422P;
406 avctx->pix_fmt = PIX_FMT_RGBA32;
408 avctx->pix_fmt = PIX_FMT_BGR24;
415 // printf("pred:%d bpp:%d hbpp:%d il:%d\n", s->predictor, s->bitstream_bpp, avctx->bits_per_sample, s->interlaced);
420 static void store_table(HYuvContext *s, uint8_t *len){
422 int index= s->avctx->extradata_size;
429 for(; i<256 && len[i]==val; i++);
434 ((uint8_t*)s->avctx->extradata)[index++]= val;
435 ((uint8_t*)s->avctx->extradata)[index++]= repeat;
437 ((uint8_t*)s->avctx->extradata)[index++]= val | (repeat<<5);
441 s->avctx->extradata_size= index;
444 static int encode_init(AVCodecContext *avctx)
446 HYuvContext *s = avctx->priv_data;
447 int i, j, width, height;
450 s->flags= avctx->flags;
452 dsputil_init(&s->dsp, avctx->dsp_mask);
454 width= s->width= avctx->width;
455 height= s->height= avctx->height;
457 assert(width && height);
459 avctx->extradata= av_mallocz(1024*10);
460 avctx->stats_out= av_mallocz(1024*10);
463 avctx->coded_frame= &s->picture;
465 switch(avctx->pix_fmt){
466 case PIX_FMT_YUV420P:
467 if(avctx->strict_std_compliance>=0){
468 fprintf(stderr, "YV12-huffyuv is experimental, there WILL be no compatbility! (use (v)strict=-1)\n");
471 s->bitstream_bpp= 12;
473 case PIX_FMT_YUV422P:
474 s->bitstream_bpp= 16;
477 fprintf(stderr, "format not supported\n");
480 avctx->bits_per_sample= s->bitstream_bpp;
481 s->decorrelate= s->bitstream_bpp >= 24;
482 s->predictor= avctx->prediction_method;
484 ((uint8_t*)avctx->extradata)[0]= s->predictor;
485 ((uint8_t*)avctx->extradata)[1]= s->bitstream_bpp;
486 ((uint8_t*)avctx->extradata)[2]=
487 ((uint8_t*)avctx->extradata)[3]= 0;
488 s->avctx->extradata_size= 4;
491 char *p= avctx->stats_in;
501 for(j=0; j<256; j++){
502 s->stats[i][j]+= strtol(p, &next, 0);
503 if(next==p) return -1;
507 if(p[0]==0 || p[1]==0 || p[2]==0) break;
511 for(j=0; j<256; j++){
512 int d= FFMIN(j, 256-j);
514 s->stats[i][j]= 100000000/(d+1);
519 generate_len_table(s->len[i], s->stats[i], 256);
521 if(generate_bits_table(s->bits[i], s->len[i])<0){
525 store_table(s, s->len[i]);
532 s->interlaced= height > 288;
534 // printf("pred:%d bpp:%d hbpp:%d il:%d\n", s->predictor, s->bitstream_bpp, avctx->bits_per_sample, s->interlaced);
541 static void decode_422_bitstream(HYuvContext *s, int count){
546 for(i=0; i<count; i++){
547 s->temp[0][2*i ]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3);
548 s->temp[1][ i ]= get_vlc2(&s->gb, s->vlc[1].table, VLC_BITS, 3);
549 s->temp[0][2*i+1]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3);
550 s->temp[2][ i ]= get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3);
554 static void decode_gray_bitstream(HYuvContext *s, int count){
559 for(i=0; i<count; i++){
560 s->temp[0][2*i ]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3);
561 s->temp[0][2*i+1]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3);
565 static void encode_422_bitstream(HYuvContext *s, int count){
569 if(s->flags&CODEC_FLAG_PASS1){
570 for(i=0; i<count; i++){
571 s->stats[0][ s->temp[0][2*i ] ]++;
572 s->stats[1][ s->temp[1][ i ] ]++;
573 s->stats[0][ s->temp[0][2*i+1] ]++;
574 s->stats[2][ s->temp[2][ i ] ]++;
577 for(i=0; i<count; i++){
578 put_bits(&s->pb, s->len[0][ s->temp[0][2*i ] ], s->bits[0][ s->temp[0][2*i ] ]);
579 put_bits(&s->pb, s->len[1][ s->temp[1][ i ] ], s->bits[1][ s->temp[1][ i ] ]);
580 put_bits(&s->pb, s->len[0][ s->temp[0][2*i+1] ], s->bits[0][ s->temp[0][2*i+1] ]);
581 put_bits(&s->pb, s->len[2][ s->temp[2][ i ] ], s->bits[2][ s->temp[2][ i ] ]);
586 static void encode_gray_bitstream(HYuvContext *s, int count){
590 if(s->flags&CODEC_FLAG_PASS1){
591 for(i=0; i<count; i++){
592 s->stats[0][ s->temp[0][2*i ] ]++;
593 s->stats[0][ s->temp[0][2*i+1] ]++;
596 for(i=0; i<count; i++){
597 put_bits(&s->pb, s->len[0][ s->temp[0][2*i ] ], s->bits[0][ s->temp[0][2*i ] ]);
598 put_bits(&s->pb, s->len[0][ s->temp[0][2*i+1] ], s->bits[0][ s->temp[0][2*i+1] ]);
603 static void decode_bgr_bitstream(HYuvContext *s, int count){
607 if(s->bitstream_bpp==24){
608 for(i=0; i<count; i++){
609 s->temp[0][4*i+1]= get_vlc2(&s->gb, s->vlc[1].table, VLC_BITS, 3);
610 s->temp[0][4*i ]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3) + s->temp[0][4*i+1];
611 s->temp[0][4*i+2]= get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3) + s->temp[0][4*i+1];
614 for(i=0; i<count; i++){
615 s->temp[0][4*i+1]= get_vlc2(&s->gb, s->vlc[1].table, VLC_BITS, 3);
616 s->temp[0][4*i ]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3) + s->temp[0][4*i+1];
617 s->temp[0][4*i+2]= get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3) + s->temp[0][4*i+1];
618 get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3); //?!
622 if(s->bitstream_bpp==24){
623 for(i=0; i<count; i++){
624 s->temp[0][4*i ]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3);
625 s->temp[0][4*i+1]= get_vlc2(&s->gb, s->vlc[1].table, VLC_BITS, 3);
626 s->temp[0][4*i+2]= get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3);
629 for(i=0; i<count; i++){
630 s->temp[0][4*i ]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3);
631 s->temp[0][4*i+1]= get_vlc2(&s->gb, s->vlc[1].table, VLC_BITS, 3);
632 s->temp[0][4*i+2]= get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3);
633 get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3); //?!
639 static void draw_slice(HYuvContext *s, int y){
643 if(s->avctx->draw_horiz_band==NULL)
646 h= y - s->last_slice_end;
649 if(s->bitstream_bpp==12){
655 src_ptr[0] = s->picture.data[0] + s->picture.linesize[0]*y;
656 src_ptr[1] = s->picture.data[1] + s->picture.linesize[1]*cy;
657 src_ptr[2] = s->picture.data[2] + s->picture.linesize[2]*cy;
660 s->avctx->draw_horiz_band(s->avctx, src_ptr, s->picture.linesize[0], y, s->width, h);
662 s->last_slice_end= y + h;
665 static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8_t *buf, int buf_size){
666 HYuvContext *s = avctx->priv_data;
667 const int width= s->width;
668 const int width2= s->width>>1;
669 const int height= s->height;
670 int fake_ystride, fake_ustride, fake_vstride;
671 AVFrame * const p= &s->picture;
673 AVFrame *picture = data;
677 /* no supplementary picture */
681 bswap_buf((uint32_t*)s->bitstream_buffer, (uint32_t*)buf, buf_size/4);
683 init_get_bits(&s->gb, s->bitstream_buffer, buf_size*8);
686 if(avctx->get_buffer(avctx, p) < 0){
687 fprintf(stderr, "get_buffer() failed\n");
691 fake_ystride= s->interlaced ? p->linesize[0]*2 : p->linesize[0];
692 fake_ustride= s->interlaced ? p->linesize[1]*2 : p->linesize[1];
693 fake_vstride= s->interlaced ? p->linesize[2]*2 : p->linesize[2];
695 s->last_slice_end= 0;
697 if(s->bitstream_bpp<24){
699 int lefty, leftu, leftv;
700 int lefttopy, lefttopu, lefttopv;
703 p->data[0][3]= get_bits(&s->gb, 8);
704 p->data[0][2]= get_bits(&s->gb, 8);
705 p->data[0][1]= get_bits(&s->gb, 8);
706 p->data[0][0]= get_bits(&s->gb, 8);
708 fprintf(stderr, "YUY2 output isnt implemenetd yet\n");
712 leftv= p->data[2][0]= get_bits(&s->gb, 8);
713 lefty= p->data[0][1]= get_bits(&s->gb, 8);
714 leftu= p->data[1][0]= get_bits(&s->gb, 8);
715 p->data[0][0]= get_bits(&s->gb, 8);
717 switch(s->predictor){
720 decode_422_bitstream(s, width-2);
721 lefty= add_left_prediction(p->data[0] + 2, s->temp[0], width-2, lefty);
722 if(!(s->flags&CODEC_FLAG_GRAY)){
723 leftu= add_left_prediction(p->data[1] + 1, s->temp[1], width2-1, leftu);
724 leftv= add_left_prediction(p->data[2] + 1, s->temp[2], width2-1, leftv);
727 for(cy=y=1; y<s->height; y++,cy++){
728 uint8_t *ydst, *udst, *vdst;
730 if(s->bitstream_bpp==12){
731 decode_gray_bitstream(s, width);
733 ydst= p->data[0] + p->linesize[0]*y;
735 lefty= add_left_prediction(ydst, s->temp[0], width, lefty);
736 if(s->predictor == PLANE){
738 s->dsp.add_bytes(ydst, ydst - fake_ystride, width);
741 if(y>=s->height) break;
746 ydst= p->data[0] + p->linesize[0]*y;
747 udst= p->data[1] + p->linesize[1]*cy;
748 vdst= p->data[2] + p->linesize[2]*cy;
750 decode_422_bitstream(s, width);
751 lefty= add_left_prediction(ydst, s->temp[0], width, lefty);
752 if(!(s->flags&CODEC_FLAG_GRAY)){
753 leftu= add_left_prediction(udst, s->temp[1], width2, leftu);
754 leftv= add_left_prediction(vdst, s->temp[2], width2, leftv);
756 if(s->predictor == PLANE){
757 if(cy>s->interlaced){
758 s->dsp.add_bytes(ydst, ydst - fake_ystride, width);
759 if(!(s->flags&CODEC_FLAG_GRAY)){
760 s->dsp.add_bytes(udst, udst - fake_ustride, width2);
761 s->dsp.add_bytes(vdst, vdst - fake_vstride, width2);
766 draw_slice(s, height);
770 /* first line except first 2 pixels is left predicted */
771 decode_422_bitstream(s, width-2);
772 lefty= add_left_prediction(p->data[0] + 2, s->temp[0], width-2, lefty);
773 if(!(s->flags&CODEC_FLAG_GRAY)){
774 leftu= add_left_prediction(p->data[1] + 1, s->temp[1], width2-1, leftu);
775 leftv= add_left_prediction(p->data[2] + 1, s->temp[2], width2-1, leftv);
780 /* second line is left predicted for interlaced case */
782 decode_422_bitstream(s, width);
783 lefty= add_left_prediction(p->data[0] + p->linesize[0], s->temp[0], width, lefty);
784 if(!(s->flags&CODEC_FLAG_GRAY)){
785 leftu= add_left_prediction(p->data[1] + p->linesize[2], s->temp[1], width2, leftu);
786 leftv= add_left_prediction(p->data[2] + p->linesize[1], s->temp[2], width2, leftv);
791 /* next 4 pixels are left predicted too */
792 decode_422_bitstream(s, 4);
793 lefty= add_left_prediction(p->data[0] + fake_ystride, s->temp[0], 4, lefty);
794 if(!(s->flags&CODEC_FLAG_GRAY)){
795 leftu= add_left_prediction(p->data[1] + fake_ustride, s->temp[1], 2, leftu);
796 leftv= add_left_prediction(p->data[2] + fake_vstride, s->temp[2], 2, leftv);
799 /* next line except the first 4 pixels is median predicted */
800 lefttopy= p->data[0][3];
801 decode_422_bitstream(s, width-4);
802 add_median_prediction(p->data[0] + fake_ystride+4, p->data[0]+4, s->temp[0], width-4, &lefty, &lefttopy);
803 if(!(s->flags&CODEC_FLAG_GRAY)){
804 lefttopu= p->data[1][1];
805 lefttopv= p->data[2][1];
806 add_median_prediction(p->data[1] + fake_ustride+2, p->data[1]+2, s->temp[1], width2-2, &leftu, &lefttopu);
807 add_median_prediction(p->data[2] + fake_vstride+2, p->data[2]+2, s->temp[2], width2-2, &leftv, &lefttopv);
811 for(; y<height; y++,cy++){
812 uint8_t *ydst, *udst, *vdst;
814 if(s->bitstream_bpp==12){
816 decode_gray_bitstream(s, width);
817 ydst= p->data[0] + p->linesize[0]*y;
818 add_median_prediction(ydst, ydst - fake_ystride, s->temp[0], width, &lefty, &lefttopy);
825 decode_422_bitstream(s, width);
827 ydst= p->data[0] + p->linesize[0]*y;
828 udst= p->data[1] + p->linesize[1]*cy;
829 vdst= p->data[2] + p->linesize[2]*cy;
831 add_median_prediction(ydst, ydst - fake_ystride, s->temp[0], width, &lefty, &lefttopy);
832 if(!(s->flags&CODEC_FLAG_GRAY)){
833 add_median_prediction(udst, udst - fake_ustride, s->temp[1], width2, &leftu, &lefttopu);
834 add_median_prediction(vdst, vdst - fake_vstride, s->temp[2], width2, &leftv, &lefttopv);
838 draw_slice(s, height);
844 int leftr, leftg, leftb;
845 const int last_line= (height-1)*p->linesize[0];
847 if(s->bitstream_bpp==32){
848 p->data[0][last_line+3]= get_bits(&s->gb, 8);
849 leftr= p->data[0][last_line+2]= get_bits(&s->gb, 8);
850 leftg= p->data[0][last_line+1]= get_bits(&s->gb, 8);
851 leftb= p->data[0][last_line+0]= get_bits(&s->gb, 8);
853 leftr= p->data[0][last_line+2]= get_bits(&s->gb, 8);
854 leftg= p->data[0][last_line+1]= get_bits(&s->gb, 8);
855 leftb= p->data[0][last_line+0]= get_bits(&s->gb, 8);
856 skip_bits(&s->gb, 8);
860 switch(s->predictor){
863 decode_bgr_bitstream(s, width-1);
864 add_left_prediction_bgr32(p->data[0] + last_line+4, s->temp[0], width-1, &leftr, &leftg, &leftb);
866 for(y=s->height-2; y>=0; y--){ //yes its stored upside down
867 decode_bgr_bitstream(s, width);
869 add_left_prediction_bgr32(p->data[0] + p->linesize[0]*y, s->temp[0], width, &leftr, &leftg, &leftb);
870 if(s->predictor == PLANE){
871 if((y&s->interlaced)==0){
872 s->dsp.add_bytes(p->data[0] + p->linesize[0]*y,
873 p->data[0] + p->linesize[0]*y + fake_ystride, fake_ystride);
877 draw_slice(s, height); // just 1 large slice as this isnt possible in reverse order
880 fprintf(stderr, "prediction type not supported!\n");
884 fprintf(stderr, "BGR24 output isnt implemenetd yet\n");
892 avctx->release_buffer(avctx, p);
894 *data_size = sizeof(AVFrame);
896 return (get_bits_count(&s->gb)+7)>>3;
899 static int decode_end(AVCodecContext *avctx)
901 HYuvContext *s = avctx->priv_data;
905 free_vlc(&s->vlc[i]);
908 if(avctx->get_buffer == avcodec_default_get_buffer){
910 av_freep(&s->picture.base[i]);
911 s->picture.data[i]= NULL;
913 av_freep(&s->picture.opaque);
919 static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){
920 HYuvContext *s = avctx->priv_data;
921 AVFrame *pict = data;
922 const int width= s->width;
923 const int width2= s->width>>1;
924 const int height= s->height;
925 const int fake_ystride= s->interlaced ? pict->linesize[0]*2 : pict->linesize[0];
926 const int fake_ustride= s->interlaced ? pict->linesize[1]*2 : pict->linesize[1];
927 const int fake_vstride= s->interlaced ? pict->linesize[2]*2 : pict->linesize[2];
928 AVFrame * const p= &s->picture;
931 init_put_bits(&s->pb, buf, buf_size, NULL, NULL);
934 p->pict_type= FF_I_TYPE;
937 if(avctx->pix_fmt == PIX_FMT_YUV422P || avctx->pix_fmt == PIX_FMT_YUV420P){
938 int lefty, leftu, leftv, y, cy;
940 put_bits(&s->pb, 8, leftv= p->data[2][0]);
941 put_bits(&s->pb, 8, lefty= p->data[0][1]);
942 put_bits(&s->pb, 8, leftu= p->data[1][0]);
943 put_bits(&s->pb, 8, p->data[0][0]);
945 lefty= sub_left_prediction(s, s->temp[0], p->data[0]+2, width-2 , lefty);
946 leftu= sub_left_prediction(s, s->temp[1], p->data[1]+1, width2-1, leftu);
947 leftv= sub_left_prediction(s, s->temp[2], p->data[2]+1, width2-1, leftv);
949 encode_422_bitstream(s, width-2);
951 if(s->predictor==MEDIAN){
952 int lefttopy, lefttopu, lefttopv;
955 lefty= sub_left_prediction(s, s->temp[0], p->data[0]+p->linesize[0], width , lefty);
956 leftu= sub_left_prediction(s, s->temp[1], p->data[1]+p->linesize[1], width2, leftu);
957 leftv= sub_left_prediction(s, s->temp[2], p->data[2]+p->linesize[2], width2, leftv);
959 encode_422_bitstream(s, width);
963 lefty= sub_left_prediction(s, s->temp[0], p->data[0]+fake_ystride, 4, lefty);
964 leftu= sub_left_prediction(s, s->temp[1], p->data[1]+fake_ystride, 2, leftu);
965 leftv= sub_left_prediction(s, s->temp[2], p->data[2]+fake_ystride, 2, leftv);
967 encode_422_bitstream(s, 4);
969 lefttopy= p->data[0][3];
970 lefttopu= p->data[1][1];
971 lefttopv= p->data[2][1];
972 sub_median_prediction(s->temp[0], p->data[0]+4, p->data[0] + fake_ystride+4, width-4 , &lefty, &lefttopy);
973 sub_median_prediction(s->temp[1], p->data[1]+2, p->data[1] + fake_ustride+2, width2-2, &leftu, &lefttopu);
974 sub_median_prediction(s->temp[2], p->data[2]+2, p->data[2] + fake_vstride+2, width2-2, &leftv, &lefttopv);
975 encode_422_bitstream(s, width-4);
978 for(; y<height; y++,cy++){
979 uint8_t *ydst, *udst, *vdst;
981 if(s->bitstream_bpp==12){
983 ydst= p->data[0] + p->linesize[0]*y;
984 sub_median_prediction(s->temp[0], ydst - fake_ystride, ydst, width , &lefty, &lefttopy);
985 encode_gray_bitstream(s, width);
990 ydst= p->data[0] + p->linesize[0]*y;
991 udst= p->data[1] + p->linesize[1]*cy;
992 vdst= p->data[2] + p->linesize[2]*cy;
994 sub_median_prediction(s->temp[0], ydst - fake_ystride, ydst, width , &lefty, &lefttopy);
995 sub_median_prediction(s->temp[1], udst - fake_ustride, udst, width2, &leftu, &lefttopu);
996 sub_median_prediction(s->temp[2], vdst - fake_vstride, vdst, width2, &leftv, &lefttopv);
998 encode_422_bitstream(s, width);
1001 for(cy=y=1; y<height; y++,cy++){
1002 uint8_t *ydst, *udst, *vdst;
1004 /* encode a luma only line & y++ */
1005 if(s->bitstream_bpp==12){
1006 ydst= p->data[0] + p->linesize[0]*y;
1008 if(s->predictor == PLANE && s->interlaced < y){
1009 s->dsp.diff_bytes(s->temp[1], ydst, ydst - fake_ystride, width);
1011 lefty= sub_left_prediction(s, s->temp[0], s->temp[1], width , lefty);
1013 lefty= sub_left_prediction(s, s->temp[0], ydst, width , lefty);
1015 encode_gray_bitstream(s, width);
1017 if(y>=height) break;
1020 ydst= p->data[0] + p->linesize[0]*y;
1021 udst= p->data[1] + p->linesize[1]*cy;
1022 vdst= p->data[2] + p->linesize[2]*cy;
1024 if(s->predictor == PLANE && s->interlaced < cy){
1025 s->dsp.diff_bytes(s->temp[1], ydst, ydst - fake_ystride, width);
1026 s->dsp.diff_bytes(s->temp[2], udst, udst - fake_ustride, width2);
1027 s->dsp.diff_bytes(s->temp[3], vdst, vdst - fake_vstride, width2);
1029 lefty= sub_left_prediction(s, s->temp[0], s->temp[1], width , lefty);
1030 leftu= sub_left_prediction(s, s->temp[1], s->temp[2], width2, leftu);
1031 leftv= sub_left_prediction(s, s->temp[2], s->temp[3], width2, leftv);
1033 lefty= sub_left_prediction(s, s->temp[0], ydst, width , lefty);
1034 leftu= sub_left_prediction(s, s->temp[1], udst, width2, leftu);
1035 leftv= sub_left_prediction(s, s->temp[2], vdst, width2, leftv);
1038 encode_422_bitstream(s, width);
1042 fprintf(stderr, "Format not supported!\n");
1046 size= (get_bit_count(&s->pb)+31)/32;
1048 if((s->flags&CODEC_FLAG_PASS1) && (s->picture_number&31)==0){
1050 char *p= avctx->stats_out;
1052 for(j=0; j<256; j++){
1053 sprintf(p, "%Ld ", s->stats[i][j]);
1061 flush_put_bits(&s->pb);
1062 bswap_buf((uint32_t*)buf, (uint32_t*)buf, size);
1065 s->picture_number++;
1070 static int encode_end(AVCodecContext *avctx)
1072 // HYuvContext *s = avctx->priv_data;
1074 av_freep(&avctx->extradata);
1075 av_freep(&avctx->stats_out);
1080 AVCodec huffyuv_decoder = {
1084 sizeof(HYuvContext),
1089 CODEC_CAP_DR1 | CODEC_CAP_DRAW_HORIZ_BAND,
1093 AVCodec huffyuv_encoder = {
1097 sizeof(HYuvContext),