summaryrefslogtreecommitdiff
path: root/gst-libs
diff options
context:
space:
mode:
authorMathieu Duponchelle <mathieu@centricular.com>2019-03-30 01:17:08 +0100
committerMathieu Duponchelle <mduponchelle1@gmail.com>2019-04-01 10:02:33 +0000
commit55bb8966e1508ab7b35b6a507ef90cc5f64d8486 (patch)
tree17b73b18a5e642a7d1b2851719701b067414de22 /gst-libs
parent7c425cf3395cc0063daeb0bc0e289732c4339c68 (diff)
downloadgstreamer-plugins-bad-55bb8966e1508ab7b35b6a507ef90cc5f64d8486.tar.gz
h265parse: forward time codes
This transforms time code SEIs into GstVideoTimeCodeMeta
Diffstat (limited to 'gst-libs')
-rw-r--r--gst-libs/gst/codecparsers/gsth265parser.c62
-rw-r--r--gst-libs/gst/codecparsers/gsth265parser.h34
2 files changed, 96 insertions, 0 deletions
diff --git a/gst-libs/gst/codecparsers/gsth265parser.c b/gst-libs/gst/codecparsers/gsth265parser.c
index d44a045f7..16fce006b 100644
--- a/gst-libs/gst/codecparsers/gsth265parser.c
+++ b/gst-libs/gst/codecparsers/gsth265parser.c
@@ -1124,6 +1124,64 @@ error:
return GST_H265_PARSER_ERROR;
}
+static GstH265ParserResult
+gst_h265_parser_parse_time_code (GstH265Parser * parser,
+ GstH265TimeCode * tc, NalReader * nr)
+{
+ guint i;
+
+ GST_DEBUG ("parsing \"Time code\"");
+
+ READ_UINT8 (nr, tc->num_clock_ts, 2);
+
+ for (i = 0; i < tc->num_clock_ts; i++) {
+ READ_UINT8 (nr, tc->clock_timestamp_flag[i], 1);
+ if (tc->clock_timestamp_flag[i]) {
+ READ_UINT8 (nr, tc->units_field_based_flag[i], 1);
+ READ_UINT8 (nr, tc->counting_type[i], 5);
+ READ_UINT8 (nr, tc->full_timestamp_flag[i], 1);
+ READ_UINT8 (nr, tc->discontinuity_flag[i], 1);
+ READ_UINT8 (nr, tc->cnt_dropped_flag[i], 1);
+ READ_UINT16 (nr, tc->n_frames[i], 9);
+
+ if (tc->full_timestamp_flag[i]) {
+ tc->seconds_flag[i] = TRUE;
+ READ_UINT8 (nr, tc->seconds_value[i], 6);
+
+ tc->minutes_flag[i] = TRUE;
+ READ_UINT8 (nr, tc->minutes_value[i], 6);
+
+ tc->hours_flag[i] = TRUE;
+ READ_UINT8 (nr, tc->hours_value[i], 5);
+ } else {
+ READ_UINT8 (nr, tc->seconds_flag[i], 1);
+ if (tc->seconds_flag[i]) {
+ READ_UINT8 (nr, tc->seconds_value[i], 6);
+ READ_UINT8 (nr, tc->minutes_flag[i], 1);
+ if (tc->minutes_flag[i]) {
+ READ_UINT8 (nr, tc->minutes_value[i], 6);
+ READ_UINT8 (nr, tc->hours_flag[i], 1);
+ if (tc->hours_flag[i]) {
+ READ_UINT8 (nr, tc->hours_value[i], 5);
+ }
+ }
+ }
+ }
+ }
+
+ READ_UINT8 (nr, tc->time_offset_length[i], 5);
+
+ if (tc->time_offset_length[i] > 0)
+ READ_UINT32 (nr, tc->time_offset_value[i], tc->time_offset_length[i]);
+ }
+
+ return GST_H265_PARSER_OK;
+
+error:
+ GST_WARNING ("error parsing \"Time code\"");
+ return GST_H265_PARSER_ERROR;
+}
+
/******** API *************/
/**
@@ -2312,6 +2370,10 @@ gst_h265_parser_parse_sei_message (GstH265Parser * parser,
res = gst_h265_parser_parse_recovery_point (parser,
&sei->payload.recovery_point, nr);
break;
+ case GST_H265_SEI_TIME_CODE:
+ res = gst_h265_parser_parse_time_code (parser,
+ &sei->payload.time_code, nr);
+ break;
default:
/* Just consume payloadSize bytes, which does not account for
emulation prevention bytes */
diff --git a/gst-libs/gst/codecparsers/gsth265parser.h b/gst-libs/gst/codecparsers/gsth265parser.h
index b4d1901c0..db996fc99 100644
--- a/gst-libs/gst/codecparsers/gsth265parser.h
+++ b/gst-libs/gst/codecparsers/gsth265parser.h
@@ -221,6 +221,7 @@ typedef enum
* @GST_H265_SEI_BUF_PERIOD: Buffering Period SEI Message
* @GST_H265_SEI_PIC_TIMING: Picture Timing SEI Message
* @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)
* ...
*
* The type of SEI message.
@@ -230,6 +231,7 @@ typedef enum
GST_H265_SEI_BUF_PERIOD = 0,
GST_H265_SEI_PIC_TIMING = 1,
GST_H265_SEI_RECOVERY_POINT = 6,
+ GST_H265_SEI_TIME_CODE = 136,
/* and more... */
} GstH265SEIPayloadType;
@@ -316,6 +318,7 @@ typedef struct _GstH265SliceHdr GstH265SliceHdr;
typedef struct _GstH265PicTiming GstH265PicTiming;
typedef struct _GstH265BufferingPeriod GstH265BufferingPeriod;
typedef struct _GstH265RecoveryPoint GstH265RecoveryPoint;
+typedef struct _GstH265TimeCode GstH265TimeCode;
typedef struct _GstH265SEIMessage GstH265SEIMessage;
/**
@@ -1073,6 +1076,36 @@ struct _GstH265RecoveryPoint
guint8 broken_link_flag;
};
+/**
+ * GstH265TimeCode:
+ * The time code SEI message provides time code information similar to that
+ * defined by SMPTE ST 12-1 (2014) for field(s) or frame(s) of the current
+ * picture.
+ *
+ * D.2.27
+ *
+ * Since: 1.16
+ */
+struct _GstH265TimeCode
+{
+ guint8 num_clock_ts;
+ guint8 clock_timestamp_flag[3];
+ guint8 units_field_based_flag[3];
+ guint8 counting_type[3];
+ guint8 full_timestamp_flag[3];
+ guint8 discontinuity_flag[3];
+ guint8 cnt_dropped_flag[3];
+ guint16 n_frames[3];
+ guint8 seconds_flag[3];
+ guint8 seconds_value[3];
+ guint8 minutes_flag[3];
+ guint8 minutes_value[3];
+ guint8 hours_flag[3];
+ guint8 hours_value[3];
+ guint8 time_offset_length[3];
+ guint32 time_offset_value[3];
+};
+
struct _GstH265SEIMessage
{
GstH265SEIPayloadType payloadType;
@@ -1081,6 +1114,7 @@ struct _GstH265SEIMessage
GstH265BufferingPeriod buffering_period;
GstH265PicTiming pic_timing;
GstH265RecoveryPoint recovery_point;
+ GstH265TimeCode time_code;
/* ... could implement more */
} payload;
};