libavcodec/kmvc.c
Go to the documentation of this file.
00001 /*
00002  * KMVC decoder
00003  * Copyright (c) 2006 Konstantin Shishkov
00004  *
00005  * This file is part of FFmpeg.
00006  *
00007  * FFmpeg is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or (at your option) any later version.
00011  *
00012  * FFmpeg is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with FFmpeg; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
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  * Decoder context
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) {         // fill whole 8x8 block
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 {            // handle four 4x4 subblocks
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) {     // fill whole 4x4 block
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 {        // copy block from already decoded place
00106                             val = bytestream2_get_byte(&ctx->g);
00107                             mx = val & 0xF;
00108                             my = val >> 4;
00109                             for (j = 0; j < 16; j++)
00110                                 BLK(ctx->cur, l0x + (j & 3), l0y + (j >> 2)) =
00111                                     BLK(ctx->cur, l0x + (j & 3) - mx, l0y + (j >> 2) - my);
00112                         }
00113                     } else {    // descend to 2x2 sub-sub-blocks
00114                         for (j = 0; j < 4; j++) {
00115                             l1x = l0x + (j & 1) * 2;
00116                             l1y = l0y + (j & 2);
00117                             kmvc_getbit(bb, &ctx->g, res);
00118                             if (!res) {
00119                                 kmvc_getbit(bb, &ctx->g, res);
00120                                 if (!res) {     // fill whole 2x2 block
00121                                     val = bytestream2_get_byte(&ctx->g);
00122                                     BLK(ctx->cur, l1x, l1y) = val;
00123                                     BLK(ctx->cur, l1x + 1, l1y) = val;
00124                                     BLK(ctx->cur, l1x, l1y + 1) = val;
00125                                     BLK(ctx->cur, l1x + 1, l1y + 1) = val;
00126                                 } else {        // copy block from already decoded place
00127                                     val = bytestream2_get_byte(&ctx->g);
00128                                     mx = val & 0xF;
00129                                     my = val >> 4;
00130                                     BLK(ctx->cur, l1x, l1y) = BLK(ctx->cur, l1x - mx, l1y - my);
00131                                     BLK(ctx->cur, l1x + 1, l1y) =
00132                                         BLK(ctx->cur, l1x + 1 - mx, l1y - my);
00133                                     BLK(ctx->cur, l1x, l1y + 1) =
00134                                         BLK(ctx->cur, l1x - mx, l1y + 1 - my);
00135                                     BLK(ctx->cur, l1x + 1, l1y + 1) =
00136                                         BLK(ctx->cur, l1x + 1 - mx, l1y + 1 - my);
00137                                 }
00138                             } else {    // read values for block
00139                                 BLK(ctx->cur, l1x, l1y) = bytestream2_get_byte(&ctx->g);
00140                                 BLK(ctx->cur, l1x + 1, l1y) = bytestream2_get_byte(&ctx->g);
00141                                 BLK(ctx->cur, l1x, l1y + 1) = bytestream2_get_byte(&ctx->g);
00142                                 BLK(ctx->cur, l1x + 1, l1y + 1) = bytestream2_get_byte(&ctx->g);
00143                             }
00144                         }
00145                     }
00146                 }
00147             }
00148         }
00149 
00150     return 0;
00151 }
00152 
00153 static int kmvc_decode_inter_8x8(KmvcContext * ctx, int w, int h)
00154 {
00155     BitBuf bb;
00156     int res, val;
00157     int i, j;
00158     int bx, by;
00159     int l0x, l1x, l0y, l1y;
00160     int mx, my;
00161 
00162     kmvc_init_getbits(bb, &ctx->g);
00163 
00164     for (by = 0; by < h; by += 8)
00165         for (bx = 0; bx < w; bx += 8) {
00166             kmvc_getbit(bb, &ctx->g, res);
00167             if (!res) {
00168                 kmvc_getbit(bb, &ctx->g, res);
00169                 if (!res) {     // fill whole 8x8 block
00170                     if (!bytestream2_get_bytes_left(&ctx->g)) {
00171                         av_log(ctx->avctx, AV_LOG_ERROR, "Data overrun\n");
00172                         return AVERROR_INVALIDDATA;
00173                     }
00174                     val = bytestream2_get_byte(&ctx->g);
00175                     for (i = 0; i < 64; i++)
00176                         BLK(ctx->cur, bx + (i & 0x7), by + (i >> 3)) = val;
00177                 } else {        // copy block from previous frame
00178                     for (i = 0; i < 64; i++)
00179                         BLK(ctx->cur, bx + (i & 0x7), by + (i >> 3)) =
00180                             BLK(ctx->prev, bx + (i & 0x7), by + (i >> 3));
00181                 }
00182             } else {            // handle four 4x4 subblocks
00183                 if (!bytestream2_get_bytes_left(&ctx->g)) {
00184                     av_log(ctx->avctx, AV_LOG_ERROR, "Data overrun\n");
00185                     return AVERROR_INVALIDDATA;
00186                 }
00187                 for (i = 0; i < 4; i++) {
00188                     l0x = bx + (i & 1) * 4;
00189                     l0y = by + (i & 2) * 2;
00190                     kmvc_getbit(bb, &ctx->g, res);
00191                     if (!res) {
00192                         kmvc_getbit(bb, &ctx->g, res);
00193                         if (!res) {     // fill whole 4x4 block
00194                             val = bytestream2_get_byte(&ctx->g);
00195                             for (j = 0; j < 16; j++)
00196                                 BLK(ctx->cur, l0x + (j & 3), l0y + (j >> 2)) = val;
00197                         } else {        // copy block
00198                             val = bytestream2_get_byte(&ctx->g);
00199                             mx = (val & 0xF) - 8;
00200                             my = (val >> 4) - 8;
00201                             for (j = 0; j < 16; j++)
00202                                 BLK(ctx->cur, l0x + (j & 3), l0y + (j >> 2)) =
00203                                     BLK(ctx->prev, l0x + (j & 3) + mx, l0y + (j >> 2) + my);
00204                         }
00205                     } else {    // descend to 2x2 sub-sub-blocks
00206                         for (j = 0; j < 4; j++) {
00207                             l1x = l0x + (j & 1) * 2;
00208                             l1y = l0y + (j & 2);
00209                             kmvc_getbit(bb, &ctx->g, res);
00210                             if (!res) {
00211                                 kmvc_getbit(bb, &ctx->g, res);
00212                                 if (!res) {     // fill whole 2x2 block
00213                                     val = bytestream2_get_byte(&ctx->g);
00214                                     BLK(ctx->cur, l1x, l1y) = val;
00215                                     BLK(ctx->cur, l1x + 1, l1y) = val;
00216                                     BLK(ctx->cur, l1x, l1y + 1) = val;
00217                                     BLK(ctx->cur, l1x + 1, l1y + 1) = val;
00218                                 } else {        // copy block
00219                                     val = bytestream2_get_byte(&ctx->g);
00220                                     mx = (val & 0xF) - 8;
00221                                     my = (val >> 4) - 8;
00222                                     BLK(ctx->cur, l1x, l1y) = BLK(ctx->prev, l1x + mx, l1y + my);
00223                                     BLK(ctx->cur, l1x + 1, l1y) =
00224                                         BLK(ctx->prev, l1x + 1 + mx, l1y + my);
00225                                     BLK(ctx->cur, l1x, l1y + 1) =
00226                                         BLK(ctx->prev, l1x + mx, l1y + 1 + my);
00227                                     BLK(ctx->cur, l1x + 1, l1y + 1) =
00228                                         BLK(ctx->prev, l1x + 1 + mx, l1y + 1 + my);
00229                                 }
00230                             } else {    // read values for block
00231                                 BLK(ctx->cur, l1x, l1y) = bytestream2_get_byte(&ctx->g);
00232                                 BLK(ctx->cur, l1x + 1, l1y) = bytestream2_get_byte(&ctx->g);
00233                                 BLK(ctx->cur, l1x, l1y + 1) = bytestream2_get_byte(&ctx->g);
00234                                 BLK(ctx->cur, l1x + 1, l1y + 1) = bytestream2_get_byte(&ctx->g);
00235                             }
00236                         }
00237                     }
00238                 }
00239             }
00240         }
00241 
00242     return 0;
00243 }
00244 
00245 static int decode_frame(AVCodecContext * avctx, void *data, int *data_size, AVPacket *avpkt)
00246 {
00247     KmvcContext *const ctx = avctx->priv_data;
00248     uint8_t *out, *src;
00249     int i;
00250     int header;
00251     int blocksize;
00252     const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, NULL);
00253 
00254     bytestream2_init(&ctx->g, avpkt->data, avpkt->size);
00255     if (ctx->pic.data[0])
00256         avctx->release_buffer(avctx, &ctx->pic);
00257 
00258     ctx->pic.reference = 3;
00259     ctx->pic.buffer_hints = FF_BUFFER_HINTS_VALID;
00260     if (avctx->get_buffer(avctx, &ctx->pic) < 0) {
00261         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
00262         return -1;
00263     }
00264 
00265     header = bytestream2_get_byte(&ctx->g);
00266 
00267     /* blocksize 127 is really palette change event */
00268     if (bytestream2_peek_byte(&ctx->g) == 127) {
00269         bytestream2_skip(&ctx->g, 3);
00270         for (i = 0; i < 127; i++) {
00271             ctx->pal[i + (header & 0x81)] = 0xFFU << 24 | bytestream2_get_be24(&ctx->g);
00272             bytestream2_skip(&ctx->g, 1);
00273         }
00274         bytestream2_seek(&ctx->g, -127 * 4 - 3, SEEK_CUR);
00275     }
00276 
00277     if (header & KMVC_KEYFRAME) {
00278         ctx->pic.key_frame = 1;
00279         ctx->pic.pict_type = AV_PICTURE_TYPE_I;
00280     } else {
00281         ctx->pic.key_frame = 0;
00282         ctx->pic.pict_type = AV_PICTURE_TYPE_P;
00283     }
00284 
00285     if (header & KMVC_PALETTE) {
00286         ctx->pic.palette_has_changed = 1;
00287         // palette starts from index 1 and has 127 entries
00288         for (i = 1; i <= ctx->palsize; i++) {
00289             ctx->pal[i] = 0xFFU << 24 | bytestream2_get_be24(&ctx->g);
00290         }
00291     }
00292 
00293     if (pal) {
00294         ctx->pic.palette_has_changed = 1;
00295         memcpy(ctx->pal, pal, AVPALETTE_SIZE);
00296     }
00297 
00298     if (ctx->setpal) {
00299         ctx->setpal = 0;
00300         ctx->pic.palette_has_changed = 1;
00301     }
00302 
00303     /* make the palette available on the way out */
00304     memcpy(ctx->pic.data[1], ctx->pal, 1024);
00305 
00306     blocksize = bytestream2_get_byte(&ctx->g);
00307 
00308     if (blocksize != 8 && blocksize != 127) {
00309         av_log(avctx, AV_LOG_ERROR, "Block size = %i\n", blocksize);
00310         return -1;
00311     }
00312     memset(ctx->cur, 0, 320 * 200);
00313     switch (header & KMVC_METHOD) {
00314     case 0:
00315     case 1: // used in palette changed event
00316         memcpy(ctx->cur, ctx->prev, 320 * 200);
00317         break;
00318     case 3:
00319         kmvc_decode_intra_8x8(ctx, avctx->width, avctx->height);
00320         break;
00321     case 4:
00322         kmvc_decode_inter_8x8(ctx, avctx->width, avctx->height);
00323         break;
00324     default:
00325         av_log(avctx, AV_LOG_ERROR, "Unknown compression method %i\n", header & KMVC_METHOD);
00326         return -1;
00327     }
00328 
00329     out = ctx->pic.data[0];
00330     src = ctx->cur;
00331     for (i = 0; i < avctx->height; i++) {
00332         memcpy(out, src, avctx->width);
00333         src += 320;
00334         out += ctx->pic.linesize[0];
00335     }
00336 
00337     /* flip buffers */
00338     if (ctx->cur == ctx->frm0) {
00339         ctx->cur = ctx->frm1;
00340         ctx->prev = ctx->frm0;
00341     } else {
00342         ctx->cur = ctx->frm0;
00343         ctx->prev = ctx->frm1;
00344     }
00345 
00346     *data_size = sizeof(AVFrame);
00347     *(AVFrame *) data = ctx->pic;
00348 
00349     /* always report that the buffer was completely consumed */
00350     return avpkt->size;
00351 }
00352 
00353 
00354 
00355 /*
00356  * Init kmvc decoder
00357  */
00358 static av_cold int decode_init(AVCodecContext * avctx)
00359 {
00360     KmvcContext *const c = avctx->priv_data;
00361     int i;
00362 
00363     c->avctx = avctx;
00364 
00365     if (avctx->width > 320 || avctx->height > 200) {
00366         av_log(avctx, AV_LOG_ERROR, "KMVC supports frames <= 320x200\n");
00367         return -1;
00368     }
00369 
00370     c->frm0 = av_mallocz(320 * 200);
00371     c->frm1 = av_mallocz(320 * 200);
00372     c->cur = c->frm0;
00373     c->prev = c->frm1;
00374 
00375     for (i = 0; i < 256; i++) {
00376         c->pal[i] = 0xFF << 24 | i * 0x10101;
00377     }
00378 
00379     if (avctx->extradata_size < 12) {
00380         av_log(NULL, 0, "Extradata missing, decoding may not work properly...\n");
00381         c->palsize = 127;
00382     } else {
00383         c->palsize = AV_RL16(avctx->extradata + 10);
00384         if (c->palsize >= (unsigned)MAX_PALSIZE) {
00385             c->palsize = 127;
00386             av_log(avctx, AV_LOG_ERROR, "KMVC palette too large\n");
00387             return AVERROR_INVALIDDATA;
00388         }
00389     }
00390 
00391     if (avctx->extradata_size == 1036) {        // palette in extradata
00392         uint8_t *src = avctx->extradata + 12;
00393         for (i = 0; i < 256; i++) {
00394             c->pal[i] = AV_RL32(src);
00395             src += 4;
00396         }
00397         c->setpal = 1;
00398     }
00399 
00400     avcodec_get_frame_defaults(&c->pic);
00401     avctx->pix_fmt = PIX_FMT_PAL8;
00402 
00403     return 0;
00404 }
00405 
00406 
00407 
00408 /*
00409  * Uninit kmvc decoder
00410  */
00411 static av_cold int decode_end(AVCodecContext * avctx)
00412 {
00413     KmvcContext *const c = avctx->priv_data;
00414 
00415     av_freep(&c->frm0);
00416     av_freep(&c->frm1);
00417     if (c->pic.data[0])
00418         avctx->release_buffer(avctx, &c->pic);
00419 
00420     return 0;
00421 }
00422 
00423 AVCodec ff_kmvc_decoder = {
00424     .name           = "kmvc",
00425     .type           = AVMEDIA_TYPE_VIDEO,
00426     .id             = CODEC_ID_KMVC,
00427     .priv_data_size = sizeof(KmvcContext),
00428     .init           = decode_init,
00429     .close          = decode_end,
00430     .decode         = decode_frame,
00431     .capabilities   = CODEC_CAP_DR1,
00432     .long_name = NULL_IF_CONFIG_SMALL("Karl Morton's video codec"),
00433 };