Something like this - note this adds no tests, but fate still passes for me.

Kevin
From db02ae26c3c4278da4ed328e767bab98271da51e Mon Sep 17 00:00:00 2001
From: Kevin Wheatley <kevin.j.wheat...@gmail.com>
Date: Mon, 2 Mar 2015 12:50:53 +0000
Subject: [PATCH] Add 'gama' atom for .mov only, reuses pngenc.c gamma values by sharing
 function in new color_utils.[ch] file.


Signed-off-by: Kevin Wheatley <kevin.j.wheat...@gmail.com>
---
 libavcodec/pngenc.c     |   29 +++----------------------
 libavformat/movenc.c    |   34 ++++++++++++++++++++++++++++++
 libavformat/movenc.h    |    2 +
 libavutil/Makefile      |    2 +
 libavutil/color_utils.c |   52 +++++++++++++++++++++++++++++++++++++++++++++++
 libavutil/color_utils.h |   29 ++++++++++++++++++++++++++
 6 files changed, 123 insertions(+), 25 deletions(-)
 create mode 100644 libavutil/color_utils.c
 create mode 100644 libavutil/color_utils.h

diff --git a/libavcodec/pngenc.c b/libavcodec/pngenc.c
index 9fd8eef..db849fb 100644
--- a/libavcodec/pngenc.c
+++ b/libavcodec/pngenc.c
@@ -27,6 +27,7 @@
 
 #include "libavutil/avassert.h"
 #include "libavutil/opt.h"
+#include "libavutil/color_utils.h"
 
 #include <zlib.h>
 
