2 * huffyuv codec for libavcodec
4 * Copyright (c) 2002 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
);
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
));
299 read_len_table(s
->len
[0], &gb
);
300 init_get_bits(&gb
, classic_shift_chroma
, sizeof(classic_shift_chroma
));
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_BGRA32
;
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
;
464 s
->picture
.pict_type
= FF_I_TYPE
;
465 s
->picture
.key_frame
= 1;
467 switch(avctx
->pix_fmt
){
468 case PIX_FMT_YUV420P
:
469 if(avctx
->strict_std_compliance
>=0){
470 fprintf(stderr
, "YV12-huffyuv is experimental, there WILL be no compatbility! (use (v)strict=-1)\n");
473 s
->bitstream_bpp
= 12;
475 case PIX_FMT_YUV422P
:
476 s
->bitstream_bpp
= 16;
479 fprintf(stderr
, "format not supported\n");
482 avctx
->bits_per_sample
= s
->bitstream_bpp
;
483 s
->decorrelate
= s
->bitstream_bpp
>= 24;
484 s
->predictor
= avctx
->prediction_method
;
486 ((uint8_t*)avctx
->extradata
)[0]= s
->predictor
;
487 ((uint8_t*)avctx
->extradata
)[1]= s
->bitstream_bpp
;
488 ((uint8_t*)avctx
->extradata
)[2]=
489 ((uint8_t*)avctx
->extradata
)[3]= 0;
490 s
->avctx
->extradata_size
= 4;
493 char *p
= avctx
->stats_in
;
503 for(j
=0; j
<256; j
++){
504 s
->stats
[i
][j
]+= strtol(p
, &next
, 0);
505 if(next
==p
) return -1;
509 if(p
[0]==0 || p
[1]==0 || p
[2]==0) break;
513 for(j
=0; j
<256; j
++){
514 int d
= FFMIN(j
, 256-j
);
516 s
->stats
[i
][j
]= 100000000/(d
+1);
521 generate_len_table(s
->len
[i
], s
->stats
[i
], 256);
523 if(generate_bits_table(s
->bits
[i
], s
->len
[i
])<0){
527 store_table(s
, s
->len
[i
]);
534 s
->interlaced
= height
> 288;
536 // printf("pred:%d bpp:%d hbpp:%d il:%d\n", s->predictor, s->bitstream_bpp, avctx->bits_per_sample, s->interlaced);
543 static void decode_422_bitstream(HYuvContext
*s
, int count
){
548 for(i
=0; i
<count
; i
++){
549 s
->temp
[0][2*i
]= get_vlc2(&s
->gb
, s
->vlc
[0].table
, VLC_BITS
, 3);
550 s
->temp
[1][ i
]= get_vlc2(&s
->gb
, s
->vlc
[1].table
, VLC_BITS
, 3);
551 s
->temp
[0][2*i
+1]= get_vlc2(&s
->gb
, s
->vlc
[0].table
, VLC_BITS
, 3);
552 s
->temp
[2][ i
]= get_vlc2(&s
->gb
, s
->vlc
[2].table
, VLC_BITS
, 3);
556 static void decode_gray_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
[0][2*i
+1]= get_vlc2(&s
->gb
, s
->vlc
[0].table
, VLC_BITS
, 3);
567 static void encode_422_bitstream(HYuvContext
*s
, int count
){
571 if(s
->flags
&CODEC_FLAG_PASS1
){
572 for(i
=0; i
<count
; i
++){
573 s
->stats
[0][ s
->temp
[0][2*i
] ]++;
574 s
->stats
[1][ s
->temp
[1][ i
] ]++;
575 s
->stats
[0][ s
->temp
[0][2*i
+1] ]++;
576 s
->stats
[2][ s
->temp
[2][ i
] ]++;
579 for(i
=0; i
<count
; i
++){
580 put_bits(&s
->pb
, s
->len
[0][ s
->temp
[0][2*i
] ], s
->bits
[0][ s
->temp
[0][2*i
] ]);
581 put_bits(&s
->pb
, s
->len
[1][ s
->temp
[1][ i
] ], s
->bits
[1][ s
->temp
[1][ i
] ]);
582 put_bits(&s
->pb
, s
->len
[0][ s
->temp
[0][2*i
+1] ], s
->bits
[0][ s
->temp
[0][2*i
+1] ]);
583 put_bits(&s
->pb
, s
->len
[2][ s
->temp
[2][ i
] ], s
->bits
[2][ s
->temp
[2][ i
] ]);
588 static void encode_gray_bitstream(HYuvContext
*s
, int count
){
592 if(s
->flags
&CODEC_FLAG_PASS1
){
593 for(i
=0; i
<count
; i
++){
594 s
->stats
[0][ s
->temp
[0][2*i
] ]++;
595 s
->stats
[0][ s
->temp
[0][2*i
+1] ]++;
598 for(i
=0; i
<count
; i
++){
599 put_bits(&s
->pb
, s
->len
[0][ s
->temp
[0][2*i
] ], s
->bits
[0][ s
->temp
[0][2*i
] ]);
600 put_bits(&s
->pb
, s
->len
[0][ s
->temp
[0][2*i
+1] ], s
->bits
[0][ s
->temp
[0][2*i
+1] ]);
605 static void decode_bgr_bitstream(HYuvContext
*s
, int count
){
609 if(s
->bitstream_bpp
==24){
610 for(i
=0; i
<count
; i
++){
611 s
->temp
[0][4*i
+1]= get_vlc2(&s
->gb
, s
->vlc
[1].table
, VLC_BITS
, 3);
612 s
->temp
[0][4*i
]= get_vlc2(&s
->gb
, s
->vlc
[0].table
, VLC_BITS
, 3) + s
->temp
[0][4*i
+1];
613 s
->temp
[0][4*i
+2]= get_vlc2(&s
->gb
, s
->vlc
[2].table
, VLC_BITS
, 3) + s
->temp
[0][4*i
+1];
616 for(i
=0; i
<count
; i
++){
617 s
->temp
[0][4*i
+1]= get_vlc2(&s
->gb
, s
->vlc
[1].table
, VLC_BITS
, 3);
618 s
->temp
[0][4*i
]= get_vlc2(&s
->gb
, s
->vlc
[0].table
, VLC_BITS
, 3) + s
->temp
[0][4*i
+1];
619 s
->temp
[0][4*i
+2]= get_vlc2(&s
->gb
, s
->vlc
[2].table
, VLC_BITS
, 3) + s
->temp
[0][4*i
+1];
620 get_vlc2(&s
->gb
, s
->vlc
[2].table
, VLC_BITS
, 3); //?!
624 if(s
->bitstream_bpp
==24){
625 for(i
=0; i
<count
; i
++){
626 s
->temp
[0][4*i
]= get_vlc2(&s
->gb
, s
->vlc
[0].table
, VLC_BITS
, 3);
627 s
->temp
[0][4*i
+1]= get_vlc2(&s
->gb
, s
->vlc
[1].table
, VLC_BITS
, 3);
628 s
->temp
[0][4*i
+2]= get_vlc2(&s
->gb
, s
->vlc
[2].table
, VLC_BITS
, 3);
631 for(i
=0; i
<count
; i
++){
632 s
->temp
[0][4*i
]= get_vlc2(&s
->gb
, s
->vlc
[0].table
, VLC_BITS
, 3);
633 s
->temp
[0][4*i
+1]= get_vlc2(&s
->gb
, s
->vlc
[1].table
, VLC_BITS
, 3);
634 s
->temp
[0][4*i
+2]= get_vlc2(&s
->gb
, s
->vlc
[2].table
, VLC_BITS
, 3);
635 get_vlc2(&s
->gb
, s
->vlc
[2].table
, VLC_BITS
, 3); //?!
641 static void draw_slice(HYuvContext
*s
, int y
){
645 if(s
->avctx
->draw_horiz_band
==NULL
)
648 h
= y
- s
->last_slice_end
;
651 if(s
->bitstream_bpp
==12){
657 src_ptr
[0] = s
->picture
.data
[0] + s
->picture
.linesize
[0]*y
;
658 src_ptr
[1] = s
->picture
.data
[1] + s
->picture
.linesize
[1]*cy
;
659 src_ptr
[2] = s
->picture
.data
[2] + s
->picture
.linesize
[2]*cy
;
662 s
->avctx
->draw_horiz_band(s
->avctx
, src_ptr
, s
->picture
.linesize
[0], y
, s
->width
, h
);
664 s
->last_slice_end
= y
+ h
;
667 static int decode_frame(AVCodecContext
*avctx
, void *data
, int *data_size
, uint8_t *buf
, int buf_size
){
668 HYuvContext
*s
= avctx
->priv_data
;
669 const int width
= s
->width
;
670 const int width2
= s
->width
>>1;
671 const int height
= s
->height
;
672 int fake_ystride
, fake_ustride
, fake_vstride
;
673 AVFrame
* const p
= &s
->picture
;
675 AVFrame
*picture
= data
;
679 /* no supplementary picture */
683 bswap_buf((uint32_t*)s
->bitstream_buffer
, (uint32_t*)buf
, buf_size
/4);
685 init_get_bits(&s
->gb
, s
->bitstream_buffer
, buf_size
);
688 if(avctx
->get_buffer(avctx
, p
) < 0){
689 fprintf(stderr
, "get_buffer() failed\n");
693 fake_ystride
= s
->interlaced
? p
->linesize
[0]*2 : p
->linesize
[0];
694 fake_ustride
= s
->interlaced
? p
->linesize
[1]*2 : p
->linesize
[1];
695 fake_vstride
= s
->interlaced
? p
->linesize
[2]*2 : p
->linesize
[2];
697 s
->last_slice_end
= 0;
699 if(s
->bitstream_bpp
<24){
701 int lefty
, leftu
, leftv
;
702 int lefttopy
, lefttopu
, lefttopv
;
705 p
->data
[0][3]= get_bits(&s
->gb
, 8);
706 p
->data
[0][2]= get_bits(&s
->gb
, 8);
707 p
->data
[0][1]= get_bits(&s
->gb
, 8);
708 p
->data
[0][0]= get_bits(&s
->gb
, 8);
710 fprintf(stderr
, "YUY2 output isnt implemenetd yet\n");
714 leftv
= p
->data
[2][0]= get_bits(&s
->gb
, 8);
715 lefty
= p
->data
[0][1]= get_bits(&s
->gb
, 8);
716 leftu
= p
->data
[1][0]= get_bits(&s
->gb
, 8);
717 p
->data
[0][0]= get_bits(&s
->gb
, 8);
719 switch(s
->predictor
){
722 decode_422_bitstream(s
, width
-2);
723 lefty
= add_left_prediction(p
->data
[0] + 2, s
->temp
[0], width
-2, lefty
);
724 if(!(s
->flags
&CODEC_FLAG_GRAY
)){
725 leftu
= add_left_prediction(p
->data
[1] + 1, s
->temp
[1], width2
-1, leftu
);
726 leftv
= add_left_prediction(p
->data
[2] + 1, s
->temp
[2], width2
-1, leftv
);
729 for(cy
=y
=1; y
<s
->height
; y
++,cy
++){
730 uint8_t *ydst
, *udst
, *vdst
;
732 if(s
->bitstream_bpp
==12){
733 decode_gray_bitstream(s
, width
);
735 ydst
= p
->data
[0] + p
->linesize
[0]*y
;
737 lefty
= add_left_prediction(ydst
, s
->temp
[0], width
, lefty
);
738 if(s
->predictor
== PLANE
){
740 s
->dsp
.add_bytes(ydst
, ydst
- fake_ystride
, width
);
743 if(y
>=s
->height
) break;
748 ydst
= p
->data
[0] + p
->linesize
[0]*y
;
749 udst
= p
->data
[1] + p
->linesize
[1]*cy
;
750 vdst
= p
->data
[2] + p
->linesize
[2]*cy
;
752 decode_422_bitstream(s
, width
);
753 lefty
= add_left_prediction(ydst
, s
->temp
[0], width
, lefty
);
754 if(!(s
->flags
&CODEC_FLAG_GRAY
)){
755 leftu
= add_left_prediction(udst
, s
->temp
[1], width2
, leftu
);
756 leftv
= add_left_prediction(vdst
, s
->temp
[2], width2
, leftv
);
758 if(s
->predictor
== PLANE
){
759 if(cy
>s
->interlaced
){
760 s
->dsp
.add_bytes(ydst
, ydst
- fake_ystride
, width
);
761 if(!(s
->flags
&CODEC_FLAG_GRAY
)){
762 s
->dsp
.add_bytes(udst
, udst
- fake_ustride
, width2
);
763 s
->dsp
.add_bytes(vdst
, vdst
- fake_vstride
, width2
);
768 draw_slice(s
, height
);
772 /* first line except first 2 pixels is left predicted */
773 decode_422_bitstream(s
, width
-2);
774 lefty
= add_left_prediction(p
->data
[0] + 2, s
->temp
[0], width
-2, lefty
);
775 if(!(s
->flags
&CODEC_FLAG_GRAY
)){
776 leftu
= add_left_prediction(p
->data
[1] + 1, s
->temp
[1], width2
-1, leftu
);
777 leftv
= add_left_prediction(p
->data
[2] + 1, s
->temp
[2], width2
-1, leftv
);
782 /* second line is left predicted for interlaced case */
784 decode_422_bitstream(s
, width
);
785 lefty
= add_left_prediction(p
->data
[0] + p
->linesize
[0], s
->temp
[0], width
, lefty
);
786 if(!(s
->flags
&CODEC_FLAG_GRAY
)){
787 leftu
= add_left_prediction(p
->data
[1] + p
->linesize
[2], s
->temp
[1], width2
, leftu
);
788 leftv
= add_left_prediction(p
->data
[2] + p
->linesize
[1], s
->temp
[2], width2
, leftv
);
793 /* next 4 pixels are left predicted too */
794 decode_422_bitstream(s
, 4);
795 lefty
= add_left_prediction(p
->data
[0] + fake_ystride
, s
->temp
[0], 4, lefty
);
796 if(!(s
->flags
&CODEC_FLAG_GRAY
)){
797 leftu
= add_left_prediction(p
->data
[1] + fake_ustride
, s
->temp
[1], 2, leftu
);
798 leftv
= add_left_prediction(p
->data
[2] + fake_vstride
, s
->temp
[2], 2, leftv
);
801 /* next line except the first 4 pixels is median predicted */
802 lefttopy
= p
->data
[0][3];
803 decode_422_bitstream(s
, width
-4);
804 add_median_prediction(p
->data
[0] + fake_ystride
+4, p
->data
[0]+4, s
->temp
[0], width
-4, &lefty
, &lefttopy
);
805 if(!(s
->flags
&CODEC_FLAG_GRAY
)){
806 lefttopu
= p
->data
[1][1];
807 lefttopv
= p
->data
[2][1];
808 add_median_prediction(p
->data
[1] + fake_ustride
+2, p
->data
[1]+2, s
->temp
[1], width2
-2, &leftu
, &lefttopu
);
809 add_median_prediction(p
->data
[2] + fake_vstride
+2, p
->data
[2]+2, s
->temp
[2], width2
-2, &leftv
, &lefttopv
);
813 for(; y
<height
; y
++,cy
++){
814 uint8_t *ydst
, *udst
, *vdst
;
816 if(s
->bitstream_bpp
==12){
818 decode_gray_bitstream(s
, width
);
819 ydst
= p
->data
[0] + p
->linesize
[0]*y
;
820 add_median_prediction(ydst
, ydst
- fake_ystride
, s
->temp
[0], width
, &lefty
, &lefttopy
);
827 decode_422_bitstream(s
, width
);
829 ydst
= p
->data
[0] + p
->linesize
[0]*y
;
830 udst
= p
->data
[1] + p
->linesize
[1]*cy
;
831 vdst
= p
->data
[2] + p
->linesize
[2]*cy
;
833 add_median_prediction(ydst
, ydst
- fake_ystride
, s
->temp
[0], width
, &lefty
, &lefttopy
);
834 if(!(s
->flags
&CODEC_FLAG_GRAY
)){
835 add_median_prediction(udst
, udst
- fake_ustride
, s
->temp
[1], width2
, &leftu
, &lefttopu
);
836 add_median_prediction(vdst
, vdst
- fake_vstride
, s
->temp
[2], width2
, &leftv
, &lefttopv
);
840 draw_slice(s
, height
);
846 int leftr
, leftg
, leftb
;
847 const int last_line
= (height
-1)*p
->linesize
[0];
849 if(s
->bitstream_bpp
==32){
850 p
->data
[0][last_line
+3]= get_bits(&s
->gb
, 8);
851 leftr
= p
->data
[0][last_line
+2]= get_bits(&s
->gb
, 8);
852 leftg
= p
->data
[0][last_line
+1]= get_bits(&s
->gb
, 8);
853 leftb
= p
->data
[0][last_line
+0]= get_bits(&s
->gb
, 8);
855 leftr
= p
->data
[0][last_line
+2]= get_bits(&s
->gb
, 8);
856 leftg
= p
->data
[0][last_line
+1]= get_bits(&s
->gb
, 8);
857 leftb
= p
->data
[0][last_line
+0]= get_bits(&s
->gb
, 8);
858 skip_bits(&s
->gb
, 8);
862 switch(s
->predictor
){
865 decode_bgr_bitstream(s
, width
-1);
866 add_left_prediction_bgr32(p
->data
[0] + last_line
+4, s
->temp
[0], width
-1, &leftr
, &leftg
, &leftb
);
868 for(y
=s
->height
-2; y
>=0; y
--){ //yes its stored upside down
869 decode_bgr_bitstream(s
, width
);
871 add_left_prediction_bgr32(p
->data
[0] + p
->linesize
[0]*y
, s
->temp
[0], width
, &leftr
, &leftg
, &leftb
);
872 if(s
->predictor
== PLANE
){
873 if((y
&s
->interlaced
)==0){
874 s
->dsp
.add_bytes(p
->data
[0] + p
->linesize
[0]*y
,
875 p
->data
[0] + p
->linesize
[0]*y
+ fake_ystride
, fake_ystride
);
879 draw_slice(s
, height
); // just 1 large slice as this isnt possible in reverse order
882 fprintf(stderr
, "prediction type not supported!\n");
886 fprintf(stderr
, "BGR24 output isnt implemenetd yet\n");
894 avctx
->release_buffer(avctx
, p
);
896 *data_size
= sizeof(AVFrame
);
898 return (get_bits_count(&s
->gb
)+7)>>3;
901 static int decode_end(AVCodecContext
*avctx
)
903 HYuvContext
*s
= avctx
->priv_data
;
907 free_vlc(&s
->vlc
[i
]);
910 if(avctx
->get_buffer
== avcodec_default_get_buffer
){
912 av_freep(&s
->picture
.base
[i
]);
913 s
->picture
.data
[i
]= NULL
;
915 av_freep(&s
->picture
.opaque
);
921 static int encode_frame(AVCodecContext
*avctx
, unsigned char *buf
, int buf_size
, void *data
){
922 HYuvContext
*s
= avctx
->priv_data
;
923 AVFrame
*pict
= data
;
924 const int width
= s
->width
;
925 const int width2
= s
->width
>>1;
926 const int height
= s
->height
;
927 const int fake_ystride
= s
->interlaced
? pict
->linesize
[0]*2 : pict
->linesize
[0];
928 const int fake_ustride
= s
->interlaced
? pict
->linesize
[1]*2 : pict
->linesize
[1];
929 const int fake_vstride
= s
->interlaced
? pict
->linesize
[2]*2 : pict
->linesize
[2];
930 AVFrame
* const p
= &s
->picture
;
933 init_put_bits(&s
->pb
, buf
, buf_size
, NULL
, NULL
);
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
),