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