From 7d6f72e956e63a0e8c4998c730d67c52e2b69a8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Cerveau?= Date: Mon, 27 Jan 2020 10:12:05 +0100 Subject: [PATCH] video-hdr: add HDR10+ structure Provides structure and GstVideoMeta Part-of: --- gst-libs/gst/video/video-hdr.c | 106 +++++++++++++++++ gst-libs/gst/video/video-hdr.h | 201 +++++++++++++++++++++++++++++++++ 2 files changed, 307 insertions(+) diff --git a/gst-libs/gst/video/video-hdr.c b/gst-libs/gst/video/video-hdr.c index 2f97c5d8a5..bf4cf37601 100644 --- a/gst-libs/gst/video/video-hdr.c +++ b/gst-libs/gst/video/video-hdr.c @@ -390,3 +390,109 @@ gst_video_content_light_level_add_to_caps (const GstVideoContentLightLevel * return TRUE; } + +/* Dynamic HDR Meta implementation */ + +GType +gst_video_hdr_meta_api_get_type (void) +{ + static volatile GType type = 0; + + if (g_once_init_enter (&type)) { + static const gchar *tags[] = { + GST_META_TAG_VIDEO_STR, + NULL + }; + GType _type = gst_meta_api_type_register ("GstVideoHDRMetaAPI", tags); + g_once_init_leave (&type, _type); + } + return type; +} + +static gboolean +gst_video_hdr_meta_transform (GstBuffer * dest, GstMeta * meta, + GstBuffer * buffer, GQuark type, gpointer data) +{ + GstVideoHDRMeta *dmeta, *smeta; + + /* We always copy over the caption meta */ + smeta = (GstVideoHDRMeta *) meta; + + GST_DEBUG ("copy HDR metadata"); + dmeta = + gst_buffer_add_video_hdr_meta (dest, smeta->format, smeta->data, + smeta->size); + if (!dmeta) + return FALSE; + + return TRUE; +} + +static gboolean +gst_video_hdr_meta_init (GstMeta * meta, gpointer params, GstBuffer * buffer) +{ + GstVideoHDRMeta *emeta = (GstVideoHDRMeta *) meta; + + emeta->data = NULL; + + return TRUE; +} + +static void +gst_video_hdr_meta_free (GstMeta * meta, GstBuffer * buffer) +{ + GstVideoHDRMeta *emeta = (GstVideoHDRMeta *) meta; + + g_free (emeta->data); +} + +const GstMetaInfo * +gst_video_hdr_meta_get_info (void) +{ + static const GstMetaInfo *meta_info = NULL; + + if (g_once_init_enter ((GstMetaInfo **) & meta_info)) { + const GstMetaInfo *mi = gst_meta_register (GST_VIDEO_HDR_META_API_TYPE, + "GstVideoHDRMeta", + sizeof (GstVideoHDRMeta), + gst_video_hdr_meta_init, + gst_video_hdr_meta_free, + gst_video_hdr_meta_transform); + g_once_init_leave ((GstMetaInfo **) & meta_info, (GstMetaInfo *) mi); + } + return meta_info; +} + +/** + * gst_buffer_add_video_hdr_meta: + * @buffer: a #GstBuffer + * @format: The type of dynamic HDR contained in the meta. + * @data: contains the dynamic HDR data + * @size: The size in bytes of @data + * + * Attaches #GstVideoHDRMeta metadata to @buffer with the given + * parameters. + * + * Returns: (transfer none): the #GstVideoHDRMeta on @buffer. + * + * Since: 1.20 + */ +GstVideoHDRMeta * +gst_buffer_add_video_hdr_meta (GstBuffer * buffer, + GstVideoHDRFormat format, const guint8 * data, gsize size) +{ + GstVideoHDRMeta *meta; + + g_return_val_if_fail (GST_IS_BUFFER (buffer), NULL); + g_return_val_if_fail (data != NULL, NULL); + + meta = (GstVideoHDRMeta *) gst_buffer_add_meta (buffer, + GST_VIDEO_HDR_META_INFO, NULL); + g_assert (meta != NULL); + + meta->format = format; + meta->data = g_memdup (data, size); + meta->size = size; + + return meta; +} diff --git a/gst-libs/gst/video/video-hdr.h b/gst-libs/gst/video/video-hdr.h index 35765cb809..c5b5fdb95a 100644 --- a/gst-libs/gst/video/video-hdr.h +++ b/gst-libs/gst/video/video-hdr.h @@ -22,12 +22,82 @@ #include #include +#include G_BEGIN_DECLS +/** + * GstVideoHDRFormat: + * @GST_VIDEO_HDR_FORMAT_NONE: No HDR format detected. + * @GST_VIDEO_HDR_FORMAT_HDR10: HDR10 format + * @GST_VIDEO_HDR_FORMAT_HDR10_PLUS: HDR10+ format + * * @GST_VIDEO_HDR_FORMAT_DOLBY_VISION: Dolby Vision format + * + * Enum value describing the most common video for High Dynamic Range (HDR) formats. + * + * Since: 1.20 + */ +typedef enum { + GST_VIDEO_HDR_FORMAT_NONE, + GST_VIDEO_HDR_FORMAT_HDR10, + GST_VIDEO_HDR_FORMAT_HDR10_PLUS, + GST_VIDEO_HDR_FORMAT_DOLBY_VISION, +} GstVideoHDRFormat; + +/* defined in CTA-861-G */ +#define GST_VIDEO_HDR10_PLUS_NUM_WINDOWS 1 /* number of windows, shall be 1. */ +#define GST_VIDEO_HDR10_PLUS_MAX_TSD_APL 25 /* targeted_system_display_actual_peak_luminance max value */ +#define GST_VIDEO_HDR10_PLUS_MAX_MD_APL 25 /* mastering_display_actual_peak_luminance max value */ + typedef struct _GstVideoMasteringDisplayInfoCoordinates GstVideoMasteringDisplayInfoCoordinates; typedef struct _GstVideoMasteringDisplayInfo GstVideoMasteringDisplayInfo; typedef struct _GstVideoContentLightLevel GstVideoContentLightLevel; +typedef struct _GstVideoHDR10Plus GstVideoHDR10Plus; +typedef struct _GstVideoColorVolumeTransformation GstVideoColorVolumeTransformation; + +/** + * GstVideoHDRMeta: + * @meta: parent #GstMeta + * @format: The type of dynamic HDR contained in the meta. + * @data: contains the dynamic HDR data + * @size: The size in bytes of @data + * + * Dynamic HDR data should be included in video user data + * + * Since: 1.20 + */ +typedef struct { + GstMeta meta; + GstVideoHDRFormat format; + guint8 *data; + gsize size; +} GstVideoHDRMeta; + +GST_VIDEO_API +GType gst_video_hdr_meta_api_get_type (void); +#define GST_VIDEO_HDR_META_API_TYPE (gst_video_hdr_meta_api_get_type()) + +GST_VIDEO_API +const GstMetaInfo *gst_video_hdr_meta_get_info (void); +#define GST_VIDEO_HDR_META_INFO (gst_video_hdr_meta_get_info()) + +/** + * gst_buffer_get_video_hdr_meta: + * @b: A #GstBuffer + * + * Gets the #GstVideoHDRMeta that might be present on @b. + * + * Since: 1.20 + * + * Returns: The first #GstVideoHDRMeta present on @b, or %NULL if + * no #GstVideoHDRMeta are present + */ +#define gst_buffer_get_video_hdr_meta(b) \ + ((GstVideoHDRMeta*)gst_buffer_get_meta((b), GST_VIDEO_HDR_META_API_TYPE)) + +GST_VIDEO_API +GstVideoHDRMeta *gst_buffer_add_video_hdr_meta (GstBuffer * buffer, GstVideoHDRFormat format, + const guint8 * data, gsize size); /** * GstVideoMasteringDisplayInfoCoordinates: @@ -133,6 +203,137 @@ GST_VIDEO_API gboolean gst_video_content_light_level_add_to_caps (const GstVideoContentLightLevel * linfo, GstCaps * caps); +/** + * GstVideoColorVolumeTransformation: + * @window_upper_left_corner_x: the x coordinate of the top left pixel of the w-th processing + * @window_upper_left_corner_y: the y coordinate of the top left pixel of the w-th processing + * @window_lower_right_corner_x: the x coordinate of the lower right pixel of the w-th processing + * @window_lower_right_corner_y: the y coordinate of the lower right pixel of the w-th processing + * @center_of_ellipse_x: the x coordinate of the center position of the concentric internal + * and external ellipses of the elliptical pixel selector in the w-th processing window + * @center_of_ellipse_y: the y coordinate of the center position of the concentric internal + * and external ellipses of the elliptical pixel selector in the w-th processing window + * @rotation_angle: the clockwise rotation angle in degree of arc with respect to the + * positive direction of the x-axis of the concentric internal and external ellipses of the elliptical + * pixel selector in the w-th processing window + * @semimajor_axis_internal_ellipse: the semi-major axis value of the internal ellipse of the + * elliptical pixel selector in amount of pixels in the w-th processing window + * @semimajor_axis_external_ellipse: the semi-major axis value of the external ellipse of + * the elliptical pixel selector in amount of pixels in the w-th processing window + * @semiminor_axis_external_ellipse: the semi-minor axis value of the external ellipse of + * the elliptical pixel selector in amount of pixels in the w-th processing window + * @overlap_process_option: one of the two methods of combining + * rendered pixels in the w-th processing window in an image with at least one elliptical pixel + * selector + * @maxscl: the maximum of the i-th color component of linearized RGB values in the + * w-th processing window in the scene + * @average_maxrgb: the average of linearized maxRGB values in the w-th processing + * window in the scene + * @num_distribution_maxrgb_percentiles: the number of linearized maxRGB values at + * given percentiles in the w-th processing window in the scene. Maximum value should be 9. + * @distribution_maxrgb_percentages: an integer percentage value corresponding to the + * i-th percentile linearized RGB value in the w-th processing window in the scene + * @fraction_bright_pixels: the fraction of selected pixels in the image that contains the + * brightest pixel in the scene + * @tone_mapping_flag: true if the tone mapping function in the w-th + * processing window is present + * @knee_point_x: the x coordinate of the separation point between the linear part and the + * curved part of the tone mapping function + * @knee_point_y: the y coordinate of the separation point between the linear part and the + * curved part of the tone mapping function + * @num_bezier_curve_anchors: the number of the intermediate anchor parameters of the + * tone mapping function in the w-th processing window. Maximum value should be 9. + * @bezier_curve_anchors: the i-th intermediate anchor parameter of the tone mapping +function in the w-th processing window in the scene + * @color_saturation_mapping_flag: shall be equal to zero in this version of the standard. + * @color_saturation_weight: a number that shall adjust the color saturation gain in the w- +th processing window in the scene + * + * Processing window in dynamic metadata defined in SMPTE ST 2094-40:2016 + * and CTA-861-G Annex S HDR Dynamic Metadata Syntax Type 4. + * + * Since: 1.20 + */ +struct _GstVideoColorVolumeTransformation +{ + guint16 window_upper_left_corner_x; + guint16 window_upper_left_corner_y; + guint16 window_lower_right_corner_x; + guint16 window_lower_right_corner_y; + guint16 center_of_ellipse_x; + guint16 center_of_ellipse_y; + guint8 rotation_angle; + guint16 semimajor_axis_internal_ellipse; + guint16 semimajor_axis_external_ellipse; + guint16 semiminor_axis_external_ellipse; + guint8 overlap_process_option; + guint32 maxscl[3]; + guint32 average_maxrgb; + guint8 num_distribution_maxrgb_percentiles; + guint8 distribution_maxrgb_percentages[16]; + guint32 distribution_maxrgb_percentiles[16]; + guint16 fraction_bright_pixels; + guint8 tone_mapping_flag; + guint16 knee_point_x; + guint16 knee_point_y; + guint8 num_bezier_curve_anchors; + guint16 bezier_curve_anchors[16]; + guint8 color_saturation_mapping_flag; + guint8 color_saturation_weight; + + /*< private >*/ + guint32 _gst_reserved[GST_PADDING]; +}; + +/** + * GstVideoHDR10Plus: + * @application_identifier: the application identifier + * @application_version: the application version + * @num_windows: the number of processing windows. The first processing window shall be + * for the entire picture + * @processing_window: the color volume transformation for the processing window. + * @targeted_system_display_maximum_luminance: the nominal maximum display luminance + * of the targeted system display in units of 0.0001 candelas per square meter + * @targeted_system_display_actual_peak_luminance_flag: shall be equal to zero in this + * version of the standard + * @num_rows_targeted_system_display_actual_peak_luminance: the number of rows + * in the targeted_system_display_actual_peak_luminance array + * @num_cols_targeted_system_display_actual_peak_luminance: the number of columns in the + * targeted_system_display_actual_peak_luminance array + * @targeted_system_display_actual_peak_luminance: the normalized actual peak luminance of + * the targeted system display + * @mastering_display_actual_peak_luminance_flag: shall be equal to 0 for this version of this Standard + * @num_rows_mastering_display_actual_peak_luminance: the number of rows in the + * mastering_display_actual_peak_luminance array + * @num_cols_mastering_display_actual_peak_luminance: the number of columns in the + * mastering_display_actual_peak_luminance array. + * @mastering_display_actual_peak_luminance: the normalized actual peak luminance of + * the mastering display used for mastering the image essence + * + * Dynamic HDR 10+ metadata defined in SMPTE2094-40 + * and CTA-861-G Annex S HDR Dynamic Metadata Syntax Type 4. + * + * Since: 1.20 + */ +struct _GstVideoHDR10Plus +{ + guint8 application_identifier; + guint8 application_version; + guint8 num_windows; + GstVideoColorVolumeTransformation processing_window[GST_VIDEO_HDR10_PLUS_NUM_WINDOWS]; + guint32 targeted_system_display_maximum_luminance; + guint8 targeted_system_display_actual_peak_luminance_flag; + guint8 num_rows_targeted_system_display_actual_peak_luminance; + guint8 num_cols_targeted_system_display_actual_peak_luminance; + guint8 targeted_system_display_actual_peak_luminance[GST_VIDEO_HDR10_PLUS_MAX_TSD_APL][GST_VIDEO_HDR10_PLUS_MAX_TSD_APL]; + guint8 mastering_display_actual_peak_luminance_flag; + guint8 num_rows_mastering_display_actual_peak_luminance; + guint8 num_cols_mastering_display_actual_peak_luminance; + guint8 mastering_display_actual_peak_luminance[GST_VIDEO_HDR10_PLUS_MAX_MD_APL][GST_VIDEO_HDR10_PLUS_MAX_MD_APL]; + + /*< private >*/ + gpointer _gst_reserved[GST_PADDING]; +}; G_END_DECLS