[FFmpeg-cvslog] avcodec/cfhdenc: compand coefficients

Paul B Mahol git at videolan.org
Sat Aug 8 13:13:04 EEST 2020


ffmpeg | branch: master | Paul B Mahol <onemda at gmail.com> | Fri Aug  7 16:12:33 2020 +0200| [8d48e8d251f0ff5ae90a4e8e29d33f9cb27379f5] | committer: Paul B Mahol

avcodec/cfhdenc: compand coefficients

Also use -quality private option and add more modes.

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=8d48e8d251f0ff5ae90a4e8e29d33f9cb27379f5
---

 libavcodec/cfhdenc.c | 145 ++++++++++++++++++++++++++++++++++-----------------
 1 file changed, 98 insertions(+), 47 deletions(-)

diff --git a/libavcodec/cfhdenc.c b/libavcodec/cfhdenc.c
index 9b21bc2894..2dccb95d56 100644
--- a/libavcodec/cfhdenc.c
+++ b/libavcodec/cfhdenc.c
@@ -103,57 +103,65 @@ static const uint16_t runbook[8][3] = {
  * Derived by inspecting various quality encodes
  * and adding some more from scratch.
  */
-static const uint16_t quantization_per_subband[2][3][11][9] = {
+static const uint16_t quantization_per_subband[2][3][13][9] = {
     {{
-        { 16, 16,  8,  4,  4,  2,   6,   6,   9, }, // film3+
-        { 16, 16,  8,  4,  4,  2,   6,   6,   9, }, // film3
-        { 16, 16,  8,  4,  4,  2,   8,   8,  12, }, // film2+
-        { 16, 16,  8,  4,  4,  2,   8,   8,  12, }, // film2
-        { 24, 24, 12,  6,  6,  3,  24,  24,  36, }, // film1+
-        { 24, 24, 12,  6,  6,  3,  24,  24,  36, }, // film1
-        { 32, 32, 24,  8,  8,  6,  32,  32,  48, }, // high+
-        { 32, 32, 24,  8,  8,  6,  32,  32,  48, }, // high
-        { 48, 48, 32, 12, 12,  8,  64,  64,  96, }, // medium+
-        { 48, 48, 32, 12, 12,  8,  64,  64,  96, }, // medium
-        { 64, 64, 48, 16, 16, 12, 128, 128, 192, }, // low
+        { 16, 16,  8,  4,  4,  2,   3,   3,   4, }, // film3+
+        { 16, 16,  8,  4,  4,  2,   3,   3,   4, }, // film3
+        { 16, 16,  8,  4,  4,  2,   4,   4,   6, }, // film2+
+        { 16, 16,  8,  4,  4,  2,   4,   4,   6, }, // film2
+        { 16, 16,  8,  4,  4,  2,   8,   8,  12, }, // film1++
+        { 24, 24, 12,  6,  6,  3,  12,  12,  18, }, // film1+
+        { 24, 24, 12,  6,  6,  3,  12,  12,  18, }, // film1
+        { 32, 32, 24,  8,  8,  6,  16,  16,  24, }, // high+
+        { 32, 32, 24,  8,  8,  6,  16,  16,  24, }, // high
+        { 48, 48, 32, 12, 12,  8,  32,  32,  48, }, // medium+
+        { 48, 48, 32, 12, 12,  8,  32,  32,  48, }, // medium
+        { 64, 64, 48, 16, 16, 12,  48,  48,  64, }, // low+
+        { 64, 64, 48, 16, 16, 12,  64,  64,  96, }, // low
     },
     {
-        { 16, 16,  8,  4,  4,  2,   6,   6,   9, },
-        { 16, 16,  8,  4,  4,  2,   6,   6,  12, },
-        { 16, 16,  8,  4,  4,  2,   8,   8,  12, },
+        { 16, 16,  8,  4,  4,  2,   3,   3,   4, },
+        { 16, 16,  8,  4,  4,  2,   3,   3,   6, },
+        { 16, 16,  8,  4,  4,  2,   4,   4,   6, },
+        { 16, 16,  8,  4,  4,  2,   4,   4,   8, },
         { 16, 16,  8,  4,  4,  2,   8,   8,  16, },
-        { 24, 24, 12,  6,  6,  3,  24,  24,  36, },
-        { 24, 24, 12,  6,  6,  3,  24,  24,  48, },
-        { 32, 32, 24,  8,  8,  6,  32,  32,  48, },
+        { 24, 24, 12,  6,  6,  3,  12,  12,  18, },
+        { 24, 24, 12,  6,  6,  3,  12,  12,  24, },
+        { 32, 32, 24,  8,  8,  6,  16,  16,  24, },
+        { 48, 48, 32, 12, 12,  8,  16,  16,  32, },
+        { 48, 48, 32, 12, 12,  8,  32,  32,  48, },
         { 48, 48, 32, 12, 12,  8,  32,  32,  64, },
-        { 48, 48, 32, 12, 12,  8,  64,  64,  96, },
-        { 48, 48, 32, 12, 12,  8,  64,  64, 128, },
-        { 64, 64, 48, 16, 16, 12, 128, 128, 192, },
+        { 64, 64, 48, 16, 16, 12,  48,  48,  64, },
+        { 64, 64, 48, 16, 16, 12,  64,  64,  96, },
     },
     {
-        { 16, 16,  8,  4,  4,  2,   6,   6,   9, },
-        { 16, 16,  8,  4,  4,  2,   6,   6,  12, },
-        { 16, 16,  8,  4,  4,  2,   8,   8,  12, },
+        { 16, 16,  8,  4,  4,  2,   3,   3,   4, },
+        { 16, 16,  8,  4,  4,  2,   3,   3,   6, },
+        { 16, 16,  8,  4,  4,  2,   4,   4,   6, },
+        { 16, 16,  8,  4,  4,  2,   4,   4,   8, },
         { 16, 16,  8,  4,  4,  2,   8,   8,  16, },
-        { 24, 24, 12,  6,  6,  3,  24,  24,  36, },
-        { 24, 24, 12,  6,  6,  3,  24,  24,  48, },
-        { 32, 32, 24,  8,  8,  6,  32,  32,  48, },
+        { 24, 24, 12,  6,  6,  3,  12,  12,  18, },
+        { 24, 24, 12,  6,  6,  3,  12,  12,  24, },
+        { 32, 32, 24,  8,  8,  6,  16,  16,  24, },
+        { 48, 48, 32, 12, 12,  8,  16,  16,  32, },
+        { 48, 48, 32, 12, 12,  8,  32,  32,  48, },
         { 48, 48, 32, 12, 12,  8,  32,  32,  64, },
-        { 48, 48, 32, 12, 12,  8,  64,  64,  96, },
-        { 48, 48, 32, 12, 12,  8,  64,  64, 128, },
-        { 64, 64, 48, 16, 16, 12, 128, 128, 192, },
+        { 64, 64, 48, 16, 16, 12,  48,  48,  64, },
+        { 64, 64, 48, 16, 16, 12,  64,  64,  96, },
     }},
     {{
         { 16, 16,  8, 16, 16,  8,  24,  24,  36, },
         { 16, 16,  8, 16, 16,  8,  32,  32,  48, },
         { 16, 16,  8, 16, 16,  8,  48,  48,  72, },
         { 16, 16,  8, 16, 16,  8,  64,  64,  96, },
+        { 16, 16,  8, 20, 20, 10,  80,  80, 128, },
         { 24, 24, 12, 24, 24, 12,  96,  96, 144, },
-        { 24, 24, 12, 24, 24, 12, 192, 192, 288, },
-        { 32, 32, 24, 32, 32, 24, 128, 128, 192, },
+        { 24, 24, 12, 24, 24, 12, 128, 128, 192, },
+        { 32, 32, 24, 32, 32, 24, 192, 192, 288, },
         { 32, 32, 24, 32, 32, 24, 256, 256, 384, },
         { 48, 48, 32, 48, 48, 32, 256, 256, 384, },
         { 48, 48, 32, 48, 48, 32, 512, 512, 768, },
+        { 56, 56, 40, 56, 56, 40, 512, 512, 768, },
         { 64, 64, 48, 64, 64, 48, 512, 512, 768, },
     },
     {
@@ -161,12 +169,14 @@ static const uint16_t quantization_per_subband[2][3][11][9] = {
         { 16, 16,  8, 16, 16,  8,  32,  32,  48, },
         { 16, 16,  8, 16, 16,  8,  48,  48,  72, },
         { 16, 16,  8, 16, 16,  8,  64,  64,  96, },
+        { 16, 16,  8, 20, 20, 10,  80,  80, 128, },
         { 24, 24, 12, 24, 24, 12,  96,  96, 144, },
-        { 24, 24, 12, 24, 24, 12, 192, 192, 288, },
-        { 32, 32, 24, 32, 32, 24, 128, 128, 192, },
+        { 24, 24, 12, 24, 24, 12, 128, 128, 192, },
+        { 32, 32, 24, 32, 32, 24, 192, 192, 288, },
         { 32, 32, 24, 32, 32, 24, 256, 256, 384, },
         { 48, 48, 32, 48, 48, 32, 256, 256, 384, },
         { 48, 48, 32, 48, 48, 32, 512, 512, 768, },
+        { 56, 56, 40, 56, 56, 40, 512, 512, 768, },
         { 64, 64, 48, 64, 64, 48, 512, 512, 768, },
     },
     {
@@ -174,12 +184,14 @@ static const uint16_t quantization_per_subband[2][3][11][9] = {
         { 16, 16,  8, 16, 16,  8,  32,  32,  48, },
         { 16, 16,  8, 16, 16,  8,  48,  48,  72, },
         { 16, 16,  8, 16, 16,  8,  64,  64,  96, },
+        { 16, 16, 10, 20, 20, 10,  80,  80, 128, },
         { 24, 24, 12, 24, 24, 12,  96,  96, 144, },
-        { 24, 24, 12, 24, 24, 12, 192, 192, 288, },
-        { 32, 32, 24, 32, 32, 24, 128, 128, 192, },
+        { 24, 24, 12, 24, 24, 12, 128, 128, 192, },
+        { 32, 32, 24, 32, 32, 24, 192, 192, 288, },
         { 32, 32, 24, 32, 32, 24, 256, 256, 384, },
         { 48, 48, 32, 48, 48, 32, 256, 256, 384, },
         { 48, 48, 32, 48, 48, 32, 512, 512, 768, },
+        { 56, 56, 40, 56, 56, 40, 512, 512, 768, },
         { 64, 64, 48, 64, 64, 48, 512, 512, 768, },
     }},
 };
@@ -209,15 +221,18 @@ typedef struct PlaneEnc {
 } PlaneEnc;
 
 typedef struct CFHDEncContext {
+    const AVClass *class;
+
     PutBitContext       pb;
     PutByteContext      pby;
 
-    int compression;
+    int quality;
     int planes;
     int chroma_h_shift;
     int chroma_v_shift;
     PlaneEnc plane[4];
 
+    uint16_t lut[1024];
     Runbook  rb[321];
     Codebook cb[513];
 } CFHDEncContext;
@@ -228,7 +243,7 @@ static av_cold int cfhd_encode_init(AVCodecContext *avctx)
     const int sign_mask = 256;
     const int twos_complement = -sign_mask;
     const int mag_mask = sign_mask - 1;
-    int ret;
+    int ret, last = 0;
 
     ret = av_pix_fmt_get_chroma_sub_sample(avctx->pix_fmt,
                                            &s->chroma_h_shift,
@@ -242,11 +257,6 @@ static av_cold int cfhd_encode_init(AVCodecContext *avctx)
     }
 
     s->planes = av_pix_fmt_count_planes(avctx->pix_fmt);
-    s->compression = avctx->compression_level;
-
-    if (s->compression == FF_COMPRESSION_DEFAULT)
-        s->compression = 2;
-    s->compression = av_clip(s->compression, 0, 10);
 
     for (int i = 0; i < s->planes; i++) {
         int w8, h8, w4, h4, w2, h2;
@@ -333,6 +343,18 @@ static av_cold int cfhd_encode_init(AVCodecContext *avctx)
     s->rb[320].size = runbook[7][0];
     s->rb[320].run = 320;
 
+    for (int i = 0; i < 256; i++) {
+        int idx = i + ((768LL * i * i * i) / (256 * 256 * 256));
+
+        s->lut[idx] = i;
+    }
+    for (int i = 0; i < 1024; i++) {
+        if (s->lut[i])
+            last = s->lut[i];
+        else
+            s->lut[i] = last;
+    }
+
     return 0;
 }
 
@@ -379,7 +401,7 @@ static void quantize_band(int16_t *input, int width, int a_width,
 
     for (int i = 0; i < height; i++) {
         for (int j = 0; j < width; j++)
-            input[j] = av_clip_intp2((input[j] * factor) / 65536, 8);
+            input[j] = av_clip_intp2((input[j] * factor) / 65536, 10);
         input += a_width;
     }
 }
@@ -404,6 +426,7 @@ static int cfhd_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
     PutBitContext *pb = &s->pb;
     const Codebook *const cb = s->cb;
     const Runbook *const rb = s->rb;
+    const uint16_t *lut = s->lut;
     unsigned pos;
     int ret = 0;
 
@@ -653,7 +676,7 @@ static int cfhd_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
 
         for (int l = 0; l < 3; l++) {
             for (int i = 0; i < 3; i++) {
-                s->plane[p].quantization[1 + l * 3 + i] = quantization_per_subband[avctx->pix_fmt != AV_PIX_FMT_YUV422P10][p][s->compression][l * 3 + i];
+                s->plane[p].quantization[1 + l * 3 + i] = quantization_per_subband[avctx->pix_fmt != AV_PIX_FMT_YUV422P10][p][s->quality][l * 3 + i];
             }
         }
 
@@ -707,7 +730,7 @@ static int cfhd_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
                 bytestream2_put_be16(pby, i + 1);
 
                 bytestream2_put_be16(pby, BandCodingFlags);
-                bytestream2_put_be16(pby, 2);
+                bytestream2_put_be16(pby, 1);
 
                 bytestream2_put_be16(pby, BandWidth);
                 bytestream2_put_be16(pby, width);
@@ -737,7 +760,7 @@ static int cfhd_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
 
                 for (int m = 0; m < height; m++) {
                     for (int j = 0; j < stride; j++) {
-                        int16_t index = data[j];
+                        int16_t index = FFSIGN(data[j]) * lut[FFABS(data[j])];
 
                         if (index < 0)
                             index += 512;
@@ -811,12 +834,40 @@ static av_cold int cfhd_encode_close(AVCodecContext *avctx)
     return 0;
 }
 
+#define OFFSET(x) offsetof(CFHDEncContext, x)
+#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
+static const AVOption options[] = {
+    { "quality", "set quality", OFFSET(quality), AV_OPT_TYPE_INT,   {.i64= 0}, 0, 12, VE, "q" },
+    { "film3+",   NULL,         0,               AV_OPT_TYPE_CONST, {.i64= 0}, 0,  0, VE, "q" },
+    { "film3",    NULL,         0,               AV_OPT_TYPE_CONST, {.i64= 1}, 0,  0, VE, "q" },
+    { "film2+",   NULL,         0,               AV_OPT_TYPE_CONST, {.i64= 2}, 0,  0, VE, "q" },
+    { "film2",    NULL,         0,               AV_OPT_TYPE_CONST, {.i64= 3}, 0,  0, VE, "q" },
+    { "film1.5",  NULL,         0,               AV_OPT_TYPE_CONST, {.i64= 4}, 0,  0, VE, "q" },
+    { "film1+",   NULL,         0,               AV_OPT_TYPE_CONST, {.i64= 5}, 0,  0, VE, "q" },
+    { "film1",    NULL,         0,               AV_OPT_TYPE_CONST, {.i64= 6}, 0,  0, VE, "q" },
+    { "high+",    NULL,         0,               AV_OPT_TYPE_CONST, {.i64= 7}, 0,  0, VE, "q" },
+    { "high",     NULL,         0,               AV_OPT_TYPE_CONST, {.i64= 8}, 0,  0, VE, "q" },
+    { "medium+",  NULL,         0,               AV_OPT_TYPE_CONST, {.i64= 9}, 0,  0, VE, "q" },
+    { "medium",   NULL,         0,               AV_OPT_TYPE_CONST, {.i64=10}, 0,  0, VE, "q" },
+    { "low+",     NULL,         0,               AV_OPT_TYPE_CONST, {.i64=11}, 0,  0, VE, "q" },
+    { "low",      NULL,         0,               AV_OPT_TYPE_CONST, {.i64=12}, 0,  0, VE, "q" },
+    { NULL},
+};
+
+static const AVClass cfhd_class = {
+    .class_name = "cfhd",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
 AVCodec ff_cfhd_encoder = {
     .name             = "cfhd",
     .long_name        = NULL_IF_CONFIG_SMALL("Cineform HD"),
     .type             = AVMEDIA_TYPE_VIDEO,
     .id               = AV_CODEC_ID_CFHD,
     .priv_data_size   = sizeof(CFHDEncContext),
+    .priv_class       = &cfhd_class,
     .init             = cfhd_encode_init,
     .close            = cfhd_encode_close,
     .encode2          = cfhd_encode_frame,



More information about the ffmpeg-cvslog mailing list