Aaron Colwell
2005-Mar-02 09:22 UTC
[Theora-dev] Patch that fixes distortions during static scenes
Here is a patch that fixes distortions that appear during scenes with no motion. Tbe problem was that UpdateFrame() was not being called when a MotionScore of 0 was computed. Since UpdateFrame() was not called the buffer returned by theora_encode_packetout() would be the same buffer that was output for the last frame that had a non-zero MotionScore. This is obviously incorrect behavior. I've just moved the UpdateFrame() out of the (MotionScore > 0) conditional block. I've also included my change that prevents the encoder from spending WAY to many bits on keyframes. This helps prevent the artifact where the video suddenly gets very clear when keyframes occur but gets progressively blurry for interframes. This change helps minimize some of the drastic Q changes that cause this artifact. Aaron Index: encoder_toplevel.c ==================================================================--- encoder_toplevel.c (revision 9007) +++ encoder_toplevel.c (working copy) @@ -739,12 +739,12 @@ /* Increment the frames since last key frame count */ cpi->LastKeyFrame++; + /* Proceed with the frame update. */ + UpdateFrame(cpi); + if ( cpi->MotionScore > 0 ){ cpi->DropCount = 0; - /* Proceed with the frame update. */ - UpdateFrame(cpi); - /* Note the Quantizer used for each block coded. */ for ( i = 0; i < cpi->pb.UnitFragments; i++ ){ if ( cpi->pb.display_fragments[i] ){ @@ -862,8 +862,8 @@ /* Set key frame data rate target; this is nominal keyframe size */ cpi->Configuration.KeyFrameDataTarget = (c->keyframe_data_target_bitrate * - c->fps_numerator / - c->fps_denominator ) / 8; + c->fps_denominator / + c->fps_numerator ) / 8; /* Note the height and width in the pre-processor control structure. */ cpi->ScanConfig.VideoFrameHeight = cpi->pb.info.height;
Ivan Popov
2005-Mar-03 05:15 UTC
[Theora-dev] Patch that fixes distortions during static scenes
Hi Aaron,> Here is a patch that fixes distortions that appear during scenes with no > motion. Tbe problem was that UpdateFrame() was not being called when a > MotionScore of 0 was computed. Since UpdateFrame() was not called the buffer > returned by theora_encode_packetout() would be the same buffer that was output > for the last frame that had a non-zero MotionScore. This is obviously incorrect > behavior. I've just moved the UpdateFrame() out of the (MotionScore > 0) > conditional block.this fix definitely removes the "accumulating artifacts" I observed. Thanks! On the other side, other keyframe-related artifacts are in place, and I see a problem which is quite opposite to one you descibed. It looks like a keyframe is being encoded with a "too bad" quality, so that the following frames gradually improve it. This looks like a perfect behaviour when a keyframe is inserted as the scene changes, but as well very bad during static scenes (causing a burst of artifacts). It looks even more strange as it happens when we clearly have a huge excess of unused bits - I ask for 2000 kbit/s and get about 250 kbit/s On the third side, I can reduce the probablility of such "error bursts" by tweaking keyframe frequency - yet it feels like a workaround for an unexpected encoder behaviour. I guess the bit-allocation machinery has some problems yet. Again, thanks for fix! -- Ivan