Statistics
| Branch: | Revision:

ffmpeg / libavcodec / huffyuv.c @ e20c4069

History | View | Annotate | Download (37.4 KB)

1
/*
2
 * huffyuv codec for libavcodec
3
 *
4
 * Copyright (c) 2002-2003 Michael Niedermayer <michaelni@gmx.at>
5
 *
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.
10
 *
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.
15
 *
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
19
 *
20
 * see http://www.pcisys.net/~melanson/codecs/huffyuv.txt for a description of
21
 * the algorithm used 
22
 */
23
 
24
/**
25
 * @file huffyuv.c
26
 * huffyuv codec for libavcodec.
27
 */
28

    
29
#include "common.h"
30
#include "avcodec.h"
31
#include "dsputil.h"
32

    
33
#ifndef INT64_MAX
34
#define INT64_MAX 9223372036854775807LL
35
#endif
36

    
37
#define VLC_BITS 11
38

    
39
typedef enum Predictor{
40
    LEFT= 0,
41
    PLANE,
42
    MEDIAN,
43
} Predictor;
44
 
45
typedef struct HYuvContext{
46
    AVCodecContext *avctx;
47
    Predictor predictor;
48
    GetBitContext gb;
49
    PutBitContext pb;
50
    int interlaced;
51
    int decorrelate;
52
    int bitstream_bpp;
53
    int version;
54
    int yuy2;                               //use yuy2 instead of 422P
55
    int bgr32;                              //use bgr32 instead of bgr24
56
    int width, height;
57
    int flags;
58
    int picture_number;
59
    int last_slice_end;
60
    uint8_t __align8 temp[3][2500];
61
    uint64_t stats[3][256];
62
    uint8_t len[3][256];
63
    uint32_t bits[3][256];
64
    VLC vlc[3];
65
    AVFrame picture;
66
    uint8_t __align8 bitstream_buffer[1024*1024*3]; //FIXME dynamic alloc or some other solution
67
    DSPContext dsp; 
68
}HYuvContext;
69

    
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,
73
  69,68, 0
