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

libavcodec/bink.c

Go to the documentation of this file.
00001 /*
00002  * Bink video decoder
00003  * Copyright (c) 2009 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 
00022 #include "avcodec.h"
00023 #include "dsputil.h"
00024 #include "binkdata.h"
00025 #include "mathops.h"
00026 
00027 #define ALT_BITSTREAM_READER_LE
00028 #include "get_bits.h"
00029 
00030 #define BINK_FLAG_ALPHA 0x00100000
00031 #define BINK_FLAG_GRAY  0x00020000
00032 
00033 static VLC bink_trees[16];
00034 
00038 enum Sources {
00039     BINK_SRC_BLOCK_TYPES = 0, 
00040     BINK_SRC_SUB_BLOCK_TYPES, 
00041     BINK_SRC_COLORS,          
00042     BINK_SRC_PATTERN,         
00043     BINK_SRC_X_OFF,           
00044     BINK_SRC_Y_OFF,           
00045     BINK_SRC_INTRA_DC,        
00046     BINK_SRC_INTER_DC,        
00047     BINK_SRC_RUN,             
00048 
00049     BINK_NB_SRC
00050 };
00051 
00055 typedef struct Tree {
00056     int     vlc_num;  
00057     uint8_t syms[16]; 
00058 } Tree;
00059 
00060 #define GET_HUFF(gb, tree)  (tree).syms[get_vlc2(gb, bink_trees[(tree).vlc_num].table,\
00061                                                  bink_trees[(tree).vlc_num].bits, 1)]
00062 
00066 typedef struct Bundle {
00067     int     len;       
00068     Tree    tree;      
00069     uint8_t *data;     
00070     uint8_t *data_end; 
00071     uint8_t *cur_dec;  
00072     uint8_t *cur_ptr;  
00073 } Bundle;
00074 
00075 /*
00076  * Decoder context
00077  */
00078 typedef struct BinkContext {
00079     AVCodecContext *avctx;
00080     DSPContext     dsp;
00081     AVFrame        pic, last;
00082     int            version;              
00083     int            has_alpha;
00084     int            swap_planes;
00085     ScanTable      scantable;            
00086 
00087     Bundle         bundle[BINK_NB_SRC];  
00088     Tree           col_high[16];         
00089     int            col_lastval;          
00090 } BinkContext;
00091 
00095 enum BlockTypes {
00096     SKIP_BLOCK = 0, 
00097     SCALED_BLOCK,   
00098     MOTION_BLOCK,   
00099     RUN_BLOCK,      
00100     RESIDUE_BLOCK,  
00101     INTRA_BLOCK,    
00102     FILL_BLOCK,     
00103     INTER_BLOCK,    
00104     PATTERN_BLOCK,  
00105     RAW_BLOCK,      
00106 };
00107 
00115 static void init_lengths(BinkContext *c, int width, int bw)
00116 {
00117     c->bundle[BINK_SRC_BLOCK_TYPES].len = av_log2((width >> 3) + 511) + 1;
00118 
00119     c->bundle[BINK_SRC_SUB_BLOCK_TYPES].len = av_log2((width >> 4) + 511) + 1;
00120 
00121     c->bundle[BINK_SRC_COLORS].len = av_log2((width >> 3)*64 + 511) + 1;
00122 
00123     c->bundle[BINK_SRC_INTRA_DC].len =
00124     c->bundle[BINK_SRC_INTER_DC].len =
00125     c->bundle[BINK_SRC_X_OFF].len =
00126     c->bundle[BINK_SRC_Y_OFF].len = av_log2((width >> 3) + 511) + 1;
00127 
00128     c->bundle[BINK_SRC_PATTERN].len = av_log2((bw << 3) + 511) + 1;
00129 
00130     c->bundle[BINK_SRC_RUN].len = av_log2((width >> 3)*48 + 511) + 1;
00131 }
00132 
00138 static av_cold void init_bundles(BinkContext *c)
00139 {
00140     int bw, bh, blocks;
00141     int i;
00142 
00143     bw = (c->avctx->width  + 7) >> 3;
00144     bh = (c->avctx->height + 7) >> 3;
00145     blocks = bw * bh;
00146 
00147     for (i = 0; i < BINK_NB_SRC; i++) {
00148         c->bundle[i].data = av_malloc(blocks * 64);
00149         c->bundle[i].data_end = c->bundle[i].data + blocks * 64;
00150     }
00151 }
00152 
00158 static av_cold void free_bundles(BinkContext *c)
00159 {
00160     int i;
00161     for (i = 0; i < BINK_NB_SRC; i++)
00162         av_freep(&c->bundle[i].data);
00163 }
00164 
00173 static void merge(GetBitContext *gb, uint8_t *dst, uint8_t *src, int size)
00174 {
00175     uint8_t *src2 = src + size;
00176     int size2 = size;
00177 
00178     do {
00179         if (!get_bits1(gb)) {
00180             *dst++ = *src++;
00181             size--;
00182         } else {
00183             *dst++ = *src2++;
00184             size2--;
00185         }
00186     } while (size && size2);
00187 
00188     while (size--)
00189         *dst++ = *src++;
00190     while (size2--)
00191         *dst++ = *src2++;
00192 }
00193 
00200 static void read_tree(GetBitContext *gb, Tree *tree)
00201 {
00202     uint8_t tmp1[16], tmp2[16], *in = tmp1, *out = tmp2;
00203     int i, t, len;
00204 
00205     tree->vlc_num = get_bits(gb, 4);
00206     if (!tree->vlc_num) {
00207         for (i = 0; i < 16; i++)
00208             tree->syms[i] = i;
00209         return;
00210     }
00211     if (get_bits1(gb)) {
00212         len = get_bits(gb, 3);
00213         memset(tmp1, 0, sizeof(tmp1));
00214         for (i = 0; i <= len; i++) {
00215             tree->syms[i] = get_bits(gb, 4);
00216             tmp1[tree->syms[i]] = 1;
00217         }
00218         for (i = 0; i < 16; i++)
00219             if (!tmp1[i])
00220                 tree->syms[++len] = i;
00221     } else {
00222         len = get_bits(gb, 2);
00223         for (i = 0; i < 16; i++)
00224             in[i] = i;
00225         for (i = 0; i <= len; i++) {
00226             int size = 1 << i;
00227             for (t = 0; t < 16; t += size << 1)
00228                 merge(gb, out + t, in + t, size);
00229             FFSWAP(uint8_t*, in, out);
00230         }
00231         memcpy(tree->syms, in, 16);
00232     }
00233 }
00234 
00242 static void read_bundle(GetBitContext *gb, BinkContext *c, int bundle_num)
00243 {
00244     int i;
00245 
00246     if (bundle_num == BINK_SRC_COLORS) {
00247         for (i = 0; i < 16; i++)
00248             read_tree(gb, &c->col_high[i]);
00249         c->col_lastval = 0;
00250     }
00251     if (bundle_num != BINK_SRC_INTRA_DC && bundle_num != BINK_SRC_INTER_DC)
00252         read_tree(gb, &c->bundle[bundle_num].tree);
00253     c->bundle[bundle_num].cur_dec =
00254     c->bundle[bundle_num].cur_ptr = c->bundle[bundle_num].data;
00255 }
00256 
00264 #define CHECK_READ_VAL(gb, b, t) \
00265     if (!b->cur_dec || (b->cur_dec > b->cur_ptr)) \
00266         return 0; \
00267     t = get_bits(gb, b->len); \
00268     if (!t) { \
00269         b->cur_dec = NULL; \
00270         return 0; \
00271     } \
00272 
00273 static int read_runs(AVCodecContext *avctx, GetBitContext *gb, Bundle *b)
00274 {
00275     int t, v;
00276     const uint8_t *dec_end;
00277 
00278     CHECK_READ_VAL(gb, b, t);
00279     dec_end = b->cur_dec + t;
00280     if (dec_end > b->data_end) {
00281         av_log(avctx, AV_LOG_ERROR, "Run value went out of bounds\n");
00282         return -1;
00283     }
00284     if (get_bits1(gb)) {
00285         v = get_bits(gb, 4);
00286         memset(b->cur_dec, v, t);
00287         b->cur_dec += t;
00288     } else {
00289         while (b->cur_dec < dec_end)
00290             *b->cur_dec++ = GET_HUFF(gb, b->tree);
00291     }
00292     return 0;
00293 }
00294 
00295 static int read_motion_values(AVCodecContext *avctx, GetBitContext *gb, Bundle *b)
00296 {
00297     int t, sign, v;
00298     const uint8_t *dec_end;
00299 
00300     CHECK_READ_VAL(gb, b, t);
00301     dec_end = b->cur_dec + t;
00302     if (dec_end > b->data_end) {
00303         av_log(avctx, AV_LOG_ERROR, "Too many motion values\n");
00304         return -1;
00305     }
00306     if (get_bits1(gb)) {
00307         v = get_bits(gb, 4);
00308         if (v) {
00309             sign = -get_bits1(gb);
00310             v = (v ^ sign) - sign;
00311         }
00312         memset(b->cur_dec, v, t);
00313         b->cur_dec += t;
00314     } else {
00315         do {
00316             v = GET_HUFF(gb, b->tree);
00317             if (v) {
00318                 sign = -get_bits1(gb);
00319                 v = (v ^ sign) - sign;
00320             }
00321             *b->cur_dec++ = v;
00322         } while (b->cur_dec < dec_end);
00323     }
00324     return 0;
00325 }
00326 
00327 const uint8_t bink_rlelens[4] = { 4, 8, 12, 32 };
00328 
00329 static int read_block_types(AVCodecContext *avctx, GetBitContext *gb, Bundle *b)
00330 {
00331     int t, v;
00332     int last = 0;
00333     const uint8_t *dec_end;
00334 
00335     CHECK_READ_VAL(gb, b, t);
00336     dec_end = b->cur_dec + t;
00337     if (dec_end > b->data_end) {
00338         av_log(avctx, AV_LOG_ERROR, "Too many block type values\n");
00339         return -1;
00340     }
00341     if (get_bits1(gb)) {
00342         v = get_bits(gb, 4);
00343         memset(b->cur_dec, v, t);
00344         b->cur_dec += t;
00345     } else {
00346         do {
00347             v = GET_HUFF(gb, b->tree);
00348             if (v < 12) {
00349                 last = v;
00350                 *b->cur_dec++ = v;
00351             } else {
00352                 int run = bink_rlelens[v - 12];
00353 
00354                 memset(b->cur_dec, last, run);
00355                 b->cur_dec += run;
00356             }
00357         } while (b->cur_dec < dec_end);
00358     }
00359     return 0;
00360 }
00361 
00362 static int read_patterns(AVCodecContext *avctx, GetBitContext *gb, Bundle *b)
00363 {
00364     int t, v;
00365     const uint8_t *dec_end;
00366 
00367     CHECK_READ_VAL(gb, b, t);
00368     dec_end = b->cur_dec + t;
00369     if (dec_end > b->data_end) {
00370         av_log(avctx, AV_LOG_ERROR, "Too many pattern values\n");
00371         return -1;
00372     }
00373     while (b->cur_dec < dec_end) {
00374         v  = GET_HUFF(gb, b->tree);
00375         v |= GET_HUFF(gb, b->tree) << 4;
00376         *b->cur_dec++ = v;
00377     }
00378 
00379     return 0;
00380 }
00381 
00382 static int read_colors(GetBitContext *gb, Bundle *b, BinkContext *c)
00383 {
00384     int t, sign, v;
00385     const uint8_t *dec_end;
00386 
00387     CHECK_READ_VAL(gb, b, t);
00388     dec_end = b->cur_dec + t;
00389     if (dec_end > b->data_end) {
00390         av_log(c->avctx, AV_LOG_ERROR, "Too many color values\n");
00391         return -1;
00392     }
00393     if (get_bits1(gb)) {
00394         c->col_lastval = GET_HUFF(gb, c->col_high[c->col_lastval]);
00395         v = GET_HUFF(gb, b->tree);
00396         v = (c->col_lastval << 4) | v;
00397         if (c->version < 'i') {
00398             sign = ((int8_t) v) >> 7;
00399             v = ((v & 0x7F) ^ sign) - sign;
00400             v += 0x80;
00401         }
00402         memset(b->cur_dec, v, t);
00403         b->cur_dec += t;
00404     } else {
00405         while (b->cur_dec < dec_end) {
00406             c->col_lastval = GET_HUFF(gb, c->col_high[c->col_lastval]);
00407             v = GET_HUFF(gb, b->tree);
00408             v = (c->col_lastval << 4) | v;
00409             if (c->version < 'i') {
00410                 sign = ((int8_t) v) >> 7;
00411                 v = ((v & 0x7F) ^ sign) - sign;
00412                 v += 0x80;
00413             }
00414             *b->cur_dec++ = v;
00415         }
00416     }
00417     return 0;
00418 }
00419 
00421 #define DC_START_BITS 11
00422 
00423 static int read_dcs(AVCodecContext *avctx, GetBitContext *gb, Bundle *b,
00424                     int start_bits, int has_sign)
00425 {
00426     int i, j, len, len2, bsize, sign, v, v2;
00427     int16_t *dst = (int16_t*)b->cur_dec;
00428 
00429     CHECK_READ_VAL(gb, b, len);
00430     v = get_bits(gb, start_bits - has_sign);
00431     if (v && has_sign) {
00432         sign = -get_bits1(gb);
00433         v = (v ^ sign) - sign;
00434     }
00435     *dst++ = v;
00436     len--;
00437     for (i = 0; i < len; i += 8) {
00438         len2 = FFMIN(len - i, 8);
00439         bsize = get_bits(gb, 4);
00440         if (bsize) {
00441             for (j = 0; j < len2; j++) {
00442                 v2 = get_bits(gb, bsize);
00443                 if (v2) {
00444                     sign = -get_bits1(gb);
00445                     v2 = (v2 ^ sign) - sign;
00446                 }
00447                 v += v2;
00448                 *dst++ = v;
00449                 if (v < -32768 || v > 32767) {
00450                     av_log(avctx, AV_LOG_ERROR, "DC value went out of bounds: %d\n", v);
00451                     return -1;
00452                 }
00453             }
00454         } else {
00455             for (j = 0; j < len2; j++)
00456                 *dst++ = v;
00457         }
00458     }
00459 
00460     b->cur_dec = (uint8_t*)dst;
00461     return 0;
00462 }
00463 
00470 static inline int get_value(BinkContext *c, int bundle)
00471 {
00472     int16_t ret;
00473 
00474     if (bundle < BINK_SRC_X_OFF || bundle == BINK_SRC_RUN)
00475         return *c->bundle[bundle].cur_ptr++;
00476     if (bundle == BINK_SRC_X_OFF || bundle == BINK_SRC_Y_OFF)
00477         return (int8_t)*c->bundle[bundle].cur_ptr++;
00478     ret = *(int16_t*)c->bundle[bundle].cur_ptr;
00479     c->bundle[bundle].cur_ptr += 2;
00480     return ret;
00481 }
00482 
00492 static int read_dct_coeffs(GetBitContext *gb, DCTELEM block[64], const uint8_t *scan,
00493                            int is_intra)
00494 {
00495     int coef_list[128];
00496     int mode_list[128];
00497     int i, t, mask, bits, ccoef, mode, sign;
00498     int list_start = 64, list_end = 64, list_pos;
00499     int coef_count = 0;
00500     int coef_idx[64];
00501     int quant_idx;
00502     const uint32_t *quant;
00503 
00504     coef_list[list_end] = 4;  mode_list[list_end++] = 0;
00505     coef_list[list_end] = 24; mode_list[list_end++] = 0;
00506     coef_list[list_end] = 44; mode_list[list_end++] = 0;
00507     coef_list[list_end] = 1;  mode_list[list_end++] = 3;
00508     coef_list[list_end] = 2;  mode_list[list_end++] = 3;
00509     coef_list[list_end] = 3;  mode_list[list_end++] = 3;
00510 
00511     bits = get_bits(gb, 4) - 1;
00512     for (mask = 1 << bits; bits >= 0; mask >>= 1, bits--) {
00513         list_pos = list_start;
00514         while (list_pos < list_end) {
00515             if (!(mode_list[list_pos] | coef_list[list_pos]) || !get_bits1(gb)) {
00516                 list_pos++;
00517                 continue;
00518             }
00519             ccoef = coef_list[list_pos];
00520             mode  = mode_list[list_pos];
00521             switch (mode) {
00522             case 0:
00523                 coef_list[list_pos] = ccoef + 4;
00524                 mode_list[list_pos] = 1;
00525             case 2:
00526                 if (mode == 2) {
00527                     coef_list[list_pos]   = 0;
00528                     mode_list[list_pos++] = 0;
00529                 }
00530                 for (i = 0; i < 4; i++, ccoef++) {
00531                     if (get_bits1(gb)) {
00532                         coef_list[--list_start] = ccoef;
00533                         mode_list[  list_start] = 3;
00534                     } else {
00535                         int t;
00536                         if (!bits) {
00537                             t = 1 - (get_bits1(gb) << 1);
00538                         } else {
00539                             t = get_bits(gb, bits) | mask;
00540                             sign = -get_bits1(gb);
00541                             t = (t ^ sign) - sign;
00542                         }
00543                         block[scan[ccoef]] = t;
00544                         coef_idx[coef_count++] = ccoef;
00545                     }
00546                 }
00547                 break;
00548             case 1:
00549                 mode_list[list_pos] = 2;
00550                 for (i = 0; i < 3; i++) {
00551                     ccoef += 4;
00552                     coef_list[list_end]   = ccoef;
00553                     mode_list[list_end++] = 2;
00554                 }
00555                 break;
00556             case 3:
00557                 if (!bits) {
00558                     t = 1 - (get_bits1(gb) << 1);
00559                 } else {
00560                     t = get_bits(gb, bits) | mask;
00561                     sign = -get_bits1(gb);
00562                     t = (t ^ sign) - sign;
00563                 }
00564                 block[scan[ccoef]] = t;
00565                 coef_idx[coef_count++] = ccoef;
00566                 coef_list[list_pos]   = 0;
00567                 mode_list[list_pos++] = 0;
00568                 break;
00569             }
00570         }
00571     }
00572 
00573     quant_idx = get_bits(gb, 4);
00574     quant = is_intra ? bink_intra_quant[quant_idx]
00575                      : bink_inter_quant[quant_idx];
00576     block[0] = (block[0] * quant[0]) >> 11;
00577     for (i = 0; i < coef_count; i++) {
00578         int idx = coef_idx[i];
00579         block[scan[idx]] = (block[scan[idx]] * quant[idx]) >> 11;
00580     }
00581 
00582     return 0;
00583 }
00584 
00593 static int read_residue(GetBitContext *gb, DCTELEM block[64], int masks_count)
00594 {
00595     int coef_list[128];
00596     int mode_list[128];
00597     int i, sign, mask, ccoef, mode;
00598     int list_start = 64, list_end = 64, list_pos;
00599     int nz_coeff[64];
00600     int nz_coeff_count = 0;
00601 
00602     coef_list[list_end] =  4; mode_list[list_end++] = 0;
00603     coef_list[list_end] = 24; mode_list[list_end++] = 0;
00604     coef_list[list_end] = 44; mode_list[list_end++] = 0;
00605     coef_list[list_end] =  0; mode_list[list_end++] = 2;
00606 
00607     for (mask = 1 << get_bits(gb, 3); mask; mask >>= 1) {
00608         for (i = 0; i < nz_coeff_count; i++) {
00609             if (!get_bits1(gb))
00610                 continue;
00611             if (block[nz_coeff[i]] < 0)
00612                 block[nz_coeff[i]] -= mask;
00613             else
00614                 block[nz_coeff[i]] += mask;
00615             masks_count--;
00616             if (masks_count < 0)
00617                 return 0;
00618         }
00619         list_pos = list_start;
00620         while (list_pos < list_end) {
00621             if (!(coef_list[list_pos] | mode_list[list_pos]) || !get_bits1(gb)) {
00622                 list_pos++;
00623                 continue;
00624             }
00625             ccoef = coef_list[list_pos];
00626             mode  = mode_list[list_pos];
00627             switch (mode) {
00628             case 0:
00629                 coef_list[list_pos] = ccoef + 4;
00630                 mode_list[list_pos] = 1;
00631             case 2:
00632                 if (mode == 2) {
00633                     coef_list[list_pos]   = 0;
00634                     mode_list[list_pos++] = 0;
00635                 }
00636                 for (i = 0; i < 4; i++, ccoef++) {
00637                     if (get_bits1(gb)) {
00638                         coef_list[--list_start] = ccoef;
00639                         mode_list[  list_start] = 3;
00640                     } else {
00641                         nz_coeff[nz_coeff_count++] = bink_scan[ccoef];
00642                         sign = -get_bits1(gb);
00643                         block[bink_scan[ccoef]] = (mask ^ sign) - sign;
00644                         masks_count--;
00645                         if (masks_count < 0)
00646                             return 0;
00647                     }
00648                 }
00649                 break;
00650             case 1:
00651                 mode_list[list_pos] = 2;
00652                 for (i = 0; i < 3; i++) {
00653                     ccoef += 4;
00654                     coef_list[list_end]   = ccoef;
00655                     mode_list[list_end++] = 2;
00656                 }
00657                 break;
00658             case 3:
00659                 nz_coeff[nz_coeff_count++] = bink_scan[ccoef];
00660                 sign = -get_bits1(gb);
00661                 block[bink_scan[ccoef]] = (mask ^ sign) - sign;
00662                 coef_list[list_pos]   = 0;
00663                 mode_list[list_pos++] = 0;
00664                 masks_count--;
00665                 if (masks_count < 0)
00666                     return 0;
00667                 break;
00668             }
00669         }
00670     }
00671 
00672     return 0;
00673 }
00674 
00675 static int bink_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx,
00676                              int is_chroma)
00677 {
00678     int blk;
00679     int i, j, bx, by;
00680     uint8_t *dst, *prev, *ref, *ref_start, *ref_end;
00681     int v, col[2];
00682     const uint8_t *scan;
00683     int xoff, yoff;
00684     DECLARE_ALIGNED(16, DCTELEM, block[64]);
00685     DECLARE_ALIGNED(16, uint8_t, ublock[64]);
00686     int coordmap[64];
00687 
00688     const int stride = c->pic.linesize[plane_idx];
00689     int bw = is_chroma ? (c->avctx->width  + 15) >> 4 : (c->avctx->width  + 7) >> 3;
00690     int bh = is_chroma ? (c->avctx->height + 15) >> 4 : (c->avctx->height + 7) >> 3;
00691     int width = c->avctx->width >> is_chroma;
00692 
00693     init_lengths(c, FFMAX(width, 8), bw);
00694     for (i = 0; i < BINK_NB_SRC; i++)
00695         read_bundle(gb, c, i);
00696 
00697     ref_start = c->last.data[plane_idx];
00698     ref_end   = c->last.data[plane_idx]
00699                 + (bw - 1 + c->last.linesize[plane_idx] * (bh - 1)) * 8;
00700 
00701     for (i = 0; i < 64; i++)
00702         coordmap[i] = (i & 7) + (i >> 3) * stride;
00703 
00704     for (by = 0; by < bh; by++) {
00705         if (read_block_types(c->avctx, gb, &c->bundle[BINK_SRC_BLOCK_TYPES]) < 0)
00706             return -1;
00707         if (read_block_types(c->avctx, gb, &c->bundle[BINK_SRC_SUB_BLOCK_TYPES]) < 0)
00708             return -1;
00709         if (read_colors(gb, &c->bundle[BINK_SRC_COLORS], c) < 0)
00710             return -1;
00711         if (read_patterns(c->avctx, gb, &c->bundle[BINK_SRC_PATTERN]) < 0)
00712             return -1;
00713         if (read_motion_values(c->avctx, gb, &c->bundle[BINK_SRC_X_OFF]) < 0)
00714             return -1;
00715         if (read_motion_values(c->avctx, gb, &c->bundle[BINK_SRC_Y_OFF]) < 0)
00716             return -1;
00717         if (read_dcs(c->avctx, gb, &c->bundle[BINK_SRC_INTRA_DC], DC_START_BITS, 0) < 0)
00718             return -1;
00719         if (read_dcs(c->avctx, gb, &c->bundle[BINK_SRC_INTER_DC], DC_START_BITS, 1) < 0)
00720             return -1;
00721         if (read_runs(c->avctx, gb, &c->bundle[BINK_SRC_RUN]) < 0)
00722             return -1;
00723 
00724         if (by == bh)
00725             break;
00726         dst  = c->pic.data[plane_idx]  + 8*by*stride;
00727         prev = c->last.data[plane_idx] + 8*by*stride;
00728         for (bx = 0; bx < bw; bx++, dst += 8, prev += 8) {
00729             blk = get_value(c, BINK_SRC_BLOCK_TYPES);
00730             // 16x16 block type on odd line means part of the already decoded block, so skip it
00731             if ((by & 1) && blk == SCALED_BLOCK) {
00732                 bx++;
00733                 dst  += 8;
00734                 prev += 8;
00735                 continue;
00736             }
00737             switch (blk) {
00738             case SKIP_BLOCK:
00739                 c->dsp.put_pixels_tab[1][0](dst, prev, stride, 8);
00740                 break;
00741             case SCALED_BLOCK:
00742                 blk = get_value(c, BINK_SRC_SUB_BLOCK_TYPES);
00743                 switch (blk) {
00744                 case RUN_BLOCK:
00745                     scan = bink_patterns[get_bits(gb, 4)];
00746                     i = 0;
00747                     do {
00748                         int run = get_value(c, BINK_SRC_RUN) + 1;
00749 
00750                         i += run;
00751                         if (i > 64) {
00752                             av_log(c->avctx, AV_LOG_ERROR, "Run went out of bounds\n");
00753                             return -1;
00754                         }
00755                         if (get_bits1(gb)) {
00756                             v = get_value(c, BINK_SRC_COLORS);
00757                             for (j = 0; j < run; j++)
00758                                 ublock[*scan++] = v;
00759                         } else {
00760                             for (j = 0; j < run; j++)
00761                                 ublock[*scan++] = get_value(c, BINK_SRC_COLORS);
00762                         }
00763                     } while (i < 63);
00764                     if (i == 63)
00765                         ublock[*scan++] = get_value(c, BINK_SRC_COLORS);
00766                     break;
00767                 case INTRA_BLOCK:
00768                     c->dsp.clear_block(block);
00769                     block[0] = get_value(c, BINK_SRC_INTRA_DC);
00770                     read_dct_coeffs(gb, block, c->scantable.permutated, 1);
00771                     c->dsp.idct(block);
00772                     c->dsp.put_pixels_nonclamped(block, ublock, 8);
00773                     break;
00774                 case FILL_BLOCK:
00775                     v = get_value(c, BINK_SRC_COLORS);
00776                     c->dsp.fill_block_tab[0](dst, v, stride, 16);
00777                     break;
00778                 case PATTERN_BLOCK:
00779                     for (i = 0; i < 2; i++)
00780                         col[i] = get_value(c, BINK_SRC_COLORS);
00781                     for (j = 0; j < 8; j++) {
00782                         v = get_value(c, BINK_SRC_PATTERN);
00783                         for (i = 0; i < 8; i++, v >>= 1)
00784                             ublock[i + j*8] = col[v & 1];
00785                     }
00786                     break;
00787                 case RAW_BLOCK:
00788                     for (j = 0; j < 8; j++)
00789                         for (i = 0; i < 8; i++)
00790                             ublock[i + j*8] = get_value(c, BINK_SRC_COLORS);
00791                     break;
00792                 default:
00793                     av_log(c->avctx, AV_LOG_ERROR, "Incorrect 16x16 block type %d\n", blk);
00794                     return -1;
00795                 }
00796                 if (blk != FILL_BLOCK)
00797                 c->dsp.scale_block(ublock, dst, stride);
00798                 bx++;
00799                 dst  += 8;
00800                 prev += 8;
00801                 break;
00802             case MOTION_BLOCK:
00803                 xoff = get_value(c, BINK_SRC_X_OFF);
00804                 yoff = get_value(c, BINK_SRC_Y_OFF);
00805                 ref = prev + xoff + yoff * stride;
00806                 if (ref < ref_start || ref > ref_end) {
00807                     av_log(c->avctx, AV_LOG_ERROR, "Copy out of bounds @%d, %d\n",
00808                            bx*8 + xoff, by*8 + yoff);
00809                     return -1;
00810                 }
00811                 c->dsp.put_pixels_tab[1][0](dst, ref, stride, 8);
00812                 break;
00813             case RUN_BLOCK:
00814                 scan = bink_patterns[get_bits(gb, 4)];
00815                 i = 0;
00816                 do {
00817                     int run = get_value(c, BINK_SRC_RUN) + 1;
00818 
00819                     i += run;
00820                     if (i > 64) {
00821                         av_log(c->avctx, AV_LOG_ERROR, "Run went out of bounds\n");
00822                         return -1;
00823                     }
00824                     if (get_bits1(gb)) {
00825                         v = get_value(c, BINK_SRC_COLORS);
00826                         for (j = 0; j < run; j++)
00827                             dst[coordmap[*scan++]] = v;
00828                     } else {
00829                         for (j = 0; j < run; j++)
00830                             dst[coordmap[*scan++]] = get_value(c, BINK_SRC_COLORS);
00831                     }
00832                 } while (i < 63);
00833                 if (i == 63)
00834                     dst[coordmap[*scan++]] = get_value(c, BINK_SRC_COLORS);
00835                 break;
00836             case RESIDUE_BLOCK:
00837                 xoff = get_value(c, BINK_SRC_X_OFF);
00838                 yoff = get_value(c, BINK_SRC_Y_OFF);
00839                 ref = prev + xoff + yoff * stride;
00840                 if (ref < ref_start || ref > ref_end) {
00841                     av_log(c->avctx, AV_LOG_ERROR, "Copy out of bounds @%d, %d\n",
00842                            bx*8 + xoff, by*8 + yoff);
00843                     return -1;
00844                 }
00845                 c->dsp.put_pixels_tab[1][0](dst, ref, stride, 8);
00846                 c->dsp.clear_block(block);
00847                 v = get_bits(gb, 7);
00848                 read_residue(gb, block, v);
00849                 c->dsp.add_pixels8(dst, block, stride);
00850                 break;
00851             case INTRA_BLOCK:
00852                 c->dsp.clear_block(block);
00853                 block[0] = get_value(c, BINK_SRC_INTRA_DC);
00854                 read_dct_coeffs(gb, block, c->scantable.permutated, 1);
00855                 c->dsp.idct_put(dst, stride, block);
00856                 break;
00857             case FILL_BLOCK:
00858                 v = get_value(c, BINK_SRC_COLORS);
00859                 c->dsp.fill_block_tab[1](dst, v, stride, 8);
00860                 break;
00861             case INTER_BLOCK:
00862                 xoff = get_value(c, BINK_SRC_X_OFF);
00863                 yoff = get_value(c, BINK_SRC_Y_OFF);
00864                 ref = prev + xoff + yoff * stride;
00865                 c->dsp.put_pixels_tab[1][0](dst, ref, stride, 8);
00866                 c->dsp.clear_block(block);
00867                 block[0] = get_value(c, BINK_SRC_INTER_DC);
00868                 read_dct_coeffs(gb, block, c->scantable.permutated, 0);
00869                 c->dsp.idct_add(dst, stride, block);
00870                 break;
00871             case PATTERN_BLOCK:
00872                 for (i = 0; i < 2; i++)
00873                     col[i] = get_value(c, BINK_SRC_COLORS);
00874                 for (i = 0; i < 8; i++) {
00875                     v = get_value(c, BINK_SRC_PATTERN);
00876                     for (j = 0; j < 8; j++, v >>= 1)
00877                         dst[i*stride + j] = col[v & 1];
00878                 }
00879                 break;
00880             case RAW_BLOCK:
00881                 for (i = 0; i < 8; i++)
00882                     memcpy(dst + i*stride, c->bundle[BINK_SRC_COLORS].cur_ptr + i*8, 8);
00883                 c->bundle[BINK_SRC_COLORS].cur_ptr += 64;
00884                 break;
00885             default:
00886                 av_log(c->avctx, AV_LOG_ERROR, "Unknown block type %d\n", blk);
00887                 return -1;
00888             }
00889         }
00890     }
00891     if (get_bits_count(gb) & 0x1F) //next plane data starts at 32-bit boundary
00892         skip_bits_long(gb, 32 - (get_bits_count(gb) & 0x1F));
00893 
00894     return 0;
00895 }
00896 
00897 static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *pkt)
00898 {
00899     BinkContext * const c = avctx->priv_data;
00900     GetBitContext gb;
00901     int plane, plane_idx;
00902     int bits_count = pkt->size << 3;
00903 
00904     if(c->pic.data[0])
00905         avctx->release_buffer(avctx, &c->pic);
00906 
00907     if(avctx->get_buffer(avctx, &c->pic) < 0){
00908         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
00909         return -1;
00910     }
00911 
00912     init_get_bits(&gb, pkt->data, bits_count);
00913     if (c->has_alpha) {
00914         if (c->version >= 'i')
00915             skip_bits_long(&gb, 32);
00916         if (bink_decode_plane(c, &gb, 3, 0) < 0)
00917             return -1;
00918     }
00919     if (c->version >= 'i')
00920         skip_bits_long(&gb, 32);
00921 
00922     for (plane = 0; plane < 3; plane++) {
00923         plane_idx = (!plane || !c->swap_planes) ? plane : (plane ^ 3);
00924 
00925         if (bink_decode_plane(c, &gb, plane_idx, !!plane) < 0)
00926             return -1;
00927         if (get_bits_count(&gb) >= bits_count)
00928             break;
00929     }
00930     emms_c();
00931 
00932     *data_size = sizeof(AVFrame);
00933     *(AVFrame*)data = c->pic;
00934 
00935     FFSWAP(AVFrame, c->pic, c->last);
00936 
00937     /* always report that the buffer was completely consumed */
00938     return pkt->size;
00939 }
00940 
00941 static av_cold int decode_init(AVCodecContext *avctx)
00942 {
00943     BinkContext * const c = avctx->priv_data;
00944     static VLC_TYPE table[16 * 128][2];
00945     int i;
00946     int flags;
00947 
00948     c->version = avctx->codec_tag >> 24;
00949     if (c->version < 'c') {
00950         av_log(avctx, AV_LOG_ERROR, "Too old version '%c'\n", c->version);
00951         return -1;
00952     }
00953     if (avctx->extradata_size < 4) {
00954         av_log(avctx, AV_LOG_ERROR, "Extradata missing or too short\n");
00955         return -1;
00956     }
00957     flags = AV_RL32(avctx->extradata);
00958     c->has_alpha = flags & BINK_FLAG_ALPHA;
00959     c->swap_planes = c->version >= 'h';
00960     if (!bink_trees[15].table) {
00961         for (i = 0; i < 16; i++) {
00962             const int maxbits = bink_tree_lens[i][15];
00963             bink_trees[i].table = table + i*128;
00964             bink_trees[i].table_allocated = 1 << maxbits;
00965             init_vlc(&bink_trees[i], maxbits, 16,
00966                      bink_tree_lens[i], 1, 1,
00967                      bink_tree_bits[i], 1, 1, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE);
00968         }
00969     }
00970     c->avctx = avctx;
00971 
00972     c->pic.data[0] = NULL;
00973 
00974     if (avcodec_check_dimensions(avctx, avctx->width, avctx->height) < 0) {
00975         return 1;
00976     }
00977 
00978     avctx->pix_fmt = c->has_alpha ? PIX_FMT_YUVA420P : PIX_FMT_YUV420P;
00979 
00980     avctx->idct_algo = FF_IDCT_BINK;
00981     dsputil_init(&c->dsp, avctx);
00982     ff_init_scantable(c->dsp.idct_permutation, &c->scantable, bink_scan);
00983 
00984     init_bundles(c);
00985 
00986     return 0;
00987 }
00988 
00989 static av_cold int decode_end(AVCodecContext *avctx)
00990 {
00991     BinkContext * const c = avctx->priv_data;
00992 
00993     if (c->pic.data[0])
00994         avctx->release_buffer(avctx, &c->pic);
00995     if (c->last.data[0])
00996         avctx->release_buffer(avctx, &c->last);
00997 
00998     free_bundles(c);
00999     return 0;
01000 }
01001 
01002 AVCodec bink_decoder = {
01003     "binkvideo",
01004     AVMEDIA_TYPE_VIDEO,
01005     CODEC_ID_BINKVIDEO,
01006     sizeof(BinkContext),
01007     decode_init,
01008     NULL,
01009     decode_end,
01010     decode_frame,
01011     .long_name = NULL_IF_CONFIG_SMALL("Bink video"),
01012 };

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