1/* 2 * Intel Indeo 2 codec 3 * Copyright (c) 2005 Konstantin Shishkov 4 * 5 * This file is part of FFmpeg. 6 * 7 * FFmpeg is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * FFmpeg is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with FFmpeg; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 */ 21 22/** 23 * @file 24 * Intel Indeo 2 decoder. 25 */ 26#define ALT_BITSTREAM_READER_LE 27#include "avcodec.h" 28#include "get_bits.h" 29#include "indeo2data.h" 30#include "libavutil/common.h" 31 32typedef struct Ir2Context{ 33 AVCodecContext *avctx; 34 AVFrame picture; 35 GetBitContext gb; 36 int decode_delta; 37} Ir2Context; 38 39#define CODE_VLC_BITS 14 40static VLC ir2_vlc; 41 42/* Indeo 2 codes are in range 0x01..0x7F and 0x81..0x90 */ 43static inline int ir2_get_code(GetBitContext *gb) 44{ 45 return get_vlc2(gb, ir2_vlc.table, CODE_VLC_BITS, 1) + 1; 46} 47 48static int ir2_decode_plane(Ir2Context *ctx, int width, int height, uint8_t *dst, int stride, 49 const uint8_t *table) 50{ 51 int i; 52 int j; 53 int out = 0; 54 int c; 55 int t; 56 57 if(width&1) 58 return -1; 59 60 /* first line contain absolute values, other lines contain deltas */ 61 while (out < width){ 62 c = ir2_get_code(&ctx->gb); 63 if(c >= 0x80) { /* we have a run */ 64 c -= 0x7F; 65 if(out + c*2 > width) 66 return -1; 67 for (i = 0; i < c * 2; i++) 68 dst[out++] = 0x80; 69 } else { /* copy two values from table */ 70 dst[out++] = table[c * 2]; 71 dst[out++] = table[(c * 2) + 1]; 72 } 73 } 74 dst += stride; 75 76 for (j = 1; j < height; j++){ 77 out = 0; 78 while (out < width){ 79 c = ir2_get_code(&ctx->gb); 80 if(c >= 0x80) { /* we have a skip */ 81 c -= 0x7F; 82 if(out + c*2 > width) 83 return -1; 84 for (i = 0; i < c * 2; i++) { 85 dst[out] = dst[out - stride]; 86 out++; 87 } 88 } else { /* add two deltas from table */ 89 t = dst[out - stride] + (table[c * 2] - 128); 90 t= av_clip_uint8(t); 91 dst[out] = t; 92 out++; 93 t = dst[out - stride] + (table[(c * 2) + 1] - 128); 94 t= av_clip_uint8(t); 95 dst[out] = t; 96 out++; 97 } 98 } 99 dst += stride; 100 } 101 return 0; 102} 103 104static int ir2_decode_plane_inter(Ir2Context *ctx, int width, int height, uint8_t *dst, int stride, 105 const uint8_t *table) 106{ 107 int j; 108 int out = 0; 109 int c; 110 int t; 111 112 if(width&1) 113 return -1; 114 115 for (j = 0; j < height; j++){ 116 out = 0; 117 while (out < width){ 118 c = ir2_get_code(&ctx->gb); 119 if(c >= 0x80) { /* we have a skip */ 120 c -= 0x7F; 121 out += c * 2; 122 } else { /* add two deltas from table */ 123 t = dst[out] + (((table[c * 2] - 128)*3) >> 2); 124 t= av_clip_uint8(t); 125 dst[out] = t; 126 out++; 127 t = dst[out] + (((table[(c * 2) + 1] - 128)*3) >> 2); 128 t= av_clip_uint8(t); 129 dst[out] = t; 130 out++; 131 } 132 } 133 dst += stride; 134 } 135 return 0; 136} 137 138static int ir2_decode_frame(AVCodecContext *avctx, 139 void *data, int *data_size, 140 AVPacket *avpkt) 141{ 142 const uint8_t *buf = avpkt->data; 143 int buf_size = avpkt->size; 144 Ir2Context * const s = avctx->priv_data; 145 AVFrame *picture = data; 146 AVFrame * const p= (AVFrame*)&s->picture; 147 int start; 148 149 if(p->data[0]) 150 avctx->release_buffer(avctx, p); 151 152 p->reference = 1; 153 p->buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; 154 if (avctx->reget_buffer(avctx, p)) { 155 av_log(s->avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); 156 return -1; 157 } 158 159 s->decode_delta = buf[18]; 160 161 /* decide whether frame uses deltas or not */ 162#ifndef ALT_BITSTREAM_READER_LE 163 for (i = 0; i < buf_size; i++) 164 buf[i] = av_reverse[buf[i]]; 165#endif 166 start = 48; /* hardcoded for now */ 167 168 init_get_bits(&s->gb, buf + start, buf_size - start); 169 170 if (s->decode_delta) { /* intraframe */ 171 ir2_decode_plane(s, avctx->width, avctx->height, 172 s->picture.data[0], s->picture.linesize[0], ir2_luma_table); 173 /* swapped U and V */ 174 ir2_decode_plane(s, avctx->width >> 2, avctx->height >> 2, 175 s->picture.data[2], s->picture.linesize[2], ir2_luma_table); 176 ir2_decode_plane(s, avctx->width >> 2, avctx->height >> 2, 177 s->picture.data[1], s->picture.linesize[1], ir2_luma_table); 178 } else { /* interframe */ 179 ir2_decode_plane_inter(s, avctx->width, avctx->height, 180 s->picture.data[0], s->picture.linesize[0], ir2_luma_table); 181 /* swapped U and V */ 182 ir2_decode_plane_inter(s, avctx->width >> 2, avctx->height >> 2, 183 s->picture.data[2], s->picture.linesize[2], ir2_luma_table); 184 ir2_decode_plane_inter(s, avctx->width >> 2, avctx->height >> 2, 185 s->picture.data[1], s->picture.linesize[1], ir2_luma_table); 186 } 187 188 *picture= *(AVFrame*)&s->picture; 189 *data_size = sizeof(AVPicture); 190 191 return buf_size; 192} 193 194static av_cold int ir2_decode_init(AVCodecContext *avctx){ 195 Ir2Context * const ic = avctx->priv_data; 196 static VLC_TYPE vlc_tables[1 << CODE_VLC_BITS][2]; 197 198 ic->avctx = avctx; 199 200 avctx->pix_fmt= PIX_FMT_YUV410P; 201 202 ir2_vlc.table = vlc_tables; 203 ir2_vlc.table_allocated = 1 << CODE_VLC_BITS; 204#ifdef ALT_BITSTREAM_READER_LE 205 init_vlc(&ir2_vlc, CODE_VLC_BITS, IR2_CODES, 206 &ir2_codes[0][1], 4, 2, 207 &ir2_codes[0][0], 4, 2, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); 208#else 209 init_vlc(&ir2_vlc, CODE_VLC_BITS, IR2_CODES, 210 &ir2_codes[0][1], 4, 2, 211 &ir2_codes[0][0], 4, 2, INIT_VLC_USE_NEW_STATIC); 212#endif 213 214 return 0; 215} 216 217static av_cold int ir2_decode_end(AVCodecContext *avctx){ 218 Ir2Context * const ic = avctx->priv_data; 219 AVFrame *pic = &ic->picture; 220 221 if (pic->data[0]) 222 avctx->release_buffer(avctx, pic); 223 224 return 0; 225} 226 227AVCodec indeo2_decoder = { 228 "indeo2", 229 AVMEDIA_TYPE_VIDEO, 230 CODEC_ID_INDEO2, 231 sizeof(Ir2Context), 232 ir2_decode_init, 233 NULL, 234 ir2_decode_end, 235 ir2_decode_frame, 236 CODEC_CAP_DR1, 237 .long_name = NULL_IF_CONFIG_SMALL("Intel Indeo 2"), 238}; 239