74
};
75

    
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
80
};
81

    
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,
99
};
100

    
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,
118
};
119

    
120
static inline void bswap_buf(uint32_t *dst, uint32_t *src, int w){
121
    int i;
122
    
123
    for(i=0; i+8<=w; i+=8){
124
        dst[i+0]= bswap_32(src[i+0]);
125
        dst[i+1]= bswap_32(src[i+1]);
126
        dst[i+2]= bswap_32(src[i+2]);
127
        dst[i+3]= bswap_32(src[i+3]);
128
        dst[i+4]= bswap_32(src[i+4]);
129
        dst[i+5]= bswap_32(src[i+5]);
130
        dst[i+6]= bswap_32(src[i+6]);
131
        dst[i+7]= bswap_32(src[i+7]);
132
    }
133
    for(;i<w; i++){
134
        dst[i+0]= bswap_32(src[i+0]);
135
    }
136
}
137

    
138
static inline int add_left_prediction(uint8_t *dst, uint8_t *src, int w, int acc){
139
    int i;
140

    
141
    for(i=0; i<w-1; i++){
142
        acc+= src[i];
143
        dst[i]= acc;
144
        i++;
145
        acc+= src[i];
146
        dst[i]= acc;
147
    }
148

    
149
    for(; i<w; i++){
150
        acc+= src[i];
151
        dst[i]= acc;
152
    }
153

    
154
    return acc;
155
}
156

    
157
static inline void add_median_prediction(uint8_t *dst, uint8_t *src1, uint8_t *diff, int w, int *left, int *left_top){
158
    int i;
159
    uint8_t l, lt;
160

    
161
    l= *left;
162
    lt= *left_top;
163

    
164
    for(i=0; i<w; i++){
165
        l= mid_pred(l, src1[i], (l + src1[i] - lt)&0xFF) + diff[i];
166
        lt= src1[i];
167
        dst[i]= l;
168
    }    
169

    
170
    *left= l;
171
    *left_top= lt;
172
}
173
//FIXME optimize
174
static inline void sub_median_prediction(uint8_t *dst, uint8_t *src1, uint8_t *src2, int w, int *left, int *left_top){
175
    int i;
176
    uint8_t l, lt;
177

    
178
    l= *left;
179
    lt= *left_top;
180

    
181
    for(i=0; i<w; i++){
182
        const int pred= mid_pred(l, src1[i], (l + src1[i] - lt)&0xFF);
183
        lt= src1[i];
184
        l= src2[i];
185
        dst[i]= l - pred;
186
    }    
187

    
188
    *left= l;
189
    *left_top= lt;
190
}
191

    
192

    
193
static inline void add_left_prediction_bgr32(uint8_t *dst, uint8_t *src, int w, int *red, int *green, int *blue){
194
    int i;
195
    int r,g,b;
196
    r= *red;
197
    g= *green;
198
    b= *blue;
199

    
200
    for(i=0; i<w; i++){
201
        b+= src[4*i+0];
202
        g+= src[4*i+1];
203
        r+= src[4*i+2];
204
        
205
        dst[4*i+0]= b;
206
        dst[4*i+1]= g;
207
        dst[4*i+2]= r;
208
    }
209

    
210
    *red= r;
211
    *green= g;
212
    *blue= b;
213
}
214

    
215
static inline int sub_left_prediction(HYuvContext *s, uint8_t *dst, uint8_t *src, int w, int left){
216
    int i;
217
    if(w<32){
218
        for(i=0; i<w; i++){
219
            const int temp= src[i];
220
            dst[i]= temp - left;
221
            left= temp;
222
        }
223
        return left;
224
    }else{
225
        for(i=0; i<16; i++){
226
            const int temp= src[i];
227
            dst[i]= temp - left;
228
            left= temp;
229
        }
230
        s->dsp.diff_bytes(dst+16, src+16, src+15, w-16);
231
        return src[w-1];
232
    }
233
}
234

    
235
static void read_len_table(uint8_t *dst, GetBitContext *gb){
236
    int i, val, repeat;
237
  
238
    for(i=0; i<256;){
239
        repeat= get_bits(gb, 3);
240
        val   = get_bits(gb, 5);
241
        if(repeat==0)
242
            repeat= get_bits(gb, 8);
243
//printf("%d %d\n", val, repeat);
244
        while (repeat--)
245
            dst[i++] = val;
246
    }
247
}
248

    
249
static int generate_bits_table(uint32_t *dst, uint8_t *len_table){
250
    int len, index;
251
    uint32_t bits=0;
252

    
253
    for(len=32; len>0; len--){
254
        int bit= 1<<(32-len);
255
        for(index=0; index<256; index++){
256
            if(len_table[index]==len){
257
                if(bits & (bit-1)){
258
                    fprintf(stderr, "Error generating huffman table\n");
259
                    return -1;
260
                }
261
                dst[index]= bits>>(32-len);
262
                bits+= bit;
263
            }
264
        }
265
    }
266
    return 0;
267
}
268

    
269
static void generate_len_table(uint8_t *dst, uint64_t *stats, int size){
270
    uint64_t counts[2*size];
271
    int up[2*size];
272
    int offset, i, next;
273
    
274
    for(offset=1; ; offset<<=1){
275
        for(i=0; i<size; i++){
276
            counts[i]= stats[i] + offset - 1;
277
        }
278
        
279
        for(next=size; next<size*2; next++){
280
            uint64_t min1, min2;
281
            int min1_i, min2_i;
282
            
283
            min1=min2= INT64_MAX;
284
            min1_i= min2_i=-1;
285
            
286
            for(i=0; i<next; i++){
287
                if(min2 > counts[i]){
288
                    if(min1 > counts[i]){
289
                        min2= min1;
290
                        min2_i= min1_i;
291
                        min1= counts[i];
292
                        min1_i= i;
293
                    }else{
294
                        min2= counts[i];
295
                        min2_i= i;
296
                    }
297
                }
298
            }
299
            
300
            if(min2==INT64_MAX) break;
301
            
302
            counts[next]= min1 + min2;
303
            counts[min1_i]=
304
            counts[min2_i]= INT64_MAX;
305
            up[min1_i]=
306
            up[min2_i]= next;
307
            up[next]= -1;
308
        }
309
        
310
        for(i=0; i<size; i++){
311
            int len;
312
            int index=i;
313
            
314
            for(len=0; up[index] != -1; len++)
315
                index= up[index];
316
                
317
            if(len > 32) break;
318
            
319
            dst[i]= len;
320
        }
321
        if(i==size) break;
322
    }
323
}
324

    
325
static int read_huffman_tables(HYuvContext *s, uint8_t *src, int length){
326
    GetBitContext gb;
327
    int i;
328
    
329
    init_get_bits(&gb, src, length*8);
330
    
331
    for(i=0; i<3; i++){
332
        read_len_table(s->len[i], &gb);
333
        
334
        if(generate_bits_table(s->bits[i], s->len[i])<0){
335
            return -1;
336
        }
337
#if 0
338
for(j=0; j<256; j++){
339
printf("%6X, %2d,  %3d\n", s->bits[i][j], s->len[i][j], j);
340
}
341
#endif
342
        init_vlc(&s->vlc[i], VLC_BITS, 256, s->len[i], 1, 1, s->bits[i], 4, 4);
343
    }
344
    
345
    return 0;
346
}
347

    
348
static int read_old_huffman_tables(HYuvContext *s){
349
#if 1
350
    GetBitContext gb;
351
    int i;
352

    
353
    init_get_bits(&gb, classic_shift_luma, sizeof(classic_shift_luma)*8);
354
    read_len_table(s->len[0], &gb);
355
    init_get_bits(&gb, classic_shift_chroma, sizeof(classic_shift_chroma)*8);
356
    read_len_table(s->len[1], &gb);
357
    
358
    for(i=0; i<256; i++) s->bits[0][i] = classic_add_luma  [i];
359
    for(i=0; i<256; i++) s->bits[1][i] = classic_add_chroma[i];
360

    
361
    if(s->bitstream_bpp >= 24){
362
        memcpy(s->bits[1], s->bits[0], 256*sizeof(uint32_t));
363
        memcpy(s->len[1] , s->len [0], 256*sizeof(uint8_t));
364
    }
365
    memcpy(s->bits[2], s->bits[1], 256*sizeof(uint32_t));
366
    memcpy(s->len[2] , s->len [1], 256*sizeof(uint8_t));
367
    
368
    for(i=0; i<3; i++)
369
        init_vlc(&s->vlc[i], VLC_BITS, 256, s->len[i], 1, 1, s->bits[i], 4, 4);
370
    
371
    return 0;
372
#else
373
    fprintf(stderr, "v1 huffyuv is not supported \n");
374
    return -1;
375
#endif
376
}
377

    
378
static int decode_init(AVCodecContext *avctx)
379
{
380
    HYuvContext *s = avctx->priv_data;
381
    int width, height;
382

    
383
    s->avctx= avctx;
384
    s->flags= avctx->flags;
385
        
386
    dsputil_init(&s->dsp, avctx);
387
    
388
    width= s->width= avctx->width;
389
    height= s->height= avctx->height;
390
    avctx->coded_frame= &s->picture;
391

    
392
s->bgr32=1;
393
    assert(width && height);
394
//if(avctx->extradata)
395
//  printf("extradata:%X, extradata_size:%d\n", *(uint32_t*)avctx->extradata, avctx->extradata_size);
396
    if(avctx->extradata_size){
397
        if((avctx->bits_per_sample&7) && avctx->bits_per_sample != 12)
398
            s->version=1; // do such files exist at all?
399
        else
400
            s->version=2;
401
    }else
402
        s->version=0;
403
    
404
    if(s->version==2){
405
        int method;
406

    
407
        method= ((uint8_t*)avctx->extradata)[0];
408
        s->decorrelate= method&64 ? 1 : 0;
409
        s->predictor= method&63;
410
        s->bitstream_bpp= ((uint8_t*)avctx->extradata)[1];
411
        if(s->bitstream_bpp==0) 
412
            s->bitstream_bpp= avctx->bits_per_sample&~7;
413
            
414
        if(read_huffman_tables(s, ((uint8_t*)avctx->extradata)+4, avctx->extradata_size) < 0)
415
            return -1;
416
    }else{
417
        switch(avctx->bits_per_sample&7){
418
        case 1:
419
            s->predictor= LEFT;
420
            s->decorrelate= 0;
421
            break;
422
        case 2:
423
            s->predictor= LEFT;
424
            s->decorrelate= 1;
425
            break;
426
        case 3:
427
            s->predictor= PLANE;
428
            s->decorrelate= avctx->bits_per_sample >= 24;
429
            break;
430
        case 4:
431
            s->predictor= MEDIAN;
432
            s->decorrelate= 0;
433
            break;
434
        default:
435
            s->predictor= LEFT; //OLD
436
            s->decorrelate= 0;
437
            break;
438
        }
439
        s->bitstream_bpp= avctx->bits_per_sample & ~7;
440
        
441
        if(read_old_huffman_tables(s) < 0)
442
            return -1;
443
    }
444
    
445
    s->interlaced= height > 288;
446
    
447
    switch(s->bitstream_bpp){
448
    case 12:
449
        avctx->pix_fmt = PIX_FMT_YUV420P;
450
        break;
451
    case 16:
452
        if(s->yuy2){
453
            avctx->pix_fmt = PIX_FMT_YUV422;
454
        }else{
455
            avctx->pix_fmt = PIX_FMT_YUV422P;
456
        }
457
        break;
458
    case 24:
459
    case 32:
460
        if(s->bgr32){
461
            avctx->pix_fmt = PIX_FMT_RGBA32;
462
        }else{
463
            avctx->pix_fmt = PIX_FMT_BGR24;
464
        }
465
        break;
466
    default:
467
        assert(0);
468
    }
469
    
470
//    printf("pred:%d bpp:%d hbpp:%d il:%d\n", s->predictor, s->bitstream_bpp, avctx->bits_per_sample, s->interlaced);
471
    
472
    return 0;
473
}
474

    
475
static void store_table(HYuvContext *s, uint8_t *len){
476
    int i;
477
    int index= s->avctx->extradata_size;
478

    
479
    for(i=0; i<256;){
480
        int cur=i;
481
        int val= len[i];
482
        int repeat;
483
        
484
        for(; i<256 && len[i]==val; i++);
485
        
486
        repeat= i - cur;
487
        
488
        if(repeat>7){
489
            ((uint8_t*)s->avctx->extradata)[index++]= val;
490
            ((uint8_t*)s->avctx->extradata)[index++]= repeat;
491
        }else{
492
            ((uint8_t*)s->avctx->extradata)[index++]= val | (repeat<<5);
493
        }
494
    }
495
    
496
    s->avctx->extradata_size= index;
497
}
498

    
499
static int encode_init(AVCodecContext *avctx)
500
{
501
    HYuvContext *s = avctx->priv_data;
502
    int i, j, width, height;
503

    
504
    s->avctx= avctx;
505
    s->flags= avctx->flags;
506
        
507
    dsputil_init(&s->dsp, avctx);
508
    
509
    width= s->width= avctx->width;
510
    height= s->height= avctx->height;
511
    
512
    assert(width && height);
513
    
514
    avctx->extradata= av_mallocz(1024*10);
515
    avctx->stats_out= av_mallocz(1024*10);
516
    s->version=2;
517
    
518
    avctx->coded_frame= &s->picture;
519
    
520
    switch(avctx->pix_fmt){
521
    case PIX_FMT_YUV420P:
522
        if(avctx->strict_std_compliance>=0){
523
            fprintf(stderr, "YV12-huffyuv is experimental, there WILL be no compatbility! (use (v)strict=-1)\n");
524
            return -1;
525
        }
526
        s->bitstream_bpp= 12;
527
        break;
528
    case PIX_FMT_YUV422P:
529
        s->bitstream_bpp= 16;
530
        break;
531
    default:
532
        fprintf(stderr, "format not supported\n");
533
        return -1;
534
    }
535
    avctx->bits_per_sample= s->bitstream_bpp;
536
    s->decorrelate= s->bitstream_bpp >= 24;
537
    s->predictor= avctx->prediction_method;
538
    
539
    ((uint8_t*)avctx->extradata)[0]= s->predictor;
540
    ((uint8_t*)avctx->extradata)[1]= s->bitstream_bpp;
541
    ((uint8_t*)avctx->extradata)[2]=
542
    ((uint8_t*)avctx->extradata)[3]= 0;
543
    s->avctx->extradata_size= 4;
544
    
545
    if(avctx->stats_in){
546
        char *p= avctx->stats_in;
547
    
548
        for(i=0; i<3; i++)
549
            for(j=0; j<256; j++)
550
                s->stats[i][j]= 1;
551

    
552
        for(;;){
553
            for(i=0; i<3; i++){
554
                char *next;
555

    
556
                for(j=0; j<256; j++){
557
                    s->stats[i][j]+= strtol(p, &next, 0);
558
                    if(next==p) return -1;
559
                    p=next;
560
                }        
561
            }
562
            if(p[0]==0 || p[1]==0 || p[2]==0) break;
563
        }
564
    }else{
565
        for(i=0; i<3; i++)
566
            for(j=0; j<256; j++){
567
                int d= FFMIN(j, 256-j);
568
                
569
                s->stats[i][j]= 100000000/(d+1);
570
            }
571
    }
572
    
573
    for(i=0; i<3; i++){
574
        generate_len_table(s->len[i], s->stats[i], 256);
575

    
576
        if(generate_bits_table(s->bits[i], s->len[i])<0){
577
            return -1;
578
        }
579
        
580
        store_table(s, s->len[i]);
581
    }
582

    
583
    for(i=0; i<3; i++)
584
        for(j=0; j<256; j++)
585
            s->stats[i][j]= 0;
586
    
587
    s->interlaced= height > 288;
588
    
589
//    printf("pred:%d bpp:%d hbpp:%d il:%d\n", s->predictor, s->bitstream_bpp, avctx->bits_per_sample, s->interlaced);
590
    
591
    s->picture_number=0;
592
    
593
    return 0;
594
}
595

    
596
static void decode_422_bitstream(HYuvContext *s, int count){
597
    int i;
598
    
599
    count/=2;
600
    
601
    for(i=0; i<count; i++){
602
        s->temp[0][2*i  ]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3); 
603
        s->temp[1][  i  ]= get_vlc2(&s->gb, s->vlc[1].table, VLC_BITS, 3); 
604
        s->temp[0][2*i+1]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3); 
