mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-03-30 12:49:40 +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;
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
gst_h265_parser_parse_time_code (GstH265Parser * parser,
|
||||
GstH265TimeCode * tc, NalReader * nr)
|
||||
|
@ -2472,6 +2519,10 @@ gst_h265_parser_parse_sei_message (GstH265Parser * parser,
|
|||
res = gst_h265_parser_parse_pic_timing (parser,
|
||||
&sei->payload.pic_timing, nr);
|
||||
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:
|
||||
res = gst_h265_parser_parse_recovery_point (parser,
|
||||
&sei->payload.recovery_point, nr);
|
||||
|
|
|
@ -271,6 +271,7 @@ typedef enum
|
|||
* GstH265SEIPayloadType:
|
||||
* @GST_H265_SEI_BUF_PERIOD: Buffering Period 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_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)
|
||||
|
@ -283,6 +284,7 @@ typedef enum
|
|||
{
|
||||
GST_H265_SEI_BUF_PERIOD = 0,
|
||||
GST_H265_SEI_PIC_TIMING = 1,
|
||||
GST_H265_SEI_REGISTERED_USER_DATA = 4,
|
||||
GST_H265_SEI_RECOVERY_POINT = 6,
|
||||
GST_H265_SEI_TIME_CODE = 136,
|
||||
GST_H265_SEI_MASTERING_DISPLAY_COLOUR_VOLUME = 137,
|
||||
|
@ -373,6 +375,7 @@ typedef struct _GstH265ShortTermRefPicSet GstH265ShortTermRefPicSet;
|
|||
typedef struct _GstH265SliceHdr GstH265SliceHdr;
|
||||
|
||||
typedef struct _GstH265PicTiming GstH265PicTiming;
|
||||
typedef struct _GstH265RegisteredUserData GstH265RegisteredUserData;
|
||||
typedef struct _GstH265BufferingPeriod GstH265BufferingPeriod;
|
||||
typedef struct _GstH265RecoveryPoint GstH265RecoveryPoint;
|
||||
typedef struct _GstH265TimeCode GstH265TimeCode;
|
||||
|
@ -1226,6 +1229,15 @@ struct _GstH265RecoveryPoint
|
|||
guint8 broken_link_flag;
|
||||
};
|
||||
|
||||
struct _GstH265RegisteredUserData
|
||||
{
|
||||
guint8 country_code;
|
||||
guint8 country_code_extension;
|
||||
const guint8 *data;
|
||||
guint size;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* GstH265TimeCode:
|
||||
* The time code SEI message provides time code information similar to that
|
||||
|
@ -1297,6 +1309,7 @@ struct _GstH265SEIMessage
|
|||
union {
|
||||
GstH265BufferingPeriod buffering_period;
|
||||
GstH265PicTiming pic_timing;
|
||||
GstH265RegisteredUserData registered_user_data;
|
||||
GstH265RecoveryPoint recovery_point;
|
||||
GstH265TimeCode time_code;
|
||||
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_src_event (GstBaseParse * parse,
|
||||
GstEvent * event);
|
||||
static void
|
||||
gst_h265_parse_process_sei_user_data (GstH265Parse * h265parse,
|
||||
GstH265RegisteredUserData * rud);
|
||||
|
||||
static void
|
||||
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:
|
||||
h265parse->sei_pic_struct = sei.payload.pic_timing.pic_struct;
|
||||
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:
|
||||
/* FIXME */
|
||||
break;
|
||||
|
@ -672,6 +679,39 @@ gst_h265_parse_process_sei (GstH265Parse * h265parse, GstH265NalUnit * nalu)
|
|||
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 */
|
||||
static gboolean
|
||||
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;
|
||||
GstBuffer *buffer;
|
||||
GstEvent *event;
|
||||
GstBuffer *parse_buffer = NULL;
|
||||
|
||||
h265parse = GST_H265_PARSE (parse);
|
||||
|
||||
|
@ -2671,9 +2712,9 @@ gst_h265_parse_pre_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
|
|||
guint i = 0;
|
||||
|
||||
for (i = 0; i < h265parse->time_code.num_clock_ts; i++) {
|
||||
GstVideoTimeCodeFlags flags = 0;
|
||||
gint field_count = -1;
|
||||
guint n_frames;
|
||||
GstVideoTimeCodeFlags flags = 0;
|
||||
|
||||
if (!h265parse->time_code.clock_timestamp_flag[i])
|
||||
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);
|
||||
|
||||
return GST_FLOW_OK;
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include <gst/base/gstbaseparse.h>
|
||||
#include <gst/codecparsers/gsth265parser.h>
|
||||
#include <gst/video/video.h>
|
||||
#include "gstvideoparseutils.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
@ -108,6 +109,8 @@ struct _GstH265Parse
|
|||
/* AU state */
|
||||
gboolean picture_start;
|
||||
|
||||
GstVideoParseUserData user_data;
|
||||
|
||||
/* props */
|
||||
gint interval;
|
||||
|
||||
|
|
Loading…
Reference in a new issue