[FFmpeg-devel] [PATCH] Support block-level quantization in Theora

Michael Niedermayer michaelni
Fri May 29 21:52:37 CEST 2009


On Thu, May 28, 2009 at 06:56:06PM -0400, David Conrad wrote:
> On May 28, 2009, at 5:46 PM, Michael Niedermayer wrote:
>
>> On Thu, May 28, 2009 at 01:32:02PM -0400, David Conrad wrote:
>>> Hi,
>>>
>>> This mostly fixes theora_derf.ogg [1]; keyframes are good but interframes
>>> degrade due to a bug in libtheora when that file was created (inter quant
>>> matrices were assumed to be copied from intra when they shouldn't have 
>>> been
>>> according to the spec.)
>>>
>>> Also I reduced the number of planes in qmat to 3 because Theora/vp3 can't
>>> have more.
>>>
>>> [1]
>>> http://ftp.icm.edu.pl/pub/unix/video/mplayer/samples/ogg/Theora/theora_derf.ogg
>>>
>>
>>> commit c1a1975b43c1c4f1a2ec62a556348455828a22dd
>>> Author: David Conrad <lessen42 at gmail.com>
>>> Date:   Thu May 28 13:30:57 2009 -0400
>>>
>>>    Support block-level quantization in Theora
>>>
>>> diff --git a/libavcodec/vp3.c b/libavcodec/vp3.c
>>> index 9f7dfb6..5d4be28 100644
>>> --- a/libavcodec/vp3.c
>>> +++ b/libavcodec/vp3.c
>>> @@ -60,6 +60,7 @@ typedef struct Vp3Fragment {
>>>     uint8_t coding_method;
>>>     int8_t motion_x;
>>>     int8_t motion_y;
>>> +    uint8_t qi;
>>> } Vp3Fragment;
>>
>> what is qi ?
>> is it what everyone but xiph calls qp? if so i would prefer to follow
>> what the majority calls it.
>
> Xiph does indeed call qp qi. However, here it's an index into the 3 qps 
> that are defined for the frame (I was thinking quant index.) So maybe this 
> should be called qpi?
>
>> [...]
>>> @@ -477,10 +478,10 @@ static void init_frame(Vp3DecodeContext *s, 
>>> GetBitContext *gb)
>>>  * This function sets up the dequantization tables used for a particular
>>>  * frame.
>>>  */
>>> -static void init_dequantizer(Vp3DecodeContext *s)
>>> +static void init_dequantizer(Vp3DecodeContext *s, int qi)
>>> {
>>> -    int ac_scale_factor = s->coded_ac_scale_factor[s->quality_index];
>>> -    int dc_scale_factor = s->coded_dc_scale_factor[s->quality_index];
>>
>>> +    int ac_scale_factor = s->coded_ac_scale_factor[s->qis[qi]];
>>> +    int dc_scale_factor = s->coded_dc_scale_factor[s->qis[qi]];
>>
>> qis is hardly a better name than qi btw ...
>> "quality_index" at least made some sense
>
> In this case it already existed :) I renamed it qps, though maybe it should 
> be frame_qps?
>
>> [...]
>>> @@ -963,6 +966,56 @@ static int unpack_vectors(Vp3DecodeContext *s, 
>>> GetBitContext *gb)
>>>     return 0;
>>> }
>>>
>>> +static int unpack_block_qis(Vp3DecodeContext *s, GetBitContext *gb)
>>> +{
>>> +    int qi, i, j, bit, run_length, blocks_decoded, num_blocks_at_qi;
>>> +    int num_blocks = s->coded_fragment_list_index;
>>> +
>>> +    for (qi = 0; qi < s->nqis-1 && num_blocks > 0; qi++) {
>>> +        i = blocks_decoded = num_blocks_at_qi = 0;
>>> +
>>> +        bit = get_bits1(gb);
>>> +
>>> +        do {
>>
>>> +            run_length = get_vlc2(gb, 
>>> s->superblock_run_length_vlc.table, 6, 2);
>>> +            if (run_length == 33)
>>> +                run_length += get_bits(gb, 12);
>>
>>> +            run_length++;
>>
>> run_length = get_vlc2(gb, s->superblock_run_length_vlc.table, 6, 2) + 1;
>
> Fixed.
>
>>> +            blocks_decoded += run_length;
>>> +
>>
>>> +            if (bit) {
>>> +                for (j = 0; j < run_length; i++) {
>>> +                    if (i > s->coded_fragment_list_index)
>>> +                        return -1;
>>> +
>>> +                    if (s->all_fragments[s->coded_fragment_list[i]].qi 
>>> == qi) {
>>> +                        
>>> s->all_fragments[s->coded_fragment_list[i]].qi++;
>>> +                        j++;
>>> +                    }
>>> +                }
>>> +            } else {
>>> +                num_blocks_at_qi += run_length;
>>> +                for (j = 0; j < run_length; i++) {
>>> +                    if (i > s->coded_fragment_list_index)
>>> +                        return -1;
>>> +
>>> +                    if (s->all_fragments[s->coded_fragment_list[i]].qi 
>>> == qi)
>>> +                        j++;
>>> +                }
>>> +            }
>>
>> this could be factorized, though tht would be slower, by a hair in theory
>> what effect on the whole does this have speedwise?
>
> This loop is not executed if there's only one quant per frame (essentially 
> all Theora files in existence) and takes 1% of the decode time on the 
> sample I'm using, so I factored the two sides with no noticeable speedloss.
>
> The additional indirection in determining the dequant table has a 0.4% 
> slowdown however.
>

> commit 6d8bb33c99f55af808c9e349dc50c06a27c11aea
> Author: David Conrad <lessen42 at gmail.com>
> Date:   Thu May 28 13:30:57 2009 -0400
> 
>     Support block-level quantization in Theora

probably ok, assuming its tested

[...]

-- 
Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

Observe your enemies, for they first find out your faults. -- Antisthenes
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20090529/52c21804/attachment.pgp>



More information about the ffmpeg-devel mailing list