00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00027 #include <stdio.h>
00028 #include <stdlib.h>
00029
00030 #include "avcodec.h"
00031 #include "bytestream.h"
00032 #include "internal.h"
00033
00034 #define KMVC_KEYFRAME 0x80
00035 #define KMVC_PALETTE 0x40
00036 #define KMVC_METHOD 0x0F
00037 #define MAX_PALSIZE 256
00038
00039
00040
00041
00042 typedef struct KmvcContext {
00043 AVCodecContext *avctx;
00044 AVFrame pic;
00045
00046 int setpal;
00047 int palsize;
00048 uint32_t pal[MAX_PALSIZE];
00049 uint8_t *cur, *prev;
00050 uint8_t *frm0, *frm1;
00051 GetByteContext g;
00052 } KmvcContext;
00053
00054 typedef struct BitBuf {
00055 int bits;
00056 int bitbuf;
00057 } BitBuf;
00058
00059 #define BLK(data, x, y) data[(x) + (y) * 320]
00060
00061 #define kmvc_init_getbits(bb, g) bb.bits = 7; bb.bitbuf = bytestream2_get_byte(g);
00062
00063 #define kmvc_getbit(bb, g, res) {\
00064 res = 0; \
00065 if (bb.bitbuf & (1 << bb.bits)) res = 1; \
00066 bb.bits--; \
00067 if(bb.bits == -1) { \
00068 bb.bitbuf = bytestream2_get_byte(g); \
00069 bb.bits = 7; \
00070 } \
00071 }
00072
00073 static int kmvc_decode_intra_8x8(KmvcContext * ctx, int w, int h)
00074 {
00075 BitBuf bb;
00076 int res, val;
00077 int i, j;
00078 int bx, by;
00079 int l0x, l1x, l0y, l1y;
00080 int mx, my;
00081
00082 kmvc_init_getbits(bb, &ctx->g);
00083
00084 for (by = 0; by < h; by += 8)
00085 for (bx = 0; bx < w; bx += 8) {
00086 if (!bytestream2_get_bytes_left(&ctx->g)) {
00087 av_log(ctx->avctx, AV_LOG_ERROR, "Data overrun\n");
00088 return AVERROR_INVALIDDATA;
00089 }
00090 kmvc_getbit(bb, &ctx->g, res);
00091 if (!res) {
00092 val = bytestream2_get_byte(&ctx->g);
00093 for (i = 0; i < 64; i++)
00094 BLK(ctx->cur, bx + (i & 0x7), by + (i >> 3)) = val;
00095 } else {
00096 for (i = 0; i < 4; i++) {
00097 l0x = bx + (i & 1) * 4;
00098 l0y = by + (i & 2) * 2;
00099 kmvc_getbit(bb, &ctx->g, res);
00100 if (!res) {
00101 kmvc_getbit(bb, &ctx->g, res);
00102 if (!res) {
00103 val = bytestream2_get_byte(&ctx->g);
00104 for (j = 0; j < 16; j++)
00105 BLK(ctx->cur, l0x + (j & 3), l0y + (j >> 2)) = val;
00106 } else {
00107 val = bytestream2_get_byte(&ctx->g);
00108 mx = val & 0xF;
00109 my = val >> 4;
00110 if ((l0x-mx) + 320*(l0y-my) < 0 || (l0x-mx) + 320*(l0y-my) > 316*196) {
00111 av_log(ctx->avctx, AV_LOG_ERROR, "Invalid MV\n");
00112 return AVERROR_INVALIDDATA;
00113 }
00114 for (j = 0; j < 16; j++)
00115 BLK(ctx->cur, l0x + (j & 3), l0y + (j >> 2)) =
00116 BLK(ctx->cur, l0x + (j & 3) - mx, l0y + (j >> 2) - my);
00117 }
00118 } else {
00119 for (j = 0; j < 4; j++) {
00120 l1x = l0x + (j & 1) * 2;
00121 l1y = l0y + (j & 2);
00122 kmvc_getbit(bb, &ctx->g, res);
00123 if (!res) {
00124 kmvc_getbit(bb, &ctx->g, res);
00125 if (!res) {
00126 val = bytestream2_get_byte(&ctx->g);
00127 BLK(ctx->cur, l1x, l1y) = val;
00128 BLK(ctx->cur, l1x + 1, l1y) = val;
00129 BLK(ctx->cur, l1x, l1y + 1) = val;
00130 BLK(ctx->cur, l1x + 1, l1y + 1) = val;
00131 } else {
00132 val = bytestream2_get_byte(&ctx->g);
00133 mx = val & 0xF;
00134 my = val >> 4;
00135 if ((l1x-mx) + 320*(l1y-my) < 0 || (l1x-mx) + 320*(l1y-my) > 318*198) {
00136 av_log(ctx->avctx, AV_LOG_ERROR, "Invalid MV\n");
00137 return AVERROR_INVALIDDATA;
00138 }
00139 BLK(ctx->cur, l1x, l1y) = BLK(ctx->cur, l1x - mx, l1y - my);
00140 BLK(ctx->cur, l1x + 1, l1y) =
00141 BLK(ctx->cur, l1x + 1 - mx, l1y - my);
00142 BLK(ctx->cur, l1x, l1y + 1) =
00143 BLK(ctx->cur, l1x - mx, l1y + 1 - my);
00144 BLK(ctx->cur, l1x + 1, l1y + 1) =
00145 BLK(ctx->cur, l1x + 1 - mx, l1y + 1 - my);
00146 }
00147 } else {
00148 BLK(ctx->cur, l1x, l1y) = bytestream2_get_byte(&ctx->g);
00149 BLK(ctx->cur, l1x + 1, l1y) = bytestream2_get_byte(&ctx->g);
00150 BLK(ctx->cur, l1x, l1y + 1) = bytestream2_get_byte(&ctx->g);
00151 BLK(ctx->cur, l1x + 1, l1y + 1) = bytestream2_get_byte(&ctx->g);
00152 }
00153 }
00154 }
00155 }
00156 }
00157 }
00158
00159 return 0;
00160 }
00161
00162 static int kmvc_decode_inter_8x8(KmvcContext * ctx, int w, int h)
00163 {
00164 BitBuf bb;
00165 int res, val;
00166 int i, j;
00167 int bx, by;
00168 int l0x, l1x, l0y, l1y;
00169 int mx, my;
00170
00171 kmvc_init_getbits(bb, &ctx->g);
00172
00173 for (by = 0; by < h; by += 8)
00174 for (bx = 0; bx < w; bx += 8) {
00175 kmvc_getbit(bb, &ctx->g, res);
00176 if (!res) {
00177 kmvc_getbit(bb, &ctx->g, res);
00178 if (!res) {
00179 if (!bytestream2_get_bytes_left(&ctx->g)) {
00180 av_log(ctx->avctx, AV_LOG_ERROR, "Data overrun\n");
00181 return AVERROR_INVALIDDATA;
00182 }
00183 val = bytestream2_get_byte(&ctx->g);
00184 for (i = 0; i < 64; i++)
00185 BLK(ctx->cur, bx + (i & 0x7), by + (i >> 3)) = val;
00186 } else {
00187 for (i = 0; i < 64; i++)
00188 BLK(ctx->cur, bx + (i & 0x7), by + (i >> 3)) =
00189 BLK(ctx->prev, bx + (i & 0x7), by + (i >> 3));
00190 }
00191 } else {
00192 if (!bytestream2_get_bytes_left(&ctx->g)) {
00193 av_log(ctx->avctx, AV_LOG_ERROR, "Data overrun\n");
00194 return AVERROR_INVALIDDATA;
00195 }
00196 for (i = 0; i < 4; i++) {
00197 l0x = bx + (i & 1) * 4;
00198 l0y = by + (i & 2) * 2;
00199 kmvc_getbit(bb, &ctx->g, res);
00200 if (!res) {
00201 kmvc_getbit(bb, &ctx->g, res);
00202 if (!res) {
00203 val = bytestream2_get_byte(&ctx->g);
00204 for (j = 0; j < 16; j++)
00205 BLK(ctx->cur, l0x + (j & 3), l0y + (j >> 2)) = val;
00206 } else {
00207 val = bytestream2_get_byte(&ctx->g);
00208 mx = (val & 0xF) - 8;
00209 my = (val >> 4) - 8;
00210 if ((l0x+mx) + 320*(l0y+my) < 0 || (l0x+mx) + 320*(l0y+my) > 318*198) {
00211 av_log(ctx->avctx, AV_LOG_ERROR, "Invalid MV\n");
00212 return AVERROR_INVALIDDATA;
00213 }
00214 for (j = 0; j < 16; j++)
00215 BLK(ctx->cur, l0x + (j & 3), l0y + (j >> 2)) =
00216 BLK(ctx->prev, l0x + (j & 3) + mx, l0y + (j >> 2) + my);
00217 }
00218 } else {
00219 for (j = 0; j < 4; j++) {
00220 l1x = l0x + (j & 1) * 2;
00221 l1y = l0y + (j & 2);
00222 kmvc_getbit(bb, &ctx->g, res);
00223 if (!res) {
00224 kmvc_getbit(bb, &ctx->g, res);
00225 if (!res) {
00226 val = bytestream2_get_byte(&ctx->g);
00227 BLK(ctx->cur, l1x, l1y) = val;
00228 BLK(ctx->cur, l1x + 1, l1y) = val;
00229 BLK(ctx->cur, l1x, l1y + 1) = val;
00230 BLK(ctx->cur, l1x + 1, l1y + 1) = val;
00231 } else {
00232 val = bytestream2_get_byte(&ctx->g);
00233 mx = (val & 0xF) - 8;
00234 my = (val >> 4) - 8;
00235 if ((l1x+mx) + 320*(l1y+my) < 0 || (l1x+mx) + 320*(l1y+my) > 318*198) {
00236 av_log(ctx->avctx, AV_LOG_ERROR, "Invalid MV\n");
00237 return AVERROR_INVALIDDATA;
00238 }
00239 BLK(ctx->cur, l1x, l1y) = BLK(ctx->prev, l1x + mx, l1y + my);
00240 BLK(ctx->cur, l1x + 1, l1y) =
00241 BLK(ctx->prev, l1x + 1 + mx, l1y + my);
00242 BLK(ctx->cur, l1x, l1y + 1) =
00243 BLK(ctx->prev, l1x + mx, l1y + 1 + my);
00244 BLK(ctx->cur, l1x + 1, l1y + 1) =
00245 BLK(ctx->prev, l1x + 1 + mx, l1y + 1 + my);
00246 }
00247 } else {
00248 BLK(ctx->cur, l1x, l1y) = bytestream2_get_byte(&ctx->g);
00249 BLK(ctx->cur, l1x + 1, l1y) = bytestream2_get_byte(&ctx->g);
00250 BLK(ctx->cur, l1x, l1y + 1) = bytestream2_get_byte(&ctx->g);
00251 BLK(ctx->cur, l1x + 1, l1y + 1) = bytestream2_get_byte(&ctx->g);
00252 }
00253 }
00254 }
00255 }
00256 }
00257 }
00258
00259 return 0;
00260 }
00261
00262 static int decode_frame(AVCodecContext * avctx, void *data, int *got_frame,
00263 AVPacket *avpkt)
00264 {
00265 KmvcContext *const ctx = avctx->priv_data;
00266 uint8_t *out, *src;
00267 int i;
00268 int header;
00269 int blocksize;
00270 const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, NULL);
00271 int ret;
00272
00273 bytestream2_init(&ctx->g, avpkt->data, avpkt->size);
00274 if (ctx->pic.data[0])
00275 avctx->release_buffer(avctx, &ctx->pic);
00276
00277 ctx->pic.reference = 3;
00278 ctx->pic.buffer_hints = FF_BUFFER_HINTS_VALID;
00279 if ((ret = ff_get_buffer(avctx, &ctx->pic)) < 0) {
00280 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
00281 return ret;
00282 }
00283
00284 header = bytestream2_get_byte(&ctx->g);
00285
00286
00287 if (bytestream2_peek_byte(&ctx->g) == 127) {
00288 bytestream2_skip(&ctx->g, 3);
00289 for (i = 0; i < 127; i++) {
00290 ctx->pal[i + (header & 0x81)] = 0xFFU << 24 | bytestream2_get_be24(&ctx->g);
00291 bytestream2_skip(&ctx->g, 1);
00292 }
00293 bytestream2_seek(&ctx->g, -127 * 4 - 3, SEEK_CUR);
00294 }
00295
00296 if (header & KMVC_KEYFRAME) {
00297 ctx->pic.key_frame = 1;
00298 ctx->pic.pict_type = AV_PICTURE_TYPE_I;
00299 } else {
00300 ctx->pic.key_frame = 0;
00301 ctx->pic.pict_type = AV_PICTURE_TYPE_P;
00302 }
00303
00304 if (header & KMVC_PALETTE) {
00305 ctx->pic.palette_has_changed = 1;
00306
00307 for (i = 1; i <= ctx->palsize; i++) {
00308 ctx->pal[i] = 0xFFU << 24 | bytestream2_get_be24(&ctx->g);
00309 }
00310 }
00311
00312 if (pal) {
00313 ctx->pic.palette_has_changed = 1;
00314 memcpy(ctx->pal, pal, AVPALETTE_SIZE);
00315 }
00316
00317 if (ctx->setpal) {
00318 ctx->setpal = 0;
00319 ctx->pic.palette_has_changed = 1;
00320 }
00321
00322
00323 memcpy(ctx->pic.data[1], ctx->pal, 1024);
00324
00325 blocksize = bytestream2_get_byte(&ctx->g);
00326
00327 if (blocksize != 8 && blocksize != 127) {
00328 av_log(avctx, AV_LOG_ERROR, "Block size = %i\n", blocksize);
00329 return AVERROR_INVALIDDATA;
00330 }
00331 memset(ctx->cur, 0, 320 * 200);
00332 switch (header & KMVC_METHOD) {
00333 case 0:
00334 case 1:
00335 memcpy(ctx->cur, ctx->prev, 320 * 200);
00336 break;
00337 case 3:
00338 kmvc_decode_intra_8x8(ctx, avctx->width, avctx->height);
00339 break;
00340 case 4:
00341 kmvc_decode_inter_8x8(ctx, avctx->width, avctx->height);
00342 break;
00343 default:
00344 av_log(avctx, AV_LOG_ERROR, "Unknown compression method %i\n", header & KMVC_METHOD);
00345 return AVERROR_INVALIDDATA;
00346 }
00347
00348 out = ctx->pic.data[0];
00349 src = ctx->cur;
00350 for (i = 0; i < avctx->height; i++) {
00351 memcpy(out, src, avctx->width);
00352 src += 320;
00353 out += ctx->pic.linesize[0];
00354 }
00355
00356
00357 if (ctx->cur == ctx->frm0) {
00358 ctx->cur = ctx->frm1;
00359 ctx->prev = ctx->frm0;
00360 } else {
00361 ctx->cur = ctx->frm0;
00362 ctx->prev = ctx->frm1;
00363 }
00364
00365 *got_frame = 1;
00366 *(AVFrame *) data = ctx->pic;
00367
00368
00369 return avpkt->size;
00370 }
00371
00372
00373
00374
00375
00376
00377 static av_cold int decode_init(AVCodecContext * avctx)
00378 {
00379 KmvcContext *const c = avctx->priv_data;
00380 int i;
00381
00382 c->avctx = avctx;
00383
00384 if (avctx->width > 320 || avctx->height > 200) {
00385 av_log(avctx, AV_LOG_ERROR, "KMVC supports frames <= 320x200\n");
00386 return AVERROR_INVALIDDATA;
00387 }
00388
00389 c->frm0 = av_mallocz(320 * 200);
00390 c->frm1 = av_mallocz(320 * 200);
00391 c->cur = c->frm0;
00392 c->prev = c->frm1;
00393
00394 for (i = 0; i < 256; i++) {
00395 c->pal[i] = 0xFFU << 24 | i * 0x10101;
00396 }
00397
00398 if (avctx->extradata_size < 12) {
00399 av_log(avctx, AV_LOG_WARNING,
00400 "Extradata missing, decoding may not work properly...\n");
00401 c->palsize = 127;
00402 } else {
00403 c->palsize = AV_RL16(avctx->extradata + 10);
00404 if (c->palsize >= (unsigned)MAX_PALSIZE) {
00405 c->palsize = 127;
00406 av_log(avctx, AV_LOG_ERROR, "KMVC palette too large\n");
00407 return AVERROR_INVALIDDATA;
00408 }
00409 }
00410
00411 if (avctx->extradata_size == 1036) {
00412 uint8_t *src = avctx->extradata + 12;
00413 for (i = 0; i < 256; i++) {
00414 c->pal[i] = AV_RL32(src);
00415 src += 4;
00416 }
00417 c->setpal = 1;
00418 }
00419
00420 avcodec_get_frame_defaults(&c->pic);
00421 avctx->pix_fmt = AV_PIX_FMT_PAL8;
00422
00423 return 0;
00424 }
00425
00426
00427
00428
00429
00430
00431 static av_cold int decode_end(AVCodecContext * avctx)
00432 {
00433 KmvcContext *const c = avctx->priv_data;
00434
00435 av_freep(&c->frm0);
00436 av_freep(&c->frm1);
00437 if (c->pic.data[0])
00438 avctx->release_buffer(avctx, &c->pic);
00439
00440 return 0;
00441 }
00442
00443 AVCodec ff_kmvc_decoder = {
00444 .name = "kmvc",
00445 .type = AVMEDIA_TYPE_VIDEO,
00446 .id = AV_CODEC_ID_KMVC,
00447 .priv_data_size = sizeof(KmvcContext),
00448 .init = decode_init,
00449 .close = decode_end,
00450 .decode = decode_frame,
00451 .capabilities = CODEC_CAP_DR1,
00452 .long_name = NULL_IF_CONFIG_SMALL("Karl Morton's video codec"),
00453 };