605
        s->temp[2][  i  ]= get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3); 
606
    }
607
}
608

    
609
static void decode_gray_bitstream(HYuvContext *s, int count){
610
    int i;
611
    
612
    count/=2;
613
    
614
    for(i=0; i<count; i++){
615
        s->temp[0][2*i  ]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3); 
616
        s->temp[0][2*i+1]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3); 
617
    }
618
}
619

    
620
static void encode_422_bitstream(HYuvContext *s, int count){
621
    int i;
622
    
623
    count/=2;
624
    if(s->flags&CODEC_FLAG_PASS1){
625
        for(i=0; i<count; i++){
626
            s->stats[0][ s->temp[0][2*i  ] ]++;
627
            s->stats[1][ s->temp[1][  i  ] ]++;
628
            s->stats[0][ s->temp[0][2*i+1] ]++;
629
            s->stats[2][ s->temp[2][  i  ] ]++;
630
        }
631
    }else{
632
        for(i=0; i<count; i++){
633
            put_bits(&s->pb, s->len[0][ s->temp[0][2*i  ] ], s->bits[0][ s->temp[0][2*i  ] ]);
634
            put_bits(&s->pb, s->len[1][ s->temp[1][  i  ] ], s->bits[1][ s->temp[1][  i  ] ]);
635
            put_bits(&s->pb, s->len[0][ s->temp[0][2*i+1] ], s->bits[0][ s->temp[0][2*i+1] ]);
636
            put_bits(&s->pb, s->len[2][ s->temp[2][  i  ] ], s->bits[2][ s->temp[2][  i  ] ]);
637
        }
638
    }
639
}
640

    
641
static void encode_gray_bitstream(HYuvContext *s, int count){
642
    int i;
643
    
644
    count/=2;
645
    if(s->flags&CODEC_FLAG_PASS1){
646
        for(i=0; i<count; i++){
647
            s->stats[0][ s->temp[0][2*i  ] ]++;
648
            s->stats[0][ s->temp[0][2*i+1] ]++;
649
        }
650
    }else{
651
        for(i=0; i<count; i++){
652
            put_bits(&s->pb, s->len[0][ s->temp[0][2*i  ] ], s->bits[0][ s->temp[0][2*i  ] ]);
653
            put_bits(&s->pb, s->len[0][ s->temp[0][2*i+1] ], s->bits[0][ s->temp[0][2*i+1] ]);
654
        }
655
    }
656
}
657

    
658
static void decode_bgr_bitstream(HYuvContext *s, int count){
659
    int i;
660
    
661
    if(s->decorrelate){
662
        if(s->bitstream_bpp==24){
663
            for(i=0; i<count; i++){
664
                s->temp[0][4*i+1]= get_vlc2(&s->gb, s->vlc[1].table, VLC_BITS, 3); 
665
                s->temp[0][4*i  ]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3) + s->temp[0][4*i+1];
666
                s->temp[0][4*i+2]= get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3) + s->temp[0][4*i+1];
667
            }
668
        }else{
669
            for(i=0; i<count; i++){
670
                s->temp[0][4*i+1]= get_vlc2(&s->gb, s->vlc[1].table, VLC_BITS, 3); 
671
                s->temp[0][4*i  ]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3) + s->temp[0][4*i+1];
672
                s->temp[0][4*i+2]= get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3) + s->temp[0][4*i+1]; 
