ieee1722: Add dissectors for Compressed Video format (H264 and MJPEG)

This dissector is implemented according to "IEEE Std 1722-
2016 Parag 8: Compressed Video Format"

Change-Id: I39668e7b8665f6b11461d55f16b40bf3942c9c8d
Signed-off-by: Marouen Ghodhbane <marouen.ghodhbane@nxp.com>
Reviewed-on: https://code.wireshark.org/review/24914
Reviewed-by: Pascal Quantin <pascal.quantin@gmail.com>
Petri-Dish: Pascal Quantin <pascal.quantin@gmail.com>
Tested-by: Petri Dish Buildbot
Reviewed-by: Anders Broman <a.broman58@gmail.com>
This commit is contained in:
Marouen Ghodhbane 2017-12-19 18:02:19 +01:00 committed by Anders Broman
parent 00974e1dc4
commit af0c46fb92
1 changed files with 322 additions and 2 deletions

View File

@ -13,6 +13,11 @@
* IEC 61883-6 audio/music data transmission protocol improved.
* Changes to meet 1722 Draft 15 specification.
*
* Copyright 2017, Marouen Ghodhbane <marouen.ghodhbane@nxp.com>
* Dissection for the 1722 Compressed Video subtype added.
* CVF Format subtype supported: H264 and MJPEG
* The dissection meets the 1722-2016 specification.
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
@ -50,6 +55,8 @@ void proto_register_1722_aaf(void);
void proto_reg_handoff_1722_aaf(void);
void proto_register_1722_61883(void);
void proto_reg_handoff_1722_61883(void);
void proto_register_1722_cvf(void);
void proto_reg_handoff_1722_cvf(void);
/**************************************************************************************************/
/* 1722 */
@ -57,6 +64,7 @@ void proto_reg_handoff_1722_61883(void);
/**************************************************************************************************/
#define IEEE_1722_SUBTYPE_61883 0x00
#define IEEE_1722_SUBTYPE_AAF 0x02
#define IEEE_1722_SUBTYPE_CVF 0x03
#define IEEE_1722_SUBTYPE_CRF 0x04
/* Bit Field Masks */
@ -127,6 +135,36 @@ void proto_reg_handoff_1722_61883(void);
#define IEEE_1722_DATA_MASK 0x00
#define IEEE_1722_SAMPLE_MASK 0x00
/**************************************************************************************************/
/* subtype CVF */
/* */
/**************************************************************************************************/
#define IEEE_1722_CVF_FORMAT_SUBTYPE_MJPEG 0x00
#define IEEE_1722_CVF_FORMAT_SUBTYPE_H264 0x01
#define IEEE_1722_CVF_FORMAT_SUBTYPE_JPEG2000 0x02
/* Bit Field Masks */
#define IEEE_1722_MR_MASK 0x08
#define IEEE_1722_TV_MASK 0x01
#define IEEE_1722_SEQ_NUM_MASK 0x00
#define IEEE_1722_TU_MASK 0x01
#define IEEE_1722_STREAM_ID_MASK 0x00
#define IEEE_1722_TIMESTAMP_MASK 0x00
#define IEEE_1722_FORMAT_MASK 0x00
#define IEEE_1722_FORMAT_SUBTYPE_MASK 0x00
#define IEEE_1722_CVF_H264_TIMESTAMP_MASK 0x00
#define IEEE_1722_CVF_H264_FORBIDDEN_MASK 0x80
#define IEEE_1722_CVF_H264_NRI_MASK 0x60
#define IEEE_1722_CVF_H264_NAL_TYPE_MASK 0x1f
#define IEEE_1722_CVF_MJPEG_TS_MASK 0x00
#define IEEE_1722_CVF_MJPEG_FRAGMENT_OFFSET_MASK 0x00
#define IEEE_1722_CVF_MJPEG_TYPE_MASK 0x00
#define IEEE_1722_CVF_MJPEG_Q_MASK 0x00
#define IEEE_1722_CVF_MJPEG_WIDTH_MASK 0x00
#define IEEE_1722_CVF_MJPEG_HEIGHT_MASK 0x00
#define IEEE_1722_MARKER_BIT_MASK 0x10
#define IEEE_1722_EVT_MASK 0x0f
/**************************************************************************************************/
/* subtype CRF */
/* */
@ -441,6 +479,81 @@ static int ett_1722_crf_timestamp = -1;
/* Initialize expert fields */
static expert_field ei_crf_datalen = EI_INIT;
/**************************************************************************************************/
/* subtype CVF */
/* */
/**************************************************************************************************/
static const range_string cvf_format_range_rvals [] = {
{0, 1, "Reserved"},
{2, 2, "RFC payload type"},
{3, 0xff, "Reserved"},
{0, 0, NULL}
};
static const true_false_string tfs_marker_bit_set_not_set = { "Marker Bit is set", "Marker bit not set" };
static const range_string cvf_format_subtype_range_rvals [] = {
{0, 0, "MJPEG Format (RFC2435)"},
{1, 1, "H264 Format"},
{2, 2, "JPEG 2000 Video"},
{3, 0xff, "Reserved"},
{0, 0, NULL}
};
static const range_string cvf_h264_nal_type_range_rvals [] = {
{0x00, 0x00, "Undefined"},
{0x01, 0x17, "Single Nal Unit Packet"},
{0x18, 0x18, "STAP-A"},
{0x19, 0x19, "STAP-B"},
{0x1a, 0x1a, "MTAP16"},
{0x1b, 0x1b, "MTAP24"},
{0x1c, 0x1c, "FU-A"},
{0x1d, 0x1d, "FU-B"},
{0x1e, 0xff, "Unspecified"},
{0, 0, NULL}
};
static const range_string cvf_mjpeg_ts_range_rvals [] = {
{0, 0, "MJPEG TYPE SPEC PROGRESSIVE"},
{1, 1, "MJPEG TYPE SPEC ODD"},
{2, 2, "MJPEG TYPE SPEC EVEN"},
{3, 3, "MJPEG TYPE SPEC SINGLE"},
{3, 0xff, "Unspecified"},
{0, 0, NULL}
};
/* Initialize the protocol and registered fields */
static int proto_1722_cvf = -1;
static int hf_1722_cvf_mrfield = -1;
static int hf_1722_cvf_tvfield = -1;
static int hf_1722_cvf_seqnum = -1;
static int hf_1722_cvf_tufield = -1;
static int hf_1722_cvf_stream_id = -1;
static int hf_1722_cvf_avtp_timestamp = -1;
static int hf_1722_cvf_format = -1;
static int hf_1722_cvf_format_subtype = -1;
static int hf_1722_cvf_stream_data_length = -1;
static int hf_1722_cvf_evtfield = -1;
static int hf_1722_cvf_marker_bit = -1;
static int hf_1722_cvf_h264_timestamp = -1;
static int hf_1722_cvf_h264_forbidden_bit = -1;
static int hf_1722_cvf_h264_nri = -1;
static int hf_1722_cvf_h264_nal_type = -1;
static int hf_1722_cvf_mjpeg_ts = -1;
static int hf_1722_cvf_mjpeg_fragment_offset = -1;
static int hf_1722_cvf_mjpeg_type = -1;
static int hf_1722_cvf_mjpeg_q = -1;
static int hf_1722_cvf_mjpeg_width = -1;
static int hf_1722_cvf_mjpeg_height = -1;
/* Initialize the subtree pointers */
static int ett_1722_cvf = -1;
/* Initialize expert fields */
static expert_field ei_cvf_jpeg2000_format = EI_INIT;
static expert_field ei_cvf_reserved_format = EI_INIT;
/**************************************************************************************************/
/* 1722 dissector implementation */
/* */
@ -467,7 +580,7 @@ static int dissect_1722(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, voi
offset += 1;
proto_tree_add_bitmask_list(ieee1722_tree, tvb, offset, 1, fields, ENC_NA);
/* call any registered subtype dissectors which use only the common AVTPDU (e.g. 1722.1, MAAP, 61883, AAF or CRF) */
/* call any registered subtype dissectors which use only the common AVTPDU (e.g. 1722.1, MAAP, 61883, AAF, CRF or CVF) */
if (dissector_try_uint(avb_dissector_table, subtype, tvb, pinfo, tree))
return tvb_captured_length(tvb);
@ -503,7 +616,7 @@ void proto_register_1722(void)
proto_register_field_array(proto_1722, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
/* Sub-dissector for 1772.1, 1722 AAF, 1722 CRF, 1722 61883 */
/* Sub-dissector for 1772.1, 1722 AAF, 1722 CRF, 1722 61883, 1722 CVF */
avb_dissector_table = register_dissector_table("ieee1722.subtype",
"IEEE1722 AVBTP Subtype", proto_1722, FT_UINT8, BASE_HEX);
}
@ -1220,6 +1333,213 @@ void proto_reg_handoff_1722_aaf(void)
dissector_add_uint("ieee1722.subtype", IEEE_1722_SUBTYPE_AAF, avb1722_aaf_handle);
}
/**************************************************************************************************/
/* 1722 CVF dissector implementation */
/* */
/**************************************************************************************************/
static int dissect_1722_cvf (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
{
proto_item *ti;
proto_tree *ti_cvf_tree;
gint offset = 1;
guint format_subtype = 0;
proto_tree *ti_format;
const gint *fields[] = {
&hf_1722_cvf_mrfield,
&hf_1722_cvf_tvfield,
NULL
};
const gint *fields_cvf[] = {
&hf_1722_cvf_marker_bit,
&hf_1722_cvf_evtfield,
NULL
};
const gint *fields_h264[] = {
&hf_1722_cvf_h264_forbidden_bit,
&hf_1722_cvf_h264_nri,
&hf_1722_cvf_h264_nal_type,
NULL
};
ti = proto_tree_add_item(tree, proto_1722_cvf, tvb, 0, -1, ENC_NA);
ti_cvf_tree = proto_item_add_subtree(ti, ett_1722_cvf);
proto_tree_add_bitmask_list(ti_cvf_tree, tvb, offset, 1, fields, ENC_NA);
offset += 1;
proto_tree_add_item(ti_cvf_tree, hf_1722_cvf_seqnum, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
proto_tree_add_item(ti_cvf_tree, hf_1722_cvf_tufield, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
proto_tree_add_item(ti_cvf_tree, hf_1722_cvf_stream_id, tvb, offset, 8, ENC_BIG_ENDIAN);
offset += 8;
proto_tree_add_item(ti_cvf_tree, hf_1722_cvf_avtp_timestamp, tvb, offset, 4, ENC_BIG_ENDIAN);
offset += 4;
proto_tree_add_item(ti_cvf_tree, hf_1722_cvf_format, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
ti_format = proto_tree_add_item_ret_uint(ti_cvf_tree, hf_1722_cvf_format_subtype, tvb, offset, 1, ENC_BIG_ENDIAN, &format_subtype);
offset += 3;
proto_tree_add_item(ti_cvf_tree, hf_1722_cvf_stream_data_length, tvb, offset, 2, ENC_BIG_ENDIAN);
offset += 2;
proto_tree_add_bitmask_list(ti_cvf_tree, tvb, offset, 1, fields_cvf, ENC_BIG_ENDIAN);
offset += 2;
switch(format_subtype) {
case IEEE_1722_CVF_FORMAT_SUBTYPE_MJPEG:
proto_tree_add_item(ti_cvf_tree, hf_1722_cvf_mjpeg_ts, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
proto_tree_add_item(ti_cvf_tree, hf_1722_cvf_mjpeg_fragment_offset, tvb, offset, 3, ENC_BIG_ENDIAN);
offset += 3;
proto_tree_add_item(ti_cvf_tree, hf_1722_cvf_mjpeg_type, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
proto_tree_add_item(ti_cvf_tree, hf_1722_cvf_mjpeg_q, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
proto_tree_add_item(ti_cvf_tree, hf_1722_cvf_mjpeg_width, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
proto_tree_add_item(ti_cvf_tree, hf_1722_cvf_mjpeg_height, tvb, offset, 1, ENC_BIG_ENDIAN);
break;
case IEEE_1722_CVF_FORMAT_SUBTYPE_H264:
proto_tree_add_item(ti_cvf_tree, hf_1722_cvf_h264_timestamp, tvb, offset, 4, ENC_BIG_ENDIAN);
offset += 4;
proto_tree_add_bitmask_list(ti_cvf_tree, tvb, offset, 1, fields_h264, ENC_BIG_ENDIAN);
break;
case IEEE_1722_CVF_FORMAT_SUBTYPE_JPEG2000:
expert_add_info(pinfo, ti_format, &ei_cvf_jpeg2000_format);
break;
default:
expert_add_info(pinfo, ti_format, &ei_cvf_reserved_format);
break;
}
return tvb_captured_length(tvb);
}
void proto_register_1722_cvf (void)
{
static hf_register_info hf[] =
{
{ &hf_1722_cvf_mrfield,
{ "Media Clock Restart", "cvf.mrfield",
FT_BOOLEAN, 8, NULL, IEEE_1722_MR_MASK, NULL, HFILL }
},
{ &hf_1722_cvf_tvfield,
{ "Source Timestamp Valid", "cvf.tvfield",
FT_BOOLEAN, 8, NULL, IEEE_1722_TV_MASK, NULL, HFILL }
},
{ &hf_1722_cvf_seqnum,
{ "Sequence Number", "cvf.seqnum",
FT_UINT8, BASE_DEC, NULL, IEEE_1722_SEQ_NUM_MASK, NULL, HFILL }
},
{ &hf_1722_cvf_tufield,
{ "Timestamp Uncertain", "cvf.tufield",
FT_BOOLEAN, 8, NULL, IEEE_1722_TU_MASK, NULL, HFILL }
},
{ &hf_1722_cvf_stream_id,
{ "Stream ID", "cvf.stream_id",
FT_UINT64, BASE_HEX, NULL, IEEE_1722_STREAM_ID_MASK, NULL, HFILL }
},
{ &hf_1722_cvf_avtp_timestamp,
{ "AVTP Timestamp", "cvf.avtp_timestamp",
FT_UINT32, BASE_DEC, NULL, IEEE_1722_TIMESTAMP_MASK, NULL, HFILL }
},
{ &hf_1722_cvf_format,
{ "Format", "cvf.format",
FT_UINT8, BASE_HEX | BASE_RANGE_STRING, RVALS(cvf_format_range_rvals), IEEE_1722_FORMAT_MASK, NULL, HFILL }
},
{ &hf_1722_cvf_format_subtype,
{ "CVF Format Subtype", "cvf.format_subtype",
FT_UINT8, BASE_HEX | BASE_RANGE_STRING, RVALS(cvf_format_subtype_range_rvals), IEEE_1722_FORMAT_SUBTYPE_MASK, NULL, HFILL }
},
{ &hf_1722_cvf_stream_data_length,
{ "Stream Data Length", "cvf.stream_data_len",
FT_UINT16, BASE_DEC | BASE_UNIT_STRING, &units_byte_bytes, IEEE_1722_STREAM_DATA_LENGTH_MASK, NULL, HFILL }
},
{ &hf_1722_cvf_marker_bit,
{ "Marker Bit", "cvf.marker_bit",
FT_BOOLEAN, 8, TFS(&tfs_marker_bit_set_not_set), IEEE_1722_MARKER_BIT_MASK, NULL, HFILL }
},
{ &hf_1722_cvf_evtfield,
{ "EVT", "cvf.evtfield",
FT_UINT8, BASE_HEX, NULL, IEEE_1722_EVT_MASK, NULL, HFILL }
},
{ &hf_1722_cvf_h264_timestamp,
{ "H264 Timestamp", "cvf.h264_timestamp",
FT_UINT32, BASE_DEC, NULL, IEEE_1722_CVF_H264_TIMESTAMP_MASK, NULL, HFILL }
},
{ &hf_1722_cvf_h264_forbidden_bit,
{ "H264 Forbidden Bit", "cvf.h264_f_bit",
FT_BOOLEAN, 8, NULL, IEEE_1722_CVF_H264_FORBIDDEN_MASK, NULL, HFILL }
},
{ &hf_1722_cvf_h264_nri,
{ "H264 NRI", "cvf.h264_nri",
FT_UINT8, BASE_HEX, NULL, IEEE_1722_CVF_H264_NRI_MASK, NULL, HFILL }
},
{ &hf_1722_cvf_h264_nal_type,
{ "H264 NAL Type", "cvf.h264_nal_type",
FT_UINT8, BASE_HEX | BASE_RANGE_STRING, RVALS(cvf_h264_nal_type_range_rvals), IEEE_1722_CVF_H264_NAL_TYPE_MASK, NULL, HFILL }
},
{ &hf_1722_cvf_mjpeg_ts,
{ "MJPEG Type Specific", "cvf.mjpeg_type_specific",
FT_UINT8, BASE_DEC | BASE_RANGE_STRING, RVALS(cvf_mjpeg_ts_range_rvals), IEEE_1722_CVF_MJPEG_TS_MASK, NULL, HFILL }
},
{ &hf_1722_cvf_mjpeg_fragment_offset,
{ "MJPEG Fragment Offset", "cvf.mjpeg_fragment_offset",
FT_UINT24, BASE_DEC, NULL, IEEE_1722_CVF_MJPEG_FRAGMENT_OFFSET_MASK, NULL, HFILL }
},
{ &hf_1722_cvf_mjpeg_type,
{ "MJPEG Type", "cvf.mjpeg_type",
FT_UINT8, BASE_DEC, NULL, IEEE_1722_CVF_MJPEG_TYPE_MASK, NULL, HFILL }
},
{ &hf_1722_cvf_mjpeg_q,
{ "MJPEG Q", "cvf.mjpeg_q",
FT_UINT8, BASE_DEC, NULL, IEEE_1722_CVF_MJPEG_Q_MASK, NULL, HFILL }
},
{ &hf_1722_cvf_mjpeg_width,
{ "MJPEG Width", "cvf.mjpeg_width",
FT_UINT8, BASE_DEC, NULL, IEEE_1722_CVF_MJPEG_WIDTH_MASK, NULL, HFILL }
},
{ &hf_1722_cvf_mjpeg_height,
{ "MJPEG Height", "cvf.mjpeg_height",
FT_UINT8, BASE_DEC, NULL, IEEE_1722_CVF_MJPEG_HEIGHT_MASK, NULL, HFILL }
},
};
static ei_register_info ei[] = {
{ &ei_cvf_jpeg2000_format, { "cvf.expert.jpeg2000_video", PI_PROTOCOL, PI_WARN, "JPEG2000 format is currently not supported", EXPFILL }},
{ &ei_cvf_reserved_format, { "cvf.expert.reserved_format", PI_PROTOCOL, PI_WARN, "Incorrect format, can`t be dissected", EXPFILL }}
};
static gint *ett[] =
{
&ett_1722_cvf,
};
expert_module_t *expert_1722_cvf;
/* Register the protocol name and description */
proto_1722_cvf = proto_register_protocol("AVTP Compressed Video Format", "CVF", "cvf");
/* Required function calls to register the header fields and subtrees used */
proto_register_field_array(proto_1722_cvf, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
expert_1722_cvf = expert_register_protocol(proto_1722_cvf);
expert_register_field_array(expert_1722_cvf, ei, array_length(ei));
}
void proto_reg_handoff_1722_cvf(void)
{
dissector_handle_t avb1722_cvf_handle;
avb1722_cvf_handle = create_dissector_handle(dissect_1722_cvf, proto_1722_cvf);
dissector_add_uint("ieee1722.subtype", IEEE_1722_SUBTYPE_CVF, avb1722_cvf_handle);
}
/**************************************************************************************************/
/* 1722 CRF dissector implementation */
/* */