Statistics
| Branch: | Revision:

ffmpeg / libavcodec / zmbv.c @ 2029f312

History | View | Annotate | Download (19.2 KB)

1
/*
2
 * Zip Motion Blocks Video (ZMBV) decoder
3
 * Copyright (c) 2006 Konstantin Shishkov
4
 *
5
 * This file is part of FFmpeg.
6
 *
7
 * FFmpeg is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU Lesser General Public
9
 * License as published by the Free Software Foundation; either
10
 * version 2.1 of the License, or (at your option) any later version.
11
 *
12
 * FFmpeg is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 * Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with FFmpeg; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
 *
21
 */
22

    
23
/**
24
 * @file zmbv.c
25
 * Zip Motion Blocks Video decoder
26
 */
27

    
28
#include <stdio.h>
29
#include <stdlib.h>
30

    
31
#include "avcodec.h"
32

    
33
#ifdef CONFIG_ZLIB
34
#include <zlib.h>
35
#endif
36

    
37
#define ZMBV_KEYFRAME 1
38
#define ZMBV_DELTAPAL 2
39

    
40
enum ZmbvFormat {
41
    ZMBV_FMT_NONE  = 0,
42
    ZMBV_FMT_1BPP  = 1,
43
    ZMBV_FMT_2BPP  = 2,
44
    ZMBV_FMT_4BPP  = 3,
45
    ZMBV_FMT_8BPP  = 4,
46
    ZMBV_FMT_15BPP = 5,
47
    ZMBV_FMT_16BPP = 6,
48
    ZMBV_FMT_24BPP = 7,
49
    ZMBV_FMT_32BPP = 8
50
};
51

    
52
/*
53
 * Decoder context
54
 */
55
typedef struct ZmbvContext {
56
    AVCodecContext *avctx;
57
    AVFrame pic;
58

    
59
    int bpp;
60
    unsigned int decomp_size;
61
    uint8_t* decomp_buf;
62
    uint8_t pal[768];
63
    uint8_t *prev, *cur;
64
    int width, height;
65
    int fmt;
66
    int comp;
67
    int flags;
68
    int bw, bh, bx, by;
69
    int decomp_len;
70
#ifdef CONFIG_ZLIB
71
    z_stream zstream;
72
#endif
73
    int (*decode_intra)(struct ZmbvContext *c);
74
    int (*decode_xor)(struct ZmbvContext *c);
75
} ZmbvContext;
76

    
77
/**
78
 * Decode XOR'ed frame - 8bpp version
79
 */
80

    
81
static int zmbv_decode_xor_8(ZmbvContext *c)
82
{
83
    uint8_t *src = c->decomp_buf;
84
    uint8_t *output, *prev;
85
    int8_t *mvec;
86
    int x, y;
87
    int d, dx, dy, bw2, bh2;
88
    int block;
89
    int i, j;
90
    int mx, my;
91

    
92
    output = c->cur;
93
    prev = c->prev;
94

    
95
    if(c->flags & ZMBV_DELTAPAL){
96
        for(i = 0; i < 768; i++)
97
            c->pal[i] ^= *src++;
98
    }
99

    
100
    mvec = (int8_t*)src;
101
    src += ((c->bx * c->by * 2 + 3) & ~3);
102

    
103
    block = 0;
104
    for(y = 0; y < c->height; y += c->bh) {
105
        bh2 = ((c->height - y) > c->bh) ? c->bh : (c->height - y);
106
        for(x = 0; x < c->width; x += c->bw) {
107
            uint8_t *out, *tprev;
108

    
109
            d = mvec[block] & 1;
110
            dx = mvec[block] >> 1;
111
            dy = mvec[block + 1] >> 1;
112
            block += 2;
113

    
114
            bw2 = ((c->width - x) > c->bw) ? c->bw : (c->width - x);
115

    
116
            /* copy block - motion vectors out of bounds are used to zero blocks */
117
            out = output + x;
118
            tprev = prev + x + dx + dy * c->width;
119
            mx = x + dx;
120
            my = y + dy;
121
            for(j = 0; j < bh2; j++){
122
                if((my + j < 0) || (my + j >= c->height)) {
123
                    memset(out, 0, bw2);
124
                } else {
125
                    for(i = 0; i < bw2; i++){
126
                        if((mx + i < 0) || (mx + i >= c->width))
127
                            out[i] = 0;
128
                        else
129
                            out[i] = tprev[i];
130
                    }
131
                }
132
                out += c->width;
133
                tprev += c->width;
134
            }
135

    
136
            if(d) { /* apply XOR'ed difference */
137
                out = output + x;
138
                for(j = 0; j < bh2; j++){
139
                    for(i = 0; i < bw2; i++)
140
                        out[i] ^= *src++;
141
                    out += c->width;
142
                }
143
            }
144
        }
145
        output += c->width * c->bh;
146
        prev += c->width * c->bh;
147
    }
148
    if(src - c->decomp_buf != c->decomp_len)
149
        av_log(c->avctx, AV_LOG_ERROR, "Used %i of %i bytes\n", src-c->decomp_buf, c->decomp_len);
150
    return 0;
151
}
152

    
153
/**
154
 * Decode XOR'ed frame - 15bpp and 16bpp version
155
 */
156

    
157
static int zmbv_decode_xor_16(ZmbvContext *c)
158
{
159
    uint8_t *src = c->decomp_buf;
160
    uint16_t *output, *prev;
161
    int8_t *mvec;
162
    int x, y;
163
    int d, dx, dy, bw2, bh2;
164
    int block;
165
    int i, j;
166
    int mx, my;
167

    
168
    output = (uint16_t*)c->cur;
169
    prev = (uint16_t*)c->prev;
170

    
171
    mvec = (int8_t*)src;
172
    src += ((c->bx * c->by * 2 + 3) & ~3);
173

    
174
    block = 0;
175
    for(y = 0; y < c->height; y += c->bh) {
176
        bh2 = ((c->height - y) > c->bh) ? c->bh : (c->height - y);
177
        for(x = 0; x < c->width; x += c->bw) {
178
            uint16_t *out, *tprev;
179

    
180
            d = mvec[block] & 1;
181
            dx = mvec[block] >> 1;
182
            dy = mvec[block + 1] >> 1;
183
            block += 2;
184

    
185
            bw2 = ((c->width - x) > c->bw) ? c->bw : (c->width - x);
186

    
187
            /* copy block - motion vectors out of bounds are used to zero blocks */
188
            out = output + x;
189
            tprev = prev + x + dx + dy * c->width;
190
            mx = x + dx;
191
            my = y + dy;
192
            for(j = 0; j < bh2; j++){
193
                if((my + j < 0) || (my + j >= c->height)) {
194
                    memset(out, 0, bw2 * 2);
195
                } else {
196
                    for(i = 0; i < bw2; i++){
197
                        if((mx + i < 0) || (mx + i >= c->width))
198
                            out[i] = 0;
199
                        else
200
                            out[i] = tprev[i];
201
                    }
202
                }
203
                out += c->width;
204
                tprev += c->width;
205
            }
206

    
207
            if(d) { /* apply XOR'ed difference */
208
                out = output + x;
209
                for(j = 0; j < bh2; j++){
210
                    for(i = 0; i < bw2; i++) {
211
                        out[i] ^= *((uint16_t*)src);
212
                        src += 2;
213
                    }
214
                    out += c->width;
215
                }
216
            }
217
        }
218
        output += c->width * c->bh;
219
        prev += c->width * c->bh;
220
    }
221
    if(src - c->decomp_buf != c->decomp_len)
222
        av_log(c->avctx, AV_LOG_ERROR, "Used %i of %i bytes\n", src-c->decomp_buf, c->decomp_len);
223
    return 0;
224
}
225

    
226
#ifdef ZMBV_ENABLE_24BPP
227
/**
228
 * Decode XOR'ed frame - 24bpp version
229
 */
