Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4349 Serge 1
/*
2
 * Flash Screen Video decoder
3
 * Copyright (C) 2004 Alex Beregszaszi
4
 * Copyright (C) 2006 Benjamin Larsson
5
 *
6
 * This file is part of FFmpeg.
7
 *
8
 * FFmpeg is free software; you can redistribute it and/or
9
 * modify it under the terms of the GNU Lesser General Public
10
 * License as published by the Free Software Foundation; either
11
 * version 2.1 of the License, or (at your option) any later version.
12
 *
13
 * FFmpeg is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
 * Lesser General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public
19
 * License along with FFmpeg; if not, write to the Free Software
20
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21
 */
22
 
23
/**
24
 * @file
25
 * Flash Screen Video decoder
26
 * @author Alex Beregszaszi
27
 * @author Benjamin Larsson
28
 * @author Daniel Verkamp
29
 * @author Konstantin Shishkov
30
 *
31
 * A description of the bitstream format for Flash Screen Video version 1/2
32
 * is part of the SWF File Format Specification (version 10), which can be
33
 * downloaded from http://www.adobe.com/devnet/swf.html.
34
 */
35
 
36
#include 
37
#include 
38
#include 
39
 
40
#include "libavutil/intreadwrite.h"
41
#include "avcodec.h"
42
#include "bytestream.h"
43
#include "get_bits.h"
44
#include "internal.h"
45
 
46
typedef struct BlockInfo {
47
    uint8_t *pos;
48
    int      size;
49
} BlockInfo;
50
 
51
typedef struct FlashSVContext {
52
    AVCodecContext *avctx;
53
    AVFrame         frame;
54
    int             image_width, image_height;
55
    int             block_width, block_height;
56
    uint8_t        *tmpblock;
57
    int             block_size;
58
    z_stream        zstream;
59
    int             ver;
60
    const uint32_t *pal;
61
    int             is_keyframe;
62
    uint8_t        *keyframedata;
63
    uint8_t        *keyframe;
64
    BlockInfo      *blocks;
65
    uint8_t        *deflate_block;
66
    int             deflate_block_size;
67
    int             color_depth;
68
    int             zlibprime_curr, zlibprime_prev;
69
    int             diff_start, diff_height;
70
} FlashSVContext;
71
 
72
 
73
static int decode_hybrid(const uint8_t *sptr, uint8_t *dptr, int dx, int dy,
74
                         int h, int w, int stride, const uint32_t *pal)
75
{
76
    int x, y;
77
    const uint8_t *orig_src = sptr;
78
 
79
    for (y = dx+h; y > dx; y--) {
80
        uint8_t *dst = dptr + (y * stride) + dy * 3;
81
        for (x = 0; x < w; x++) {
82
            if (*sptr & 0x80) {
83
                /* 15-bit color */
84
                unsigned c = AV_RB16(sptr) & ~0x8000;
85
                unsigned b =  c        & 0x1F;
86
                unsigned g = (c >>  5) & 0x1F;
87
                unsigned r =  c >> 10;
88
                /* 000aaabb -> aaabbaaa  */
89
                *dst++ = (b << 3) | (b >> 2);
90
                *dst++ = (g << 3) | (g >> 2);
91
                *dst++ = (r << 3) | (r >> 2);
92
                sptr += 2;
93
            } else {
94
                /* palette index */
95
                uint32_t c = pal[*sptr++];
96
                bytestream_put_le24(&dst, c);
97
            }
98
        }
99
    }
100
    return sptr - orig_src;
101
}
102
 
103
static av_cold int flashsv_decode_init(AVCodecContext *avctx)
104
{
105
    FlashSVContext *s = avctx->priv_data;
106
    int zret; // Zlib return code
107
 
108
    s->avctx          = avctx;
109
    s->zstream.zalloc = Z_NULL;
110
    s->zstream.zfree  = Z_NULL;
111
    s->zstream.opaque = Z_NULL;
112
    zret = inflateInit(&s->zstream);
113
    if (zret != Z_OK) {
114
        av_log(avctx, AV_LOG_ERROR, "Inflate init error: %d\n", zret);
115
        return 1;
116
    }
117
    avctx->pix_fmt = AV_PIX_FMT_BGR24;
118
    avcodec_get_frame_defaults(&s->frame);
119
 
120
    return 0;
121
}
122
 
