diff options
author | Kostya Shishkov <kostya.shishkov@gmail.com> | 2010-02-27 15:32:31 +0300 |
---|---|---|
committer | Kostya Shishkov <kostya.shishkov@gmail.com> | 2010-02-27 15:32:31 +0300 |
commit | e322aacedd1e91cbd1b1463ae9b4bb59a8316b5c (patch) | |
tree | d0979e86a0cb869af2ee7a401334b630594bf719 /libavcodec/ivi_common.c | |
parent | 4982a77e56bba5c21964cf55a55c40525cd0f399 (diff) |
Encapsulate VLC information needed for decoding blocks and macroblocks in
Indeo 5 into single structure IVIHuffTab and factorize code using it.
Based on patch by Maxim (max_pole at German GMX)
Originally committed as revision 22092 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavcodec/ivi_common.c')
-rw-r--r-- | libavcodec/ivi_common.c | 62 |
1 files changed, 45 insertions, 17 deletions
diff --git a/libavcodec/ivi_common.c b/libavcodec/ivi_common.c index 0a58a689f5..ad08b448b0 100644 --- a/libavcodec/ivi_common.c +++ b/libavcodec/ivi_common.c @@ -108,20 +108,48 @@ void ff_ivi_init_static_vlc(void) initialized_vlcs = 1; } -int ff_ivi_dec_huff_desc(GetBitContext *gb, IVIHuffDesc *desc) +int ff_ivi_dec_huff_desc(GetBitContext *gb, int desc_coded, int which_tab, + IVIHuffTab *huff_tab, AVCodecContext *avctx) { - int tab_sel, i; + int i, result; + IVIHuffDesc new_huff; - tab_sel = get_bits(gb, 3); - if (tab_sel == 7) { - /* custom huffman table (explicitly encoded) */ - desc->num_rows = get_bits(gb, 4); - - for (i = 0; i < desc->num_rows; i++) - desc->xbits[i] = get_bits(gb, 4); + if (!desc_coded) { + /* select default table */ + huff_tab->tab = (which_tab) ? &ff_ivi_blk_vlc_tabs[7] + : &ff_ivi_mb_vlc_tabs [7]; + } else { + huff_tab->tab_sel = get_bits(gb, 3); + if (huff_tab->tab_sel == 7) { + /* custom huffman table (explicitly encoded) */ + new_huff.num_rows = get_bits(gb, 4); + + for (i = 0; i < new_huff.num_rows; i++) + new_huff.xbits[i] = get_bits(gb, 4); + + /* Have we got the same custom table? Rebuild if not. */ + if (ff_ivi_huff_desc_cmp(&new_huff, &huff_tab->cust_desc)) { + ff_ivi_huff_desc_copy(&huff_tab->cust_desc, &new_huff); + + if (huff_tab->cust_tab.table) + free_vlc(&huff_tab->cust_tab); + result = ff_ivi_create_huff_from_desc(&huff_tab->cust_desc, + &huff_tab->cust_tab, 0); + if (result) { + av_log(avctx, AV_LOG_ERROR, + "Error while initializing custom vlc table!\n"); + return -1; + } + } + huff_tab->tab = &huff_tab->cust_tab; + } else { + /* select one of predefined tables */ + huff_tab->tab = (which_tab) ? &ff_ivi_blk_vlc_tabs[huff_tab->tab_sel] + : &ff_ivi_mb_vlc_tabs [huff_tab->tab_sel]; + } } - return tab_sel; + return 0; } int ff_ivi_huff_desc_cmp(const IVIHuffDesc *desc1, const IVIHuffDesc *desc2) @@ -191,7 +219,7 @@ int av_cold ff_ivi_init_planes(IVIPlaneDesc *planes, const IVIPicConfig *cfg) return AVERROR(ENOMEM); } - planes[p].bands[0].huff_desc.num_rows = 0; /* reset custom vlc */ + planes[p].bands[0].blk_vlc.cust_desc.num_rows = 0; /* reset custom vlc */ } } @@ -208,8 +236,8 @@ void av_cold ff_ivi_free_buffers(IVIPlaneDesc *planes) av_freep(&planes[p].bands[b].bufs[1]); av_freep(&planes[p].bands[b].bufs[2]); - if (planes[p].bands[b].blk_vlc_cust.table) - free_vlc(&planes[p].bands[b].blk_vlc_cust); + if (planes[p].bands[b].blk_vlc.cust_tab.table) + free_vlc(&planes[p].bands[b].blk_vlc.cust_tab); for (t = 0; t < planes[p].bands[b].num_tiles; t++) av_freep(&planes[p].bands[b].tiles[t].mbs); av_freep(&planes[p].bands[b].tiles); @@ -358,14 +386,14 @@ int ff_ivi_decode_blocks(GetBitContext *gb, IVIBandDesc *band, IVITile *tile) memset(col_flags, 0, sizeof(col_flags)); /* zero column flags */ while (scan_pos <= num_coeffs) { - sym = get_vlc2(gb, band->blk_vlc->table, IVI_VLC_BITS, 1); + sym = get_vlc2(gb, band->blk_vlc.tab->table, IVI_VLC_BITS, 1); if (sym == rvmap->eob_sym) break; /* End of block */ if (sym == rvmap->esc_sym) { /* Escape - run/val explicitly coded using 3 vlc codes */ - run = get_vlc2(gb, band->blk_vlc->table, IVI_VLC_BITS, 1) + 1; - lo = get_vlc2(gb, band->blk_vlc->table, IVI_VLC_BITS, 1); - hi = get_vlc2(gb, band->blk_vlc->table, IVI_VLC_BITS, 1); + run = get_vlc2(gb, band->blk_vlc.tab->table, IVI_VLC_BITS, 1) + 1; + lo = get_vlc2(gb, band->blk_vlc.tab->table, IVI_VLC_BITS, 1); + hi = get_vlc2(gb, band->blk_vlc.tab->table, IVI_VLC_BITS, 1); val = IVI_TOSIGNED((hi << 6) | lo); /* merge them and convert into signed val */ } else { run = rvmap->runtab[sym]; |