libxvid: add working lumimasking and variance AQ
authorTimothy Gu <timothygu99@gmail.com>
Wed, 31 Jul 2013 02:39:06 +0000 (19:39 -0700)
committerMichael Niedermayer <michaelni@gmx.at>
Wed, 31 Jul 2013 09:57:52 +0000 (11:57 +0200)
The old implementation is unusable due to change in the Xvid API.

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
doc/encoders.texi
libavcodec/libxvid.c

index 16be948..a647836 100644 (file)
@@ -1323,6 +1323,19 @@ half pixel and quarter pixel refinement for 8x8 blocks, and rate
 distortion-based search using square pattern.
 @end table
 
+@item lumi_aq
+Enable lumi masking adaptive quantization when set to 1. Default is 0
+(disabled).
+
+@item variance_aq
+Enable variance adaptive quantization when set to 1. Default is 0
+(disabled).
+
+When combined with @option{lumi_aq}, the resulting quality will not
+be better than any of the two specified individually. In other
+words, the resulting quality will be the worse one of the two
+effects.
+
 @end table
 
 @section png
index 05a12db..0c94c8c 100644 (file)
@@ -63,6 +63,8 @@ struct xvid_context {
     int twopassfd;
     unsigned char *intra_matrix;   /**< P-Frame Quant Matrix */
     unsigned char *inter_matrix;   /**< I-Frame Quant Matrix */
+    int lumi_aq;                   /**< Lumi masking as an aq method */
+    int variance_aq;               /**< Variance adaptive quantization */
 };
 
 /**
@@ -355,6 +357,8 @@ static av_cold int xvid_encode_init(AVCodecContext *avctx)  {
     xvid_plugin_single_t single       = { 0 };
     struct xvid_ff_pass1 rc2pass1     = { 0 };
     xvid_plugin_2pass2_t rc2pass2     = { 0 };
+    xvid_plugin_lumimasking_t masking_l = { 0 }; /* For lumi masking */
+    xvid_plugin_lumimasking_t masking_v = { 0 }; /* For variance AQ */
     xvid_gbl_init_t xvid_gbl_init     = { 0 };
     xvid_enc_create_t xvid_enc_create = { 0 };
     xvid_enc_plugin_t plugins[7];
@@ -526,12 +530,29 @@ static av_cold int xvid_encode_init(AVCodecContext *avctx)  {
     }
 
     /* Luminance Masking */
-    if( 0.0 != avctx->lumi_masking ) {
+    if( avctx->lumi_masking != 0.0 || x->lumi_aq ) {
+        masking_l.method = 0;
         plugins[xvid_enc_create.num_plugins].func = xvid_plugin_lumimasking;
-        plugins[xvid_enc_create.num_plugins].param = NULL;
+
+        /* The old behavior is that when avctx->lumi_masking is specified,
+         * plugins[...].param = NULL. Trying to keep the old behavior here. */
+        plugins[xvid_enc_create.num_plugins].param = x->lumi_aq ? &masking_l : NULL ;
         xvid_enc_create.num_plugins++;
     }
 
+    /* Variance AQ */
+    if( x->variance_aq ) {
+        masking_v.method = 1;
+        plugins[xvid_enc_create.num_plugins].func  = xvid_plugin_lumimasking;
+        plugins[xvid_enc_create.num_plugins].param = &masking_v ;
+        xvid_enc_create.num_plugins++;
+    }
+
+    if( x->lumi_aq && x->variance_aq )
+        av_log(avctx, AV_LOG_INFO,
+               "Both lumi_aq and variance_aq are enabled. The resulting quality"
+               "will be the worse one of the two effects made by the AQ.\n");
+
     /* Frame Rate and Key Frames */
     xvid_correct_framerate(avctx);
     xvid_enc_create.fincr = avctx->time_base.num;
@@ -762,6 +783,21 @@ static av_cold int xvid_encode_close(AVCodecContext *avctx) {
     return 0;
 }
 
+#define OFFSET(x) offsetof(struct xvid_context, x)
+#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
+static const AVOption options[] = {
+    { "lumi_aq",     "Luminance masking AQ", OFFSET(lumi_aq),     AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE },
+    { "variance_aq", "Variance AQ",          OFFSET(variance_aq), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE },
+    { NULL },
+};
+
+static const AVClass xvid_class = {
+    .class_name = "libxvid",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
 AVCodec ff_libxvid_encoder = {
     .name           = "libxvid",
     .type           = AVMEDIA_TYPE_VIDEO,
@@ -772,4 +808,5 @@ AVCodec ff_libxvid_encoder = {
     .close          = xvid_encode_close,
     .pix_fmts       = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE },
     .long_name      = NULL_IF_CONFIG_SMALL("libxvidcore MPEG-4 part 2"),
+    .priv_class     = &xvid_class,
 };