123
 
124
static int flashsv2_prime(FlashSVContext *s, uint8_t *src, int size)
125
{
126
    z_stream zs;
127
    int zret; // Zlib return code
128
 
129
    if (!src)
130
        return AVERROR_INVALIDDATA;
131
 
132
    zs.zalloc = NULL;
133
    zs.zfree  = NULL;
134
    zs.opaque = NULL;
135
 
136
    s->zstream.next_in   = src;
137
    s->zstream.avail_in  = size;
138
    s->zstream.next_out  = s->tmpblock;
139
    s->zstream.avail_out = s->block_size * 3;
140
    inflate(&s->zstream, Z_SYNC_FLUSH);
141
 
142
    if (deflateInit(&zs, 0) != Z_OK)
143
        return -1;
144
    zs.next_in   = s->tmpblock;
145
    zs.avail_in  = s->block_size * 3 - s->zstream.avail_out;
146
    zs.next_out  = s->deflate_block;
147
    zs.avail_out = s->deflate_block_size;
148
    deflate(&zs, Z_SYNC_FLUSH);
149
    deflateEnd(&zs);
150
 
151
    if ((zret = inflateReset(&s->zstream)) != Z_OK) {
152
        av_log(s->avctx, AV_LOG_ERROR, "Inflate reset error: %d\n", zret);
153
        return AVERROR_UNKNOWN;
154
    }
155
 
156
    s->zstream.next_in   = s->deflate_block;
157
    s->zstream.avail_in  = s->deflate_block_size - zs.avail_out;
158
    s->zstream.next_out  = s->tmpblock;
159
    s->zstream.avail_out = s->block_size * 3;
160
    inflate(&s->zstream, Z_SYNC_FLUSH);
161
 
162
    return 0;
163
}
164
 
165
static int flashsv_decode_block(AVCodecContext *avctx, AVPacket *avpkt,
166
                                GetBitContext *gb, int block_size,
167
                                int width, int height, int x_pos, int y_pos,
168
                                int blk_idx)
169
{
170
    struct FlashSVContext *s = avctx->priv_data;
171
    uint8_t *line = s->tmpblock;
172
    int k;
173
    int ret = inflateReset(&s->zstream);
174
    if (ret != Z_OK) {
175
        av_log(avctx, AV_LOG_ERROR, "Inflate reset error: %d\n", ret);
176
        return AVERROR_UNKNOWN;
177
    }
178
    if (s->zlibprime_curr || s->zlibprime_prev) {
179
        ret = flashsv2_prime(s,
180
                             s->blocks[blk_idx].pos,
181
                             s->blocks[blk_idx].size);
182
        if (ret < 0)
183
            return ret;
184
    }
185
    s->zstream.next_in   = avpkt->data + get_bits_count(gb) / 8;
186
    s->zstream.avail_in  = block_size;
187
    s->zstream.next_out  = s->tmpblock;
188
    s->zstream.avail_out = s->block_size * 3;
189
    ret = inflate(&s->zstream, Z_FINISH);
190
    if (ret == Z_DATA_ERROR) {
191
        av_log(avctx, AV_LOG_ERROR, "Zlib resync occurred\n");
192
        inflateSync(&s->zstream);
193
        ret = inflate(&s->zstream, Z_FINISH);
194
    }
195
 
196
    if (ret != Z_OK && ret != Z_STREAM_END) {
197
        //return -1;
198
    }
199
 
200
    if (s->is_keyframe) {
201
        s->blocks[blk_idx].pos      = s->keyframedata + (get_bits_count(gb) / 8);
202
        s->blocks[blk_idx].size     = block_size;
203
    }
204
    if (!s->color_depth) {
205
        /* Flash Screen Video stores the image upside down, so copy
206
         * lines to destination in reverse order. */
207
        for (k = 1; k <= s->diff_height; k++) {
208
            memcpy(s->frame.data[0] + x_pos * 3 +
209
                   (s->image_height - y_pos - s->diff_start - k) * s->frame.linesize[0],
210
                   line, width * 3);
211
            /* advance source pointer to next line */
212
            line += width * 3;
213
        }
214
    } else {
215
        /* hybrid 15-bit/palette mode */
216
        decode_hybrid(s->tmpblock, s->frame.data[0],
217
                      s->image_height - (y_pos + 1 + s->diff_start + s->diff_height),
218
                      x_pos, s->diff_height, width,
219
                      s->frame.linesize[0], s->pal);
220
    }
221
    skip_bits_long(gb, 8 * block_size); /* skip the consumed bits */
222
    return 0;
223
}
224
 
