Michael, wm4, Thank you for your feedback, I believe I've addressed your concerns, please let me know if there is anything else that needs fixing.
Kevin
From 079ff77a1885b5ef879a8cd3b4c032a3182e8e67 Mon Sep 17 00:00:00 2001 From: Kevin Wheatley <kevin.j.wheat...@gmail.com> Date: Thu, 5 Mar 2015 10:37:51 +0000 Subject: [PATCH 1/2] Extract gamma determination from PNG encoder for future use. Adds private avpriv_get_gamma_from_trc() function to libavutil. Signed-off-by: Kevin Wheatley <kevin.j.wheat...@gmail.com> --- libavcodec/pngenc.c | 29 +++---------------------- libavutil/Makefile | 1 + libavutil/color_utils.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++ libavutil/color_utils.h | 39 +++++++++++++++++++++++++++++++++++ libavutil/version.h | 2 +- 5 files changed, 97 insertions(+), 26 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 6c9f43e..9bdefc4 100644 --- a/libavcodec/pngenc.c +++ b/libavcodec/pngenc.c @@ -28,6 +28,7 @@ #include "libavutil/avassert.h" #include "libavutil/libm.h" #include "libavutil/opt.h" +#include "libavutil/color_utils.h" #include <zlib.h> @@ -277,31 +278,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 = avpriv_get_gamma_from_trc(trc); + if (gamma <= 1e-6) + return 0; AV_WB32_PNG(buf, 1.0 / gamma); return 1; diff --git a/libavutil/Makefile b/libavutil/Makefile index 6caf896..df85cd1 100644 --- a/libavutil/Makefile +++ b/libavutil/Makefile @@ -88,6 +88,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..59146be --- /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 avpriv_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; // Unknown value representation + } + return gamma; +} diff --git a/libavutil/color_utils.h b/libavutil/color_utils.h new file mode 100644 index 0000000..3600a72 --- /dev/null +++ b/libavutil/color_utils.h @@ -0,0 +1,39 @@ +/* + * 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" + +/** + * Determine a suitable 'gamma' value to match the supplied + * AVColorTransferCharacteristic. + * + * See Apple Technical Note TN2257 (https://developer.apple.com/library/mac/technotes/tn2257/_index.html) + * + * @return Will return an approximation to the simple gamma function matching + * the supplied Transfer Characteristic, Will return 0.0 for any + * we cannot reasonably match against. + */ +double avpriv_get_gamma_from_trc(enum AVColorTransferCharacteristic trc); + +#endif diff --git a/libavutil/version.h b/libavutil/version.h index 355eef3..5d43308 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -56,7 +56,7 @@ */ #define LIBAVUTIL_VERSION_MAJOR 54 -#define LIBAVUTIL_VERSION_MINOR 19 +#define LIBAVUTIL_VERSION_MINOR 20 #define LIBAVUTIL_VERSION_MICRO 100 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ -- 1.7.1
From 303afbeefe589df807aebfe4033d96c054736db6 Mon Sep 17 00:00:00 2001 From: Kevin Wheatley <kevin.j.wheat...@gmail.com> Date: Thu, 5 Mar 2015 10:40:13 +0000 Subject: [PATCH 2/2] Add support for writing 'gama' atom to QuickTime .mov files. As this is depricated it should not be on by default, it is only supported for MOV containers, depends on avpriv_get_gamma_from_trc() Enable by: -movflags +write_gama This will use the color_trc to supply a gamma value, if desired an explicit value may be supplied using the -mov_gamma option supplying a suitable floating point value, values <=1e-6 will not be written. Signed-off-by: Kevin Wheatley <kevin.j.wheat...@gmail.com> --- libavformat/movenc.c | 35 +++++++++++++++++++++++++++++++++++ libavformat/movenc.h | 2 ++ 2 files changed, 37 insertions(+), 0 deletions(-) diff --git a/libavformat/movenc.c b/libavformat/movenc.c index f883013..edaf118 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -40,10 +40,12 @@ #include "libavutil/avstring.h" #include "libavutil/intfloat.h" #include "libavutil/mathematics.h" +#include "libavutil/libm.h" #include "libavutil/opt.h" #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 +67,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 (Experimental, may be renamed or changed, do not use from scripts)", 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 +80,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 +1523,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 = avpriv_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)lrint((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 +1729,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); -- 1.7.1
_______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel