summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBritt McKinley <bmckinley@sonusnet.com>2014-06-23 14:32:34 -0400
committerPascal Quantin <pascal.quantin@gmail.com>2014-07-06 19:11:24 +0000
commit4e9802e67957f96be95f6743ba2338f19ed60d39 (patch)
tree91ad64c3d976d5d8c35dcdb866d78da58231588e
parentc35b82c8f1853f99cd587a115a23e8b612d05142 (diff)
downloadwireshark-4e9802e67957f96be95f6743ba2338f19ed60d39.tar.gz
H264: Add support of packetization modes, SVC, MS-H264
Add support for Prefix, STAP, MTAP, NI-MTAP, and PACSI packet types. Add support for Microsoft SEI messages [MS-H264PF] Add support for dissecting scalable profiles SDP: Add profile-level-id decode for payload type H264-SVC MS-H264PF: http://msdn.microsoft.com/en-us/library/hh659565.aspx Update #1 - Fix Tabs -> Spaces, Reinsert accidentally removed entry 19 from h264_type_values Update #2 - Changed to using expert info for exceptions and Microsoft errata. Update #3: - Correct handling of truncated packets - Use guid functions and compare techniques - Correct ranges for expert info messages - Change to using reported_length from captured_length Change-Id: I520a3c9a6d85c78a976b520cf5a6a405064a48f1 Reviewed-on: https://code.wireshark.org/review/2580 Reviewed-by: Pascal Quantin <pascal.quantin@gmail.com>
-rw-r--r--epan/dissectors/packet-h264.c989
-rw-r--r--epan/dissectors/packet-sdp.c2
2 files changed, 956 insertions, 35 deletions
diff --git a/epan/dissectors/packet-h264.c b/epan/dissectors/packet-h264.c
index 5d0e55fa11..453595eeb7 100644
--- a/epan/dissectors/packet-h264.c
+++ b/epan/dissectors/packet-h264.c
@@ -21,8 +21,11 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* References:
- * http://www.ietf.org/rfc/rfc3984.txt?number=3984
+ * http://www.ietf.org/rfc/rfc3984.txt?number=3984 Obsolete
+ * http://www.ietf.org/rfc/rfc6184.txt?number=6184
+ * http://www.ietf.org/rfc/rfc6190.txt?number=6190
* http://www.itu.int/rec/T-REC-H.264/en
+ * MS-H264PF http://msdn.microsoft.com/en-us/library/hh659565.aspx
*/
#include "config.h"
@@ -59,7 +62,9 @@ static int hf_h264_constraint_set0_flag = -1;
static int hf_h264_constraint_set1_flag = -1;
static int hf_h264_constraint_set2_flag = -1;
static int hf_h264_constraint_set3_flag = -1;
-static int hf_h264_reserved_zero_4bits = -1;
+static int hf_h264_constraint_set4_flag = -1;
+static int hf_h264_constraint_set5_flag = -1;
+static int hf_h264_reserved_zero_2bits = -1;
static int hf_h264_level_idc = -1;
static int hf_h264_nal_unit = -1;
static int hf_h264_forbidden_zero_bit = -1;
@@ -126,6 +131,68 @@ static int hf_h264_par_ProfileIOP = -1;
static int hf_h264_par_constraint_set0_flag = -1;
static int hf_h264_par_constraint_set1_flag = -1;
static int hf_h264_par_constraint_set2_flag = -1;
+/* Packetization Values */
+static int hf_h264_nalu_size = -1;
+static int hf_h264_don = -1;
+static int hf_h264_dond = -1;
+static int hf_h264_ts_offset16 = -1;
+static int hf_h264_ts_offset24 = -1;
+/* Extension Header */
+static int hf_h264_nal_extension_subtype = -1;
+static int hf_h264_nal_extension_j = -1;
+static int hf_h264_nal_extension_k = -1;
+static int hf_h264_nal_extension_l = -1;
+
+/* SEI Decoding Information */
+static int hf_h264_sei_uuid = -1;
+/* Microsoft Layout SEI */
+static int hf_h264_sei_ms_lpb = -1;
+static int hf_h264_sei_ms_layout_p = -1;
+static int hf_h264_sei_ms_layout_ldsize = -1;
+static int hf_h264_sei_ms_layer_desc_coded_width = -1;
+static int hf_h264_sei_ms_layer_desc_coded_height = -1;
+static int hf_h264_sei_ms_layer_desc_display_width = -1;
+static int hf_h264_sei_ms_layer_desc_display_height = -1;
+static int hf_h264_sei_ms_layer_desc_bitrate = -1;
+static int hf_h264_sei_ms_layer_desc_frame_rate = -1;
+static int hf_h264_sei_ms_layer_desc_layer_type = -1;
+static int hf_h264_sei_ms_layer_desc_prid = -1;
+static int hf_h264_sei_ms_layer_desc_cb = -1;
+/* Microsoft Bitstream SEI */
+static int hf_h264_sei_ms_bitstream_ref_frame_cnt = -1;
+static int hf_h264_sei_ms_bitstream_num_nalus = -1;
+/* Microsoft Crop SEI */
+static int hf_h264_sei_ms_crop_num_data = -1;
+static int hf_h264_sei_ms_crop_info_type = -1;
+static int hf_h264_sei_ms_crop_confidence_level = -1;
+static int hf_h264_sei_ms_crop_frame_left_offset = -1;
+static int hf_h264_sei_ms_crop_frame_right_offset = -1;
+static int hf_h264_sei_ms_crop_frame_top_offset = -1;
+static int hf_h264_sei_ms_crop_frame_bottom_offset = -1;
+/* SVC NAL Header Extension Values Annex G.7.3.1.1 */
+static int hf_h264_nal_hdr_ext_svc = -1;
+static int hf_h264_nal_hdr_ext_i = -1;
+static int hf_h264_nal_hdr_ext_prid = -1;
+static int hf_h264_nal_hdr_ext_n = -1;
+static int hf_h264_nal_hdr_ext_did = -1;
+static int hf_h264_nal_hdr_ext_qid = -1;
+static int hf_h264_nal_hdr_ext_tid = -1;
+static int hf_h264_nal_hdr_ext_u = -1;
+static int hf_h264_nal_hdr_ext_d = -1;
+static int hf_h264_nal_hdr_ext_o = -1;
+static int hf_h264_nal_hdr_ext_rr = -1;
+/* PACSI Values */
+static int hf_h264_pacsi_x = -1;
+static int hf_h264_pacsi_y = -1;
+static int hf_h264_pacsi_t = -1;
+static int hf_h264_pacsi_a = -1;
+static int hf_h264_pacsi_p = -1;
+static int hf_h264_pacsi_c = -1;
+static int hf_h264_pacsi_s = -1;
+static int hf_h264_pacsi_e = -1;
+static int hf_h264_pacsi_tl0picidx = -1;
+static int hf_h264_pacsi_idrpicid = -1;
+static int hf_h264_pacsi_donc = -1;
/* VUI parameters */
static int hf_h264_aspect_ratio_info_present_flag = -1;
@@ -188,8 +255,15 @@ static int ett_h264_nal_unit = -1;
static int ett_h264_par_profile = -1;
static int ett_h264_par_AdditionalModesSupported = -1;
static int ett_h264_par_ProfileIOP = -1;
+static int ett_h264_ms_layer_description = -1;
+static int ett_h264_ms_crop_data = -1;
static expert_field ei_h264_undecoded = EI_INIT;
+static expert_field ei_h264_ms_layout_missing_presence = EI_INIT;
+static expert_field ei_h264_ms_layout_wrong_length = EI_INIT;
+static expert_field ei_h264_bad_nal_length = EI_INIT;
+static expert_field ei_h264_ms_sei_extra_data = EI_INIT;
+static expert_field ei_h264_sei_invalid_length = EI_INIT;
/* The dynamic payload type range which will be dissected as H.264 */
@@ -233,6 +307,14 @@ static const true_false_string h264_forbidden_bit_vals = {
#define H264_SEQ_PAR_SET 7
#define H264_PIC_PAR_SET 8
+#define H264_PREFIX 14
+#define H264_STAP_A 24
+#define H264_STAP_B 25
+#define H264_MTAP16 26
+#define H264_MTAP24 27
+#define H264_PACSI 30
+#define H264_EXTENSION 31
+
static const value_string h264_type_values[] = {
{ 0, "Undefined" },
@@ -249,24 +331,74 @@ static const value_string h264_type_values[] = {
{ 11, "NAL unit - End of stream" },
{ 12, "NAL unit - Filler data" },
{ 13, "NAL unit - Sequence parameter set extension" },
- { 14, "NAL unit - Reserved" },
- { 15, "NAL unit - Reserved" },
+ { H264_PREFIX, "NAL unit - Prefix" },
+ { 15, "NAL unit - Subset sequence parameter set" },
{ 16, "NAL unit - Reserved" },
{ 17, "NAL unit - Reserved" },
{ 18, "NAL unit - Reserved" },
{ 19, "NAL unit - Coded slice of an auxiliary coded picture without partitioning" },
- { 20, "NAL unit - Reserved" },
- { 21, "NAL unit - Reserved" },
+ { 20, "NAL unit - Coded slice extension" },
+ { 21, "NAL unit - Coded slice extension for depth view components" },
{ 22, "NAL unit - Reserved" },
{ 23, "NAL unit - Reserved" },
- { 24, "STAP-A" }, /* Single-time aggregation packet */
- { 25, "STAP-B" }, /* Single-time aggregation packet */
- { 26, "MTAP16" }, /* Multi-time aggregation packet */
- { 27, "MTAP24" }, /* Multi-time aggregation packet */
- { 28, "FU-A" }, /* Fragmentation unit */
- { 29, "FU-B" }, /* Fragmentation unit */
- { 30, "undefined" },
- { 31, "undefined" },
+ { 24, "Single-time aggregation packet A (STAP-A)" },
+ { 25, "Single-time aggregation packet B (STAP-B)" },
+ { 26, "Multi-time aggregation packet 16 (MTAP16)" },
+ { 27, "Multi-time aggregation packet 24 (MTAP24)" },
+ { 28, "Fragmentation unit A (FU-A)" },
+ { 29, "Fragmentation unit B (FU-B)" },
+ { 30, "NAL unit - Payload Content Scalability Information (PACSI)" },
+ { 31, "NAL unit - Extended NAL Header" },
+ { 0, NULL }
+};
+
+static const value_string h264_type_summary_values[] = {
+ { 0, "Undefined" },
+ { 1, "non-IDR-Slice" }, /* Single NAL unit packet per H.264 */
+ { 2, "Slice-A" },
+ { 3, "Slice-B" },
+ { 4, "Slice-C" },
+ { 5, "IDR-Slice" },
+ { 6, "SEI" },
+ { H264_SEQ_PAR_SET, "SPS" }, /* 7 */
+ { H264_PIC_PAR_SET, "PPS" }, /* 8 */
+ { 9, "Access-Delimiter" },
+ { 10, "End-of-Seq" },
+ { 11, "End-of-Stream" },
+ { 12, "Filler" },
+ { 13, "SPS-Ext" },
+ { H264_PREFIX, "Prefix" },
+ { 15, "Reserved" },
+ { 16, "Reserved" },
+ { 17, "Reserved" },
+ { 18, "Reserved" },
+ { 19, "Slice-Aux" },
+ { 20, "Slice-Ext" },
+ { 21, "Slice-Ext-Depth" },
+ { 22, "Reserved" },
+ { 23, "Reserved" },
+ { 24, "STAP-A" },
+ { 25, "STAP-B" },
+ { 26, "MTAP16" },
+ { 27, "MTAP24" },
+ { 28, "FU-A" },
+ { 29, "FU-B" },
+ { 30, "PACSI" },
+ { 31, "EXT" },
+ { 0, NULL }
+};
+
+/* Extension Subtype Strings RFC 6190 4.3 */
+static const value_string h264_subtype_values[] = {
+ { 0, "Reserved" },
+ { 1, "NAL Unit - Empty" },
+ { 2, "Non-interleaved Multi-Time Aggregation Packet (NI-MTAP)" },
+ { 0, NULL }
+};
+static const value_string h264_subtype_summary_values[] = {
+ { 0, "Reserved" },
+ { 1, "Empty" },
+ { 2, "NI-MTAP" },
{ 0, NULL }
};
@@ -274,10 +406,14 @@ static const value_string h264_type_values[] = {
static const value_string h264_profile_idc_values[] = {
{ 66, "Baseline profile" },
{ 77, "Main profile" },
+ { 83, "Scalable Baseline" },
+ { 86, "Scalable High" },
{ 88, "Extended profile" },
{ 100, "High profile" },
{ 110, "High 10 profile" },
+ { 118, "Multi-view High" },
{ 122, "High 4:2:2 profile" },
+ { 128, "Stereo High" },
{ 144, "High 4:4:4 profile" },
{ 0, NULL }
};
@@ -299,6 +435,7 @@ static const value_string h264_level_bitrate_values[] = {
{ 42, "50 Mb/s" },
{ 50, "135 Mb/s" },
{ 51, "240 Mb/s" },
+ { 52, "240 Mb/s" },
{ 0, NULL }
};
@@ -317,14 +454,14 @@ static const value_string h264_nal_unit_type_vals[] = {
{ 11, "End of stream" },
{ 12, "Filler data" },
{ 13, "Sequence parameter set extension" },
- { 14, "Reserved" },
- { 15, "Reserved" },
+ { 14, "Prefix" },
+ { 15, "Subset sequence parameter set" },
{ 16, "Reserved" },
{ 17, "Reserved" },
{ 18, "Reserved" },
{ 19, "Coded slice of an auxiliary coded picture without partitioning" },
- { 20, "Reserved" },
- { 21, "Reserved" },
+ { 20, "Coded slice extension" },
+ { 21, "Coded slice extension for depth view components" },
{ 22, "Reserved" },
{ 23, "Reserved" },
{ 24, "Unspecified" },
@@ -364,6 +501,31 @@ static const value_string h264_slice_type_vals[] = {
{ 0, NULL }
};
+/* Microsoft Frame per second index */
+static const value_string h264_sei_ms_frame_values[] = {
+ { 0, "7.5 fps" },
+ { 1, "12.5 fps" },
+ { 2, "15 fps" },
+ { 3, "25 fps" },
+ { 4, "30 fps" },
+ { 5, "50 fps" },
+ { 6, "60 fps" },
+ { 0, NULL }
+};
+
+/* Microsoft UUIDs from MS-H264-PF */
+#define MS_LAYOUT 0
+#define MS_CROPPING 1
+#define MS_BITSTREAM 2
+static const e_guid_t ms_guids[3] = {
+ { 0x139FB1A9, 0x446A, 0x4DEC, {0x8C, 0xBF, 0x65, 0xB1, 0xE1, 0x2D, 0x2C, 0xFD}}, /* Stream Layout */
+ { 0xBB7FC1A0, 0x6986, 0x4052, {0x90, 0xF0, 0x09, 0x29, 0x21, 0x75, 0x39, 0xCF}}, /* Cropping Information*/
+ { 0x05FBC6B9, 0x5A80, 0x40E5, {0xA2, 0x2A, 0xAB, 0x40, 0x20, 0x26, 0x7E, 0x26}} /* Bitstream Information */
+};
+
+static void
+dissect_h264(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
+
/* byte_aligned( ) is specified as follows.
* - If the current position in the bitstream is on a byte boundary, i.e.,
* the next bit in the bitstream is the first bit in a byte,
@@ -1019,7 +1181,9 @@ dissect_h264_profile(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
proto_tree_add_item(h264_profile_tree, hf_h264_constraint_set1_flag, tvb, offset, 1, ENC_BIG_ENDIAN);
proto_tree_add_item(h264_profile_tree, hf_h264_constraint_set2_flag, tvb, offset, 1, ENC_BIG_ENDIAN);
proto_tree_add_item(h264_profile_tree, hf_h264_constraint_set3_flag, tvb, offset, 1, ENC_BIG_ENDIAN);
- proto_tree_add_item(h264_profile_tree, hf_h264_reserved_zero_4bits, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(h264_profile_tree, hf_h264_constraint_set4_flag, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(h264_profile_tree, hf_h264_constraint_set5_flag, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(h264_profile_tree, hf_h264_reserved_zero_2bits, tvb, offset, 1, ENC_BIG_ENDIAN);
offset++;
/* A level to which the bitstream conforms shall be indicated by the syntax element level_idc as follows.
@@ -1176,20 +1340,141 @@ dissect_h264_slice_data_partition_c_layer_rbsp(proto_tree *tree, tvbuff_t *tvb,
static int
h264_user_data_unregistered(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo _U_, gint bit_offset, guint32 payloadSize)
{
+ guint8 i;
+ guint8 ld_size;
+ guint8 p_flag;
+ guint8 desc =0;
+ guint8 num_crops;
+ gint offset = bit_offset >> 3;
+ proto_item *item;
+ proto_item *uuid_item;
+ proto_tree *h264_ms_layer_desc_tree;
+ proto_tree *h264_ms_crop_data_tree;
+ e_guid_t guid;
+
+
/* user_data_unregistered( payloadSize ) { C Descriptor */
/* uuid_iso_iec_11578 5 u(128)
* uuid_iso_iec_11578 shall have a value specified as a UUID
* according to the procedures of ISO/IEC 11578:1996 Annex A.
*/
- proto_tree_add_text(tree, tvb, bit_offset>>3, 16, "uuid_iso_iec_1157");
- bit_offset+=128;
+
+ uuid_item = proto_tree_add_item (tree, hf_h264_sei_uuid, tvb, offset, 16, ENC_BIG_ENDIAN);
+ /* Extract the ISO/IEC value for comparison */
+ tvb_get_ntohguid(tvb, offset, &guid);
+ offset+=16;
+
+ /* Microsoft MS-H264PF Specification */
+ if ( memcmp(&guid, &(ms_guids[MS_LAYOUT]), sizeof(e_guid_t)) == 0)
+ {
+ col_append_fstr(pinfo->cinfo, COL_INFO, ":MS_Layout");
+ proto_item_append_text(uuid_item," - Microsoft Stream Layout SEI Message");
+ /* Loop through the layer presence bytes 0-7 */
+ for (i = 0; i < 8 ; i++)
+ {
+ proto_tree_add_item (tree, hf_h264_sei_ms_lpb, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset++;
+ }
+ /* Get the presence bit for the layer description.
+ * NOTE: This byte is supposed to be in the structure according to the spec but seems to be missing in the Microsoft implementation.
+ * So to determine if it is there check for a value less than or equal to 1. When Microsoft forgets to put it in the length is next and that
+ * has a minimum size of 16.
+ */
+ p_flag = tvb_get_guint8 (tvb, offset);
+ if (p_flag <= 1)
+ {
+ proto_tree_add_item (tree, hf_h264_sei_ms_layout_p, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset++;
+ }
+ else
+ {
+ /* When it is missing act like it was set to 1. */
+ proto_tree_add_expert(tree, pinfo, &ei_h264_ms_layout_missing_presence, tvb, offset, 0);
+ p_flag = 1;
+ }
+ if (p_flag == 1)
+ {
+ ld_size = tvb_get_guint8 (tvb, offset);
+ proto_tree_add_item (tree, hf_h264_sei_ms_layout_ldsize, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset++;
+ /* MS Errata - Microsoft seems to be setting the LD size to 1 but then including 2 layer descriptions
+ * To compensate for that keep decoding layers as long as there are 16 or more bytes left in the SEI message.
+ */
+ if (tvb_reported_length_remaining (tvb, offset) != ld_size)
+ {
+ item = proto_tree_add_expert(tree, pinfo, &ei_h264_ms_layout_wrong_length, tvb, offset-1, 1);
+ proto_item_append_text(item," Size of %d, remaining size %d",
+ ld_size,
+ tvb_reported_length_remaining (tvb, offset));
+ }
+ while (tvb_reported_length_remaining (tvb, offset) >= 16)
+ {
+ h264_ms_layer_desc_tree = proto_tree_add_subtree_format(tree, tvb, offset, 16, ett_h264_ms_layer_description, NULL, "MS Layer Description #%d", ++desc);
+
+ proto_tree_add_item (h264_ms_layer_desc_tree, hf_h264_sei_ms_layer_desc_coded_width, tvb, offset, 2, ENC_BIG_ENDIAN);
+ proto_tree_add_item (h264_ms_layer_desc_tree, hf_h264_sei_ms_layer_desc_coded_height, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
+ proto_tree_add_item (h264_ms_layer_desc_tree, hf_h264_sei_ms_layer_desc_display_width, tvb, offset + 4, 2, ENC_BIG_ENDIAN);
+ proto_tree_add_item (h264_ms_layer_desc_tree, hf_h264_sei_ms_layer_desc_display_height, tvb, offset + 6, 2, ENC_BIG_ENDIAN);
+ proto_tree_add_item (h264_ms_layer_desc_tree, hf_h264_sei_ms_layer_desc_bitrate, tvb, offset + 8, 4, ENC_BIG_ENDIAN);
+ proto_tree_add_item (h264_ms_layer_desc_tree, hf_h264_sei_ms_layer_desc_frame_rate, tvb, offset + 12, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item (h264_ms_layer_desc_tree, hf_h264_sei_ms_layer_desc_layer_type, tvb, offset + 12, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item (h264_ms_layer_desc_tree, hf_h264_sei_ms_layer_desc_prid, tvb, offset + 13, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item (h264_ms_layer_desc_tree, hf_h264_sei_ms_layer_desc_cb, tvb, offset + 13, 1, ENC_BIG_ENDIAN);
+ offset += 16;
+ }
+ if (tvb_reported_length_remaining (tvb, offset) != 0)
+ {
+ item = proto_tree_add_expert(tree, pinfo, &ei_h264_ms_sei_extra_data, tvb, offset, tvb_reported_length_remaining (tvb, offset));
+ proto_item_append_text(item," Extra %d bytes", tvb_reported_length_remaining (tvb, offset));
+ /* Skip over data. */
+ offset += tvb_reported_length_remaining (tvb, offset);
+ }
+ }
+ }
+ else if ( memcmp(&guid, &(ms_guids[MS_CROPPING]), sizeof(e_guid_t)) == 0)
+ {
+ col_append_fstr(pinfo->cinfo, COL_INFO, ":MS_Cropping");
+ proto_item_append_text(uuid_item," - Microsoft Cropping Info SEI Message");
+ num_crops = tvb_get_guint8 (tvb, offset);
+ proto_tree_add_item (tree, hf_h264_sei_ms_crop_num_data, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset++;
+ proto_tree_add_item (tree, hf_h264_sei_ms_crop_info_type, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset++;
+ while (num_crops != 0)
+ {
+ h264_ms_crop_data_tree = proto_tree_add_subtree_format(tree, tvb, offset, 9, ett_h264_ms_crop_data, NULL, "Crop Data #%d", ++desc);
+ proto_tree_add_item (h264_ms_crop_data_tree, hf_h264_sei_ms_crop_confidence_level, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item (h264_ms_crop_data_tree, hf_h264_sei_ms_crop_frame_left_offset, tvb, offset+1, 2, ENC_BIG_ENDIAN);
+ proto_tree_add_item (h264_ms_crop_data_tree, hf_h264_sei_ms_crop_frame_right_offset, tvb, offset+3, 2, ENC_BIG_ENDIAN);
+ proto_tree_add_item (h264_ms_crop_data_tree, hf_h264_sei_ms_crop_frame_top_offset, tvb, offset+5, 2, ENC_BIG_ENDIAN);
+ proto_tree_add_item (h264_ms_crop_data_tree, hf_h264_sei_ms_crop_frame_bottom_offset, tvb, offset+7, 2, ENC_BIG_ENDIAN);
+ num_crops--;
+ offset += 9;
+ }
+ }
+ else if ( memcmp(&guid, &(ms_guids[MS_BITSTREAM]), sizeof(e_guid_t)) == 0)
+ {
+ col_append_fstr(pinfo->cinfo, COL_INFO, ":MS_Bitstream");
+ proto_item_append_text(uuid_item," - Microsoft Bitstream Info SEI Message");
+ proto_tree_add_item (tree, hf_h264_sei_ms_bitstream_ref_frame_cnt, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset++;
+ proto_tree_add_item (tree, hf_h264_sei_ms_bitstream_num_nalus, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset++;
+ }
+ else
+ {
+ proto_tree_add_text(tree, tvb, offset, 16, "Unparsed iso_iec information");
/* for (i = 16; i < payloadSize; i++)
* user_data_payload_byte 5 b(8)
*/
- proto_tree_add_text(tree, tvb, bit_offset>>3, payloadSize-16, "user_data_payload");
- bit_offset+=(payloadSize-16)<<3;
+ if (payloadSize > 16)
+ {
+ proto_tree_add_expert(tree, pinfo, &ei_h264_undecoded, tvb, offset, payloadSize-16);
+ offset+=(payloadSize-16);
+ }
+ }
- return bit_offset;
+ return offset << 3;
}
/* D.1 SEI payload syntax */
@@ -1216,7 +1501,23 @@ static const value_string h264_sei_payload_vals[] = {
{ 19, "film_grain_characteristics)" },
{ 20, "deblocking_filter_display_preference)" },
{ 21, "stereo_video_info)" },
- { 22, "reserved_sei_message)" },
+ { 22, "post_filter_hint" },
+ { 23, "tone_mapping_info" },
+ /* Annex G Values */
+ { 24, "scalability_info" },
+ { 25, "sub_pic_scalable_layer" },
+ { 26, "non_required_layer_rep" },
+ { 27, "priority_layer_info" },
+ { 28, "layers_not_present" },
+ { 29, "layer_dependency_change" },
+ { 30, "scalable_nesting" },
+ { 31, "base_layer_temporal_hrd" },
+ { 32, "quality_layer_integrity_check" },
+ { 33, "redundant_pic_property" },
+ { 34, "tl0_dep_rep_index" },
+ { 35, "tl_switching_point" },
+ /* Annex H 37 to 46 - Not Decoded*/
+ /* Annex I 47 to 53 - Not Decoded*/
{ 0, NULL }
};
@@ -1357,7 +1658,10 @@ dissect_h264_sei_rbsp(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo _U_, g
* the return value of more_rbsp_data( ) is equal to TRUE.
*/
/* rbsp_trailing_bits( ) 5 */
+ if (tvb_reported_length_remaining (tvb, bit_offset >> 3) != 0 || (bit_offset & 0x7) != 0)
+ {
bit_offset = dissect_h264_rbsp_trailing_bits(tree, tvb, pinfo, bit_offset);
+ }
return bit_offset;
}
@@ -1394,8 +1698,14 @@ dissect_h264_seq_parameter_set_rbsp(proto_tree *tree, tvbuff_t *tvb, packet_info
/* constraint_set3_flag 0 u(1) */
proto_tree_add_item(tree, hf_h264_constraint_set3_flag, tvb, offset, 1, ENC_BIG_ENDIAN);
+ /* constraint_set4_flag 0 u(1) */
+ proto_tree_add_item(tree, hf_h264_constraint_set4_flag, tvb, offset, 1, ENC_BIG_ENDIAN);
+
+ /* constraint_set5_flag 0 u(1) */
+ proto_tree_add_item(tree, hf_h264_constraint_set5_flag, tvb, offset, 1, ENC_BIG_ENDIAN);
+
/* reserved_zero_4bits equal to 0 0 u(4)*/
- proto_tree_add_item(tree, hf_h264_reserved_zero_4bits, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(tree, hf_h264_reserved_zero_2bits, tvb, offset, 1, ENC_BIG_ENDIAN);
offset++;
/* level_idc 0 u(8) */
@@ -1416,7 +1726,11 @@ dissect_h264_seq_parameter_set_rbsp(proto_tree *tree, tvbuff_t *tvb, packet_info
if ((profile_idc == 100) || (profile_idc == 110) ||
- (profile_idc == 122) || (profile_idc == 144)) {
+ (profile_idc == 122) || (profile_idc == 144) ||
+ (profile_idc == 44) || (profile_idc == 83) ||
+ (profile_idc == 86) || (profile_idc == 118) ||
+ (profile_idc == 128) || (profile_idc == 138))
+ {
/* chroma_format_idc 0 ue(v) */
chroma_format_idc = dissect_h264_exp_golomb_code(tree, hf_h264_chroma_format_idc, tvb, &bit_offset, H264_UE_V);
@@ -1543,6 +1857,7 @@ dissect_h264_seq_parameter_set_rbsp(proto_tree *tree, tvbuff_t *tvb, packet_info
offset = bit_offset>>3;
+ /* TODO - Add dissector of SPS SVC extension from Annex G*/
return offset;
}
@@ -1727,9 +2042,298 @@ dissect_h264_seq_parameter_set_extension_rbsp(proto_tree *tree, tvbuff_t *tvb, p
proto_tree_add_expert(tree, pinfo, &ei_h264_undecoded, tvb, offset, -1);
}
+/* RFC 6190 Section: 1.1.3 - NAL Unit Header Extension - H.264 Annex G*/
+static gint
+dissect_h264_svc_nal_header_extension(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, gint offset)
+{
+ proto_tree_add_item(tree, hf_h264_nal_hdr_ext_svc, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(tree, hf_h264_nal_hdr_ext_i, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(tree, hf_h264_nal_hdr_ext_prid, tvb, offset, 1, ENC_BIG_ENDIAN);
+
+ proto_tree_add_item(tree, hf_h264_nal_hdr_ext_n, tvb, offset + 1, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(tree, hf_h264_nal_hdr_ext_did, tvb, offset + 1, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(tree, hf_h264_nal_hdr_ext_qid, tvb, offset + 1, 1, ENC_BIG_ENDIAN);
+
+ proto_tree_add_item(tree, hf_h264_nal_hdr_ext_tid, tvb, offset + 2, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(tree, hf_h264_nal_hdr_ext_u, tvb, offset + 2, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(tree, hf_h264_nal_hdr_ext_d, tvb, offset + 2, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(tree, hf_h264_nal_hdr_ext_o, tvb, offset + 2, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(tree, hf_h264_nal_hdr_ext_rr, tvb, offset + 2, 1, ENC_BIG_ENDIAN);
+
+ return offset + 3;
+}
+/* H.264 Annex G Prefix NAL Unit */
+
+static int dissect_h264_prefix(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, gint offset)
+{
+ guint8 svc_extension_flag;
+
+ svc_extension_flag = tvb_get_bits8(tvb, offset << 3, 1);
+ if (svc_extension_flag)
+ {
+ /* Annex G NAL Unit Header SVC Extension */
+ dissect_h264_svc_nal_header_extension (tree, tvb, pinfo, offset);
+ }
+ else
+ {
+ /* Annex H NAL Unit Header MVC Extension */
+ /* Not Decoded */
+ offset +=3;
+ }
+ return offset;
+}
+
+/* RFC 6190 Section: 4.9 - Payload Content Scalability Information (PACSI) */
+static void
+dissect_h264_pacsi(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, gint offset)
+{
+ gint8 pacsi_flags;
+ guint16 nal_unit_size;
+ tvbuff_t *nalu_tvb;
+ gboolean error = FALSE;
+ gboolean contains_sei = FALSE;
+ proto_item *item;
+
+ offset = dissect_h264_svc_nal_header_extension(tree, tvb, pinfo, offset);
+
+ pacsi_flags = tvb_get_guint8(tvb, offset);
+ proto_tree_add_item(tree, hf_h264_pacsi_x, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(tree, hf_h264_pacsi_y, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(tree, hf_h264_pacsi_t, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(tree, hf_h264_pacsi_a, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(tree, hf_h264_pacsi_p, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(tree, hf_h264_pacsi_c, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(tree, hf_h264_pacsi_s, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(tree, hf_h264_pacsi_e, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset++;
+
+ if (pacsi_flags & 0x40)
+ {
+ proto_tree_add_item(tree, hf_h264_pacsi_tl0picidx, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset++;
+ proto_tree_add_item(tree, hf_h264_pacsi_idrpicid, tvb, offset, 2, ENC_BIG_ENDIAN);
+ offset += 2;
+ }
+ if (pacsi_flags & 0x20)
+ {
+ proto_tree_add_item(tree, hf_h264_pacsi_donc, tvb, offset, 2, ENC_BIG_ENDIAN);
+ offset += 2;
+ }
+ if (tvb_reported_length_remaining(tvb, offset) > 0)
+ {
+ contains_sei = TRUE;
+ col_append_fstr(pinfo->cinfo, COL_INFO, "(");
+ }
+
+ /* Decode the SEI units that are in the packet. */
+ while (tvb_reported_length_remaining(tvb, offset) > 0 && !error)
+ {
+ nal_unit_size = tvb_get_ntohs(tvb, offset);
+ /* Perform a sanity check on the value. */
+ if (nal_unit_size == 0 || nal_unit_size > tvb_reported_length_remaining(tvb, offset))
+ {
+ /* Microsoft has a bug where it doesn't put in the P flag byte in the Layout message, but sets the size as if is there, so the size is off by
+ * byte too many in the first SEI message. Back up one and then try again.
+ */
+ item = proto_tree_add_expert(tree, pinfo, &ei_h264_sei_invalid_length, tvb, offset, 2);
+ proto_item_append_text (item, " Size is %d, Remaining:%d, Try backing up 1 byte.",
+ nal_unit_size, tvb_reported_length_remaining(tvb, offset));
+ offset--;
+ nal_unit_size = tvb_get_ntohs(tvb, offset);
+ }
+ proto_tree_add_item(tree, hf_h264_nalu_size, tvb, offset, 2, ENC_NA);
+ offset += 2;
+
+ if (nal_unit_size == 0 || nal_unit_size > tvb_reported_length_remaining(tvb, offset))
+ {
+ item = proto_tree_add_expert(tree, pinfo, &ei_h264_bad_nal_length, tvb, offset-2, 2);
+ error = TRUE;
+ }
+ else
+ {
+ /* Make a new subset of the existing buffer for the NAL unit */
+ nalu_tvb = tvb_new_subset(tvb, offset, tvb_captured_length_remaining(tvb,offset), nal_unit_size);
+ /* Decode the NAL unit */
+ dissect_h264(nalu_tvb, pinfo, tree);
+ offset += nal_unit_size;
+ }
+ }
+ if (contains_sei == TRUE)
+ {
+ col_append_fstr(pinfo->cinfo, COL_INFO, ")");
+ }
+}
/*
- * Dissect NAL unit as recived in sprop-parameter-sets of SDP
+ * RFC 3984 Section 5.7.1 - Single-Time Aggregation Packet (STAP)
+ */
+static void
+dissect_h264_stap(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo _U_, gint offset, gint8 nal_type)
+{
+ guint16 nal_unit_size;
+ tvbuff_t *nalu_tvb;
+ proto_item *item;
+
+ /* If it is a STAP-B then the Decoder Order Number if present before the NAL Units */
+ if (nal_type == H264_STAP_B)
+ {
+ proto_tree_add_item(tree, hf_h264_don, tvb, offset, 2, ENC_NA);
+ offset += 2;
+ }
+
+ while (tvb_reported_length_remaining(tvb, offset) > 0)
+ {
+ /* Get the size of the NAL unit and display */
+ proto_tree_add_item(tree, hf_h264_nalu_size, tvb, offset, 2, ENC_NA);
+ nal_unit_size = tvb_get_ntohs(tvb, offset);
+ offset += 2;
+
+ /* Do a sanity check on the unit size versus what is left in the packet. */
+ if (nal_unit_size == 0 || tvb_reported_length_remaining(tvb, offset) < nal_unit_size)
+ {
+ /* Throw an exception if the size is wrong and don't try to decode the rest of the packet. */
+ col_append_fstr(pinfo->cinfo, COL_INFO, " [Bad NAL Length]");
+ item = proto_tree_add_expert (tree, pinfo, &ei_h264_bad_nal_length, tvb, offset-2, 2);
+ proto_item_append_text(item, " Size of %d, Remaining %d",
+ nal_unit_size, tvb_reported_length_remaining(tvb, offset));
+ offset += tvb_reported_length_remaining(tvb, offset);
+ }
+ else
+ {
+ /* Make a new subset of the existing buffer for the NAL unit */
+ nalu_tvb = tvb_new_subset(tvb, offset, tvb_captured_length_remaining(tvb, offset), nal_unit_size);
+ /* Decode the NAL unit */
+ dissect_h264(nalu_tvb, pinfo, tree);
+ offset += nal_unit_size;
+ }
+ }
+}
+
+/*
+ * RFC 3984 Section 5.7.2 Multi-Time Aggregation Packet (MTAP)
+ */
+static void
+dissect_h264_mtap(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo _U_, gint offset, gint8 nal_type)
+{
+ gint size_offset;
+ guint16 nal_unit_size;
+ tvbuff_t *nalu_tvb;
+ proto_item *item;
+
+ /* Get the DON base value for type MTAP16 & MTAP24 */
+ proto_tree_add_item(tree, hf_h264_don, tvb, offset, 2, ENC_NA);
+ offset += 2;
+
+ while (tvb_reported_length_remaining(tvb, offset) > 0)
+ {
+ proto_tree_add_item(tree, hf_h264_nalu_size, tvb, offset, 2, ENC_NA);
+ nal_unit_size = tvb_get_ntohs(tvb, offset);
+ size_offset = offset;
+ offset += 2;
+ proto_tree_add_item(tree, hf_h264_dond, tvb, offset, 1, ENC_NA);
+ offset += 1;
+
+ if (nal_type == H264_MTAP16)
+ {
+ /* Get the 16 bit DOND value */
+ proto_tree_add_item(tree, hf_h264_ts_offset16, tvb, offset, 2, ENC_NA);
+ offset += 2;
+ }
+ else
+ {
+ /* Get the 24 bit DOND value */
+ proto_tree_add_item(tree, hf_h264_ts_offset24, tvb, offset, 2, ENC_NA);
+ offset += 3;
+ }
+
+ if (nal_unit_size == 0 || tvb_reported_length_remaining(tvb, offset) < nal_unit_size)
+ {
+ /* Throw an exception if the size is wrong and don't try to decode the rest of the packet. */
+ col_append_fstr(pinfo->cinfo, COL_INFO, " [Bad NAL Length]");
+ item = proto_tree_add_expert (tree, pinfo, &ei_h264_bad_nal_length, tvb, size_offset, 2);
+ proto_item_append_text(item, " Size of %d, Remaining %d",
+ nal_unit_size, tvb_reported_length_remaining(tvb, offset));
+ offset += tvb_reported_length_remaining(tvb, offset);
+ }
+ else
+ {
+ /* Make a new subset of the existing buffer for the NAL unit */
+ nalu_tvb = tvb_new_subset(tvb, offset, tvb_captured_length_remaining(tvb, offset), nal_unit_size);
+ /* Decode the NAL unit */
+ dissect_h264(nalu_tvb, pinfo, tree);
+ offset += nal_unit_size;
+ }
+ }
+}
+
+/*
+ * Dissect NAL Header extension and NI-MTAP Subtype defined in RFC 6190
+ */
+static void
+dissect_h264_nalu_extension (proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo _U_, gint offset)
+{
+ gint size_offset;
+ guint16 nal_unit_size;
+ tvbuff_t *nalu_tvb;
+ guint8 subtype;
+ guint8 j_flag;
+ guint8 bit_offset = offset << 3;
+ guint8 unit = 1;
+ proto_item *item;
+
+ subtype = tvb_get_bits8(tvb, bit_offset, 5);
+ j_flag = tvb_get_bits8(tvb, bit_offset+5, 1);
+
+ /* NAL Header Extension Decoding */
+ proto_tree_add_item(tree, hf_h264_nal_extension_subtype, tvb, offset, 1, ENC_NA);
+ proto_tree_add_item(tree, hf_h264_nal_extension_j, tvb, offset, 1, ENC_NA);
+ proto_tree_add_item(tree, hf_h264_nal_extension_k, tvb, offset, 1, ENC_NA);
+ proto_tree_add_item(tree, hf_h264_nal_extension_l, tvb, offset, 1, ENC_NA);
+ col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
+ val_to_str(subtype, h264_subtype_summary_values, "Unknown Subtype (%u)"));
+ offset++;
+
+ if (subtype == 2)
+ {
+ /* Multi-Time Aggregation Packet (NI-MTAP) - RFC 6190 Section 4.7.1 */
+ while (tvb_reported_length_remaining(tvb, offset) > 0)
+ {
+ proto_tree_add_text(tree, tvb, offset, 1, "NI-MTAP Unit %d", unit++);
+ proto_tree_add_item(tree, hf_h264_nalu_size, tvb, offset, 2, ENC_NA);
+ nal_unit_size = tvb_get_ntohs(tvb, offset);
+ size_offset = offset;
+ offset += 2;
+ proto_tree_add_item(tree, hf_h264_ts_offset16, tvb, offset, 2, ENC_NA);
+ offset += 2;
+ /* If J flag is set then DON is present in packet */
+ if (j_flag)
+ {
+ proto_tree_add_item(tree, hf_h264_don, tvb, offset, 2, ENC_NA);
+ offset += 2;
+ }
+ if (nal_unit_size == 0 || tvb_reported_length_remaining(tvb, offset) < nal_unit_size)
+ {
+ /* Throw an exception if the size is wrong and don't try to decode the rest of the packet. */
+ col_append_fstr(pinfo->cinfo, COL_INFO, " [Bad NAL Length]");
+ item = proto_tree_add_expert (tree, pinfo, &ei_h264_bad_nal_length, tvb, size_offset, 2);
+ proto_item_append_text(item, " Size of %d, Remaining %d",
+ nal_unit_size, tvb_reported_length_remaining(tvb, offset));
+ offset += tvb_reported_length_remaining(tvb, offset);
+ }
+ else
+ {
+ /* Make a new subset of the existing buffer for the NAL unit */
+ nalu_tvb = tvb_new_subset(tvb, offset, tvb_captured_length_remaining(tvb, offset), nal_unit_size);
+ /* Decode the NAL unit */
+ dissect_h264(nalu_tvb, pinfo, tree);
+ offset += nal_unit_size;
+ }
+ }
+ }
+}
+
+/*
+ * Dissect NAL unit as received in sprop-parameter-sets of SDP
* or "DecoderConfiguration parameter in H.245
*/
void
@@ -1847,13 +2451,13 @@ dissect_h264(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
tvbuff_t *rbsp_tvb;
-/* Make entries in Protocol column and Info column on summary display */
+ /* Make entries in Protocol column and Info column on summary display */
col_set_str(pinfo->cinfo, COL_PROTOCOL, "H264");
type = tvb_get_guint8(tvb, offset)&0x1f;
col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
- val_to_str(type, h264_type_values, "Unknown Type (%u)"));
+ val_to_str(type, h264_type_summary_values, "Unknown Type (%u)"));
if (tree) {
item = proto_tree_add_item(tree, proto_h264, tvb, 0, -1, ENC_NA);
@@ -1891,16 +2495,23 @@ dissect_h264(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
proto_tree_add_item(fua_tree, hf_h264_nal_unit_type, tvb, offset, 1, ENC_BIG_ENDIAN);
if ((tvb_get_guint8(tvb, offset)&0x80) == 0x80) {
type = tvb_get_guint8(tvb, offset)&0x1f;
+ col_append_fstr(pinfo->cinfo, COL_INFO, " Start:%s",
+ val_to_str(type, h264_type_summary_values, "Unknown Type (%u)"));
offset++;
}
else
+ {
+ if ((tvb_get_guint8(tvb, offset)&0x40) == 0x40) {
+ col_append_fstr(pinfo->cinfo, COL_INFO, " End");
+ }
return;
}
+ }
/* Unescape NAL unit */
rbsp_tvb = dissect_h265_unescap_nal_unit(tvb, pinfo, offset);
- stream_tree = proto_tree_add_subtree(h264_tree, tvb, offset, -1, ett_h264_stream, NULL, "H264 bitstream");
+ stream_tree = proto_tree_add_subtree(h264_tree, tvb, offset, -1, ett_h264_stream, NULL, "H264 NAL Unit Payload");
switch (type) {
case 1: /* 1 Coded slice of a non-IDR picture */
dissect_h264_slice_layer_without_partitioning_rbsp(stream_tree, rbsp_tvb, pinfo, 0);
@@ -1923,9 +2534,26 @@ dissect_h264(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
case H264_PIC_PAR_SET: /* 8 Picture parameter set */
dissect_h264_pic_parameter_set_rbsp(stream_tree, rbsp_tvb, pinfo, 0);
break;
+ case H264_PREFIX:
+ dissect_h264_prefix(stream_tree, rbsp_tvb, pinfo, 0);
+ break;
case 19: /* Coded slice of an auxiliary coded picture without partitioning */
dissect_h264_slice_layer_without_partitioning_rbsp(stream_tree, rbsp_tvb, pinfo, 0);
break;
+ case H264_STAP_A: /* STAP-A */
+ case H264_STAP_B: /* STAP-B */
+ dissect_h264_stap(stream_tree, tvb, pinfo, offset, type);
+ break;
+ case H264_MTAP16: /* MSTAP16 */
+ case H264_MTAP24: /* MSTAP24 */
+ dissect_h264_mtap(stream_tree, tvb, pinfo, offset, type);
+ break;
+ case H264_PACSI: /* PACSI */
+ dissect_h264_pacsi(stream_tree, tvb, pinfo, offset);
+ break;
+ case H264_EXTENSION: /* Extension Header */
+ dissect_h264_nalu_extension(stream_tree, rbsp_tvb, pinfo, 0);
+ break;
default:
break;
}
@@ -2208,9 +2836,19 @@ proto_register_h264(void)
FT_UINT8, BASE_DEC, NULL, 0x10,
NULL, HFILL }
},
- { &hf_h264_reserved_zero_4bits,
- { "Reserved_zero_4bits", "h264.reserved_zero_4bits",
- FT_UINT8, BASE_DEC, NULL, 0x0f,
+ { &hf_h264_constraint_set4_flag,
+ { "Constraint_set4_flag", "h264.constraint_set4_flag",
+ FT_UINT8, BASE_DEC, NULL, 0x08,
+ NULL, HFILL }
+ },
+ { &hf_h264_constraint_set5_flag,
+ { "Constraint_set5_flag", "h264.constraint_set5_flag",
+ FT_UINT8, BASE_DEC, NULL, 0x04,
+ NULL, HFILL }
+ },
+ { &hf_h264_reserved_zero_2bits,
+ { "Reserved_zero_2bits", "h264.reserved_zero_2bits",
+ FT_UINT8, BASE_DEC, NULL, 0x03,
NULL, HFILL }
},
{ &hf_h264_level_idc,
@@ -2773,6 +3411,280 @@ proto_register_h264(void)
{ "constraint_set2_flag", "h264.par.constraint_set2_flag",
FT_BOOLEAN, 8, NULL, 0x20,
NULL, HFILL}},
+ /* Packization Values */
+ { &hf_h264_nalu_size,
+ { "NAL Unit Size", "h264.nalu_size",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_h264_don,
+ { "Decoder Order Number", "h264.don",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_h264_dond,
+ { "MTAP Decoder Order Number Delta", "h264.don_delta",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_h264_ts_offset16,
+ { "MTAP TS Offset", "h264.ts_offset16",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_h264_ts_offset24,
+ { "MTAP TS Offset", "h264.ts_offset24",
+ FT_UINT24, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_h264_nal_extension_subtype,
+ { "Extension Header Subtype", "h264.nal_hdr_extension.subtype",
+ FT_UINT8, BASE_DEC, VALS(h264_subtype_values), 0xF8,
+ NULL, HFILL }
+ },
+ { &hf_h264_nal_extension_j,
+ { "Extension Header J - DON Present Indicator", "h264.nal_hdr_extension.j",
+ FT_BOOLEAN, 8, NULL, 0x4,
+ NULL, HFILL }
+ },
+ { &hf_h264_nal_extension_k,
+ { "Extension Header K", "h264.nal_hdr_extension.k",
+ FT_BOOLEAN, 8, NULL, 0x2,
+ NULL, HFILL }
+ },
+ { &hf_h264_nal_extension_l,
+ { "Extension Header L", "h264.nal_hdr_extension.l",
+ FT_BOOLEAN, 8, NULL, 0x1,
+ NULL, HFILL }
+ },
+
+ /* SEI Parsing values */
+ { &hf_h264_sei_uuid,
+ { "UUID", "h264.sei.uuid",
+ FT_GUID, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_h264_sei_ms_lpb,
+ { "Stream Layer Presence", "h264.sei.ms.layout.lpb",
+ FT_UINT8, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_h264_sei_ms_layout_p,
+ { "Stream Layer Description Presence", "h264.sei.ms.layout.p",
+ FT_BOOLEAN, 8, NULL, 0x01,
+ NULL, HFILL }
+ },
+ { &hf_h264_sei_ms_layout_ldsize,
+ { "Stream Layer Description Size", "h264.sei.ms.layout.desc.ldsize",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_h264_sei_ms_layer_desc_coded_width,
+ { "Coded Width", "h264.sei.ms.layout.desc.coded_width",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_h264_sei_ms_layer_desc_coded_height,
+ { "Coded Height", "h264.sei.ms.layout.desc.coded_height",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_h264_sei_ms_layer_desc_display_width,
+ { "Display Width", "h264.sei.ms.layout.desc.display_width",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_h264_sei_ms_layer_desc_display_height,
+ { "Display Height", "h264.sei.ms.layout.desc.display_height",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_h264_sei_ms_layer_desc_bitrate,
+ { "Bitrate", "h264.sei.ms.layout.desc.bitrate",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_h264_sei_ms_layer_desc_frame_rate,
+ { "Frame Rate Index", "h264.sei.ms.layout.desc.frame_rate",
+ FT_UINT8, BASE_DEC, VALS(h264_sei_ms_frame_values), 0xF8,
+ NULL, HFILL }
+ },
+ { &hf_h264_sei_ms_layer_desc_layer_type,
+ { "Layer Type", "h264.sei.ms.layout.desc.layer_type",
+ FT_UINT8, BASE_DEC, NULL, 0x07,
+ NULL, HFILL }
+ },
+ { &hf_h264_sei_ms_layer_desc_prid,
+ { "Priority ID", "h264.sei.ms.layout.desc.prid",
+ FT_UINT8, BASE_DEC, NULL, 0xFC,
+ NULL, HFILL }
+ },
+ { &hf_h264_sei_ms_layer_desc_cb,
+ { "Constrained Baseline", "h264.sei.ms.layout.desc.constrained_baseline",
+ FT_BOOLEAN, 8, NULL, 0x02,
+ NULL, HFILL }
+ },
+ /* MS Bitstream SEI */
+ { &hf_h264_sei_ms_bitstream_ref_frame_cnt,
+ { "Reference Frame Count", "h264.sei.ms.bitstream_info.ref_frm_cnt",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_h264_sei_ms_bitstream_num_nalus,
+ { "Number of NAL units", "h264.sei.ms.bitstrea3416m_info.num_nalus",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ /* MS Crop SEI */
+ { &hf_h264_sei_ms_crop_num_data,
+ { "Number of Data Entries", "h264.sei.ms.crop.num_data",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_h264_sei_ms_crop_info_type,
+ { "Info Type", "h264.sei.ms.crop.info_type",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_h264_sei_ms_crop_confidence_level,
+ { "Confidence Level", "h264.sei.ms.crop.confidence_level",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_h264_sei_ms_crop_frame_left_offset,
+ { "Left Offset", "h264.sei.ms.crop.left_offset",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_h264_sei_ms_crop_frame_right_offset,
+ { "Right Offset", "h264.sei.ms.crop.right_offset",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_h264_sei_ms_crop_frame_top_offset,
+ { "Top Offset", "h264.sei.ms.crop.top_offset",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_h264_sei_ms_crop_frame_bottom_offset,
+ { "Bottom Offset", "h264.sei.ms.crop.bottom_offset",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ /* NALU Header Extension */
+ /* Annex G NAL Unit Header SVC Extension */
+ { &hf_h264_nal_hdr_ext_svc,
+ { "SVC Extension / Reserved", "h264.nal_hdr_ext.r",
+ FT_BOOLEAN, 8, NULL, 0x80,
+ NULL, HFILL }
+ },
+ { &hf_h264_nal_hdr_ext_i,
+ { "IDR Picture", "h264.nal_hdr_ext.i",
+ FT_BOOLEAN, 8, NULL, 0x40,
+ NULL, HFILL }
+ },
+ { &hf_h264_nal_hdr_ext_prid,
+ { "Priority ID", "h264.nal_hdr_ext.prid",
+ FT_UINT8, BASE_DEC, NULL, 0x3f,
+ NULL, HFILL }
+ },
+ { &hf_h264_nal_hdr_ext_n,
+ { "No Inter Layer Prediction", "h264.nal_hdr_ext.n",
+ FT_BOOLEAN, 8, NULL, 0x80,
+ NULL, HFILL }
+ },
+ { &hf_h264_nal_hdr_ext_did,
+ { "Dependency ID", "h264.nal_hdr_ext.did",
+ FT_UINT8, BASE_DEC, NULL, 0x70,
+ NULL, HFILL }
+ },
+ { &hf_h264_nal_hdr_ext_qid,
+ { "Quality ID", "h264.nal_hdr_ext.qid",
+ FT_UINT8, BASE_DEC, NULL, 0x0f,
+ NULL, HFILL }
+ },
+ { &hf_h264_nal_hdr_ext_tid,
+ { "Temporal ID", "h264.nal_hdr_ext.tid",
+ FT_UINT8, BASE_DEC, NULL, 0xe0,
+ NULL, HFILL }
+ },
+ { &hf_h264_nal_hdr_ext_u,
+ { "Use Ref Base Picture", "h264.nal_hdr_ext.u",
+ FT_BOOLEAN, 8, NULL, 0x10,
+ NULL, HFILL }
+ },
+ { &hf_h264_nal_hdr_ext_d,
+ { "Discardable", "h264.nal_hdr_ext.d",
+ FT_BOOLEAN, 8, NULL, 0x08,
+ NULL, HFILL }
+ },
+ { &hf_h264_nal_hdr_ext_o,
+ { "Output", "h264.nal_hdr_ext.o",
+ FT_BOOLEAN, 8, NULL, 0x04,
+ NULL, HFILL }
+ },
+ { &hf_h264_nal_hdr_ext_rr,
+ { "Reserved", "h264.nal_hdr_ext.rr",
+ FT_UINT8, BASE_HEX, NULL, 0x03,
+ NULL, HFILL }
+ },
+ /* PACSI Values */
+ { &hf_h264_pacsi_x,
+ { "X - A,P,C Field Indicator", "h264.pacsi.x",
+ FT_BOOLEAN, 8, NULL, 0x80,
+ NULL, HFILL }
+ },
+ { &hf_h264_pacsi_y,
+ { "Y - Pic Fields Indicator", "h264.pacsi.y",
+ FT_BOOLEAN, 8, NULL, 0x40,
+ NULL, HFILL }
+ },
+ { &hf_h264_pacsi_t,
+ { "T - DONC Field Indicator", "h264.pacsi.t",
+ FT_BOOLEAN, 8, NULL, 0x20,
+ NULL, HFILL }
+ },
+ { &hf_h264_pacsi_a,
+ { "A - Anchor Layer", "h264.pacsi.a",
+ FT_BOOLEAN, 8, NULL, 0x10,
+ NULL, HFILL }
+ },
+ { &hf_h264_pacsi_p,
+ { "P - Redundant Slice", "h264.pacsi.p",
+ FT_BOOLEAN, 8, NULL, 0x08,
+ NULL, HFILL }
+ },
+ { &hf_h264_pacsi_c,
+ { "C - Intra Slice", "h264.pacsi.c",
+ FT_BOOLEAN, 8, NULL, 0x04,
+ NULL, HFILL }
+ },
+ { &hf_h264_pacsi_s,
+ { "S - First Nal Unit of Layer", "h264.pacsi.s",
+ FT_BOOLEAN, 8, NULL, 0x02,
+ NULL, HFILL }
+ },
+ { &hf_h264_pacsi_e,
+ { "E - Last Nal Unit of Layer", "h264.pacsi.e",
+ FT_BOOLEAN, 8, NULL, 0x01,
+ NULL, HFILL }
+ },
+ { &hf_h264_pacsi_tl0picidx,
+ { "TL0PICIDX", "h264.pacsi.tl0picidx",
+ FT_UINT8, BASE_DEC, NULL, 0xFF,
+ NULL, HFILL }
+ },
+ { &hf_h264_pacsi_idrpicid,
+ { "IDRPICID - IDR Picture ID", "h264.pacsi.idrpicid",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_h264_pacsi_donc,
+ { "DONC - Cross Session Decoder Order Number", "h264.pacsi.donc",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+
};
/* Setup protocol subtree array */
@@ -2786,10 +3698,17 @@ proto_register_h264(void)
&ett_h264_par_profile,
&ett_h264_par_AdditionalModesSupported,
&ett_h264_par_ProfileIOP,
+ &ett_h264_ms_layer_description,
+ &ett_h264_ms_crop_data
};
static ei_register_info ei[] = {
{ &ei_h264_undecoded, { "h264.undecoded", PI_UNDECODED, PI_WARN, "[Not decoded yet]", EXPFILL }},
+ { &ei_h264_ms_layout_missing_presence, { "h264.ms_layout.missing_presence", PI_PROTOCOL, PI_WARN, "[Missing Presence Byte]", EXPFILL }},
+ { &ei_h264_ms_layout_wrong_length, { "h264.ms_layout.wrong_length", PI_PROTOCOL, PI_WARN, "[Wrong Layer Description Table Length]", EXPFILL }},
+ { &ei_h264_ms_sei_extra_data, { "h264.sei_extra_data", PI_PROTOCOL, PI_WARN, "[Extra data in SEI message]", EXPFILL }},
+ { &ei_h264_sei_invalid_length, { "h264.sei_invalid_length", PI_PROTOCOL, PI_WARN, "[Bad SEI Unit Size in PACSI]", EXPFILL }},
+ { &ei_h264_bad_nal_length, { "h264.bad_nalu_length", PI_MALFORMED, PI_ERROR, "[Bad NAL Unit Length]", EXPFILL }},
};
/* Register the protocol name and description */
@@ -2829,6 +3748,8 @@ proto_reg_handoff_h264(void)
h264_handle = find_dissector("h264");
dissector_add_string("rtp_dyn_payload_type","H264", h264_handle);
+ dissector_add_string("rtp_dyn_payload_type","H264-SVC", h264_handle);
+ dissector_add_string("rtp_dyn_payload_type","X-H264UC", h264_handle);
h264_name_handle = new_create_dissector_handle(dissect_h264_name, proto_h264);
for (ftr=h264_capability_tab; ftr->id; ftr++) {
diff --git a/epan/dissectors/packet-sdp.c b/epan/dissectors/packet-sdp.c
index a62eb19166..c5555d8b57 100644
--- a/epan/dissectors/packet-sdp.c
+++ b/epan/dissectors/packet-sdp.c
@@ -1184,7 +1184,7 @@ decode_sdp_fmtp(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, gint offset
* in bit-significance order, starting from the
* most significant bit, and 3) level_idc.
*/
- if ((mime_type != NULL) && (g_ascii_strcasecmp(mime_type, "H264") == 0)) {
+ if ((mime_type != NULL) && ((g_ascii_strcasecmp(mime_type, "H264") == 0) || (g_ascii_strcasecmp(mime_type, "H264-SVC") == 0))) {
if (strcmp(field_name, "profile-level-id") == 0) {
int length = 0;