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

David Conrad lessen42
Fri May 29 00:56:06 CEST 2009


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.

-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: ffmpeg-theora-blockqi.txt
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20090528/d7ff6ded/attachment.txt>
-------------- next part --------------




More information about the ffmpeg-devel mailing list