Please see updated patch. On Mon, Jan 25, 2016 at 11:39 PM, Neil Birkbeck <neil.birkb...@gmail.com> wrote: > I guess png is another example; 100000 is the denominator for the 32-bit > integer: > https://github.com/FFmpeg/FFmpeg/blob/b58cfa616c169c90166938608e7135cdab5820e0/libavcodec/pngenc.c#L290 > > In the standards, the primaries and white point coords are usually only > referenced in 2-4 significant figures (ISO/IEC 23001-8:2013(E) has them all > in one doc). The display primaries can be different from these, but I don't > think you'd see them measured with any more precision (more precision is > unlikely to matter for this metadata anyway). > > It seems that most are in favor of AVRational, so I'll change the avutil > struct float internal fields to rational. > > > > > > On Mon, Jan 25, 2016 at 1:43 PM, Hendrik Leppkes <h.lepp...@gmail.com> > wrote: >> >> On Mon, Jan 25, 2016 at 10:37 PM, Michael Niedermayer >> <mich...@niedermayer.cc> wrote: >> > On Fri, Jan 22, 2016 at 02:54:21PM -0800, Neil Birkbeck wrote: >> >> Hmm. I don't have a good idea of how likely it is for this conversion >> >> to >> >> float (by dividing a constant) to not be bit-exact on different >> >> architectures (compilers?) when there should not be any other math >> >> transforming the metadata (other than the conversion back to the >> >> integer >> >> coding for cases like hevc, which for a given architecture is possible >> >> without loss). The fact that this could happen at all does make it >> >> annoying >> >> in terms of bit-exact test expectations across arch, and this is the >> >> main >> >> concern, right? (for this type of metadata, it is really a hint to >> >> TVs/algorithms, and some will ignore it altogether) >> > >> > bitexactness is one concern, also theres the issue with what is ideally >> > correct. >> > that is what are the ideal values dictated by various standards >> > that hardware (cammeras, ...) aim at ? >> > are these rational or float or what can represent them better ? >> > >> >> Both HEVC and the HDMI Info Frames use fixed-point integers (the same >> scales too, apparently), I do not know of the formats anything else >> uses. >> Maybe we should be using AVRationals? >> >> I would argue that MKV storing floats is a terrible idea, and someone >> should bonk them over the head and store fixed point as well. >> >> - Hendrik >> _______________________________________________ >> ffmpeg-devel mailing list >> ffmpeg-devel@ffmpeg.org >> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel > >
From 345db2caf7cac5c0acfb74501b6db9bd57e66f7d Mon Sep 17 00:00:00 2001 From: Neil Birkbeck <neil.birkb...@gmail.com> Date: Thu, 21 Jan 2016 10:56:50 -0800 Subject: [PATCH] lavc/hevc Parse SEI_TYPE_MASTERING_DISPLAY_INFO and propagate content into the AVMasteringDisplayMetadata side data.
Add support for parsing SEI_TYPE_MASTERING_DISPLAY_INFO and propagate contents into the AVMasteringDisplayMetadata side data. Primaries are ordered in RGB order and the values are converted to rationals ([0,1] for CEI 1931 Chroma coords, and cd/m^2 for luma). Signed-off-by: Neil Birkbeck <neil.birkb...@gmail.com> --- libavcodec/hevc.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ libavcodec/hevc.h | 7 +++++++ libavcodec/hevc_sei.c | 22 ++++++++++++++++++++++ libavcodec/version.h | 2 +- 4 files changed, 76 insertions(+), 1 deletion(-) diff --git a/libavcodec/hevc.c b/libavcodec/hevc.c index c245d3b..e475f94 100644 --- a/libavcodec/hevc.c +++ b/libavcodec/hevc.c @@ -28,6 +28,7 @@ #include "libavutil/common.h" #include "libavutil/display.h" #include "libavutil/internal.h" +#include "libavutil/mastering_display_metadata.h" #include "libavutil/md5.h" #include "libavutil/opt.h" #include "libavutil/pixdesc.h" @@ -2580,6 +2581,51 @@ static int set_side_data(HEVCContext *s) s->sei_hflip, s->sei_vflip); } + if (s->sei_mastering_display_info_present) { + // HEVC uses a g,b,r ordering, which we convert to a more natural r,g,b + const int mapping[3] = {2, 0, 1}; + const int chroma_den = 50000; + const int luma_den = 10000; + int i; + AVMasteringDisplayMetadata *metadata = + av_mastering_display_metadata_create_side_data(out); + if (!metadata) + return AVERROR(ENOMEM); + + for (i = 0; i < 3; i++) { + const int j = mapping[i]; + metadata->display_primaries[i][0].num = s->display_primaries[j][0]; + metadata->display_primaries[i][0].den = chroma_den; + metadata->display_primaries[i][1].num = s->display_primaries[j][1]; + metadata->display_primaries[i][1].den = chroma_den; + } + metadata->white_point[0].num = s->white_point[0]; + metadata->white_point[0].den = chroma_den; + metadata->white_point[1].num = s->white_point[1]; + metadata->white_point[1].den = chroma_den; + + metadata->max_luminance.num = s->max_mastering_luminance; + metadata->max_luminance.den = luma_den; + metadata->min_luminance.num = s->min_mastering_luminance; + metadata->min_luminance.den = luma_den; + metadata->has_luminance = 1; + metadata->has_primaries = 1; + + av_log(s->avctx, AV_LOG_DEBUG, "Mastering Display Metadata:\n"); + av_log(s->avctx, AV_LOG_DEBUG, + "r(%5.4f,%5.4f) g(%5.4f,%5.4f) b(%5.4f %5.4f) wp(%5.4f, %5.4f)\n", + av_q2d(metadata->display_primaries[0][0]), + av_q2d(metadata->display_primaries[0][1]), + av_q2d(metadata->display_primaries[1][0]), + av_q2d(metadata->display_primaries[1][1]), + av_q2d(metadata->display_primaries[2][0]), + av_q2d(metadata->display_primaries[2][1]), + av_q2d(metadata->white_point[0]), av_q2d(metadata->white_point[1])); + av_log(s->avctx, AV_LOG_DEBUG, + "min_luminance=%f, max_luminance=%f\n", + av_q2d(metadata->min_luminance), av_q2d(metadata->max_luminance)); + } + if (s->a53_caption) { AVFrameSideData* sd = av_frame_new_side_data(out, AV_FRAME_DATA_A53_CC, diff --git a/libavcodec/hevc.h b/libavcodec/hevc.h index 9d72555..c91f815 100644 --- a/libavcodec/hevc.h +++ b/libavcodec/hevc.h @@ -941,6 +941,13 @@ typedef struct HEVCContext { uint8_t* a53_caption; int a53_caption_size; + /** mastering display */ + int sei_mastering_display_info_present; + uint16_t display_primaries[3][2]; + uint16_t white_point[2]; + uint32_t max_mastering_luminance; + uint32_t min_mastering_luminance; + } HEVCContext; int ff_hevc_decode_short_term_rps(GetBitContext *gb, AVCodecContext *avctx, diff --git a/libavcodec/hevc_sei.c b/libavcodec/hevc_sei.c index 07856f2..d33530b 100644 --- a/libavcodec/hevc_sei.c +++ b/libavcodec/hevc_sei.c @@ -78,6 +78,26 @@ static int decode_nal_sei_decoded_picture_hash(HEVCContext *s) return 0; } +static int decode_nal_sei_mastering_display_info(HEVCContext *s) +{ + GetBitContext *gb = &s->HEVClc->gb; + int i; + // Mastering primaries + for (i = 0; i < 3; i++) { + s->display_primaries[i][0] = get_bits(gb, 16); + s->display_primaries[i][1] = get_bits(gb, 16); + } + // White point (x, y) + s->white_point[0] = get_bits(gb, 16); + s->white_point[1] = get_bits(gb, 16); + + // Max and min luminance of mastering display + s->max_mastering_luminance = get_bits_long(gb, 32); + s->min_mastering_luminance = get_bits_long(gb, 32); + s->sei_mastering_display_info_present = 1; + return 0; +} + static int decode_nal_sei_frame_packing_arrangement(HEVCContext *s) { GetBitContext *gb = &s->HEVClc->gb; @@ -278,6 +298,8 @@ static int decode_nal_sei_prefix(HEVCContext *s, int type, int size) skip_bits(gb, 8 * size); return ret; } + case SEI_TYPE_MASTERING_DISPLAY_INFO: + return decode_nal_sei_mastering_display_info(s); case SEI_TYPE_ACTIVE_PARAMETER_SETS: active_parameter_sets(s); av_log(s->avctx, AV_LOG_DEBUG, "Skipped PREFIX SEI %d\n", type); diff --git a/libavcodec/version.h b/libavcodec/version.h index 02063c8..37a35e0 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -30,7 +30,7 @@ #define LIBAVCODEC_VERSION_MAJOR 57 #define LIBAVCODEC_VERSION_MINOR 24 -#define LIBAVCODEC_VERSION_MICRO 101 +#define LIBAVCODEC_VERSION_MICRO 102 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ LIBAVCODEC_VERSION_MINOR, \ -- 2.7.0.rc3.207.g0ac5344
_______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel