summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdward Hervey <edward@collabora.com>2013-07-26 08:36:51 +0200
committerEdward Hervey <edward@collabora.com>2013-08-26 08:11:15 +0200
commit7e8c6be3c37537ec588ed2025112b5030a28806a (patch)
tree4fc1f3bb37f346cbb542c61605b3724de119e57b
parente481ecbf2229468873296b350c1ff5b3ea28a71f (diff)
WIP video descriptorcurrent
-rw-r--r--gst-libs/gst/mpegts/gstmpegtsdescriptor.c61
-rw-r--r--gst-libs/gst/mpegts/gstmpegtsdescriptor.h15
-rw-r--r--gst/mpegtsdemux/tsdemux.c4
-rw-r--r--tests/examples/mpegts/ts-parser.c33
4 files changed, 113 insertions, 0 deletions
diff --git a/gst-libs/gst/mpegts/gstmpegtsdescriptor.c b/gst-libs/gst/mpegts/gstmpegtsdescriptor.c
index 16a7741ee..f80244883 100644
--- a/gst-libs/gst/mpegts/gstmpegtsdescriptor.c
+++ b/gst-libs/gst/mpegts/gstmpegtsdescriptor.c
@@ -598,6 +598,67 @@ gst_mpegts_find_descriptor (GPtrArray * descriptors, guint8 tag)
}
+/* GST_MTS_DESC_VIDEO_STREAM (0x02) */
+/**
+ * gst_mpegts_descriptor_parse_video_stream:
+ * @descriptor: a %GST_MTS_DESC_VIDEO_STREAM #GstMpegTsDescriptor
+ * @flags: (out): the flags contained in the descriptor
+ * @framerate_num: (out): the framerate numerator
+ * @framerate_denom: (out): the framerate denominator
+ * @profile_and_level: (out): the profile and level (only valid if
+ * %GST_MPEGTS_VIDEO_STREAM_DESC_FLAG_MPEG1_ONLY is not set in @flags)
+ * @chroma_format: (out): the chroma format (only valid if
+ * %GST_MPEGTS_VIDEO_STREAM_DESC_FLAG_MPEG1_ONLY is not set in @flags)
+ *
+ * Extracts the video stream information from @descriptor.
+ *
+ * Returns: %TRUE if parsing succeeded, else %FALSE.
+ */
+gboolean
+gst_mpegts_descriptor_parse_video_stream (const GstMpegTsDescriptor *
+ descriptor, GstMpegTSVideoStreamDescFlags * flags, guint * framerate_num,
+ guint * framerate_denom, guint8 * profile_and_level, guint8 * chroma_format)
+{
+ const gint framerates[][2] = {
+ {30, 1}, {24000, 1001}, {24, 1}, {25, 1},
+ {30000, 1001}, {30, 1}, {50, 1}, {60000, 1001},
+ {60, 1}, {30, 1}
+ };
+ guint8 *data, fps_code;
+
+ g_return_val_if_fail (descriptor != NULL && descriptor->data != NULL, FALSE);
+ g_return_val_if_fail (flags != NULL, FALSE);
+ g_return_val_if_fail (descriptor->tag == 0x02, FALSE);
+
+ data = (guint8 *) descriptor->data + 2;
+ *flags = *data++;
+
+ /* FIXME : We should have helper/shared code for
+ * framerate, profile, level, chroma_format */
+ fps_code = *flags >> 3 & 0x0f;
+
+ if (framerate_num && framerate_denom) {
+ if (fps_code && fps_code < 8) {
+ *framerate_num = framerates[fps_code][0];
+ *framerate_denom = framerates[fps_code][1];
+ } else {
+ *framerate_num = 0;
+ *framerate_denom = 1;
+ }
+ }
+ if (profile_and_level && chroma_format) {
+ if (!(*flags & 0x04)) {
+ *profile_and_level = *data++;
+ *chroma_format = *data >> 6;
+ } else {
+ *profile_and_level = 0;
+ *chroma_format = 0;
+ }
+ }
+
+ return TRUE;
+}
+
/* GST_MTS_DESC_ISO_639_LANGUAGE (0x0A) */
/**
* gst_mpegts_descriptor_parse_iso_639_language:
diff --git a/gst-libs/gst/mpegts/gstmpegtsdescriptor.h b/gst-libs/gst/mpegts/gstmpegtsdescriptor.h
index c976cc13f..650a3a3fb 100644
--- a/gst-libs/gst/mpegts/gstmpegtsdescriptor.h
+++ b/gst-libs/gst/mpegts/gstmpegtsdescriptor.h
@@ -260,6 +260,21 @@ GPtrArray *gst_mpegts_parse_descriptors (guint8 * buffer, gsize buf_len);
const GstMpegTsDescriptor * gst_mpegts_find_descriptor (GPtrArray *descriptors,
guint8 tag);
+/* GST_MTS_DESC_VIDEO_STREAM (0x02) */
+
+typedef enum {
+ GST_MPEGTS_VIDEO_STREAM_DESC_FLAG_MULTIPLE_FRAMERATE = 0x80,
+ GST_MPEGTS_VIDEO_STREAM_DESC_FLAG_MPEG1_ONLY = 0x04,
+ GST_MPEGTS_VIDEO_STREAM_DESC_FLAG_CONSTRAINED_PARAMETER = 0x02,
+ GST_MPEGTS_VIDEO_STREAM_DESC_FLAG_STILL_PICTURE = 0x01
+} GstMpegTSVideoStreamDescFlags;
+
+gboolean gst_mpegts_descriptor_parse_video_stream (const GstMpegTsDescriptor *descriptor,
+ GstMpegTSVideoStreamDescFlags *flags,
+ guint *framerate_num, guint *framerate_denom,
+ guint8 *profile_and_level,
+ guint8 *chroma_format);
+
/* GST_MTS_DESC_ISO_639_LANGUAGE (0x0A) */
/**
* GstMpegTsISO639AudioType:
diff --git a/gst/mpegtsdemux/tsdemux.c b/gst/mpegtsdemux/tsdemux.c
index 0553ed98b..eedf4aca0 100644
--- a/gst/mpegtsdemux/tsdemux.c
+++ b/gst/mpegtsdemux/tsdemux.c
@@ -910,6 +910,10 @@ create_pad_for_stream (MpegTSBase * base, MpegTSBaseStream * bstream,
caps = gst_caps_new_simple ("video/x-h264",
"stream-format", G_TYPE_STRING, "byte-stream",
"alignment", G_TYPE_STRING, "nal", NULL);
+ if ((desc =
+ mpegts_get_descriptor_from_stream (bstream,
+ GST_MTS_DESC_AVC_VIDEO)))
+ gst_codec_utils_h264_caps_set_level_and_profile (caps, desc + 2, 3);
break;
case ST_VIDEO_DIRAC:
if (bstream->registration_id == 0x64726163) {
diff --git a/tests/examples/mpegts/ts-parser.c b/tests/examples/mpegts/ts-parser.c
index 89db16f07..980a1072d 100644
--- a/tests/examples/mpegts/ts-parser.c
+++ b/tests/examples/mpegts/ts-parser.c
@@ -71,6 +71,35 @@ enum_name (GType instance_type, gint val)
}
static void
+dump_video_stream_descriptor (GstMpegTsDescriptor * desc, guint spacing)
+{
+ GstMpegTSVideoStreamDescFlags flags;
+ guint framerate_num, framerate_denom;
+ guint8 profile_and_level, chroma_format;
+
+ if (gst_mpegts_descriptor_parse_video_stream (desc, &flags, &framerate_num,
+ &framerate_denom, &profile_and_level, &chroma_format)) {
+ g_printf ("%*s Video Stream Descriptor\n", spacing, "");
+ g_printf ("%*s flags : %s%s%s%s%s \n", spacing, "",
+ flags & GST_MPEGTS_VIDEO_STREAM_DESC_FLAG_MULTIPLE_FRAMERATE ?
+ "multiple_framerate " : "",
+ flags & GST_MPEGTS_VIDEO_STREAM_DESC_FLAG_MPEG1_ONLY ? "MPEG_1_only " :
+ "",
+ flags & GST_MPEGTS_VIDEO_STREAM_DESC_FLAG_CONSTRAINED_PARAMETER ?
+ "constrained_parameter " : "",
+ flags & GST_MPEGTS_VIDEO_STREAM_DESC_FLAG_STILL_PICTURE ?
+ "still_picture " : "", flags ? "" : "<none>");
+ g_printf ("%*s framerate : %d/%d\n", spacing, "", framerate_num,
+ framerate_denom);
+ if (!(flags & GST_MPEGTS_VIDEO_STREAM_DESC_FLAG_MPEG1_ONLY)) {
+ g_printf ("%*s profile_and_level : %d\n", spacing, "",
+ profile_and_level);
+ g_printf ("%*s chroma_format : %d\n", spacing, "", chroma_format);
+ }
+ }
+}
+
+static void
dump_cable_delivery_descriptor (GstMpegTsDescriptor * desc, guint spacing)
{
GstMpegTsCableDeliverySystemDescriptor res;
@@ -129,6 +158,9 @@ dump_descriptors (GPtrArray * descriptors, guint spacing)
g_printf ("%*s [descriptor 0x%02x (%s) length:%d]\n", spacing, "",
desc->tag, descriptor_name (desc->tag), desc->length);
switch (desc->tag) {
+ case GST_MTS_DESC_VIDEO_STREAM:
+ dump_video_stream_descriptor (desc, spacing + 2);
+ break;
case GST_MTS_DESC_REGISTRATION:
{
const guint8 *data = desc->data + 2;
@@ -468,6 +500,7 @@ main (int argc, gchar ** argv)
}
/* Hack: ensure all enum type classes are loaded */
+ /* FIXME : Move this to gst_mpegts_initialize() */
g_type_class_ref (GST_TYPE_MPEG_TS_SECTION_TYPE);
g_type_class_ref (GST_TYPE_MPEG_TS_SECTION_TABLE_ID);
g_type_class_ref (GST_TYPE_MPEG_TS_RUNNING_STATUS);