Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  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.  */
  43. typedef 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.  
  54. typedef 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.  
  73. static 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.  
  162. static 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.  
  262. static 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.  */
  370. static 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.  
  416. AVCodec 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.