diff options
author | Marouen Ghodhbane <marouen.ghodhbane@nxp.com> | 2017-12-19 18:02:19 +0100 |
---|---|---|
committer | Anders Broman <a.broman58@gmail.com> | 2017-12-21 11:39:42 +0000 |
commit | af0c46fb92d952e4502d817fba02441db4047010 (patch) | |
tree | c597bb5a1c830743238ca3939a1bb69823a645c3 /epan/dissectors/packet-ieee1722.c | |
parent | 00974e1dc4bccb23491dca5fe1f9bf0f24833915 (diff) |
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>
Diffstat (limited to 'epan/dissectors/packet-ieee1722.c')
-rw-r--r-- | epan/dissectors/packet-ieee1722.c | 324 |
1 files changed, 322 insertions, 2 deletions
diff --git a/epan/dissectors/packet-ieee1722.c b/epan/dissectors/packet-ieee1722.c index a1256d94fc..9284c77266 100644 --- a/epan/dissectors/packet-ieee1722.c +++ b/epan/dissectors/packet-ieee1722.c @@ -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 */ @@ -128,6 +136,36 @@ void proto_reg_handoff_1722_61883(void); #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 */ /* */ /**************************************************************************************************/ @@ -442,6 +480,81 @@ static int ett_1722_crf_timestamp = -1; 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); } @@ -1221,6 +1334,213 @@ void proto_reg_handoff_1722_aaf(void) } /**************************************************************************************************/ +/* 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 */ /* */ /**************************************************************************************************/ |