• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

libavcodec/4xm.c

Go to the documentation of this file.
00001 /*
00002  * 4XM codec
00003  * Copyright (c) 2003 Michael Niedermayer
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 
00027 #include "libavutil/intreadwrite.h"
00028 #include "avcodec.h"
00029 #include "dsputil.h"
00030 #include "get_bits.h"
00031 #include "bytestream.h"
00032 
00033 //#undef NDEBUG
00034 //#include <assert.h>
00035 
00036 #define BLOCK_TYPE_VLC_BITS 5
00037 #define ACDC_VLC_BITS 9
00038 
00039 #define CFRAME_BUFFER_COUNT 100
00040 
00041 static const uint8_t block_type_tab[2][4][8][2]={
00042  {
00043   {   //{8,4,2}x{8,4,2}
00044     { 0,1}, { 2,2}, { 6,3}, {14,4}, {30,5}, {31,5}, { 0,0}
00045   },{ //{8,4}x1
00046     { 0,1}, { 0,0}, { 2,2}, { 6,3}, {14,4}, {15,4}, { 0,0}
00047   },{ //1x{8,4}
00048     { 0,1}, { 2,2}, { 0,0}, { 6,3}, {14,4}, {15,4}, { 0,0}
00049   },{ //1x2, 2x1
00050     { 0,1}, { 0,0}, { 0,0}, { 2,2}, { 6,3}, {14,4}, {15,4}
00051   }
00052  },{
00053   {  //{8,4,2}x{8,4,2}
00054     { 1,2}, { 4,3}, { 5,3}, {0,2}, {6,3}, {7,3}, {0,0}
00055   },{//{8,4}x1
00056     { 1,2}, { 0,0}, { 2,2}, {0,2}, {6,3}, {7,3}, {0,0}
00057   },{//1x{8,4}
00058     { 1,2}, { 2,2}, { 0,0}, {0,2}, {6,3}, {7,3}, {0,0}
00059   },{//1x2, 2x1
00060     { 1,2}, { 0,0}, { 0,0}, {0,2}, {2,2}, {6,3}, {7,3}
00061   }
00062  }
00063 };
00064 
00065 static const uint8_t size2index[4][4]={
00066   {-1, 3, 1, 1},
00067   { 3, 0, 0, 0},
00068   { 2, 0, 0, 0},
00069   { 2, 0, 0, 0},
00070 };
00071 
00072 static const int8_t mv[256][2]={
00073 {  0,  0},{  0, -1},{ -1,  0},{  1,  0},{  0,  1},{ -1, -1},{  1, -1},{ -1,  1},
00074 {  1,  1},{  0, -2},{ -2,  0},{  2,  0},{  0,  2},{ -1, -2},{  1, -2},{ -2, -1},
00075 {  2, -1},{ -2,  1},{  2,  1},{ -1,  2},{  1,  2},{ -2, -2},{  2, -2},{ -2,  2},
00076 {  2,  2},{  0, -3},{ -3,  0},{  3,  0},{  0,  3},{ -1, -3},{  1, -3},{ -3, -1},
00077 {  3, -1},{ -3,  1},{  3,  1},{ -1,  3},{  1,  3},{ -2, -3},{  2, -3},{ -3, -2},
00078 {  3, -2},{ -3,  2},{  3,  2},{ -2,  3},{  2,  3},{  0, -4},{ -4,  0},{  4,  0},
00079 {  0,  4},{ -1, -4},{  1, -4},{ -4, -1},{  4, -1},{  4,  1},{ -1,  4},{  1,  4},
00080 { -3, -3},{ -3,  3},{  3,  3},{ -2, -4},{ -4, -2},{  4, -2},{ -4,  2},{ -2,  4},
00081 {  2,  4},{ -3, -4},{  3, -4},{  4, -3},{ -5,  0},{ -4,  3},{ -3,  4},{  3,  4},
00082 { -1, -5},{ -5, -1},{ -5,  1},{ -1,  5},{ -2, -5},{  2, -5},{  5, -2},{  5,  2},
00083 { -4, -4},{ -4,  4},{ -3, -5},{ -5, -3},{ -5,  3},{  3,  5},{ -6,  0},{  0,  6},
00084 { -6, -1},{ -6,  1},{  1,  6},{  2, -6},{ -6,  2},{  2,  6},{ -5, -4},{  5,  4},
00085 {  4,  5},{ -6, -3},{  6,  3},{ -7,  0},{ -1, -7},{  5, -5},{ -7,  1},{ -1,  7},
00086 {  4, -6},{  6,  4},{ -2, -7},{ -7,  2},{ -3, -7},{  7, -3},{  3,  7},{  6, -5},
00087 {  0, -8},{ -1, -8},{ -7, -4},{ -8,  1},{  4,  7},{  2, -8},{ -2,  8},{  6,  6},
00088 { -8,  3},{  5, -7},{ -5,  7},{  8, -4},{  0, -9},{ -9, -1},{  1,  9},{  7, -6},
00089 { -7,  6},{ -5, -8},{ -5,  8},{ -9,  3},{  9, -4},{  7, -7},{  8, -6},{  6,  8},
00090 { 10,  1},{-10,  2},{  9, -5},{ 10, -3},{ -8, -7},{-10, -4},{  6, -9},{-11,  0},
00091 { 11,  1},{-11, -2},{ -2, 11},{  7, -9},{ -7,  9},{ 10,  6},{ -4, 11},{  8, -9},
00092 {  8,  9},{  5, 11},{  7,-10},{ 12, -3},{ 11,  6},{ -9, -9},{  8, 10},{  5, 12},
00093 {-11,  7},{ 13,  2},{  6,-12},{ 10,  9},{-11,  8},{ -7, 12},{  0, 14},{ 14, -2},
00094 { -9, 11},{ -6, 13},{-14, -4},{ -5,-14},{  5, 14},{-15, -1},{-14, -6},{  3,-15},
00095 { 11,-11},{ -7, 14},{ -5, 15},{  8,-14},{ 15,  6},{  3, 16},{  7,-15},{-16,  5},
00096 {  0, 17},{-16, -6},{-10, 14},{-16,  7},{ 12, 13},{-16,  8},{-17,  6},{-18,  3},
00097 { -7, 17},{ 15, 11},{ 16, 10},{  2,-19},{  3,-19},{-11,-16},{-18,  8},{-19, -6},
00098 {  2,-20},{-17,-11},{-10,-18},{  8, 19},{-21, -1},{-20,  7},{ -4, 21},{ 21,  5},
00099 { 15, 16},{  2,-22},{-10,-20},{-22,  5},{ 20,-11},{ -7,-22},{-12, 20},{ 23, -5},
00100 { 13,-20},{ 24, -2},{-15, 19},{-11, 22},{ 16, 19},{ 23,-10},{-18,-18},{ -9,-24},
00101 { 24,-10},{ -3, 26},{-23, 13},{-18,-20},{ 17, 21},{ -4, 27},{ 27,  6},{  1,-28},
00102 {-11, 26},{-17,-23},{  7, 28},{ 11,-27},{ 29,  5},{-23,-19},{-28,-11},{-21, 22},
00103 {-30,  7},{-17, 26},{-27, 16},{ 13, 29},{ 19,-26},{ 10,-31},{-14,-30},{ 20,-27},
00104 {-29, 18},{-16,-31},{-28,-22},{ 21,-30},{-25, 28},{ 26,-29},{ 25,-32},{-32,-32}
00105 };
00106 
00107 // this is simply the scaled down elementwise product of the standard jpeg quantizer table and the AAN premul table
00108 static const uint8_t dequant_table[64]={
00109  16, 15, 13, 19, 24, 31, 28, 17,
00110  17, 23, 25, 31, 36, 63, 45, 21,
00111  18, 24, 27, 37, 52, 59, 49, 20,
00112  16, 28, 34, 40, 60, 80, 51, 20,
00113  18, 31, 48, 66, 68, 86, 56, 21,
00114  19, 38, 56, 59, 64, 64, 48, 20,
00115  27, 48, 55, 55, 56, 51, 35, 15,
00116  20, 35, 34, 32, 31, 22, 15,  8,
00117 };
00118 
00119 static VLC block_type_vlc[2][4];
00120 
00121 
00122 typedef struct CFrameBuffer{
00123     unsigned int allocated_size;
00124     unsigned int size;
00125     int id;
00126     uint8_t *data;
00127 }CFrameBuffer;
00128 
00129 typedef struct FourXContext{
00130     AVCodecContext *avctx;
00131     DSPContext dsp;
00132     AVFrame current_picture, last_picture;
00133     GetBitContext pre_gb;          
00134     GetBitContext gb;
00135     const uint8_t *bytestream;
00136     const uint16_t *wordstream;
00137     int mv[256];
00138     VLC pre_vlc;
00139     int last_dc;
00140     DECLARE_ALIGNED(16, DCTELEM, block)[6][64];
00141     void *bitstream_buffer;
00142     unsigned int bitstream_buffer_size;
00143     int version;
00144     CFrameBuffer cfrm[CFRAME_BUFFER_COUNT];
00145 } FourXContext;
00146 
00147 
00148 #define FIX_1_082392200  70936
00149 #define FIX_1_414213562  92682
00150 #define FIX_1_847759065 121095
00151 #define FIX_2_613125930 171254
00152 
00153 #define MULTIPLY(var,const)  (((var)*(const)) >> 16)
00154 
00155 static void idct(DCTELEM block[64]){
00156     int tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
00157     int tmp10, tmp11, tmp12, tmp13;
00158     int z5, z10, z11, z12, z13;
00159     int i;
00160     int temp[64];
00161 
00162     for(i=0; i<8; i++){
00163         tmp10 = block[8*0 + i] + block[8*4 + i];
00164         tmp11 = block[8*0 + i] - block[8*4 + i];
00165 
00166         tmp13 =          block[8*2 + i] + block[8*6 + i];
00167         tmp12 = MULTIPLY(block[8*2 + i] - block[8*6 + i], FIX_1_414213562) - tmp13;
00168 
00169         tmp0 = tmp10 + tmp13;
00170         tmp3 = tmp10 - tmp13;
00171         tmp1 = tmp11 + tmp12;
00172         tmp2 = tmp11 - tmp12;
00173 
00174         z13 = block[8*5 + i] + block[8*3 + i];
00175         z10 = block[8*5 + i] - block[8*3 + i];
00176         z11 = block[8*1 + i] + block[8*7 + i];
00177         z12 = block[8*1 + i] - block[8*7 + i];
00178 
00179         tmp7  =          z11 + z13;
00180         tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562);
00181 
00182         z5    = MULTIPLY(z10 + z12, FIX_1_847759065);
00183         tmp10 = MULTIPLY(z12, FIX_1_082392200) - z5;
00184         tmp12 = MULTIPLY(z10, - FIX_2_613125930) + z5;
00185 
00186         tmp6 = tmp12 - tmp7;
00187         tmp5 = tmp11 - tmp6;
00188         tmp4 = tmp10 + tmp5;
00189 
00190         temp[8*0 + i] = tmp0 + tmp7;
00191         temp[8*7 + i] = tmp0 - tmp7;
00192         temp[8*1 + i] = tmp1 + tmp6;
00193         temp[8*6 + i] = tmp1 - tmp6;
00194         temp[8*2 + i] = tmp2 + tmp5;
00195         temp[8*5 + i] = tmp2 - tmp5;
00196         temp[8*4 + i] = tmp3 + tmp4;
00197         temp[8*3 + i] = tmp3 - tmp4;
00198     }
00199 
00200     for(i=0; i<8*8; i+=8){
00201         tmp10 = temp[0 + i] + temp[4 + i];
00202         tmp11 = temp[0 + i] - temp[4 + i];
00203 
00204         tmp13 = temp[2 + i] + temp[6 + i];
00205         tmp12 = MULTIPLY(temp[2 + i] - temp[6 + i], FIX_1_414213562) - tmp13;
00206 
00207         tmp0 = tmp10 + tmp13;
00208         tmp3 = tmp10 - tmp13;
00209         tmp1 = tmp11 + tmp12;
00210         tmp2 = tmp11 - tmp12;
00211 
00212         z13 = temp[5 + i] + temp[3 + i];
00213         z10 = temp[5 + i] - temp[3 + i];
00214         z11 = temp[1 + i] + temp[7 + i];
00215         z12 = temp[1 + i] - temp[7 + i];
00216 
00217         tmp7 = z11 + z13;
00218         tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562);
00219 
00220         z5 = MULTIPLY(z10 + z12, FIX_1_847759065);
00221         tmp10 = MULTIPLY(z12, FIX_1_082392200) - z5;
00222         tmp12 = MULTIPLY(z10, - FIX_2_613125930) + z5;
00223 
00224         tmp6 = tmp12 - tmp7;
00225         tmp5 = tmp11 - tmp6;
00226         tmp4 = tmp10 + tmp5;
00227 
00228         block[0 + i] = (tmp0 + tmp7)>>6;
00229         block[7 + i] = (tmp0 - tmp7)>>6;
00230         block[1 + i] = (tmp1 + tmp6)>>6;
00231         block[6 + i] = (tmp1 - tmp6)>>6;
00232         block[2 + i] = (tmp2 + tmp5)>>6;
00233         block[5 + i] = (tmp2 - tmp5)>>6;
00234         block[4 + i] = (tmp3 + tmp4)>>6;
00235         block[3 + i] = (tmp3 - tmp4)>>6;
00236     }
00237 }
00238 
00239 static av_cold void init_vlcs(FourXContext *f){
00240     static VLC_TYPE table[8][32][2];
00241     int i;
00242 
00243     for(i=0; i<8; i++){
00244         block_type_vlc[0][i].table= table[i];
00245         block_type_vlc[0][i].table_allocated= 32;
00246         init_vlc(&block_type_vlc[0][i], BLOCK_TYPE_VLC_BITS, 7,
00247                  &block_type_tab[0][i][0][1], 2, 1,
00248                  &block_type_tab[0][i][0][0], 2, 1, INIT_VLC_USE_NEW_STATIC);
00249     }
00250 }
00251 
00252 static void init_mv(FourXContext *f){
00253     int i;
00254 
00255     for(i=0; i<256; i++){
00256         if(f->version>1)
00257             f->mv[i] = mv[i][0]   + mv[i][1]  *f->current_picture.linesize[0]/2;
00258         else
00259             f->mv[i] = (i&15) - 8 + ((i>>4)-8)*f->current_picture.linesize[0]/2;
00260     }
00261 }
00262 
00263 static inline void mcdc(uint16_t *dst, uint16_t *src, int log2w, int h, int stride, int scale, int dc){
00264    int i;
00265    dc*= 0x10001;
00266 
00267    switch(log2w){
00268    case 0:
00269         for(i=0; i<h; i++){
00270             dst[0] = scale*src[0] + dc;
00271             if(scale) src += stride;
00272             dst += stride;
00273         }
00274         break;
00275     case 1:
00276         for(i=0; i<h; i++){
00277             ((uint32_t*)dst)[0] = scale*((uint32_t*)src)[0] + dc;
00278             if(scale) src += stride;
00279             dst += stride;
00280         }
00281         break;
00282     case 2:
00283         for(i=0; i<h; i++){
00284             ((uint32_t*)dst)[0] = scale*((uint32_t*)src)[0] + dc;
00285             ((uint32_t*)dst)[1] = scale*((uint32_t*)src)[1] + dc;
00286             if(scale) src += stride;
00287             dst += stride;
00288         }
00289         break;
00290     case 3:
00291         for(i=0; i<h; i++){
00292             ((uint32_t*)dst)[0] = scale*((uint32_t*)src)[0] + dc;
00293             ((uint32_t*)dst)[1] = scale*((uint32_t*)src)[1] + dc;
00294             ((uint32_t*)dst)[2] = scale*((uint32_t*)src)[2] + dc;
00295             ((uint32_t*)dst)[3] = scale*((uint32_t*)src)[3] + dc;
00296             if(scale) src += stride;
00297             dst += stride;
00298         }
00299         break;
00300     default: assert(0);
00301     }
00302 }
00303 
00304 static void decode_p_block(FourXContext *f, uint16_t *dst, uint16_t *src, int log2w, int log2h, int stride){
00305     const int index= size2index[log2h][log2w];
00306     const int h= 1<<log2h;
00307     int code= get_vlc2(&f->gb, block_type_vlc[1-(f->version>1)][index].table, BLOCK_TYPE_VLC_BITS, 1);
00308     uint16_t *start= (uint16_t*)f->last_picture.data[0];
00309     uint16_t *end= start + stride*(f->avctx->height-h+1) - (1<<log2w);
00310 
00311     assert(code>=0 && code<=6);
00312 
00313     if(code == 0){
00314         src += f->mv[ *f->bytestream++ ];
00315         if(start > src || src > end){
00316             av_log(f->avctx, AV_LOG_ERROR, "mv out of pic\n");
00317             return;
00318         }
00319         mcdc(dst, src, log2w, h, stride, 1, 0);
00320     }else if(code == 1){
00321         log2h--;
00322         decode_p_block(f, dst                  , src                  , log2w, log2h, stride);
00323         decode_p_block(f, dst + (stride<<log2h), src + (stride<<log2h), log2w, log2h, stride);
00324     }else if(code == 2){
00325         log2w--;
00326         decode_p_block(f, dst             , src             , log2w, log2h, stride);
00327         decode_p_block(f, dst + (1<<log2w), src + (1<<log2w), log2w, log2h, stride);
00328     }else if(code == 3 && f->version<2){
00329         mcdc(dst, src, log2w, h, stride, 1, 0);
00330     }else if(code == 4){
00331         src += f->mv[ *f->bytestream++ ];
00332         if(start > src || src > end){
00333             av_log(f->avctx, AV_LOG_ERROR, "mv out of pic\n");
00334             return;
00335         }
00336         mcdc(dst, src, log2w, h, stride, 1, le2me_16(*f->wordstream++));
00337     }else if(code == 5){
00338         mcdc(dst, src, log2w, h, stride, 0, le2me_16(*f->wordstream++));
00339     }else if(code == 6){
00340         if(log2w){
00341             dst[0] = le2me_16(*f->wordstream++);
00342             dst[1] = le2me_16(*f->wordstream++);
00343         }else{
00344             dst[0     ] = le2me_16(*f->wordstream++);
00345             dst[stride] = le2me_16(*f->wordstream++);
00346         }
00347     }
00348 }
00349 
00350 static int decode_p_frame(FourXContext *f, const uint8_t *buf, int length){
00351     int x, y;
00352     const int width= f->avctx->width;
00353     const int height= f->avctx->height;
00354     uint16_t *src= (uint16_t*)f->last_picture.data[0];
00355     uint16_t *dst= (uint16_t*)f->current_picture.data[0];
00356     const int stride= f->current_picture.linesize[0]>>1;
00357     unsigned int bitstream_size, bytestream_size, wordstream_size, extra;
00358 
00359     if(f->version>1){
00360         extra=20;
00361         bitstream_size= AV_RL32(buf+8);
00362         wordstream_size= AV_RL32(buf+12);
00363         bytestream_size= AV_RL32(buf+16);
00364     }else{
00365         extra=0;
00366         bitstream_size = AV_RL16(buf-4);
00367         wordstream_size= AV_RL16(buf-2);
00368         bytestream_size= FFMAX(length - bitstream_size - wordstream_size, 0);
00369     }
00370 
00371     if(bitstream_size+ bytestream_size+ wordstream_size + extra != length
00372        || bitstream_size  > (1<<26)
00373        || bytestream_size > (1<<26)
00374        || wordstream_size > (1<<26)
00375        ){
00376         av_log(f->avctx, AV_LOG_ERROR, "lengths %d %d %d %d\n", bitstream_size, bytestream_size, wordstream_size,
00377         bitstream_size+ bytestream_size+ wordstream_size - length);
00378         return -1;
00379     }
00380 
00381     av_fast_malloc(&f->bitstream_buffer, &f->bitstream_buffer_size, bitstream_size + FF_INPUT_BUFFER_PADDING_SIZE);
00382     if (!f->bitstream_buffer)
00383         return AVERROR(ENOMEM);
00384     f->dsp.bswap_buf(f->bitstream_buffer, (const uint32_t*)(buf + extra), bitstream_size/4);
00385     init_get_bits(&f->gb, f->bitstream_buffer, 8*bitstream_size);
00386 
00387     f->wordstream= (const uint16_t*)(buf + extra + bitstream_size);
00388     f->bytestream= buf + extra + bitstream_size + wordstream_size;
00389 
00390     init_mv(f);
00391 
00392     for(y=0; y<height; y+=8){
00393         for(x=0; x<width; x+=8){
00394             decode_p_block(f, dst + x, src + x, 3, 3, stride);
00395         }
00396         src += 8*stride;
00397         dst += 8*stride;
00398     }
00399 
00400     if(   bitstream_size != (get_bits_count(&f->gb)+31)/32*4
00401        || (((const char*)f->wordstream - (const char*)buf + 2)&~2) != extra + bitstream_size + wordstream_size
00402        || (((const char*)f->bytestream - (const char*)buf + 3)&~3) != extra + bitstream_size + wordstream_size + bytestream_size)
00403         av_log(f->avctx, AV_LOG_ERROR, " %d %td %td bytes left\n",
00404             bitstream_size - (get_bits_count(&f->gb)+31)/32*4,
00405             -(((const char*)f->bytestream - (const char*)buf + 3)&~3) + (extra + bitstream_size + wordstream_size + bytestream_size),
00406             -(((const char*)f->wordstream - (const char*)buf + 2)&~2) + (extra + bitstream_size + wordstream_size)
00407         );
00408 
00409     return 0;
00410 }
00411 
00416 static int decode_i_block(FourXContext *f, DCTELEM *block){
00417     int code, i, j, level, val;
00418 
00419     /* DC coef */
00420     val = get_vlc2(&f->pre_gb, f->pre_vlc.table, ACDC_VLC_BITS, 3);
00421     if (val>>4){
00422         av_log(f->avctx, AV_LOG_ERROR, "error dc run != 0\n");
00423     }
00424 
00425     if(val)
00426         val = get_xbits(&f->gb, val);
00427 
00428     val = val * dequant_table[0] + f->last_dc;
00429     f->last_dc =
00430     block[0] = val;
00431     /* AC coefs */
00432     i = 1;
00433     for(;;) {
00434         code = get_vlc2(&f->pre_gb, f->pre_vlc.table, ACDC_VLC_BITS, 3);
00435 
00436         /* EOB */
00437         if (code == 0)
00438             break;
00439         if (code == 0xf0) {
00440             i += 16;
00441         } else {
00442             level = get_xbits(&f->gb, code & 0xf);
00443             i += code >> 4;
00444             if (i >= 64) {
00445                 av_log(f->avctx, AV_LOG_ERROR, "run %d oveflow\n", i);
00446                 return 0;
00447             }
00448 
00449             j= ff_zigzag_direct[i];
00450             block[j] = level * dequant_table[j];
00451             i++;
00452             if (i >= 64)
00453                 break;
00454         }
00455     }
00456 
00457     return 0;
00458 }
00459 
00460 static inline void idct_put(FourXContext *f, int x, int y){
00461     DCTELEM (*block)[64]= f->block;
00462     int stride= f->current_picture.linesize[0]>>1;
00463     int i;
00464     uint16_t *dst = ((uint16_t*)f->current_picture.data[0]) + y * stride + x;
00465 
00466     for(i=0; i<4; i++){
00467         block[i][0] += 0x80*8*8;
00468         idct(block[i]);
00469     }
00470 
00471     if(!(f->avctx->flags&CODEC_FLAG_GRAY)){
00472         for(i=4; i<6; i++) idct(block[i]);
00473     }
00474 
00475 /* Note transform is:
00476 y= ( 1b + 4g + 2r)/14
00477 cb=( 3b - 2g - 1r)/14
00478 cr=(-1b - 4g + 5r)/14
00479 */
00480     for(y=0; y<8; y++){
00481         for(x=0; x<8; x++){
00482             DCTELEM *temp= block[(x>>2) + 2*(y>>2)] + 2*(x&3) + 2*8*(y&3); //FIXME optimize
00483             int cb= block[4][x + 8*y];
00484             int cr= block[5][x + 8*y];
00485             int cg= (cb + cr)>>1;
00486             int y;
00487 
00488             cb+=cb;
00489 
00490             y = temp[0];
00491             dst[0       ]= ((y+cb)>>3) + (((y-cg)&0xFC)<<3) + (((y+cr)&0xF8)<<8);
00492             y = temp[1];
00493             dst[1       ]= ((y+cb)>>3) + (((y-cg)&0xFC)<<3) + (((y+cr)&0xF8)<<8);
00494             y = temp[8];
00495             dst[  stride]= ((y+cb)>>3) + (((y-cg)&0xFC)<<3) + (((y+cr)&0xF8)<<8);
00496             y = temp[9];
00497             dst[1+stride]= ((y+cb)>>3) + (((y-cg)&0xFC)<<3) + (((y+cr)&0xF8)<<8);
00498             dst += 2;
00499         }
00500         dst += 2*stride - 2*8;
00501     }
00502 }
00503 
00504 static int decode_i_mb(FourXContext *f){
00505     int i;
00506 
00507     f->dsp.clear_blocks(f->block[0]);
00508 
00509     for(i=0; i<6; i++){
00510         if(decode_i_block(f, f->block[i]) < 0)
00511             return -1;
00512     }
00513 
00514     return 0;
00515 }
00516 
00517 static const uint8_t *read_huffman_tables(FourXContext *f, const uint8_t * const buf){
00518     int frequency[512];
00519     uint8_t flag[512];
00520     int up[512];
00521     uint8_t len_tab[257];
00522     int bits_tab[257];
00523     int start, end;
00524     const uint8_t *ptr= buf;
00525     int j;
00526 
00527     memset(frequency, 0, sizeof(frequency));
00528     memset(up, -1, sizeof(up));
00529 
00530     start= *ptr++;
00531     end= *ptr++;
00532     for(;;){
00533         int i;
00534 
00535         for(i=start; i<=end; i++){
00536             frequency[i]= *ptr++;
00537         }
00538         start= *ptr++;
00539         if(start==0) break;
00540 
00541         end= *ptr++;
00542     }
00543     frequency[256]=1;
00544 
00545     while((ptr - buf)&3) ptr++; // 4byte align
00546 
00547     for(j=257; j<512; j++){
00548         int min_freq[2]= {256*256, 256*256};
00549         int smallest[2]= {0, 0};
00550         int i;
00551         for(i=0; i<j; i++){
00552             if(frequency[i] == 0) continue;
00553             if(frequency[i] < min_freq[1]){
00554                 if(frequency[i] < min_freq[0]){
00555                     min_freq[1]= min_freq[0]; smallest[1]= smallest[0];
00556                     min_freq[0]= frequency[i];smallest[0]= i;
00557                 }else{
00558                     min_freq[1]= frequency[i];smallest[1]= i;
00559                 }
00560             }
00561         }
00562         if(min_freq[1] == 256*256) break;
00563 
00564         frequency[j]= min_freq[0] + min_freq[1];
00565         flag[ smallest[0] ]= 0;
00566         flag[ smallest[1] ]= 1;
00567         up[ smallest[0] ]=
00568         up[ smallest[1] ]= j;
00569         frequency[ smallest[0] ]= frequency[ smallest[1] ]= 0;
00570     }
00571 
00572     for(j=0; j<257; j++){
00573         int node;
00574         int len=0;
00575         int bits=0;
00576 
00577         for(node= j; up[node] != -1; node= up[node]){
00578             bits += flag[node]<<len;
00579             len++;
00580             if(len > 31) av_log(f->avctx, AV_LOG_ERROR, "vlc length overflow\n"); //can this happen at all ?
00581         }
00582 
00583         bits_tab[j]= bits;
00584         len_tab[j]= len;
00585     }
00586 
00587     init_vlc(&f->pre_vlc, ACDC_VLC_BITS, 257,
00588              len_tab , 1, 1,
00589              bits_tab, 4, 4, 0);
00590 
00591     return ptr;
00592 }
00593 
00594 static int mix(int c0, int c1){
00595     int blue = 2*(c0&0x001F) + (c1&0x001F);
00596     int green= (2*(c0&0x03E0) + (c1&0x03E0))>>5;
00597     int red  = 2*(c0>>10) + (c1>>10);
00598     return red/3*1024 + green/3*32 + blue/3;
00599 }
00600 
00601 static int decode_i2_frame(FourXContext *f, const uint8_t *buf, int length){
00602     int x, y, x2, y2;
00603     const int width= f->avctx->width;
00604     const int height= f->avctx->height;
00605     uint16_t *dst= (uint16_t*)f->current_picture.data[0];
00606     const int stride= f->current_picture.linesize[0]>>1;
00607 
00608     for(y=0; y<height; y+=16){
00609         for(x=0; x<width; x+=16){
00610             unsigned int color[4], bits;
00611             memset(color, 0, sizeof(color));
00612 //warning following is purely guessed ...
00613             color[0]= bytestream_get_le16(&buf);
00614             color[1]= bytestream_get_le16(&buf);
00615 
00616             if(color[0]&0x8000) av_log(NULL, AV_LOG_ERROR, "unk bit 1\n");
00617             if(color[1]&0x8000) av_log(NULL, AV_LOG_ERROR, "unk bit 2\n");
00618 
00619             color[2]= mix(color[0], color[1]);
00620             color[3]= mix(color[1], color[0]);
00621 
00622             bits= bytestream_get_le32(&buf);
00623             for(y2=0; y2<16; y2++){
00624                 for(x2=0; x2<16; x2++){
00625                     int index= 2*(x2>>2) + 8*(y2>>2);
00626                     dst[y2*stride+x2]= color[(bits>>index)&3];
00627                 }
00628             }
00629             dst+=16;
00630         }
00631         dst += 16*stride - width;
00632     }
00633 
00634     return 0;
00635 }
00636 
00637 static int decode_i_frame(FourXContext *f, const uint8_t *buf, int length){
00638     int x, y;
00639     const int width= f->avctx->width;
00640     const int height= f->avctx->height;
00641     uint16_t *dst= (uint16_t*)f->current_picture.data[0];
00642     const int stride= f->current_picture.linesize[0]>>1;
00643     const unsigned int bitstream_size= AV_RL32(buf);
00644     const int token_count av_unused = AV_RL32(buf + bitstream_size + 8);
00645     unsigned int prestream_size= 4*AV_RL32(buf + bitstream_size + 4);
00646     const uint8_t *prestream= buf + bitstream_size + 12;
00647 
00648     if(prestream_size + bitstream_size + 12 != length
00649        || bitstream_size > (1<<26)
00650        || prestream_size > (1<<26)){
00651         av_log(f->avctx, AV_LOG_ERROR, "size mismatch %d %d %d\n", prestream_size, bitstream_size, length);
00652         return -1;
00653     }
00654 
00655     prestream= read_huffman_tables(f, prestream);
00656 
00657     init_get_bits(&f->gb, buf + 4, 8*bitstream_size);
00658 
00659     prestream_size= length + buf - prestream;
00660 
00661     av_fast_malloc(&f->bitstream_buffer, &f->bitstream_buffer_size, prestream_size + FF_INPUT_BUFFER_PADDING_SIZE);
00662     if (!f->bitstream_buffer)
00663         return AVERROR(ENOMEM);
00664     f->dsp.bswap_buf(f->bitstream_buffer, (const uint32_t*)prestream, prestream_size/4);
00665     init_get_bits(&f->pre_gb, f->bitstream_buffer, 8*prestream_size);
00666 
00667     f->last_dc= 0*128*8*8;
00668 
00669     for(y=0; y<height; y+=16){
00670         for(x=0; x<width; x+=16){
00671             if(decode_i_mb(f) < 0)
00672                 return -1;
00673 
00674             idct_put(f, x, y);
00675         }
00676         dst += 16*stride;
00677     }
00678 
00679     if(get_vlc2(&f->pre_gb, f->pre_vlc.table, ACDC_VLC_BITS, 3) != 256)
00680         av_log(f->avctx, AV_LOG_ERROR, "end mismatch\n");
00681 
00682     return 0;
00683 }
00684 
00685 static int decode_frame(AVCodecContext *avctx,
00686                         void *data, int *data_size,
00687                         AVPacket *avpkt)
00688 {
00689     const uint8_t *buf = avpkt->data;
00690     int buf_size = avpkt->size;
00691     FourXContext * const f = avctx->priv_data;
00692     AVFrame *picture = data;
00693     AVFrame *p, temp;
00694     int i, frame_4cc, frame_size;
00695 
00696     frame_4cc= AV_RL32(buf);
00697     if(buf_size != AV_RL32(buf+4)+8 || buf_size < 20){
00698         av_log(f->avctx, AV_LOG_ERROR, "size mismatch %d %d\n", buf_size, AV_RL32(buf+4));
00699     }
00700 
00701     if(frame_4cc == AV_RL32("cfrm")){
00702         int free_index=-1;
00703         const int data_size= buf_size - 20;
00704         const int id= AV_RL32(buf+12);
00705         const int whole_size= AV_RL32(buf+16);
00706         CFrameBuffer *cfrm;
00707 
00708         for(i=0; i<CFRAME_BUFFER_COUNT; i++){
00709             if(f->cfrm[i].id && f->cfrm[i].id < avctx->frame_number)
00710                 av_log(f->avctx, AV_LOG_ERROR, "lost c frame %d\n", f->cfrm[i].id);
00711         }
00712 
00713         for(i=0; i<CFRAME_BUFFER_COUNT; i++){
00714             if(f->cfrm[i].id   == id) break;
00715             if(f->cfrm[i].size == 0 ) free_index= i;
00716         }
00717 
00718         if(i>=CFRAME_BUFFER_COUNT){
00719             i= free_index;
00720             f->cfrm[i].id= id;
00721         }
00722         cfrm= &f->cfrm[i];
00723 
00724         cfrm->data= av_fast_realloc(cfrm->data, &cfrm->allocated_size, cfrm->size + data_size + FF_INPUT_BUFFER_PADDING_SIZE);
00725         if(!cfrm->data){ //explicit check needed as memcpy below might not catch a NULL
00726             av_log(f->avctx, AV_LOG_ERROR, "realloc falure");
00727             return -1;
00728         }
00729 
00730         memcpy(cfrm->data + cfrm->size, buf+20, data_size);
00731         cfrm->size += data_size;
00732 
00733         if(cfrm->size >= whole_size){
00734             buf= cfrm->data;
00735             frame_size= cfrm->size;
00736 
00737             if(id != avctx->frame_number){
00738                 av_log(f->avctx, AV_LOG_ERROR, "cframe id mismatch %d %d\n", id, avctx->frame_number);
00739             }
00740 
00741             cfrm->size= cfrm->id= 0;
00742             frame_4cc= AV_RL32("pfrm");
00743         }else
00744             return buf_size;
00745     }else{
00746         buf= buf + 12;
00747         frame_size= buf_size - 12;
00748     }
00749 
00750     temp= f->current_picture;
00751     f->current_picture= f->last_picture;
00752     f->last_picture= temp;
00753 
00754     p= &f->current_picture;
00755     avctx->coded_frame= p;
00756 
00757     avctx->flags |= CODEC_FLAG_EMU_EDGE; // alternatively we would have to use our own buffer management
00758 
00759     if(p->data[0])
00760         avctx->release_buffer(avctx, p);
00761 
00762     p->reference= 1;
00763     if(avctx->get_buffer(avctx, p) < 0){
00764         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
00765         return -1;
00766     }
00767 
00768     if(frame_4cc == AV_RL32("ifr2")){
00769         p->pict_type= FF_I_TYPE;
00770         if(decode_i2_frame(f, buf-4, frame_size) < 0)
00771             return -1;
00772     }else if(frame_4cc == AV_RL32("ifrm")){
00773         p->pict_type= FF_I_TYPE;
00774         if(decode_i_frame(f, buf, frame_size) < 0)
00775             return -1;
00776     }else if(frame_4cc == AV_RL32("pfrm") || frame_4cc == AV_RL32("pfr2")){
00777         p->pict_type= FF_P_TYPE;
00778         if(decode_p_frame(f, buf, frame_size) < 0)
00779             return -1;
00780     }else if(frame_4cc == AV_RL32("snd_")){
00781         av_log(avctx, AV_LOG_ERROR, "ignoring snd_ chunk length:%d\n", buf_size);
00782     }else{
00783         av_log(avctx, AV_LOG_ERROR, "ignoring unknown chunk length:%d\n", buf_size);
00784     }
00785 
00786     p->key_frame= p->pict_type == FF_I_TYPE;
00787 
00788     *picture= *p;
00789     *data_size = sizeof(AVPicture);
00790 
00791     emms_c();
00792 
00793     return buf_size;
00794 }
00795 
00796 
00797 static av_cold void common_init(AVCodecContext *avctx){
00798     FourXContext * const f = avctx->priv_data;
00799 
00800     dsputil_init(&f->dsp, avctx);
00801 
00802     f->avctx= avctx;
00803 }
00804 
00805 static av_cold int decode_init(AVCodecContext *avctx){
00806     FourXContext * const f = avctx->priv_data;
00807 
00808     if(avctx->extradata_size != 4 || !avctx->extradata) {
00809         av_log(avctx, AV_LOG_ERROR, "extradata wrong or missing\n");
00810         return 1;
00811     }
00812 
00813     f->version= AV_RL32(avctx->extradata)>>16;
00814     common_init(avctx);
00815     init_vlcs(f);
00816 
00817     if(f->version>2) avctx->pix_fmt= PIX_FMT_RGB565;
00818     else             avctx->pix_fmt= PIX_FMT_BGR555;
00819 
00820     return 0;
00821 }
00822 
00823 
00824 static av_cold int decode_end(AVCodecContext *avctx){
00825     FourXContext * const f = avctx->priv_data;
00826     int i;
00827 
00828     av_freep(&f->bitstream_buffer);
00829     f->bitstream_buffer_size=0;
00830     for(i=0; i<CFRAME_BUFFER_COUNT; i++){
00831         av_freep(&f->cfrm[i].data);
00832         f->cfrm[i].allocated_size= 0;
00833     }
00834     free_vlc(&f->pre_vlc);
00835     if(f->current_picture.data[0])
00836         avctx->release_buffer(avctx, &f->current_picture);
00837     if(f->last_picture.data[0])
00838         avctx->release_buffer(avctx, &f->last_picture);
00839 
00840     return 0;
00841 }
00842 
00843 AVCodec fourxm_decoder = {
00844     "4xm",
00845     AVMEDIA_TYPE_VIDEO,
00846     CODEC_ID_4XM,
00847     sizeof(FourXContext),
00848     decode_init,
00849     NULL,
00850     decode_end,
00851     decode_frame,
00852     CODEC_CAP_DR1,
00853     .long_name = NULL_IF_CONFIG_SMALL("4X Movie"),
00854 };
00855 

Generated on Fri Sep 16 2011 17:17:32 for FFmpeg by  doxygen 1.7.1