225
static int calc_deflate_block_size(int tmpblock_size)
226
{
227
    z_stream zstream;
228
    int size;
229
 
230
    zstream.zalloc = Z_NULL;
231
    zstream.zfree  = Z_NULL;
232
    zstream.opaque = Z_NULL;
233
    if (deflateInit(&zstream, 0) != Z_OK)
234
        return -1;
235
    size = deflateBound(&zstream, tmpblock_size);
236
    deflateEnd(&zstream);
237
 
238
    return size;
239
}
240
 
241
static int flashsv_decode_frame(AVCodecContext *avctx, void *data,
242
                                int *got_frame, AVPacket *avpkt)
243
{
244
    int buf_size       = avpkt->size;
245
    FlashSVContext *s  = avctx->priv_data;
246
    int h_blocks, v_blocks, h_part, v_part, i, j, ret;
247
    GetBitContext gb;
248
    int last_blockwidth = s->block_width;
249
    int last_blockheight= s->block_height;
250
 
251
    /* no supplementary picture */
252
    if (buf_size == 0)
253
        return 0;
254
    if (buf_size < 4)
255
        return -1;
256
 
257
    init_get_bits(&gb, avpkt->data, buf_size * 8);
258
 
259
    /* start to parse the bitstream */
260
    s->block_width  = 16 * (get_bits(&gb,  4) + 1);
261
    s->image_width  =       get_bits(&gb, 12);
262
    s->block_height = 16 * (get_bits(&gb,  4) + 1);
263
    s->image_height =       get_bits(&gb, 12);
264
 
265
    if (   last_blockwidth != s->block_width
266
        || last_blockheight!= s->block_height)
267
        av_freep(&s->blocks);
268
 
269
    if (s->ver == 2) {
270
        skip_bits(&gb, 6);
271
        if (get_bits1(&gb)) {
272
            avpriv_request_sample(avctx, "iframe");
273
            return AVERROR_PATCHWELCOME;
274
        }
275
        if (get_bits1(&gb)) {
276
            avpriv_request_sample(avctx, "Custom palette");
277
            return AVERROR_PATCHWELCOME;
278
        }
279
    }
280
 
281
    /* calculate number of blocks and size of border (partial) blocks */
282
    h_blocks = s->image_width  / s->block_width;
283
    h_part   = s->image_width  % s->block_width;
284
    v_blocks = s->image_height / s->block_height;
285
    v_part   = s->image_height % s->block_height;
286
 
287
    /* the block size could change between frames, make sure the buffer
288
     * is large enough, if not, get a larger one */
289
    if (s->block_size < s->block_width * s->block_height) {
290
        int tmpblock_size = 3 * s->block_width * s->block_height;
291
 
292
        s->tmpblock = av_realloc(s->tmpblock, tmpblock_size);
293
        if (!s->tmpblock) {
294
            av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n");
295
            return AVERROR(ENOMEM);
296
        }
297
        if (s->ver == 2) {
298
            s->deflate_block_size = calc_deflate_block_size(tmpblock_size);
299
            if (s->deflate_block_size <= 0) {
300
                av_log(avctx, AV_LOG_ERROR, "Can't determine deflate buffer size.\n");
301
                return -1;
302
            }
303
            s->deflate_block = av_realloc(s->deflate_block, s->deflate_block_size);
304
            if (!s->deflate_block) {
305
                av_log(avctx, AV_LOG_ERROR, "Can't allocate deflate buffer.\n");
306
                return AVERROR(ENOMEM);
307
            }
308
        }
309
    }
310
    s->block_size = s->block_width * s->block_height;
311
 
312
    /* initialize the image size once */
313
    if (avctx->width == 0 && avctx->height == 0) {
314
        avcodec_set_dimensions(avctx, s->image_width, s->image_height);
315
    }
316
 
317
    /* check for changes of image width and image height */
318
    if (avctx->width != s->image_width || avctx->height != s->image_height) {
319
        av_log(avctx, AV_LOG_ERROR,
320
               "Frame width or height differs from first frame!\n");
321
        av_log(avctx, AV_LOG_ERROR, "fh = %d, fv %d  vs  ch = %d, cv = %d\n",
322
               avctx->height, avctx->width, s->image_height, s->image_width);
323
        return AVERROR_INVALIDDATA;
324
    }
325
 
326
    /* we care for keyframes only in Screen Video v2 */
327
    s->is_keyframe = (avpkt->flags & AV_PKT_FLAG_KEY) && (s->ver == 2);
328
    if (s->is_keyframe) {
329
        s->keyframedata = av_realloc(s->keyframedata, avpkt->size);
330
        memcpy(s->keyframedata, avpkt->data, avpkt->size);
331
    }
332
    if(s->ver == 2 && !s->blocks)
333
        s->blocks = av_mallocz((v_blocks + !!v_part) * (h_blocks + !!h_part)
334
                                * sizeof(s->blocks[0]));
335
 
336
    av_dlog(avctx, "image: %dx%d block: %dx%d num: %dx%d part: %dx%d\n",
337
            s->image_width, s->image_height, s->block_width, s->block_height,
338
            h_blocks, v_blocks, h_part, v_part);
339
 
340
    if ((ret = ff_reget_buffer(avctx, &s->frame)) < 0)
341
        return ret;
342
 
343
    /* loop over all block columns */
344
    for (j = 0; j < v_blocks + (v_part ? 1 : 0); j++) {
345
 
346
        int y_pos  = j * s->block_height; // vertical position in frame
347
        int cur_blk_height = (j < v_blocks) ? s->block_height : v_part;
348
 
349
        /* loop over all block rows */
350
        for (i = 0; i < h_blocks + (h_part ? 1 : 0); i++) {
351
            int x_pos = i * s->block_width; // horizontal position in frame
352
            int cur_blk_width = (i < h_blocks) ? s->block_width : h_part;
353
            int has_diff = 0;
354
 
355
            /* get the size of the compressed zlib chunk */
356
            int size = get_bits(&gb, 16);
357
 
358
            s->color_depth    = 0;
359
            s->zlibprime_curr = 0;
360
            s->zlibprime_prev = 0;
361
            s->diff_start     = 0;
362
            s->diff_height    = cur_blk_height;
363
 
364
            if (8 * size > get_bits_left(&gb)) {
365
                av_frame_unref(&s->frame);
366
                return AVERROR_INVALIDDATA;
367
            }
368
 
369
            if (s->ver == 2 && size) {
370
                skip_bits(&gb, 3);
371
                s->color_depth    = get_bits(&gb, 2);
372
                has_diff          = get_bits1(&gb);
373
                s->zlibprime_curr = get_bits1(&gb);
374
                s->zlibprime_prev = get_bits1(&gb);
375
 
376
                if (s->color_depth != 0 && s->color_depth != 2) {
377
                    av_log(avctx, AV_LOG_ERROR,
378
                           "%dx%d invalid color depth %d\n", i, j, s->color_depth);
379
                    return AVERROR_INVALIDDATA;
380
                }
381
 
382
                if (has_diff) {
383
                    if (!s->keyframe) {
384
                        av_log(avctx, AV_LOG_ERROR,
385
                               "inter frame without keyframe\n");
386
                        return AVERROR_INVALIDDATA;
387
                    }
388
                    s->diff_start  = get_bits(&gb, 8);
389
                    s->diff_height = get_bits(&gb, 8);
390
                    if (s->diff_start + s->diff_height > cur_blk_height) {
391
                        av_log(avctx, AV_LOG_ERROR, "Block parameters invalid\n");
392
                        return AVERROR_INVALIDDATA;
393
                    }
394
                    av_log(avctx, AV_LOG_DEBUG,
395
                           "%dx%d diff start %d height %d\n",
396
                           i, j, s->diff_start, s->diff_height);
397
                    size -= 2;
398
                }
399
 
400
                if (s->zlibprime_prev)
401
                    av_log(avctx, AV_LOG_DEBUG, "%dx%d zlibprime_prev\n", i, j);
402
 
403
                if (s->zlibprime_curr) {
404
                    int col = get_bits(&gb, 8);
405
                    int row = get_bits(&gb, 8);
406
                    av_log(avctx, AV_LOG_DEBUG, "%dx%d zlibprime_curr %dx%d\n", i, j, col, row);
407
                    size -= 2;
408
                    avpriv_request_sample(avctx, "zlibprime_curr");
409
                    return AVERROR_PATCHWELCOME;
410
                }
411
                if (!s->blocks && (s->zlibprime_curr || s->zlibprime_prev)) {
412
                    av_log(avctx, AV_LOG_ERROR, "no data available for zlib "
413
                           "priming\n");
414
                    return AVERROR_INVALIDDATA;
415
                }
416
                size--; // account for flags byte
417
            }
418
 
419
            if (has_diff) {
420
                int k;
421
                int off = (s->image_height - y_pos - 1) * s->frame.linesize[0];
422
 
423
                for (k = 0; k < cur_blk_height; k++)
424
                    memcpy(s->frame.data[0] + off - k*s->frame.linesize[0] + x_pos*3,
425
                           s->keyframe + off - k*s->frame.linesize[0] + x_pos*3,
426
                           cur_blk_width * 3);
427
            }
428
 
429
            /* skip unchanged blocks, which have size 0 */
430
            if (size) {
431
                if (flashsv_decode_block(avctx, avpkt, &gb, size,
432
                                         cur_blk_width, cur_blk_height,
433
                                         x_pos, y_pos,
434
                                         i + j * (h_blocks + !!h_part)))
435
                    av_log(avctx, AV_LOG_ERROR,
436
                           "error in decompression of block %dx%d\n", i, j);
437
            }
438
        }
439
    }
440
    if (s->is_keyframe && s->ver == 2) {
441
        if (!s->keyframe) {
442
            s->keyframe = av_malloc(s->frame.linesize[0] * avctx->height);
443
            if (!s->keyframe) {
444
                av_log(avctx, AV_LOG_ERROR, "Cannot allocate image data\n");
445
                return AVERROR(ENOMEM);
446
            }
447
        }
448
        memcpy(s->keyframe, s->frame.data[0], s->frame.linesize[0] * avctx->height);
449
    }
450
 
451
    if ((ret = av_frame_ref(data, &s->frame)) < 0)
452
        return ret;
453
 
454
    *got_frame = 1;
455
 
456
    if ((get_bits_count(&gb) / 8) != buf_size)
457
        av_log(avctx, AV_LOG_ERROR, "buffer not fully consumed (%d != %d)\n",
458
               buf_size, (get_bits_count(&gb) / 8));
459
 
460
    /* report that the buffer was completely consumed */
461
    return buf_size;
462
}
463
 
464
 
465
static av_cold int flashsv_decode_end(AVCodecContext *avctx)
466
{
467
    FlashSVContext *s = avctx->priv_data;
468
    inflateEnd(&s->zstream);
469
    /* release the frame if needed */
470
    av_frame_unref(&s->frame);
471
 
472
    /* free the tmpblock */
473
    av_free(s->tmpblock);
474
 
475
    return 0;
476
}
477
 
478
 
479
#if CONFIG_FLASHSV_DECODER
480
AVCodec ff_flashsv_decoder = {
481
    .name           = "flashsv",
482
    .long_name      = NULL_IF_CONFIG_SMALL("Flash Screen Video v1"),
483
    .type           = AVMEDIA_TYPE_VIDEO,
484
    .id             = AV_CODEC_ID_FLASHSV,
485
    .priv_data_size = sizeof(FlashSVContext),
486
    .init           = flashsv_decode_init,
487
    .close          = flashsv_decode_end,
488
    .decode         = flashsv_decode_frame,
489
    .capabilities   = CODEC_CAP_DR1,
490
    .pix_fmts       = (const enum AVPixelFormat[]){ AV_PIX_FMT_BGR24, AV_PIX_FMT_NONE },
491
};
492
#endif /* CONFIG_FLASHSV_DECODER */
493
 
