Mercurial > audlegacy-plugins
comparison src/ffmpeg/libavcodec/mdec.c @ 808:e8776388b02a trunk
[svn] - add ffmpeg
| author | nenolod |
|---|---|
| date | Mon, 12 Mar 2007 11:18:54 -0700 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 807:0f9c8d4d3ac4 | 808:e8776388b02a |
|---|---|
| 1 /* | |
| 2 * PSX MDEC codec | |
| 3 * Copyright (c) 2003 Michael Niedermayer | |
| 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 * based upon code from Sebastian Jedruszkiewicz <elf@frogger.rules.pl> | |
| 22 */ | |
| 23 | |
| 24 /** | |
| 25 * @file mdec.c | |
| 26 * PSX MDEC codec. | |
| 27 * This is very similar to intra only MPEG1. | |
| 28 */ | |
| 29 | |
| 30 #include "avcodec.h" | |
| 31 #include "dsputil.h" | |
| 32 #include "mpegvideo.h" | |
| 33 | |
| 34 //#undef NDEBUG | |
| 35 //#include <assert.h> | |
| 36 | |
| 37 typedef struct MDECContext{ | |
| 38 AVCodecContext *avctx; | |
| 39 DSPContext dsp; | |
| 40 AVFrame picture; | |
| 41 PutBitContext pb; | |
| 42 GetBitContext gb; | |
| 43 ScanTable scantable; | |
| 44 int version; | |
| 45 int qscale; | |
| 46 int last_dc[3]; | |
| 47 int mb_width; | |
| 48 int mb_height; | |
| 49 int mb_x, mb_y; | |
| 50 DECLARE_ALIGNED_8(DCTELEM, block[6][64]); | |
| 51 DECLARE_ALIGNED_8(uint16_t, intra_matrix[64]); | |
| 52 DECLARE_ALIGNED_8(int, q_intra_matrix[64]); | |
| 53 uint8_t *bitstream_buffer; | |
| 54 unsigned int bitstream_buffer_size; | |
| 55 int block_last_index[6]; | |
| 56 } MDECContext; | |
| 57 | |
| 58 //very similar to mpeg1 | |
| 59 static inline int mdec_decode_block_intra(MDECContext *a, DCTELEM *block, int n) | |
| 60 { | |
| 61 int level, diff, i, j, run; | |
| 62 int component; | |
| 63 RLTable *rl = &rl_mpeg1; | |
| 64 uint8_t * const scantable= a->scantable.permutated; | |
| 65 const uint16_t *quant_matrix= ff_mpeg1_default_intra_matrix; | |
| 66 const int qscale= a->qscale; | |
| 67 | |
| 68 /* DC coef */ | |
| 69 if(a->version==2){ | |
| 70 block[0]= 2*get_sbits(&a->gb, 10) + 1024; | |
| 71 }else{ | |
| 72 component = (n <= 3 ? 0 : n - 4 + 1); | |
| 73 diff = decode_dc(&a->gb, component); | |
| 74 if (diff >= 0xffff) | |
| 75 return -1; | |
| 76 a->last_dc[component]+= diff; | |
| 77 block[0] = a->last_dc[component]<<3; | |
| 78 } | |
| 79 | |
| 80 i = 0; | |
| 81 { | |
| 82 OPEN_READER(re, &a->gb); | |
| 83 /* now quantify & encode AC coefs */ | |
| 84 for(;;) { | |
| 85 UPDATE_CACHE(re, &a->gb); | |
| 86 GET_RL_VLC(level, run, re, &a->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2, 0); | |
| 87 | |
| 88 if(level == 127){ | |
| 89 break; | |
| 90 } else if(level != 0) { | |
| 91 i += run; | |
| 92 j = scantable[i]; | |
| 93 level= (level*qscale*quant_matrix[j])>>3; | |
| 94 // level= (level-1)|1; | |
| 95 level = (level ^ SHOW_SBITS(re, &a->gb, 1)) - SHOW_SBITS(re, &a->gb, 1); | |
| 96 LAST_SKIP_BITS(re, &a->gb, 1); | |
| 97 } else { | |
| 98 /* escape */ | |
| 99 run = SHOW_UBITS(re, &a->gb, 6)+1; LAST_SKIP_BITS(re, &a->gb, 6); | |
| 100 UPDATE_CACHE(re, &a->gb); | |
| 101 level = SHOW_SBITS(re, &a->gb, 10); SKIP_BITS(re, &a->gb, 10); | |
| 102 i += run; | |
| 103 j = scantable[i]; | |
| 104 if(level<0){ | |
| 105 level= -level; | |
| 106 level= (level*qscale*quant_matrix[j])>>3; | |
| 107 level= (level-1)|1; | |
| 108 level= -level; | |
| 109 }else{ | |
| 110 level= (level*qscale*quant_matrix[j])>>3; | |
| 111 level= (level-1)|1; | |
| 112 } | |
| 113 } | |
| 114 if (i > 63){ | |
| 115 av_log(a->avctx, AV_LOG_ERROR, "ac-tex damaged at %d %d\n", a->mb_x, a->mb_y); | |
| 116 return -1; | |
| 117 } | |
| 118 | |
| 119 block[j] = level; | |
| 120 } | |
| 121 CLOSE_READER(re, &a->gb); | |
| 122 } | |
| 123 a->block_last_index[n] = i; | |
| 124 return 0; | |
| 125 } | |
| 126 | |
| 127 static inline int decode_mb(MDECContext *a, DCTELEM block[6][64]){ | |
| 128 int i; | |
| 129 const int block_index[6]= {5,4,0,1,2,3}; | |
| 130 | |
| 131 a->dsp.clear_blocks(block[0]); | |
| 132 | |
| 133 for(i=0; i<6; i++){ | |
| 134 if( mdec_decode_block_intra(a, block[ block_index[i] ], block_index[i]) < 0) | |
| 135 return -1; | |
| 136 } | |
| 137 return 0; | |
| 138 } | |
| 139 | |
| 140 static inline void idct_put(MDECContext *a, int mb_x, int mb_y){ | |
| 141 DCTELEM (*block)[64]= a->block; | |
| 142 int linesize= a->picture.linesize[0]; | |
| 143 | |
| 144 uint8_t *dest_y = a->picture.data[0] + (mb_y * 16* linesize ) + mb_x * 16; | |
| 145 uint8_t *dest_cb = a->picture.data[1] + (mb_y * 8 * a->picture.linesize[1]) + mb_x * 8; | |
| 146 uint8_t *dest_cr = a->picture.data[2] + (mb_y * 8 * a->picture.linesize[2]) + mb_x * 8; | |
| 147 | |
| 148 a->dsp.idct_put(dest_y , linesize, block[0]); | |
| 149 a->dsp.idct_put(dest_y + 8, linesize, block[1]); | |
| 150 a->dsp.idct_put(dest_y + 8*linesize , linesize, block[2]); | |
| 151 a->dsp.idct_put(dest_y + 8*linesize + 8, linesize, block[3]); | |
| 152 | |
| 153 if(!(a->avctx->flags&CODEC_FLAG_GRAY)){ | |
| 154 a->dsp.idct_put(dest_cb, a->picture.linesize[1], block[4]); | |
| 155 a->dsp.idct_put(dest_cr, a->picture.linesize[2], block[5]); | |
| 156 } | |
| 157 } | |
| 158 | |
| 159 static int decode_frame(AVCodecContext *avctx, | |
| 160 void *data, int *data_size, | |
| 161 uint8_t *buf, int buf_size) | |
| 162 { | |
| 163 MDECContext * const a = avctx->priv_data; | |
| 164 AVFrame *picture = data; | |
| 165 AVFrame * const p= (AVFrame*)&a->picture; | |
| 166 int i; | |
| 167 | |
| 168 if(p->data[0]) | |
| 169 avctx->release_buffer(avctx, p); | |
| 170 | |
| 171 p->reference= 0; | |
| 172 if(avctx->get_buffer(avctx, p) < 0){ | |
| 173 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); | |
| 174 return -1; | |
| 175 } | |
| 176 p->pict_type= I_TYPE; | |
| 177 p->key_frame= 1; | |
| 178 a->last_dc[0]= | |
| 179 a->last_dc[1]= | |
| 180 a->last_dc[2]= 0; | |
| 181 | |
| 182 a->bitstream_buffer= av_fast_realloc(a->bitstream_buffer, &a->bitstream_buffer_size, buf_size + FF_INPUT_BUFFER_PADDING_SIZE); | |
| 183 for(i=0; i<buf_size; i+=2){ | |
| 184 a->bitstream_buffer[i] = buf[i+1]; | |
| 185 a->bitstream_buffer[i+1]= buf[i ]; | |
| 186 } | |
| 187 init_get_bits(&a->gb, a->bitstream_buffer, buf_size*8); | |
| 188 | |
| 189 /* skip over 4 preamble bytes in stream (typically 0xXX 0xXX 0x00 0x38) */ | |
| 190 skip_bits(&a->gb, 32); | |
| 191 | |
| 192 a->qscale= get_bits(&a->gb, 16); | |
| 193 a->version= get_bits(&a->gb, 16); | |
| 194 | |
| 195 // printf("qscale:%d (0x%X), version:%d (0x%X)\n", a->qscale, a->qscale, a->version, a->version); | |
| 196 | |
| 197 for(a->mb_x=0; a->mb_x<a->mb_width; a->mb_x++){ | |
| 198 for(a->mb_y=0; a->mb_y<a->mb_height; a->mb_y++){ | |
| 199 if( decode_mb(a, a->block) <0) | |
| 200 return -1; | |
| 201 | |
| 202 idct_put(a, a->mb_x, a->mb_y); | |
| 203 } | |
| 204 } | |
| 205 | |
| 206 // p->quality= (32 + a->inv_qscale/2)/a->inv_qscale; | |
| 207 // memset(p->qscale_table, p->quality, p->qstride*a->mb_height); | |
| 208 | |
| 209 *picture= *(AVFrame*)&a->picture; | |
| 210 *data_size = sizeof(AVPicture); | |
| 211 | |
| 212 emms_c(); | |
| 213 | |
| 214 return (get_bits_count(&a->gb)+31)/32*4; | |
| 215 } | |
| 216 | |
| 217 static void mdec_common_init(AVCodecContext *avctx){ | |
| 218 MDECContext * const a = avctx->priv_data; | |
| 219 | |
| 220 dsputil_init(&a->dsp, avctx); | |
| 221 | |
| 222 a->mb_width = (avctx->coded_width + 15) / 16; | |
| 223 a->mb_height = (avctx->coded_height + 15) / 16; | |
| 224 | |
| 225 avctx->coded_frame= (AVFrame*)&a->picture; | |
| 226 a->avctx= avctx; | |
| 227 } | |
| 228 | |
| 229 static int decode_init(AVCodecContext *avctx){ | |
| 230 MDECContext * const a = avctx->priv_data; | |
| 231 AVFrame *p= (AVFrame*)&a->picture; | |
| 232 | |
| 233 mdec_common_init(avctx); | |
| 234 init_vlcs(); | |
| 235 ff_init_scantable(a->dsp.idct_permutation, &a->scantable, ff_zigzag_direct); | |
| 236 /* | |
| 237 for(i=0; i<64; i++){ | |
| 238 int index= ff_zigzag_direct[i]; | |
| 239 a->intra_matrix[i]= 64*ff_mpeg1_default_intra_matrix[index] / a->inv_qscale; | |
| 240 } | |
| 241 */ | |
| 242 p->qstride= a->mb_width; | |
| 243 p->qscale_table= av_mallocz( p->qstride * a->mb_height); | |
| 244 avctx->pix_fmt= PIX_FMT_YUV420P; | |
| 245 | |
| 246 return 0; | |
| 247 } | |
| 248 | |
| 249 static int decode_end(AVCodecContext *avctx){ | |
| 250 MDECContext * const a = avctx->priv_data; | |
| 251 | |
| 252 av_freep(&a->bitstream_buffer); | |
| 253 av_freep(&a->picture.qscale_table); | |
| 254 a->bitstream_buffer_size=0; | |
| 255 | |
| 256 return 0; | |
| 257 } | |
| 258 | |
| 259 AVCodec mdec_decoder = { | |
| 260 "mdec", | |
| 261 CODEC_TYPE_VIDEO, | |
| 262 CODEC_ID_MDEC, | |
| 263 sizeof(MDECContext), | |
| 264 decode_init, | |
| 265 NULL, | |
| 266 decode_end, | |
| 267 decode_frame, | |
| 268 CODEC_CAP_DR1, | |
| 269 }; | |
| 270 |