230

    
231
static int zmbv_decode_xor_24(ZmbvContext *c)
232
{
233
    uint8_t *src = c->decomp_buf;
234
    uint8_t *output, *prev;
235
    int8_t *mvec;
236
    int x, y;
237
    int d, dx, dy, bw2, bh2;
238
    int block;
239
    int i, j;
240
    int mx, my;
241
    int stride;
242

    
243
    output = c->cur;
244
    prev = c->prev;
245

    
246
    stride = c->width * 3;
247
    mvec = (int8_t*)src;
248
    src += ((c->bx * c->by * 2 + 3) & ~3);
249

    
250
    block = 0;
251
    for(y = 0; y < c->height; y += c->bh) {
252
        bh2 = ((c->height - y) > c->bh) ? c->bh : (c->height - y);
253
        for(x = 0; x < c->width; x += c->bw) {
254
            uint8_t *out, *tprev;
255

    
256
            d = mvec[block] & 1;
257
            dx = mvec[block] >> 1;
258
            dy = mvec[block + 1] >> 1;
259
            block += 2;
260

    
261
            bw2 = ((c->width - x) > c->bw) ? c->bw : (c->width - x);
262

    
263
            /* copy block - motion vectors out of bounds are used to zero blocks */
264
            out = output + x * 3;
265
            tprev = prev + (x + dx) * 3 + dy * stride;
266
            mx = x + dx;
267
            my = y + dy;
268
            for(j = 0; j < bh2; j++){
269
                if((my + j < 0) || (my + j >= c->height)) {
270
                    memset(out, 0, bw2 * 3);
271
                } else {
272
                    for(i = 0; i < bw2; i++){
273
                        if((mx + i < 0) || (mx + i >= c->width)) {
274
                            out[i * 3 + 0] = 0;
275
                            out[i * 3 + 1] = 0;
276
                            out[i * 3 + 2] = 0;
277
                        } else {
278
                            out[i * 3 + 0] = tprev[i * 3 + 0];
279
                            out[i * 3 + 1] = tprev[i * 3 + 1];
280
                            out[i * 3 + 2] = tprev[i * 3 + 2];
281
                        }
282
                    }
283
                }
284
                out += stride;
285
                tprev += stride;
286
            }
287

    
288
            if(d) { /* apply XOR'ed difference */
289
                out = output + x * 3;
290
                for(j = 0; j < bh2; j++){
291
                    for(i = 0; i < bw2; i++) {
292
                        out[i * 3 + 0] ^= *src++;
293
                        out[i * 3 + 1] ^= *src++;
294
                        out[i * 3 + 2] ^= *src++;
295
                    }
296
                    out += stride;
297
                }
298
            }
299
        }
300
        output += stride * c->bh;
301
        prev += stride * c->bh;
302
    }
303
    if(src - c->decomp_buf != c->decomp_len)
304
        av_log(c->avctx, AV_LOG_ERROR, "Used %i of %i bytes\n", src-c->decomp_buf, c->decomp_len);
305
    return 0;
306
}
307
#endif //ZMBV_ENABLE_24BPP
308

    
309
/**
310
 * Decode XOR'ed frame - 32bpp version
311
 */
312

    
313
static int zmbv_decode_xor_32(ZmbvContext *c)
314
{
315
    uint8_t *src = c->decomp_buf;
316
    uint32_t *output, *prev;
317
    int8_t *mvec;
318
    int x, y;
319
    int d, dx, dy, bw2, bh2;
320
    int block;
321
    int i, j;
322
    int mx, my;
323

    
324
    output = (uint32_t*)c->cur;
325
    prev = (uint32_t*)c->prev;
326

    
327
    mvec = (int8_t*)src;
328
    src += ((c->bx * c->by * 2 + 3) & ~3);
329

    
330
    block = 0;
331
    for(y = 0; y < c->height; y += c->bh) {
332
        bh2 = ((c->height - y) > c->bh) ? c->bh : (c->height - y);
333
        for(x = 0; x < c->width; x += c->bw) {
334
            uint32_t *out, *tprev;
335

    
336
            d = mvec[block] & 1;
337
            dx = mvec[block] >> 1;
338
            dy = mvec[block + 1] >> 1;
339
            block += 2;
340

    
341
            bw2 = ((c->width - x) > c->bw) ? c->bw : (c->width - x);
342

    
343
            /* copy block - motion vectors out of bounds are used to zero blocks */
344
            out = output + x;
345
            tprev = prev + x + dx + dy * c->width;
346
            mx = x + dx;
347
            my = y + dy;
348
            for(j = 0; j < bh2; j++){
349
                if((my + j < 0) || (my + j >= c->height)) {
350
                    memset(out, 0, bw2 * 4);
351
                } else {
352
                    for(i = 0; i < bw2; i++){
353
                        if((mx + i < 0) || (mx + i >= c->width))
354
                            out[i] = 0;
355
                        else
356
                            out[i] = tprev[i];
357
                    }
358
                }
359
                out += c->width;
360
                tprev += c->width;
361
            }
362

    
363
            if(d) { /* apply XOR'ed difference */
364
                out = output + x;
365
                for(j = 0; j < bh2; j++){
366
                    for(i = 0; i < bw2; i++) {
367
                        out[i] ^= *((uint32_t*)src);
368
                        src += 4;
369
                    }
370
                    out += c->width;
371
                }
372
            }
373
        }
374
        output += c->width * c->bh;
375
        prev += c->width * c->bh;
376
    }
377
    if(src - c->decomp_buf != c->decomp_len)
378
        av_log(c->avctx, AV_LOG_ERROR, "Used %i of %i bytes\n", src-c->decomp_buf, c->decomp_len);
379
    return 0;
380
}
381

    
382
/**
383
 * Decode intraframe
384
 */
385
static int zmbv_decode_intra(ZmbvContext *c)
386
{
387
    uint8_t *src = c->decomp_buf;
388

    
389
    /* make the palette available on the way out */
390
    if (c->fmt == ZMBV_FMT_8BPP) {
391
        memcpy(c->pal, src, 768);
392
        src += 768;
393
    }
394

    
395
    memcpy(c->cur, src, c->width * c->height * (c->bpp / 8));
396
    return 0;
397
}
398

    
399
static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8_t *buf, int buf_size)
400
{
401
    ZmbvContext * const c = avctx->priv_data;
402
    uint8_t *outptr;
403
#ifdef CONFIG_ZLIB
404
    int zret = Z_OK; // Zlib return code
405
#endif
406
    int len = buf_size;
407
    int hi_ver, lo_ver;
408

    
409
    if(c->pic.data[0])
410
            avctx->release_buffer(avctx, &c->pic);
411

    
412
    c->pic.reference = 1;
413
    c->pic.buffer_hints = FF_BUFFER_HINTS_VALID;
414
    if(avctx->get_buffer(avctx, &c->pic) < 0){
415
        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
416
        return -1;
417
    }
418

    
419
    outptr = c->pic.data[0]; // Output image pointer
420

    
421
    /* parse header */
422
    c->flags = buf[0];
423
    buf++; len--;
424
    if(c->flags & ZMBV_KEYFRAME) {
425
        hi_ver = buf[0];
426
        lo_ver = buf[1];
427
        c->comp = buf[2];
428
        c->fmt = buf[3];
429
        c->bw = buf[4];
430
        c->bh = buf[5];
431

    
432
        buf += 6;
433
        len -= 6;
434
        av_log(avctx, AV_LOG_DEBUG, "Flags=%X ver=%i.%i comp=%i fmt=%i blk=%ix%i\n",c->flags,hi_ver,lo_ver,c->comp,c->fmt,c->bw,c->bh);
435
        if(hi_ver != 0 || lo_ver != 1) {
436
            av_log(avctx, AV_LOG_ERROR, "Unsupported version %i.%i\n", hi_ver, lo_ver);
437
            return -1;
438
        }
439
        if(c->bw == 0 || c->bh == 0) {
440
            av_log(avctx, AV_LOG_ERROR, "Unsupported block size %ix%i\n", c->bw, c->bh);
441
        }
442
        if(c->comp != 0 && c->comp != 1) {
443
            av_log(avctx, AV_LOG_ERROR, "Unsupported compression type %i\n", c->comp);
444
            return -1;
445
        }
446

    
447
        switch(c->fmt) {
448
        case ZMBV_FMT_8BPP:
449
            c->bpp = 8;
450
            c->decode_intra = zmbv_decode_intra;
451
            c->decode_xor = zmbv_decode_xor_8;
452
            break;
453
        case ZMBV_FMT_15BPP:
454
        case ZMBV_FMT_16BPP:
455
            c->bpp = 16;
456
            c->decode_intra = zmbv_decode_intra;
457
            c->decode_xor = zmbv_decode_xor_16;
458
            break;
459
#ifdef ZMBV_ENABLE_24BPP
460
        case ZMBV_FMT_24BPP:
461
            c->bpp = 24;
462
            c->decode_intra = zmbv_decode_intra;
463
            c->decode_xor = zmbv_decode_xor_24;
464
            break;
465
#endif //ZMBV_ENABLE_24BPP
466
        case ZMBV_FMT_32BPP:
467
            c->bpp = 32;
468
            c->decode_intra = zmbv_decode_intra;
469
            c->decode_xor = zmbv_decode_xor_32;
470
            break;
471
        default:
472
            c->decode_intra = NULL;
473
            c->decode_xor = NULL;
474
            av_log(avctx, AV_LOG_ERROR, "Unsupported (for now) format %i\n", c->fmt);
475
            return -1;
476
        }
477
#ifdef CONFIG_ZLIB
478
        zret = inflateReset(&c->zstream);
479
        if (zret != Z_OK) {
480
            av_log(avctx, AV_LOG_ERROR, "Inflate reset error: %d\n", zret);
481
            return -1;
482
        }
483
#else
484
        av_log(avctx, AV_LOG_ERROR, "BUG! Zlib support not compiled in frame decoder.\n");
485
        return -1;
486
#endif  /* CONFIG_ZLIB */
487
        c->cur = av_realloc(c->cur, avctx->width * avctx->height * (c->bpp / 8));
488
        c->prev = av_realloc(c->prev, avctx->width * avctx->height * (c->bpp / 8));
489
        c->bx = (c->width + c->bw - 1) / c->bw;
490
        c->by = (c->height+ c->bh - 1) / c->bh;
491
    }
492

    
493
    if(c->decode_intra == NULL) {
494
        av_log(avctx, AV_LOG_ERROR, "Error! Got no format or no keyframe!\n");
495
        return -1;
496
    }
497

    
498
    if(c->comp == 0) { //Uncompressed data
499
        memcpy(c->decomp_buf, buf, len);
500
        c->decomp_size = 1;
501
    } else { // ZLIB-compressed data
502
#ifdef CONFIG_ZLIB
503
        c->zstream.total_in = c->zstream.total_out = 0;
504
        c->zstream.next_in = buf;
505
        c->zstream.avail_in = len;
506
        c->zstream.next_out = c->decomp_buf;
507
        c->zstream.avail_out = c->decomp_size;
508
        inflate(&c->zstream, Z_FINISH);
509
        c->decomp_len = c->zstream.total_out;
510
#else
511
        av_log(avctx, AV_LOG_ERROR, "BUG! Zlib support not compiled in frame decoder.\n");
512
        return -1;
513
#endif
514
    }
515
    if(c->flags & ZMBV_KEYFRAME) {
516
        c->pic.key_frame = 1;
517
        c->pic.pict_type = FF_I_TYPE;
518
        c->decode_intra(c);
519
    } else {
520
        c->pic.key_frame = 0;
521
        c->pic.pict_type = FF_P_TYPE;
522
        c->decode_xor(c);
523
    }
524

    
525
    /* update frames */
526
    {
527
        uint8_t *out, *src;
528
        int i, j;
529

    
530
        out = c->pic.data[0];
531
        src = c->cur;
532
        switch(c->fmt) {
533
        case ZMBV_FMT_8BPP:
534
            for(j = 0; j < c->height; j++) {
535
                for(i = 0; i < c->width; i++) {
536
                    out[i * 3 + 0] = c->pal[(*src) * 3 + 0];
537
                    out[i * 3 + 1] = c->pal[(*src) * 3 + 1];
538
                    out[i * 3 + 2] = c->pal[(*src) * 3 + 2];
539
                    *src++;
540
                }
541
                out += c->pic.linesize[0];
542
            }
543
            break;
544
        case ZMBV_FMT_15BPP:
545
            for(j = 0; j < c->height; j++) {
546
                for(i = 0; i < c->width; i++) {
547
                    uint16_t tmp = AV_RL16(src);
548
                    src += 2;
549
                    out[i * 3 + 0] = (tmp & 0x7C00) >> 7;
550
                    out[i * 3 + 1] = (tmp & 0x03E0) >> 2;
551
                    out[i * 3 + 2] = (tmp & 0x001F) << 3;
552
                }
553
                out += c->pic.linesize[0];
554
            }
555
            break;
556
        case ZMBV_FMT_16BPP:
557
            for(j = 0; j < c->height; j++) {
558
                for(i = 0; i < c->width; i++) {
559
                    uint16_t tmp = AV_RL16(src);
560
                    src += 2;
561
                    out[i * 3 + 0] = (tmp & 0xF800) >> 8;
562
                    out[i * 3 + 1] = (tmp & 0x07E0) >> 3;
563
                    out[i * 3 + 2] = (tmp & 0x001F) << 3;
564
                }
565
                out += c->pic.linesize[0];
566
            }
567
            break;
568
#ifdef ZMBV_ENABLE_24BPP
569
        case ZMBV_FMT_24BPP:
570
            for(j = 0; j < c->height; j++) {
571
                memcpy(out, src, c->width * 3);
572
                src += c->width * 3;
573
                out += c->pic.linesize[0];
574
            }
575
            break;
576
#endif //ZMBV_ENABLE_24BPP
577
        case ZMBV_FMT_32BPP:
578
            for(j = 0; j < c->height; j++) {
579
                for(i = 0; i < c->width; i++) {
580
                    uint32_t tmp = AV_RL32(src);
581
                    src += 4;
582
                    out[i * 3 + 0] = tmp >> 16;
583
                    out[i * 3 + 1] = tmp >> 8;
584
                    out[i * 3 + 2] = tmp >> 0;
585
                }
586
                out += c->pic.linesize[0];
587
            }
588
            break;
589
        default:
590
            av_log(avctx, AV_LOG_ERROR, "Cannot handle format %i\n", c->fmt);
591
        }
592
        memcpy(c->prev, c->cur, c->width * c->height * (c->bpp / 8));
593
    }
594
    *data_size = sizeof(AVFrame);
595
    *(AVFrame*)data = c->pic;
596

    
597
    /* always report that the buffer was completely consumed */
598
    return buf_size;
599
}
600

    
601

    
602

    
603
/*
604
 *
605
 * Init zmbv decoder
606
 *
607
 */
608
static int decode_init(AVCodecContext *avctx)
609
{
610
    ZmbvContext * const c = avctx->priv_data;
611
    int zret; // Zlib return code
612

    
613
    c->avctx = avctx;
614

    
615
    c->pic.data[0] = NULL;
616
    c->width = avctx->width;
617
    c->height = avctx->height;
618

    
619
    if (avcodec_check_dimensions(avctx, avctx->width, avctx->height) < 0) {
620
        return 1;
621
    }
622
    c->bpp = avctx->bits_per_sample;
623

    
624
#ifdef CONFIG_ZLIB
625
    // Needed if zlib unused or init aborted before inflateInit
626
    memset(&(c->zstream), 0, sizeof(z_stream));
627
#else
628
    av_log(avctx, AV_LOG_ERROR, "Zlib support not compiled.\n");
629
    return 1;
630
#endif
631
    avctx->pix_fmt = PIX_FMT_RGB24;
632
    c->decomp_size = (avctx->width + 255) * 4 * (avctx->height + 64);
633

    
634
    /* Allocate decompression buffer */
635
    if (c->decomp_size) {
636
        if ((c->decomp_buf = av_malloc(c->decomp_size)) == NULL) {
637
            av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n");
638
            return 1;
639
        }
640
    }
641

    
642
#ifdef CONFIG_ZLIB
643
    c->zstream.zalloc = Z_NULL;
644
    c->zstream.zfree = Z_NULL;
645
    c->zstream.opaque = Z_NULL;
646
    zret = inflateInit(&(c->zstream));
647
    if (zret != Z_OK) {
648
        av_log(avctx, AV_LOG_ERROR, "Inflate init error: %d\n", zret);
649
        return 1;
650
    }
651
#endif
652

    
653
    return 0;
654
}
655

    
656

    
657

    
658
/*
659
 *
660
 * Uninit zmbv decoder
661
 *
662
 */
663
static int decode_end(AVCodecContext *avctx)
664
{
665
    ZmbvContext * const c = avctx->priv_data;
666

    
667
    av_freep(&c->decomp_buf);
668

    
669
    if (c->pic.data[0])
670
        avctx->release_buffer(avctx, &c->pic);
671
#ifdef CONFIG_ZLIB
672
    inflateEnd(&(c->zstream));
673
#endif
674
    av_freep(&c->cur);
675
    av_freep(&c->prev);
676

    
677
    return 0;
678
}
679

    
680
AVCodec zmbv_decoder = {
681
    "zmbv",
682
    CODEC_TYPE_VIDEO,
683
    CODEC_ID_ZMBV,
684
    sizeof(ZmbvContext),
685
    decode_init,
686
    NULL,
687
    decode_end,
688
    decode_frame
689
};
690