Where a key frame occurs because of a minimum interval
selected by the user, then these forced key frames ideally need
to be more closely matched in quality to the surrounding frame.
Change-Id: Ia55b1f047e77dc7fbd78379c45869554f25b3df7
Add a flag to always enable block4x4 search for speed=0 (good
quality) to guarantee no quality loss for speed0.
Change-Id: Ie04bbc25f7e6a33a7bfa30e05775d33148731c81
The maximum possible MV in 1/8 pel units is (1<<11), which could
cause mvcost out of its range that is 1023. Change maximum
possible MV in 1/8 pel units to (1<<11)-8 will fix this problem.
Change-Id: I5788ed1de773f66658c14f225fb4ab5b1679b74b
Further experiment with restriction of the Q range.
This uses the average non KF/GF/ARF quantizer, instead
of just relying on the initial value. It is not such a strong constraint
but there may be a reduced risk of rate misses.
Change-Id: I424fe782a37a2f4e18c70805e240db55bfaa25ec
The merge includes hooks to for CQ mode and other code
changes merged from the test branch.
CQ mode attempts to maintain a more stable quantizer within a clip
whilst also trying to adhere to a guidline maximum bitrate.
The existing target data rate parameter is used to specify the
guideline maximum bitrate.
A new parameter allows the user to specify a target CQ level.
For normal (non kf/gf/arf) frames, the quantizer will not drop BELOW the
user specified value (0-63). However, in some cases the encoder may
choose to impose a target CQ that is above that specified by the user,
if it estimates that consistent use of the target value is not compatible
with guideline maximum bitrate.
Change-Id: I2221f9eecae8cc3c431d36caf83503941b25e4c1
In two pass encoding each frame is given an active
Q range to work with. This change limits how much this
Q range can be altered over time from the initial estimate
made for the clip as a whole.
There is some danger this could lead to overshoot or undershoot
in some corner cases but it helps considerably in regard to
clips where either there is a glut or famine of bits in some sections,
particularly near the end of a clip.
Change-Id: I34fcd1af31d2ee3d5444f93e334645254043026e
cpi->target_bits_per_mb is currently not being used,
so delete it. Also removed other unused code in rdopt.c.
Change-Id: I98449f9030bcd2f15451d9b7a3b9b93dd1409923
count can be reduced to short because the max number of filtered frames
is set to 15. the max value for any frame is 32 (modifier = 16,
filter_weight = 2). 15*32 = 480 which requires 9 bits
this function goes from about 7000 us / 1000 iterations for the C code
to < 275 us / 1000 iterations for sse2 for block_size = 16 and from
about 1800 us / 1000 iters to < 100 us / 1000 iters for block_size = 8
Change-Id: I64a32607f58a2d33c39286f468b04ccd457d9e6e
Commit 0ce3901 introduced a change in the frame buffer copy logic where
the NEW frame could be copied to the ARF or GF buffer through the
copy_buffer_to_{arf,gf}==1 flags, if the LAST frame was not being
refreshed. This is not correct. The intent of the
copy_buffer_to_{arf,gf}==1 flag is to copy the LAST buffer. To copy the
NEW buffer, the refresh_{alt_ref,golden}_frame flag should be used.
The original buffer copy logic is fairly convoluted. For example:
if (cm->refresh_last_frame)
{
vp8_swap_yv12_buffer(&cm->last_frame, &cm->new_frame);
cm->frame_to_show = &cm->last_frame;
}
else
{
cm->frame_to_show = &cm->new_frame;
}
...
if (cm->copy_buffer_to_arf)
{
if (cm->copy_buffer_to_arf == 1)
{
if (cm->refresh_last_frame)
vp8_yv12_copy_frame_ptr(&cm->new_frame, &cm->alt_ref_frame);
else
vp8_yv12_copy_frame_ptr(&cm->last_frame, &cm->alt_ref_frame);
}
else if (cm->copy_buffer_to_arf == 2)
vp8_yv12_copy_frame_ptr(&cm->golden_frame, &cm->alt_ref_frame);
}
Effectively, if refresh_last_frame, then new and last are swapped, so
when "new" is copied to ARF, it's equivalent to copying LAST to ARF. If
not refresh_last_frame, then LAST is copied to ARF. So LAST is copied to
ARF in both cases.
Commit 0ce3901 removed the first buffer swap but kept the
refresh_last_frame?new:last behavior, changing the sense since the first
swap wasn't done to the more readable refresh_last_frame?last:new, but
this logic is not correct when !refresh_last_frame.
This commit restores the correct behavior from v0.9.1 and prior. This
case is missing from the test vector set.
Change-Id: I8369fc13a37ae882e31a8a104da808a08bc8428f
The following features don't make sense for the first
pass in its current form and have a significant impact on its
speed (up to 50%).
Slow quantizer, slow dct and trellis optimization.
Change-Id: Id9943f6765ffbd71fc0084ec7dfbc9d376fd6fcd
Calculate a minimum intra value to be used in determining the
IIratio scores used in two pass, second pass.
This is to make sure sections that are low complexity" in the
intra domain are still boosted appropriately for KF/GF/ARF.
For now I have commented out the Q based adjustment of
KF boost.
Change-Id: I15deb09c5bd9b53180a2ddd3e5f575b2aba244b3
Scott pointed out that last_frame_type only gets updated while
loopfilter exists. Since last_frame_type is also needed in
motion search now, it needs to be updated every frame.
Change-Id: I9203532fd67361588d4024628d9ddb8e391ad912
Use the fast quantizer for inter mode selection and the
regular quantizer for the rest of the encode for good quality,
speed 1. Both performance and quality were improved. The
quality gains will make up for the quality loss mentioned in
I9dc089007ca08129fb6c11fe7692777ebb8647b0.
Change-Id: Ia90bc9cf326a7c65d60d31fa32f6465ab6984d21
1. Search for block8x16/block16x8 uses block8x8's search results.
2. Check block4x4 only if block8x8 is chosen. (This hurts quality,
which will be improved in another check-in.)
3. In block4x4 search, the previous block's result is used as
MV predictor for next block.
This change improves performance.
Change-Id: I9dc089007ca08129fb6c11fe7692777ebb8647b0
Re-calibrated sad_per_bit16 and sad_per_bit4 tables to linearly
correlated to quantizer values, these two variables are used in
motion search for costing motion vectors. This change has an small
positive effect on compression.
Change-Id: Ic9b5ea6fb8d5078ef663ba4899db019cc51f4166
stats_close() was not freeing memory for
single pass runs. It now takes in arg_passes
to determine when it should free memory.
Change-Id: I6623b7e30b76f9bf2e16008490f9b20484d03f31
the lookup table is based on floating point calculations (see source)
by moving the *3 before the downshift and adding the rounding bit, the
delta (LUT - integer) goes from:
______________________________________
__ 1__ 1______________________________
__ 1__ 1______________________________
____ 1______ 1________________________
____ 1 2__ 2 1________________________
______ 1 1 2__ 2__ 2__ 2 1 1__________
________ 1 1 2 2__ 1 2 3 1 2__ 2__ 2__
to:
__-1__-1______________________________
______________________________________
____-1______-1________________________
______________________________________
________-1______________-1____________
______________________________________
it's important to be able to use the integer version because the LUT
more or less precludes SIMD optimizations
Change-Id: I45a81127dc7b72a06fba951649135d9d918386c0
allow for optimized versions of apply_temporal_filter
(now vp8_apply_temporal_filter_c)
the function was previously declared as static and appears to have been
inlined. with this change, that's no longer possible. performance takes
a small hit.
the declaration for vp8_cx_temp_filter_c was moved to onyx_if.c because
of a circular dependency. for rtcd, temporal_filter.h holds the
definition for the rtcd table, so it needs to be included by onyx_int.h.
however, onyx_int.h holds the definition for VP8_COMP which is needed
for the function prototype. blah.
Change-Id: I499c055fdc652ac4659c21c5a55fe10ceb7e95e3