[FFmpeg-devel] [PATCH][RFC] avcodec/dpxenc: add option to force color transfer characteristics

Tobias Rapp t.rapp at noa-archive.com
Fri Dec 15 23:22:09 EET 2017


Based on a patch by Kieran O'Leary. Fixes ticket #6023.

Open topics:
 - is there some mapping missing in color_trc_to_dpx?
 - the default for color_trc is DPX_TRC_UNDEFINED, would it be better to
   use DPX_TRC_USER_DEFINED instead?
 - do we need a separate encoder option for the colorimetric
   specification field? If yes, do we try to map the value from frame
   color_trc/color_primaries/...?

Signed-off-by: Tobias Rapp <t.rapp at noa-archive.com>
---
 doc/encoders.texi   | 43 ++++++++++++++++++++++++++++
 libavcodec/dpxenc.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++--
 tests/ref/lavf/dpx  | 12 ++++----
 3 files changed, 127 insertions(+), 8 deletions(-)

diff --git a/doc/encoders.texi b/doc/encoders.texi
index 88ef8f9..f3f36bf 100644
--- a/doc/encoders.texi
+++ b/doc/encoders.texi
@@ -1312,6 +1312,49 @@ disabled
 A description of some of the currently available video encoders
 follows.
 
+ at section dpx
+
+Digital Moving-Picture Exchange (DPX) image encoder.
+
+ at subsection Options
+
+ at table @option
+ at item dpx_color_trc @var{integer}
+DPX color transfer characteristics (see Table 5A in SMPTE 268M-2003).
+
+ at table @option
+ at item user
+User Defined
+ at item print
+Printing Density
+ at item linear
+Linear
+ at item log
+Logarithmic
+ at item video
+Unspecified Video
+ at item smpte274m
+SMPTE-274M
+ at item itur709
+ITU-R 709-4
+ at item itur601bg
+ITU-R 601-5 (system B or G)
+ at item itur601m
+ITU-R 601-5 (system M)
+ at item ntsc
+NTSC Composite Video
+ at item pal
+PAL Composite Video
+ at item zlinear
+Z-Linear
+ at item zhomogen
+Z-Homogeneous
+ at end table
+
+Default value is derived from encoder, when mapping is available.
+
+ at end table
+
 @section Hap
 
 Vidvox Hap video encoder.
diff --git a/libavcodec/dpxenc.c b/libavcodec/dpxenc.c
index a596033..ddcd53b 100644
--- a/libavcodec/dpxenc.c
+++ b/libavcodec/dpxenc.c
@@ -22,17 +22,56 @@
 #include "libavutil/common.h"
 #include "libavutil/intreadwrite.h"
 #include "libavutil/imgutils.h"
+#include "libavutil/opt.h"
+#include "libavutil/pixdesc.h"
+#include "libavutil/pixfmt.h"
 #include "avcodec.h"
 #include "internal.h"
 
 typedef struct DPXContext {
+    AVClass *class;
     int big_endian;
     int bits_per_component;
     int num_components;
     int descriptor;
     int planar;
+    int color_trc;
 } DPXContext;
 