494
#if CONFIG_FLASHSV2_DECODER
495
static const uint32_t ff_flashsv2_default_palette[128] = {
496
    0x000000, 0x333333, 0x666666, 0x999999, 0xCCCCCC, 0xFFFFFF,
497
    0x330000, 0x660000, 0x990000, 0xCC0000, 0xFF0000, 0x003300,
498
    0x006600, 0x009900, 0x00CC00, 0x00FF00, 0x000033, 0x000066,
499
    0x000099, 0x0000CC, 0x0000FF, 0x333300, 0x666600, 0x999900,
500
    0xCCCC00, 0xFFFF00, 0x003333, 0x006666, 0x009999, 0x00CCCC,
501
    0x00FFFF, 0x330033, 0x660066, 0x990099, 0xCC00CC, 0xFF00FF,
502
    0xFFFF33, 0xFFFF66, 0xFFFF99, 0xFFFFCC, 0xFF33FF, 0xFF66FF,
503
    0xFF99FF, 0xFFCCFF, 0x33FFFF, 0x66FFFF, 0x99FFFF, 0xCCFFFF,
504
    0xCCCC33, 0xCCCC66, 0xCCCC99, 0xCCCCFF, 0xCC33CC, 0xCC66CC,
505
    0xCC99CC, 0xCCFFCC, 0x33CCCC, 0x66CCCC, 0x99CCCC, 0xFFCCCC,
506
    0x999933, 0x999966, 0x9999CC, 0x9999FF, 0x993399, 0x996699,
507
    0x99CC99, 0x99FF99, 0x339999, 0x669999, 0xCC9999, 0xFF9999,
508
    0x666633, 0x666699, 0x6666CC, 0x6666FF, 0x663366, 0x669966,
509
    0x66CC66, 0x66FF66, 0x336666, 0x996666, 0xCC6666, 0xFF6666,
510
    0x333366, 0x333399, 0x3333CC, 0x3333FF, 0x336633, 0x339933,
511
    0x33CC33, 0x33FF33, 0x663333, 0x993333, 0xCC3333, 0xFF3333,
512
    0x003366, 0x336600, 0x660033, 0x006633, 0x330066, 0x663300,
513
    0x336699, 0x669933, 0x993366, 0x339966, 0x663399, 0x996633,
514
    0x6699CC, 0x99CC66, 0xCC6699, 0x66CC99, 0x9966CC, 0xCC9966,
515
    0x99CCFF, 0xCCFF99, 0xFF99CC, 0x99FFCC, 0xCC99FF, 0xFFCC99,
516
    0x111111, 0x222222, 0x444444, 0x555555, 0xAAAAAA, 0xBBBBBB,
517
    0xDDDDDD, 0xEEEEEE
518
};
519
 
