Libav
|
00001 /* 00002 * Intel Indeo 2 codec 00003 * Copyright (c) 2005 Konstantin Shishkov 00004 * 00005 * This file is part of FFmpeg. 00006 * 00007 * FFmpeg is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public 00009 * License as published by the Free Software Foundation; either 00010 * version 2.1 of the License, or (at your option) any later version. 00011 * 00012 * FFmpeg is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with FFmpeg; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00020 */ 00021 00026 #define ALT_BITSTREAM_READER_LE 00027 #include "avcodec.h" 00028 #include "get_bits.h" 00029 #include "indeo2data.h" 00030 #include "libavutil/common.h" 00031 00032 typedef struct Ir2Context{ 00033 AVCodecContext *avctx; 00034 AVFrame picture; 00035 GetBitContext gb; 00036 int decode_delta; 00037 } Ir2Context; 00038 00039 #define CODE_VLC_BITS 14 00040 static VLC ir2_vlc; 00041 00042 /* Indeo 2 codes are in range 0x01..0x7F and 0x81..0x90 */ 00043 static inline int ir2_get_code(GetBitContext *gb) 00044 { 00045 return get_vlc2(gb, ir2_vlc.table, CODE_VLC_BITS, 1) + 1; 00046 } 00047 00048 static int ir2_decode_plane(Ir2Context *ctx, int width, int height, uint8_t *dst, int stride, 00049 const uint8_t *table) 00050 { 00051 int i; 00052 int j; 00053 int out = 0; 00054 int c; 00055 int t; 00056 00057 if(width&1) 00058 return -1; 00059 00060 /* first line contain absolute values, other lines contain deltas */ 00061 while (out < width){ 00062 c = ir2_get_code(&ctx->gb); 00063 if(c >= 0x80) { /* we have a run */ 00064 c -= 0x7F; 00065 if(out + c*2 > width) 00066 return -1; 00067 for (i = 0; i < c * 2; i++) 00068 dst[out++] = 0x80; 00069 } else { /* copy two values from table */ 00070 dst[out++] = table[c * 2]; 00071 dst[out++] = table[(c * 2) + 1]; 00072 } 00073 } 00074 dst += stride; 00075 00076 for (j = 1; j < height; j++){ 00077 out = 0; 00078 while (out < width){ 00079 c = ir2_get_code(&ctx->gb); 00080 if(c >= 0x80) { /* we have a skip */ 00081 c -= 0x7F; 00082 if(out + c*2 > width) 00083 return -1; 00084 for (i = 0; i < c * 2; i++) { 00085 dst[out] = dst[out - stride]; 00086 out++; 00087 } 00088 } else { /* add two deltas from table */ 00089 t = dst[out - stride] + (table[c * 2] - 128); 00090 t= av_clip_uint8(t); 00091 dst[out] = t; 00092 out++; 00093 t = dst[out - stride] + (table[(c * 2) + 1] - 128); 00094 t= av_clip_uint8(t); 00095 dst[out] = t; 00096 out++; 00097 } 00098 } 00099 dst += stride; 00100 } 00101 return 0; 00102 } 00103 00104 static int ir2_decode_plane_inter(Ir2Context *ctx, int width, int height, uint8_t *dst, int stride, 00105 const uint8_t *table) 00106 { 00107 int j; 00108 int out = 0; 00109 int c; 00110 int t; 00111 00112 if(width&1) 00113 return -1; 00114 00115 for (j = 0; j < height; j++){ 00116 out = 0; 00117 while (out < width){ 00118 c = ir2_get_code(&ctx->gb); 00119 if(c >= 0x80) { /* we have a skip */ 00120 c -= 0x7F; 00121 out += c * 2; 00122 } else { /* add two deltas from table */ 00123 t = dst[out] + (((table[c * 2] - 128)*3) >> 2); 00124 t= av_clip_uint8(t); 00125 dst[out] = t; 00126 out++; 00127 t = dst[out] + (((table[(c * 2) + 1] - 128)*3) >> 2); 00128 t= av_clip_uint8(t); 00129 dst[out] = t; 00130 out++; 00131 } 00132 } 00133 dst += stride; 00134 } 00135 return 0; 00136 } 00137 00138 static int ir2_decode_frame(AVCodecContext *avctx, 00139 void *data, int *data_size, 00140 AVPacket *avpkt) 00141 { 00142 const uint8_t *buf = avpkt->data; 00143 int buf_size = avpkt->size; 00144 Ir2Context * const s = avctx->priv_data; 00145 AVFrame *picture = data; 00146 AVFrame * const p= (AVFrame*)&s->picture; 00147 int start; 00148 00149 if(p->data[0]) 00150 avctx->release_buffer(avctx, p); 00151 00152 p->reference = 1; 00153 p->buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; 00154 if (avctx->reget_buffer(avctx, p)) { 00155 av_log(s->avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); 00156 return -1; 00157 } 00158 00159 start = 48; /* hardcoded for now */ 00160 00161 if (start >= buf_size) { 00162 av_log(s->avctx, AV_LOG_ERROR, "input buffer size too small (%d)\n", buf_size); 00163 return AVERROR_INVALIDDATA; 00164 } 00165 00166 s->decode_delta = buf[18]; 00167 00168 /* decide whether frame uses deltas or not */ 00169 #ifndef ALT_BITSTREAM_READER_LE 00170 for (i = 0; i < buf_size; i++) 00171 buf[i] = av_reverse[buf[i]]; 00172 #endif 00173 00174 init_get_bits(&s->gb, buf + start, (buf_size - start) * 8); 00175 00176 if (s->decode_delta) { /* intraframe */ 00177 ir2_decode_plane(s, avctx->width, avctx->height, 00178 s->picture.data[0], s->picture.linesize[0], ir2_luma_table); 00179 /* swapped U and V */ 00180 ir2_decode_plane(s, avctx->width >> 2, avctx->height >> 2, 00181 s->picture.data[2], s->picture.linesize[2], ir2_luma_table); 00182 ir2_decode_plane(s, avctx->width >> 2, avctx->height >> 2, 00183 s->picture.data[1], s->picture.linesize[1], ir2_luma_table); 00184 } else { /* interframe */ 00185 ir2_decode_plane_inter(s, avctx->width, avctx->height, 00186 s->picture.data[0], s->picture.linesize[0], ir2_luma_table); 00187 /* swapped U and V */ 00188 ir2_decode_plane_inter(s, avctx->width >> 2, avctx->height >> 2, 00189 s->picture.data[2], s->picture.linesize[2], ir2_luma_table); 00190 ir2_decode_plane_inter(s, avctx->width >> 2, avctx->height >> 2, 00191 s->picture.data[1], s->picture.linesize[1], ir2_luma_table); 00192 } 00193 00194 *picture= *(AVFrame*)&s->picture; 00195 *data_size = sizeof(AVPicture); 00196 00197 return buf_size; 00198 } 00199 00200 static av_cold int ir2_decode_init(AVCodecContext *avctx){ 00201 Ir2Context * const ic = avctx->priv_data; 00202 static VLC_TYPE vlc_tables[1 << CODE_VLC_BITS][2]; 00203 00204 ic->avctx = avctx; 00205 00206 avctx->pix_fmt= PIX_FMT_YUV410P; 00207 00208 ir2_vlc.table = vlc_tables; 00209 ir2_vlc.table_allocated = 1 << CODE_VLC_BITS; 00210 #ifdef ALT_BITSTREAM_READER_LE 00211 init_vlc(&ir2_vlc, CODE_VLC_BITS, IR2_CODES, 00212 &ir2_codes[0][1], 4, 2, 00213 &ir2_codes[0][0], 4, 2, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); 00214 #else 00215 init_vlc(&ir2_vlc, CODE_VLC_BITS, IR2_CODES, 00216 &ir2_codes[0][1], 4, 2, 00217 &ir2_codes[0][0], 4, 2, INIT_VLC_USE_NEW_STATIC); 00218 #endif 00219 00220 return 0; 00221 } 00222 00223 static av_cold int ir2_decode_end(AVCodecContext *avctx){ 00224 Ir2Context * const ic = avctx->priv_data; 00225 AVFrame *pic = &ic->picture; 00226 00227 if (pic->data[0]) 00228 avctx->release_buffer(avctx, pic); 00229 00230 return 0; 00231 } 00232 00233 AVCodec indeo2_decoder = { 00234 "indeo2", 00235 AVMEDIA_TYPE_VIDEO, 00236 CODEC_ID_INDEO2, 00237 sizeof(Ir2Context), 00238 ir2_decode_init, 00239 NULL, 00240 ir2_decode_end, 00241 ir2_decode_frame, 00242 CODEC_CAP_DR1, 00243 .long_name = NULL_IF_CONFIG_SMALL("Intel Indeo 2"), 00244 };