Unified · Split
| @@ -111,6 +111,7 @@ easier to use. The changes are: · 110 unmodified lines | ||
| 111 | 111 | - v410 QuickTime uncompressed 4:4:4 10-bit encoder and decoder |
| 112 | 112 | - OpenMG Audio muxer |
| 113 | 113 | - Simple segmenting muxer |
| 114 | +- Indeo 4 decoder | |
| 114 | 115 | |
| 115 | 116 | |
| 116 | 117 | version 0.7: |
| @@ -491,6 +491,7 @@ following image formats are supported: · 490 unmodified lines | ||
| 491 | 491 | @item Intel H.263 @tab @tab X |
| 492 | 492 | @item Intel Indeo 2 @tab @tab X |
| 493 | 493 | @item Intel Indeo 3 @tab @tab X |
| 494 | +@item Intel Indeo 4 @tab @tab X | |
| 494 | 495 | @item Intel Indeo 5 @tab @tab X |
| 495 | 496 | @item Interplay C93 @tab @tab X |
| 496 | 497 | @tab Used in the game Cyberia from Interplay. |
| @@ -191,6 +191,7 @@ OBJS-$(CONFIG_IFF_ILBM_DECODER) += iff.o · 190 unmodified lines | ||
| 191 | 191 | OBJS-$(CONFIG_IMC_DECODER) += imc.o |
| 192 | 192 | OBJS-$(CONFIG_INDEO2_DECODER) += indeo2.o |
| 193 | 193 | OBJS-$(CONFIG_INDEO3_DECODER) += indeo3.o |
| 194 | +OBJS-$(CONFIG_INDEO4_DECODER) += indeo4.o ivi_common.o ivi_dsp.o | |
| 194 | 195 | OBJS-$(CONFIG_INDEO5_DECODER) += indeo5.o ivi_common.o ivi_dsp.o |
| 195 | 196 | OBJS-$(CONFIG_INTERPLAY_DPCM_DECODER) += dpcm.o |
| 196 | 197 | OBJS-$(CONFIG_INTERPLAY_VIDEO_DECODER) += interplayvideo.o |
| @@ -128,6 +128,7 @@ void avcodec_register_all(void) · 127 unmodified lines | ||
| 128 | 128 | REGISTER_DECODER (IFF_ILBM, iff_ilbm); |
| 129 | 129 | REGISTER_DECODER (INDEO2, indeo2); |
| 130 | 130 | REGISTER_DECODER (INDEO3, indeo3); |
| 131 | + REGISTER_DECODER (INDEO4, indeo4); | |
| 131 | 132 | REGISTER_DECODER (INDEO5, indeo5); |
| 132 | 133 | REGISTER_DECODER (INTERPLAY_VIDEO, interplay_video); |
| 133 | 134 | REGISTER_ENCDEC (JPEGLS, jpegls); |
| @@ -0,0 +1,823 @@ | ||
| 1 | +/* | |
| 2 | + * Indeo Video Interactive v4 compatible decoder | |
| 3 | + * Copyright (c) 2009-2011 Maxim Poliakovski | |
| 4 | + * | |
| 5 | + * This file is part of Libav. | |
| 6 | + * | |
| 7 | + * Libav 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 | + * Libav 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 Libav; 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 | + * Indeo Video Interactive version 4 decoder | |
| 25 | + * | |
| 26 | + * Indeo 4 data is usually transported within .avi or .mov files. | |
| 27 | + * Known FOURCCs: 'IV41' | |
| 28 | + */ | |
| 29 | + | |
| 30 | +#define BITSTREAM_READER_LE | |
| 31 | +#include "avcodec.h" | |
| 32 | +#include "get_bits.h" | |
| 33 | +#include "dsputil.h" | |
| 34 | +#include "ivi_dsp.h" | |
| 35 | +#include "ivi_common.h" | |
| 36 | +#include "indeo4data.h" | |
| 37 | + | |
| 38 | +#define IVI4_STREAM_ANALYSER 0 | |
| 39 | +#define IVI4_DEBUG_CHECKSUM 0 | |
| 40 | + | |
| 41 | +/** | |
| 42 | + * Indeo 4 frame types. | |
| 43 | + */ | |
| 44 | +enum { | |
| 45 | + FRAMETYPE_INTRA = 0, | |
| 46 | + FRAMETYPE_BIDIR1 = 1, ///< bidirectional frame | |
| 47 | + FRAMETYPE_INTER = 2, ///< non-droppable P-frame | |
| 48 | + FRAMETYPE_BIDIR = 3, ///< bidirectional frame | |
| 49 | + FRAMETYPE_INTER_NOREF = 4, ///< droppable P-frame | |
| 50 | + FRAMETYPE_NULL_FIRST = 5, ///< empty frame with no data | |
| 51 | + FRAMETYPE_NULL_LAST = 6 ///< empty frame with no data | |
| 52 | +}; | |
| 53 | + | |
| 54 | +#define IVI4_PIC_SIZE_ESC 7 | |
| 55 | + | |
| 56 | + | |
| 57 | +typedef struct { | |
| 58 | + GetBitContext gb; | |
| 59 | + AVFrame frame; | |
| 60 | + RVMapDesc rvmap_tabs[9]; ///< local corrected copy of the static rvmap tables | |
| 61 | + | |
| 62 | + uint32_t frame_num; | |
| 63 | + int frame_type; | |
| 64 | + int prev_frame_type; ///< frame type of the previous frame | |
| 65 | + uint32_t data_size; ///< size of the frame data in bytes from picture header | |
| 66 | + int is_scalable; | |
| 67 | + int transp_status; ///< transparency mode status: 1 - enabled | |
| 68 | + | |
| 69 | + IVIPicConfig pic_conf; | |
| 70 | + IVIPlaneDesc planes[3]; ///< color planes | |
| 71 | + | |
| 72 | + int buf_switch; ///< used to switch between three buffers | |
| 73 | + int dst_buf; ///< buffer index for the currently decoded frame | |
| 74 | + int ref_buf; ///< inter frame reference buffer index | |
| 75 | + | |
| 76 | + IVIHuffTab mb_vlc; ///< current macroblock table descriptor | |
| 77 | + IVIHuffTab blk_vlc; ///< current block table descriptor | |
| 78 | + | |
| 79 | + uint16_t checksum; ///< frame checksum | |
| 80 | + | |
| 81 | + uint8_t rvmap_sel; | |
| 82 | + uint8_t in_imf; | |
| 83 | + uint8_t in_q; ///< flag for explicitly stored quantiser delta | |
| 84 | + uint8_t pic_glob_quant; | |
| 85 | + uint8_t unknown1; | |
| 86 | + | |
| 87 | +#if IVI4_STREAM_ANALYSER | |
| 88 | + uint8_t has_b_frames; | |
| 89 | + uint8_t has_transp; | |
| 90 | + uint8_t uses_tiling; | |
| 91 | + uint8_t uses_haar; | |
| 92 | + uint8_t uses_fullpel; | |
| 93 | +#endif | |
| 94 | +} IVI4DecContext; | |
| 95 | + | |
| 96 | + | |
| 97 | +struct { | |
| 98 | + InvTransformPtr *inv_trans; | |
| 99 | + DCTransformPtr *dc_trans; | |
| 100 | + int is_2d_trans; | |
| 101 | +} transforms[18] = { | |
| 102 | + { ff_ivi_inverse_haar_8x8, ff_ivi_dc_haar_2d, 1 }, | |
| 103 | + { NULL, NULL, 0 }, /* inverse Haar 8x1 */ | |
| 104 | + { NULL, NULL, 0 }, /* inverse Haar 1x8 */ | |
| 105 | + { ff_ivi_put_pixels_8x8, ff_ivi_put_dc_pixel_8x8, 1 }, | |
| 106 | + { ff_ivi_inverse_slant_8x8, ff_ivi_dc_slant_2d, 1 }, | |
| 107 | + { ff_ivi_row_slant8, ff_ivi_dc_row_slant, 1 }, | |
| 108 | + { ff_ivi_col_slant8, ff_ivi_dc_col_slant, 1 }, | |
| 109 | + { NULL, NULL, 0 }, /* inverse DCT 8x8 */ | |
| 110 | + { NULL, NULL, 0 }, /* inverse DCT 8x1 */ | |
| 111 | + { NULL, NULL, 0 }, /* inverse DCT 1x8 */ | |
| 112 | + { NULL, NULL, 0 }, /* inverse Haar 4x4 */ | |
| 113 | + { ff_ivi_inverse_slant_4x4, ff_ivi_dc_slant_2d, 1 }, | |
| 114 | + { NULL, NULL, 0 }, /* no transform 4x4 */ | |
| 115 | + { NULL, NULL, 0 }, /* inverse Haar 1x4 */ | |
| 116 | + { NULL, NULL, 0 }, /* inverse Haar 4x1 */ | |
| 117 | + { NULL, NULL, 0 }, /* inverse slant 1x4 */ | |
| 118 | + { NULL, NULL, 0 }, /* inverse slant 4x1 */ | |
| 119 | + { NULL, NULL, 0 }, /* inverse DCT 4x4 */ | |
| 120 | +}; | |
| 121 | + | |
| 122 | +/** | |
| 123 | + * Decode subdivision of a plane. | |
| 124 | + * This is a simplified version that checks for two supported subdivisions: | |
| 125 | + * - 1 wavelet band per plane, size factor 1:1, code pattern: 3 | |
| 126 | + * - 4 wavelet bands per plane, size factor 1:4, code pattern: 2,3,3,3,3 | |
| 127 | + * Anything else is either unsupported or corrupt. | |
| 128 | + * | |
| 129 | + * @param[in,out] gb the GetBit context | |
| 130 | + * @return number of wavelet bands or 0 on error | |
| 131 | + */ | |
| 132 | +static int decode_plane_subdivision(GetBitContext *gb) | |
| 133 | +{ | |
| 134 | + int i; | |
| 135 | + | |
| 136 | + switch (get_bits(gb, 2)) { | |
| 137 | + case 3: | |
| 138 | + return 1; | |
| 139 | + case 2: | |
| 140 | + for (i = 0; i < 4; i++) | |
| 141 | + if (get_bits(gb, 2) != 3) | |
| 142 | + return 0; | |
| 143 | + return 4; | |
| 144 | + default: | |
| 145 | + return 0; | |
| 146 | + } | |
| 147 | +} | |
| 148 | + | |
| 149 | +static inline int scale_tile_size(int def_size, int size_factor) | |
| 150 | +{ | |
| 151 | + return (size_factor == 15 ? def_size : (size_factor + 1) << 5); | |
| 152 | +} | |
| 153 | + | |
| 154 | +/** | |
| 155 | + * Decode Indeo 4 picture header. | |
| 156 | + * | |
| 157 | + * @param[in,out] ctx pointer to the decoder context | |
| 158 | + * @param[in] avctx pointer to the AVCodecContext | |
| 159 | + * @return result code: 0 = OK, negative number = error | |
| 160 | + */ | |
| 161 | +static int decode_pic_hdr(IVI4DecContext *ctx, AVCodecContext *avctx) | |
| 162 | +{ | |
| 163 | + int pic_size_indx, val, i, p; | |
| 164 | + IVIPicConfig pic_conf; | |
| 165 | + | |
| 166 | + if (get_bits(&ctx->gb, 18) != 0x3FFF8) { | |
| 167 | + av_log(avctx, AV_LOG_ERROR, "Invalid picture start code!\n"); | |
| 168 | + return AVERROR_INVALIDDATA; | |
| 169 | + } | |
| 170 | + | |
| 171 | + ctx->prev_frame_type = ctx->frame_type; | |
| 172 | + ctx->frame_type = get_bits(&ctx->gb, 3); | |
| 173 | + if (ctx->frame_type == 7) { | |
| 174 | + av_log(avctx, AV_LOG_ERROR, "Invalid frame type: %d\n", ctx->frame_type); | |
| 175 | + return AVERROR_INVALIDDATA; | |
| 176 | + } | |
| 177 | + | |
| 178 | +#if IVI4_STREAM_ANALYSER | |
| 179 | + if ( ctx->frame_type == FRAMETYPE_BIDIR1 | |
| 180 | + || ctx->frame_type == FRAMETYPE_BIDIR) | |
| 181 | + ctx->has_b_frames = 1; | |
| 182 | +#endif | |
| 183 | + | |
| 184 | + ctx->transp_status = get_bits1(&ctx->gb); | |
| 185 | +#if IVI4_STREAM_ANALYSER | |
| 186 | + if (ctx->transp_status) { | |
| 187 | + ctx->has_transp = 1; | |
| 188 | + } | |
| 189 | +#endif | |
| 190 | + | |
| 191 | + /* unknown bit: Mac decoder ignores this bit, XANIM returns error */ | |
| 192 | + if (get_bits1(&ctx->gb)) { | |
| 193 | + av_log(avctx, AV_LOG_ERROR, "Sync bit is set!\n"); | |
| 194 | + return AVERROR_INVALIDDATA; | |
| 195 | + } | |
| 196 | + | |
| 197 | + ctx->data_size = get_bits1(&ctx->gb) ? get_bits(&ctx->gb, 24) : 0; | |
| 198 | + | |
| 199 | + /* null frames don't contain anything else so we just return */ | |
| 200 | + if (ctx->frame_type >= FRAMETYPE_NULL_FIRST) { | |
| 201 | + av_dlog(avctx, "Null frame encountered!\n"); | |
| 202 | + return 0; | |
| 203 | + } | |
| 204 | + | |
| 205 | + /* Check key lock status. If enabled - ignore lock word. */ | |
| 206 | + /* Usually we have to prompt the user for the password, but */ | |
| 207 | + /* we don't do that because Indeo 4 videos can be decoded anyway */ | |
| 208 | + if (get_bits1(&ctx->gb)) { | |
| 209 | + skip_bits_long(&ctx->gb, 32); | |
| 210 | + av_dlog(avctx, "Password-protected clip!\n"); | |
| 211 | + } | |
| 212 | + | |
| 213 | + pic_size_indx = get_bits(&ctx->gb, 3); | |
| 214 | + if (pic_size_indx == IVI4_PIC_SIZE_ESC) { | |
| 215 | + pic_conf.pic_height = get_bits(&ctx->gb, 16); | |
| 216 | + pic_conf.pic_width = get_bits(&ctx->gb, 16); | |
| 217 | + } else { | |
| 218 | + pic_conf.pic_height = ivi4_common_pic_sizes[pic_size_indx * 2 + 1]; | |
| 219 | + pic_conf.pic_width = ivi4_common_pic_sizes[pic_size_indx * 2 ]; | |
| 220 | + } | |
| 221 | + | |
| 222 | + /* Decode tile dimensions. */ | |
| 223 | + if (get_bits1(&ctx->gb)) { | |
| 224 | + pic_conf.tile_height = scale_tile_size(pic_conf.pic_height, get_bits(&ctx->gb, 4)); | |
| 225 | + pic_conf.tile_width = scale_tile_size(pic_conf.pic_width, get_bits(&ctx->gb, 4)); | |
| 226 | +#if IVI4_STREAM_ANALYSER | |
| 227 | + ctx->uses_tiling = 1; | |
| 228 | +#endif | |
| 229 | + } else { | |
| 230 | + pic_conf.tile_height = pic_conf.pic_height; | |
| 231 | + pic_conf.tile_width = pic_conf.pic_width; | |
| 232 | + } | |
| 233 | + | |
| 234 | + /* Decode chroma subsampling. We support only 4:4 aka YVU9. */ | |
| 235 | + if (get_bits(&ctx->gb, 2)) { | |
| 236 | + av_log(avctx, AV_LOG_ERROR, "Only YVU9 picture format is supported!\n"); | |
| 237 | + return AVERROR_INVALIDDATA; | |
| 238 | + } | |
| 239 | + pic_conf.chroma_height = (pic_conf.pic_height + 3) >> 2; | |
| 240 | + pic_conf.chroma_width = (pic_conf.pic_width + 3) >> 2; | |
| 241 | + | |
| 242 | + /* decode subdivision of the planes */ | |
| 243 | + pic_conf.luma_bands = decode_plane_subdivision(&ctx->gb); | |
| 244 | + if (pic_conf.luma_bands) | |
| 245 | + pic_conf.chroma_bands = decode_plane_subdivision(&ctx->gb); | |
| 246 | + ctx->is_scalable = pic_conf.luma_bands != 1 || pic_conf.chroma_bands != 1; | |
| 247 | + if (ctx->is_scalable && (pic_conf.luma_bands != 4 || pic_conf.chroma_bands != 1)) { | |
| 248 | + av_log(avctx, AV_LOG_ERROR, "Scalability: unsupported subdivision! Luma bands: %d, chroma bands: %d\n", | |
| 249 | + pic_conf.luma_bands, pic_conf.chroma_bands); | |
| 250 | + return AVERROR_INVALIDDATA; | |
| 251 | + } | |
| 252 | + | |
| 253 | + /* check if picture layout was changed and reallocate buffers */ | |
| 254 | + if (ivi_pic_config_cmp(&pic_conf, &ctx->pic_conf)) { | |
| 255 | + if (ff_ivi_init_planes(ctx->planes, &pic_conf)) { | |
| 256 | + av_log(avctx, AV_LOG_ERROR, "Couldn't reallocate color planes!\n"); | |
| 257 | + return AVERROR(ENOMEM); | |
| 258 | + } | |
| 259 | + | |
| 260 | + ctx->pic_conf = pic_conf; | |
| 261 | + | |
| 262 | + /* set default macroblock/block dimensions */ | |
| 263 | + for (p = 0; p <= 2; p++) { | |
| 264 | + for (i = 0; i < (!p ? pic_conf.luma_bands : pic_conf.chroma_bands); i++) { | |
| 265 | + ctx->planes[p].bands[i].mb_size = !p ? (!ctx->is_scalable ? 16 : 8) : 4; | |
| 266 | + ctx->planes[p].bands[i].blk_size = !p ? 8 : 4; | |
| 267 | + } | |
| 268 | + } | |
| 269 | + | |
| 270 | + if (ff_ivi_init_tiles(ctx->planes, ctx->pic_conf.tile_width, | |
| 271 | + ctx->pic_conf.tile_height)) { | |
| 272 | + av_log(avctx, AV_LOG_ERROR, | |
| 273 | + "Couldn't reallocate internal structures!\n"); | |
| 274 | + return AVERROR(ENOMEM); | |
| 275 | + } | |
| 276 | + } | |
| 277 | + | |
| 278 | + ctx->frame_num = get_bits1(&ctx->gb) ? get_bits(&ctx->gb, 20) : 0; | |
| 279 | + | |
| 280 | + /* skip decTimeEst field if present */ | |
| 281 | + if (get_bits1(&ctx->gb)) | |
| 282 | + skip_bits(&ctx->gb, 8); | |
| 283 | + | |
| 284 | + /* decode macroblock and block huffman codebooks */ | |
| 285 | + if (ff_ivi_dec_huff_desc(&ctx->gb, get_bits1(&ctx->gb), IVI_MB_HUFF, &ctx->mb_vlc, avctx) || | |
| 286 | + ff_ivi_dec_huff_desc(&ctx->gb, get_bits1(&ctx->gb), IVI_BLK_HUFF, &ctx->blk_vlc, avctx)) | |
| 287 | + return AVERROR_INVALIDDATA; | |
| 288 | + | |
| 289 | + ctx->rvmap_sel = get_bits1(&ctx->gb) ? get_bits(&ctx->gb, 3) : 8; | |
| 290 | + | |
| 291 | + ctx->in_imf = get_bits1(&ctx->gb); | |
| 292 | + ctx->in_q = get_bits1(&ctx->gb); | |
| 293 | + | |
| 294 | + ctx->pic_glob_quant = get_bits(&ctx->gb, 5); | |
| 295 | + | |
| 296 | + /* TODO: ignore this parameter if unused */ | |
| 297 | + ctx->unknown1 = get_bits1(&ctx->gb) ? get_bits(&ctx->gb, 3) : 0; | |
| 298 | + | |
| 299 | + ctx->checksum = get_bits1(&ctx->gb) ? get_bits(&ctx->gb, 16) : 0; | |
| 300 | + | |
| 301 | + /* skip picture header extension if any */ | |
| 302 | + while (get_bits1(&ctx->gb)) { | |
| 303 | + av_dlog(avctx, "Pic hdr extension encountered!\n"); | |
| 304 | + val = get_bits(&ctx->gb, 8); | |
| 305 | + } | |
| 306 | + | |
| 307 | + if (get_bits1(&ctx->gb)) { | |
| 308 | + av_log(avctx, AV_LOG_ERROR, "Bad blocks bits encountered!\n"); | |
| 309 | + } | |
| 310 | + | |
| 311 | + align_get_bits(&ctx->gb); | |
| 312 | + | |
| 313 | + return 0; | |
| 314 | +} | |
| 315 | + | |
| 316 | + | |
| 317 | +/** | |
| 318 | + * Decode Indeo 4 band header. | |
| 319 | + * | |
| 320 | + * @param[in,out] ctx pointer to the decoder context | |
| 321 | + * @param[in,out] band pointer to the band descriptor | |
| 322 | + * @param[in] avctx pointer to the AVCodecContext | |
| 323 | + * @return result code: 0 = OK, negative number = error | |
| 324 | + */ | |
| 325 | +static int decode_band_hdr(IVI4DecContext *ctx, IVIBandDesc *band, | |
| 326 | + AVCodecContext *avctx) | |
| 327 | +{ | |
| 328 | + int plane, band_num, hdr_size, indx, transform_id, scan_indx; | |
| 329 | + int i; | |
| 330 | + | |
| 331 | + plane = get_bits(&ctx->gb, 2); | |
| 332 | + band_num = get_bits(&ctx->gb, 4); | |
| 333 | + if (band->plane != plane || band->band_num != band_num) { | |
| 334 | + av_log(avctx, AV_LOG_ERROR, "Invalid band header sequence!\n"); | |
| 335 | + return AVERROR_INVALIDDATA; | |
| 336 | + } | |
| 337 | + | |
| 338 | + band->is_empty = get_bits1(&ctx->gb); | |
| 339 | + if (!band->is_empty) { | |
| 340 | + hdr_size = get_bits1(&ctx->gb) ? get_bits(&ctx->gb, 16) : 4; | |
| 341 | + | |
| 342 | + band->is_halfpel = get_bits(&ctx->gb, 2); | |
| 343 | + if (band->is_halfpel >= 2) { | |
| 344 | + av_log(avctx, AV_LOG_ERROR, "Invalid/unsupported mv resolution: %d!\n", | |
| 345 | + band->is_halfpel); | |
| 346 | + return AVERROR_INVALIDDATA; | |
| 347 | + } | |
| 348 | +#if IVI4_STREAM_ANALYSER | |
| 349 | + if (!band->is_halfpel) | |
| 350 | + ctx->uses_fullpel = 1; | |
| 351 | +#endif | |
| 352 | + | |
| 353 | + band->checksum_present = get_bits1(&ctx->gb); | |
| 354 | + if (band->checksum_present) | |
| 355 | + band->checksum = get_bits(&ctx->gb, 16); | |
| 356 | + | |
| 357 | + indx = get_bits(&ctx->gb, 2); | |
| 358 | + if (indx == 3) { | |
| 359 | + av_log(avctx, AV_LOG_ERROR, "Invalid block size!\n"); | |
| 360 | + return AVERROR_INVALIDDATA; | |
| 361 | + } | |
| 362 | + band->mb_size = 16 >> indx; | |
| 363 | + band->blk_size = 8 >> (indx >> 1); | |
| 364 | + | |
| 365 | + band->inherit_mv = get_bits1(&ctx->gb); | |
| 366 | + band->inherit_qdelta = get_bits1(&ctx->gb); | |
| 367 | + | |
| 368 | + band->glob_quant = get_bits(&ctx->gb, 5); | |
| 369 | + | |
| 370 | + if (!get_bits1(&ctx->gb) || ctx->frame_type == FRAMETYPE_INTRA) { | |
| 371 | + transform_id = get_bits(&ctx->gb, 5); | |
| 372 | + if (!transforms[transform_id].inv_trans) { | |
| 373 | + av_log_ask_for_sample(avctx, "Unimplemented transform: %d!\n", transform_id); | |
| 374 | + return AVERROR_PATCHWELCOME; | |
| 375 | + } | |
| 376 | + if ((transform_id >= 7 && transform_id <= 9) || | |
| 377 | + transform_id == 17) { | |
| 378 | + av_log_ask_for_sample(avctx, "DCT transform not supported yet!\n"); | |
| 379 | + return AVERROR_PATCHWELCOME; | |
| 380 | + } | |
| 381 | + | |
| 382 | +#if IVI4_STREAM_ANALYSER | |
| 383 | + if ((transform_id >= 0 && transform_id <= 2) || transform_id == 10) | |
| 384 | + ctx->uses_haar = 1; | |
| 385 | +#endif | |
| 386 | + | |
| 387 | + band->inv_transform = transforms[transform_id].inv_trans; | |
| 388 | + band->dc_transform = transforms[transform_id].dc_trans; | |
| 389 | + band->is_2d_trans = transforms[transform_id].is_2d_trans; | |
| 390 | + | |
| 391 | + scan_indx = get_bits(&ctx->gb, 4); | |
| 392 | + if (scan_indx == 15) { | |
| 393 | + av_log(avctx, AV_LOG_ERROR, "Custom scan pattern encountered!\n"); | |
| 394 | + return AVERROR_INVALIDDATA; | |
| 395 | + } | |
| 396 | + band->scan = scan_index_to_tab[scan_indx]; | |
| 397 | + | |
| 398 | + band->quant_mat = get_bits(&ctx->gb, 5); | |
| 399 | + if (band->quant_mat == 31) { | |
| 400 | + av_log(avctx, AV_LOG_ERROR, "Custom quant matrix encountered!\n"); | |
| 401 | + return AVERROR_INVALIDDATA; | |
| 402 | + } | |
| 403 | + } | |
| 404 | + | |
| 405 | + /* decode block huffman codebook */ | |
| 406 | + if (ff_ivi_dec_huff_desc(&ctx->gb, get_bits1(&ctx->gb), IVI_BLK_HUFF, | |
| 407 | + &band->blk_vlc, avctx)) | |
| 408 | + return AVERROR_INVALIDDATA; | |
| 409 | + | |
| 410 | + /* select appropriate rvmap table for this band */ | |
| 411 | + band->rvmap_sel = get_bits1(&ctx->gb) ? get_bits(&ctx->gb, 3) : 8; | |
| 412 | + | |
| 413 | + /* decode rvmap probability corrections if any */ | |
| 414 | + band->num_corr = 0; /* there is no corrections */ | |
| 415 | + if (get_bits1(&ctx->gb)) { | |
| 416 | + band->num_corr = get_bits(&ctx->gb, 8); /* get number of correction pairs */ | |
| 417 | + if (band->num_corr > 61) { | |
| 418 | + av_log(avctx, AV_LOG_ERROR, "Too many corrections: %d\n", | |
| 419 | + band->num_corr); | |
| 420 | + return AVERROR_INVALIDDATA; | |
| 421 | + } | |
| 422 | + | |
| 423 | + /* read correction pairs */ | |
| 424 | + for (i = 0; i < band->num_corr * 2; i++) | |
| 425 | + band->corr[i] = get_bits(&ctx->gb, 8); | |
| 426 | + } | |
| 427 | + } | |
| 428 | + | |
| 429 | + if (band->blk_size == 8) { | |
| 430 | + band->intra_base = &ivi4_quant_8x8_intra[quant_index_to_tab[band->quant_mat]][0]; | |
| 431 | + band->inter_base = &ivi4_quant_8x8_inter[quant_index_to_tab[band->quant_mat]][0]; | |
| 432 | + } else { | |
| 433 | + band->intra_base = &ivi4_quant_4x4_intra[quant_index_to_tab[band->quant_mat]][0]; | |
| 434 | + band->inter_base = &ivi4_quant_4x4_inter[quant_index_to_tab[band->quant_mat]][0]; | |
| 435 | + } | |
| 436 | + | |
| 437 | + /* Indeo 4 doesn't use scale tables */ | |
| 438 | + band->intra_scale = NULL; | |
| 439 | + band->inter_scale = NULL; | |
| 440 | + | |
| 441 | + align_get_bits(&ctx->gb); | |
| 442 | + | |
| 443 | + return 0; | |
| 444 | +} | |
| 445 | + | |
| 446 | + | |
| 447 | +/** | |
| 448 | + * Decode information (block type, cbp, quant delta, motion vector) | |
| 449 | + * for all macroblocks in the current tile. | |
| 450 | + * | |
| 451 | + * @param[in,out] ctx pointer to the decoder context | |
| 452 | + * @param[in,out] band pointer to the band descriptor | |
| 453 | + * @param[in,out] tile pointer to the tile descriptor | |
| 454 | + * @param[in] avctx pointer to the AVCodecContext | |
| 455 | + * @return result code: 0 = OK, negative number = error | |
| 456 | + */ | |
| 457 | +static int decode_mb_info(IVI4DecContext *ctx, IVIBandDesc *band, | |
| 458 | + IVITile *tile, AVCodecContext *avctx) | |
| 459 | +{ | |
| 460 | + int x, y, mv_x, mv_y, mv_delta, offs, mb_offset, blks_per_mb, | |
| 461 | + mv_scale, mb_type_bits; | |
| 462 | + IVIMbInfo *mb, *ref_mb; | |
| 463 | + int row_offset = band->mb_size * band->pitch; | |
| 464 | + | |
| 465 | + mb = tile->mbs; | |
| 466 | + ref_mb = tile->ref_mbs; | |
| 467 | + offs = tile->ypos * band->pitch + tile->xpos; | |
| 468 | + | |
| 469 | + blks_per_mb = band->mb_size != band->blk_size ? 4 : 1; | |
| 470 | + mb_type_bits = ctx->frame_type == FRAMETYPE_BIDIR ? 2 : 1; | |
| 471 | + | |
| 472 | + /* scale factor for motion vectors */ | |
| 473 | + mv_scale = (ctx->planes[0].bands[0].mb_size >> 3) - (band->mb_size >> 3); | |
| 474 | + mv_x = mv_y = 0; | |
| 475 | + | |
| 476 | + for (y = tile->ypos; y < tile->ypos + tile->height; y += band->mb_size) { | |
| 477 | + mb_offset = offs; | |
| 478 | + | |
| 479 | + for (x = tile->xpos; x < tile->xpos + tile->width; x += band->mb_size) { | |
| 480 | + mb->xpos = x; | |
| 481 | + mb->ypos = y; | |
| 482 | + mb->buf_offs = mb_offset; | |
| 483 | + | |
| 484 | + if (get_bits1(&ctx->gb)) { | |
| 485 | + if (ctx->frame_type == FRAMETYPE_INTRA) { | |
| 486 | + av_log(avctx, AV_LOG_ERROR, "Empty macroblock in an INTRA picture!\n"); | |
| 487 | + return AVERROR_INVALIDDATA; | |
| 488 | + } | |
| 489 | + mb->type = 1; /* empty macroblocks are always INTER */ | |
| 490 | + mb->cbp = 0; /* all blocks are empty */ | |
| 491 | + | |
| 492 | + mb->q_delta = 0; | |
| 493 | + if (!band->plane && !band->band_num && ctx->in_q) { | |
| 494 | + mb->q_delta = get_vlc2(&ctx->gb, ctx->mb_vlc.tab->table, | |
| 495 | + IVI_VLC_BITS, 1); | |
| 496 | + mb->q_delta = IVI_TOSIGNED(mb->q_delta); | |
| 497 | + } | |
| 498 | + | |
| 499 | + mb->mv_x = mb->mv_y = 0; /* no motion vector coded */ | |
| 500 | + if (band->inherit_mv) { | |
| 501 | + /* motion vector inheritance */ | |
| 502 | + if (mv_scale) { | |
| 503 | + mb->mv_x = ivi_scale_mv(ref_mb->mv_x, mv_scale); | |
| 504 | + mb->mv_y = ivi_scale_mv(ref_mb->mv_y, mv_scale); | |
| 505 | + } else { | |
| 506 | + mb->mv_x = ref_mb->mv_x; | |
| 507 | + mb->mv_y = ref_mb->mv_y; | |
| 508 | + } | |
| 509 | + } | |
| 510 | + } else { | |
| 511 | + if (band->inherit_mv) { | |
| 512 | + mb->type = ref_mb->type; /* copy mb_type from corresponding reference mb */ | |
| 513 | + } else if (ctx->frame_type == FRAMETYPE_INTRA) { | |
| 514 | + mb->type = 0; /* mb_type is always INTRA for intra-frames */ | |
| 515 | + } else { | |
| 516 | + mb->type = get_bits(&ctx->gb, mb_type_bits); | |
| 517 | + } | |
| 518 | + | |
| 519 | + mb->cbp = get_bits(&ctx->gb, blks_per_mb); | |
| 520 | + | |
| 521 | + mb->q_delta = 0; | |
| 522 | + if (band->inherit_qdelta) { | |
| 523 | + if (ref_mb) mb->q_delta = ref_mb->q_delta; | |
| 524 | + } else if (mb->cbp || (!band->plane && !band->band_num && | |
| 525 | + ctx->in_q)) { | |
| 526 | + mb->q_delta = get_vlc2(&ctx->gb, ctx->mb_vlc.tab->table, | |
| 527 | + IVI_VLC_BITS, 1); | |
| 528 | + mb->q_delta = IVI_TOSIGNED(mb->q_delta); | |
| 529 | + } | |
| 530 | + | |
| 531 | + if (!mb->type) { | |
| 532 | + mb->mv_x = mb->mv_y = 0; /* there is no motion vector in intra-macroblocks */ | |
| 533 | + } else { | |
| 534 | + if (band->inherit_mv) { | |
| 535 | + /* motion vector inheritance */ | |
| 536 | + if (mv_scale) { | |
| 537 | + mb->mv_x = ivi_scale_mv(ref_mb->mv_x, mv_scale); | |
| 538 | + mb->mv_y = ivi_scale_mv(ref_mb->mv_y, mv_scale); | |
| 539 | + } else { | |
| 540 | + mb->mv_x = ref_mb->mv_x; | |
| 541 | + mb->mv_y = ref_mb->mv_y; | |
| 542 | + } | |
| 543 | + } else { | |
| 544 | + /* decode motion vector deltas */ | |
| 545 | + mv_delta = get_vlc2(&ctx->gb, ctx->mb_vlc.tab->table, | |
| 546 | + IVI_VLC_BITS, 1); | |
| 547 | + mv_y += IVI_TOSIGNED(mv_delta); | |
| 548 | + mv_delta = get_vlc2(&ctx->gb, ctx->mb_vlc.tab->table, | |
| 549 | + IVI_VLC_BITS, 1); | |
| 550 | + mv_x += IVI_TOSIGNED(mv_delta); | |
| 551 | + mb->mv_x = mv_x; | |
| 552 | + mb->mv_y = mv_y; | |
| 553 | + } | |
| 554 | + } | |
| 555 | + } | |
| 556 | + | |
| 557 | + mb++; | |
| 558 | + if (ref_mb) | |
| 559 | + ref_mb++; | |
| 560 | + mb_offset += band->mb_size; | |
| 561 | + } | |
| 562 | + | |
| 563 | + offs += row_offset; | |
| 564 | + } | |
| 565 | + | |
| 566 | + align_get_bits(&ctx->gb); | |
| 567 | + | |
| 568 | + return 0; | |
| 569 | +} | |
| 570 | + | |
| 571 | + | |
| 572 | +/** | |
| 573 | + * Decode an Indeo 4 band. | |
| 574 | + * | |
| 575 | + * @param[in,out] ctx pointer to the decoder context | |
| 576 | + * @param[in,out] band pointer to the band descriptor | |
| 577 | + * @param[in] avctx pointer to the AVCodecContext | |
| 578 | + * @return result code: 0 = OK, negative number = error | |
| 579 | + */ | |
| 580 | +static int decode_band(IVI4DecContext *ctx, int plane_num, | |
| 581 | + IVIBandDesc *band, AVCodecContext *avctx) | |
| 582 | +{ | |
| 583 | + int result, i, t, pos, idx1, idx2; | |
| 584 | + IVITile *tile; | |
| 585 | + | |
| 586 | + band->buf = band->bufs[ctx->dst_buf]; | |
| 587 | + band->ref_buf = band->bufs[ctx->ref_buf]; | |
| 588 | + | |
| 589 | + result = decode_band_hdr(ctx, band, avctx); | |
| 590 | + if (result) { | |
| 591 | + av_log(avctx, AV_LOG_ERROR, "Error decoding band header\n"); | |
| 592 | + return result; | |
| 593 | + } | |
| 594 | + | |
| 595 | + if (band->is_empty) { | |
| 596 | + av_log(avctx, AV_LOG_ERROR, "Empty band encountered!\n"); | |
| 597 | + return AVERROR_INVALIDDATA; | |
| 598 | + } | |
| 599 | + | |
| 600 | + band->rv_map = &ctx->rvmap_tabs[band->rvmap_sel]; | |
| 601 | + | |
| 602 | + /* apply corrections to the selected rvmap table if present */ | |
| 603 | + for (i = 0; i < band->num_corr; i++) { | |
| 604 | + idx1 = band->corr[i * 2]; | |
| 605 | + idx2 = band->corr[i * 2 + 1]; | |
| 606 | + FFSWAP(uint8_t, band->rv_map->runtab[idx1], band->rv_map->runtab[idx2]); | |
| 607 | + FFSWAP(int16_t, band->rv_map->valtab[idx1], band->rv_map->valtab[idx2]); | |
| 608 | + } | |
| 609 | + | |
| 610 | + pos = get_bits_count(&ctx->gb); | |
| 611 | + | |
| 612 | + for (t = 0; t < band->num_tiles; t++) { | |
| 613 | + tile = &band->tiles[t]; | |
| 614 | + | |
| 615 | + tile->is_empty = get_bits1(&ctx->gb); | |
| 616 | + if (tile->is_empty) { | |
| 617 | + ff_ivi_process_empty_tile(avctx, band, tile, | |
| 618 | + (ctx->planes[0].bands[0].mb_size >> 3) - (band->mb_size >> 3)); | |
| 619 | + av_dlog(avctx, "Empty tile encountered!\n"); | |
| 620 | + } else { | |
| 621 | + tile->data_size = ff_ivi_dec_tile_data_size(&ctx->gb); | |
| 622 | + if (!tile->data_size) { | |
| 623 | + av_log(avctx, AV_LOG_ERROR, "Tile data size is zero!\n"); | |
| 624 | + return AVERROR_INVALIDDATA; | |
| 625 | + } | |
| 626 | + | |
| 627 | + result = decode_mb_info(ctx, band, tile, avctx); | |
| 628 | + if (result < 0) | |
| 629 | + break; | |
| 630 | + | |
| 631 | + result = ff_ivi_decode_blocks(&ctx->gb, band, tile); | |
| 632 | + if (result < 0 || ((get_bits_count(&ctx->gb) - pos) >> 3) != tile->data_size) { | |
| 633 | + av_log(avctx, AV_LOG_ERROR, "Corrupted tile data encountered!\n"); | |
| 634 | + break; | |
| 635 | + } | |
| 636 | + | |
| 637 | + pos += tile->data_size << 3; // skip to next tile | |
| 638 | + } | |
| 639 | + } | |
| 640 | + | |
| 641 | + /* restore the selected rvmap table by applying its corrections in reverse order */ | |
| 642 | + for (i = band->num_corr - 1; i >= 0; i--) { | |
| 643 | + idx1 = band->corr[i * 2]; | |
| 644 | + idx2 = band->corr[i * 2 + 1]; | |
| 645 | + FFSWAP(uint8_t, band->rv_map->runtab[idx1], band->rv_map->runtab[idx2]); | |
| 646 | + FFSWAP(int16_t, band->rv_map->valtab[idx1], band->rv_map->valtab[idx2]); | |
| 647 | + } | |
| 648 | + | |
| 649 | +#if defined(DEBUG) && IVI4_DEBUG_CHECKSUM | |
| 650 | + if (band->checksum_present) { | |
| 651 | + uint16_t chksum = ivi_calc_band_checksum(band); | |
| 652 | + if (chksum != band->checksum) { | |
| 653 | + av_log(avctx, AV_LOG_ERROR, | |
| 654 | + "Band checksum mismatch! Plane %d, band %d, received: %x, calculated: %x\n", | |
| 655 | + band->plane, band->band_num, band->checksum, chksum); | |
| 656 | + } | |
| 657 | + } | |
| 658 | +#endif | |
| 659 | + | |
| 660 | + align_get_bits(&ctx->gb); | |
| 661 | + | |
| 662 | + return 0; | |
| 663 | +} | |
| 664 | + | |
| 665 | + | |
| 666 | +static av_cold int decode_init(AVCodecContext *avctx) | |
| 667 | +{ | |
| 668 | + IVI4DecContext *ctx = avctx->priv_data; | |
| 669 | + | |
| 670 | + ff_ivi_init_static_vlc(); | |
| 671 | + | |
| 672 | + /* copy rvmap tables in our context so we can apply changes to them */ | |
| 673 | + memcpy(ctx->rvmap_tabs, ff_ivi_rvmap_tabs, sizeof(ff_ivi_rvmap_tabs)); | |
| 674 | + | |
| 675 | + /* Force allocation of the internal buffers */ | |
| 676 | + /* during picture header decoding. */ | |
| 677 | + ctx->pic_conf.pic_width = 0; | |
| 678 | + ctx->pic_conf.pic_height = 0; | |
| 679 | + | |
| 680 | + avctx->pix_fmt = PIX_FMT_YUV410P; | |
| 681 | + | |
| 682 | + return 0; | |
| 683 | +} | |
| 684 | + | |
| 685 | + | |
| 686 | +/** | |
| 687 | + * Rearrange decoding and reference buffers. | |
| 688 | + * | |
| 689 | + * @param[in,out] ctx pointer to the decoder context | |
| 690 | + */ | |
| 691 | +static void switch_buffers(IVI4DecContext *ctx) | |
| 692 | +{ | |
| 693 | + switch (ctx->prev_frame_type) { | |
| 694 | + case FRAMETYPE_INTRA: | |
| 695 | + case FRAMETYPE_INTER: | |
| 696 | + ctx->buf_switch ^= 1; | |
| 697 | + ctx->dst_buf = ctx->buf_switch; | |
| 698 | + ctx->ref_buf = ctx->buf_switch ^ 1; | |
| 699 | + break; | |
| 700 | + case FRAMETYPE_INTER_NOREF: | |
| 701 | + break; | |
| 702 | + } | |
| 703 | + | |
| 704 | + switch (ctx->frame_type) { | |
| 705 | + case FRAMETYPE_INTRA: | |
| 706 | + ctx->buf_switch = 0; | |
| 707 | + /* FALLTHROUGH */ | |
| 708 | + case FRAMETYPE_INTER: | |
| 709 | + ctx->dst_buf = ctx->buf_switch; | |
| 710 | + ctx->ref_buf = ctx->buf_switch ^ 1; | |
| 711 | + break; | |
| 712 | + case FRAMETYPE_INTER_NOREF: | |
| 713 | + case FRAMETYPE_NULL_FIRST: | |
| 714 | + case FRAMETYPE_NULL_LAST: | |
| 715 | + break; | |
| 716 | + } | |
| 717 | +} | |
| 718 | + | |
| 719 | + | |
| 720 | +static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, | |
| 721 | + AVPacket *avpkt) | |
| 722 | +{ | |
| 723 | + IVI4DecContext *ctx = avctx->priv_data; | |
| 724 | + const uint8_t *buf = avpkt->data; | |
| 725 | + int buf_size = avpkt->size; | |
| 726 | + int result, p, b; | |
| 727 | + | |
| 728 | + init_get_bits(&ctx->gb, buf, buf_size * 8); | |
| 729 | + | |
| 730 | + result = decode_pic_hdr(ctx, avctx); | |
| 731 | + if (result) { | |
| 732 | + av_log(avctx, AV_LOG_ERROR, "Error decoding picture header\n"); | |
| 733 | + return result; | |
| 734 | + } | |
| 735 | + | |
| 736 | + switch_buffers(ctx); | |
| 737 | + | |
| 738 | + if (ctx->frame_type < FRAMETYPE_NULL_FIRST) { | |
| 739 | + for (p = 0; p < 3; p++) { | |
| 740 | + for (b = 0; b < ctx->planes[p].num_bands; b++) { | |
| 741 | + result = decode_band(ctx, p, &ctx->planes[p].bands[b], avctx); | |
| 742 | + if (result) { | |
| 743 | + av_log(avctx, AV_LOG_ERROR, | |
| 744 | + "Error decoding band: %d, plane: %d\n", b, p); | |
| 745 | + return result; | |
| 746 | + } | |
| 747 | + } | |
| 748 | + } | |
| 749 | + } | |
| 750 | + | |
| 751 | + /* If the bidirectional mode is enabled, next I and the following P frame will */ | |
| 752 | + /* be sent together. Unfortunately the approach below seems to be the only way */ | |
| 753 | + /* to handle the B-frames mode. That's exactly the same Intel decoders do. */ | |
| 754 | + if (ctx->frame_type == FRAMETYPE_INTRA) { | |
| 755 | + while (get_bits(&ctx->gb, 8)); // skip version string | |
| 756 | + skip_bits_long(&ctx->gb, 64); // skip padding, TODO: implement correct 8-bytes alignment | |
| 757 | + if (get_bits_left(&ctx->gb) > 18 && show_bits(&ctx->gb, 18) == 0x3FFF8) | |
| 758 | + av_log(avctx, AV_LOG_ERROR, "Buffer contains IP frames!\n"); | |
| 759 | + } | |
| 760 | + | |
| 761 | + if (ctx->frame.data[0]) | |
| 762 | + avctx->release_buffer(avctx, &ctx->frame); | |
| 763 | + | |
| 764 | + ctx->frame.reference = 0; | |
| 765 | + if ((result = avctx->get_buffer(avctx, &ctx->frame)) < 0) { | |
| 766 | + av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); | |
| 767 | + return result; | |
| 768 | + } | |
| 769 | + | |
| 770 | + if (ctx->is_scalable) { | |
| 771 | + ff_ivi_recompose_haar(&ctx->planes[0], ctx->frame.data[0], ctx->frame.linesize[0], 4); | |
| 772 | + } else { | |
| 773 | + ff_ivi_output_plane(&ctx->planes[0], ctx->frame.data[0], ctx->frame.linesize[0]); | |
| 774 | + } | |
| 775 | + | |
| 776 | + ff_ivi_output_plane(&ctx->planes[2], ctx->frame.data[1], ctx->frame.linesize[1]); | |
| 777 | + ff_ivi_output_plane(&ctx->planes[1], ctx->frame.data[2], ctx->frame.linesize[2]); | |
| 778 | + | |
| 779 | + *data_size = sizeof(AVFrame); | |
| 780 | + *(AVFrame*)data = ctx->frame; | |
| 781 | + | |
| 782 | + return buf_size; | |
| 783 | +} | |
| 784 | + | |
| 785 | + | |
| 786 | +static av_cold int decode_close(AVCodecContext *avctx) | |
| 787 | +{ | |
| 788 | + IVI4DecContext *ctx = avctx->priv_data; | |
| 789 | + | |
| 790 | + ff_ivi_free_buffers(&ctx->planes[0]); | |
| 791 | + | |
| 792 | + if (ctx->frame.data[0]) | |
| 793 | + avctx->release_buffer(avctx, &ctx->frame); | |
| 794 | + | |
| 795 | +#if IVI4_STREAM_ANALYSER | |
| 796 | + if (ctx->is_scalable) | |
| 797 | + av_log(avctx, AV_LOG_ERROR, "This video uses scalability mode!\n"); | |
| 798 | + if (ctx->uses_tiling) | |
| 799 | + av_log(avctx, AV_LOG_ERROR, "This video uses local decoding!\n"); | |
| 800 | + if (ctx->has_b_frames) | |
| 801 | + av_log(avctx, AV_LOG_ERROR, "This video contains B-frames!\n"); | |
| 802 | + if (ctx->has_transp) | |
| 803 | + av_log(avctx, AV_LOG_ERROR, "Transparency mode is enabled!\n"); | |
| 804 | + if (ctx->uses_haar) | |
| 805 | + av_log(avctx, AV_LOG_ERROR, "This video uses Haar transform!\n"); | |
| 806 | + if (ctx->uses_fullpel) | |
| 807 | + av_log(avctx, AV_LOG_ERROR, "This video uses fullpel motion vectors!\n"); | |
| 808 | +#endif | |
| 809 | + | |
| 810 | + return 0; | |
| 811 | +} | |
| 812 | + | |
| 813 | + | |
| 814 | +AVCodec ff_indeo4_decoder = { | |
| 815 | + .name = "indeo4", | |
| 816 | + .type = AVMEDIA_TYPE_VIDEO, | |
| 817 | + .id = CODEC_ID_INDEO4, | |
| 818 | + .priv_data_size = sizeof(IVI4DecContext), | |
| 819 | + .init = decode_init, | |
| 820 | + .close = decode_close, | |
| 821 | + .decode = decode_frame, | |
| 822 | + .long_name = NULL_IF_CONFIG_SMALL("Intel Indeo Video Interactive 4"), | |
| 823 | +}; | |
| @@ -0,0 +1,350 @@ | ||
| 1 | +/* | |
| 2 | + * Indeo Video Interactive 4 compatible decoder | |
| 3 | + * Copyright (c) 2009-2010 Maxim Poliakovski | |
| 4 | + * | |
| 5 | + * This file is part of Libav. | |
| 6 | + * | |
| 7 | + * Libav 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 | + * Libav 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 Libav; 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 | + * This file contains data needed for the Indeo 4 decoder. | |
| 25 | + */ | |
| 26 | + | |
| 27 | +#ifndef AVCODEC_INDEO4DATA_H | |
| 28 | +#define AVCODEC_INDEO4DATA_H | |
| 29 | + | |
| 30 | +#include <stdint.h> | |
| 31 | +#include "dsputil.h" | |
| 32 | +#include "ivi_common.h" | |
| 33 | + | |
| 34 | +/** | |
| 35 | + * standard picture dimensions | |
| 36 | + */ | |
| 37 | +static const uint16_t ivi4_common_pic_sizes[14] = { | |
| 38 | + 640, 480, 320, 240, 160, 120, 704, 480, 352, 240, 352, 288, 176, 144 | |
| 39 | +}; | |
| 40 | + | |
| 41 | +/** | |
| 42 | + * Indeo 4 8x8 scan (zigzag) patterns | |
| 43 | + */ | |
| 44 | +static const uint8_t ivi4_alternate_scan_8x8[64] = { | |
| 45 | + 0, 8, 1, 9, 16, 24, 2, 3, 17, 25, 10, 11, 32, 40, 48, 56, | |
| 46 | + 4, 5, 6, 7, 33, 41, 49, 57, 18, 19, 26, 27, 12, 13, 14, 15, | |
| 47 | + 34, 35, 43, 42, 50, 51, 59, 58, 20, 21, 22, 23, 31, 30, 29, 28, | |
| 48 | + 36, 37, 38, 39, 47, 46, 45, 44, 52, 53, 54, 55, 63, 62, 61, 60 | |
| 49 | +}; | |
| 50 | + | |
| 51 | +static const uint8_t ivi4_alternate_scan_4x4[16] = { | |
| 52 | + 0, 1, 4, 5, 8, 12, 2, 3, 9, 13, 6, 7, 10, 11, 14, 15 | |
| 53 | +}; | |
| 54 | + | |
| 55 | +static const uint8_t ivi4_vertical_scan_4x4[16] = { | |
| 56 | + 0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15 | |
| 57 | +}; | |
| 58 | + | |
| 59 | +static const uint8_t ivi4_horizontal_scan_4x4[16] = { | |
| 60 | + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 | |
| 61 | +}; | |
| 62 | + | |
| 63 | +static const uint8_t *scan_index_to_tab[15] = { | |
| 64 | + // for 8x8 transforms | |
| 65 | + ff_zigzag_direct, | |
| 66 | + ivi4_alternate_scan_8x8, | |
| 67 | + ff_ivi_horizontal_scan_8x8, | |
| 68 | + ff_ivi_vertical_scan_8x8, | |
| 69 | + ff_zigzag_direct, | |
| 70 | + | |
| 71 | + // for 4x4 transforms | |
| 72 | + ff_ivi_direct_scan_4x4, | |
| 73 | + ivi4_alternate_scan_4x4, | |
| 74 | + ivi4_vertical_scan_4x4, | |
| 75 | + ivi4_horizontal_scan_4x4, | |
| 76 | + ff_ivi_direct_scan_4x4, | |
| 77 | + | |
| 78 | + // TODO: check if those are needed | |
| 79 | + ff_ivi_horizontal_scan_8x8, | |
| 80 | + ff_ivi_horizontal_scan_8x8, | |
| 81 | + ff_ivi_horizontal_scan_8x8, | |
| 82 | + ff_ivi_horizontal_scan_8x8, | |
| 83 | + ff_ivi_horizontal_scan_8x8 | |
| 84 | +}; | |
| 85 | + | |
| 86 | +/** | |
| 87 | + * Indeo 4 dequant tables | |
| 88 | + */ | |
| 89 | +static uint16_t ivi4_quant_8x8_intra[9][64] = { | |
| 90 | + { | |
| 91 | + 43, 342, 385, 470, 555, 555, 598, 726, | |
| 92 | + 342, 342, 470, 513, 555, 598, 726, 769, | |
| 93 | + 385, 470, 555, 555, 598, 726, 726, 811, | |
| 94 | + 470, 470, 555, 555, 598, 726, 769, 854, | |
| 95 | + 470, 555, 555, 598, 683, 726, 854, 1025, | |
| 96 | + 555, 555, 598, 683, 726, 854, 1025, 1153, | |
| 97 | + 555, 555, 598, 726, 811, 982, 1195, 1451, | |
| 98 | + 555, 598, 726, 811, 982, 1195, 1451, 1793 | |
| 99 | + }, | |
| 100 | + { | |
| 101 | + 86, 1195, 2390, 2390, 4865, 4865, 4865, 4865, | |
| 102 | + 1195, 1195, 2390, 2390, 4865, 4865, 4865, 4865, | |
| 103 | + 2390, 2390, 4865, 4865, 6827, 6827, 6827, 6827, | |
| 104 | + 2390, 2390, 4865, 4865, 6827, 6827, 6827, 6827, | |
| 105 | + 4865, 4865, 6827, 6827, 6827, 6827, 6827, 6827, | |
| 106 | + 4865, 4865, 6827, 6827, 6827, 6827, 6827, 6827, | |
| 107 | + 4865, 4865, 6827, 6827, 6827, 6827, 6827, 6827, | |
| 108 | + 4865, 4865, 6827, 6827, 6827, 6827, 6827, 6827 | |
| 109 | + }, | |
| 110 | + { | |
| 111 | + 235, 1067, 1195, 1323, 1451, 1579, 1707, 1835, | |
| 112 | + 235, 1067, 1195, 1323, 1451, 1579, 1707, 1835, | |
| 113 | + 235, 1067, 1195, 1323, 1451, 1579, 1707, 1835, | |
| 114 | + 235, 1067, 1195, 1323, 1451, 1579, 1707, 1835, | |
| 115 | + 235, 1067, 1195, 1323, 1451, 1579, 1707, 1835, | |
| 116 | + 235, 1067, 1195, 1323, 1451, 1579, 1707, 1835, | |
| 117 | + 235, 1067, 1195, 1323, 1451, 1579, 1707, 1835, | |
| 118 | + 235, 1067, 1195, 1323, 1451, 1579, 1707, 1835 | |
| 119 | + }, | |
| 120 | + { | |
| 121 | + 1707, 1707, 3414, 3414, 3414, 3414, 3414, 3414, | |
| 122 | + 1707, 1707, 3414, 3414, 3414, 3414, 3414, 3414, | |
| 123 | + 1707, 1707, 3414, 3414, 3414, 3414, 3414, 3414, | |
| 124 | + 1707, 1707, 3414, 3414, 3414, 3414, 3414, 3414, | |
| 125 | + 1707, 1707, 3414, 3414, 3414, 3414, 3414, 3414, | |
| 126 | + 1707, 1707, 3414, 3414, 3414, 3414, 3414, 3414, | |
| 127 | + 1707, 1707, 3414, 3414, 3414, 3414, 3414, 3414, | |
| 128 | + 1707, 1707, 3414, 3414, 3414, 3414, 3414, 3414 | |
| 129 | + }, | |
| 130 | + { | |
| 131 | + 897, 897, 897, 897, 897, 897, 897, 897, | |
| 132 | + 1067, 1067, 1067, 1067, 1067, 1067, 1067, 1067, | |
| 133 | + 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, | |
| 134 | + 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409, | |
| 135 | + 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579, | |
| 136 | + 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, | |
| 137 | + 1921, 1921, 1921, 1921, 1921, 1921, 1921, 1921, | |
| 138 | + 2091, 2091, 2091, 2091, 2091, 2091, 2091, 2091 | |
| 139 | + }, | |
| 140 | + { | |
| 141 | + 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, | |
| 142 | + 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, | |
| 143 | + 3414, 3414, 3414, 3414, 3414, 3414, 3414, 3414, | |
| 144 | + 3414, 3414, 3414, 3414, 3414, 3414, 3414, 3414, | |
| 145 | + 3414, 3414, 3414, 3414, 3414, 3414, 3414, 3414, | |
| 146 | + 3414, 3414, 3414, 3414, 3414, 3414, 3414, 3414, | |
| 147 | + 3414, 3414, 3414, 3414, 3414, 3414, 3414, 3414, | |
| 148 | + 3414, 3414, 3414, 3414, 3414, 3414, 3414, 3414 | |
| 149 | + }, | |
| 150 | + { | |
| 151 | + 2390, 2390, 2390, 2390, 2390, 2390, 2390, 2390, | |
| 152 | + 2390, 2390, 2390, 2390, 2390, 2390, 2390, 2390, | |
| 153 | + 2390, 2390, 2390, 2390, 2390, 2390, 2390, 2390, | |
| 154 | + 2390, 2390, 2390, 2390, 2390, 2390, 2390, 2390, | |
| 155 | + 2390, 2390, 2390, 2390, 2390, 2390, 2390, 2390, | |
| 156 | + 2390, 2390, 2390, 2390, 2390, 2390, 2390, 2390, | |
| 157 | + 2390, 2390, 2390, 2390, 2390, 2390, 2390, 2390, | |
| 158 | + 2390, 2390, 2390, 2390, 2390, 2390, 2390, 2390 | |
| 159 | + }, | |
| 160 | + { | |
| 161 | + 22, 171, 214, 257, 257, 299, 299, 342, | |
| 162 | + 171, 171, 257, 257, 299, 299, 342, 385, | |
| 163 | + 214, 257, 257, 299, 299, 342, 342, 385, | |
| 164 | + 257, 257, 257, 299, 299, 342, 385, 427, | |
| 165 | + 257, 257, 299, 299, 342, 385, 427, 513, | |
| 166 | + 257, 299, 299, 342, 385, 427, 513, 598, | |
| 167 | + 299, 299, 299, 385, 385, 470, 598, 726, | |
| 168 | + 299, 299, 385, 385, 470, 598, 726, 897 | |
| 169 | + }, | |
| 170 | + { | |
| 171 | + 86, 598, 1195, 1195, 2390, 2390, 2390, 2390, | |
| 172 | + 598, 598, 1195, 1195, 2390, 2390, 2390, 2390, | |
| 173 | + 1195, 1195, 2390, 2390, 3414, 3414, 3414, 3414, | |
| 174 | + 1195, 1195, 2390, 2390, 3414, 3414, 3414, 3414, | |
| 175 | + 2390, 2390, 3414, 3414, 3414, 3414, 3414, 3414, | |
| 176 | + 2390, 2390, 3414, 3414, 3414, 3414, 3414, 3414, | |
| 177 | + 2390, 2390, 3414, 3414, 3414, 3414, 3414, 3414, | |
| 178 | + 2390, 2390, 3414, 3414, 3414, 3414, 3414, 3414 | |
| 179 | + } | |
| 180 | +}; | |
| 181 | + | |
| 182 | +static uint16_t ivi4_quant_8x8_inter[9][64] = { | |
| 183 | + { | |
| 184 | + 427, 427, 470, 427, 427, 427, 470, 470, | |
| 185 | + 427, 427, 470, 427, 427, 427, 470, 470, | |
| 186 | + 470, 470, 470, 470, 470, 470, 470, 470, | |
| 187 | + 427, 427, 470, 470, 427, 427, 470, 470, | |
| 188 | + 427, 427, 470, 427, 427, 427, 470, 470, | |
| 189 | + 427, 427, 470, 427, 427, 427, 470, 470, | |
| 190 | + 470, 470, 470, 470, 470, 470, 470, 470, | |
| 191 | + 470, 470, 470, 470, 470, 470, 470, 470 | |
| 192 | + }, | |
| 193 | + { | |
| 194 | + 1707, 1707, 2433, 2433, 3414, 3414, 3414, 3414, | |
| 195 | + 1707, 1707, 2433, 2433, 3414, 3414, 3414, 3414, | |
| 196 | + 2433, 2433, 3414, 3414, 4822, 4822, 4822, 4822, | |
| 197 | + 2433, 2433, 3414, 3414, 4822, 4822, 4822, 4822, | |
| 198 | + 3414, 3414, 4822, 4822, 3414, 3414, 3414, 3414, | |
| 199 | + 3414, 3414, 4822, 4822, 3414, 3414, 3414, 3414, | |
| 200 | + 3414, 3414, 4822, 4822, 3414, 3414, 3414, 3414, | |
| 201 | + 3414, 3414, 4822, 4822, 3414, 3414, 3414, 3414 | |
| 202 | + }, | |
| 203 | + { | |
| 204 | + 1195, 1195, 1281, 1238, 1195, 1195, 1281, 1281, | |
| 205 | + 1195, 1195, 1281, 1238, 1195, 1195, 1281, 1281, | |
| 206 | + 1195, 1195, 1281, 1238, 1195, 1195, 1281, 1281, | |
| 207 | + 1195, 1195, 1281, 1238, 1195, 1195, 1281, 1281, | |
| 208 | + 1195, 1195, 1281, 1238, 1195, 1195, 1281, 1281, | |
| 209 | + 1195, 1195, 1281, 1238, 1195, 1195, 1281, 1281, | |
| 210 | + 1195, 1195, 1281, 1238, 1195, 1195, 1281, 1281, | |
| 211 | + 1195, 1195, 1281, 1238, 1195, 1195, 1281, 1281 | |
| 212 | + }, | |
| 213 | + { | |
| 214 | + 2433, 2433, 3414, 3414, 2433, 2433, 2433, 2433, | |
| 215 | + 2433, 2433, 3414, 3414, 2433, 2433, 2433, 2433, | |
| 216 | + 2433, 2433, 3414, 3414, 2433, 2433, 2433, 2433, | |
| 217 | + 2433, 2433, 3414, 3414, 2433, 2433, 2433, 2433, | |
| 218 | + 2433, 2433, 3414, 3414, 2433, 2433, 2433, 2433, | |
| 219 | + 2433, 2433, 3414, 3414, 2433, 2433, 2433, 2433, | |
| 220 | + 2433, 2433, 3414, 3414, 2433, 2433, 2433, 2433, | |
| 221 | + 2433, 2433, 3414, 3414, 2433, 2433, 2433, 2433 | |
| 222 | + }, | |
| 223 | + { | |
| 224 | + 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, | |
| 225 | + 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, | |
| 226 | + 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, | |
| 227 | + 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, | |
| 228 | + 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, | |
| 229 | + 1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195, | |
| 230 | + 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, | |
| 231 | + 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281 | |
| 232 | + }, | |
| 233 | + { | |
| 234 | + 2433, 2433, 2433, 2433, 2433, 2433, 2433, 2433, | |
| 235 | + 2433, 2433, 2433, 2433, 2433, 2433, 2433, 2433, | |
| 236 | + 3414, 3414, 3414, 3414, 3414, 3414, 3414, 3414, | |
| 237 | + 3414, 3414, 3414, 3414, 3414, 3414, 3414, 3414, | |
| 238 | + 2433, 2433, 2433, 2433, 2433, 2433, 2433, 2433, | |
| 239 | + 2433, 2433, 2433, 2433, 2433, 2433, 2433, 2433, | |
| 240 | + 2433, 2433, 2433, 2433, 2433, 2433, 2433, 2433, | |
| 241 | + 2433, 2433, 2433, 2433, 2433, 2433, 2433, 2433 | |
| 242 | + }, | |
| 243 | + { | |
| 244 | + 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, | |
| 245 | + 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, | |
| 246 | + 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, | |
| 247 | + 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, | |
| 248 | + 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, | |
| 249 | + 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, | |
| 250 | + 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707, | |
| 251 | + 1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707 | |
| 252 | + }, | |
| 253 | + { | |
| 254 | + 86, 171, 171, 214, 214, 214, 214, 257, | |
| 255 | + 171, 171, 214, 214, 214, 214, 257, 257, | |
| 256 | + 171, 214, 214, 214, 214, 257, 257, 257, | |
| 257 | + 214, 214, 214, 214, 257, 257, 257, 299, | |
| 258 | + 214, 214, 214, 257, 257, 257, 299, 299, | |
| 259 | + 214, 214, 257, 257, 257, 299, 299, 299, | |
| 260 | + 214, 257, 257, 257, 299, 299, 299, 342, | |
| 261 | + 257, 257, 257, 299, 299, 299, 342, 342 | |
| 262 | + }, | |
| 263 | + { | |
| 264 | + 854, 854, 1195, 1195, 1707, 1707, 1707, 1707, | |
| 265 | + 854, 854, 1195, 1195, 1707, 1707, 1707, 1707, | |
| 266 | + 1195, 1195, 1707, 1707, 2390, 2390, 2390, 2390, | |
| 267 | + 1195, 1195, 1707, 1707, 2390, 2390, 2390, 2390, | |
| 268 | + 1707, 1707, 2390, 2390, 1707, 1707, 1707, 1707, | |
| 269 | + 1707, 1707, 2390, 2390, 1707, 1707, 1707, 1707, | |
| 270 | + 1707, 1707, 2390, 2390, 1707, 1707, 1707, 1707, | |
| 271 | + 1707, 1707, 2390, 2390, 1707, 1707, 1707, 1707 | |
| 272 | + } | |
| 273 | +}; | |
| 274 | + | |
| 275 | +static uint16_t ivi4_quant_4x4_intra[5][16] = { | |
| 276 | + { | |
| 277 | + 22, 214, 257, 299, | |
| 278 | + 214, 257, 299, 342, | |
| 279 | + 257, 299, 342, 427, | |
| 280 | + 299, 342, 427, 513 | |
| 281 | + }, | |
| 282 | + { | |
| 283 | + 129, 1025, 1451, 1451, | |
| 284 | + 1025, 1025, 1451, 1451, | |
| 285 | + 1451, 1451, 2049, 2049, | |
| 286 | + 1451, 1451, 2049, 2049 | |
| 287 | + }, | |
| 288 | + { | |
| 289 | + 43, 171, 171, 171, | |
| 290 | + 43, 171, 171, 171, | |
| 291 | + 43, 171, 171, 171, | |
| 292 | + 43, 171, 171, 171 | |
| 293 | + }, | |
| 294 | + { | |
| 295 | + 43, 43, 43, 43, | |
| 296 | + 171, 171, 171, 171, | |
| 297 | + 171, 171, 171, 171, | |
| 298 | + 171, 171, 171, 171 | |
| 299 | + }, | |
| 300 | + { | |
| 301 | + 43, 43, 43, 43, | |
| 302 | + 43, 43, 43, 43, | |
| 303 | + 43, 43, 43, 43, | |
| 304 | + 43, 43, 43, 43 | |
| 305 | + } | |
| 306 | +}; | |
| 307 | + | |
| 308 | +static uint16_t ivi4_quant_4x4_inter[5][16] = { | |
| 309 | + { | |
| 310 | + 107, 214, 257, 299, | |
| 311 | + 214, 257, 299, 299, | |
| 312 | + 257, 299, 299, 342, | |
| 313 | + 299, 299, 342, 342 | |
| 314 | + }, | |
| 315 | + { | |
| 316 | + 513, 1025, 1238, 1238, | |
| 317 | + 1025, 1025, 1238, 1238, | |
| 318 | + 1238, 1238, 1451, 1451, | |
| 319 | + 1238, 1238, 1451, 1451 | |
| 320 | + }, | |
| 321 | + { | |
| 322 | + 43, 171, 171, 171, | |
| 323 | + 43, 171, 171, 171, | |
| 324 | + 43, 171, 171, 171, | |
| 325 | + 43, 171, 171, 171 | |
| 326 | + }, | |
| 327 | + { | |
| 328 | + 43, 43, 43, 43, | |
| 329 | + 171, 171, 171, 171, | |
| 330 | + 171, 171, 171, 171, | |
| 331 | + 171, 171, 171, 171 | |
| 332 | + }, | |
| 333 | + { | |
| 334 | + 43, 43, 43, 43, | |
| 335 | + 43, 43, 43, 43, | |
| 336 | + 43, 43, 43, 43, | |
| 337 | + 43, 43, 43, 43 | |
| 338 | + } | |
| 339 | +}; | |
| 340 | + | |
| 341 | +/** | |
| 342 | + * Table for mapping quant matrix index from the bitstream | |
| 343 | + * into internal quant table number. | |
| 344 | + */ | |
| 345 | +static uint8_t quant_index_to_tab[22] = { | |
| 346 | + 0, 1, 0, 2, 1, 3, 0, 4, 1, 5, 0, 1, 6, 7, 8, // for 8x8 quant matrixes | |
| 347 | + 0, 1, 2, 2, 3, 3, 4 // for 4x4 quant matrixes | |
| 348 | +}; | |
| 349 | + | |
| 350 | +#endif /* AVCODEC_INDEO4DATA_H */ | |
| @@ -1,7 +1,7 @@ | ||
| 1 | 1 | /* |
| 2 | 2 | * DSP functions for Indeo Video Interactive codecs (Indeo4 and Indeo5) |
| 3 | 3 | * |
| 4 | − * Copyright (c) 2009 Maxim Poliakovski | |
| 4 | + * Copyright (c) 2009-2011 Maxim Poliakovski | |
| 5 | 5 | * |
| 6 | 6 | * This file is part of Libav. |
| 7 | 7 | * |
| @@ -178,6 +178,153 @@ void ff_ivi_recompose53(const IVIPlaneDesc *plane, uint8_t *dst, · 170 unmodified lines | ||
| 178 | 178 | } |
| 179 | 179 | } |
| 180 | 180 | |
| 181 | +void ff_ivi_recompose_haar(const IVIPlaneDesc *plane, uint8_t *dst, | |
| 182 | + const int dst_pitch, const int num_bands) | |
| 183 | +{ | |
| 184 | + int x, y, indx, b0, b1, b2, b3, p0, p1, p2, p3; | |
| 185 | + const IDWTELEM *b0_ptr, *b1_ptr, *b2_ptr, *b3_ptr; | |
| 186 | + int32_t pitch; | |
| 187 | + | |
| 188 | + /* all bands should have the same pitch */ | |
| 189 | + pitch = plane->bands[0].pitch; | |
| 190 | + | |
| 191 | + /* get pointers to the wavelet bands */ | |
| 192 | + b0_ptr = plane->bands[0].buf; | |
| 193 | + b1_ptr = plane->bands[1].buf; | |
| 194 | + b2_ptr = plane->bands[2].buf; | |
| 195 | + b3_ptr = plane->bands[3].buf; | |
| 196 | + | |
| 197 | + for (y = 0; y < plane->height; y += 2) { | |
| 198 | + for (x = 0, indx = 0; x < plane->width; x += 2, indx++) { | |
| 199 | + /* load coefficients */ | |
| 200 | + b0 = b0_ptr[indx]; //should be: b0 = (num_bands > 0) ? b0_ptr[indx] : 0; | |
| 201 | + b1 = b1_ptr[indx]; //should be: b1 = (num_bands > 1) ? b1_ptr[indx] : 0; | |
| 202 | + b2 = b2_ptr[indx]; //should be: b2 = (num_bands > 2) ? b2_ptr[indx] : 0; | |
| 203 | + b3 = b3_ptr[indx]; //should be: b3 = (num_bands > 3) ? b3_ptr[indx] : 0; | |
| 204 | + | |
| 205 | + /* haar wavelet recomposition */ | |
| 206 | + p0 = (b0 + b1 + b2 + b3 + 2) >> 2; | |
| 207 | + p1 = (b0 + b1 - b2 - b3 + 2) >> 2; | |
| 208 | + p2 = (b0 - b1 + b2 - b3 + 2) >> 2; | |
| 209 | + p3 = (b0 - b1 - b2 + b3 + 2) >> 2; | |
| 210 | + | |
| 211 | + /* bias, convert and output four pixels */ | |
| 212 | + dst[x] = av_clip_uint8(p0 + 128); | |
| 213 | + dst[x + 1] = av_clip_uint8(p1 + 128); | |
| 214 | + dst[dst_pitch + x] = av_clip_uint8(p2 + 128); | |
| 215 | + dst[dst_pitch + x + 1] = av_clip_uint8(p3 + 128); | |
| 216 | + }// for x | |
| 217 | + | |
| 218 | + dst += dst_pitch << 1; | |
| 219 | + | |
| 220 | + b0_ptr += pitch; | |
| 221 | + b1_ptr += pitch; | |
| 222 | + b2_ptr += pitch; | |
| 223 | + b3_ptr += pitch; | |
| 224 | + }// for y | |
| 225 | +} | |
| 226 | + | |
| 227 | +/** butterfly operation for the inverse Haar transform */ | |
| 228 | +#define IVI_HAAR_BFLY(s1, s2, o1, o2, t) \ | |
| 229 | + t = (s1 - s2) >> 1;\ | |
| 230 | + o1 = (s1 + s2) >> 1;\ | |
| 231 | + o2 = t;\ | |
| 232 | + | |
| 233 | +/** inverse 8-point Haar transform */ | |
| 234 | +#define INV_HAAR8(s1, s5, s3, s7, s2, s4, s6, s8,\ | |
| 235 | + d1, d2, d3, d4, d5, d6, d7, d8,\ | |
| 236 | + t0, t1, t2, t3, t4, t5, t6, t7, t8) {\ | |
| 237 | + t1 = s1 << 1; t5 = s5 << 1;\ | |
| 238 | + IVI_HAAR_BFLY(t1, t5, t1, t5, t0); IVI_HAAR_BFLY(t1, s3, t1, t3, t0);\ | |
| 239 | + IVI_HAAR_BFLY(t5, s7, t5, t7, t0); IVI_HAAR_BFLY(t1, s2, t1, t2, t0);\ | |
| 240 | + IVI_HAAR_BFLY(t3, s4, t3, t4, t0); IVI_HAAR_BFLY(t5, s6, t5, t6, t0);\ | |
| 241 | + IVI_HAAR_BFLY(t7, s8, t7, t8, t0);\ | |
| 242 | + d1 = COMPENSATE(t1);\ | |
| 243 | + d2 = COMPENSATE(t2);\ | |
| 244 | + d3 = COMPENSATE(t3);\ | |
| 245 | + d4 = COMPENSATE(t4);\ | |
| 246 | + d5 = COMPENSATE(t5);\ | |
| 247 | + d6 = COMPENSATE(t6);\ | |
| 248 | + d7 = COMPENSATE(t7);\ | |
| 249 | + d8 = COMPENSATE(t8); } | |
| 250 | + | |
| 251 | +/** inverse 4-point Haar transform */ | |
| 252 | +#define INV_HAAR4(s1, s3, s5, s7) {\ | |
| 253 | + HAAR_BFLY(s1, s5); HAAR_BFLY(s1, s3); HAAR_BFLY(s5, s7);\ | |
| 254 | + s1 = COMPENSATE(s1);\ | |
| 255 | + s3 = COMPENSATE(s3);\ | |
| 256 | + s5 = COMPENSATE(s5);\ | |
| 257 | + s7 = COMPENSATE(s7); } | |
| 258 | + | |
| 259 | +void ff_ivi_inverse_haar_8x8(const int32_t *in, int16_t *out, uint32_t pitch, | |
| 260 | + const uint8_t *flags) | |
| 261 | +{ | |
| 262 | + int i, shift, sp1, sp2, sp3, sp4; | |
| 263 | + const int32_t *src; | |
| 264 | + int32_t *dst; | |
| 265 | + int tmp[64]; | |
| 266 | + int t0, t1, t2, t3, t4, t5, t6, t7, t8; | |
| 267 | + | |
| 268 | + /* apply the InvHaar8 to all columns */ | |
| 269 | +#define COMPENSATE(x) (x) | |
| 270 | + src = in; | |
| 271 | + dst = tmp; | |
| 272 | + for (i = 0; i < 8; i++) { | |
| 273 | + if (flags[i]) { | |
| 274 | + /* pre-scaling */ | |
| 275 | + shift = !(i & 4); | |
| 276 | + sp1 = src[ 0] << shift; | |
| 277 | + sp2 = src[ 8] << shift; | |
| 278 | + sp3 = src[16] << shift; | |
| 279 | + sp4 = src[24] << shift; | |
| 280 | + INV_HAAR8( sp1, sp2, sp3, sp4, | |
| 281 | + src[32], src[40], src[48], src[56], | |
| 282 | + dst[ 0], dst[ 8], dst[16], dst[24], | |
| 283 | + dst[32], dst[40], dst[48], dst[56], | |
| 284 | + t0, t1, t2, t3, t4, t5, t6, t7, t8); | |
| 285 | + } else | |
| 286 | + dst[ 0] = dst[ 8] = dst[16] = dst[24] = | |
| 287 | + dst[32] = dst[40] = dst[48] = dst[56] = 0; | |
| 288 | + | |
| 289 | + src++; | |
| 290 | + dst++; | |
| 291 | + } | |
| 292 | +#undef COMPENSATE | |
| 293 | + | |
| 294 | + /* apply the InvHaar8 to all rows */ | |
| 295 | +#define COMPENSATE(x) (x) | |
| 296 | + src = tmp; | |
| 297 | + for (i = 0; i < 8; i++) { | |
| 298 | + if ( !src[0] && !src[1] && !src[2] && !src[3] | |
| 299 | + && !src[4] && !src[5] && !src[6] && !src[7]) { | |
| 300 | + memset(out, 0, 8 * sizeof(out[0])); | |
| 301 | + } else { | |
| 302 | + INV_HAAR8(src[0], src[1], src[2], src[3], | |
| 303 | + src[4], src[5], src[6], src[7], | |
| 304 | + out[0], out[1], out[2], out[3], | |
| 305 | + out[4], out[5], out[6], out[7], | |
| 306 | + t0, t1, t2, t3, t4, t5, t6, t7, t8); | |
| 307 | + } | |
| 308 | + src += 8; | |
| 309 | + out += pitch; | |
| 310 | + } | |
| 311 | +#undef COMPENSATE | |
| 312 | +} | |
| 313 | + | |
| 314 | +void ff_ivi_dc_haar_2d(const int32_t *in, int16_t *out, uint32_t pitch, | |
| 315 | + int blk_size) | |
| 316 | +{ | |
| 317 | + int x, y; | |
| 318 | + int16_t dc_coeff; | |
| 319 | + | |
| 320 | + dc_coeff = (*in + 0) >> 3; | |
| 321 | + | |
| 322 | + for (y = 0; y < blk_size; out += pitch, y++) { | |
| 323 | + for (x = 0; x < blk_size; x++) | |
| 324 | + out[x] = dc_coeff; | |
| 325 | + } | |
| 326 | +} | |
| 327 | + | |
| 181 | 328 | /** butterfly operation for the inverse slant transform */ |
| 182 | 329 | #define IVI_SLANT_BFLY(s1, s2, o1, o2, t) \ |
| 183 | 330 | t = s1 - s2;\ |
| @@ -1,7 +1,7 @@ | ||
| 1 | 1 | /* |
| 2 | 2 | * DSP functions for Indeo Video Interactive codecs (Indeo4 and Indeo5) |
| 3 | 3 | * |
| 4 | − * Copyright (c) 2009 Maxim Poliakovski | |
| 4 | + * Copyright (c) 2009-2011 Maxim Poliakovski | |
| 5 | 5 | * |
| 6 | 6 | * This file is part of Libav. |
| 7 | 7 | * |
| @@ -43,6 +43,43 @@ · 35 unmodified lines | ||
| 43 | 43 | void ff_ivi_recompose53(const IVIPlaneDesc *plane, uint8_t *dst, |
| 44 | 44 | const int dst_pitch, const int num_bands); |
| 45 | 45 | |
| 46 | +/** | |
| 47 | + * Haar wavelet recomposition filter for Indeo 4 | |
| 48 | + * | |
| 49 | + * @param[in] plane pointer to the descriptor of the plane being processed | |
| 50 | + * @param[out] dst pointer to the destination buffer | |
| 51 | + * @param[in] dst_pitch pitch of the destination buffer | |
| 52 | + * @param[in] num_bands number of wavelet bands to be processed | |
| 53 | + */ | |
| 54 | +void ff_ivi_recompose_haar(const IVIPlaneDesc *plane, uint8_t *dst, | |
| 55 | + const int dst_pitch, const int num_bands); | |
| 56 | + | |
| 57 | +/** | |
| 58 | + * two-dimensional inverse Haar 8x8 transform for Indeo 4 | |
| 59 | + * | |
| 60 | + * @param[in] in pointer to the vector of transform coefficients | |
| 61 | + * @param[out] out pointer to the output buffer (frame) | |
| 62 | + * @param[in] pitch pitch to move to the next y line | |
| 63 | + * @param[in] flags pointer to the array of column flags: | |
| 64 | + * != 0 - non_empty column, 0 - empty one | |
| 65 | + * (this array must be filled by caller) | |
| 66 | + */ | |
| 67 | +void ff_ivi_inverse_haar_8x8(const int32_t *in, int16_t *out, uint32_t pitch, | |
| 68 | + const uint8_t *flags); | |
| 69 | + | |
| 70 | +/** | |
| 71 | + * DC-only two-dimensional inverse Haar transform for Indeo 4. | |
| 72 | + * Performing the inverse transform in this case is equivalent to | |
| 73 | + * spreading DC_coeff >> 3 over the whole block. | |
| 74 | + * | |
| 75 | + * @param[in] in pointer to the dc coefficient | |
| 76 | + * @param[out] out pointer to the output buffer (frame) | |
| 77 | + * @param[in] pitch pitch to move to the next y line | |
| 78 | + * @param[in] blk_size transform block size | |
| 79 | + */ | |
| 80 | +void ff_ivi_dc_haar_2d(const int32_t *in, int16_t *out, uint32_t pitch, | |
| 81 | + int blk_size); | |
| 82 | + | |
| 46 | 83 | /** |
| 47 | 84 | * two-dimensional inverse slant 8x8 transform |
| 48 | 85 | * |
| @@ -21,7 +21,7 @@ · 20 unmodified lines | ||
| 21 | 21 | #define AVCODEC_VERSION_H |
| 22 | 22 | |
| 23 | 23 | #define LIBAVCODEC_VERSION_MAJOR 53 |
| 24 | −#define LIBAVCODEC_VERSION_MINOR 31 | |
| 24 | +#define LIBAVCODEC_VERSION_MINOR 32 | |
| 25 | 25 | #define LIBAVCODEC_VERSION_MICRO 0 |
| 26 | 26 | |
| 27 | 27 | #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ |