[FFmpeg-devel] [PATCH] Support block-level quantization in Theora
David Conrad
lessen42
Fri May 29 23:43:30 CEST 2009
On May 29, 2009, at 3:52 PM, Michael Niedermayer wrote:
> 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
Doesn't change normal VP3/Theora, and I'm attributing the artifacts on
interframes of theora_derf.ogg to the quant tables being stored
incorrectly.
Applied.
More information about the ffmpeg-devel
mailing list