Statistics
| Branch: | Revision:

ffmpeg / libavcodec / huffyuv.c @ 983e3246

History | View | Annotate | Download (37.3 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
    p->reference= 0;
741
    if(avctx->get_buffer(avctx, p) < 0){
742
        fprintf(stderr, "get_buffer() failed\n");
743
        return -1;
744
    }
745

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

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

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

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

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

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

    
880
                    decode_422_bitstream(s, width);
881

    
882
                    ydst= p->data[0] + p->linesize[0]*y;
883
                    udst= p->data[1] + p->linesize[1]*cy;
884
                    vdst= p->data[2] + p->linesize[2]*cy;
885

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

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

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

    
939
            fprintf(stderr, "BGR24 output isnt implemenetd yet\n");
940
            return -1;
941
        }
942
    }
943
    emms_c();
944
    
945
    *picture= *p;
946
    
947
    avctx->release_buffer(avctx, p);
948

    
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
    if(avctx->get_buffer == avcodec_default_get_buffer){
964
        for(i=0; i<4; i++){
965
            av_freep(&s->picture.base[i]);
966
            s->picture.data[i]= NULL;
967
        }
968
        av_freep(&s->picture.opaque);
969
    }
970

    
971
    return 0;
972
}
973

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

    
986
    init_put_bits(&s->pb, buf, buf_size, NULL, NULL);
987
    
988
    *p = *pict;
989
    p->pict_type= FF_I_TYPE;
990
    p->key_frame= 1;
991
    
992
    if(avctx->pix_fmt == PIX_FMT_YUV422P || avctx->pix_fmt == PIX_FMT_YUV420P){
993
        int lefty, leftu, leftv, y, cy;
994

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

    
1024
            lefttopy= p->data[0][3];
1025
            lefttopu= p->data[1][1];
1026
            lefttopv= p->data[2][1];
1027
            sub_median_prediction(s->temp[0], p->data[0]+4, p->data[0] + fake_ystride+4, width-4 , &lefty, &lefttopy);
1028
            sub_median_prediction(s->temp[1], p->data[1]+2, p->data[1] + fake_ustride+2, width2-2, &leftu, &lefttopu);
1029
            sub_median_prediction(s->temp[2], p->data[2]+2, p->data[2] + fake_vstride+2, width2-2, &leftv, &lefttopv);
1030
            encode_422_bitstream(s, width-4);
1031
            y++; cy++;
1032

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

    
1049
                sub_median_prediction(s->temp[0], ydst - fake_ystride, ydst, width , &lefty, &lefttopy);
1050
                sub_median_prediction(s->temp[1], udst - fake_ustride, udst, width2, &leftu, &lefttopu);
1051
                sub_median_prediction(s->temp[2], vdst - fake_vstride, vdst, width2, &leftv, &lefttopv);
1052

    
1053
                encode_422_bitstream(s, width);
1054
            }
1055
        }else{
1056
            for(cy=y=1; y<height; y++,cy++){
1057
                uint8_t *ydst, *udst, *vdst;
1058
                
1059
                /* encode a luma only line & y++ */
1060
                if(s->bitstream_bpp==12){
1061
                    ydst= p->data[0] + p->linesize[0]*y;
1062

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

    
1066
                        lefty= sub_left_prediction(s, s->temp[0], s->temp[1], width , lefty);
1067
                    }else{
1068
                        lefty= sub_left_prediction(s, s->temp[0], ydst, width , lefty);
1069
                    }
1070
                    encode_gray_bitstream(s, width);
1071
                    y++;
1072
                    if(y>=height) break;
1073
                }
1074
                
1075
                ydst= p->data[0] + p->linesize[0]*y;
1076
                udst= p->data[1] + p->linesize[1]*cy;
1077
                vdst= p->data[2] + p->linesize[2]*cy;
1078

    
1079
                if(s->predictor == PLANE && s->interlaced < cy){
1080
                    s->dsp.diff_bytes(s->temp[1], ydst, ydst - fake_ystride, width);
1081
                    s->dsp.diff_bytes(s->temp[2], udst, udst - fake_ustride, width2);
1082
                    s->dsp.diff_bytes(s->temp[3], vdst, vdst - fake_vstride, width2);
1083

    
1084
                    lefty= sub_left_prediction(s, s->temp[0], s->temp[1], width , lefty);
1085
                    leftu= sub_left_prediction(s, s->temp[1], s->temp[2], width2, leftu);
1086
                    leftv= sub_left_prediction(s, s->temp[2], s->temp[3], width2, leftv);
1087
                }else{
1088
                    lefty= sub_left_prediction(s, s->temp[0], ydst, width , lefty);
1089
                    leftu= sub_left_prediction(s, s->temp[1], udst, width2, leftu);
1090
                    leftv= sub_left_prediction(s, s->temp[2], vdst, width2, leftv);
1091
                }
1092

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

    
1122
    return size*4;
1123
}
1124

    
1125
static int encode_end(AVCodecContext *avctx)
1126
{
1127
//    HYuvContext *s = avctx->priv_data;
1128

    
1129
    av_freep(&avctx->extradata);
1130
    av_freep(&avctx->stats_out);
1131
    
1132
    return 0;
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
};