@@ -276,31 +277,9 @@ static int png_get_chrm(enum AVColorPrimaries prim,  uint8_t *buf)
 
 static int png_get_gama(enum AVColorTransferCharacteristic trc, uint8_t *buf)
 {
-    double gamma;
-    switch (trc) {
-        case AVCOL_TRC_BT709:
-        case AVCOL_TRC_SMPTE170M:
-        case AVCOL_TRC_SMPTE240M:
-        case AVCOL_TRC_BT1361_ECG:
-        case AVCOL_TRC_BT2020_10:
-        case AVCOL_TRC_BT2020_12:
-            /* these share a segmented TRC, but gamma 1.961 is a close
-              approximation, and also more correct for decoding content */
-            gamma = 1.961;
-            break;
-        case AVCOL_TRC_GAMMA22:
-        case AVCOL_TRC_IEC61966_2_1:
-            gamma = 2.2;
-            break;
-        case AVCOL_TRC_GAMMA28:
-            gamma = 2.8;
-            break;
-        case AVCOL_TRC_LINEAR:
-            gamma = 1.0;
-            break;
-        default:
-            return 0;
-    }
+    double gamma = get_gamma_from_trc(trc);
+    if (gamma <= 1e-6)
+        return 0;
 
     AV_WB32_PNG(buf, 1.0 / gamma);
     return 1;
diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index e496ba4..05516a8 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -44,6 +44,7 @@
 #include "libavutil/dict.h"
 #include "libavutil/pixdesc.h"
 #include "libavutil/timecode.h"
+#include "libavutil/color_utils.h"
 #include "hevc.h"
 #include "rtpenc.h"
 #include "mov_chan.h"
@@ -65,6 +66,7 @@ static const AVOption options[] = {
     { "frag_discont", "Signal that the next fragment is discontinuous from earlier ones", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_FRAG_DISCONT}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
     { "delay_moov", "Delay writing the initial moov until the first fragment is cut, or until the first fragment flush", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_DELAY_MOOV}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
     { "write_colr", "Write colr atom", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_WRITE_COLR}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
+    { "write_gama", "Write deprecated gama atom", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_WRITE_GAMA}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
     FF_RTP_FLAG_OPTS(MOVMuxContext, rtp_flags),
     { "skip_iods", "Skip writing iods atom.", offsetof(MOVMuxContext, iods_skip), AV_OPT_TYPE_INT, {.i64 = 1}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM},
     { "iods_audio_profile", "iods audio profile atom.", offsetof(MOVMuxContext, iods_audio_profile), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 255, AV_OPT_FLAG_ENCODING_PARAM},
@@ -77,6 +79,7 @@ static const AVOption options[] = {
     { "brand",    "Override major brand", offsetof(MOVMuxContext, major_brand),   AV_OPT_TYPE_STRING, {.str = NULL}, .flags = AV_OPT_FLAG_ENCODING_PARAM },
     { "use_editlist", "use edit list", offsetof(MOVMuxContext, use_editlist), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 1, AV_OPT_FLAG_ENCODING_PARAM},
     { "fragment_index", "Fragment number of the next fragment", offsetof(MOVMuxContext, fragments), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
+    { "mov_gamma", "gamma value for gama atom", offsetof(MOVMuxContext, gamma), AV_OPT_TYPE_FLOAT, {.dbl = 0.0 }, 0.0, 10, AV_OPT_FLAG_ENCODING_PARAM},
     { NULL },
 };
 
@@ -1519,6 +1522,31 @@ static int mov_write_pasp_tag(AVIOContext *pb, MOVTrack *track)
     return 16;
 }
 
+static int mov_write_gama_tag(AVIOContext *pb, MOVTrack *track, double gamma)
+{
+    uint32_t gama = 0;
+    if (gamma <= 0.0)
+    {
+        gamma = get_gamma_from_trc(track->enc->color_trc);
+    }
+    av_log(pb, AV_LOG_DEBUG, "gamma value %g\n", gamma);
+
+    if (gamma > 1e-6) {
+        gama = (uint32_t)round((double)(1<<16) * gamma);
+        av_log(pb, AV_LOG_DEBUG, "writing gama value %d\n", gama);
+        
+        av_assert0(track->mode == MODE_MOV);
+        avio_wb32(pb, 12);
+        ffio_wfourcc(pb, "gama");
+        avio_wb32(pb, gama);
+        return 12;
+    }
+    else {
+        av_log(pb, AV_LOG_WARNING, "gamma value unknown, unable to write gama atom\n");
+    }
+    return 0;
+}
+
 static int mov_write_colr_tag(AVIOContext *pb, MOVTrack *track)
 {
     // Ref (MOV): https://developer.apple.com/library/mac/technotes/tn2162/_index.html#//apple_ref/doc/uid/DTS40013070-CH1-TNTAG9
@@ -1700,6 +1728,12 @@ static int mov_write_video_tag(AVIOContext *pb, MOVMuxContext *mov, MOVTrack *tr
         if (track->enc->field_order != AV_FIELD_UNKNOWN)
             mov_write_fiel_tag(pb, track);
 
+    if (mov->flags & FF_MOV_FLAG_WRITE_GAMA) {
+        if (track->mode == MODE_MOV)
+            mov_write_gama_tag(pb, track, mov->gamma);
+        else
+            av_log(mov->fc, AV_LOG_WARNING, "Not writing 'gama' atom. Format is not MOV.\n");
+    }
     if (mov->flags & FF_MOV_FLAG_WRITE_COLR) {
         if (track->mode == MODE_MOV || track->mode == MODE_MP4)
             mov_write_colr_tag(pb, track);
diff --git a/libavformat/movenc.h b/libavformat/movenc.h
index 3a72937..21d0ee7 100644
--- a/libavformat/movenc.h
+++ b/libavformat/movenc.h
@@ -185,6 +185,7 @@ typedef struct MOVMuxContext {
     AVFormatContext *fc;
 
     int use_editlist;
+    float gamma;
 } MOVMuxContext;
 
 #define FF_MOV_FLAG_RTP_HINT              (1 <<  0)
@@ -202,6 +203,7 @@ typedef struct MOVMuxContext {
 #define FF_MOV_FLAG_FRAG_DISCONT          (1 << 12)
 #define FF_MOV_FLAG_DELAY_MOOV            (1 << 13)
 #define FF_MOV_FLAG_WRITE_COLR            (1 << 14)
+#define FF_MOV_FLAG_WRITE_GAMA            (1 << 15)
 
 int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt);
 
diff --git a/libavutil/Makefile b/libavutil/Makefile
index 6caf896..ca20539 100644
--- a/libavutil/Makefile
+++ b/libavutil/Makefile
@@ -18,6 +18,7 @@ HEADERS = adler32.h                                                     \
           cast5.h                                                       \
           camellia.h                                                    \
           channel_layout.h                                              \
+          color_utils.h                                                 \
           common.h                                                      \
           cpu.h                                                         \
           crc.h                                                         \
@@ -88,6 +89,7 @@ OBJS = adler32.o                                                        \
        cast5.o                                                          \
        camellia.o                                                       \
        channel_layout.o                                                 \
+       color_utils.o                                                    \
        cpu.o                                                            \
        crc.o                                                            \
        des.o                                                            \
diff --git a/libavutil/color_utils.c b/libavutil/color_utils.c
new file mode 100644
index 0000000..a4d75a5
--- /dev/null
+++ b/libavutil/color_utils.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2015 Kevin Wheatley <kevin.j.wheat...@gmail.com>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libavutil/color_utils.h"
+#include "libavutil/pixfmt.h"
+
+double get_gamma_from_trc(enum AVColorTransferCharacteristic trc)
+{
+    double gamma;
+    switch (trc) {
+        case AVCOL_TRC_BT709:
+        case AVCOL_TRC_SMPTE170M:
+        case AVCOL_TRC_SMPTE240M:
+        case AVCOL_TRC_BT1361_ECG:
+        case AVCOL_TRC_BT2020_10:
+        case AVCOL_TRC_BT2020_12:
+            /* these share a segmented TRC, but gamma 1.961 is a close
+              approximation, and also more correct for decoding content */
+            gamma = 1.961;
+            break;
+        case AVCOL_TRC_GAMMA22:
+        case AVCOL_TRC_IEC61966_2_1:
+            gamma = 2.2;
+            break;
+        case AVCOL_TRC_GAMMA28:
+            gamma = 2.8;
+            break;
+        case AVCOL_TRC_LINEAR:
+            gamma = 1.0;
+            break;
+        default:
+            gamma = 0.0;
+    }
+    return gamma;
+}
diff --git a/libavutil/color_utils.h b/libavutil/color_utils.h
new file mode 100644
index 0000000..f70d906
--- /dev/null
+++ b/libavutil/color_utils.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2015 Kevin Wheatley <kevin.j.wheat...@gmail.com>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVUTIL_COLOR_UTILS_H
+#define AVUTIL_COLOR_UTILS_H
+
+
+#include "libavutil/pixfmt.h"
+
+double get_gamma_from_trc(enum AVColorTransferCharacteristic trc);
+
+#endif
-- 
1.7.1

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel

Reply via email to