+enum DPXTransferCharacteristic {
+    DPX_TRC_UNDEFINED            = -1,
+    DPX_TRC_USER_DEFINED         = 0,
+    DPX_TRC_PRINTING_DENSITY     = 1,
+    DPX_TRC_LINEAR               = 2,
+    DPX_TRC_LOG                  = 3,   // Logarithmic
+    DPX_TRC_UNSPECIFIED_VIDEO    = 4,
+    DPX_TRC_SMPTE274M            = 5,   // SMPTE 274M
+    DPX_TRC_ITUR709              = 6,   // ITU-R 709-4
+    DPX_TRC_ITUR601BG            = 7,   // ITU-R 601-5 system B or G (625)
+    DPX_TRC_ITUR601M             = 8,   // ITU-R 601-5 system M (525)
+    DPX_TRC_COMPOSITE_VIDEO_NTSC = 9,   // Composite video (NTSC), see SMPTE 170M
+    DPX_TRC_COMPOSITE_VIDEO_PAL  = 10,  // Composite video (PAL), see ITU-R 624-4
+    DPX_TRC_Z_LINEAR             = 11,
+    DPX_TRC_Z_HOMOGENEOUS        = 12,
+    DPX_TRC_NB
+};
+
+static int color_trc_to_dpx(enum AVColorTransferCharacteristic color_trc)
+{
+    switch (color_trc) {
+    case AVCOL_TRC_LINEAR:
+        return DPX_TRC_LINEAR;
+    case AVCOL_TRC_LOG:
+        return DPX_TRC_LOG;
+    case AVCOL_TRC_BT709:
+        return DPX_TRC_ITUR709;
+    case AVCOL_TRC_SMPTE170M:
+        return DPX_TRC_COMPOSITE_VIDEO_NTSC;
+    default:
+        return DPX_TRC_UNDEFINED;
+    }
+}
+
 static av_cold int encode_init(AVCodecContext *avctx)
 {
     DPXContext *s = avctx->priv_data;
@@ -178,6 +217,7 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
 {
     DPXContext *s = avctx->priv_data;
     int size, ret, need_align, len;
+    int color_trc = s->color_trc;
     uint8_t *buf;
 
 #define HEADER_SIZE 1664  /* DPX Generic header */
@@ -200,6 +240,14 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
         return ret;
     buf = pkt->data;
 
+    if (color_trc < 0)
+        color_trc = color_trc_to_dpx(frame->color_trc);
+    if (color_trc < 0)
+        color_trc = color_trc_to_dpx(avctx->color_trc);
+    av_log(avctx, AV_LOG_TRACE, "codec_color_trc:%s frame_color_trc:%s dpx_color_trc:%d\n",
+           av_color_transfer_name(avctx->color_trc), av_color_transfer_name(frame->color_trc),
+           color_trc);
+
     memset(buf, 0, HEADER_SIZE);
 
     /* File information header */
@@ -218,8 +266,8 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
     write32(buf + 772, avctx->width);
     write32(buf + 776, avctx->height);
     buf[800] = s->descriptor;
-    buf[801] = 2; /* linear transfer */
-    buf[802] = 2; /* linear colorimetric */
+    buf[801] = color_trc; /* transfer characteristics */
+    buf[802] = color_trc; /* colorimetric specification */
     buf[803] = s->bits_per_component;
     write16(buf + 804, (s->bits_per_component == 10 || s->bits_per_component == 12) ?
                        1 : 0); /* packing method */
@@ -276,6 +324,33 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
     return 0;
 }
 
+#define OFFSET(x) offsetof(DPXContext, x)
+#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
+static const AVOption options[] = {
+    { "dpx_color_trc",  "Transfer Characteristics", OFFSET(color_trc), AV_OPT_TYPE_INT, { .i64 = DPX_TRC_UNDEFINED }, DPX_TRC_UNDEFINED, DPX_TRC_NB-1, VE, "trc" },
+        { "user",       "User Defined",                0, AV_OPT_TYPE_CONST, { .i64 = DPX_TRC_USER_DEFINED },          0, 0, VE, "trc" },
+        { "print",      "Printing Density",            0, AV_OPT_TYPE_CONST, { .i64 = DPX_TRC_PRINTING_DENSITY },      0, 0, VE, "trc" },
+        { "linear",     "Linear",                      0, AV_OPT_TYPE_CONST, { .i64 = DPX_TRC_LINEAR },                0, 0, VE, "trc" },
+        { "log",        "Logarithmic",                 0, AV_OPT_TYPE_CONST, { .i64 = DPX_TRC_LOG },                   0, 0, VE, "trc" },
+        { "video",      "Unspecified Video",           0, AV_OPT_TYPE_CONST, { .i64 = DPX_TRC_UNSPECIFIED_VIDEO },     0, 0, VE, "trc" },
+        { "smpte274m",  "SMPTE-274M",                  0, AV_OPT_TYPE_CONST, { .i64 = DPX_TRC_SMPTE274M },             0, 0, VE, "trc" },
+        { "itur709",    "ITU-R 709-4",                 0, AV_OPT_TYPE_CONST, { .i64 = DPX_TRC_ITUR709 },               0, 0, VE, "trc" },
+        { "itur601bg",  "ITU-R 601-5 (system B or G)", 0, AV_OPT_TYPE_CONST, { .i64 = DPX_TRC_ITUR601BG },             0, 0, VE, "trc" },
+        { "itur601m",   "ITU-R 601-5 (system M)",      0, AV_OPT_TYPE_CONST, { .i64 = DPX_TRC_ITUR601M },              0, 0, VE, "trc" },
+        { "ntsc",       "NTSC Composite Video",        0, AV_OPT_TYPE_CONST, { .i64 = DPX_TRC_COMPOSITE_VIDEO_NTSC },  0, 0, VE, "trc" },
+        { "pal",        "PAL Composite Video",         0, AV_OPT_TYPE_CONST, { .i64 = DPX_TRC_COMPOSITE_VIDEO_PAL },   0, 0, VE, "trc" },
+        { "zlinear",    "Z-Linear",                    0, AV_OPT_TYPE_CONST, { .i64 = DPX_TRC_Z_LINEAR },              0, 0, VE, "trc" },
+        { "zhomogen",   "Z-Homogeneous",               0, AV_OPT_TYPE_CONST, { .i64 = DPX_TRC_Z_HOMOGENEOUS },         0, 0, VE, "trc" },
+    { NULL }
+};
+
+static const AVClass dpxenc_class = {
+    .class_name = "DPX encoder",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
 AVCodec ff_dpx_encoder = {
     .name           = "dpx",
     .long_name      = NULL_IF_CONFIG_SMALL("DPX (Digital Picture Exchange) image"),
@@ -293,4 +368,5 @@ AVCodec ff_dpx_encoder = {
         AV_PIX_FMT_GBRP10LE, AV_PIX_FMT_GBRP10BE,
         AV_PIX_FMT_GBRP12LE, AV_PIX_FMT_GBRP12BE,
         AV_PIX_FMT_NONE},
+    .priv_class     = &dpxenc_class,
 };
diff --git a/tests/ref/lavf/dpx b/tests/ref/lavf/dpx
index 7bbed3e..6092570 100644
--- a/tests/ref/lavf/dpx
+++ b/tests/ref/lavf/dpx
@@ -1,18 +1,18 @@
-4c8880d5835ffb5fe37c1ed8c8d404de *./tests/data/images/dpx/02.dpx
+f7c1f414a5ac67fb46c19094af15d88b *./tests/data/images/dpx/02.dpx
 ./tests/data/images/dpx/%02d.dpx CRC=0x6da01946
 305792 ./tests/data/images/dpx/02.dpx
-7ca935d5d5e00c54acbc85565d3039b6 *./tests/data/images/dpx/02.dpx
+2196b8d0a224177487438da63f5c7f86 *./tests/data/images/dpx/02.dpx
 ./tests/data/images/dpx/%02d.dpx CRC=0xe6663fba
 407168 ./tests/data/images/dpx/02.dpx
-a4cfea1797c928f2eff73573e559675d *./tests/data/images/dpx/02.dpx
+6596e31dca6122759601650d9b9b33b5 *./tests/data/images/dpx/02.dpx
 ./tests/data/images/dpx/%02d.dpx CRC=0x1c755633
 609920 ./tests/data/images/dpx/02.dpx
-075963c3c08978b6a20555ba09161434 *./tests/data/images/dpx/02.dpx
+958042039a25d5cbb9a351503bc57052 *./tests/data/images/dpx/02.dpx
 ./tests/data/images/dpx/%02d.dpx CRC=0xe5b9c023
 609920 ./tests/data/images/dpx/02.dpx
-b9f22728f8ff393bf30cf6cbd624fa95 *./tests/data/images/dpx/02.dpx
+7bf3bf630d5ca27d5703e5dfb5ad217c *./tests/data/images/dpx/02.dpx
 ./tests/data/images/dpx/%02d.dpx CRC=0xf38d5830
 407168 ./tests/data/images/dpx/02.dpx
-545603630f30dec2768c8ae8d12eb8ea *./tests/data/images/dpx/02.dpx
+414c10bfd8c8d14d1ad65ed009755ab0 *./tests/data/images/dpx/02.dpx
 ./tests/data/images/dpx/%02d.dpx CRC=0xe72ce131
 812672 ./tests/data/images/dpx/02.dpx
-- 
2.7.4




More information about the ffmpeg-devel mailing list