On Tue, 3 Mar 2015 11:10:54 +0000 Kevin Wheatley <kevin.j.wheat...@gmail.com> wrote:
> From 794c8c3cf1e8506393fbcb4ddf1360042b0fc82f 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. > > Use lrint() instead of round() > > Signed-off-by: Kevin Wheatley <kevin.j.wheat...@gmail.com> > --- > libavcodec/pngenc.c | 29 +++---------------------- > libavformat/movenc.c | 35 +++++++++++++++++++++++++++++++ > libavformat/movenc.h | 2 + > libavutil/Makefile | 2 + > libavutil/color_utils.c | 52 > +++++++++++++++++++++++++++++++++++++++++++++++ > libavutil/color_utils.h | 29 ++++++++++++++++++++++++++ > 6 files changed, 124 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 4e67ce2..fddcca4 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 = 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..7c10d0e 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", 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 = 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); > > 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 \ IMO this header shouldn't be public, at least not yet. And I think adding them to HEADERS will install the header. (Not sure about how this works.) > 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) Public API functions must start with "av_". API functions which are private to FFmpeg, but are used across the sub-libs (e.g. libavcodec using a private libavutil function) must start with "avpriv_". > +{ > + 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; Is this really a sane default? Or is it some placeholder value (i.e. "not valid")? > + } > + 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); Lacks doxygen documentation. > + > +#endif _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel