yading@10
|
1 /*
|
yading@10
|
2 * KMVC decoder
|
yading@10
|
3 * Copyright (c) 2006 Konstantin Shishkov
|
yading@10
|
4 *
|
yading@10
|
5 * This file is part of FFmpeg.
|
yading@10
|
6 *
|
yading@10
|
7 * FFmpeg is free software; you can redistribute it and/or
|
yading@10
|
8 * modify it under the terms of the GNU Lesser General Public
|
yading@10
|
9 * License as published by the Free Software Foundation; either
|
yading@10
|
10 * version 2.1 of the License, or (at your option) any later version.
|
yading@10
|
11 *
|
yading@10
|
12 * FFmpeg is distributed in the hope that it will be useful,
|
yading@10
|
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
yading@10
|
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
yading@10
|
15 * Lesser General Public License for more details.
|
yading@10
|
16 *
|
yading@10
|
17 * You should have received a copy of the GNU Lesser General Public
|
yading@10
|
18 * License along with FFmpeg; if not, write to the Free Software
|
yading@10
|
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
yading@10
|
20 */
|
yading@10
|
21
|
yading@10
|
22 /**
|
yading@10
|
23 * @file
|
yading@10
|
24 * Karl Morton's Video Codec decoder
|
yading@10
|
25 */
|
yading@10
|
26
|
yading@10
|
27 #include <stdio.h>
|
yading@10
|
28 #include <stdlib.h>
|
yading@10
|
29
|
yading@10
|
30 #include "avcodec.h"
|
yading@10
|
31 #include "bytestream.h"
|
yading@10
|
32 #include "internal.h"
|
yading@10
|
33
|
yading@10
|
34 #define KMVC_KEYFRAME 0x80
|
yading@10
|
35 #define KMVC_PALETTE 0x40
|
yading@10
|
36 #define KMVC_METHOD 0x0F
|
yading@10
|
37 #define MAX_PALSIZE 256
|
yading@10
|
38
|
yading@10
|
39 /*
|
yading@10
|
40 * Decoder context
|
yading@10
|
41 */
|
yading@10
|
42 typedef struct KmvcContext {
|
yading@10
|
43 AVCodecContext *avctx;
|
yading@10
|
44
|
yading@10
|
45 int setpal;
|
yading@10
|
46 int palsize;
|
yading@10
|
47 uint32_t pal[MAX_PALSIZE];
|
yading@10
|
48 uint8_t *cur, *prev;
|
yading@10
|
49 uint8_t *frm0, *frm1;
|
yading@10
|
50 GetByteContext g;
|
yading@10
|
51 } KmvcContext;
|
yading@10
|
52
|
yading@10
|
53 typedef struct BitBuf {
|
yading@10
|
54 int bits;
|
yading@10
|
55 int bitbuf;
|
yading@10
|
56 } BitBuf;
|
yading@10
|
57
|
yading@10
|
58 #define BLK(data, x, y) data[(x) + (y) * 320]
|
yading@10
|
59
|
yading@10
|
60 #define kmvc_init_getbits(bb, g) bb.bits = 7; bb.bitbuf = bytestream2_get_byte(g);
|
yading@10
|
61
|
yading@10
|
62 #define kmvc_getbit(bb, g, res) {\
|
yading@10
|
63 res = 0; \
|
yading@10
|
64 if (bb.bitbuf & (1 << bb.bits)) res = 1; \
|
yading@10
|
65 bb.bits--; \
|
yading@10
|
66 if(bb.bits == -1) { \
|
yading@10
|
67 bb.bitbuf = bytestream2_get_byte(g); \
|
yading@10
|
68 bb.bits = 7; \
|
yading@10
|
69 } \
|
yading@10
|
70 }
|
yading@10
|
71
|
yading@10
|
72 static int kmvc_decode_intra_8x8(KmvcContext * ctx, int w, int h)
|
yading@10
|
73 {
|
yading@10
|
74 BitBuf bb;
|
yading@10
|
75 int res, val;
|
yading@10
|
76 int i, j;
|
yading@10
|
77 int bx, by;
|
yading@10
|
78 int l0x, l1x, l0y, l1y;
|
yading@10
|
79 int mx, my;
|
yading@10
|
80
|
yading@10
|
81 kmvc_init_getbits(bb, &ctx->g);
|
yading@10
|
82
|
yading@10
|
83 for (by = 0; by < h; by += 8)
|
yading@10
|
84 for (bx = 0; bx < w; bx += 8) {
|
yading@10
|
85 if (!bytestream2_get_bytes_left(&ctx->g)) {
|
yading@10
|
86 av_log(ctx->avctx, AV_LOG_ERROR, "Data overrun\n");
|
yading@10
|
87 return AVERROR_INVALIDDATA;
|
yading@10
|
88 }
|
yading@10
|
89 kmvc_getbit(bb, &ctx->g, res);
|
yading@10
|
90 if (!res) { // fill whole 8x8 block
|
yading@10
|
91 val = bytestream2_get_byte(&ctx->g);
|
yading@10
|
92 for (i = 0; i < 64; i++)
|
yading@10
|
93 BLK(ctx->cur, bx + (i & 0x7), by + (i >> 3)) = val;
|
yading@10
|
94 } else { // handle four 4x4 subblocks
|
yading@10
|
95 for (i = 0; i < 4; i++) {
|
yading@10
|
96 l0x = bx + (i & 1) * 4;
|
yading@10
|
97 l0y = by + (i & 2) * 2;
|
yading@10
|
98 kmvc_getbit(bb, &ctx->g, res);
|
yading@10
|
99 if (!res) {
|
yading@10
|
100 kmvc_getbit(bb, &ctx->g, res);
|
yading@10
|
101 if (!res) { // fill whole 4x4 block
|
yading@10
|
102 val = bytestream2_get_byte(&ctx->g);
|
yading@10
|
103 for (j = 0; j < 16; j++)
|
yading@10
|
104 BLK(ctx->cur, l0x + (j & 3), l0y + (j >> 2)) = val;
|
yading@10
|
105 } else { // copy block from already decoded place
|
yading@10
|
106 val = bytestream2_get_byte(&ctx->g);
|
yading@10
|
107 mx = val & 0xF;
|
yading@10
|
108 my = val >> 4;
|
yading@10
|
109 if ((l0x-mx) + 320*(l0y-my) < 0 || (l0x-mx) + 320*(l0y-my) > 316*196) {
|
yading@10
|
110 av_log(ctx->avctx, AV_LOG_ERROR, "Invalid MV\n");
|
yading@10
|
111 return AVERROR_INVALIDDATA;
|
yading@10
|
112 }
|
yading@10
|
113 for (j = 0; j < 16; j++)
|
yading@10
|
114 BLK(ctx->cur, l0x + (j & 3), l0y + (j >> 2)) =
|
yading@10
|
115 BLK(ctx->cur, l0x + (j & 3) - mx, l0y + (j >> 2) - my);
|
yading@10
|
116 }
|
yading@10
|
117 } else { // descend to 2x2 sub-sub-blocks
|
yading@10
|
118 for (j = 0; j < 4; j++) {
|
yading@10
|
119 l1x = l0x + (j & 1) * 2;
|
yading@10
|
120 l1y = l0y + (j & 2);
|
yading@10
|
121 kmvc_getbit(bb, &ctx->g, res);
|
yading@10
|
122 if (!res) {
|
yading@10
|
123 kmvc_getbit(bb, &ctx->g, res);
|
yading@10
|
124 if (!res) { // fill whole 2x2 block
|
yading@10
|
125 val = bytestream2_get_byte(&ctx->g);
|
yading@10
|
126 BLK(ctx->cur, l1x, l1y) = val;
|
yading@10
|
127 BLK(ctx->cur, l1x + 1, l1y) = val;
|
yading@10
|
128 BLK(ctx->cur, l1x, l1y + 1) = val;
|
yading@10
|
129 BLK(ctx->cur, l1x + 1, l1y + 1) = val;
|
yading@10
|
130 } else { // copy block from already decoded place
|
yading@10
|
131 val = bytestream2_get_byte(&ctx->g);
|
yading@10
|
132 mx = val & 0xF;
|
yading@10
|
133 my = val >> 4;
|
yading@10
|
134 if ((l1x-mx) + 320*(l1y-my) < 0 || (l1x-mx) + 320*(l1y-my) > 318*198) {
|
yading@10
|
135 av_log(ctx->avctx, AV_LOG_ERROR, "Invalid MV\n");
|
yading@10
|
136 return AVERROR_INVALIDDATA;
|
yading@10
|
137 }
|
yading@10
|
138 BLK(ctx->cur, l1x, l1y) = BLK(ctx->cur, l1x - mx, l1y - my);
|
yading@10
|
139 BLK(ctx->cur, l1x + 1, l1y) =
|
yading@10
|
140 BLK(ctx->cur, l1x + 1 - mx, l1y - my);
|
yading@10
|
141 BLK(ctx->cur, l1x, l1y + 1) =
|
yading@10
|
142 BLK(ctx->cur, l1x - mx, l1y + 1 - my);
|
yading@10
|
143 BLK(ctx->cur, l1x + 1, l1y + 1) =
|
yading@10
|
144 BLK(ctx->cur, l1x + 1 - mx, l1y + 1 - my);
|
yading@10
|
145 }
|
yading@10
|
146 } else { // read values for block
|
yading@10
|
147 BLK(ctx->cur, l1x, l1y) = bytestream2_get_byte(&ctx->g);
|
yading@10
|
148 BLK(ctx->cur, l1x + 1, l1y) = bytestream2_get_byte(&ctx->g);
|
yading@10
|
149 BLK(ctx->cur, l1x, l1y + 1) = bytestream2_get_byte(&ctx->g);
|
yading@10
|
150 BLK(ctx->cur, l1x + 1, l1y + 1) = bytestream2_get_byte(&ctx->g);
|
yading@10
|
151 }
|
yading@10
|
152 }
|
yading@10
|
153 }
|
yading@10
|
154 }
|
yading@10
|
155 }
|
yading@10
|
156 }
|
yading@10
|
157
|
yading@10
|
158 return 0;
|
yading@10
|
159 }
|
yading@10
|
160
|
yading@10
|
161 static int kmvc_decode_inter_8x8(KmvcContext * ctx, int w, int h)
|
yading@10
|
162 {
|
yading@10
|
163 BitBuf bb;
|
yading@10
|
164 int res, val;
|
yading@10
|
165 int i, j;
|
yading@10
|
166 int bx, by;
|
yading@10
|
167 int l0x, l1x, l0y, l1y;
|
yading@10
|
168 int mx, my;
|
yading@10
|
169
|
yading@10
|
170 kmvc_init_getbits(bb, &ctx->g);
|
yading@10
|
171
|
yading@10
|
172 for (by = 0; by < h; by += 8)
|
yading@10
|
173 for (bx = 0; bx < w; bx += 8) {
|
yading@10
|
174 kmvc_getbit(bb, &ctx->g, res);
|
yading@10
|
175 if (!res) {
|
yading@10
|
176 kmvc_getbit(bb, &ctx->g, res);
|
yading@10
|
177 if (!res) { // fill whole 8x8 block
|
yading@10
|
178 if (!bytestream2_get_bytes_left(&ctx->g)) {
|
yading@10
|
179 av_log(ctx->avctx, AV_LOG_ERROR, "Data overrun\n");
|
yading@10
|
180 return AVERROR_INVALIDDATA;
|
yading@10
|
181 }
|
yading@10
|
182 val = bytestream2_get_byte(&ctx->g);
|
yading@10
|
183 for (i = 0; i < 64; i++)
|
yading@10
|
184 BLK(ctx->cur, bx + (i & 0x7), by + (i >> 3)) = val;
|
yading@10
|
185 } else { // copy block from previous frame
|
yading@10
|
186 for (i = 0; i < 64; i++)
|
yading@10
|
187 BLK(ctx->cur, bx + (i & 0x7), by + (i >> 3)) =
|
yading@10
|
188 BLK(ctx->prev, bx + (i & 0x7), by + (i >> 3));
|
yading@10
|
189 }
|
yading@10
|
190 } else { // handle four 4x4 subblocks
|
yading@10
|
191 if (!bytestream2_get_bytes_left(&ctx->g)) {
|
yading@10
|
192 av_log(ctx->avctx, AV_LOG_ERROR, "Data overrun\n");
|
yading@10
|
193 return AVERROR_INVALIDDATA;
|
yading@10
|
194 }
|
yading@10
|
195 for (i = 0; i < 4; i++) {
|
yading@10
|
196 l0x = bx + (i & 1) * 4;
|
yading@10
|
197 l0y = by + (i & 2) * 2;
|
yading@10
|
198 kmvc_getbit(bb, &ctx->g, res);
|
yading@10
|
199 if (!res) {
|
yading@10
|
200 kmvc_getbit(bb, &ctx->g, res);
|
yading@10
|
201 if (!res) { // fill whole 4x4 block
|
yading@10
|
202 val = bytestream2_get_byte(&ctx->g);
|
yading@10
|
203 for (j = 0; j < 16; j++)
|
yading@10
|
204 BLK(ctx->cur, l0x + (j & 3), l0y + (j >> 2)) = val;
|
yading@10
|
205 } else { // copy block
|
yading@10
|
206 val = bytestream2_get_byte(&ctx->g);
|
yading@10
|
207 mx = (val & 0xF) - 8;
|
yading@10
|
208 my = (val >> 4) - 8;
|
yading@10
|
209 if ((l0x+mx) + 320*(l0y+my) < 0 || (l0x+mx) + 320*(l0y+my) > 318*198) {
|
yading@10
|
210 av_log(ctx->avctx, AV_LOG_ERROR, "Invalid MV\n");
|
yading@10
|
211 return AVERROR_INVALIDDATA;
|
yading@10
|
212 }
|
yading@10
|
213 for (j = 0; j < 16; j++)
|
yading@10
|
214 BLK(ctx->cur, l0x + (j & 3), l0y + (j >> 2)) =
|
yading@10
|
215 BLK(ctx->prev, l0x + (j & 3) + mx, l0y + (j >> 2) + my);
|
yading@10
|
216 }
|
yading@10
|
217 } else { // descend to 2x2 sub-sub-blocks
|
yading@10
|
218 for (j = 0; j < 4; j++) {
|
yading@10
|
219 l1x = l0x + (j & 1) * 2;
|
yading@10
|
220 l1y = l0y + (j & 2);
|
yading@10
|
221 kmvc_getbit(bb, &ctx->g, res);
|
yading@10
|
222 if (!res) {
|
yading@10
|
223 kmvc_getbit(bb, &ctx->g, res);
|
yading@10
|
224 if (!res) { // fill whole 2x2 block
|
yading@10
|
225 val = bytestream2_get_byte(&ctx->g);
|
yading@10
|
226 BLK(ctx->cur, l1x, l1y) = val;
|
yading@10
|
227 BLK(ctx->cur, l1x + 1, l1y) = val;
|
yading@10
|
228 BLK(ctx->cur, l1x, l1y + 1) = val;
|
yading@10
|
229 BLK(ctx->cur, l1x + 1, l1y + 1) = val;
|
yading@10
|
230 } else { // copy block
|
yading@10
|
231 val = bytestream2_get_byte(&ctx->g);
|
yading@10
|
232 mx = (val & 0xF) - 8;
|
yading@10
|
233 my = (val >> 4) - 8;
|
yading@10
|
234 if ((l1x+mx) + 320*(l1y+my) < 0 || (l1x+mx) + 320*(l1y+my) > 318*198) {
|
yading@10
|
235 av_log(ctx->avctx, AV_LOG_ERROR, "Invalid MV\n");
|
yading@10
|
236 return AVERROR_INVALIDDATA;
|
yading@10
|
237 }
|
yading@10
|
238 BLK(ctx->cur, l1x, l1y) = BLK(ctx->prev, l1x + mx, l1y + my);
|
yading@10
|
239 BLK(ctx->cur, l1x + 1, l1y) =
|
yading@10
|
240 BLK(ctx->prev, l1x + 1 + mx, l1y + my);
|
yading@10
|
241 BLK(ctx->cur, l1x, l1y + 1) =
|
yading@10
|
242 BLK(ctx->prev, l1x + mx, l1y + 1 + my);
|
yading@10
|
243 BLK(ctx->cur, l1x + 1, l1y + 1) =
|
yading@10
|
244 BLK(ctx->prev, l1x + 1 + mx, l1y + 1 + my);
|
yading@10
|
245 }
|
yading@10
|
246 } else { // read values for block
|
yading@10
|
247 BLK(ctx->cur, l1x, l1y) = bytestream2_get_byte(&ctx->g);
|
yading@10
|
248 BLK(ctx->cur, l1x + 1, l1y) = bytestream2_get_byte(&ctx->g);
|
yading@10
|
249 BLK(ctx->cur, l1x, l1y + 1) = bytestream2_get_byte(&ctx->g);
|
yading@10
|
250 BLK(ctx->cur, l1x + 1, l1y + 1) = bytestream2_get_byte(&ctx->g);
|
yading@10
|
251 }
|
yading@10
|
252 }
|
yading@10
|
253 }
|
yading@10
|
254 }
|
yading@10
|
255 }
|
yading@10
|
256 }
|
yading@10
|
257
|
yading@10
|
258 return 0;
|
yading@10
|
259 }
|
yading@10
|
260
|
yading@10
|
261 static int decode_frame(AVCodecContext * avctx, void *data, int *got_frame,
|
yading@10
|
262 AVPacket *avpkt)
|
yading@10
|
263 {
|
yading@10
|
264 KmvcContext *const ctx = avctx->priv_data;
|
yading@10
|
265 AVFrame *frame = data;
|
yading@10
|
266 uint8_t *out, *src;
|
yading@10
|
267 int i, ret;
|
yading@10
|
268 int header;
|
yading@10
|
269 int blocksize;
|
yading@10
|
270 const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, NULL);
|
yading@10
|
271
|
yading@10
|
272 bytestream2_init(&ctx->g, avpkt->data, avpkt->size);
|
yading@10
|
273
|
yading@10
|
274 if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
|
yading@10
|
275 return ret;
|
yading@10
|
276
|
yading@10
|
277 header = bytestream2_get_byte(&ctx->g);
|
yading@10
|
278
|
yading@10
|
279 /* blocksize 127 is really palette change event */
|
yading@10
|
280 if (bytestream2_peek_byte(&ctx->g) == 127) {
|
yading@10
|
281 bytestream2_skip(&ctx->g, 3);
|
yading@10
|
282 for (i = 0; i < 127; i++) {
|
yading@10
|
283 ctx->pal[i + (header & 0x81)] = 0xFFU << 24 | bytestream2_get_be24(&ctx->g);
|
yading@10
|
284 bytestream2_skip(&ctx->g, 1);
|
yading@10
|
285 }
|
yading@10
|
286 bytestream2_seek(&ctx->g, -127 * 4 - 3, SEEK_CUR);
|
yading@10
|
287 }
|
yading@10
|
288
|
yading@10
|
289 if (header & KMVC_KEYFRAME) {
|
yading@10
|
290 frame->key_frame = 1;
|
yading@10
|
291 frame->pict_type = AV_PICTURE_TYPE_I;
|
yading@10
|
292 } else {
|
yading@10
|
293 frame->key_frame = 0;
|
yading@10
|
294 frame->pict_type = AV_PICTURE_TYPE_P;
|
yading@10
|
295 }
|
yading@10
|
296
|
yading@10
|
297 if (header & KMVC_PALETTE) {
|
yading@10
|
298 frame->palette_has_changed = 1;
|
yading@10
|
299 // palette starts from index 1 and has 127 entries
|
yading@10
|
300 for (i = 1; i <= ctx->palsize; i++) {
|
yading@10
|
301 ctx->pal[i] = 0xFFU << 24 | bytestream2_get_be24(&ctx->g);
|
yading@10
|
302 }
|
yading@10
|
303 }
|
yading@10
|
304
|
yading@10
|
305 if (pal) {
|
yading@10
|
306 frame->palette_has_changed = 1;
|
yading@10
|
307 memcpy(ctx->pal, pal, AVPALETTE_SIZE);
|
yading@10
|
308 }
|
yading@10
|
309
|
yading@10
|
310 if (ctx->setpal) {
|
yading@10
|
311 ctx->setpal = 0;
|
yading@10
|
312 frame->palette_has_changed = 1;
|
yading@10
|
313 }
|
yading@10
|
314
|
yading@10
|
315 /* make the palette available on the way out */
|
yading@10
|
316 memcpy(frame->data[1], ctx->pal, 1024);
|
yading@10
|
317
|
yading@10
|
318 blocksize = bytestream2_get_byte(&ctx->g);
|
yading@10
|
319
|
yading@10
|
320 if (blocksize != 8 && blocksize != 127) {
|
yading@10
|
321 av_log(avctx, AV_LOG_ERROR, "Block size = %i\n", blocksize);
|
yading@10
|
322 return AVERROR_INVALIDDATA;
|
yading@10
|
323 }
|
yading@10
|
324 memset(ctx->cur, 0, 320 * 200);
|
yading@10
|
325 switch (header & KMVC_METHOD) {
|
yading@10
|
326 case 0:
|
yading@10
|
327 case 1: // used in palette changed event
|
yading@10
|
328 memcpy(ctx->cur, ctx->prev, 320 * 200);
|
yading@10
|
329 break;
|
yading@10
|
330 case 3:
|
yading@10
|
331 kmvc_decode_intra_8x8(ctx, avctx->width, avctx->height);
|
yading@10
|
332 break;
|
yading@10
|
333 case 4:
|
yading@10
|
334 kmvc_decode_inter_8x8(ctx, avctx->width, avctx->height);
|
yading@10
|
335 break;
|
yading@10
|
336 default:
|
yading@10
|
337 av_log(avctx, AV_LOG_ERROR, "Unknown compression method %i\n", header & KMVC_METHOD);
|
yading@10
|
338 return AVERROR_INVALIDDATA;
|
yading@10
|
339 }
|
yading@10
|
340
|
yading@10
|
341 out = frame->data[0];
|
yading@10
|
342 src = ctx->cur;
|
yading@10
|
343 for (i = 0; i < avctx->height; i++) {
|
yading@10
|
344 memcpy(out, src, avctx->width);
|
yading@10
|
345 src += 320;
|
yading@10
|
346 out += frame->linesize[0];
|
yading@10
|
347 }
|
yading@10
|
348
|
yading@10
|
349 /* flip buffers */
|
yading@10
|
350 if (ctx->cur == ctx->frm0) {
|
yading@10
|
351 ctx->cur = ctx->frm1;
|
yading@10
|
352 ctx->prev = ctx->frm0;
|
yading@10
|
353 } else {
|
yading@10
|
354 ctx->cur = ctx->frm0;
|
yading@10
|
355 ctx->prev = ctx->frm1;
|
yading@10
|
356 }
|
yading@10
|
357
|
yading@10
|
358 *got_frame = 1;
|
yading@10
|
359
|
yading@10
|
360 /* always report that the buffer was completely consumed */
|
yading@10
|
361 return avpkt->size;
|
yading@10
|
362 }
|
yading@10
|
363
|
yading@10
|
364
|
yading@10
|
365
|
yading@10
|
366 /*
|
yading@10
|
367 * Init kmvc decoder
|
yading@10
|
368 */
|
yading@10
|
369 static av_cold int decode_init(AVCodecContext * avctx)
|
yading@10
|
370 {
|
yading@10
|
371 KmvcContext *const c = avctx->priv_data;
|
yading@10
|
372 int i;
|
yading@10
|
373
|
yading@10
|
374 c->avctx = avctx;
|
yading@10
|
375
|
yading@10
|
376 if (avctx->width > 320 || avctx->height > 200) {
|
yading@10
|
377 av_log(avctx, AV_LOG_ERROR, "KMVC supports frames <= 320x200\n");
|
yading@10
|
378 return AVERROR(EINVAL);
|
yading@10
|
379 }
|
yading@10
|
380
|
yading@10
|
381 c->frm0 = av_mallocz(320 * 200);
|
yading@10
|
382 c->frm1 = av_mallocz(320 * 200);
|
yading@10
|
383 c->cur = c->frm0;
|
yading@10
|
384 c->prev = c->frm1;
|
yading@10
|
385
|
yading@10
|
386 for (i = 0; i < 256; i++) {
|
yading@10
|
387 c->pal[i] = 0xFFU << 24 | i * 0x10101;
|
yading@10
|
388 }
|
yading@10
|
389
|
yading@10
|
390 if (avctx->extradata_size < 12) {
|
yading@10
|
391 av_log(avctx, AV_LOG_WARNING,
|
yading@10
|
392 "Extradata missing, decoding may not work properly...\n");
|
yading@10
|
393 c->palsize = 127;
|
yading@10
|
394 } else {
|
yading@10
|
395 c->palsize = AV_RL16(avctx->extradata + 10);
|
yading@10
|
396 if (c->palsize >= (unsigned)MAX_PALSIZE) {
|
yading@10
|
397 c->palsize = 127;
|
yading@10
|
398 av_log(avctx, AV_LOG_ERROR, "KMVC palette too large\n");
|
yading@10
|
399 return AVERROR_INVALIDDATA;
|
yading@10
|
400 }
|
yading@10
|
401 }
|
yading@10
|
402
|
yading@10
|
403 if (avctx->extradata_size == 1036) { // palette in extradata
|
yading@10
|
404 uint8_t *src = avctx->extradata + 12;
|
yading@10
|
405 for (i = 0; i < 256; i++) {
|
yading@10
|
406 c->pal[i] = AV_RL32(src);
|
yading@10
|
407 src += 4;
|
yading@10
|
408 }
|
yading@10
|
409 c->setpal = 1;
|
yading@10
|
410 }
|
yading@10
|
411
|
yading@10
|
412 avctx->pix_fmt = AV_PIX_FMT_PAL8;
|
yading@10
|
413
|
yading@10
|
414 return 0;
|
yading@10
|
415 }
|
yading@10
|
416
|
yading@10
|
417
|
yading@10
|
418
|
yading@10
|
419 /*
|
yading@10
|
420 * Uninit kmvc decoder
|
yading@10
|
421 */
|
yading@10
|
422 static av_cold int decode_end(AVCodecContext * avctx)
|
yading@10
|
423 {
|
yading@10
|
424 KmvcContext *const c = avctx->priv_data;
|
yading@10
|
425
|
yading@10
|
426 av_freep(&c->frm0);
|
yading@10
|
427 av_freep(&c->frm1);
|
yading@10
|
428
|
yading@10
|
429 return 0;
|
yading@10
|
430 }
|
yading@10
|
431
|
yading@10
|
432 AVCodec ff_kmvc_decoder = {
|
yading@10
|
433 .name = "kmvc",
|
yading@10
|
434 .type = AVMEDIA_TYPE_VIDEO,
|
yading@10
|
435 .id = AV_CODEC_ID_KMVC,
|
yading@10
|
436 .priv_data_size = sizeof(KmvcContext),
|
yading@10
|
437 .init = decode_init,
|
yading@10
|
438 .close = decode_end,
|
yading@10
|
439 .decode = decode_frame,
|
yading@10
|
440 .capabilities = CODEC_CAP_DR1,
|
yading@10
|
441 .long_name = NULL_IF_CONFIG_SMALL("Karl Morton's video codec"),
|
yading@10
|
442 };
|