summaryrefslogtreecommitdiff
path: root/gst/videoparsers
diff options
context:
space:
mode:
authorSreerenj Balachandran <sreerenj.balachandran@intel.com>2015-05-02 18:06:18 +0300
committerSebastian Dröge <sebastian@centricular.com>2015-05-04 09:30:05 +0200
commit3fae18b5d259fdf76ac7de36d79e59a1083f16b2 (patch)
tree493b6097d123a9b8f28f3c6fa120a1e588a78d3e /gst/videoparsers
parent2ed71bee3b8ea2ea65302bb8f02ed7412ea93c25 (diff)
downloadgstreamer-plugins-bad-3fae18b5d259fdf76ac7de36d79e59a1083f16b2.tar.gz
h264parse: Fix profile and level setting in caps
Don't use the apis in codec-utils to extract the profile and level syntax elements since it is wrong if there are emulation prevention bytes existing in the byte-stream data. https://bugzilla.gnome.org/show_bug.cgi?id=747613
Diffstat (limited to 'gst/videoparsers')
-rw-r--r--gst/videoparsers/gsth264parse.c138
1 files changed, 127 insertions, 11 deletions
diff --git a/gst/videoparsers/gsth264parse.c b/gst/videoparsers/gsth264parse.c
index 4c7513df1..7546e6f50 100644
--- a/gst/videoparsers/gsth264parse.c
+++ b/gst/videoparsers/gsth264parse.c
@@ -1395,6 +1395,121 @@ ensure_caps_profile (GstH264Parse * h264parse, GstCaps * caps, GstH264SPS * sps)
gst_caps_unref (filter_caps);
}
+static const gchar *
+digit_to_string (guint digit)
+{
+ static const char itoa[][2] = {
+ "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"
+ };
+
+ if (G_LIKELY (digit < 10))
+ return itoa[digit];
+ else
+ return NULL;
+}
+
+static const gchar *
+get_profile_string (GstH264SPS * sps)
+{
+ const gchar *profile = NULL;
+
+ switch (sps->profile_idc) {
+ case 66:
+ if (sps->constraint_set1_flag)
+ profile = "constrained-baseline";
+ else
+ profile = "baseline";
+ break;
+ case 77:
+ profile = "main";
+ break;
+ case 88:
+ profile = "extended";
+ break;
+ case 100:
+ profile = "high";
+ break;
+ case 110:
+ if (sps->constraint_set3_flag)
+ profile = "high-10-intra";
+ else
+ profile = "high-10";
+ break;
+ case 122:
+ if (sps->constraint_set3_flag)
+ profile = "high-4:2:2-intra";
+ else
+ profile = "high-4:2:2";
+ break;
+ case 244:
+ if (sps->constraint_set3_flag)
+ profile = "high-4:4:4-intra";
+ else
+ profile = "high-4:4:4";
+ break;
+ case 44:
+ profile = "cavlc-4:4:4-intra";
+ break;
+ case 118:
+ profile = "multiview-high";
+ break;
+ case 128:
+ profile = "stereo-high";
+ break;
+ case 83:
+ if (sps->constraint_set5_flag)
+ profile = "scalable-constrained-baseline";
+ else
+ profile = "scalable-baseline";
+ break;
+ case 86:
+ profile = "scalable-high";
+ break;
+ default:
+ return NULL;
+ }
+
+ return profile;
+}
+
+static const gchar *
+get_level_string (GstH264SPS * sps)
+{
+ if ((sps->level_idc == 11 && sps->constraint_set3_flag)
+ || sps->level_idc == 9)
+ return "1b";
+ else if (sps->level_idc % 10 == 0)
+ return digit_to_string (sps->level_idc / 10);
+ else {
+ switch (sps->level_idc) {
+ case 11:
+ return "1.1";
+ case 12:
+ return "1.2";
+ case 13:
+ return "1.3";
+ case 21:
+ return "2.1";
+ case 22:
+ return "2.2";
+ case 31:
+ return "3.1";
+ case 32:
+ return "3.2";
+ case 41:
+ return "4.1";
+ case 42:
+ return "4.2";
+ case 51:
+ return "5.1";
+ case 52:
+ return "5.2";
+ default:
+ return NULL;
+ }
+ }
+}
+
static void
gst_h264_parse_update_src_caps (GstH264Parse * h264parse, GstCaps * caps)
{
@@ -1554,17 +1669,18 @@ gst_h264_parse_update_src_caps (GstH264Parse * h264parse, GstCaps * caps)
/* set profile and level in caps */
if (sps) {
- GstMapInfo map;
- GstBuffer *sps_buf = h264parse->sps_nals[sps->id];
-
- if (sps_buf) {
- gst_buffer_map (sps_buf, &map, GST_MAP_READ);
- gst_codec_utils_h264_caps_set_level_and_profile (caps,
- map.data + 1, map.size - 1);
- gst_buffer_unmap (sps_buf, &map);
- /* relax the profile constraint to find a suitable decoder */
- ensure_caps_profile (h264parse, caps, sps);
- }
+ const gchar *profile, *level;
+
+ profile = get_profile_string (sps);
+ if (profile != NULL)
+ gst_caps_set_simple (caps, "profile", G_TYPE_STRING, profile, NULL);
+
+ level = get_level_string (sps);
+ if (level != NULL)
+ gst_caps_set_simple (caps, "level", G_TYPE_STRING, level, NULL);
+
+ /* relax the profile constraint to find a suitable decoder */
+ ensure_caps_profile (h264parse, caps, sps);
}
src_caps = gst_pad_get_current_caps (GST_BASE_PARSE_SRC_PAD (h264parse));