520
static av_cold int flashsv2_decode_init(AVCodecContext *avctx)
521
{
522
    FlashSVContext *s = avctx->priv_data;
523
    flashsv_decode_init(avctx);
524
    s->pal = ff_flashsv2_default_palette;
525
    s->ver = 2;
526
 
527
    return 0;
528
}
529
 
530
static av_cold int flashsv2_decode_end(AVCodecContext *avctx)
531
{
532
    FlashSVContext *s = avctx->priv_data;
533
 
534
    av_freep(&s->keyframedata);
535
    av_freep(&s->blocks);
536
    av_freep(&s->keyframe);
537
    av_freep(&s->deflate_block);
538
    flashsv_decode_end(avctx);
539
 
540
    return 0;
541
}
542
 
543
AVCodec ff_flashsv2_decoder = {
544
    .name           = "flashsv2",
545
    .long_name      = NULL_IF_CONFIG_SMALL("Flash Screen Video v2"),
546
    .type           = AVMEDIA_TYPE_VIDEO,
547
    .id             = AV_CODEC_ID_FLASHSV2,
548
    .priv_data_size = sizeof(FlashSVContext),
549
    .init           = flashsv2_decode_init,
550
    .close          = flashsv2_decode_end,
551
    .decode         = flashsv_decode_frame,
552
    .capabilities   = CODEC_CAP_DR1,
553
    .pix_fmts       = (const enum AVPixelFormat[]){ AV_PIX_FMT_BGR24, AV_PIX_FMT_NONE },
554
};
555
#endif /* CONFIG_FLASHSV2_DECODER */