[FFmpeg-devel] indeo4/indeo5 inverse quantization
Maxim
max_pole
Mon May 31 01:18:12 CEST 2010
First of all - thank you for your suggestions!
> [...]
>
>
>> Index: libavcodec/ivi_common.c
>> ===================================================================
>> --- libavcodec/ivi_common.c (Revision 23369)
>> +++ libavcodec/ivi_common.c (Arbeitskopie)
>> @@ -338,7 +338,8 @@
>> RVMapDesc *rvmap = band->rv_map;
>> void (*mc_with_delta_func)(int16_t *buf, const int16_t *ref_buf, uint32_t pitch, int mc_type);
>> void (*mc_no_delta_func) (int16_t *buf, const int16_t *ref_buf, uint32_t pitch, int mc_type);
>> - const uint8_t *base_tab, *scale_tab;
>> + const uint16_t *base_tab;
>> + const uint8_t *scale_tab;
>>
>> prev_dc = 0; /* init intra prediction for the DC coefficient */
>>
>> @@ -414,7 +415,7 @@
>> if (IVI_DEBUG && !val)
>> av_log(NULL, AV_LOG_ERROR, "Val = 0 encountered!\n");
>>
>> - q = (base_tab[pos] * scale_tab[quant]) >> 8;
>> + q = (base_tab[pos] * scale_tab[quant]) >> 9;
>> if (q > 1)
>> val = val * q + FFSIGN(val) * ((q >> 1) - (q & 1));
>>
>
> ((q >> 1) - (q & 1))
> could be replaced by
>
> ((q^1)-1)>>1
>
What is the advantage of such a replacement? Anyway it looks more
compactly and friendly to me...
> also val could be kept in absolute value + sign form and onl be changed
> to normal c style int afterwards this would avoid the need for FFSIGN()
>
Hmm, I'm not sure that FFSIGN can be completely avoided.
if (sym == rvmap->esc_sym) { /* Escape - run/val explicitly coded using
3 vlc codes */
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 */
*************** IVI_TOSIGNED can be rewritten to return the sign separately.
} else {
run = rvmap->runtab[sym];
val = rvmap->valtab[sym];
*************** Smth like FFSIGN is still needed here.
}
> and quant changes per mb not per block thus scale_tab[quant] can be calculated
> outside the loop
>
This is a good idea in principle. But the main disadvantage of it could
be the fact that we never know how much coeff were transmitted for a block.
Consider we have four blocks in a 4-blocks-macroblock for each of them
only the DC coeff was sent. Then the final amount of calculations will
look like:
64 MULS in order to precalculate 64 Q-values
-------------------------------------------------------------------------------
4 MULS in order to calculate 4 DC coeffs
which is surely wasteful.
I did some statistical research right now and found out that the most
indeo5 videos I have uses THE SAME QUANT level across the WHOLE SEQUENCE!
For such videos one need to precalculate the Q-values only once and use
them all along. In the attached patch I proposed such a cache variant.
Unfortunately there are some videos (I own 5 of them) changing its QUANT
steady. The proposed scheme produces a big overhead in this case.
I could imagine myself a more sophisticated algorithm based on the fact
the first 16 coeffs are mostly often being coded. The rest (48 coeffs)
would be almost all the time 0 and will be never transmitted at all. One
can precalculate the Q-values for the coeffs 0...15 and cache them. The
rest could be calculated on the fly if needed...
Indeo4 tends to change the quant level more often...
Should I try implement that "sophisticated" approach or does it all look
like "black magic"?
Regards
Maxim
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: qcache_patch.txt
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20100531/a224aa7d/attachment.txt>
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: iv50_quant_performance
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20100531/a224aa7d/attachment.asc>
More information about the ffmpeg-devel
mailing list