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.
35 #ifdef WORDS_BIGENDIAN
45 typedef enum Predictor
{
51 typedef struct HYuvContext
{
52 AVCodecContext
*avctx
;
60 int yuy2
; //use yuy2 instead of 422P
61 int bgr32
; //use bgr32 instead of bgr24
66 uint8_t __align8 temp
[3][2560];
67 uint64_t stats
[3][256];
69 uint32_t bits
[3][256];
72 uint8_t __align8 bitstream_buffer
[1024*1024*3]; //FIXME dynamic alloc or some other solution
76 static const unsigned char classic_shift_luma
[] = {
77 34,36,35,69,135,232,9,16,10,24,11,23,12,16,13,10,14,8,15,8,
78 16,8,17,20,16,10,207,206,205,236,11,8,10,21,9,23,8,8,199,70,
82 static const unsigned char classic_shift_chroma
[] = {
83 66,36,37,38,39,40,41,75,76,77,110,239,144,81,82,83,84,85,118,183,
84 56,57,88,89,56,89,154,57,58,57,26,141,57,56,58,57,58,57,184,119,
85 214,245,116,83,82,49,80,79,78,77,44,75,41,40,39,38,37,36,34, 0
88 static const unsigned char classic_add_luma
[256] = {
89 3, 9, 5, 12, 10, 35, 32, 29, 27, 50, 48, 45, 44, 41, 39, 37,
90 73, 70, 68, 65, 64, 61, 58, 56, 53, 50, 49, 46, 44, 41, 38, 36,
91 68, 65, 63, 61, 58, 55, 53, 51, 48, 46, 45, 43, 41, 39, 38, 36,
92 35, 33, 32, 30, 29, 27, 26, 25, 48, 47, 46, 44, 43, 41, 40, 39,
93 37, 36, 35, 34, 32, 31, 30, 28, 27, 26, 24, 23, 22, 20, 19, 37,
94 35, 34, 33, 31, 30, 29, 27, 26, 24, 23, 21, 20, 18, 17, 15, 29,
95 27, 26, 24, 22, 21, 19, 17, 16, 14, 26, 25, 23, 21, 19, 18, 16,
96 15, 27, 25, 23, 21, 19, 17, 16, 14, 26, 25, 23, 21, 18, 17, 14,
97 12, 17, 19, 13, 4, 9, 2, 11, 1, 7, 8, 0, 16, 3, 14, 6,
98 12, 10, 5, 15, 18, 11, 10, 13, 15, 16, 19, 20, 22, 24, 27, 15,
99 18, 20, 22, 24, 26, 14, 17, 20, 22, 24, 27, 15, 18, 20, 23, 25,
100 28, 16, 19, 22, 25, 28, 32, 36, 21, 25, 29, 33, 38, 42, 45, 49,
101 28, 31, 34, 37, 40, 42, 44, 47, 49, 50, 52, 54, 56, 57, 59, 60,
102 62, 64, 66, 67, 69, 35, 37, 39, 40, 42, 43, 45, 47, 48, 51, 52,
103 54, 55, 57, 59, 60, 62, 63, 66, 67, 69, 71, 72, 38, 40, 42, 43,
104 46, 47, 49, 51, 26, 28, 30, 31, 33, 34, 18, 19, 11, 13, 7, 8,
107 static const unsigned char classic_add_chroma
[256] = {
108 3, 1, 2, 2, 2, 2, 3, 3, 7, 5, 7, 5, 8, 6, 11, 9,
109 7, 13, 11, 10, 9, 8, 7, 5, 9, 7, 6, 4, 7, 5, 8, 7,
110 11, 8, 13, 11, 19, 15, 22, 23, 20, 33, 32, 28, 27, 29, 51, 77,
111 43, 45, 76, 81, 46, 82, 75, 55, 56,144, 58, 80, 60, 74,147, 63,
112 143, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
113 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 27, 30, 21, 22,
114 17, 14, 5, 6,100, 54, 47, 50, 51, 53,106,107,108,109,110,111,
115 112,113,114,115, 4,117,118, 92, 94,121,122, 3,124,103, 2, 1,
116 0,129,130,131,120,119,126,125,136,137,138,139,140,141,142,134,
117 135,132,133,104, 64,101, 62, 57,102, 95, 93, 59, 61, 28, 97, 96,
118 52, 49, 48, 29, 32, 25, 24, 46, 23, 98, 45, 44, 43, 20, 42, 41,
119 19, 18, 99, 40, 15, 39, 38, 16, 13, 12, 11, 37, 10, 9, 8, 36,
120 7,128,127,105,123,116, 35, 34, 33,145, 31, 79, 42,146, 78, 26,
121 83, 48, 49, 50, 44, 47, 26, 31, 30, 18, 17, 19, 21, 24, 25, 13,
122 14, 16, 17, 18, 20, 21, 12, 14, 15, 9, 10, 6, 9, 6, 5, 8,
123 6, 12, 8, 10, 7, 9, 6, 4, 6, 2, 2, 3, 3, 3, 3, 2,
126 static inline int add_left_prediction(uint8_t *dst
, uint8_t *src
, int w
, int acc
){
129 for(i
=0; i
<w
-1; i
++){
145 static inline void add_median_prediction(uint8_t *dst
, uint8_t *src1
, uint8_t *diff
, int w
, int *left
, int *left_top
){
153 l
= mid_pred(l
, src1
[i
], (l
+ src1
[i
] - lt
)&0xFF) + diff
[i
];
162 static inline void add_left_prediction_bgr32(uint8_t *dst
, uint8_t *src
, int w
, int *red
, int *green
, int *blue
){
184 static inline int sub_left_prediction(HYuvContext
*s
, uint8_t *dst
, uint8_t *src
, int w
, int left
){
188 const int temp
= src
[i
];
195 const int temp
= src
[i
];
199 s
->dsp
.diff_bytes(dst
+16, src
+16, src
+15, w
-16);
204 static void read_len_table(uint8_t *dst
, GetBitContext
*gb
){
208 repeat
= get_bits(gb
, 3);
209 val
= get_bits(gb
, 5);
211 repeat
= get_bits(gb
, 8);
212 //printf("%d %d\n", val, repeat);
218 static int generate_bits_table(uint32_t *dst
, uint8_t *len_table
){
222 for(len
=32; len
>0; len
--){
223 for(index
=0; index
<256; index
++){
224 if(len_table
[index
]==len
)
228 av_log(NULL
, AV_LOG_ERROR
, "Error generating huffman table\n");
236 static void generate_len_table(uint8_t *dst
, uint64_t *stats
, int size
){
237 uint64_t counts
[2*size
];
241 for(offset
=1; ; offset
<<=1){
242 for(i
=0; i
<size
; i
++){
243 counts
[i
]= stats
[i
] + offset
- 1;
246 for(next
=size
; next
<size
*2; next
++){
250 min1
=min2
= INT64_MAX
;
253 for(i
=0; i
<next
; i
++){
254 if(min2
> counts
[i
]){
255 if(min1
> counts
[i
]){
267 if(min2
==INT64_MAX
) break;
269 counts
[next
]= min1
+ min2
;
271 counts
[min2_i
]= INT64_MAX
;
277 for(i
=0; i
<size
; i
++){
281 for(len
=0; up
[index
] != -1; len
++)
292 static int read_huffman_tables(HYuvContext
*s
, uint8_t *src
, int length
){
296 init_get_bits(&gb
, src
, length
*8);
299 read_len_table(s
->len
[i
], &gb
);
301 if(generate_bits_table(s
->bits
[i
], s
->len
[i
])<0){
305 for(j
=0; j
<256; j
++){
306 printf("%6X, %2d, %3d\n", s
->bits
[i
][j
], s
->len
[i
][j
], j
);
309 init_vlc(&s
->vlc
[i
], VLC_BITS
, 256, s
->len
[i
], 1, 1, s
->bits
[i
], 4, 4);
315 static int read_old_huffman_tables(HYuvContext
*s
){
320 init_get_bits(&gb
, classic_shift_luma
, sizeof(classic_shift_luma
)*8);
321 read_len_table(s
->len
[0], &gb
);
322 init_get_bits(&gb
, classic_shift_chroma
, sizeof(classic_shift_chroma
)*8);
323 read_len_table(s
->len
[1], &gb
);
325 for(i
=0; i
<256; i
++) s
->bits
[0][i
] = classic_add_luma
[i
];
326 for(i
=0; i
<256; i
++) s
->bits
[1][i
] = classic_add_chroma
[i
];
328 if(s
->bitstream_bpp
>= 24){
329 memcpy(s
->bits
[1], s
->bits
[0], 256*sizeof(uint32_t));
330 memcpy(s
->len
[1] , s
->len
[0], 256*sizeof(uint8_t));
332 memcpy(s
->bits
[2], s
->bits
[1], 256*sizeof(uint32_t));
333 memcpy(s
->len
[2] , s
->len
[1], 256*sizeof(uint8_t));
336 init_vlc(&s
->vlc
[i
], VLC_BITS
, 256, s
->len
[i
], 1, 1, s
->bits
[i
], 4, 4);
340 fprintf(stderr
, "v1 huffyuv is not supported \n");
345 static int decode_init(AVCodecContext
*avctx
)
347 HYuvContext
*s
= avctx
->priv_data
;
351 s
->flags
= avctx
->flags
;
353 dsputil_init(&s
->dsp
, avctx
);
355 width
= s
->width
= avctx
->width
;
356 height
= s
->height
= avctx
->height
;
357 avctx
->coded_frame
= &s
->picture
;
360 assert(width
&& height
);
361 //if(avctx->extradata)
362 // printf("extradata:%X, extradata_size:%d\n", *(uint32_t*)avctx->extradata, avctx->extradata_size);
363 if(avctx
->extradata_size
){
364 if((avctx
->bits_per_sample
&7) && avctx
->bits_per_sample
!= 12)
365 s
->version
=1; // do such files exist at all?
374 method
= ((uint8_t*)avctx
->extradata
)[0];
375 s
->decorrelate
= method
&64 ?
1 : 0;
376 s
->predictor
= method
&63;
377 s
->bitstream_bpp
= ((uint8_t*)avctx
->extradata
)[1];
378 if(s
->bitstream_bpp
==0)
379 s
->bitstream_bpp
= avctx
->bits_per_sample
&~7;
381 if(read_huffman_tables(s
, ((uint8_t*)avctx
->extradata
)+4, avctx
->extradata_size
) < 0)
384 switch(avctx
->bits_per_sample
&7){
395 s
->decorrelate
= avctx
->bits_per_sample
>= 24;
398 s
->predictor
= MEDIAN
;
402 s
->predictor
= LEFT
; //OLD
406 s
->bitstream_bpp
= avctx
->bits_per_sample
& ~7;
408 if(read_old_huffman_tables(s
) < 0)
412 s
->interlaced
= height
> 288;
414 switch(s
->bitstream_bpp
){
416 avctx
->pix_fmt
= PIX_FMT_YUV420P
;
420 avctx
->pix_fmt
= PIX_FMT_YUV422
;
422 avctx
->pix_fmt
= PIX_FMT_YUV422P
;
428 avctx
->pix_fmt
= PIX_FMT_RGBA32
;
430 avctx
->pix_fmt
= PIX_FMT_BGR24
;
437 // av_log(NULL, AV_LOG_DEBUG, "pred:%d bpp:%d hbpp:%d il:%d\n", s->predictor, s->bitstream_bpp, avctx->bits_per_sample, s->interlaced);
442 static void store_table(HYuvContext
*s
, uint8_t *len
){
444 int index
= s
->avctx
->extradata_size
;
450 for(; i
<256 && len
[i
]==val
&& repeat
<255; i
++)
453 assert(val
< 32 && val
>0 && repeat
<256 && repeat
>0);
455 ((uint8_t*)s
->avctx
->extradata
)[index
++]= val
;
456 ((uint8_t*)s
->avctx
->extradata
)[index
++]= repeat
;
458 ((uint8_t*)s
->avctx
->extradata
)[index
++]= val
| (repeat
<<5);
462 s
->avctx
->extradata_size
= index
;
465 static int encode_init(AVCodecContext
*avctx
)
467 HYuvContext
*s
= avctx
->priv_data
;
468 int i
, j
, width
, height
;
471 s
->flags
= avctx
->flags
;
473 dsputil_init(&s
->dsp
, avctx
);
475 width
= s
->width
= avctx
->width
;
476 height
= s
->height
= avctx
->height
;
478 assert(width
&& height
);
480 avctx
->extradata
= av_mallocz(1024*30);
481 avctx
->stats_out
= av_mallocz(1024*30);
484 avctx
->coded_frame
= &s
->picture
;
486 switch(avctx
->pix_fmt
){
487 case PIX_FMT_YUV420P
:
488 s
->bitstream_bpp
= 12;
490 case PIX_FMT_YUV422P
:
491 s
->bitstream_bpp
= 16;
494 av_log(avctx
, AV_LOG_ERROR
, "format not supported\n");
497 avctx
->bits_per_sample
= s
->bitstream_bpp
;
498 s
->decorrelate
= s
->bitstream_bpp
>= 24;
499 s
->predictor
= avctx
->prediction_method
;
501 ((uint8_t*)avctx
->extradata
)[0]= s
->predictor
;
502 ((uint8_t*)avctx
->extradata
)[1]= s
->bitstream_bpp
;
503 ((uint8_t*)avctx
->extradata
)[2]=
504 ((uint8_t*)avctx
->extradata
)[3]= 0;
505 s
->avctx
->extradata_size
= 4;
508 char *p
= avctx
->stats_in
;
518 for(j
=0; j
<256; j
++){
519 s
->stats
[i
][j
]+= strtol(p
, &next
, 0);
520 if(next
==p
) return -1;
524 if(p
[0]==0 || p
[1]==0 || p
[2]==0) break;
528 for(j
=0; j
<256; j
++){
529 int d
= FFMIN(j
, 256-j
);
531 s
->stats
[i
][j
]= 100000000/(d
+1);
536 generate_len_table(s
->len
[i
], s
->stats
[i
], 256);
538 if(generate_bits_table(s
->bits
[i
], s
->len
[i
])<0){
542 store_table(s
, s
->len
[i
]);
549 s
->interlaced
= height
> 288;
551 // printf("pred:%d bpp:%d hbpp:%d il:%d\n", s->predictor, s->bitstream_bpp, avctx->bits_per_sample, s->interlaced);
558 static void decode_422_bitstream(HYuvContext
*s
, int count
){
563 for(i
=0; i
<count
; i
++){
564 s
->temp
[0][2*i
]= get_vlc2(&s
->gb
, s
->vlc
[0].table
, VLC_BITS
, 3);
565 s
->temp
[1][ i
]= get_vlc2(&s
->gb
, s
->vlc
[1].table
, VLC_BITS
, 3);
566 s
->temp
[0][2*i
+1]= get_vlc2(&s
->gb
, s
->vlc
[0].table
, VLC_BITS
, 3);
567 s
->temp
[2][ i
]= get_vlc2(&s
->gb
, s
->vlc
[2].table
, VLC_BITS
, 3);
571 static void decode_gray_bitstream(HYuvContext
*s
, int count
){
576 for(i
=0; i
<count
; i
++){
577 s
->temp
[0][2*i
]= get_vlc2(&s
->gb
, s
->vlc
[0].table
, VLC_BITS
, 3);
578 s
->temp
[0][2*i
+1]= get_vlc2(&s
->gb
, s
->vlc
[0].table
, VLC_BITS
, 3);
582 static void encode_422_bitstream(HYuvContext
*s
, int count
){
586 if(s
->flags
&CODEC_FLAG_PASS1
){
587 for(i
=0; i
<count
; i
++){
588 s
->stats
[0][ s
->temp
[0][2*i
] ]++;
589 s
->stats
[1][ s
->temp
[1][ i
] ]++;
590 s
->stats
[0][ s
->temp
[0][2*i
+1] ]++;
591 s
->stats
[2][ s
->temp
[2][ i
] ]++;
594 for(i
=0; i
<count
; i
++){
595 put_bits(&s
->pb
, s
->len
[0][ s
->temp
[0][2*i
] ], s
->bits
[0][ s
->temp
[0][2*i
] ]);
596 put_bits(&s
->pb
, s
->len
[1][ s
->temp
[1][ i
] ], s
->bits
[1][ s
->temp
[1][ i
] ]);
597 put_bits(&s
->pb
, s
->len
[0][ s
->temp
[0][2*i
+1] ], s
->bits
[0][ s
->temp
[0][2*i
+1] ]);
598 put_bits(&s
->pb
, s
->len
[2][ s
->temp
[2][ i
] ], s
->bits
[2][ s
->temp
[2][ i
] ]);
603 static void encode_gray_bitstream(HYuvContext
*s
, int count
){
607 if(s
->flags
&CODEC_FLAG_PASS1
){
608 for(i
=0; i
<count
; i
++){
609 s
->stats
[0][ s
->temp
[0][2*i
] ]++;
610 s
->stats
[0][ s
->temp
[0][2*i
+1] ]++;
613 for(i
=0; i
<count
; i
++){
614 put_bits(&s
->pb
, s
->len
[0][ s
->temp
[0][2*i
] ], s
->bits
[0][ s
->temp
[0][2*i
] ]);
615 put_bits(&s
->pb
, s
->len
[0][ s
->temp
[0][2*i
+1] ], s
->bits
[0][ s
->temp
[0][2*i
+1] ]);
620 static void decode_bgr_bitstream(HYuvContext
*s
, int count
){
624 if(s
->bitstream_bpp
==24){
625 for(i
=0; i
<count
; i
++){
626 s
->temp
[0][4*i
+G
]= get_vlc2(&s
->gb
, s
->vlc
[1].table
, VLC_BITS
, 3);
627 s
->temp
[0][4*i
+B
]= get_vlc2(&s
->gb
, s
->vlc
[0].table
, VLC_BITS
, 3) + s
->temp
[0][4*i
+G
];
628 s
->temp
[0][4*i
+R
]= get_vlc2(&s
->gb
, s
->vlc
[2].table
, VLC_BITS
, 3) + s
->temp
[0][4*i
+G
];
631 for(i
=0; i
<count
; i
++){
632 s
->temp
[0][4*i
+G
]= get_vlc2(&s
->gb
, s
->vlc
[1].table
, VLC_BITS
, 3);
633 s
->temp
[0][4*i
+B
]= get_vlc2(&s
->gb
, s
->vlc
[0].table
, VLC_BITS
, 3) + s
->temp
[0][4*i
+G
];
634 s
->temp
[0][4*i
+R
]= get_vlc2(&s
->gb
, s
->vlc
[2].table
, VLC_BITS
, 3) + s
->temp
[0][4*i
+G
];
635 get_vlc2(&s
->gb
, s
->vlc
[2].table
, VLC_BITS
, 3); //?!
639 if(s
->bitstream_bpp
==24){
640 for(i
=0; i
<count
; i
++){
641 s
->temp
[0][4*i
+B
]= get_vlc2(&s
->gb
, s
->vlc
[0].table
, VLC_BITS
, 3);
642 s
->temp
[0][4*i
+G
]= get_vlc2(&s
->gb
, s
->vlc
[1].table
, VLC_BITS
, 3);
643 s
->temp
[0][4*i
+R
]= get_vlc2(&s
->gb
, s
->vlc
[2].table
, VLC_BITS
, 3);
646 for(i
=0; i
<count
; i
++){
647 s
->temp
[0][4*i
+B
]= get_vlc2(&s
->gb
, s
->vlc
[0].table
, VLC_BITS
, 3);
648 s
->temp
[0][4*i
+G
]= get_vlc2(&s
->gb
, s
->vlc
[1].table
, VLC_BITS
, 3);
649 s
->temp
[0][4*i
+R
]= get_vlc2(&s
->gb
, s
->vlc
[2].table
, VLC_BITS
, 3);
650 get_vlc2(&s
->gb
, s
->vlc
[2].table
, VLC_BITS
, 3); //?!
656 static void draw_slice(HYuvContext
*s
, int y
){
660 if(s
->avctx
->draw_horiz_band
==NULL
)
663 h
= y
- s
->last_slice_end
;
666 if(s
->bitstream_bpp
==12){
672 offset
[0] = s
->picture
.linesize
[0]*y
;
673 offset
[1] = s
->picture
.linesize
[1]*cy
;
674 offset
[2] = s
->picture
.linesize
[2]*cy
;
678 s
->avctx
->draw_horiz_band(s
->avctx
, &s
->picture
, offset
, y
, 3, h
);
680 s
->last_slice_end
= y
+ h
;
683 static int decode_frame(AVCodecContext
*avctx
, void *data
, int *data_size
, uint8_t *buf
, int buf_size
){
684 HYuvContext
*s
= avctx
->priv_data
;
685 const int width
= s
->width
;
686 const int width2
= s
->width
>>1;
687 const int height
= s
->height
;
688 int fake_ystride
, fake_ustride
, fake_vstride
;
689 AVFrame
* const p
= &s
->picture
;
691 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 skip_bits(&s
->gb
, 8);
868 leftr
= p
->data
[0][last_line
+R
]= get_bits(&s
->gb
, 8);
869 leftg
= p
->data
[0][last_line
+G
]= get_bits(&s
->gb
, 8);
870 leftb
= p
->data
[0][last_line
+B
]= get_bits(&s
->gb
, 8);
872 leftr
= p
->data
[0][last_line
+R
]= get_bits(&s
->gb
, 8);
873 leftg
= p
->data
[0][last_line
+G
]= get_bits(&s
->gb
, 8);
874 leftb
= p
->data
[0][last_line
+B
]= 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 && y
<s
->height
-2){
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
]);
927 static int encode_frame(AVCodecContext
*avctx
, unsigned char *buf
, int buf_size
, void *data
){
928 HYuvContext
*s
= avctx
->priv_data
;
929 AVFrame
*pict
= data
;
930 const int width
= s
->width
;
931 const int width2
= s
->width
>>1;
932 const int height
= s
->height
;
933 const int fake_ystride
= s
->interlaced ? pict
->linesize
[0]*2 : pict
->linesize
[0];
934 const int fake_ustride
= s
->interlaced ? pict
->linesize
[1]*2 : pict
->linesize
[1];
935 const int fake_vstride
= s
->interlaced ? pict
->linesize
[2]*2 : pict
->linesize
[2];
936 AVFrame
* const p
= &s
->picture
;
939 init_put_bits(&s
->pb
, buf
, buf_size
);
942 p
->pict_type
= FF_I_TYPE
;
945 if(avctx
->pix_fmt
== PIX_FMT_YUV422P
|| avctx
->pix_fmt
== PIX_FMT_YUV420P
){
946 int lefty
, leftu
, leftv
, y
, cy
;
948 put_bits(&s
->pb
, 8, leftv
= p
->data
[2][0]);
949 put_bits(&s
->pb
, 8, lefty
= p
->data
[0][1]);
950 put_bits(&s
->pb
, 8, leftu
= p
->data
[1][0]);
951 put_bits(&s
->pb
, 8, p
->data
[0][0]);
953 lefty
= sub_left_prediction(s
, s
->temp
[0], p
->data
[0]+2, width
-2 , lefty
);
954 leftu
= sub_left_prediction(s
, s
->temp
[1], p
->data
[1]+1, width2
-1, leftu
);
955 leftv
= sub_left_prediction(s
, s
->temp
[2], p
->data
[2]+1, width2
-1, leftv
);
957 encode_422_bitstream(s
, width
-2);
959 if(s
->predictor
==MEDIAN
){
960 int lefttopy
, lefttopu
, lefttopv
;
963 lefty
= sub_left_prediction(s
, s
->temp
[0], p
->data
[0]+p
->linesize
[0], width
, lefty
);
964 leftu
= sub_left_prediction(s
, s
->temp
[1], p
->data
[1]+p
->linesize
[1], width2
, leftu
);
965 leftv
= sub_left_prediction(s
, s
->temp
[2], p
->data
[2]+p
->linesize
[2], width2
, leftv
);
967 encode_422_bitstream(s
, width
);
971 lefty
= sub_left_prediction(s
, s
->temp
[0], p
->data
[0]+fake_ystride
, 4, lefty
);
972 leftu
= sub_left_prediction(s
, s
->temp
[1], p
->data
[1]+fake_ustride
, 2, leftu
);
973 leftv
= sub_left_prediction(s
, s
->temp
[2], p
->data
[2]+fake_vstride
, 2, leftv
);
975 encode_422_bitstream(s
, 4);
977 lefttopy
= p
->data
[0][3];
978 lefttopu
= p
->data
[1][1];
979 lefttopv
= p
->data
[2][1];
980 s
->dsp
.sub_hfyu_median_prediction(s
->temp
[0], p
->data
[0]+4, p
->data
[0] + fake_ystride
+4, width
-4 , &lefty
, &lefttopy
);
981 s
->dsp
.sub_hfyu_median_prediction(s
->temp
[1], p
->data
[1]+2, p
->data
[1] + fake_ustride
+2, width2
-2, &leftu
, &lefttopu
);
982 s
->dsp
.sub_hfyu_median_prediction(s
->temp
[2], p
->data
[2]+2, p
->data
[2] + fake_vstride
+2, width2
-2, &leftv
, &lefttopv
);
983 encode_422_bitstream(s
, width
-4);
986 for(; y
<height
; y
++,cy
++){
987 uint8_t *ydst
, *udst
, *vdst
;
989 if(s
->bitstream_bpp
==12){
991 ydst
= p
->data
[0] + p
->linesize
[0]*y
;
992 s
->dsp
.sub_hfyu_median_prediction(s
->temp
[0], ydst
- fake_ystride
, ydst
, width
, &lefty
, &lefttopy
);
993 encode_gray_bitstream(s
, width
);
998 ydst
= p
->data
[0] + p
->linesize
[0]*y
;
999 udst
= p
->data
[1] + p
->linesize
[1]*cy
;
1000 vdst
= p
->data
[2] + p
->linesize
[2]*cy
;
1002 s
->dsp
.sub_hfyu_median_prediction(s
->temp
[0], ydst
- fake_ystride
, ydst
, width
, &lefty
, &lefttopy
);
1003 s
->dsp
.sub_hfyu_median_prediction(s
->temp
[1], udst
- fake_ustride
, udst
, width2
, &leftu
, &lefttopu
);
1004 s
->dsp
.sub_hfyu_median_prediction(s
->temp
[2], vdst
- fake_vstride
, vdst
, width2
, &leftv
, &lefttopv
);
1006 encode_422_bitstream(s
, width
);
1009 for(cy
=y
=1; y
<height
; y
++,cy
++){
1010 uint8_t *ydst
, *udst
, *vdst
;
1012 /* encode a luma only line & y++ */
1013 if(s
->bitstream_bpp
==12){
1014 ydst
= p
->data
[0] + p
->linesize
[0]*y
;
1016 if(s
->predictor
== PLANE
&& s
->interlaced
< y
){
1017 s
->dsp
.diff_bytes(s
->temp
[1], ydst
, ydst
- fake_ystride
, width
);
1019 lefty
= sub_left_prediction(s
, s
->temp
[0], s
->temp
[1], width
, lefty
);
1021 lefty
= sub_left_prediction(s
, s
->temp
[0], ydst
, width
, lefty
);
1023 encode_gray_bitstream(s
, width
);
1025 if(y
>=height
) break;
1028 ydst
= p
->data
[0] + p
->linesize
[0]*y
;
1029 udst
= p
->data
[1] + p
->linesize
[1]*cy
;
1030 vdst
= p
->data
[2] + p
->linesize
[2]*cy
;
1032 if(s
->predictor
== PLANE
&& s
->interlaced
< cy
){
1033 s
->dsp
.diff_bytes(s
->temp
[1], ydst
, ydst
- fake_ystride
, width
);
1034 s
->dsp
.diff_bytes(s
->temp
[2], udst
, udst
- fake_ustride
, width2
);
1035 s
->dsp
.diff_bytes(s
->temp
[2] + 1250, vdst
, vdst
- fake_vstride
, width2
);
1037 lefty
= sub_left_prediction(s
, s
->temp
[0], s
->temp
[1], width
, lefty
);
1038 leftu
= sub_left_prediction(s
, s
->temp
[1], s
->temp
[2], width2
, leftu
);
1039 leftv
= sub_left_prediction(s
, s
->temp
[2], s
->temp
[2] + 1250, width2
, leftv
);
1041 lefty
= sub_left_prediction(s
, s
->temp
[0], ydst
, width
, lefty
);
1042 leftu
= sub_left_prediction(s
, s
->temp
[1], udst
, width2
, leftu
);
1043 leftv
= sub_left_prediction(s
, s
->temp
[2], vdst
, width2
, leftv
);
1046 encode_422_bitstream(s
, width
);
1050 av_log(avctx
, AV_LOG_ERROR
, "Format not supported!\n");
1054 size
= (put_bits_count(&s
->pb
)+31)/32;
1056 if((s
->flags
&CODEC_FLAG_PASS1
) && (s
->picture_number
&31)==0){
1058 char *p
= avctx
->stats_out
;
1060 for(j
=0; j
<256; j
++){
1061 sprintf(p
, "%llu ", s
->stats
[i
][j
]);
1069 flush_put_bits(&s
->pb
);
1070 s
->dsp
.bswap_buf((uint32_t*)buf
, (uint32_t*)buf
, size
);
1073 s
->picture_number
++;
1078 static int encode_end(AVCodecContext
*avctx
)
1080 // HYuvContext *s = avctx->priv_data;
1082 av_freep(&avctx
->extradata
);
1083 av_freep(&avctx
->stats_out
);
1088 static const AVOption huffyuv_options
[] =
1090 AVOPTION_CODEC_INT("prediction_method", "prediction_method", prediction_method
, 0, 2, 0),
1094 AVCodec huffyuv_decoder
= {
1098 sizeof(HYuvContext
),
1103 CODEC_CAP_DR1
| CODEC_CAP_DRAW_HORIZ_BAND
,
1107 #ifdef CONFIG_ENCODERS
1109 AVCodec huffyuv_encoder
= {
1113 sizeof(HYuvContext
),
1117 .options
= huffyuv_options
,
1120 #endif //CONFIG_ENCODERS