4 * Copyright (c) 2020 Paul B Mahol
6 * This file is part of FFmpeg.
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.
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.
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
26 #include "libavutil/mem.h"
27 #include "libavutil/thread.h"
30 #include "bytestream.h"
31 #include "codec_internal.h"
32 #include "copy_block.h"
37 #include "aandcttab.h"
39 #define CBP_VLC_BITS 9
41 typedef struct MV30Context
{
52 unsigned int mvectors_size
;
54 unsigned int coeffs_size
;
56 int16_t intraq_tab
[2][64];
57 int16_t interq_tab
[2][64];
63 static VLCElem cbp_tab
[1 << CBP_VLC_BITS
];
65 static const uint8_t luma_tab
[] = {
66 12, 12, 15, 19, 25, 34, 40, 48,
67 12, 12, 18, 22, 27, 44, 47, 46,
68 17, 18, 21, 26, 35, 46, 52, 47,
69 18, 20, 24, 28, 40, 61, 59, 51,
70 20, 24, 32, 43, 50, 72, 72, 63,
71 25, 31, 42, 48, 58, 72, 81, 75,
72 38, 46, 54, 61, 71, 84, 88, 85,
73 50, 61, 65, 68, 79, 78, 86, 91,
76 static const uint8_t chroma_tab
[] = {
77 12, 16, 24, 47, 99, 99, 99, 99,
78 16, 21, 26, 66, 99, 99, 99, 99,
79 24, 26, 56, 99, 99, 99, 99, 99,
80 47, 66, 99, 99, 99, 99, 99, 99,
81 99, 99, 99, 99, 99, 99, 99, 99,
82 99, 99, 99, 99, 99, 99, 99, 99,
83 99, 99, 99, 99, 99, 99, 99, 99,
84 99, 99, 99, 99, 99, 99, 99, 99,
87 static const uint8_t zigzag
[] = {
88 0, 1, 8, 9, 16, 2, 3, 10,
89 17, 24, 32, 25, 18, 11, 4, 5,
90 12, 19, 26, 33, 40, 48, 41, 34,
91 27, 20, 13, 6, 7, 14, 21, 28,
92 35, 42, 49, 56, 57, 50, 43, 36,
93 29, 22, 15, 23, 30, 37, 44, 51,
94 58, 59, 52, 45, 38, 31, 39, 46,
95 53, 60, 61, 54, 47, 55, 62, 63,
98 static void get_qtable(int16_t *table
, int quant
, const uint8_t *quant_tab
)
100 int factor
= quant
< 50 ? 5000 / FFMAX(quant
, 1) : 200 - FFMIN(quant
, 100) * 2;
102 for (int i
= 0; i
< 64; i
++) {
103 table
[i
] = av_clip((quant_tab
[i
] * factor
+ 0x32) / 100, 1, 0x7fff);
104 table
[i
] = ((int)ff_aanscales
[i
] * (int)table
[i
] + 0x800) >> 12;
108 static inline void idct_1d(unsigned *blk
, int step
)
110 const unsigned t0
= blk
[0 * step
] + blk
[4 * step
];
111 const unsigned t1
= blk
[0 * step
] - blk
[4 * step
];
112 const unsigned t2
= blk
[2 * step
] + blk
[6 * step
];
113 const unsigned t3
= ((int)((blk
[2 * step
] - blk
[6 * step
]) * 362U) >> 8) - t2
;
114 const unsigned t4
= t0
+ t2
;
115 const unsigned t5
= t0
- t2
;
116 const unsigned t6
= t1
+ t3
;
117 const unsigned t7
= t1
- t3
;
118 const unsigned t8
= blk
[5 * step
] + blk
[3 * step
];
119 const unsigned t9
= blk
[5 * step
] - blk
[3 * step
];
120 const unsigned tA
= blk
[1 * step
] + blk
[7 * step
];
121 const unsigned tB
= blk
[1 * step
] - blk
[7 * step
];
122 const unsigned tC
= t8
+ tA
;
123 const unsigned tD
= (int)((tB
+ t9
) * 473U) >> 8;
124 const unsigned tE
= (((int)(t9
* -669U) >> 8) - tC
) + tD
;
125 const unsigned tF
= ((int)((tA
- t8
) * 362U) >> 8) - tE
;
126 const unsigned t10
= (((int)(tB
* 277U) >> 8) - tD
) + tF
;
128 blk
[0 * step
] = t4
+ tC
;
129 blk
[1 * step
] = t6
+ tE
;
130 blk
[2 * step
] = t7
+ tF
;
131 blk
[3 * step
] = t5
- t10
;
132 blk
[4 * step
] = t5
+ t10
;
133 blk
[5 * step
] = t7
- tF
;
134 blk
[6 * step
] = t6
- tE
;
135 blk
[7 * step
] = t4
- tC
;
138 static void idct_put(uint8_t *dst
, int stride
, int *block
)
140 for (int i
= 0; i
< 8; i
++) {
141 if ((block
[0x08 + i
] |
147 block
[0x38 + i
]) == 0) {
148 block
[0x08 + i
] = block
[i
];
149 block
[0x10 + i
] = block
[i
];
150 block
[0x18 + i
] = block
[i
];
151 block
[0x20 + i
] = block
[i
];
152 block
[0x28 + i
] = block
[i
];
153 block
[0x30 + i
] = block
[i
];
154 block
[0x38 + i
] = block
[i
];
156 idct_1d(block
+ i
, 8);
160 for (int i
= 0; i
< 8; i
++) {
162 for (int j
= 0; j
< 8; j
++)
163 dst
[j
] = av_clip_uint8((block
[j
] >> 5) + 128);
169 static void idct_add(uint8_t *dst
, int stride
,
170 const uint8_t *src
, int in_linesize
, int *block
)
172 for (int i
= 0; i
< 8; i
++) {
173 if ((block
[0x08 + i
] |
179 block
[0x38 + i
]) == 0) {
180 block
[0x08 + i
] = block
[i
];
181 block
[0x10 + i
] = block
[i
];
182 block
[0x18 + i
] = block
[i
];
183 block
[0x20 + i
] = block
[i
];
184 block
[0x28 + i
] = block
[i
];
185 block
[0x30 + i
] = block
[i
];
186 block
[0x38 + i
] = block
[i
];
188 idct_1d(block
+ i
, 8);
192 for (int i
= 0; i
< 8; i
++) {
194 for (int j
= 0; j
< 8; j
++)
195 dst
[j
] = av_clip_uint8((block
[j
] >> 5) + src
[j
]);
202 static inline void idct2_1d(int *blk
, int step
)
204 const unsigned int t0
= blk
[0 * step
];
205 const unsigned int t1
= blk
[1 * step
];
206 const unsigned int t2
= (int)(t1
* 473U) >> 8;
207 const unsigned int t3
= t2
- t1
;
208 const unsigned int t4
= ((int)(t1
* 362U) >> 8) - t3
;
209 const unsigned int t5
= (((int)(t1
* 277U) >> 8) - t2
) + t4
;
211 blk
[0 * step
] = t1
+ t0
;
212 blk
[1 * step
] = t0
+ t3
;
213 blk
[2 * step
] = t4
+ t0
;
214 blk
[3 * step
] = t0
- t5
;
215 blk
[4 * step
] = t5
+ t0
;
216 blk
[5 * step
] = t0
- t4
;
217 blk
[6 * step
] = t0
- t3
;
218 blk
[7 * step
] = t0
- t1
;
221 static void idct2_put(uint8_t *dst
, int stride
, int *block
)
223 for (int i
= 0; i
< 2; i
++) {
224 if ((block
[0x08 + i
]) == 0) {
225 block
[0x08 + i
] = block
[i
];
226 block
[0x10 + i
] = block
[i
];
227 block
[0x18 + i
] = block
[i
];
228 block
[0x20 + i
] = block
[i
];
229 block
[0x28 + i
] = block
[i
];
230 block
[0x30 + i
] = block
[i
];
231 block
[0x38 + i
] = block
[i
];
233 idct2_1d(block
+ i
, 8);
237 for (int i
= 0; i
< 8; i
++) {
239 for (int j
= 0; j
< 8; j
++)
240 dst
[j
] = av_clip_uint8((block
[0] >> 5) + 128);
243 for (int j
= 0; j
< 8; j
++)
244 dst
[j
] = av_clip_uint8((block
[j
] >> 5) + 128);
251 static void idct2_add(uint8_t *dst
, int stride
,
252 const uint8_t *src
, int in_linesize
,
255 for (int i
= 0; i
< 2; i
++) {
256 if ((block
[0x08 + i
]) == 0) {
257 block
[0x08 + i
] = block
[i
];
258 block
[0x10 + i
] = block
[i
];
259 block
[0x18 + i
] = block
[i
];
260 block
[0x20 + i
] = block
[i
];
261 block
[0x28 + i
] = block
[i
];
262 block
[0x30 + i
] = block
[i
];
263 block
[0x38 + i
] = block
[i
];
265 idct2_1d(block
+ i
, 8);
269 for (int i
= 0; i
< 8; i
++) {
271 for (int j
= 0; j
< 8; j
++)
272 dst
[j
] = av_clip_uint8((block
[0] >> 5) + src
[j
]);
275 for (int j
= 0; j
< 8; j
++)
276 dst
[j
] = av_clip_uint8((block
[j
] >> 5) + src
[j
]);
284 static void update_inter_block(uint8_t *dst
, int stride
,
285 const uint8_t *src
, int in_linesize
,
288 for (int i
= 0; i
< 8; i
++) {
289 for (int j
= 0; j
< 8; j
++)
290 dst
[j
] = av_clip_uint8(block
+ src
[j
]);
296 static int decode_intra_block(AVCodecContext
*avctx
, int mode
,
297 GetByteContext
*gbyte
, int16_t *qtab
,
298 int *block
, int *pfill
,
299 uint8_t *dst
, int linesize
)
301 MV30Context
*s
= avctx
->priv_data
;
306 s
->bdsp
.fill_block_tab
[1](dst
, 128, linesize
, 8);
309 fill
= sign_extend(bytestream2_get_ne16(gbyte
), 16);
311 block
[0] = ((int)((unsigned)pfill
[0] * qtab
[0]) >> 5) + 128;
312 s
->bdsp
.fill_block_tab
[1](dst
, block
[0], linesize
, 8);
315 memset(block
, 0, sizeof(*block
) * 64);
316 fill
= sign_extend(bytestream2_get_ne16(gbyte
), 16);
318 block
[0] = (unsigned)pfill
[0] * qtab
[0];
319 block
[1] = sign_extend(bytestream2_get_ne16(gbyte
), 16) * qtab
[1];
320 block
[8] = sign_extend(bytestream2_get_ne16(gbyte
), 16) * qtab
[8];
321 block
[9] = sign_extend(bytestream2_get_ne16(gbyte
), 16) * qtab
[9];
322 idct2_put(dst
, linesize
, block
);
325 fill
= sign_extend(bytestream2_get_ne16(gbyte
), 16);
327 block
[0] = (unsigned)pfill
[0] * qtab
[0];
328 for (int i
= 1; i
< 64; i
++)
329 block
[zigzag
[i
]] = sign_extend(bytestream2_get_ne16(gbyte
), 16) * qtab
[zigzag
[i
]];
330 idct_put(dst
, linesize
, block
);
337 static int decode_inter_block(AVCodecContext
*avctx
, int mode
,
338 GetByteContext
*gbyte
, int16_t *qtab
,
339 int *block
, int *pfill
,
340 uint8_t *dst
, int linesize
,
341 const uint8_t *src
, int in_linesize
)
347 copy_block8(dst
, src
, linesize
, in_linesize
, 8);
350 fill
= sign_extend(bytestream2_get_ne16(gbyte
), 16);
352 block
[0] = (int)((unsigned)pfill
[0] * qtab
[0]) >> 5;
353 update_inter_block(dst
, linesize
, src
, in_linesize
, block
[0]);
356 memset(block
, 0, sizeof(*block
) * 64);
357 fill
= sign_extend(bytestream2_get_ne16(gbyte
), 16);
359 block
[0] = (unsigned)pfill
[0] * qtab
[0];
360 block
[1] = sign_extend(bytestream2_get_ne16(gbyte
), 16) * qtab
[1];
361 block
[8] = sign_extend(bytestream2_get_ne16(gbyte
), 16) * qtab
[8];
362 block
[9] = sign_extend(bytestream2_get_ne16(gbyte
), 16) * qtab
[9];
363 idct2_add(dst
, linesize
, src
, in_linesize
, block
);
366 fill
= sign_extend(bytestream2_get_ne16(gbyte
), 16);
368 block
[0] = (unsigned)pfill
[0] * qtab
[0];
369 for (int i
= 1; i
< 64; i
++)
370 block
[zigzag
[i
]] = sign_extend(bytestream2_get_ne16(gbyte
), 16) * qtab
[zigzag
[i
]];
371 idct_add(dst
, linesize
, src
, in_linesize
, block
);
378 static int decode_coeffs(GetBitContext
*gb
, int16_t *coeffs
, int nb_codes
)
380 memset(coeffs
, 0, nb_codes
* sizeof(*coeffs
));
382 for (int i
= 0; i
< nb_codes
;) {
383 int value
= get_vlc2(gb
, cbp_tab
, CBP_VLC_BITS
, 1);
386 int x
= get_bits(gb
, value
);
388 if (x
< (1 << value
) / 2) {
389 x
= (1 << (value
- 1)) + (x
& ((1 << value
) - 1 >> 1));
391 x
= -(1 << (value
- 1)) - (x
& ((1 << value
) - 1 >> 1));
395 int flag
= get_bits1(gb
);
397 i
+= get_bits(gb
, 3 + flag
* 3) + 1 + flag
* 8;
404 static int decode_intra(AVCodecContext
*avctx
, GetBitContext
*gb
, AVFrame
*frame
)
406 MV30Context
*s
= avctx
->priv_data
;
413 if (get_bits_left(gb
) < s
->mode_size
* 8)
414 return AVERROR_INVALIDDATA
;
416 skip_bits_long(gb
, s
->mode_size
* 8);
418 linesize
[0] = frame
->linesize
[0];
419 linesize
[1] = frame
->linesize
[0];
420 linesize
[2] = frame
->linesize
[0];
421 linesize
[3] = frame
->linesize
[0];
422 linesize
[4] = frame
->linesize
[1];
423 linesize
[5] = frame
->linesize
[2];
425 for (int y
= 0; y
< avctx
->height
; y
+= 16) {
426 GetByteContext gbyte
;
427 int pfill
[3][1] = { {0} };
428 int nb_codes
= get_bits(gb
, 16);
430 av_fast_padded_malloc(&s
->coeffs
, &s
->coeffs_size
, nb_codes
* sizeof(*s
->coeffs
));
432 return AVERROR(ENOMEM
);
433 ret
= decode_coeffs(gb
, s
->coeffs
, nb_codes
);
437 bytestream2_init(&gbyte
, (uint8_t *)s
->coeffs
, nb_codes
* sizeof(*s
->coeffs
));
439 for (int x
= 0; x
< avctx
->width
; x
+= 16) {
440 dst
[0] = frame
->data
[0] + linesize
[0] * y
+ x
;
441 dst
[1] = frame
->data
[0] + linesize
[0] * y
+ x
+ 8;
442 dst
[2] = frame
->data
[0] + linesize
[0] * (y
+ 8) + x
;
443 dst
[3] = frame
->data
[0] + linesize
[0] * (y
+ 8) + x
+ 8;
444 dst
[4] = frame
->data
[1] + linesize
[4] * (y
>> 1) + (x
>> 1);
445 dst
[5] = frame
->data
[2] + linesize
[5] * (y
>> 1) + (x
>> 1);
447 for (int b
= 0; b
< 6; b
++) {
448 int mode
= get_bits_le(&mgb
, 2);
450 ret
= decode_intra_block(avctx
, mode
, &gbyte
, s
->intraq_tab
[b
>= 4],
452 pfill
[(b
>= 4) + (b
>= 5)],
453 dst
[b
], linesize
[b
]);
463 static int decode_inter(AVCodecContext
*avctx
, GetBitContext
*gb
,
464 AVFrame
*frame
, AVFrame
*prev
)
466 MV30Context
*s
= avctx
->priv_data
;
470 const int mask_size
= ((avctx
->height
>> 4) * (avctx
->width
>> 4) * 2 + 7) / 8;
471 uint8_t *dst
[6], *src
[6];
477 in_linesize
[0] = prev
->linesize
[0];
478 in_linesize
[1] = prev
->linesize
[0];
479 in_linesize
[2] = prev
->linesize
[0];
480 in_linesize
[3] = prev
->linesize
[0];
481 in_linesize
[4] = prev
->linesize
[1];
482 in_linesize
[5] = prev
->linesize
[2];
484 linesize
[0] = frame
->linesize
[0];
485 linesize
[1] = frame
->linesize
[0];
486 linesize
[2] = frame
->linesize
[0];
487 linesize
[3] = frame
->linesize
[0];
488 linesize
[4] = frame
->linesize
[1];
489 linesize
[5] = frame
->linesize
[2];
491 av_fast_padded_malloc(&s
->mvectors
, &s
->mvectors_size
, 2 * s
->nb_mvectors
* sizeof(*s
->mvectors
));
493 ret
= AVERROR(ENOMEM
);
498 skip_bits_long(gb
, mask_size
* 8);
500 skip_bits_long(gb
, s
->mode_size
* 8);
502 ret
= decode_coeffs(gb
, s
->mvectors
, 2 * s
->nb_mvectors
);
506 bytestream2_init(&mv
, (uint8_t *)s
->mvectors
, 2 * s
->nb_mvectors
* sizeof(*s
->mvectors
));
508 for (int y
= 0; y
< avctx
->height
; y
+= 16) {
509 GetByteContext gbyte
;
510 int pfill
[3][1] = { {0} };
511 int nb_codes
= get_bits(gb
, 16);
514 if (get_bits_left(gb
) < 0) {
515 ret
= AVERROR_INVALIDDATA
;
519 av_fast_padded_malloc(&s
->coeffs
, &s
->coeffs_size
, nb_codes
* sizeof(*s
->coeffs
));
521 ret
= AVERROR(ENOMEM
);
525 ret
= decode_coeffs(gb
, s
->coeffs
, nb_codes
);
529 bytestream2_init(&gbyte
, (uint8_t *)s
->coeffs
, nb_codes
* sizeof(*s
->coeffs
));
531 for (int x
= 0; x
< avctx
->width
; x
+= 16) {
535 if (get_bits_left(&mask
) < 8) {
536 ret
= AVERROR_INVALIDDATA
;
539 flags
= get_bits(&mask
, 8);
542 dst
[0] = frame
->data
[0] + linesize
[0] * y
+ x
;
543 dst
[1] = frame
->data
[0] + linesize
[0] * y
+ x
+ 8;
544 dst
[2] = frame
->data
[0] + linesize
[0] * (y
+ 8) + x
;
545 dst
[3] = frame
->data
[0] + linesize
[0] * (y
+ 8) + x
+ 8;
546 dst
[4] = frame
->data
[1] + linesize
[4] * (y
>> 1) + (x
>> 1);
547 dst
[5] = frame
->data
[2] + linesize
[5] * (y
>> 1) + (x
>> 1);
549 if ((flags
>> (cnt
)) & 1) {
550 int mv_x
= sign_extend(bytestream2_get_ne16(&mv
), 16);
551 int mv_y
= sign_extend(bytestream2_get_ne16(&mv
), 16);
556 if (px
< 0 || px
> FFALIGN(avctx
->width
, 16) - 16 ||
557 py
< 0 || py
> FFALIGN(avctx
->height
, 16) - 16)
558 return AVERROR_INVALIDDATA
;
560 src
[0] = prev
->data
[0] + in_linesize
[0] * py
+ px
;
561 src
[1] = prev
->data
[0] + in_linesize
[0] * py
+ px
+ 8;
562 src
[2] = prev
->data
[0] + in_linesize
[0] * (py
+ 8) + px
;
563 src
[3] = prev
->data
[0] + in_linesize
[0] * (py
+ 8) + px
+ 8;
564 src
[4] = prev
->data
[1] + in_linesize
[4] * (py
>> 1) + (px
>> 1);
565 src
[5] = prev
->data
[2] + in_linesize
[5] * (py
>> 1) + (px
>> 1);
567 if ((flags
>> (cnt
+ 4)) & 1) {
568 for (int b
= 0; b
< 6; b
++)
569 copy_block8(dst
[b
], src
[b
], linesize
[b
], in_linesize
[b
], 8);
571 for (int b
= 0; b
< 6; b
++) {
572 int mode
= get_bits_le(&mgb
, 2);
574 ret
= decode_inter_block(avctx
, mode
, &gbyte
, s
->interq_tab
[b
>= 4],
576 pfill
[(b
>= 4) + (b
>= 5)],
578 src
[b
], in_linesize
[b
]);
584 for (int b
= 0; b
< 6; b
++) {
585 int mode
= get_bits_le(&mgb
, 2);
587 ret
= decode_intra_block(avctx
, mode
, &gbyte
, s
->intraq_tab
[b
>= 4],
589 pfill
[(b
>= 4) + (b
>= 5)],
590 dst
[b
], linesize
[b
]);
604 static int decode_frame(AVCodecContext
*avctx
, AVFrame
*frame
,
605 int *got_frame
, AVPacket
*avpkt
)
607 MV30Context
*s
= avctx
->priv_data
;
608 GetBitContext
*gb
= &s
->gb
;
611 if ((ret
= init_get_bits8(gb
, avpkt
->data
, avpkt
->size
)) < 0)
614 if ((ret
= ff_get_buffer(avctx
, frame
, AV_GET_BUFFER_FLAG_REF
)) < 0)
617 s
->intra_quant
= get_bits(gb
, 8);
618 s
->inter_quant
= s
->intra_quant
+ get_sbits(gb
, 8);
619 s
->is_inter
= get_bits_le(gb
, 16);
620 s
->mode_size
= get_bits_le(gb
, 16);
622 s
->nb_mvectors
= get_bits_le(gb
, 16);
624 get_qtable(s
->intraq_tab
[0], s
->intra_quant
, luma_tab
);
625 get_qtable(s
->intraq_tab
[1], s
->intra_quant
, chroma_tab
);
627 if (s
->is_inter
== 0) {
628 frame
->flags
|= AV_FRAME_FLAG_KEY
;
629 ret
= decode_intra(avctx
, gb
, frame
);
633 get_qtable(s
->interq_tab
[0], s
->inter_quant
, luma_tab
);
634 get_qtable(s
->interq_tab
[1], s
->inter_quant
, chroma_tab
);
636 if (!s
->prev_frame
->data
[0]) {
637 av_log(avctx
, AV_LOG_ERROR
, "Missing reference frame.\n");
638 return AVERROR_INVALIDDATA
;
641 frame
->flags
&= ~AV_FRAME_FLAG_KEY
;
642 ret
= decode_inter(avctx
, gb
, frame
, s
->prev_frame
);
647 if ((ret
= av_frame_replace(s
->prev_frame
, frame
)) < 0)
655 static const uint8_t cbp_bits
[] = {
656 2, 2, 3, 3, 3, 4, 5, 6, 7, 8, 9, 9,
659 static av_cold
void init_static_data(void)
661 VLC_INIT_STATIC_TABLE_FROM_LENGTHS(cbp_tab
, CBP_VLC_BITS
,
662 FF_ARRAY_ELEMS(cbp_bits
),
663 cbp_bits
, 1, NULL
, 0, 0, 0, 0);
666 static av_cold
int decode_init(AVCodecContext
*avctx
)
668 MV30Context
*s
= avctx
->priv_data
;
669 static AVOnce init_static_once
= AV_ONCE_INIT
;
671 avctx
->pix_fmt
= AV_PIX_FMT_YUV420P
;
672 avctx
->color_range
= AVCOL_RANGE_JPEG
;
674 ff_blockdsp_init(&s
->bdsp
);
676 s
->prev_frame
= av_frame_alloc();
678 return AVERROR(ENOMEM
);
680 ff_thread_once(&init_static_once
, init_static_data
);
685 static void decode_flush(AVCodecContext
*avctx
)
687 MV30Context
*s
= avctx
->priv_data
;
689 av_frame_unref(s
->prev_frame
);
692 static av_cold
int decode_close(AVCodecContext
*avctx
)
694 MV30Context
*s
= avctx
->priv_data
;
696 av_frame_free(&s
->prev_frame
);
697 av_freep(&s
->coeffs
);
699 av_freep(&s
->mvectors
);
700 s
->mvectors_size
= 0;
705 const FFCodec ff_mv30_decoder
= {
707 CODEC_LONG_NAME("MidiVid 3.0"),
708 .p
.type
= AVMEDIA_TYPE_VIDEO
,
709 .p
.id
= AV_CODEC_ID_MV30
,
710 .priv_data_size
= sizeof(MV30Context
),
712 .close
= decode_close
,
713 FF_CODEC_DECODE_CB(decode_frame
),
714 .flush
= decode_flush
,
715 .p
.capabilities
= AV_CODEC_CAP_DR1
,
716 .caps_internal
= FF_CODEC_CAP_INIT_CLEANUP
,