[FFmpeg-soc] [soc]: r5523 - in indeo5: . TODO description indeo5.c indeo5data.h ivi_common.c ivi_common.h
maximum
subversion at mplayerhq.hu
Thu Dec 10 02:21:27 CET 2009
Author: maximum
Date: Thu Dec 10 02:21:27 2009
New Revision: 5523
Log:
indeo5 folder added.
Added:
indeo5/
indeo5/TODO
indeo5/description
indeo5/indeo5.c
indeo5/indeo5data.h
indeo5/ivi_common.c
indeo5/ivi_common.h
Added: indeo5/TODO
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ indeo5/TODO Thu Dec 10 02:21:27 2009 (r5523)
@@ -0,0 +1,5 @@
+Please read my comments named "description" BEFORE doing anything! Thanks!
+
+Some small steps needed to be completed in order to make FFmpeg able to decode indeo5 videos:
+
+* split the 5/3 wavelet synthesis filter out of the snow source (see snow.c:spatial_compose53i) and adapt it to indeo5. The indeo5's high-pass coefficients must be upscaled by -2 in this case before those can be passed to that filter.
Added: indeo5/description
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ indeo5/description Thu Dec 10 02:21:27 2009 (r5523)
@@ -0,0 +1,25 @@
+This directory contains indeo5 related files for FFmpeg.
+
+Description of the files:
+--------------------------
+
+Indeo5 docs:
+-------------
+
+There is a basic indeo5 documentation being currently in progress. It can be found here:
+http://wiki.multimedia.cx/index.php?title=Indeo_5
+
+Please be aware of the following important design specifics of the indeo5 codec:
+
+1. Indeo5 operates on the pixels in the range [-128...127]. It was made in order to make the values compatible with the slant transform which requires both negative and positive numbers. The conversions look like this:
+
+ encoder -> internal_pixel = pixel - 128;
+ decoder -> pixel = clip((internal_pixel + 128), 0, 255);
+
+2. The 5/3 wavelet filter used for splitting the signal into several bands requires at least 10-bit precision of the internal pixel values. Therefore my decoder operates completely on the 16-bit pixels by using the IDWTELEM data type. Only at the last step (output a plane) those pixels will be clipped to fit the 8-bit output values. This design requires special motion compensation routines operating on the IDWTELEM data type. The internal motion compensation routines (put_pixels stuff) cannot be used in this case!!!
+
+3. The 5/3 wavelet filter of indeo5 differs from the standard one in that it scales the high-pass coefficients by the value of -1/2. It should be possible to reuse the Snow's code (see snow.c:spatial_compose53i) which implements the same wavelet but upscale the indeo5 coefficients by -2 before calling this function. Maybe it will be possible to integrate the upscale step directly into this function...
+
+4. Please work with debugging features (see "IVI_DEBUG" in my code) enabled in order to ensure you don't break anything!
+
+For the further description please read the source or ask me...
Added: indeo5/indeo5.c
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ indeo5/indeo5.c Thu Dec 10 02:21:27 2009 (r5523)
@@ -0,0 +1,900 @@
+/*
+ * Indeo Video Interactive v5 compatible decoder
+ * Copyright (c) 2009 Maxim Poliakovski
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file libavcodec/indeo5.c
+ * This is a decoder for Indeo Video Interactive v5.
+ * Indeo5 data is usually transported within .avi or .mov files.
+ * Known FOURCCs: 'IV50'
+ */
+
+#define ALT_BITSTREAM_READER_LE
+#include "avcodec.h"
+#include "get_bits.h"
+#include "ivi_slant.h"
+#include "ivi_common.h"
+#include "indeo5data.h"
+
+#define IVI_DEBUG
+
+#define IVI5_FRAMETYPE_INTRA 0
+#define IVI5_FRAMETYPE_NULL 4
+
+#define IVI5_PIC_SIZE_ESC 15
+
+#define IVI5_IS_PROTECTED 0x20
+
+typedef struct {
+ GetBitContext gb;
+ AVFrame frame;
+ RVMapDesc rvmap_tabs[9]; ///< local changeable copy of the static rvmap tables
+ IVIPlaneDesc planes[3]; ///< color planes
+ const uint8_t *frame_data; ///< ptr to the input frame data
+ uint32_t frame_size; ///< frame size in bytes
+ uint32_t frame_type;
+ uint32_t prev_frame_type; ///< frame type of the previous frame
+ uint32_t frame_num;
+ uint32_t pic_hdr_size; ///< picture header size in bytes
+ uint8_t frame_flags;
+ uint16_t check_sum; ///< frame checksum
+
+ int16_t mb_huff_sel; ///< MB huffman table selector
+ IVIHuffDesc mb_huff_desc; ///< MB table descriptor associated with the selector above
+ VLC *mb_vlc; ///< ptr to the vlc table for decoding macroblock data
+ VLC mb_vlc_cust; ///< custom macroblock vlc table
+
+ uint16_t gop_hdr_size;
+ uint8_t gop_flags;
+ uint8_t is_scalable;
+ uint32_t lock_word;
+ IVIPicConfig pic_conf;
+#ifdef IVI_DEBUG
+ int32_t gop_num; ///< gop number
+#endif
+} IVI5DecContext;
+
+//! static vlc tables (initialized at startup)
+static VLC mb_vlc_tabs [8];
+static VLC blk_vlc_tabs[8];
+
+
+/**
+ * Decode indeo5 GOP (Group of pictures) header.
+ * This header is present in key frames only.
+ * It defines parameters for all frames in a GOP.
+ *
+ * @param ctx [in,out] ptr to the decoder context
+ * @param avctx [in] ptr to the AVCodecContext
+ * @return result code: 0 = OK, -1 = error
+ */
+static int decode_gop_header(IVI5DecContext *ctx, AVCodecContext *avctx)
+{
+ int result, i, p, tile_size, pic_size_indx, mb_size, blk_size, blk_size_changed = 0;
+ IVIBandDesc *band, *band1, *band2;
+ IVIPicConfig pic_conf;
+
+ ctx->gop_flags = get_bits(&ctx->gb, 8);
+
+ /* get size of the GOP header if present */
+ ctx->gop_hdr_size = (ctx->gop_flags & 1) ? get_bits(&ctx->gb, 16) : 0;
+
+ /* get 32-bit lock word in the case of password protected video */
+ if (ctx->gop_flags & IVI5_IS_PROTECTED)
+ ctx->lock_word = get_bits_long(&ctx->gb, 32);
+
+ /* decode tile size */
+ tile_size = (ctx->gop_flags & 0x40) ? 64 << get_bits(&ctx->gb, 2) : 0;
+ if (tile_size > 256) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid tile size: %d\n", tile_size);
+ return -1;
+ }
+
+ /* decode number of wavelet bands */
+ /* num_levels * 3 + 1 */
+ pic_conf.luma_bands = get_bits(&ctx->gb, 2) * 3 + 1;
+ pic_conf.chroma_bands = get_bits1(&ctx->gb) * 3 + 1;
+ ctx->is_scalable = pic_conf.luma_bands != 1 || pic_conf.chroma_bands != 1;
+ if (ctx->is_scalable && (pic_conf.luma_bands != 4 || pic_conf.chroma_bands != 1)) {
+ av_log(avctx, AV_LOG_ERROR, "Scalability: unsupported subdivision! Luma bands: %d, chroma bands: %d\n",
+ pic_conf.luma_bands, pic_conf.chroma_bands);
+ return -1;
+ }
+
+ /* decode picture size */
+ pic_size_indx = get_bits(&ctx->gb, 4);
+ if (pic_size_indx == IVI5_PIC_SIZE_ESC) {
+ pic_conf.pic_height = get_bits(&ctx->gb, 13);
+ pic_conf.pic_width = get_bits(&ctx->gb, 13);
+ } else {
+ pic_conf.pic_height = ivi5_common_pic_sizes[pic_size_indx * 2 + 1];
+ pic_conf.pic_width = ivi5_common_pic_sizes[pic_size_indx * 2 ];
+ }
+
+ /* check the subsampling format */
+ if (ctx->gop_flags & 2) {
+ av_log(avctx, AV_LOG_ERROR, "YV12 picture format not supported!\n");
+ return -1;
+ }
+
+ pic_conf.chroma_height = (pic_conf.pic_height + 3) >> 2;
+ pic_conf.chroma_width = (pic_conf.pic_width + 3) >> 2;
+
+ /* set tile size */
+ if (!tile_size) {
+ pic_conf.tile_height = pic_conf.pic_height;
+ pic_conf.tile_width = pic_conf.pic_width;
+ } else
+ pic_conf.tile_height = pic_conf.tile_width = tile_size;
+
+ /* check if picture layout was changed and reallocate buffers */
+ if (ivi_pic_config_cmp(&pic_conf, &ctx->pic_conf)) {
+ /* reallocate internal plane structures and buffers according with new picture layout */
+ result = ff_ivi_init_planes(ctx->planes, &pic_conf);
+ if (result) {
+ av_log(avctx, AV_LOG_ERROR, "Couldn't reallocate color planes!\n");
+ return -1;
+ }
+ ctx->pic_conf = pic_conf; /* remember the new picture layout */
+ blk_size_changed = 1; /* force reallocation of the internal structures */
+ }
+
+ for (p = 0; p <= 1; p++) {
+ for (i = 0; i < (!p ? pic_conf.luma_bands : pic_conf.chroma_bands); i++) {
+ band = &ctx->planes[p].bands[i]; /* select appropriate plane/band */
+
+ band->mc_resolution = get_bits1(&ctx->gb);
+
+ /* decode block and macroblock sizes */
+ mb_size = get_bits1(&ctx->gb);
+ blk_size = get_bits1(&ctx->gb) ? 4 : 8;
+ mb_size = blk_size << !mb_size;
+
+ blk_size_changed = mb_size != band->mb_size || blk_size != band->blk_size;
+ if (blk_size_changed) {
+ band->mb_size = mb_size;
+ band->blk_size = blk_size;
+ }
+
+ if (get_bits1(&ctx->gb)) {
+ av_log(avctx, AV_LOG_ERROR, "Extended transform info encountered!\n");
+ return -1;
+ }
+
+ /* select transform function and scan pattern according with plane and band number */
+ switch ((p << 2) + i) {
+ case 0:
+ band->inv_transform = ff_ivi_inverse_slant_8x8;
+ band->dc_transform = ff_ivi_dc_slant_2d;
+ band->scan = ivi5_scans8x8[0];
+ break;
+
+ case 1:
+ band->inv_transform = ff_ivi_row_slant8;
+ band->dc_transform = ff_ivi_dc_row_slant;
+ band->scan = ivi5_scans8x8[1];
+ break;
+
+ case 2:
+ band->inv_transform = ff_ivi_col_slant8;
+ band->dc_transform = ff_ivi_dc_col_slant;
+ band->scan = ivi5_scans8x8[2];
+ break;
+
+ case 3:
+ band->inv_transform = ff_ivi_put_pixels_8x8;
+ band->dc_transform = ff_ivi_put_dc_pixel_8x8;
+ band->scan = ivi5_scans8x8[2];
+ break;
+
+ case 4:
+ band->inv_transform = ff_ivi_inverse_slant_4x4;
+ band->dc_transform = ff_ivi_dc_slant_2d;
+ band->scan = ivi5_scan4x4;
+ break;
+ }
+
+ band->is_2d_trans = band->inv_transform == ff_ivi_inverse_slant_8x8 ||
+ band->inv_transform == ff_ivi_inverse_slant_4x4;
+
+ /* select transform functions according with plane and band number */
+ //band->inv_transform = !p ? ff_ivi_inverse_slant_8x8 : ff_ivi_inverse_slant_4x4;
+ //band->dc_transform = ff_ivi_dc_slant_2d;
+
+ /* select scan pattern for this band */
+ //band->scan = (!p) ? ivi5_scans8x8[0] : ivi5_scan4x4;
+
+ /* select dequant matrix according with plane and band number */
+ if (!p) {
+ band->quant_mat = (pic_conf.luma_bands > 1) ? i+1 : 0;
+ } else
+ band->quant_mat = 5;
+
+ if (get_bits(&ctx->gb, 2)) {
+ av_log(avctx, AV_LOG_ERROR, "End marker missing!\n");
+ return -1;
+ }
+ }
+ }
+
+ /* copy chroma parameters into the 2nd chroma plane */
+ for (i = 0; i < pic_conf.chroma_bands; i++) {
+ band1 = &ctx->planes[1].bands[i];
+ band2 = &ctx->planes[2].bands[i];
+
+ band2->width = band1->width;
+ band2->height = band1->height;
+ band2->mb_size = band1->mb_size;
+ band2->blk_size = band1->blk_size;
+ band2->mc_resolution = band1->mc_resolution;
+ band2->quant_mat = band1->quant_mat;
+ band2->scan = band1->scan;
+ band2->inv_transform = band1->inv_transform;
+ band2->dc_transform = band1->dc_transform;
+ band2->is_2d_trans = band1->is_2d_trans;
+ }
+
+ /* reallocate internal structures if needed */
+ if (blk_size_changed) {
+ result = ff_ivi_init_tiles(ctx->planes, pic_conf.tile_width, pic_conf.tile_height);
+ if (result) {
+ av_log(avctx, AV_LOG_ERROR, "Couldn't reallocate internal structures!\n");
+ return -1;
+ }
+ }
+
+ if (ctx->gop_flags & 8) {
+ if (get_bits(&ctx->gb, 3)) {
+ av_log(avctx, AV_LOG_ERROR, "Alignment bits are not zero!\n");
+ return -1;
+ }
+
+ if (get_bits1(&ctx->gb))
+ skip_bits_long(&ctx->gb, 24); /* skip transparency fill color */
+ }
+
+ align_get_bits(&ctx->gb);
+
+ skip_bits(&ctx->gb, 23); /* FIXME: unknown meaning */
+
+ if (get_bits1(&ctx->gb)) {
+ av_log(avctx, AV_LOG_ERROR, "GOP extension encountered!\n");
+ return -1;
+ }
+
+ align_get_bits(&ctx->gb);
+
+ return 0;
+}
+
+
+/**
+ * Skip a header extension.
+ *
+ * @param gb [in,out] the GetBit context
+ */
+static inline void skip_hdr_extension(GetBitContext *gb)
+{
+ int i, len;
+
+ do {
+ len = get_bits(gb, 8);
+ for (i = 0; i < len; i++) skip_bits(gb, 8);
+ } while(len);
+}
+
+
+/**
+ * Decode indeo5 picture header.
+ *
+ * @param ctx [in,out] ptr to the decoder context
+ * @param avctx [in] ptr to the AVCodecContext
+ * @return result code: 0 = OK, -1 = error
+ */
+static int decode_pic_hdr(IVI5DecContext *ctx, AVCodecContext *avctx)
+{
+ int result;
+ IVIHuffDesc new_huff;
+
+ /* check for valid picture start code */
+ if (get_bits(&ctx->gb, 5) != 0x1F) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid picture start code!\n");
+ return -1;
+ }
+
+ ctx->prev_frame_type = ctx->frame_type;
+ ctx->frame_type = get_bits(&ctx->gb, 3);
+ if (ctx->frame_type >= 5) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid frame type: %d \n", ctx->frame_type);
+ return -1;
+ }
+
+ ctx->frame_num = get_bits(&ctx->gb, 8);
+
+ if (ctx->frame_type == IVI5_FRAMETYPE_INTRA) {
+ if (decode_gop_header(ctx, avctx))
+ return -1;
+#ifdef IVI_DEBUG
+ ctx->gop_num++;
+#endif
+ }
+
+ if (ctx->frame_type != IVI5_FRAMETYPE_NULL) {
+ ctx->frame_flags = get_bits(&ctx->gb, 8);
+
+ /* get size of the picture header if present */
+ ctx->pic_hdr_size = (ctx->frame_flags & 1) ? get_bits_long(&ctx->gb, 24) : 0;
+
+ /* get the frame checksum if any */
+ ctx->check_sum = (ctx->frame_flags & 0x10) ? get_bits(&ctx->gb, 16) : 0;
+
+ /* skip unknown extension if any */
+ if (ctx->frame_flags & 0x20)
+ skip_hdr_extension(&ctx->gb); /* XXX: untested */
+
+ /* decode macroblock huffman codebook */
+ if (ctx->frame_flags & 0x40) {
+ ctx->mb_huff_sel = ff_ivi_dec_huff_desc(&ctx->gb, &new_huff);
+ if (ctx->mb_huff_sel != 7) {
+ ctx->mb_vlc = &mb_vlc_tabs[ctx->mb_huff_sel];
+ } else {
+ if (ff_ivi_huff_desc_cmp(&new_huff, &ctx->mb_huff_desc)) {
+ ff_ivi_huff_desc_copy(&ctx->mb_huff_desc, &new_huff);
+
+ if (ctx->mb_vlc_cust.table)
+ free_vlc(&ctx->mb_vlc_cust);
+ result = ff_ivi_create_huff_from_desc(&ctx->mb_huff_desc, &ctx->mb_vlc_cust, 0);
+ if (result) {
+ av_log(avctx, AV_LOG_ERROR, "Error while initializing custom macroblock vlc table!\n");
+ return -1;
+ }
+ }
+ ctx->mb_vlc = &ctx->mb_vlc_cust;
+ }
+ } else
+ ctx->mb_vlc = &mb_vlc_tabs[7]; /* select the default macroblock huffman table */
+
+ skip_bits(&ctx->gb, 3); /* FIXME: unknown meaning! */
+ }
+
+ align_get_bits(&ctx->gb);
+
+ return 0;
+}
+
+
+/**
+ * Decode indeo5 band header.
+ *
+ * @param ctx [in,out] ptr to the decoder context
+ * @param band [in,out] ptr to the band descriptor
+ * @param avctx [in] ptr to the AVCodecContext
+ * @return result code: 0 = OK, -1 = error
+ */
+static int decode_band_hdr(IVI5DecContext *ctx, IVIBandDesc *band, AVCodecContext *avctx)
+{
+ int i, result;
+ uint8_t band_flags;
+ //uint32_t band_data_size;
+ IVIHuffDesc new_huff;
+
+ band_flags = get_bits(&ctx->gb, 8);
+
+ if (band_flags & 1) {
+ band->is_empty = 1; /* this band is empty (there is no coded data) */
+ return 0;
+ }
+
+ band->data_size = (ctx->frame_flags & 0x80) ? get_bits_long(&ctx->gb, 24) : 0;
+
+ band->inherit_mv = band_flags & 2;
+ band->inherit_qdelta = band_flags & 8;
+ band->qdelta_present = band_flags & 4;
+ if (!band->qdelta_present) band->inherit_qdelta = 1;
+
+ /* decode rvmap probability corrections if any */
+ band->num_corr = 0; /* there is no corrections */
+ if (band_flags & 0x10) {
+ band->num_corr = get_bits(&ctx->gb, 8); /* get number of correction pairs */
+ if (band->num_corr > 61) {
+ av_log(avctx, AV_LOG_ERROR, "Too many corrections: %d\n", band->num_corr);
+ return -1;
+ }
+
+ /* read correction pairs */
+ for (i = 0; i < band->num_corr * 2; i++)
+ band->corr[i] = get_bits(&ctx->gb, 8);
+ }
+
+ /* select appropriate rvmap table for this band */
+ band->rvmap_sel = (band_flags & 0x40) ? get_bits(&ctx->gb, 3) : 8;
+
+ /* decode block huffman codebook */
+ if (band_flags & 0x80) {
+ band->huff_sel = ff_ivi_dec_huff_desc(&ctx->gb, &new_huff);
+ if (band->huff_sel != 7) {
+ band->blk_vlc = &blk_vlc_tabs[band->huff_sel];
+ } else {
+ if (ff_ivi_huff_desc_cmp(&new_huff, &band->huff_desc)) {
+ ff_ivi_huff_desc_copy(&band->huff_desc, &new_huff);
+
+ if (band->blk_vlc_cust.table)
+ free_vlc(&band->blk_vlc_cust);
+ result = ff_ivi_create_huff_from_desc(&band->huff_desc, &band->blk_vlc_cust, 0);
+ if (result) {
+ av_log(avctx, AV_LOG_ERROR, "Error while initializing custom block vlc table!\n");
+ return -1;
+ }
+ }
+ band->blk_vlc = &band->blk_vlc_cust;
+ }
+ } else
+ band->blk_vlc = &blk_vlc_tabs[7]; /* select the default macroblock huffman table */
+
+ /* get band checksum if present */
+#ifdef IVI_DEBUG
+ if (get_bits1(&ctx->gb)) {
+ band->checksum = get_bits(&ctx->gb, 16);
+ band->checksum_present = 1;
+ } else
+ band->checksum_present = 0;
+#else
+ if (get_bits1(&ctx->gb))
+ skip_bits(&ctx->gb, 16); /* ignore band checksum */
+#endif
+
+ band->glob_quant = get_bits(&ctx->gb, 5); /* band global quant */
+
+ /* skip unknown extension if any */
+ if (band_flags & 0x20) { /* XXX: untested */
+ align_get_bits(&ctx->gb);
+ skip_hdr_extension(&ctx->gb);
+ }
+
+ align_get_bits(&ctx->gb);
+
+ return 0;
+}
+
+
+/**
+ * Decode info (block type, cbp, quant delta, motion vector)
+ * for all macroblocks in the current tile.
+ *
+ * @param ctx [in,out] ptr to the decoder context
+ * @param band [in,out] ptr to the band descriptor
+ * @param tile [in,out] ptr to the tile descriptor
+ * @param avctx [in] ptr to the AVCodecContext
+ * @return result code: 0 = OK, -1 = error
+ */
+static int decode_mb_info(IVI5DecContext *ctx, IVIBandDesc *band, IVITile *tile,
+ AVCodecContext *avctx)
+{
+ int x, y, mv_x, mv_y, mv_delta, offs, mb_offset, mv_scale, blks_per_mb;
+ IVIMbInfo *mb, *ref_mb;
+ int row_offset = band->mb_size * band->pitch;
+
+ mb = tile->mbs;
+ ref_mb = tile->ref_mbs;
+ offs = tile->ypos * band->pitch + tile->xpos;
+
+ /* factor for motion vector scaling */
+ mv_scale = (ctx->planes[0].bands[0].mb_size >> 3) - (band->mb_size >> 3);
+ mv_x = mv_y = 0;
+
+ for (y = tile->ypos; y < (tile->ypos + tile->height); y += band->mb_size) {
+ mb_offset = offs;
+
+ for (x = tile->xpos; x < (tile->xpos + tile->width); x += band->mb_size) {
+ mb->xpos = x;
+ mb->ypos = y;
+ mb->buf_offs = mb_offset;
+
+ if (get_bits1(&ctx->gb)) {
+ if (ctx->frame_type == IVI5_FRAMETYPE_INTRA) {
+ av_log(avctx, AV_LOG_ERROR, "Empty macroblock in an INTRA picture!\n");
+ return -1;
+ }
+ mb->type = 1; /* empty macroblocks are always INTER */
+ mb->cbp = 0; /* all blocks are empty */
+
+ mb->q_delta = 0;
+ if (!band->plane && !band->band_num && (ctx->frame_flags & 8)) {
+ mb->q_delta = get_vlc2(&ctx->gb, ctx->mb_vlc->table, IVI_VLC_BITS, 1);
+ mb->q_delta = IVI_TOSIGNED(mb->q_delta);
+ }
+
+ mb->mv_x = mb->mv_y = 0; /* no motion vector coded */
+ if (band->inherit_mv){
+ /* motion vector inheritance */
+ switch (mv_scale) {
+ case 0:
+ mb->mv_x = ref_mb->mv_x;
+ mb->mv_y = ref_mb->mv_y;
+ break;
+ case 1:
+ mb->mv_x = IVI_MV_DIV2(ref_mb->mv_x);
+ mb->mv_y = IVI_MV_DIV2(ref_mb->mv_y);
+ break;
+ case 2:
+ mb->mv_x = IVI_MV_DIV4(ref_mb->mv_x);
+ mb->mv_y = IVI_MV_DIV4(ref_mb->mv_y);
+ break;
+ }
+ }
+ } else {
+ if (band->inherit_mv) {
+ mb->type = ref_mb->type; /* copy mb_type from corresponding reference mb */
+ } else if (ctx->frame_type == IVI5_FRAMETYPE_INTRA) {
+ mb->type = 0; /* mb_type is always INTRA for intra-frames */
+ } else
+ mb->type = get_bits1(&ctx->gb); /* get mb_type from bitstream */
+
+ /* decode cbp (coded block pattern) */
+ blks_per_mb = band->mb_size != band->blk_size ? 4 : 1;
+ mb->cbp = get_bits(&ctx->gb, blks_per_mb);
+
+ /* decode quant delta */
+ mb->q_delta = 0;
+ if (band->qdelta_present) {
+ if (band->inherit_qdelta) {
+ if (ref_mb) mb->q_delta = ref_mb->q_delta;
+ } else if (mb->cbp || (!band->plane && !band->band_num && (ctx->frame_flags & 8))) {
+ mb->q_delta = get_vlc2(&ctx->gb, ctx->mb_vlc->table, IVI_VLC_BITS, 1);
+ mb->q_delta = IVI_TOSIGNED(mb->q_delta);
+ }
+ }
+
+ /* decode motion vector */
+ if (!mb->type) {
+ mb->mv_x = mb->mv_y = 0; /* there is no motion vector in intra-macroblocks */
+ } else {
+ if (band->inherit_mv){
+ /* motion vector inheritance */
+ switch (mv_scale) {
+ case 0:
+ mb->mv_x = ref_mb->mv_x;
+ mb->mv_y = ref_mb->mv_y;
+ break;
+ case 1:
+ mb->mv_x = IVI_MV_DIV2(ref_mb->mv_x);
+ mb->mv_y = IVI_MV_DIV2(ref_mb->mv_y);
+ break;
+ case 2:
+ mb->mv_x = IVI_MV_DIV4(ref_mb->mv_x);
+ mb->mv_y = IVI_MV_DIV4(ref_mb->mv_y);
+ break;
+ }
+ } else {
+ /* decode motion vector deltas */
+ mv_delta = get_vlc2(&ctx->gb, ctx->mb_vlc->table, IVI_VLC_BITS, 1);
+ mv_y += IVI_TOSIGNED(mv_delta);
+ mv_delta = get_vlc2(&ctx->gb, ctx->mb_vlc->table, IVI_VLC_BITS, 1);
+ mv_x += IVI_TOSIGNED(mv_delta);
+ mb->mv_x = mv_x;
+ mb->mv_y = mv_y;
+ }
+ }
+ }
+
+ mb++;
+ if (ref_mb)
+ ref_mb++;
+ mb_offset += band->mb_size;
+ } // for x
+
+ offs += row_offset;
+ } // for y
+
+ align_get_bits(&ctx->gb);
+
+ return 0;
+}
+
+
+/**
+ * Decode an indeo5 band.
+ *
+ * @param ctx [in,out] ptr to the decoder context
+ * @param band [in,out] ptr to the band descriptor
+ * @param avctx [in] ptr to the AVCodecContext
+ * @return result code: 0 = OK, -1 = error
+ */
+static int decode_band(IVI5DecContext *ctx, int plane_num, IVIBandDesc *band, AVCodecContext *avctx)
+{
+ int result, i, t, idx1, idx2;
+ IVITile *tile;
+#ifdef IVI_DEBUG
+ uint16_t chksum;
+#endif
+
+ /* setup buffer pointers according with the buffer switch */
+ if (ctx->planes[plane_num].buf_switch) {
+ band->buf = band->buf2;
+ band->ref_buf = band->buf1;
+ } else {
+ band->buf = band->buf1;
+ band->ref_buf = band->buf2;
+ }
+
+ /* get the starting position of the band data */
+ band->data_ptr = ctx->frame_data + (get_bits_count(&ctx->gb) >> 3);
+
+ /* decode band header */
+ result = decode_band_hdr(ctx, band, avctx);
+ if (result) {
+ av_log(avctx, AV_LOG_ERROR, "Error while decoding band header: %d\n", result);
+ return -1;
+ }
+
+ if (band->is_empty) {
+ av_log(avctx, AV_LOG_ERROR, "Empty band encountered!\n");
+ return -1;
+ }
+
+ band->rv_map = &ctx->rvmap_tabs[band->rvmap_sel];
+
+ /* apply corrections to the selected rvmap table if present */
+ for (i = 0; i < band->num_corr; i++) {
+ idx1 = band->corr[i*2];
+ idx2 = band->corr[i*2+1];
+ FFSWAP(uint8_t, band->rv_map->runtab[idx1], band->rv_map->runtab[idx2]);
+ FFSWAP(int16_t, band->rv_map->valtab[idx1], band->rv_map->valtab[idx2]);
+ }
+
+ for (t = 0; t < band->num_tiles; t++) {
+ tile = &band->tiles[t];
+
+ /* check for empty tiles */
+ tile->is_empty = get_bits1(&ctx->gb);
+ if (tile->is_empty) {
+ ff_ivi_process_empty_tile(avctx, band, tile, (ctx->planes[0].bands[0].mb_size >> 3) - (band->mb_size >> 3));
+ align_get_bits(&ctx->gb);
+ } else { /* decode non-empty tiles */
+ tile->data_size = ff_ivi_dec_tile_data_size(&ctx->gb); /* get tile data length */
+
+ result = decode_mb_info(ctx, band, tile, avctx);
+ if (result < 0)
+ break;
+
+ /* select appropriate dequant matrix */
+ if (band->blk_size == 8) {
+ band->intra_base = &ivi5_base_quant_8x8_intra[band->quant_mat][0];
+ band->inter_base = &ivi5_base_quant_8x8_inter[band->quant_mat][0];
+ band->intra_scale = &ivi5_scale_quant_8x8_intra[band->quant_mat][0];
+ band->inter_scale = &ivi5_scale_quant_8x8_inter[band->quant_mat][0];
+ } else {
+ band->intra_base = ivi5_base_quant_4x4_intra;
+ band->inter_base = ivi5_base_quant_4x4_inter;
+ band->intra_scale = ivi5_scale_quant_4x4_intra;
+ band->inter_scale = ivi5_scale_quant_4x4_inter;
+ }
+
+ result = ff_ivi_decode_blocks(&ctx->gb, band, tile);
+ if (result < 0) {
+ av_log(avctx, AV_LOG_ERROR, "Corrupted blocks data encountered!\n");
+ break;
+ }
+ }
+ } // for t
+
+ /* restore the selected rvmap table by applying its corrections in reverse order */
+ for (i = band->num_corr-1; i >= 0; i--) {
+ idx1 = band->corr[i*2];
+ idx2 = band->corr[i*2+1];
+ FFSWAP(uint8_t, band->rv_map->runtab[idx1], band->rv_map->runtab[idx2]);
+ FFSWAP(int16_t, band->rv_map->valtab[idx1], band->rv_map->valtab[idx2]);
+ }
+
+#ifdef IVI_DEBUG
+ if (band->checksum_present) {
+ chksum = ivi_calc_band_checksum(band);
+ if (chksum != band->checksum) {
+ av_log(avctx,AV_LOG_ERROR,"Band checksum mismatch! Plane %d, band %d, received: %x, calculated: %x\n",
+ band->plane, band->band_num, band->checksum, chksum);
+ }
+ }
+#endif
+
+ return result;
+}
+
+
+/**
+ * Switch buffers.
+ *
+ * @param ctx [in,out] ptr to the decoder context
+ * @param avctx [in] ptr to the AVCodecContext
+ */
+static void switch_buffers(IVI5DecContext *ctx, AVCodecContext *avctx)
+{
+ int p;
+ IVIPlaneDesc *plane;
+
+ for (p = 0; p < 3; p++) {
+ plane = &ctx->planes[p];
+
+ switch (ctx->frame_type) {
+ case IVI5_FRAMETYPE_INTRA:
+ plane->buf_switch = 0;
+ break;
+ case 1:
+ if (ctx->prev_frame_type != 3)
+ plane->buf_switch ^= 1; /* swap buffers only if there is no frame of the type 3 */
+ break;
+ case 2:
+ plane->buf_switch ^= 1;
+ break;
+ case 3:
+ plane->buf_switch ^= 1;
+ break;
+ case IVI5_FRAMETYPE_NULL:
+ return;
+ default:
+ av_log(avctx, AV_LOG_ERROR, "unsupported frame type: %d\n", ctx->frame_type);
+ }
+
+ //if (plane->num_bands == 1) {
+ // plane->bands[0].buf = (plane->buf_switch) ? plane->buf2 : plane->buf1;
+ // plane->bands[0].ref_buf = (plane->buf_switch) ? plane->buf1 : plane->buf2;
+ //}
+ }
+}
+
+
+/**
+ * indeo5 decoder initializations
+ */
+static av_cold int decode_init(AVCodecContext *avctx)
+{
+ IVI5DecContext *ctx = avctx->priv_data;
+ int i, result;
+
+ /* initialize static vlc tables for macroblock/block signals */
+ for (i = 0; i < 8; i++) {
+ ff_ivi_create_huff_from_desc(&ff_ivi_mb_huff_desc[i], &mb_vlc_tabs[i], 1);
+ ff_ivi_create_huff_from_desc(&ff_ivi_blk_huff_desc[i], &blk_vlc_tabs[i], 1);
+ }
+
+ /* copy rvmap tables in our context so we can apply changes to them */
+ memcpy(ctx->rvmap_tabs, ff_ivi_rvmap_tabs, sizeof(ff_ivi_rvmap_tabs));
+
+ /* set the initial picture layout according with the basic profile:
+ there is only one band per plane (no scalability), only one tile (no local decoding)
+ and picture format = YVU9 */
+ ctx->pic_conf.pic_width = avctx->width;
+ ctx->pic_conf.pic_height = avctx->height;
+ ctx->pic_conf.chroma_width = (avctx->width + 3) >> 2;
+ ctx->pic_conf.chroma_height = (avctx->height + 3) >> 2;
+ ctx->pic_conf.tile_width = avctx->width;
+ ctx->pic_conf.tile_height = avctx->height;
+ ctx->pic_conf.luma_bands = ctx->pic_conf.chroma_bands = 1;
+
+ /* allocate and initialize indeo5 internal structures */
+ result = ff_ivi_init_planes(ctx->planes, &ctx->pic_conf);
+ if (result) {
+ av_log(avctx, AV_LOG_ERROR, "Couldn't allocate color planes!\n");
+ return -1;
+ }
+
+#ifdef IVI_DEBUG
+ ctx->gop_num = -1;
+#endif
+
+ /* needed here! Otherwise "avctx->get_buffer" won't be initialized!!! */
+ avctx->pix_fmt = PIX_FMT_YUV410P;
+
+ return 0;
+}
+
+
+/**
+ * main decoder function
+ */
+static int decode_frame(AVCodecContext *avctx, void *data, int *data_size,
+ AVPacket *avpkt)
+{
+ IVI5DecContext *ctx = avctx->priv_data;
+ const uint8_t *buf = avpkt->data;
+ int buf_size = avpkt->size;
+ int result, p, b;
+
+ init_get_bits(&ctx->gb, buf, buf_size * 8);
+ ctx->frame_data = buf;
+ ctx->frame_size = buf_size;
+
+ result = decode_pic_hdr(ctx, avctx);
+ if (result) {
+ av_log(avctx, AV_LOG_ERROR, "Error while decoding picture header: %d\n", result);
+ return -1;
+ }
+
+ if (ctx->gop_flags & IVI5_IS_PROTECTED)
+ return -1;
+
+ switch_buffers(ctx, avctx);
+
+ if (ctx->gop_flags & IVI5_IS_PROTECTED) {
+ av_log(avctx, AV_LOG_ERROR, "Protected clip!\n");
+ return -1;
+ }
+
+ //START_TIMER;
+
+ if (ctx->frame_type == IVI5_FRAMETYPE_NULL) {
+ ctx->frame_type = ctx->prev_frame_type;
+ } else {
+ for (p = 0; p < 3; p++) {
+ for (b = 0; b < ctx->planes[p].num_bands; b++) {
+ result = decode_band(ctx, p, &ctx->planes[p].bands[b], avctx);
+ if (result) {
+ av_log(avctx, AV_LOG_ERROR, "Error while decoding band: %d, plane: %d\n", b, p);
+ return -1;
+ }
+ }
+ }
+ }
+
+ //STOP_TIMER("decode_planes");
+
+ if (ctx->frame.data[0])
+ avctx->release_buffer(avctx, &ctx->frame);
+
+ ctx->frame.reference = 0;
+ if (avctx->get_buffer(avctx, &ctx->frame) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+ return -1;
+ }
+
+ ff_ivi_output_plane(&ctx->planes[0], ctx->frame.data[0], ctx->frame.linesize[0]);
+ ff_ivi_output_plane(&ctx->planes[2], ctx->frame.data[1], ctx->frame.linesize[1]);
+ ff_ivi_output_plane(&ctx->planes[1], ctx->frame.data[2], ctx->frame.linesize[2]);
+
+ *data_size = sizeof(AVFrame);
+ *(AVFrame*)data = ctx->frame;
+
+ return buf_size;
+}
+
+
+/**
+ * indeo5 free function
+ */
+static av_cold int decode_close(AVCodecContext *avctx)
+{
+ IVI5DecContext *ctx = avctx->priv_data;
+
+ /* free allocated decoder buffers */
+ ff_ivi_free_buffers(&ctx->planes[0]);
+
+ return 0;
+}
+
+
+AVCodec indeo5_decoder = {
+ .name = "indeo5",
+ .type = CODEC_TYPE_VIDEO,
+ .id = CODEC_ID_INDEO5,
+ .priv_data_size = sizeof(IVI5DecContext),
+ .init = decode_init,
+ .close = decode_close,
+ .decode = decode_frame,
+ .long_name = NULL_IF_CONFIG_SMALL("Intel Indeo Video Interactive 5"),
+};
Added: indeo5/indeo5data.h
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ indeo5/indeo5data.h Thu Dec 10 02:21:27 2009 (r5523)
@@ -0,0 +1,188 @@
+/*
+ * Indeo Video Interactive 5 compatible decoder
+ * Copyright (c) 2009 Maxim Poliakovski
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file libavcodec/indeo5data.h
+ * This file contains data needed for the Indeo5 decoder.
+ */
+
+#ifndef AVCODEC_INDEO5DATA_H
+#define AVCODEC_INDEO5DATA_H
+
+#include <stdint.h>
+
+/**
+ * standard picture dimensions (width, height)
+ */
+static uint16_t ivi5_common_pic_sizes[30] = {640, 480, 320, 240, 160, 120, 704, 480, 352, 240, 352, 288, 176, 144,
+ 240, 180, 640, 240, 704, 240, 80, 60, 88, 72, 0, 0, 0, 0, 0, 0};
+
+
+/**
+ * indeo5 8x8 scan (zigzag) patterns
+ */
+static const uint8_t ivi5_scans8x8[3][64] = {
+ {0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5,
+ 12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28,
+ 35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51,
+ 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63
+ },
+ {0, 8, 16, 24, 32, 40, 48, 56, 1, 9, 17, 25, 33, 41, 49, 57,
+ 2, 10, 18, 26, 34, 42, 50, 58, 3, 11, 19, 27, 35, 43, 51, 59,
+ 4, 12, 20, 28, 36, 44, 52, 60, 5, 13, 21, 29, 37, 45, 53, 61,
+ 6, 14, 22, 30, 38, 46, 54, 62, 7, 15, 23, 31, 39, 47, 55, 63
+ },
+ {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63
+ }
+};
+
+/**
+ * indeo5 4x4 scan (zigzag) pattern
+ */
+static const uint8_t ivi5_scan4x4[16] = {
+ 0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, 10, 7, 11, 14, 15
+};
+
+
+/**
+ * indeo5 dequantization matrixes consist of two tables: base table and scale table.
+ * The base table defines the dequantization matrix itself and the scale table tells how
+ * this matrix should be scaled for a particular quant level (0...24).
+ *
+ * ivi5_base_quant_bbb_ttt - base tables for block size 'bbb' of type 'ttt'
+ * ivi5_scale_quant_bbb_ttt - scale tables for block size 'bbb' of type 'ttt'
+ */
+static const uint8_t ivi5_base_quant_8x8_inter[5][64] = {
+ {0x13, 0x1d, 0x1f, 0x23, 0x25, 0x27, 0x29, 0x2d, 0x1d, 0x1f, 0x21, 0x23, 0x25, 0x27, 0x2b, 0x2f,
+ 0x1f, 0x21, 0x23, 0x24, 0x26, 0x29, 0x2d, 0x31, 0x23, 0x23, 0x24, 0x25, 0x27, 0x2b, 0x2f, 0x33,
+ 0x25, 0x25, 0x26, 0x27, 0x29, 0x2d, 0x31, 0x35, 0x27, 0x27, 0x29, 0x2b, 0x2d, 0x2f, 0x33, 0x37,
+ 0x29, 0x2b, 0x2d, 0x2f, 0x31, 0x33, 0x35, 0x39, 0x2d, 0x2f, 0x31, 0x33, 0x35, 0x37, 0x39, 0x3b
+ },
+ {0x13, 0x1d, 0x1f, 0x23, 0x25, 0x27, 0x29, 0x2d, 0x1d, 0x1f, 0x21, 0x23, 0x25, 0x27, 0x2b, 0x2f,
+ 0x1f, 0x21, 0x23, 0x24, 0x26, 0x29, 0x2d, 0x31, 0x23, 0x23, 0x24, 0x25, 0x27, 0x2b, 0x2f, 0x33,
+ 0x25, 0x25, 0x26, 0x27, 0x29, 0x2d, 0x31, 0x35, 0x27, 0x27, 0x29, 0x2b, 0x2d, 0x2f, 0x33, 0x37,
+ 0x29, 0x2b, 0x2d, 0x2f, 0x31, 0x33, 0x35, 0x39, 0x2d, 0x2f, 0x31, 0x33, 0x35, 0x37, 0x39, 0x3b
+ },
+ {0x27, 0x55, 0x79, 0x6a, 0x6f, 0x61, 0x6b, 0x61, 0x27, 0x55, 0x79, 0x6a, 0x6f, 0x61, 0x6b, 0x61,
+ 0x27, 0x55, 0x79, 0x6a, 0x6f, 0x61, 0x6b, 0x61, 0x27, 0x55, 0x79, 0x6a, 0x6f, 0x61, 0x6b, 0x61,
+ 0x27, 0x55, 0x79, 0x6a, 0x6f, 0x61, 0x6b, 0x61, 0x27, 0x55, 0x79, 0x6a, 0x6f, 0x61, 0x6b, 0x61,
+ 0x27, 0x55, 0x79, 0x6a, 0x6f, 0x61, 0x6b, 0x61, 0x27, 0x55, 0x79, 0x6a, 0x6f, 0x61, 0x6b, 0x61
+ },
+ {0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+ 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
+ 0x6b, 0x6b, 0x6b, 0x6b, 0x6b, 0x6b, 0x6b, 0x6b, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61
+ },
+ {0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
+ 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
+ 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
+ 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f
+ }
+};
+
+static const uint8_t ivi5_base_quant_8x8_intra[5][64] = {
+ {0x0d, 0x17, 0x1b, 0x21, 0x23, 0x25, 0x27, 0x2d, 0x17, 0x19, 0x1f, 0x21, 0x23, 0x27, 0x2b, 0x35,
+ 0x1b, 0x1f, 0x1f, 0x22, 0x25, 0x2a, 0x33, 0x39, 0x21, 0x21, 0x22, 0x25, 0x29, 0x31, 0x36, 0x3d,
+ 0x23, 0x23, 0x25, 0x29, 0x2f, 0x33, 0x39, 0x47, 0x25, 0x27, 0x2a, 0x31, 0x33, 0x37, 0x43, 0x53,
+ 0x27, 0x2b, 0x33, 0x36, 0x39, 0x43, 0x4d, 0x65, 0x2d, 0x35, 0x39, 0x3d, 0x47, 0x53, 0x65, 0x7f
+ },
+ {0x13, 0x1d, 0x1f, 0x23, 0x25, 0x27, 0x29, 0x2d, 0x1d, 0x1f, 0x21, 0x23, 0x25, 0x27, 0x2b, 0x2f,
+ 0x1f, 0x21, 0x23, 0x24, 0x26, 0x29, 0x2d, 0x31, 0x23, 0x23, 0x24, 0x25, 0x27, 0x2b, 0x2f, 0x33,
+ 0x25, 0x25, 0x26, 0x27, 0x29, 0x2d, 0x31, 0x35, 0x27, 0x27, 0x29, 0x2b, 0x2d, 0x2f, 0x33, 0x37,
+ 0x29, 0x2b, 0x2d, 0x2f, 0x31, 0x33, 0x35, 0x39, 0x2d, 0x2f, 0x31, 0x33, 0x35, 0x37, 0x39, 0x3b
+ },
+ {0x27, 0x55, 0x79, 0x6a, 0x6f, 0x61, 0x6b, 0x61, 0x27, 0x55, 0x79, 0x6a, 0x6f, 0x61, 0x6b, 0x61,
+ 0x27, 0x55, 0x79, 0x6a, 0x6f, 0x61, 0x6b, 0x61, 0x27, 0x55, 0x79, 0x6a, 0x6f, 0x61, 0x6b, 0x61,
+ 0x27, 0x55, 0x79, 0x6a, 0x6f, 0x61, 0x6b, 0x61, 0x27, 0x55, 0x79, 0x6a, 0x6f, 0x61, 0x6b, 0x61,
+ 0x27, 0x55, 0x79, 0x6a, 0x6f, 0x61, 0x6b, 0x61, 0x27, 0x55, 0x79, 0x6a, 0x6f, 0x61, 0x6b, 0x61
+ },
+ {0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+ 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a,
+ 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
+ 0x6b, 0x6b, 0x6b, 0x6b, 0x6b, 0x6b, 0x6b, 0x6b, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61
+ },
+ {0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
+ 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
+ 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
+ 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f
+ }
+};
+
+static const uint8_t ivi5_base_quant_4x4_inter[16] = {
+ 0x0f, 0x1f, 0x25, 0x29, 0x1f, 0x25, 0x29, 0x2b, 0x25, 0x29, 0x2b, 0x2f, 0x29, 0x2b, 0x2f, 0x33
+};
+
+static const uint8_t ivi5_base_quant_4x4_intra[16] = {
+ 0x0f, 0x1f, 0x25, 0x29, 0x1f, 0x25, 0x29, 0x2f, 0x25, 0x29, 0x2f, 0x3d, 0x29, 0x2f, 0x3d, 0x49
+};
+
+
+static const uint8_t ivi5_scale_quant_8x8_inter[5][24] = {
+ {0x0b, 0x11, 0x13, 0x14, 0x15, 0x16, 0x18, 0x1a, 0x1b, 0x1d, 0x20, 0x22,
+ 0x23, 0x25, 0x28, 0x2a, 0x2e, 0x32, 0x35, 0x39, 0x3d, 0x41, 0x44, 0x4a,
+ },
+ {0x07, 0x14, 0x16, 0x18, 0x1b, 0x1e, 0x22, 0x25, 0x29, 0x2d, 0x31, 0x35,
+ 0x3a, 0x3f, 0x44, 0x4a, 0x50, 0x56, 0x5c, 0x63, 0x6a, 0x71, 0x78, 0x7e,
+ },
+ {0x15, 0x25, 0x28, 0x2d, 0x30, 0x34, 0x3a, 0x3d, 0x42, 0x48, 0x4c, 0x51,
+ 0x56, 0x5b, 0x60, 0x65, 0x6b, 0x70, 0x76, 0x7c, 0x82, 0x88, 0x8f, 0x97,
+ },
+ {0x13, 0x1f, 0x20, 0x22, 0x25, 0x28, 0x2b, 0x2d, 0x30, 0x33, 0x36, 0x39,
+ 0x3c, 0x3f, 0x42, 0x45, 0x48, 0x4b, 0x4e, 0x52, 0x56, 0x5a, 0x5e, 0x62,
+ },
+ {0x3c, 0x52, 0x58, 0x5d, 0x63, 0x68, 0x68, 0x6d, 0x73, 0x78, 0x7c, 0x80,
+ 0x84, 0x89, 0x8e, 0x93, 0x98, 0x9d, 0xa3, 0xa9, 0xad, 0xb1, 0xb5, 0xba,
+ },
+};
+
+static const uint8_t ivi5_scale_quant_8x8_intra[5][24] = {
+ {0x0b, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x17, 0x18, 0x1a, 0x1c, 0x1e, 0x20,
+ 0x22, 0x24, 0x27, 0x28, 0x2a, 0x2d, 0x2f, 0x31, 0x34, 0x37, 0x39, 0x3c,
+ },
+ {0x01, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1b, 0x1e, 0x22, 0x25, 0x28, 0x2c,
+ 0x30, 0x34, 0x38, 0x3d, 0x42, 0x47, 0x4c, 0x52, 0x58, 0x5e, 0x65, 0x6c,
+ },
+ {0x13, 0x22, 0x27, 0x2a, 0x2d, 0x33, 0x36, 0x3c, 0x41, 0x45, 0x49, 0x4e,
+ 0x53, 0x58, 0x5d, 0x63, 0x69, 0x6f, 0x75, 0x7c, 0x82, 0x88, 0x8e, 0x95,
+ },
+ {0x13, 0x1f, 0x21, 0x24, 0x27, 0x29, 0x2d, 0x2f, 0x34, 0x37, 0x3a, 0x3d,
+ 0x40, 0x44, 0x48, 0x4c, 0x4f, 0x52, 0x56, 0x5a, 0x5e, 0x62, 0x66, 0x6b,
+ },
+ {0x31, 0x42, 0x47, 0x47, 0x4d, 0x52, 0x58, 0x58, 0x5d, 0x63, 0x67, 0x6b,
+ 0x6f, 0x73, 0x78, 0x7c, 0x80, 0x84, 0x89, 0x8e, 0x93, 0x98, 0x9d, 0xa4,
+ }
+};
+
+static const uint8_t ivi5_scale_quant_4x4_inter[24] = {
+ 0x0b, 0x0d, 0x0d, 0x0e, 0x11, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
+};
+
+static const uint8_t ivi5_scale_quant_4x4_intra[24] = {
+ 0x01, 0x0b, 0x0b, 0x0d, 0x0d, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x13, 0x14,
+ 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20
+};
+
+
+#endif /* AVCODEC_INDEO5DATA_H */
Added: indeo5/ivi_common.c
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ indeo5/ivi_common.c Thu Dec 10 02:21:27 2009 (r5523)
@@ -0,0 +1,1060 @@
+/*
+ * common functions for Indeo Video Interactive codecs (indeo4 and indeo5)
+ *
+ * Copyright (c) 2009 Maxim Poliakovski
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file libavcodec/ivi_common.c
+ * This file contains functions and data shared by both Indeo4 and Indeo5 decoders.
+ */
+
+#define ALT_BITSTREAM_READER_LE
+#include "avcodec.h"
+#include "get_bits.h"
+#include "ivi_common.h"
+#include "ivi_mc.h"
+
+/**
+ * Reverse "nbits" bits of the value "val" and return the result right-justified.
+ */
+static uint16_t inv_bits(const uint16_t val, const int nbits)
+{
+ uint16_t res;
+
+ if (nbits <= 8) {
+ res = ff_reverse[val & 0xFF] >> (8-nbits);
+ } else
+ res = ((ff_reverse[val & 0xFF] << 8) + (ff_reverse[val >> 8])) >> (16-nbits);
+
+ return res;
+}
+
+
+/**
+ * Generates a huffman codebook from the given descriptor
+ * and convert it into the ffmpeg vlc table.
+ *
+ * @param cb [in] pointer to codebook descriptor
+ * @param pOut [out] where to place the generated VLC table
+ * @param flag [in] flag: 1 - for static or 0 for dynamic tables
+ * @return result code: 0 - OK, -1 = error (invalid codebook descriptor)
+ */
+int ff_ivi_create_huff_from_desc(const IVIHuffDesc *cb, VLC *pOut, const int flag)
+{
+ int pos, i, j, codes_per_row, prefix, last_row;
+ uint16_t codewords[256]; /* FIXME: move this temporal storage out here? */
+ uint8_t bits[256];
+
+ pos = 0; /* current position = 0 */
+
+ for (i = 0; i < cb->num_rows; i++) {
+ codes_per_row = 1 << cb->xbits[i];
+ last_row = !!(i - cb->num_rows + 1); /* = 0 for the last row */
+ prefix = ((1 << i) - 1) << (cb->xbits[i] + last_row);
+
+ for (j = 0; j < codes_per_row; j++) {
+ if (pos >= 256) /* some indeo5 codebooks can have more as 256 elements */
+ break; /* but only 256 codes are allowed! */
+
+ bits[pos] = i + cb->xbits[i] + last_row;
+ if (bits[pos] > IVI_VLC_BITS)
+ return -1; /* invalid descriptor */
+
+ codewords[pos] = inv_bits((prefix | j), bits[pos]);
+ if (!bits[pos])
+ bits[pos] = 1;
+
+ pos++;
+ }//for j
+ }//for i
+
+ /* number of codewords = pos */
+ return init_vlc(pOut, IVI_VLC_BITS, pos, bits, 1, 1, codewords, 2, 2,
+ (flag & 1) | INIT_VLC_LE);
+}
+
+
+/**
+ * Decode a huffman codebook descriptor from the bitstream.
+ *
+ * @param gb [in,out] the GetBit context
+ * @param desc [out] ptr to descriptor to be filled with data
+ * @return selector indicating huffman table:
+ * (0...6 - predefined, 7 - custom one supplied with the bitstream)
+ */
+int ff_ivi_dec_huff_desc(GetBitContext *gb, IVIHuffDesc *desc)
+{
+ int tab_sel, i;
+
+ tab_sel = get_bits(gb, 3);
+ if (tab_sel == 7) {
+ /* custom huffman table (explicitly encoded) */
+ desc->num_rows = get_bits(gb, 4);
+
+ for (i = 0; i < desc->num_rows; i++)
+ desc->xbits[i] = get_bits(gb, 4);
+ }
+
+ return tab_sel;
+}
+
+
+/**
+ * Compare two huffman codebook descriptors.
+ *
+ * @param desc1 [in] ptr to the 1st descriptor to compare
+ * @param desc2 [in] ptr to the 2nd descriptor to compare
+ * @return comparison result: 0 - equal, 1 - not equal
+ */
+int ff_ivi_huff_desc_cmp(const IVIHuffDesc *desc1, const IVIHuffDesc *desc2)
+{
+ if (desc1->num_rows != desc2->num_rows || memcmp(desc1->xbits, desc2->xbits, desc1->num_rows))
+ return 1;
+ return 0;
+}
+
+
+/**
+ * Copy huffman codebook descriptors.
+ *
+ * @param dst [out] ptr to the destination descriptor
+ * @param src [in] ptr to the source descriptor
+ */
+void ff_ivi_huff_desc_copy(IVIHuffDesc *dst, const IVIHuffDesc *src)
+{
+ dst->num_rows = src->num_rows;
+ memcpy(dst->xbits, src->xbits, src->num_rows);
+}
+
+
+/**
+ * Initialize planes (prepare descriptors, allocate buffers etc).
+ *
+ * @param planes [in,out] pointer to the array of the plane descriptors
+ * @param cfg [in] pointer to the ivi_pic_config structure describing picture layout
+ * @return result code: 0 - OK
+ */
+int av_cold ff_ivi_init_planes(IVIPlaneDesc *planes, const IVIPicConfig *cfg)
+{
+ int p, b;
+ uint32_t b_width, b_height, align_fac, width_aligned, height_aligned, buf_size;
+ IVIBandDesc *band;
+
+ ff_ivi_free_buffers(planes);
+
+ /* fill in the descriptor of the luminance plane */
+ planes[0].width = cfg->pic_width;
+ planes[0].height = cfg->pic_height;
+ planes[0].num_bands = cfg->luma_bands;
+
+ /* fill in the descriptors of the chrominance planes */
+ planes[1].width = planes[2].width = (cfg->pic_width + 3) >> 2;
+ planes[1].height = planes[2].height = (cfg->pic_height + 3) >> 2;
+ planes[1].num_bands = planes[2].num_bands = cfg->chroma_bands;
+
+ for (p = 0; p < 3; p++) {
+ planes[p].bands = av_mallocz(planes[p].num_bands * sizeof(IVIBandDesc));
+ planes[p].buf_switch = 0; /* use primary buffer */
+
+ /* select band dimensions: if there is only one band then it has the full size */
+ /* if there are several bands each of them has only a half size */
+ b_width = planes[p].num_bands == 1 ? planes[p].width : planes[p].width >> 1;
+ b_height = planes[p].num_bands == 1 ? planes[p].height : planes[p].height >> 1;
+
+ /* luma band buffers will be aligned on 16x16 (max macroblock size) */
+ /* chroma band buffers will be aligned on 8x8 (max macroblock size) */
+ align_fac = !p ? 15 : 7;
+ width_aligned = (b_width + align_fac) & ~align_fac;
+ height_aligned = (b_height + align_fac) & ~align_fac;
+ buf_size = width_aligned * height_aligned * sizeof(int16_t);
+
+ for (b = 0; b < planes[p].num_bands; b++) {
+ band = &planes[p].bands[b]; /* select appropriate plane/band */
+ band->plane = p;
+ band->band_num = b;
+ band->width = b_width;
+ band->height = b_height;
+ band->pitch = width_aligned;
+ band->buf1 = av_malloc(buf_size);
+ band->buf2 = av_malloc(buf_size);
+
+ planes[p].bands[0].huff_desc.num_rows = 0; /* reset custom vlc */
+ }
+ }
+
+ return 0;
+}
+
+
+/**
+ * Free planes, bands and macroblocks buffers.
+ *
+ * @param planes [in] pointer to the array of the plane descriptors
+ */
+void av_cold ff_ivi_free_buffers(IVIPlaneDesc *planes)
+{
+ int p, b, t;
+
+ for (p = 0; p < 3; p++) {
+ for (b = 0; b < planes[p].num_bands; b++) {
+ av_freep(&planes[p].bands[b].buf1);
+ av_freep(&planes[p].bands[b].buf2);
+
+ for (t = 0; t < planes[p].bands[b].num_tiles; t++)
+ av_freep(&planes[p].bands[b].tiles[t].mbs);
+ av_freep(&planes[p].bands[b].tiles);
+ }
+ av_freep(&planes[p].bands);
+ }
+}
+
+
+/**
+ * Initialize tile and macroblock descriptors.
+ *
+ * @param planes [in,out] pointer to the array of the plane descriptors
+ * @param tile_width [in] tile width
+ * @param tile_height [in] tile height
+ * @return result code: 0 - OK
+ */
+int av_cold ff_ivi_init_tiles(IVIPlaneDesc *planes, const int tile_width, const int tile_height)
+{
+ int p, b, x, y, x_tiles, y_tiles, t_width, t_height;
+ IVIBandDesc *band;
+ IVITile *tile, *ref_tile;
+
+ for (p = 0; p < 3; p++) {
+ t_width = !p ? tile_width : (tile_width + 3) >> 2;
+ t_height = !p ? tile_height : (tile_height + 3) >> 2;
+
+ for (b = 0; b < planes[p].num_bands; b++) {
+ band = &planes[p].bands[b];
+ x_tiles = IVI_NUM_TILES(band->width, t_width);
+ y_tiles = IVI_NUM_TILES(band->height, t_height);
+ band->num_tiles = x_tiles * y_tiles;
+
+ av_freep(&band->tiles);
+ band->tiles = av_mallocz(band->num_tiles * sizeof(IVITile));
+
+ tile = band->tiles;
+
+ /* use the first luma band as reference for motion vectors and quant */
+ ref_tile = planes[0].bands[0].tiles;
+
+ for (y = 0; y < band->height; y += t_height) {
+ for (x = 0; x < band->width; x += t_width) {
+ tile->xpos = x;
+ tile->ypos = y;
+ tile->width = FFMIN(band->width - x, t_width);
+ tile->height = FFMIN(band->height - y, t_height);
+ tile->is_empty = tile->data_size = 0;
+ /* calculate number of macroblocks */
+ tile->num_MBs = IVI_MBs_PER_TILE(tile->width, tile->height, band->mb_size);
+
+ av_freep(&tile->mbs);
+ tile->mbs = av_malloc(tile->num_MBs * sizeof(IVIMbInfo));
+
+ tile->ref_mbs = 0;
+ if (p || b) {
+ tile->ref_mbs = ref_tile->mbs;
+ ref_tile++;
+ }
+
+ tile++;
+ }
+ }
+
+ }// for b
+ }// for p
+
+ return 0;
+}
+
+
+/**
+ * Copies the pixels into the frame buffer.
+ */
+void ff_ivi_put_pixels_8x8(int32_t *in, int16_t *out, uint32_t pitch, uint8_t *flags)
+{
+ int x, y;
+
+ for (y = 0; y < 8; out += pitch, in += 8, y++) {
+ for (x = 0; x < 8; x++)
+ out[x] = in[x];
+ }
+}
+
+
+/**
+ * Copies the DC coefficient into the first pixel of the block and zero all others.
+ */
+void ff_ivi_put_dc_pixel_8x8(int32_t *in, int16_t *out, uint32_t pitch, int blk_size)
+{
+ int y;
+
+ out[0] = in[0];
+ memset(&out[1], 0, 7*sizeof(int16_t));
+
+ for (y = 1; y < 8; out += pitch, y++)
+ memset(out, 0, 8*sizeof(int16_t));
+}
+
+
+/**
+ * Decode size of the tile data.
+ * it's stored as a variable-length field having the following format:
+ * if (tile_data_size < 255) than this field is only one byte long
+ * if (tile_data_size >= 255) than this field four is byte long: 0xFF X1 X2 X3
+ * where X1-X3 is size of the tile data
+ *
+ * @param gb [in,out] the GetBit context
+ * @return size of the tile data in bytes
+ */
+int ff_ivi_dec_tile_data_size(GetBitContext *gb)
+{
+ int len;
+
+ len = 0;
+ if (get_bits1(gb)) {
+ len = get_bits(gb, 8);
+ if (len == 255)
+ len = get_bits_long(gb, 24);
+ }
+
+ /* align the bitstream reader on the byte boundary */
+ align_get_bits(gb);
+
+ return len;
+}
+
+
+/**
+ * Decode block data:
+ * extract huffman-coded transform coefficients from the bitstream, dequantize them,
+ * apply inverse transform and motion compensation in order to reconstruct picture.
+ *
+ * @param gb [in,out] the GetBit context
+ * @param band [in] pointer to the band descriptor
+ * @param tile [in] pointer to the tile descriptor
+ * @return result code: 0 - OK, -1 = error (corrupted blocks data)
+ */
+int ff_ivi_decode_blocks(GetBitContext *gb, IVIBandDesc *band, IVITile *tile)
+{
+ int mbn, blk, num_blocks, num_coeffs, blk_size, scan_pos, run, val,
+ pos, is_intra, mc_type, mv_x, mv_y, col_mask;
+ uint8_t col_flags[8];
+ int32_t prev_dc, trvec[64];
+ uint32_t cbp, sym, lo, hi, quant, buf_offs, q;
+ IVIMbInfo *mb;
+ RVMapDesc *rvmap = band->rv_map;
+ void (*mc_with_delta_func)(int16_t *buf, int16_t *ref_buf, uint32_t pitch, int mc_type);
+ void (*mc_no_delta_func) (int16_t *buf, int16_t *ref_buf, uint32_t pitch, int mc_type);
+ const uint8_t *base_tab, *scale_tab;
+
+ prev_dc = 0; /* init intra prediction for the DC coefficient */
+
+ blk_size = band->blk_size;
+ col_mask = (blk_size == 8) ? 7 : 3; /* column mask for tracking non-zero coeffs */
+ num_blocks = (band->mb_size != blk_size) ? 4 : 1; /* number of blocks per mb */
+ num_coeffs = 16 << ((blk_size >> 2) & 2); /* 64 - for 8x8 block, 16 - for 4x4 */
+ if (blk_size == 8) {
+ mc_with_delta_func = ff_ivi_mc_8x8_delta;
+ mc_no_delta_func = ff_ivi_mc_8x8_no_delta;
+ } else {
+ mc_with_delta_func = ff_ivi_mc_4x4_delta;
+ mc_no_delta_func = ff_ivi_mc_4x4_no_delta;
+ }
+
+ for (mbn = 0, mb = tile->mbs; mbn < tile->num_MBs; mb++, mbn++) {
+ is_intra = !mb->type;
+ cbp = mb->cbp;
+ buf_offs = mb->buf_offs;
+
+ quant = av_clip(band->glob_quant + mb->q_delta, 0, 23);
+
+ base_tab = (is_intra) ? band->intra_base : band->inter_base;
+ scale_tab = (is_intra) ? band->intra_scale : band->inter_scale;
+
+ if (!is_intra) {
+ mv_x = mb->mv_x;
+ mv_y = mb->mv_y;
+ if (!band->mc_resolution) {
+ mc_type = 0; /* we have only fullpel vectors */
+ } else {
+ mc_type = ((mv_y & 1) << 1) | (mv_x & 1);
+ mv_x >>= 1;
+ mv_y >>= 1; /* convert halfpel vectors into fullpel ones */
+ }
+ }
+
+ for (blk = 0; blk < num_blocks; blk++) {
+ /* adjust block position in the buffer according with its number */
+ if (blk & 1) {
+ buf_offs += blk_size;
+ } else if (blk == 2) {
+ buf_offs -= blk_size;
+ buf_offs += blk_size * band->pitch;
+ }
+
+ if (cbp & 1) { /* block coded ? */
+ scan_pos = -1;
+ memset(trvec, 0, num_coeffs*sizeof(int32_t)); /* zero transform vector */
+ memset(col_flags, 0, sizeof(col_flags)); /* zero column flags */
+
+ while(scan_pos <= num_coeffs) {
+ sym = get_vlc2(gb, band->blk_vlc->table, IVI_VLC_BITS, 1);
+ if (sym == rvmap->eob_sym)
+ break; /* End of block */
+
+ if (sym == rvmap->esc_sym) { /* Escape - run/val explicitly coded using 3 vlc codes */
+ run = get_vlc2(gb, band->blk_vlc->table, IVI_VLC_BITS, 1) + 1;
+ lo = get_vlc2(gb, band->blk_vlc->table, IVI_VLC_BITS, 1);
+ hi = get_vlc2(gb, band->blk_vlc->table, IVI_VLC_BITS, 1);
+ val = IVI_TOSIGNED((hi << 6) | lo); /* merge them and convert into signed val */
+ } else {
+ run = rvmap->runtab[sym];
+ val = rvmap->valtab[sym];
+ }
+
+ /* de-zigzag and dequantize */
+ scan_pos += run;
+ pos = band->scan[scan_pos];
+
+ #ifdef IVI_DEBUG
+ if (!val)
+ av_log(NULL,AV_LOG_ERROR,"Val = 0 encountered!\n");
+ #endif
+
+ q = (base_tab[pos] * scale_tab[quant]) >> 8;
+ q += !q; // ensure the q always >= 1
+ if (q != 1) {
+ if (val > 0) {
+ val = (val * q) + (q >> 1) - (q & 1);
+ } else
+ val = (val * q) - (q >> 1) + (q & 1);
+ }
+ trvec[pos] = val;
+ col_flags[pos & col_mask] |= val; /* track columns containing non-zero coeffs */
+ }// while
+
+ if (scan_pos >= num_coeffs && sym != rvmap->eob_sym)
+ return -1; /* corrupt block data */
+
+ /* undoing DC coeff prediction for intra-blocks */
+ if (is_intra && band->is_2d_trans) {
+ prev_dc += trvec[0];
+ trvec[0] = prev_dc;
+ col_flags[0] |= !!prev_dc;
+ }
+
+ /* apply inverse transform */
+ band->inv_transform(trvec, band->buf + buf_offs, band->pitch, col_flags);
+
+ /* apply motion compensation */
+ if (!is_intra)
+ mc_with_delta_func(band->buf + buf_offs, band->ref_buf + buf_offs + mv_y * band->pitch + mv_x, band->pitch, mc_type);
+ } else {
+ /* block not coded */
+ /* for intra blocks apply the dc slant transform */
+ /* for inter - perform the motion compensation without delta */
+ if (is_intra && band->dc_transform) {
+ band->dc_transform(&prev_dc, band->buf + buf_offs, band->pitch, blk_size);
+ } else
+ mc_no_delta_func(band->buf + buf_offs, band->ref_buf + buf_offs + mv_y * band->pitch + mv_x, band->pitch, mc_type);
+ }
+
+ cbp >>= 1;
+ }// for blk
+ }// for mbn
+
+ align_get_bits(gb);
+
+ return 0;
+}
+
+
+/**
+ * Handles empty tiles by performing data copying and motion compensation resp.
+ *
+ * @param avctx [in] ptr to the AVCodecContext
+ * @param band [in] pointer to the band descriptor
+ * @param tile [in] pointer to the tile descriptor
+ * @param mv_scale [in] scaling factor for motion vectors
+ */
+void ff_ivi_process_empty_tile(AVCodecContext *avctx, IVIBandDesc *band, IVITile *tile, int32_t mv_scale)
+{
+ int x, y, need_mc, mbn, blk, num_blocks, mv_x, mv_y, mc_type;
+ int offs, mb_offset, row_offset;
+ IVIMbInfo *mb, *ref_mb;
+ const int16_t *src;
+ int16_t *dst;
+ void (*mc_no_delta_func)(int16_t *buf, int16_t *ref_buf, uint32_t pitch, int mc_type);
+
+ offs = tile->ypos * band->pitch + tile->xpos;
+ mb = tile->mbs;
+ ref_mb = tile->ref_mbs;
+ row_offset = band->mb_size * band->pitch;
+ need_mc = 0; /* reset the mc tracking flag */
+
+ for (y = tile->ypos; y < (tile->ypos + tile->height); y += band->mb_size) {
+ mb_offset = offs;
+
+ for (x = tile->xpos; x < (tile->xpos + tile->width); x += band->mb_size) {
+ mb->xpos = x;
+ mb->ypos = y;
+ mb->buf_offs = mb_offset;
+
+ mb->type = 1; /* set the macroblocks type = INTER */
+ mb->cbp = 0; /* all blocks are empty */
+
+ if (!band->qdelta_present && !band->plane && !band->band_num) {
+ mb->q_delta = band->glob_quant;
+ mb->mv_x = 0;
+ mb->mv_y = 0;
+ }
+
+ if (band->inherit_qdelta && ref_mb)
+ mb->q_delta = ref_mb->q_delta;
+
+ if (band->inherit_mv) {
+ /* motion vector inheritance */
+ switch (mv_scale) {
+ case 0:
+ mb->mv_x = ref_mb->mv_x;
+ mb->mv_y = ref_mb->mv_y;
+ break;
+ case 1:
+ mb->mv_x = IVI_MV_DIV2(ref_mb->mv_x);
+ mb->mv_y = IVI_MV_DIV2(ref_mb->mv_y);
+ break;
+ case 2:
+ mb->mv_x = IVI_MV_DIV4(ref_mb->mv_x);
+ mb->mv_y = IVI_MV_DIV4(ref_mb->mv_y);
+ break;
+ }
+ need_mc |= mb->mv_x || mb->mv_y; /* tracking non-zero motion vectors */
+ }
+
+ mb++;
+ if (ref_mb)
+ ref_mb++;
+ mb_offset += band->mb_size;
+ } // for x
+ offs += row_offset;
+ } // for y
+
+ if (band->inherit_mv && need_mc) { /* apply motion compensation if there is at least one non-zero motion vector */
+ num_blocks = (band->mb_size != band->blk_size) ? 4 : 1; /* number of blocks per mb */
+ mc_no_delta_func = (band->blk_size == 8) ? ff_ivi_mc_8x8_no_delta : ff_ivi_mc_4x4_no_delta;
+
+ for (mbn = 0, mb = tile->mbs; mbn < tile->num_MBs; mb++, mbn++) {
+ mv_x = mb->mv_x;
+ mv_y = mb->mv_y;
+ offs = mb->buf_offs;
+ if (!band->mc_resolution) {
+ mc_type = 0; /* we have only fullpel vectors */
+ } else {
+ mc_type = ((mv_y & 1) << 1) | (mv_x & 1);
+ mv_x >>= 1;
+ mv_y >>= 1; /* convert halfpel vectors into fullpel ones */
+ }
+
+ for (blk = 0; blk < num_blocks; blk++) {
+ /* adjust block position in the buffer according with its number */
+ if (blk & 1) {
+ offs += band->blk_size;
+ } else if (blk == 2) {
+ offs -= band->blk_size;
+ offs += band->blk_size * band->pitch;
+ }
+ mc_no_delta_func(band->buf + offs, band->ref_buf + offs + mv_y * band->pitch + mv_x, band->pitch, mc_type);
+ }
+ }
+ } else {
+ /* copy data from the reference tile into the current one */
+ src = &band->ref_buf[tile->ypos * band->pitch + tile->xpos];
+ dst = &band->buf[tile->ypos * band->pitch + tile->xpos];
+ for (y = 0; y < tile->height; y++) {
+ memcpy(dst, src, tile->width*sizeof(int16_t));
+ src += band->pitch;
+ dst += band->pitch;
+ }
+ }
+}
+
+
+#ifdef IVI_DEBUG
+/**
+ * for debugging only
+ */
+uint16_t ivi_calc_band_checksum (IVIBandDesc *band)
+{
+ int x, y;
+ int16_t *src, checksum;
+
+ src = band->buf;
+ checksum = 0;
+
+ for (y = 0; y < band->height; src += band->pitch,y++) {
+ for (x = 0; x < band->width; x++)
+ checksum += src[x];
+ }
+
+ return checksum;
+}
+
+
+/**
+ * for debugging only
+ */
+int ivi_check_band (IVIBandDesc *band, uint8_t *ref, int pitch)
+{
+ int x, y, result;
+ uint8_t t1, t2;
+ int16_t *src;
+
+ src = band->buf;
+ result = 0;
+
+ for (y = 0; y < band->height; src += band->pitch,y++) {
+ for (x = 0; x < band->width; x++) {
+ t1 = av_clip(src[x] + 128, 0, 255);
+ t2 = ref[x];
+ if (t1 != t2) {
+ av_log(NULL,AV_LOG_ERROR,"Data mismatch: row %d, column %d\n", y/band->blk_size, x/band->blk_size);
+ result = -1;
+ }
+ }
+ ref += pitch;
+ }
+
+ return result;
+}
+#endif
+
+
+/**
+ * Convert and output the current plane.
+ * This conversion is done by adding back the bias value of 128
+ * (subtracted in the encoder) and clipping the result.
+ *
+ * @param plane [in] pointer to the descriptor of the plane being processed
+ * @param dst [out] pointer to the buffer receiving converted pixels
+ * @param dst_pitch [in] pitch for moving to the next y line
+ */
+void ff_ivi_output_plane(IVIPlaneDesc *plane, uint8_t *dst, int dst_pitch)
+{
+ int x, y;
+ const int16_t *src = plane->bands[0].buf;
+ uint32_t pitch = plane->bands[0].pitch;
+
+ for (y = 0; y < plane->height; y++) {
+ for (x = 0; x < plane->width; x++)
+ dst[x] = av_clip_uint8(src[x] + 128);
+ src += pitch;
+ dst += dst_pitch;
+ }
+}
+
+
+/**
+ * These are 2x8 predefined Huffman codebooks for coding macroblock/block signals.
+ * They are specified using "huffman descriptors" in order to avoid huge static tables.
+ * The decoding tables will be generated at startup from these descriptors.
+ */
+const IVIHuffDesc ff_ivi_mb_huff_desc[8] = {
+ {8, {0, 4, 5, 4, 4, 4, 6, 6}},
+ {12, {0, 2, 2, 3, 3, 3, 3, 5, 3, 2, 2, 2}},
+ {12, {0, 2, 3, 4, 3, 3, 3, 3, 4, 3, 2, 2}},
+ {12, {0, 3, 4, 4, 3, 3, 3, 3, 3, 2, 2, 2}},
+ {13, {0, 4, 4, 3, 3, 3, 3, 2, 3, 3, 2, 1, 1}},
+ {9, {0, 4, 4, 4, 4, 3, 3, 3, 2}},
+ {10, {0, 4, 4, 4, 4, 3, 3, 2, 2, 2}},
+ {12, {0, 4, 4, 4, 3, 3, 2, 3, 2, 2, 2, 2}}
+};
+
+const IVIHuffDesc ff_ivi_blk_huff_desc[8] = {
+ {10, {1, 2, 3, 4, 4, 7, 5, 5, 4, 1}},
+ {11, {2, 3, 4, 4, 4, 7, 5, 4, 3, 3, 2}},
+ {12, {2, 4, 5, 5, 5, 5, 6, 4, 4, 3, 1, 1}},
+ {13, {3, 3, 4, 4, 5, 6, 6, 4, 4, 3, 2, 1, 1}},
+ {11, {3, 4, 4, 5, 5, 5, 6, 5, 4, 2, 2}},
+ {13, {3, 4, 5, 5, 5, 5, 6, 4, 3, 3, 2, 1, 1}},
+ {13, {3, 4, 5, 5, 5, 6, 5, 4, 3, 3, 2, 1, 1}},
+ {9, {3, 4, 4, 5, 5, 5, 6, 5, 5}}
+};
+
+
+/**
+ * Run-value (RLE) tables.
+ */
+const RVMapDesc ff_ivi_rvmap_tabs[9] = {
+{ /* MapTab0 */
+ 5, /* eob_sym */
+ 2, /* esc_sym */
+ /* run table */
+ {1, 1, 0, 1, 1, 0, 1, 1, 2, 2, 1, 1, 1, 1, 3, 3,
+ 1, 1, 2, 2, 1, 1, 4, 4, 1, 1, 1, 1, 2, 2, 5, 5,
+ 1, 1, 3, 3, 1, 1, 6, 6, 1, 2, 1, 2, 7, 7, 1, 1,
+ 8, 8, 1, 1, 4, 2, 1, 4, 2, 1, 3, 3, 1, 1, 1, 9,
+ 9, 1, 2, 1, 2, 1, 5, 5, 1, 1, 10, 10, 1, 1, 3, 3,
+ 2, 2, 1, 1, 11, 11, 6, 4, 4, 1, 6, 1, 2, 1, 2, 12,
+ 8, 1, 12, 7, 8, 7, 1, 16, 1, 16, 1, 3, 3, 13, 1, 13,
+ 2, 2, 1, 15, 1, 5, 14, 15, 1, 5, 14, 1, 17, 8, 17, 8,
+ 1, 4, 4, 2, 2, 1, 25, 25, 24, 24, 1, 3, 1, 3, 1, 8,
+ 6, 7, 6, 1, 18, 8, 18, 1, 7, 23, 2, 2, 23, 1, 1, 21,
+ 22, 9, 9, 22, 19, 1, 21, 5, 19, 5, 1, 33, 20, 33, 20, 8,
+ 4, 4, 1, 32, 2, 2, 8, 3, 32, 26, 3, 1, 7, 7, 26, 6,
+ 1, 6, 1, 1, 16, 1, 10, 1, 10, 2, 16, 29, 28, 2, 29, 28,
+ 1, 27, 5, 8, 5, 27, 1, 8, 3, 7, 3, 31, 41, 31, 1, 41,
+ 6, 1, 6, 7, 4, 4, 1, 1, 2, 1, 2, 11, 34, 30, 11, 1,
+ 30, 15, 15, 34, 36, 40, 36, 40, 35, 35, 37, 37, 39, 39, 38, 38},
+
+ /* value table */
+ { 1, -1, 0, 2, -2, 0, 3, -3, 1, -1, 4, -4, 5, -5, 1, -1,
+ 6, -6, 2, -2, 7, -7, 1, -1, 8, -8, 9, -9, 3, -3, 1, -1,
+ 10, -10, 2, -2, 11, -11, 1, -1, 12, 4, -12, -4, 1, -1, 13, -13,
+ 1, -1, 14, -14, 2, 5, 15, -2, -5, -15, -3, 3, 16, -16, 17, 1,
+ -1, -17, 6, 18, -6, -18, 2, -2, 19, -19, 1, -1, 20, -20, 4, -4,
+ 7, -7, 21, -21, 1, -1, 2, 3, -3, 22, -2, -22, 8, 23, -8, 1,
+ 2, -23, -1, 2, -2, -2, 24, 1, -24, -1, 25, 5, -5, 1, -25, -1,
+ 9, -9, 26, 1, -26, 3, 1, -1, 27, -3, -1, -27, 1, 3, -1, -3,
+ 28, -4, 4, 10, -10, -28, 1, -1, 1, -1, 29, 6, -29, -6, 30, -4,
+ 3, 3, -3, -30, 1, 4, -1, 31, -3, 1, 11, -11, -1, -31, 32, -1,
+ -1, 2, -2, 1, 1, -32, 1, 4, -1, -4, 33, -1, 1, 1, -1, 5,
+ 5, -5, -33, -1, -12, 12, -5, -7, 1, 1, 7, 34, 4, -4, -1, 4,
+ -34, -4, 35, 36, -2, -35, -2, -36, 2, 13, 2, -1, 1, -13, 1, -1,
+ 37, 1, -5, 6, 5, -1, 38, -6, -8, 5, 8, -1, 1, 1, -37, -1,
+ 5, 39, -5, -5, 6, -6, -38, -39, -14, 40, 14, 2, 1, 1, -2, -40,
+ -1, -2, 2, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, -1, 1, -1}
+},{
+ /* MapTab1 */
+ 0, /* eob_sym */
+ 38, /* esc_sym */
+ /* run table */
+ {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 8, 6, 8, 7,
+ 7, 9, 9, 10, 10, 11, 11, 1, 12, 1, 12, 13, 13, 16, 14, 16,
+ 14, 15, 15, 17, 17, 18, 0, 18, 19, 20, 21, 19, 22, 21, 20, 22,
+ 25, 24, 2, 25, 24, 23, 23, 2, 26, 28, 26, 28, 29, 27, 29, 27,
+ 33, 33, 1, 32, 1, 3, 32, 30, 36, 3, 36, 30, 31, 31, 35, 34,
+ 37, 41, 34, 35, 37, 4, 41, 4, 49, 8, 8, 49, 40, 38, 5, 38,
+ 40, 39, 5, 39, 42, 43, 42, 7, 57, 6, 43, 44, 6, 50, 7, 44,
+ 57, 48, 50, 48, 45, 45, 46, 47, 51, 46, 47, 58, 1, 51, 58, 1,
+ 52, 59, 53, 9, 52, 55, 55, 59, 53, 56, 54, 56, 54, 9, 64, 64,
+ 60, 63, 60, 63, 61, 62, 61, 62, 2, 10, 2, 10, 11, 1, 11, 13,
+ 12, 1, 12, 13, 16, 16, 8, 8, 14, 3, 3, 15, 14, 15, 4, 4,
+ 1, 17, 17, 5, 1, 7, 7, 5, 6, 1, 2, 2, 6, 22, 1, 25,
+ 21, 22, 8, 24, 1, 21, 25, 24, 8, 18, 18, 23, 9, 20, 23, 33,
+ 29, 33, 20, 1, 19, 1, 29, 36, 9, 36, 19, 41, 28, 57, 32, 3,
+ 28, 3, 1, 27, 49, 49, 1, 32, 26, 26, 2, 4, 4, 7, 57, 41,
+ 2, 7, 10, 5, 37, 16, 10, 27, 8, 8, 13, 16, 37, 13, 1, 5},
+
+ /* value table */
+ {0, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, 1,
+ -1, 1, -1, 1, -1, 1, -1, 2, 1, -2, -1, 1, -1, 1, 1, -1,
+ -1, 1, -1, 1, -1, 1, 0, -1, 1, 1, 1, -1, 1, -1, -1, -1,
+ 1, 1, 2, -1, -1, 1, -1, -2, 1, 1, -1, -1, 1, 1, -1, -1,
+ 1, -1, 3, 1, -3, 2, -1, 1, 1, -2, -1, -1, -1, 1, 1, 1,
+ 1, 1, -1, -1, -1, 2, -1, -2, 1, 2, -2, -1, 1, 1, 2, -1,
+ -1, 1, -2, -1, 1, 1, -1, 2, 1, 2, -1, 1, -2, -1, -2, -1,
+ -1, 1, 1, -1, 1, -1, 1, 1, 1, -1, -1, 1, 4, -1, -1, -4,
+ 1, 1, 1, 2, -1, -1, 1, -1, -1, 1, -1, -1, 1, -2, 1, -1,
+ 1, 1, -1, -1, 1, 1, -1, -1, 3, 2, -3, -2, 2, 5, -2, 2,
+ 2, -5, -2, -2, -2, 2, -3, 3, 2, 3, -3, 2, -2, -2, 3, -3,
+ 6, 2, -2, 3, -6, 3, -3, -3, 3, 7, -4, 4, -3, 2, -7, 2,
+ 2, -2, -4, 2, 8, -2, -2, -2, 4, 2, -2, 2, 3, 2, -2, -2,
+ 2, 2, -2, -8, -2, 9, -2, 2, -3, -2, 2, -2, 2, 2, 2, 4,
+ -2, -4, 10, 2, 2, -2, -9, -2, 2, -2, 5, 4, -4, 4, -2, 2,
+ -5, -4, -3, 4, 2, -3, 3, -2, -5, 5, 3, 3, -2, -3, -10, -4}
+},{
+ /* MapTab2 */
+ 2, /* eob_sym */
+ 11, /* esc_sym */
+ /* run table */
+ {1, 1, 0, 2, 2, 1, 1, 3, 3, 4, 4, 0, 1, 1, 5, 5,
+ 2, 2, 6, 6, 7, 7, 1, 8, 1, 8, 3, 3, 9, 9, 1, 2,
+ 2, 1, 4, 10, 4, 10, 11, 11, 1, 5, 12, 12, 1, 5, 13, 13,
+ 3, 3, 6, 6, 2, 2, 14, 14, 16, 16, 15, 7, 15, 8, 8, 7,
+ 1, 1, 17, 17, 4, 4, 1, 1, 18, 18, 2, 2, 5, 5, 25, 3,
+ 9, 3, 25, 9, 19, 24, 19, 24, 1, 21, 20, 1, 21, 22, 20, 22,
+ 23, 23, 8, 6, 33, 6, 8, 33, 7, 7, 26, 26, 1, 32, 1, 32,
+ 28, 4, 28, 10, 29, 27, 27, 10, 41, 4, 29, 2, 2, 41, 36, 31,
+ 49, 31, 34, 30, 34, 36, 30, 35, 1, 49, 11, 5, 35, 11, 1, 3,
+ 3, 5, 37, 37, 8, 40, 8, 40, 12, 12, 42, 42, 1, 38, 16, 57,
+ 1, 6, 16, 39, 38, 6, 7, 7, 13, 13, 39, 43, 2, 43, 57, 2,
+ 50, 9, 44, 9, 50, 4, 15, 48, 44, 4, 1, 15, 48, 14, 14, 1,
+ 45, 45, 8, 3, 5, 8, 51, 47, 3, 46, 46, 47, 5, 51, 1, 17,
+ 17, 58, 1, 58, 2, 52, 52, 2, 53, 7, 59, 6, 6, 56, 53, 55,
+ 7, 55, 1, 54, 59, 56, 54, 10, 1, 10, 4, 60, 1, 60, 8, 4,
+ 8, 64, 64, 61, 1, 63, 3, 63, 62, 61, 5, 11, 5, 3, 11, 62},
+
+ /* value table */
+ { 1, -1, 0, 1, -1, 2, -2, 1, -1, 1, -1, 0, 3, -3, 1, -1,
+ 2, -2, 1, -1, 1, -1, 4, 1, -4, -1, 2, -2, 1, -1, 5, 3,
+ -3, -5, 2, 1, -2, -1, 1, -1, 6, 2, 1, -1, -6, -2, 1, -1,
+ 3, -3, 2, -2, 4, -4, 1, -1, 1, -1, 1, 2, -1, 2, -2, -2,
+ 7, -7, 1, -1, 3, -3, 8, -8, 1, -1, 5, -5, 3, -3, 1, 4,
+ 2, -4, -1, -2, 1, 1, -1, -1, 9, 1, 1, -9, -1, 1, -1, -1,
+ 1, -1, 3, -3, 1, 3, -3, -1, 3, -3, 1, -1, 10, 1, -10, -1,
+ 1, 4, -1, 2, 1, -1, 1, -2, 1, -4, -1, 6, -6, -1, 1, 1,
+ 1, -1, 1, 1, -1, -1, -1, 1, 11, -1, -2, 4, -1, 2, -11, 5,
+ -5, -4, -1, 1, 4, 1, -4, -1, -2, 2, 1, -1, 12, 1, -2, 1,
+ -12, 4, 2, 1, -1, -4, 4, -4, 2, -2, -1, 1, 7, -1, -1, -7,
+ -1, -3, 1, 3, 1, 5, 2, 1, -1, -5, 13, -2, -1, 2, -2, -13,
+ 1, -1, 5, 6, 5, -5, 1, 1, -6, 1, -1, -1, -5, -1, 14, 2,
+ -2, 1, -14, -1, 8, 1, -1, -8, 1, 5, 1, 5, -5, 1, -1, 1,
+ -5, -1, 15, 1, -1, -1, -1, 3, -15, -3, 6, 1, 16, -1, 6, -6,
+ -6, 1, -1, 1, -16, 1, 7, -1, 1, -1, -6, -3, 6, -7, 3, -1}
+},{
+ /* MapTab3 */
+ 0, /* eob_sym */
+ 35, /* esc_sym */
+ /* run table */
+ {0, 1, 1, 2, 2, 3, 3, 4, 4, 1, 1, 5, 5, 6, 6, 7,
+ 7, 8, 8, 9, 9, 2, 2, 10, 10, 1, 1, 11, 11, 12, 12, 3,
+ 3, 13, 13, 0, 14, 14, 16, 15, 16, 15, 4, 4, 17, 1, 17, 1,
+ 5, 5, 18, 18, 2, 2, 6, 6, 8, 19, 7, 8, 7, 19, 20, 20,
+ 21, 21, 22, 24, 22, 24, 23, 23, 1, 1, 25, 25, 3, 3, 26, 26,
+ 9, 9, 27, 27, 28, 28, 33, 29, 4, 33, 29, 1, 4, 1, 32, 32,
+ 2, 2, 31, 10, 30, 10, 30, 31, 34, 34, 5, 5, 36, 36, 35, 41,
+ 35, 11, 41, 11, 37, 1, 8, 8, 37, 6, 1, 6, 40, 7, 7, 40,
+ 12, 38, 12, 39, 39, 38, 49, 13, 49, 13, 3, 42, 3, 42, 16, 16,
+ 43, 43, 14, 14, 1, 1, 44, 15, 44, 15, 2, 2, 57, 48, 50, 48,
+ 57, 50, 4, 45, 45, 4, 46, 47, 47, 46, 1, 51, 1, 17, 17, 51,
+ 8, 9, 9, 5, 58, 8, 58, 5, 52, 52, 55, 56, 53, 56, 55, 59,
+ 59, 53, 54, 1, 6, 54, 7, 7, 6, 1, 2, 3, 2, 3, 64, 60,
+ 60, 10, 10, 64, 61, 62, 61, 63, 1, 63, 62, 1, 18, 24, 18, 4,
+ 25, 4, 8, 21, 21, 1, 24, 22, 25, 22, 8, 11, 19, 11, 23, 1,
+ 20, 23, 19, 20, 5, 12, 5, 1, 16, 2, 12, 13, 2, 13, 1, 16},
+
+ /* value table */
+ { 0, 1, -1, 1, -1, 1, -1, 1, -1, 2, -2, 1, -1, 1, -1, 1,
+ -1, 1, -1, 1, -1, 2, -2, 1, -1, 3, -3, 1, -1, 1, -1, 2,
+ -2, 1, -1, 0, 1, -1, 1, 1, -1, -1, 2, -2, 1, 4, -1, -4,
+ 2, -2, 1, -1, -3, 3, 2, -2, 2, 1, 2, -2, -2, -1, 1, -1,
+ 1, -1, 1, 1, -1, -1, 1, -1, 5, -5, 1, -1, 3, -3, 1, -1,
+ 2, -2, 1, -1, 1, -1, 1, 1, 3, -1, -1, 6, -3, -6, -1, 1,
+ 4, -4, 1, 2, 1, -2, -1, -1, 1, -1, 3, -3, 1, -1, 1, 1,
+ -1, 2, -1, -2, 1, 7, -3, 3, -1, 3, -7, -3, 1, -3, 3, -1,
+ 2, 1, -2, 1, -1, -1, 1, 2, -1, -2, -4, -1, 4, 1, 2, -2,
+ 1, -1, -2, 2, 8, -8, -1, 2, 1, -2, -5, 5, 1, -1, -1, 1,
+ -1, 1, 4, -1, 1, -4, -1, -1, 1, 1, 9, 1, -9, 2, -2, -1,
+ -4, 3, -3, -4, -1, 4, 1, 4, 1, -1, 1, -1, 1, 1, -1, 1,
+ -1, -1, -1, 10, 4, 1, 4, -4, -4, -10, 6, 5, -6, -5, 1, -1,
+ 1, 3, -3, -1, 1, -1, -1, -1, 11, 1, 1, -11, -2, -2, 2, 5,
+ -2, -5, -5, 2, -2, 12, 2, -2, 2, 2, 5, -3, -2, 3, -2, -12,
+ -2, 2, 2, 2, -5, 3, 5, 13, -3, 7, -3, -3, -7, 3, -13, 3}
+},{
+ /* MapTab4 */
+ 0, /* eob_sym */
+ 34, /* esc_sym */
+ /* run table */
+ {0, 1, 1, 1, 2, 2, 1, 3, 3, 1, 1, 1, 4, 4, 1, 5,
+ 2, 1, 5, 2, 1, 1, 6, 6, 1, 1, 1, 1, 1, 7, 3, 1,
+ 2, 3, 0, 1, 2, 7, 1, 1, 1, 8, 1, 1, 8, 1, 1, 1,
+ 9, 1, 9, 1, 2, 1, 1, 2, 1, 1, 10, 4, 1, 10, 1, 4,
+ 1, 1, 1, 1, 1, 3, 1, 1, 1, 3, 2, 1, 5, 1, 1, 1,
+ 2, 5, 1, 11, 1, 11, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 2, 1, 6, 1, 6, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 12,
+ 3, 1, 12, 1, 1, 1, 2, 1, 1, 3, 1, 1, 1, 1, 1, 1,
+ 4, 1, 1, 1, 2, 1, 1, 4, 1, 1, 1, 1, 1, 1, 2, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 2, 1, 1, 5,
+ 1, 1, 1, 1, 1, 7, 1, 7, 1, 1, 2, 3, 1, 1, 1, 1,
+ 5, 1, 1, 1, 1, 1, 1, 2, 13, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 13, 2, 1, 1, 4, 1, 1, 1,
+ 3, 1, 6, 1, 1, 1, 14, 1, 1, 1, 1, 1, 14, 6, 1, 1,
+ 1, 1, 15, 2, 4, 1, 2, 3, 15, 1, 1, 1, 8, 1, 1, 8,
+ 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1},
+
+ /* value table */
+ { 0, 1, -1, 2, 1, -1, -2, 1, -1, 3, -3, 4, 1, -1, -4, 1,
+ 2, 5, -1, -2, -5, 6, 1, -1, -6, 7, -7, 8, -8, 1, 2, 9,
+ 3, -2, 0, -9, -3, -1, 10, -10, 11, 1, -11, 12, -1, -12, 13, -13,
+ 1, 14, -1, -14, 4, 15, -15, -4, 16, -16, 1, 2, 17, -1, -17, -2,
+ 18, -18, 19, -19, 20, 3, -20, 21, -21, -3, 5, 22, 2, -22, -23, 23,
+ -5, -2, 24, 1, -24, -1, 25, -25, 26, -26, -27, 27, 28, 29, -28, -29,
+ 6, 30, 2, -31, -2, -30, 31, -6, -32, 32, 33, -33, 34, -35, -34, 1,
+ 4, -36, -1, 35, 37, 36, 7, -37, 38, -4, -38, 39, 41, 40, -40, -39,
+ 3, 42, -43, -41, -7, -42, 43, -3, 44, -44, 45, -45, 46, 47, 8, -47,
+ -48, -46, 50, -50, 48, 49, 51, -49, 52, -52, 5, -51, -8, -53, 53, 3,
+ -56, 56, 55, 54, -54, 2, 60, -2, -55, 58, 9, -5, 59, 57, -57, -63,
+ -3, -58, -60, -61, 61, -59, -62, -9, 1, 64, 62, 69, -64, 63, 65, -67,
+ -68, 66, -65, 68, -66, -69, 67, -70, -1, 10, 71, -71, 4, 73, 72, 70,
+ 6, -76, -3, 74, -78, -74, 1, 78, 80, -72, -75, 76, -1, 3, -73, 79,
+ 75, 77, 1, 11, -4, -79, -10, -6, -1, -77, -83, -80, 2, 81, -84, -2,
+ 83, -81, 82, -82, 84, -87, -86, 85, -11, -85, 86, -89, 87, -88, 88, 89}
+},{
+ /* MapTab5 */
+ 2, /* eob_sym */
+ 33, /* esc_sym */
+ /* run table */
+ {1, 1, 0, 2, 1, 2, 1, 3, 3, 1, 1, 4, 4, 2, 2, 1,
+ 1, 5, 5, 6, 1, 6, 1, 7, 7, 3, 3, 2, 8, 2, 8, 1,
+ 1, 0, 9, 9, 1, 1, 10, 4, 10, 4, 11, 11, 2, 1, 2, 1,
+ 12, 12, 3, 3, 1, 1, 13, 5, 5, 13, 14, 1, 1, 14, 2, 2,
+ 6, 6, 15, 1, 1, 15, 16, 4, 7, 16, 4, 7, 1, 1, 3, 3,
+ 8, 8, 2, 2, 1, 1, 17, 17, 1, 1, 18, 18, 5, 5, 2, 2,
+ 1, 1, 9, 19, 9, 19, 20, 3, 3, 20, 1, 10, 21, 1, 10, 4,
+ 4, 21, 22, 6, 6, 22, 1, 1, 23, 24, 2, 2, 23, 24, 11, 1,
+ 1, 11, 7, 25, 7, 1, 1, 25, 8, 8, 3, 26, 3, 1, 12, 2,
+ 2, 26, 1, 12, 5, 5, 27, 4, 1, 4, 1, 27, 28, 1, 28, 13,
+ 1, 13, 2, 29, 2, 1, 32, 6, 1, 30, 14, 29, 14, 6, 3, 31,
+ 3, 1, 30, 1, 32, 31, 33, 9, 33, 1, 1, 7, 9, 7, 2, 2,
+ 1, 1, 4, 36, 34, 4, 5, 10, 10, 5, 34, 1, 1, 35, 8, 8,
+ 36, 3, 35, 1, 15, 3, 2, 1, 16, 15, 16, 2, 37, 1, 37, 1,
+ 1, 1, 6, 6, 38, 1, 38, 11, 1, 39, 39, 40, 11, 2, 41, 4,
+ 40, 1, 2, 4, 1, 1, 1, 41, 3, 1, 3, 1, 5, 7, 5, 7},
+
+ /* value table */
+ { 1, -1, 0, 1, 2, -1, -2, 1, -1, 3, -3, 1, -1, 2, -2, 4,
+ -4, 1, -1, 1, 5, -1, -5, 1, -1, 2, -2, 3, 1, -3, -1, 6,
+ -6, 0, 1, -1, 7, -7, 1, 2, -1, -2, 1, -1, 4, 8, -4, -8,
+ 1, -1, 3, -3, 9, -9, 1, 2, -2, -1, 1, 10, -10, -1, 5, -5,
+ 2, -2, 1, 11, -11, -1, 1, 3, 2, -1, -3, -2, 12, -12, 4, -4,
+ 2, -2, -6, 6, 13, -13, 1, -1, 14, -14, 1, -1, 3, -3, 7, -7,
+ 15, -15, 2, 1, -2, -1, 1, 5, -5, -1, -16, 2, 1, 16, -2, 4,
+ -4, -1, 1, 3, -3, -1, 17, -17, 1, 1, -8, 8, -1, -1, 2, 18,
+ -18, -2, 3, 1, -3, 19, -19, -1, 3, -3, 6, 1, -6, 20, 2, 9,
+ -9, -1, -20, -2, 4, -4, 1, -5, 21, 5, -21, -1, 1, -22, -1, 2,
+ 22, -2, 10, 1, -10, 23, 1, 4, -23, 1, 2, -1, -2, -4, -7, 1,
+ 7, -24, -1, 24, -1, -1, 1, 3, -1, -25, 25, 4, -3, -4, 11, -11,
+ 26, -26, 6, 1, 1, -6, -5, -3, 3, 5, -1, -27, 27, 1, 4, -4,
+ -1, -8, -1, 28, 2, 8, -12, -28, -2, -2, 2, 12, -1, 29, 1, -29,
+ 30, -30, 5, -5, 1, -31, -1, 3, 31, -1, 1, 1, -3, -13, 1, -7,
+ -1, -32, 13, 7, 32, 33, -33, -1, -9, -34, 9, 34, -6, 5, 6, -5}
+},{
+ /* MapTab6 */
+ 2, /* eob_sym */
+ 13, /* esc_sym */
+ /* run table */
+ {1, 1, 0, 1, 1, 2, 2, 1, 1, 3, 3, 1, 1, 0, 2, 2,
+ 4, 1, 4, 1, 1, 1, 5, 5, 1, 1, 6, 6, 2, 2, 1, 1,
+ 3, 3, 7, 7, 1, 1, 8, 8, 1, 1, 2, 2, 1, 9, 1, 9,
+ 4, 4, 10, 1, 1, 10, 1, 1, 11, 11, 3, 3, 1, 2, 1, 2,
+ 1, 1, 12, 12, 5, 5, 1, 1, 13, 1, 1, 13, 2, 2, 1, 1,
+ 6, 6, 1, 1, 4, 14, 4, 14, 3, 1, 3, 1, 1, 1, 15, 7,
+ 15, 2, 2, 7, 1, 1, 1, 8, 1, 8, 16, 16, 1, 1, 1, 1,
+ 2, 1, 1, 2, 1, 1, 3, 5, 5, 3, 4, 1, 1, 4, 1, 1,
+ 17, 17, 9, 1, 1, 9, 2, 2, 1, 1, 10, 10, 1, 6, 1, 1,
+ 6, 18, 1, 1, 18, 1, 1, 1, 2, 2, 3, 1, 3, 1, 1, 1,
+ 4, 1, 19, 1, 19, 7, 1, 1, 20, 1, 4, 20, 1, 7, 11, 2,
+ 1, 11, 21, 2, 8, 5, 1, 8, 1, 5, 21, 1, 1, 1, 22, 1,
+ 1, 22, 1, 1, 3, 3, 1, 23, 2, 12, 24, 1, 1, 2, 1, 1,
+ 12, 23, 1, 1, 24, 1, 1, 1, 4, 1, 1, 1, 2, 1, 6, 6,
+ 4, 2, 1, 1, 1, 1, 1, 1, 1, 14, 13, 3, 1, 25, 9, 25,
+ 14, 1, 9, 3, 13, 1, 1, 1, 1, 1, 10, 1, 1, 2, 10, 2},
+
+ /* value table */
+ {-20, -1, 0, 2, -2, 1, -1, 3, -3, 1, -1, 4, -4, 0, 2, -2,
+ 1, 5, -1, -5, 6, -6, 1, -1, 7, -7, 1, -1, 3, -3, 8, -8,
+ 2, -2, 1, -1, 9, -9, 1, -1, 10, -10, 4, -4, 11, 1, -11, -1,
+ 2, -2, 1, 12, -12, -1, 13, -13, 1, -1, 3, -3, 14, 5, -14, -5,
+ -15, 15, -1, 1, 2, -2, 16, -16, 1, 17, -17, -1, 6, -6, 18, -18,
+ 2, -2, -19, 19, -3, 1, 3, -1, 4, 20, -4, 1, -21, 21, 1, 2,
+ -1, -7, 7, -2, 22, -22, 23, 2, -23, -2, 1, -1, -24, 24, -25, 25,
+ -8, -26, 26, 8, -27, 27, 5, 3, -3, -5, -4, 28, -28, 4, 29, -29,
+ 1, -1, -2, -30, 30, 2, 9, -9, -31, 31, 2, -2, -32, 3, 32, -33,
+ -3, 1, 33, -34, -1, 34, -35, 35, -10, 10, -6, 36, 6, -36, 37, -37,
+ -5, 38, 1, -38, -1, 3, 39, -39, -1, 40, 5, 1, -40, -3, 2, -11,
+ -41, -2, 1, 11, -3, -4, 41, 3, 42, 4, -1, -43, -42, 43, 1, -44,
+ 45, -1, 44, -45, -7, 7, -46, 1, -12, 2, 1, -47, 46, 12, 47, 48,
+ -2, -1, -48, 49, -1, -50, -49, 50, -6, -51, 51, 52, -13, 53, -4, 4,
+ 6, 13, -53, -52, -54, 55, 54, -55, -56, -2, 2, -8, 56, 1, -3, -1,
+ 2, 58, 3, 8, -2, 57, -58, -60, -59, -57, -3, 60, 59, -14, 3, 14}
+},{
+ /* MapTab7 */
+ 2, /* eob_sym */
+ 38, /* esc_sym */
+ /* run table */
+ {1, 1, 0, 2, 2, 1, 1, 3, 3, 4, 4, 5, 5, 1, 1, 6,
+ 6, 2, 2, 7, 7, 8, 8, 1, 1, 3, 3, 9, 9, 10, 10, 1,
+ 1, 2, 2, 4, 4, 11, 0, 11, 12, 12, 13, 13, 1, 1, 5, 5,
+ 14, 14, 15, 16, 15, 16, 3, 3, 1, 6, 1, 6, 2, 2, 7, 7,
+ 8, 8, 17, 17, 1, 1, 4, 4, 18, 18, 2, 2, 1, 19, 1, 20,
+ 19, 20, 21, 21, 3, 3, 22, 22, 5, 5, 24, 1, 1, 23, 9, 23,
+ 24, 9, 2, 2, 10, 1, 1, 10, 6, 6, 25, 4, 4, 25, 7, 7,
+ 26, 8, 1, 8, 3, 1, 26, 3, 11, 11, 27, 27, 2, 28, 1, 2,
+ 28, 1, 12, 12, 5, 5, 29, 13, 13, 29, 32, 1, 1, 33, 31, 30,
+ 32, 4, 30, 33, 4, 31, 3, 14, 1, 1, 3, 34, 34, 2, 2, 14,
+ 6, 6, 35, 36, 35, 36, 1, 15, 1, 16, 16, 15, 7, 9, 7, 9,
+ 37, 8, 8, 37, 1, 1, 39, 2, 38, 39, 2, 40, 5, 38, 40, 5,
+ 3, 3, 4, 4, 10, 10, 1, 1, 1, 1, 41, 2, 41, 2, 6, 6,
+ 1, 1, 11, 42, 11, 43, 3, 42, 3, 17, 4, 43, 1, 17, 7, 1,
+ 8, 44, 4, 7, 44, 5, 8, 2, 5, 1, 2, 48, 45, 1, 12, 45,
+ 12, 48, 13, 13, 1, 9, 9, 46, 1, 46, 47, 47, 49, 18, 18, 49},
+
+ /* value table */
+ { 1, -1, 0, 1, -1, 2, -2, 1, -1, 1, -1, 1, -1, 3, -3, 1,
+ -1, -2, 2, 1, -1, 1, -1, 4, -4, -2, 2, 1, -1, 1, -1, 5,
+ -5, -3, 3, 2, -2, 1, 0, -1, 1, -1, 1, -1, 6, -6, 2, -2,
+ 1, -1, 1, 1, -1, -1, -3, 3, 7, 2, -7, -2, -4, 4, 2, -2,
+ 2, -2, 1, -1, 8, -8, 3, -3, 1, -1, -5, 5, 9, 1, -9, 1,
+ -1, -1, 1, -1, -4, 4, 1, -1, 3, -3, 1, -10, 10, 1, 2, -1,
+ -1, -2, 6, -6, 2, 11, -11, -2, 3, -3, 1, -4, 4, -1, 3, -3,
+ 1, 3, 12, -3, -5, -12, -1, 5, 2, -2, 1, -1, -7, 1, 13, 7,
+ -1, -13, 2, -2, 4, -4, 1, 2, -2, -1, 1, 14, -14, 1, 1, 1,
+ -1, -5, -1, -1, 5, -1, -6, 2, -15, 15, 6, 1, -1, -8, 8, -2,
+ -4, 4, 1, 1, -1, -1, 16, 2, -16, -2, 2, -2, 4, 3, -4, -3,
+ -1, -4, 4, 1, -17, 17, -1, -9, 1, 1, 9, 1, -5, -1, -1, 5,
+ -7, 7, 6, -6, 3, -3, 18, -18, 19, -19, 1, -10, -1, 10, -5, 5,
+ 20, -20, -3, 1, 3, 1, 8, -1, -8, 2, 7, -1, -21, -2, 5, 21,
+ 5, -1, -7, -5, 1, -6, -5, -11, 6, 22, 11, 1, 1, -22, -3, -1,
+ 3, -1, 3, -3, -23, 4, -4, 1, 23, -1, 1, -1, 1, -2, 2, -1}
+},{
+ /* MapTab8 */
+ 4, /* eob_sym */
+ 11, /* esc_sym */
+ /* run table */
+ {1, 1, 1, 1, 0, 2, 2, 1, 1, 3, 3, 0, 1, 1, 2, 2,
+ 4, 4, 1, 1, 5, 5, 1, 1, 2, 2, 3, 3, 6, 6, 1, 1,
+ 7, 7, 8, 1, 8, 2, 2, 1, 4, 4, 1, 3, 1, 3, 9, 9,
+ 2, 2, 1, 5, 1, 5, 10, 10, 1, 1, 11, 11, 3, 6, 3, 4,
+ 4, 6, 2, 2, 1, 12, 1, 12, 7, 13, 7, 13, 1, 1, 8, 8,
+ 2, 2, 14, 14, 16, 15, 16, 5, 5, 1, 3, 15, 1, 3, 4, 4,
+ 1, 1, 17, 17, 2, 2, 6, 6, 1, 18, 1, 18, 22, 21, 22, 21,
+ 25, 24, 25, 19, 9, 20, 9, 23, 19, 24, 20, 3, 23, 7, 3, 1,
+ 1, 7, 28, 26, 29, 5, 28, 26, 5, 8, 29, 4, 8, 27, 2, 2,
+ 4, 27, 1, 1, 10, 36, 10, 33, 33, 36, 30, 1, 32, 32, 1, 30,
+ 6, 31, 31, 35, 3, 6, 11, 11, 3, 2, 35, 2, 34, 1, 34, 1,
+ 37, 37, 12, 7, 12, 5, 41, 5, 4, 7, 1, 8, 13, 4, 1, 41,
+ 13, 38, 8, 38, 9, 1, 40, 40, 9, 1, 39, 2, 2, 49, 39, 42,
+ 3, 3, 14, 16, 49, 14, 16, 42, 43, 43, 6, 6, 15, 1, 1, 15,
+ 44, 44, 1, 1, 50, 48, 4, 5, 4, 7, 5, 2, 10, 10, 48, 7,
+ 50, 45, 2, 1, 45, 8, 8, 1, 46, 46, 3, 47, 47, 3, 1, 1},
+
+ /* value table */
+ { 1, -1, 2, -2, 0, 1, -1, 3, -3, 1, -1, 0, 4, -4, 2, -2,
+ 1, -1, 5, -5, 1, -1, 6, -6, 3, -3, 2, -2, 1, -1, 7, -7,
+ 1, -1, 1, 8, -1, 4, -4, -8, 2, -2, 9, 3, -9, -3, 1, -1,
+ 5, -5, 10, 2, -10, -2, 1, -1, 11, -11, 1, -1, -4, 2, 4, 3,
+ -3, -2, 6, -6, 12, 1, -12, -1, 2, 1, -2, -1, 13, -13, 2, -2,
+ 7, -7, 1, -1, 1, 1, -1, 3, -3, 14, 5, -1, -14, -5, 4, -4,
+ 15, -15, 1, -1, 8, -8, -3, 3, 16, 1, -16, -1, 1, 1, -1, -1,
+ 1, 1, -1, 1, 2, 1, -2, 1, -1, -1, -1, 6, -1, 3, -6, 17,
+ -17, -3, 1, 1, 1, 4, -1, -1, -4, 3, -1, 5, -3, -1, -9, 9,
+ -5, 1, 18, -18, 2, 1, -2, 1, -1, -1, 1, 19, -1, 1, -19, -1,
+ 4, 1, -1, 1, 7, -4, -2, 2, -7, 10, -1, -10, 1, 20, -1, -20,
+ 1, -1, 2, 4, -2, 5, 1, -5, 6, -4, 21, 4, 2, -6, -21, -1,
+ -2, 1, -4, -1, -3, 22, -1, 1, 3, -22, -1, 11, -11, 1, 1, 1,
+ 8, -8, 2, 2, -1, -2, -2, -1, 1, -1, -5, 5, 2, 23, -23, -2,
+ 1, -1, 24, -24, -1, -1, 7, 6, -7, 5, -6, 12, -3, 3, 1, -5,
+ 1, 1, -12, 25, -1, -5, 5, -25, -1, 1, 9, 1, -1, -9, 26, -26}
+}
+};
Added: indeo5/ivi_common.h
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ indeo5/ivi_common.h Thu Dec 10 02:21:27 2009 (r5523)
@@ -0,0 +1,217 @@
+/*
+ * common functions for Indeo Video Interactive codecs (indeo4 and indeo5)
+ *
+ * Copyright (c) 2009 Maxim Poliakovski
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file libavcodec/ivi_common.h
+ * This file contains structures and macros shared by both Indeo4 and Indeo5 decoders.
+ */
+
+#ifndef AVCODEC_IVI_COMMON_H
+#define AVCODEC_IVI_COMMON_H
+
+#include <stdint.h>
+
+#define IVI_DEBUG
+
+#define IVI_VLC_BITS 13 ///< max number of bits of the ivi's huffman codes
+
+/**
+ * huffman codebook descriptor
+ */
+typedef struct {
+ int32_t num_rows;
+ uint8_t xbits[16];
+} IVIHuffDesc;
+
+/* see ivi_common.c for a definition */
+extern const IVIHuffDesc ff_ivi_mb_huff_desc[8]; ///< static macroblock huffman tables
+extern const IVIHuffDesc ff_ivi_blk_huff_desc[8]; ///< static block huffman tables
+
+
+/**
+ * Run-value (RLE) table descriptor
+ */
+typedef struct {
+ uint8_t eob_sym; ///< huffman symbol for EOB (end of block)
+ uint8_t esc_sym; ///< huffman symbol for ESC (escape)
+ uint8_t runtab[256];
+ int8_t valtab[256];
+} RVMapDesc;
+
+extern const RVMapDesc ff_ivi_rvmap_tabs[9]; /* defined in ivi_common.c */
+
+
+/**
+ * This structure describes an indeo macroblock (16x16, 8x8 or 4x4).
+ */
+typedef struct {
+ int16_t xpos;
+ int16_t ypos;
+ uint32_t buf_offs; ///< address in the output buffer for this mb
+ uint8_t type; ///< macroblock type: 0 - INTRA, 1 - INTER
+ uint8_t cbp; ///< coded block pattern
+ uint8_t q_delta; ///< quant delta
+ int8_t mv_x; ///< motion vector (x component)
+ int8_t mv_y; ///< motion vector (y component)
+} IVIMbInfo;
+
+
+/**
+ * This structure describes an indeo tile.
+ */
+typedef struct {
+ uint32_t xpos;
+ uint32_t ypos;
+ uint32_t width;
+ uint32_t height;
+ int32_t is_empty; ///< = 1 if this tile doesn't contain any data
+ uint32_t data_size; ///< size of the data in bytes
+ uint32_t num_MBs; ///< number of macroblocks in this tile
+ IVIMbInfo *mbs; ///< array of macroblock descriptors
+ IVIMbInfo *ref_mbs; ///< ptr to the macroblock descriptors of the reference tile
+} IVITile;
+
+
+/**
+ * This structure describes an indeo wavelet band.
+ */
+typedef struct {
+ uint8_t plane; ///< plane number this band belongs to
+ uint8_t band_num; ///< band number
+ uint32_t width;
+ uint32_t height;
+ const uint8_t *data_ptr; ///< ptr to the first byte of the band data
+ uint32_t data_size; ///< size of the band data
+ int16_t *buf; ///< ptr to the output buffer for this band
+ int16_t *ref_buf; ///< ptr to the reference frame buffer for motion compensation
+ int16_t *buf1; ///< primary band buffer
+ int16_t *buf2; ///< secondary band buffer
+ uint32_t pitch; ///< pitch associated with the buffers above
+ uint8_t is_empty; ///< = 1 if this band doesn't contain any data
+ uint8_t mb_size; ///< macroblock size
+ uint8_t blk_size; ///< block size
+ uint8_t mc_resolution; ///< resolution of the motion compensation: 0 - fullpel, 1 - halfpel
+ int8_t inherit_mv;
+ int8_t inherit_qdelta;
+ int8_t qdelta_present; ///< tells if Qdelta signal is present in the bitstream (indeo5 only)
+ uint8_t quant_mat; ///< dequant matrix
+ uint8_t glob_quant; ///< quant base for this band
+ const uint8_t *scan; ///< ptr to the scan pattern
+
+ uint8_t huff_sel; ///< huffman table for this band
+ IVIHuffDesc huff_desc; ///< table descriptor associated with the selector above
+ VLC *blk_vlc; ///< ptr to the vlc table for decoding block data
+ VLC blk_vlc_cust; ///< custom block vlc table
+
+ uint16_t *dequant_intra; ///< ptr to dequant tables for intra blocks
+ uint16_t *dequant_inter; ///< ptr dequant tables for inter blocks
+ uint8_t num_corr; ///< number of correction entries
+ uint8_t corr[61*2]; ///< rvmap correction pairs
+ uint8_t rvmap_sel; ///< rvmap table selector
+ RVMapDesc *rv_map; ///< ptr to the RLE table for this band
+ uint16_t num_tiles; ///< number of tiles in this band
+ IVITile *tiles; ///< array of tile descriptors
+ void (*inv_transform)(int32_t *in, int16_t *out, uint32_t pitch, uint8_t *flags); ///< ptr to inverse transform function
+ void (*dc_transform) (int32_t *in, int16_t *out, uint32_t pitch, int blk_size); ///< ptr to dc transform function or NULL
+ uint8_t is_2d_trans; ///< 1 indicates that the two-dimensional inverse transform
+#ifdef IVI_DEBUG
+ uint16_t checksum; ///< for debug purposes
+ int32_t checksum_present;
+ uint32_t bufsize; ///< band buffer size in bytes
+#endif
+ const uint8_t *intra_base;
+ const uint8_t *inter_base;
+ const uint8_t *intra_scale;
+ const uint8_t *inter_scale;
+} IVIBandDesc;
+
+
+/**
+ * This structure describes a color plane (luma or chroma).
+ */
+typedef struct {
+ uint16_t width;
+ uint16_t height;
+ // uint32_t pitch;
+ uint8_t buf_switch; ///< used to switch between two buffers
+ //int16_t *buf1; ///< primary buffer to store decoded pixels
+ //int16_t *buf2; ///< secondary buffer to store decoded pixels
+ uint8_t num_bands; ///< number of bands this plane subdivided into
+ IVIBandDesc *bands; ///< array of band descriptors
+} IVIPlaneDesc;
+
+
+typedef struct {
+ uint16_t pic_width;
+ uint16_t pic_height;
+ uint16_t chroma_width;
+ uint16_t chroma_height;
+ uint16_t tile_width;
+ uint16_t tile_height;
+ uint8_t luma_bands;
+ uint8_t chroma_bands;
+} IVIPicConfig;
+
+static inline int ivi_pic_config_cmp(IVIPicConfig *str1, IVIPicConfig *str2)
+{
+ return (str1->pic_width != str2->pic_width || str1->pic_height != str2->pic_height ||
+ str1->chroma_width != str2->chroma_width || str1->chroma_height != str2->chroma_height ||
+ str1->tile_width != str2->tile_width || str1->tile_height != str2->tile_height ||
+ str1->luma_bands != str2->luma_bands || str1->chroma_bands != str2->chroma_bands);
+}
+
+/** calculate number of tiles in a stride */
+#define IVI_NUM_TILES(stride, tile_size) (((stride) + (tile_size) - 1) / (tile_size))
+
+/** calculate number of macroblocks in a tile */
+#define IVI_MBs_PER_TILE(tile_width, tile_height, mb_size) ((((tile_width) + (mb_size) - 1) / (mb_size)) * (((tile_height) + (mb_size) - 1) / (mb_size)))
+
+/** convert unsigned values into signed ones (the sign is in the LSB) */
+/* TODO: find a way to calculate this without the conditional using bit magic */
+#define IVI_TOSIGNED(val) (((val) & 1) ? ((val) + 1) >> 1 : -(((val) + 1) >> 1))
+
+/** divide the motion vector mv by 4 */
+#define IVI_MV_DIV4(mv) (((mv) + 1 + ((mv) > 0))>>2)
+
+/** divide the motion vector mv by 2 */
+#define IVI_MV_DIV2(mv) (((mv) + ((mv) > 0))>>1)
+
+int ff_ivi_create_huff_from_desc(const IVIHuffDesc *cb, VLC *pOut, int flag);
+int ff_ivi_dec_huff_desc(GetBitContext *gb, IVIHuffDesc *desc);
+int ff_ivi_huff_desc_cmp(const IVIHuffDesc *desc1, const IVIHuffDesc *desc2);
+void ff_ivi_huff_desc_copy(IVIHuffDesc *dst, const IVIHuffDesc *src);
+int ff_ivi_init_planes(IVIPlaneDesc *planes, const IVIPicConfig *cfg);
+void ff_ivi_free_buffers(IVIPlaneDesc *planes);
+int ff_ivi_init_tiles(IVIPlaneDesc *planes, const int tile_width, const int tile_height);
+int ff_ivi_dec_tile_data_size(GetBitContext *gb);
+int ff_ivi_decode_blocks(GetBitContext *gb, IVIBandDesc *band, IVITile *tile);
+void ff_ivi_process_empty_tile(AVCodecContext *avctx, IVIBandDesc *band, IVITile *tile, int32_t mv_scale);
+void ff_ivi_output_plane(IVIPlaneDesc *plane, uint8_t *dst, int dst_pitch);
+void ff_ivi_put_pixels_8x8(int32_t *in, int16_t *out, uint32_t pitch, uint8_t *flags);
+void ff_ivi_put_dc_pixel_8x8(int32_t *in, int16_t *out, uint32_t pitch, int blk_size);
+
+#ifdef IVI_DEBUG
+uint16_t ivi_calc_band_checksum (IVIBandDesc *band);
+int ivi_check_band (IVIBandDesc *band, uint8_t *ref, int pitch);
+#endif
+
+#endif /* AVCODEC_IVI_COMMON_H */
More information about the FFmpeg-soc
mailing list