summaryrefslogtreecommitdiff
path: root/gst-libs
diff options
context:
space:
mode:
authorTim-Philipp Müller <tim@centricular.com>2019-03-29 21:02:44 +0000
committerTim-Philipp Müller <tim@centricular.com>2019-04-08 19:21:34 +0100
commit76f1ed15fb93d5ec5e3df02e101d8d414179ce73 (patch)
tree0479cf9d53fe91d745694bda16f0f6c273e4f2bb /gst-libs
parent2e442b801b9a3d06a44c74b0eb9e8b2cac68ff1f (diff)
downloadgstreamer-plugins-bad-76f1ed15fb93d5ec5e3df02e101d8d414179ce73.tar.gz
h264parse: extract CEA-708 closed captions
Expose SEI data in the H.264 bitstream parser API and extract closed captions and other things that are not specified in the H.264 spec itself in the videoparser. Based on patch by: Mathieu Duponchelle <mathieu@centricular.com> https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/issues/940
Diffstat (limited to 'gst-libs')
-rw-r--r--gst-libs/gst/codecparsers/gsth264parser.c66
-rw-r--r--gst-libs/gst/codecparsers/gsth264parser.h12
2 files changed, 78 insertions, 0 deletions
diff --git a/gst-libs/gst/codecparsers/gsth264parser.c b/gst-libs/gst/codecparsers/gsth264parser.c
index 30d6aea49..acc6fd91a 100644
--- a/gst-libs/gst/codecparsers/gsth264parser.c
+++ b/gst-libs/gst/codecparsers/gsth264parser.c
@@ -1009,6 +1009,51 @@ error:
}
static GstH264ParserResult
+gst_h264_parser_parse_registered_user_data (GstH264NalParser * nalparser,
+ GstH264RegisteredUserData * rud, NalReader * nr, guint payload_size)
+{
+ guint8 *data = NULL;
+ guint i;
+
+ rud->data = NULL;
+ rud->size = 0;
+
+ if (payload_size < 2)
+ return GST_H264_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_H264_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_H264_PARSER_OK;
+
+error:
+ {
+ GST_WARNING ("error parsing \"Registered User Data\"");
+ g_free (data);
+ return GST_H264_PARSER_ERROR;
+ }
+}
+
+static GstH264ParserResult
gst_h264_parser_parse_recovery_point (GstH264NalParser * nalparser,
GstH264RecoveryPoint * rp, NalReader * nr)
{
@@ -1157,6 +1202,10 @@ gst_h264_parser_parse_sei_message (GstH264NalParser * nalparser,
res = gst_h264_parser_parse_pic_timing (nalparser,
&sei->payload.pic_timing, nr);
break;
+ case GST_H264_SEI_REGISTERED_USER_DATA:
+ res = gst_h264_parser_parse_registered_user_data (nalparser,
+ &sei->payload.registered_user_data, nr, payload_size);
+ break;
case GST_H264_SEI_RECOVERY_POINT:
res = gst_h264_parser_parse_recovery_point (nalparser,
&sei->payload.recovery_point, nr);
@@ -2276,6 +2325,22 @@ gst_h264_sps_clear (GstH264SPS * sps)
}
}
+static void
+h264_sei_message_clear (GstH264SEIMessage * sei_msg)
+{
+ switch (sei_msg->payloadType) {
+ case GST_H264_SEI_REGISTERED_USER_DATA:{
+ GstH264RegisteredUserData *rud = &sei_msg->payload.registered_user_data;
+
+ g_free ((guint8 *) rud->data);
+ rud->data = NULL;
+ break;
+ }
+ default:
+ break;
+ }
+}
+
/**
* gst_h264_parser_parse_sei:
* @nalparser: a #GstH264NalParser
@@ -2299,6 +2364,7 @@ gst_h264_parser_parse_sei (GstH264NalParser * nalparser, GstH264NalUnit * nalu,
nal_reader_init (&nr, nalu->data + nalu->offset + nalu->header_bytes,
nalu->size - nalu->header_bytes);
*messages = g_array_new (FALSE, FALSE, sizeof (GstH264SEIMessage));
+ g_array_set_clear_func (*messages, (GDestroyNotify) h264_sei_message_clear);
do {
res = gst_h264_parser_parse_sei_message (nalparser, &nr, &sei);
diff --git a/gst-libs/gst/codecparsers/gsth264parser.h b/gst-libs/gst/codecparsers/gsth264parser.h
index 671b5e5fd..4e063d596 100644
--- a/gst-libs/gst/codecparsers/gsth264parser.h
+++ b/gst-libs/gst/codecparsers/gsth264parser.h
@@ -240,6 +240,7 @@ typedef enum
* GstH264SEIPayloadType:
* @GST_H264_SEI_BUF_PERIOD: Buffering Period SEI Message
* @GST_H264_SEI_PIC_TIMING: Picture Timing SEI Message
+ * @GST_H264_SEI_REGISTERED_USER_DATA: Registered user data (D.2.5)
* @GST_H264_SEI_RECOVERY_POINT: Recovery Point SEI Message (D.2.7)
* @GST_H264_SEI_STEREO_VIDEO_INFO: stereo video info SEI message (Since: 1.6)
* @GST_H264_SEI_FRAME_PACKING: Frame Packing Arrangement (FPA) message that
@@ -252,6 +253,7 @@ typedef enum
{
GST_H264_SEI_BUF_PERIOD = 0,
GST_H264_SEI_PIC_TIMING = 1,
+ GST_H264_SEI_REGISTERED_USER_DATA = 4,
GST_H264_SEI_RECOVERY_POINT = 6,
GST_H264_SEI_STEREO_VIDEO_INFO = 21,
GST_H264_SEI_FRAME_PACKING = 45
@@ -345,6 +347,7 @@ typedef struct _GstH264SliceHdr GstH264SliceHdr;
typedef struct _GstH264ClockTimestamp GstH264ClockTimestamp;
typedef struct _GstH264PicTiming GstH264PicTiming;
+typedef struct _GstH264RegisteredUserData GstH264RegisteredUserData;
typedef struct _GstH264BufferingPeriod GstH264BufferingPeriod;
typedef struct _GstH264RecoveryPoint GstH264RecoveryPoint;
typedef struct _GstH264StereoVideoInfo GstH264StereoVideoInfo;
@@ -994,6 +997,14 @@ struct _GstH264PicTiming
GstH264ClockTimestamp clock_timestamp[3];
};
+struct _GstH264RegisteredUserData
+{
+ guint8 country_code;
+ guint8 country_code_extension;
+ const guint8 *data;
+ guint size;
+};
+
struct _GstH264BufferingPeriod
{
GstH264SPS *sps;
@@ -1022,6 +1033,7 @@ struct _GstH264SEIMessage
union {
GstH264BufferingPeriod buffering_period;
GstH264PicTiming pic_timing;
+ GstH264RegisteredUserData registered_user_data;
GstH264RecoveryPoint recovery_point;
GstH264StereoVideoInfo stereo_video_info;
GstH264FramePacking frame_packing;