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