mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 04:46:13 +00:00
h265parse: add support for SEI registered user data
This commit is contained in:
parent
b7558bd190
commit
40212aaf00
4 changed files with 125 additions and 1 deletions
|
@ -1132,6 +1132,53 @@ error:
|
||||||
return GST_H265_PARSER_ERROR;
|
return GST_H265_PARSER_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static GstH265ParserResult
|
||||||
|
gst_h265_parser_parse_registered_user_data (GstH265Parser * parser,
|
||||||
|
GstH265RegisteredUserData * rud, NalReader * nr, guint payload_size)
|
||||||
|
{
|
||||||
|
guint8 *data = NULL;
|
||||||
|
guint i;
|
||||||
|
|
||||||
|
rud->data = NULL;
|
||||||
|
rud->size = 0;
|
||||||
|
|
||||||
|
if (payload_size < 2)
|
||||||
|
return GST_H265_PARSER_ERROR;
|
||||||
|
|
||||||
|
READ_UINT8 (nr, rud->country_code, 8);
|
||||||
|
--payload_size;
|
||||||
|
|
||||||
|
if (rud->country_code == 0xFF) {
|
||||||
|
READ_UINT8 (nr, rud->country_code_extension, 8);
|
||||||
|
--payload_size;
|
||||||
|
} else {
|
||||||
|
rud->country_code_extension = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (payload_size < 8)
|
||||||
|
return GST_H265_PARSER_ERROR;
|
||||||
|
|
||||||
|
data = g_malloc (payload_size);
|
||||||
|
for (i = 0; i < payload_size / 8; ++i) {
|
||||||
|
READ_UINT8 (nr, data[i], 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_MEMDUMP ("SEI user data", data, payload_size / 8);
|
||||||
|
|
||||||
|
rud->data = data;
|
||||||
|
rud->size = payload_size;
|
||||||
|
return GST_H265_PARSER_OK;
|
||||||
|
|
||||||
|
error:
|
||||||
|
{
|
||||||
|
GST_WARNING ("error parsing \"Registered User Data\"");
|
||||||
|
g_free (data);
|
||||||
|
return GST_H265_PARSER_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static GstH265ParserResult
|
static GstH265ParserResult
|
||||||
gst_h265_parser_parse_time_code (GstH265Parser * parser,
|
gst_h265_parser_parse_time_code (GstH265Parser * parser,
|
||||||
GstH265TimeCode * tc, NalReader * nr)
|
GstH265TimeCode * tc, NalReader * nr)
|
||||||
|
@ -2472,6 +2519,10 @@ gst_h265_parser_parse_sei_message (GstH265Parser * parser,
|
||||||
res = gst_h265_parser_parse_pic_timing (parser,
|
res = gst_h265_parser_parse_pic_timing (parser,
|
||||||
&sei->payload.pic_timing, nr);
|
&sei->payload.pic_timing, nr);
|
||||||
break;
|
break;
|
||||||
|
case GST_H265_SEI_REGISTERED_USER_DATA:
|
||||||
|
res = gst_h265_parser_parse_registered_user_data (parser,
|
||||||
|
&sei->payload.registered_user_data, nr, payloadSizeBytes);
|
||||||
|
break;
|
||||||
case GST_H265_SEI_RECOVERY_POINT:
|
case GST_H265_SEI_RECOVERY_POINT:
|
||||||
res = gst_h265_parser_parse_recovery_point (parser,
|
res = gst_h265_parser_parse_recovery_point (parser,
|
||||||
&sei->payload.recovery_point, nr);
|
&sei->payload.recovery_point, nr);
|
||||||
|
|
|
@ -271,6 +271,7 @@ typedef enum
|
||||||
* GstH265SEIPayloadType:
|
* GstH265SEIPayloadType:
|
||||||
* @GST_H265_SEI_BUF_PERIOD: Buffering Period SEI Message
|
* @GST_H265_SEI_BUF_PERIOD: Buffering Period SEI Message
|
||||||
* @GST_H265_SEI_PIC_TIMING: Picture Timing SEI Message
|
* @GST_H265_SEI_PIC_TIMING: Picture Timing SEI Message
|
||||||
|
* @GST_H265_SEI_REGISTERED_USER_DATA: Registered user data (D.2.5)
|
||||||
* @GST_H265_SEI_RECOVERY_POINT: Recovery Point SEI Message (D.3.8)
|
* @GST_H265_SEI_RECOVERY_POINT: Recovery Point SEI Message (D.3.8)
|
||||||
* @GST_H265_SEI_TIME_CODE: Time code SEI message (D.2.27) (Since: 1.16)
|
* @GST_H265_SEI_TIME_CODE: Time code SEI message (D.2.27) (Since: 1.16)
|
||||||
* @GST_H265_SEI_MASTERING_DISPLAY_COLOUR_VOLUME: Mastering display colour volume information SEI message (D.2.28) (Since: 1.18)
|
* @GST_H265_SEI_MASTERING_DISPLAY_COLOUR_VOLUME: Mastering display colour volume information SEI message (D.2.28) (Since: 1.18)
|
||||||
|
@ -283,6 +284,7 @@ typedef enum
|
||||||
{
|
{
|
||||||
GST_H265_SEI_BUF_PERIOD = 0,
|
GST_H265_SEI_BUF_PERIOD = 0,
|
||||||
GST_H265_SEI_PIC_TIMING = 1,
|
GST_H265_SEI_PIC_TIMING = 1,
|
||||||
|
GST_H265_SEI_REGISTERED_USER_DATA = 4,
|
||||||
GST_H265_SEI_RECOVERY_POINT = 6,
|
GST_H265_SEI_RECOVERY_POINT = 6,
|
||||||
GST_H265_SEI_TIME_CODE = 136,
|
GST_H265_SEI_TIME_CODE = 136,
|
||||||
GST_H265_SEI_MASTERING_DISPLAY_COLOUR_VOLUME = 137,
|
GST_H265_SEI_MASTERING_DISPLAY_COLOUR_VOLUME = 137,
|
||||||
|
@ -373,6 +375,7 @@ typedef struct _GstH265ShortTermRefPicSet GstH265ShortTermRefPicSet;
|
||||||
typedef struct _GstH265SliceHdr GstH265SliceHdr;
|
typedef struct _GstH265SliceHdr GstH265SliceHdr;
|
||||||
|
|
||||||
typedef struct _GstH265PicTiming GstH265PicTiming;
|
typedef struct _GstH265PicTiming GstH265PicTiming;
|
||||||
|
typedef struct _GstH265RegisteredUserData GstH265RegisteredUserData;
|
||||||
typedef struct _GstH265BufferingPeriod GstH265BufferingPeriod;
|
typedef struct _GstH265BufferingPeriod GstH265BufferingPeriod;
|
||||||
typedef struct _GstH265RecoveryPoint GstH265RecoveryPoint;
|
typedef struct _GstH265RecoveryPoint GstH265RecoveryPoint;
|
||||||
typedef struct _GstH265TimeCode GstH265TimeCode;
|
typedef struct _GstH265TimeCode GstH265TimeCode;
|
||||||
|
@ -1226,6 +1229,15 @@ struct _GstH265RecoveryPoint
|
||||||
guint8 broken_link_flag;
|
guint8 broken_link_flag;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct _GstH265RegisteredUserData
|
||||||
|
{
|
||||||
|
guint8 country_code;
|
||||||
|
guint8 country_code_extension;
|
||||||
|
const guint8 *data;
|
||||||
|
guint size;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GstH265TimeCode:
|
* GstH265TimeCode:
|
||||||
* The time code SEI message provides time code information similar to that
|
* The time code SEI message provides time code information similar to that
|
||||||
|
@ -1297,6 +1309,7 @@ struct _GstH265SEIMessage
|
||||||
union {
|
union {
|
||||||
GstH265BufferingPeriod buffering_period;
|
GstH265BufferingPeriod buffering_period;
|
||||||
GstH265PicTiming pic_timing;
|
GstH265PicTiming pic_timing;
|
||||||
|
GstH265RegisteredUserData registered_user_data;
|
||||||
GstH265RecoveryPoint recovery_point;
|
GstH265RecoveryPoint recovery_point;
|
||||||
GstH265TimeCode time_code;
|
GstH265TimeCode time_code;
|
||||||
GstH265MasteringDisplayColourVolume mastering_display_colour_volume;
|
GstH265MasteringDisplayColourVolume mastering_display_colour_volume;
|
||||||
|
|
|
@ -114,6 +114,9 @@ static GstCaps *gst_h265_parse_get_caps (GstBaseParse * parse,
|
||||||
static gboolean gst_h265_parse_event (GstBaseParse * parse, GstEvent * event);
|
static gboolean gst_h265_parse_event (GstBaseParse * parse, GstEvent * event);
|
||||||
static gboolean gst_h265_parse_src_event (GstBaseParse * parse,
|
static gboolean gst_h265_parse_src_event (GstBaseParse * parse,
|
||||||
GstEvent * event);
|
GstEvent * event);
|
||||||
|
static void
|
||||||
|
gst_h265_parse_process_sei_user_data (GstH265Parse * h265parse,
|
||||||
|
GstH265RegisteredUserData * rud);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_h265_parse_class_init (GstH265ParseClass * klass)
|
gst_h265_parse_class_init (GstH265ParseClass * klass)
|
||||||
|
@ -570,6 +573,10 @@ gst_h265_parse_process_sei (GstH265Parse * h265parse, GstH265NalUnit * nalu)
|
||||||
case GST_H265_SEI_PIC_TIMING:
|
case GST_H265_SEI_PIC_TIMING:
|
||||||
h265parse->sei_pic_struct = sei.payload.pic_timing.pic_struct;
|
h265parse->sei_pic_struct = sei.payload.pic_timing.pic_struct;
|
||||||
break;
|
break;
|
||||||
|
case GST_H265_SEI_REGISTERED_USER_DATA:
|
||||||
|
gst_h265_parse_process_sei_user_data (h265parse,
|
||||||
|
&sei.payload.registered_user_data);
|
||||||
|
break;
|
||||||
case GST_H265_SEI_BUF_PERIOD:
|
case GST_H265_SEI_BUF_PERIOD:
|
||||||
/* FIXME */
|
/* FIXME */
|
||||||
break;
|
break;
|
||||||
|
@ -672,6 +679,39 @@ gst_h265_parse_process_sei (GstH265Parse * h265parse, GstH265NalUnit * nalu)
|
||||||
g_array_free (messages, TRUE);
|
g_array_free (messages, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_h265_parse_process_sei_user_data (GstH265Parse * h265parse,
|
||||||
|
GstH265RegisteredUserData * rud)
|
||||||
|
{
|
||||||
|
guint16 provider_code;
|
||||||
|
GstByteReader br;
|
||||||
|
GstVideoParseUtilsField field = GST_VIDEO_PARSE_UTILS_FIELD_1;
|
||||||
|
|
||||||
|
/* only US country code is currently supported */
|
||||||
|
switch (rud->country_code) {
|
||||||
|
case ITU_T_T35_COUNTRY_CODE_US:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
GST_LOG_OBJECT (h265parse, "Unsupported country code %d",
|
||||||
|
rud->country_code);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rud->data == NULL || rud->size < 2)
|
||||||
|
return;
|
||||||
|
|
||||||
|
gst_byte_reader_init (&br, rud->data, rud->size);
|
||||||
|
|
||||||
|
provider_code = gst_byte_reader_get_uint16_be_unchecked (&br);
|
||||||
|
|
||||||
|
if (h265parse->sei_pic_struct ==
|
||||||
|
(guint8) GST_H265_SEI_PIC_STRUCT_BOTTOM_FIELD)
|
||||||
|
field = GST_VIDEO_PARSE_UTILS_FIELD_1;
|
||||||
|
gst_video_parse_user_data ((GstElement *) h265parse, &h265parse->user_data,
|
||||||
|
&br, field, provider_code);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* caller guarantees 2 bytes of nal payload */
|
/* caller guarantees 2 bytes of nal payload */
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_h265_parse_process_nal (GstH265Parse * h265parse, GstH265NalUnit * nalu)
|
gst_h265_parse_process_nal (GstH265Parse * h265parse, GstH265NalUnit * nalu)
|
||||||
|
@ -2565,6 +2605,7 @@ gst_h265_parse_pre_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
|
||||||
GstH265Parse *h265parse;
|
GstH265Parse *h265parse;
|
||||||
GstBuffer *buffer;
|
GstBuffer *buffer;
|
||||||
GstEvent *event;
|
GstEvent *event;
|
||||||
|
GstBuffer *parse_buffer = NULL;
|
||||||
|
|
||||||
h265parse = GST_H265_PARSE (parse);
|
h265parse = GST_H265_PARSE (parse);
|
||||||
|
|
||||||
|
@ -2671,9 +2712,9 @@ gst_h265_parse_pre_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
|
||||||
guint i = 0;
|
guint i = 0;
|
||||||
|
|
||||||
for (i = 0; i < h265parse->time_code.num_clock_ts; i++) {
|
for (i = 0; i < h265parse->time_code.num_clock_ts; i++) {
|
||||||
GstVideoTimeCodeFlags flags = 0;
|
|
||||||
gint field_count = -1;
|
gint field_count = -1;
|
||||||
guint n_frames;
|
guint n_frames;
|
||||||
|
GstVideoTimeCodeFlags flags = 0;
|
||||||
|
|
||||||
if (!h265parse->time_code.clock_timestamp_flag[i])
|
if (!h265parse->time_code.clock_timestamp_flag[i])
|
||||||
break;
|
break;
|
||||||
|
@ -2742,6 +2783,22 @@ gst_h265_parse_pre_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (frame->out_buffer) {
|
||||||
|
parse_buffer = frame->out_buffer =
|
||||||
|
gst_buffer_make_writable (frame->out_buffer);
|
||||||
|
} else {
|
||||||
|
parse_buffer = frame->buffer = gst_buffer_make_writable (frame->buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (h265parse->sei_pic_struct != GST_H265_SEI_PIC_STRUCT_FRAME) {
|
||||||
|
GST_BUFFER_FLAG_SET (parse_buffer, GST_VIDEO_BUFFER_FLAG_INTERLACED);
|
||||||
|
if (h265parse->sei_pic_struct == GST_H265_SEI_PIC_STRUCT_TOP_FIELD)
|
||||||
|
GST_BUFFER_FLAG_SET (parse_buffer, GST_VIDEO_BUFFER_FLAG_TFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
gst_video_push_user_data ((GstElement *) h265parse, &h265parse->user_data,
|
||||||
|
parse_buffer);
|
||||||
|
|
||||||
gst_h265_parse_reset_frame (h265parse);
|
gst_h265_parse_reset_frame (h265parse);
|
||||||
|
|
||||||
return GST_FLOW_OK;
|
return GST_FLOW_OK;
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include <gst/base/gstbaseparse.h>
|
#include <gst/base/gstbaseparse.h>
|
||||||
#include <gst/codecparsers/gsth265parser.h>
|
#include <gst/codecparsers/gsth265parser.h>
|
||||||
#include <gst/video/video.h>
|
#include <gst/video/video.h>
|
||||||
|
#include "gstvideoparseutils.h"
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
@ -108,6 +109,8 @@ struct _GstH265Parse
|
||||||
/* AU state */
|
/* AU state */
|
||||||
gboolean picture_start;
|
gboolean picture_start;
|
||||||
|
|
||||||
|
GstVideoParseUserData user_data;
|
||||||
|
|
||||||
/* props */
|
/* props */
|
||||||
gint interval;
|
gint interval;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue