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