[Theora-dev] Fix a bug that causes the encoder to spend way to many bits on keyframes

Aaron Colwell acolwell at real.com
Thu Feb 17 11:22:11 PST 2005

Here is a fix that prevents the encoder from spending too many bits on
keyframes. The main problem is that the old code computes the target keyframe
bitrate incorrectly. This causes the code that computes the Q for the frame to
think that it has tons of bits to spend. It selects a high Q value for the
keyframe. Since so many bits were spend on the keyframe the the inter-frames
have to use a much lower Q. This ends up causing a "popping" artifact where 
everything is clear for a keyframe, but gets progressively blurry for each
successive inter-frame. This change fixes the keyframe bitrate computation so 
that it is closer to the inter-frame bitrate, which I believe is what the 
original author intended. This prevents the huge difference in Q between 
keyframes and inter-frames.

Index: encoder_toplevel.c
--- encoder_toplevel.c	(revision 8940)
+++ encoder_toplevel.c	(working copy)
@@ -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;

I'm also playing around with the following change to help remove the "popping"
artifact that I mentioned above. This change removes the restriction that
keyframe Q must be in the range 20 <= Q <= 50. For encodes that tend to use
Q lower than 20 you see the "popping" artifact if the inter-frame Q is lower 
than 20. The results look good so far, but I want to do more testing on
various source content to make sure this is a good change.

Index: misc_common.c
--- misc_common.c	(revision 8940)
+++ misc_common.c	(working copy)
@@ -255,14 +255,6 @@
   /* QIndex should now indicate the optimal Q. */
   cpi->pb.ThisFrameQualityValue = cpi->pb.QThreshTable[QIndex];
-  /* Apply range restrictions for key frames. */
-  if ( GetFrameType(&cpi->pb) == BASE_FRAME ) {
-    if ( cpi->pb.ThisFrameQualityValue > cpi->pb.QThreshTable[20] )
-      cpi->pb.ThisFrameQualityValue = cpi->pb.QThreshTable[20];
-    else if ( cpi->pb.ThisFrameQualityValue < cpi->pb.QThreshTable[50] )
-      cpi->pb.ThisFrameQualityValue = cpi->pb.QThreshTable[50];
-  }
   /* Limit the Q value to the maximum available value */
   if (cpi->pb.ThisFrameQualityValue >
       cpi->pb.QThreshTable[cpi->Configuration.ActiveMaxQ]) {


More information about the Theora-dev mailing list