673
                                   get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3); //?!
674
            }
675
        }
676
    }else{
677
        if(s->bitstream_bpp==24){
678
            for(i=0; i<count; i++){
679
                s->temp[0][4*i  ]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3);
680
                s->temp[0][4*i+1]= get_vlc2(&s->gb, s->vlc[1].table, VLC_BITS, 3); 
681
                s->temp[0][4*i+2]= get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3); 
682
            }
683
        }else{
684
            for(i=0; i<count; i++){
685
                s->temp[0][4*i  ]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3);
686
                s->temp[0][4*i+1]= get_vlc2(&s->gb, s->vlc[1].table, VLC_BITS, 3); 
687
                s->temp[0][4*i+2]= get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3); 
688
                                   get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3); //?!
689
            }
690
        }
691
    }
692
}
693

    
694
static void draw_slice(HYuvContext *s, int y){
695
    int h, cy;
696
    uint8_t *src_ptr[3];
697
    
698
    if(s->avctx->draw_horiz_band==NULL) 
699
        return;
700
        
701
    h= y - s->last_slice_end;
702
    y -= h;
703
    
704
    if(s->bitstream_bpp==12){
705
        cy= y>>1;
706
    }else{
707
        cy= y;
708
    }
709
    
710
    src_ptr[0] = s->picture.data[0] + s->picture.linesize[0]*y;
711
    src_ptr[1] = s->picture.data[1] + s->picture.linesize[1]*cy;
712
    src_ptr[2] = s->picture.data[2] + s->picture.linesize[2]*cy;
713
    emms_c();
714

    
715
    s->avctx->draw_horiz_band(s->avctx, src_ptr, s->picture.linesize[0], y, s->width, h);
716
    
717
    s->last_slice_end= y + h;
718
}
719

    
720
static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8_t *buf, int buf_size){
721
    HYuvContext *s = avctx->priv_data;
722
    const int width= s->width;
723
    const int width2= s->width>>1;
724
    const int height= s->height;
725
    int fake_ystride, fake_ustride, fake_vstride;
726
    AVFrame * const p= &s->picture;
727

    
728
    AVFrame *picture = data;
729

    
730
    *data_size = 0;
731

    
732
    /* no supplementary picture */
733
    if (buf_size == 0)
734
        return 0;
735

    
736
    bswap_buf((uint32_t*)s->bitstream_buffer, (uint32_t*)buf, buf_size/4);
737
    
738
    init_get_bits(&s->gb, s->bitstream_buffer, buf_size*8);
739

    
740
    if(p->data[0])
741
        avctx->release_buffer(avctx, p);
742

    
743
    p->reference= 0;
744
    if(avctx->get_buffer(avctx, p) < 0){
745
        fprintf(stderr, "get_buffer() failed\n");
746
        return -1;
747
    }
748

    
749
    fake_ystride= s->interlaced ? p->linesize[0]*2  : p->linesize[0];
750
    fake_ustride= s->interlaced ? p->linesize[1]*2  : p->linesize[1];
751
    fake_vstride= s->interlaced ? p->linesize[2]*2  : p->linesize[2];
752
    
753
    s->last_slice_end= 0;
754
        
755
    if(s->bitstream_bpp<24){
756
        int y, cy;
757
        int lefty, leftu, leftv;
758
        int lefttopy, lefttopu, lefttopv;
759
        
760
        if(s->yuy2){
761
            p->data[0][3]= get_bits(&s->gb, 8);
762
            p->data[0][2]= get_bits(&s->gb, 8);
763
            p->data[0][1]= get_bits(&s->gb, 8);
764
            p->data[0][0]= get_bits(&s->gb, 8);
765
            
766
            fprintf(stderr, "YUY2 output isnt implemenetd yet\n");
767
            return -1;
768
        }else{
769
        
770
            leftv= p->data[2][0]= get_bits(&s->gb, 8);
771
            lefty= p->data[0][1]= get_bits(&s->gb, 8);
772
            leftu= p->data[1][0]= get_bits(&s->gb, 8);
773
                   p->data[0][0]= get_bits(&s->gb, 8);
774
        
775
            switch(s->predictor){
776
            case LEFT:
777
            case PLANE:
778
                decode_422_bitstream(s, width-2);
779
                lefty= add_left_prediction(p->data[0] + 2, s->temp[0], width-2, lefty);
780
                if(!(s->flags&CODEC_FLAG_GRAY)){
781
                    leftu= add_left_prediction(p->data[1] + 1, s->temp[1], width2-1, leftu);
782
                    leftv= add_left_prediction(p->data[2] + 1, s->temp[2], width2-1, leftv);
783
                }
784

    
785
                for(cy=y=1; y<s->height; y++,cy++){
786
                    uint8_t *ydst, *udst, *vdst;
787
                    
788
                    if(s->bitstream_bpp==12){
789
                        decode_gray_bitstream(s, width);
790
                    
791
                        ydst= p->data[0] + p->linesize[0]*y;
792

    
793
                        lefty= add_left_prediction(ydst, s->temp[0], width, lefty);
794
                        if(s->predictor == PLANE){
795
                            if(y>s->interlaced)
796
                                s->dsp.add_bytes(ydst, ydst - fake_ystride, width);
797
                        }
798
                        y++;
799
                        if(y>=s->height) break;
800
                    }
801
                    
802
                    draw_slice(s, y);
803
                    
804
                    ydst= p->data[0] + p->linesize[0]*y;
805
                    udst= p->data[1] + p->linesize[1]*cy;
806
                    vdst= p->data[2] + p->linesize[2]*cy;
807
                    
808
                    decode_422_bitstream(s, width);
809
                    lefty= add_left_prediction(ydst, s->temp[0], width, lefty);
810
                    if(!(s->flags&CODEC_FLAG_GRAY)){
811
                        leftu= add_left_prediction(udst, s->temp[1], width2, leftu);
812
                        leftv= add_left_prediction(vdst, s->temp[2], width2, leftv);
813
                    }
814
                    if(s->predictor == PLANE){
815
                        if(cy>s->interlaced){
816
                            s->dsp.add_bytes(ydst, ydst - fake_ystride, width);
817
                            if(!(s->flags&CODEC_FLAG_GRAY)){
818
                                s->dsp.add_bytes(udst, udst - fake_ustride, width2);
819
                                s->dsp.add_bytes(vdst, vdst - fake_vstride, width2);
820
                            }
821
                        }
822
                    }
823
                }
824
                draw_slice(s, height);
825
                
826
                break;
827
            case MEDIAN:
828
                /* first line except first 2 pixels is left predicted */
829
                decode_422_bitstream(s, width-2);
830
                lefty= add_left_prediction(p->data[0] + 2, s->temp[0], width-2, lefty);
831
                if(!(s->flags&CODEC_FLAG_GRAY)){
832
                    leftu= add_left_prediction(p->data[1] + 1, s->temp[1], width2-1, leftu);
833
                    leftv= add_left_prediction(p->data[2] + 1, s->temp[2], width2-1, leftv);
834
                }
835
                
836
                cy=y=1;
837
                
838
                /* second line is left predicted for interlaced case */
839
                if(s->interlaced){
840
                    decode_422_bitstream(s, width);
841
                    lefty= add_left_prediction(p->data[0] + p->linesize[0], s->temp[0], width, lefty);
842
                    if(!(s->flags&CODEC_FLAG_GRAY)){
843
                        leftu= add_left_prediction(p->data[1] + p->linesize[2], s->temp[1], width2, leftu);
844
                        leftv= add_left_prediction(p->data[2] + p->linesize[1], s->temp[2], width2, leftv);
845
                    }
846
                    y++; cy++;
847
                }
848

    
849
                /* next 4 pixels are left predicted too */
850
                decode_422_bitstream(s, 4);
851
                lefty= add_left_prediction(p->data[0] + fake_ystride, s->temp[0], 4, lefty);
852
                if(!(s->flags&CODEC_FLAG_GRAY)){
853
                    leftu= add_left_prediction(p->data[1] + fake_ustride, s->temp[1], 2, leftu);
854
                    leftv= add_left_prediction(p->data[2] + fake_vstride, s->temp[2], 2, leftv);
855
                }
856

    
857
                /* next line except the first 4 pixels is median predicted */
858
                lefttopy= p->data[0][3];
859
                decode_422_bitstream(s, width-4);
860
                add_median_prediction(p->data[0] + fake_ystride+4, p->data[0]+4, s->temp[0], width-4, &lefty, &lefttopy);
861
                if(!(s->flags&CODEC_FLAG_GRAY)){
862
                    lefttopu= p->data[1][1];
863
                    lefttopv= p->data[2][1];
864
                    add_median_prediction(p->data[1] + fake_ustride+2, p->data[1]+2, s->temp[1], width2-2, &leftu, &lefttopu);
865
                    add_median_prediction(p->data[2] + fake_vstride+2, p->data[2]+2, s->temp[2], width2-2, &leftv, &lefttopv);
866
                }
867
                y++; cy++;
868
                
869
                for(; y<height; y++,cy++){
870
                    uint8_t *ydst, *udst, *vdst;
871

    
872
                    if(s->bitstream_bpp==12){
873
                        while(2*cy > y){
874
                            decode_gray_bitstream(s, width);
875
                            ydst= p->data[0] + p->linesize[0]*y;
876
                            add_median_prediction(ydst, ydst - fake_ystride, s->temp[0], width, &lefty, &lefttopy);
877
                            y++;
878
                        }
879
                        if(y>=height) break;
880
                    }
881
                    draw_slice(s, y);
882

    
883
                    decode_422_bitstream(s, width);
884

    
885
                    ydst= p->data[0] + p->linesize[0]*y;
886
                    udst= p->data[1] + p->linesize[1]*cy;
887
                    vdst= p->data[2] + p->linesize[2]*cy;
888

    
889
                    add_median_prediction(ydst, ydst - fake_ystride, s->temp[0], width, &lefty, &lefttopy);
890
                    if(!(s->flags&CODEC_FLAG_GRAY)){
891
                        add_median_prediction(udst, udst - fake_ustride, s->temp[1], width2, &leftu, &lefttopu);
892
                        add_median_prediction(vdst, vdst - fake_vstride, s->temp[2], width2, &leftv, &lefttopv);
893
                    }
894
                }
895

    
896
                draw_slice(s, height);
897
                break;
898
            }
899
        }
900
    }else{
901
        int y;
902
        int leftr, leftg, leftb;
903
        const int last_line= (height-1)*p->linesize[0];
904
        
905
        if(s->bitstream_bpp==32){
906
                   p->data[0][last_line+3]= get_bits(&s->gb, 8);
907
            leftr= p->data[0][last_line+2]= get_bits(&s->gb, 8);
908
            leftg= p->data[0][last_line+1]= get_bits(&s->gb, 8);
909
            leftb= p->data[0][last_line+0]= get_bits(&s->gb, 8);
910
        }else{
911
            leftr= p->data[0][last_line+2]= get_bits(&s->gb, 8);
912
            leftg= p->data[0][last_line+1]= get_bits(&s->gb, 8);
913
            leftb= p->data[0][last_line+0]= get_bits(&s->gb, 8);
914
            skip_bits(&s->gb, 8);
915
        }
916
        
917
        if(s->bgr32){
918
            switch(s->predictor){
919
            case LEFT:
920
            case PLANE:
921
                decode_bgr_bitstream(s, width-1);
922
                add_left_prediction_bgr32(p->data[0] + last_line+4, s->temp[0], width-1, &leftr, &leftg, &leftb);
923

    
924
                for(y=s->height-2; y>=0; y--){ //yes its stored upside down
925
                    decode_bgr_bitstream(s, width);
926
                    
927
                    add_left_prediction_bgr32(p->data[0] + p->linesize[0]*y, s->temp[0], width, &leftr, &leftg, &leftb);
928
                    if(s->predictor == PLANE){
929
                        if((y&s->interlaced)==0){
930
                            s->dsp.add_bytes(p->data[0] + p->linesize[0]*y, 
931
                                             p->data[0] + p->linesize[0]*y + fake_ystride, fake_ystride);
932
                        }
933
                    }
934
                }
935
                draw_slice(s, height); // just 1 large slice as this isnt possible in reverse order
936
                break;
937
            default:
938
                fprintf(stderr, "prediction type not supported!\n");
939
            }
940
        }else{
941

    
942
            fprintf(stderr, "BGR24 output isnt implemenetd yet\n");
943
            return -1;
944
        }
945
    }
946
    emms_c();
947
    
948
    *picture= *p;
949
    *data_size = sizeof(AVFrame);
950
    
951
    return (get_bits_count(&s->gb)+31)/32*4;
952
}
953

    
954
static int decode_end(AVCodecContext *avctx)
955
{
956
    HYuvContext *s = avctx->priv_data;
957
    int i;
958
    
959
    for(i=0; i<3; i++){
960
        free_vlc(&s->vlc[i]);
961
    }
962
    
963
    avcodec_default_free_buffers(avctx);
964

    
965
    return 0;
966
}
967

    
968
static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){
969
    HYuvContext *s = avctx->priv_data;
970
    AVFrame *pict = data;
971
    const int width= s->width;
972
    const int width2= s->width>>1;
973
    const int height= s->height;
974
    const int fake_ystride= s->interlaced ? pict->linesize[0]*2  : pict->linesize[0];
975
    const int fake_ustride= s->interlaced ? pict->linesize[1]*2  : pict->linesize[1];
976
    const int fake_vstride= s->interlaced ? pict->linesize[2]*2  : pict->linesize[2];
977
    AVFrame * const p= &s->picture;
978
    int i, size;
979

    
980
    init_put_bits(&s->pb, buf, buf_size, NULL, NULL);
981
    
982
    *p = *pict;
983
    p->pict_type= FF_I_TYPE;
984
    p->key_frame= 1;
985
    
986
    if(avctx->pix_fmt == PIX_FMT_YUV422P || avctx->pix_fmt == PIX_FMT_YUV420P){
987
        int lefty, leftu, leftv, y, cy;
988

    
989
        put_bits(&s->pb, 8, leftv= p->data[2][0]);
990
        put_bits(&s->pb, 8, lefty= p->data[0][1]);
991
        put_bits(&s->pb, 8, leftu= p->data[1][0]);
992
        put_bits(&s->pb, 8,        p->data[0][0]);
993
        
994
        lefty= sub_left_prediction(s, s->temp[0], p->data[0]+2, width-2 , lefty);
995
        leftu= sub_left_prediction(s, s->temp[1], p->data[1]+1, width2-1, leftu);
996
        leftv= sub_left_prediction(s, s->temp[2], p->data[2]+1, width2-1, leftv);
997
        
998
        encode_422_bitstream(s, width-2);
999
        
1000
        if(s->predictor==MEDIAN){
1001
            int lefttopy, lefttopu, lefttopv;
1002
            cy=y=1;
1003
            if(s->interlaced){
1004
                lefty= sub_left_prediction(s, s->temp[0], p->data[0]+p->linesize[0], width , lefty);
1005
                leftu= sub_left_prediction(s, s->temp[1], p->data[1]+p->linesize[1], width2, leftu);
1006
                leftv= sub_left_prediction(s, s->temp[2], p->data[2]+p->linesize[2], width2, leftv);
1007
        
1008
                encode_422_bitstream(s, width);
1009
                y++; cy++;
1010
            }
1011
            
1012
            lefty= sub_left_prediction(s, s->temp[0], p->data[0]+fake_ystride, 4, lefty);
1013
            leftu= sub_left_prediction(s, s->temp[1], p->data[1]+fake_ystride, 2, leftu);
1014
            leftv= sub_left_prediction(s, s->temp[2], p->data[2]+fake_ystride, 2, leftv);
1015
        
1016
            encode_422_bitstream(s, 4);
1017

    
1018
            lefttopy= p->data[0][3];
1019
            lefttopu= p->data[1][1];
1020
            lefttopv= p->data[2][1];
1021
            sub_median_prediction(s->temp[0], p->data[0]+4, p->data[0] + fake_ystride+4, width-4 , &lefty, &lefttopy);
1022
            sub_median_prediction(s->temp[1], p->data[1]+2, p->data[1] + fake_ustride+2, width2-2, &leftu, &lefttopu);
1023
            sub_median_prediction(s->temp[2], p->data[2]+2, p->data[2] + fake_vstride+2, width2-2, &leftv, &lefttopv);
1024
            encode_422_bitstream(s, width-4);
1025
            y++; cy++;
1026

    
1027
            for(; y<height; y++,cy++){
1028
                uint8_t *ydst, *udst, *vdst;
1029
                    
1030
                if(s->bitstream_bpp==12){
1031
                    while(2*cy > y){
1032
                        ydst= p->data[0] + p->linesize[0]*y;
1033
                        sub_median_prediction(s->temp[0], ydst - fake_ystride, ydst, width , &lefty, &lefttopy);
1034
                        encode_gray_bitstream(s, width);
1035
                        y++;
1036
                    }
1037
                    if(y>=height) break;
1038
                }
1039
                ydst= p->data[0] + p->linesize[0]*y;
1040
                udst= p->data[1] + p->linesize[1]*cy;
1041
                vdst= p->data[2] + p->linesize[2]*cy;
1042

    
1043
                sub_median_prediction(s->temp[0], ydst - fake_ystride, ydst, width , &lefty, &lefttopy);
1044
                sub_median_prediction(s->temp[1], udst - fake_ustride, udst, width2, &leftu, &lefttopu);
1045
                sub_median_prediction(s->temp[2], vdst - fake_vstride, vdst, width2, &leftv, &lefttopv);
1046

    
1047
                encode_422_bitstream(s, width);
1048
            }
1049
        }else{
1050
            for(cy=y=1; y<height; y++,cy++){
1051
                uint8_t *ydst, *udst, *vdst;
1052
                
1053
                /* encode a luma only line & y++ */
1054
                if(s->bitstream_bpp==12){
1055
                    ydst= p->data[0] + p->linesize[0]*y;
1056

    
1057
                    if(s->predictor == PLANE && s->interlaced < y){
1058
                        s->dsp.diff_bytes(s->temp[1], ydst, ydst - fake_ystride, width);
1059

    
1060
                        lefty= sub_left_prediction(s, s->temp[0], s->temp[1], width , lefty);
1061
                    }else{
1062
                        lefty= sub_left_prediction(s, s->temp[0], ydst, width , lefty);
1063
                    }
1064
                    encode_gray_bitstream(s, width);
1065
                    y++;
1066
                    if(y>=height) break;
1067
                }
1068
                
1069
                ydst= p->data[0] + p->linesize[0]*y;
1070
                udst= p->data[1] + p->linesize[1]*cy;
1071
                vdst= p->data[2] + p->linesize[2]*cy;
1072

    
1073
                if(s->predictor == PLANE && s->interlaced < cy){
1074
                    s->dsp.diff_bytes(s->temp[1], ydst, ydst - fake_ystride, width);
1075
                    s->dsp.diff_bytes(s->temp[2], udst, udst - fake_ustride, width2);
1076
                    s->dsp.diff_bytes(s->temp[3], vdst, vdst - fake_vstride, width2);
1077

    
1078
                    lefty= sub_left_prediction(s, s->temp[0], s->temp[1], width , lefty);
1079
                    leftu= sub_left_prediction(s, s->temp[1], s->temp[2], width2, leftu);
1080
                    leftv= sub_left_prediction(s, s->temp[2], s->temp[3], width2, leftv);
1081
                }else{
1082
                    lefty= sub_left_prediction(s, s->temp[0], ydst, width , lefty);
1083
                    leftu= sub_left_prediction(s, s->temp[1], udst, width2, leftu);
1084
                    leftv= sub_left_prediction(s, s->temp[2], vdst, width2, leftv);
1085
                }
1086

    
1087
                encode_422_bitstream(s, width);
1088
            }
1089
        }        
1090
    }else{
1091
        fprintf(stderr, "Format not supported!\n");
1092
    }
1093
    emms_c();
1094
    
1095
    size= (get_bit_count(&s->pb)+31)/32;
1096
    
1097
    if((s->flags&CODEC_FLAG_PASS1) && (s->picture_number&31)==0){
1098
        int j;
1099
        char *p= avctx->stats_out;
1100
        for(i=0; i<3; i++){
1101
            for(j=0; j<256; j++){
1102
                sprintf(p, "%Ld ", s->stats[i][j]);
1103
                p+= strlen(p);
1104
                s->stats[i][j]= 0;
1105
            }
1106
            sprintf(p, "\n");
1107
            p++;
1108
        }
1109
    }else{
1110
        flush_put_bits(&s->pb);
1111
        bswap_buf((uint32_t*)buf, (uint32_t*)buf, size);
1112
    }
1113
    
1114
    s->picture_number++;
1115

    
1116
    return size*4;
1117
}
1118

    
1119
static int encode_end(AVCodecContext *avctx)
1120
{
1121
//    HYuvContext *s = avctx->priv_data;
1122

    
1123
    av_freep(&avctx->extradata);
1124
    av_freep(&avctx->stats_out);
1125
    
1126
    return 0;
1127
}
1128

    
1129
static const AVOption huffyuv_options[] =
1130
{
1131
    AVOPTION_CODEC_INT("prediction_method", "prediction_method", prediction_method, 0, 2, 0),
1132
    AVOPTION_END()
1133
};
1134

    
1135
AVCodec huffyuv_decoder = {
1136
    "huffyuv",
1137
    CODEC_TYPE_VIDEO,
1138
    CODEC_ID_HUFFYUV,
1139
    sizeof(HYuvContext),
1140
    decode_init,
1141
    NULL,
1142
    decode_end,
1143
    decode_frame,
1144
    CODEC_CAP_DR1 | CODEC_CAP_DRAW_HORIZ_BAND,
1145
    NULL
1146
};
1147

    
1148
AVCodec huffyuv_encoder = {
1149
    "huffyuv",
1150
    CODEC_TYPE_VIDEO,
1151
    CODEC_ID_HUFFYUV,
1152
    sizeof(HYuvContext),
1153
    encode_init,
1154
    encode_frame,
1155
    encode_end,
1156
    .options = huffyuv_options,
1157
};