aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-mpeg-descriptor.c
diff options
context:
space:
mode:
authorDevin Heitmueller <dheitmueller@kernellabs.com>2016-07-25 23:41:55 -0400
committerAnders Broman <a.broman58@gmail.com>2016-08-11 04:03:55 +0000
commitd13f1b0d920c8e079cb7ded8d41e4a530275148d (patch)
tree95d909b5e5f1c8bf806cc061b33aeb72c269bedb /epan/dissectors/packet-mpeg-descriptor.c
parente2b2d986cc3b86ef98ebd92d2e8b5fabb5666a35 (diff)
Add support for PMT parsing of ATSC A/52 Audio stream type and AC-3 descriptor
The ATSC A/52 specification introduces a new PMT stream type, as well as a new descriptor if the A/52 stream contains AC-3 audio. Add dissection for both. Change-Id: I859c76cc4fc6550c72711f00582e6bfa12607fa2 Reviewed-on: https://code.wireshark.org/review/16679 Petri-Dish: Alexis La Goutte <alexis.lagoutte@gmail.com> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Anders Broman <a.broman58@gmail.com>
Diffstat (limited to 'epan/dissectors/packet-mpeg-descriptor.c')
-rw-r--r--epan/dissectors/packet-mpeg-descriptor.c300
1 files changed, 300 insertions, 0 deletions
diff --git a/epan/dissectors/packet-mpeg-descriptor.c b/epan/dissectors/packet-mpeg-descriptor.c
index ab10bfce32..db1eca1cc4 100644
--- a/epan/dissectors/packet-mpeg-descriptor.c
+++ b/epan/dissectors/packet-mpeg-descriptor.c
@@ -150,6 +150,9 @@ static const value_string mpeg_descriptor_tag_vals[] = {
{ 0x7E, "FTA Content Management Descriptor" },
{ 0x7F, "Extension Descriptor" },
+ /* From ATSC A/52 */
+ { 0x81, "ATSC A/52 AC-3 Audio Descriptor" },
+
/* From ETSI EN 301 790 */
{ 0xA0, "Network Layer Info Descriptor" },
{ 0xA1, "Correction Message Descriptor" },
@@ -2402,6 +2405,193 @@ proto_mpeg_descriptor_dissect_extension(tvbuff_t *tvb, guint offset, guint len,
}
+#define MPEG_DESCR_AC3_SYSA_SRATE_MASK 0xe0
+#define MPEG_DESCR_AC3_SYSA_BSID_MASK 0x1f
+#define MPEG_DESCR_AC3_SYSA_BITRATE_CODE_LIMIT_MASK 0x80
+#define MPEG_DESCR_AC3_SYSA_BITRATE_CODE_MASK 0x7c
+#define MPEG_DESCR_AC3_SYSA_SURROUND_MODE_MASK 0x03
+#define MPEG_DESCR_AC3_SYSA_BSMOD_MASK 0xe0
+#define MPEG_DESCR_AC3_SYSA_NUM_CHANNELS_MASK 0x1e
+#define MPEG_DESCR_AC3_SYSA_FULL_SVC_MASK 0x01
+#define MPEG_DESCR_AC3_SYSA_MAINID_MASK 0xe0
+#define MPEG_DESCR_AC3_SYSA_PRIORITY_MASK 0x18
+#define MPEG_DESCR_AC3_SYSA_RESERVED_MASK 0x07
+#define MPEG_DESCR_AC3_SYSA_TEXTLEN_MASK 0xfe
+#define MPEG_DESCR_AC3_SYSA_TEXTCODE_MASK 0x01
+#define MPEG_DESCR_AC3_SYSA_LANG1_MASK 0x80
+#define MPEG_DESCR_AC3_SYSA_LANG2_MASK 0x40
+
+static int hf_mpeg_descr_ac3_sysa_srate = -1;
+static int hf_mpeg_descr_ac3_sysa_bsid = -1;
+static int hf_mpeg_descr_ac3_sysa_bitrate = -1;
+static int hf_mpeg_descr_ac3_sysa_bitrate_limit = -1;
+static int hf_mpeg_descr_ac3_sysa_surround = -1;
+static int hf_mpeg_descr_ac3_sysa_bsmod = -1;
+static int hf_mpeg_descr_ac3_sysa_num_channels = -1;
+static int hf_mpeg_descr_ac3_sysa_full_svc = -1;
+static int hf_mpeg_descr_ac3_sysa_langcode = -1;
+static int hf_mpeg_descr_ac3_sysa_langcode2 = -1;
+static int hf_mpeg_descr_ac3_sysa_mainid = -1;
+static int hf_mpeg_descr_ac3_sysa_priority = -1;
+static int hf_mpeg_descr_ac3_sysa_reserved = -1;
+static int hf_mpeg_descr_ac3_sysa_asvcflags = -1;
+static int hf_mpeg_descr_ac3_sysa_textlen = -1;
+static int hf_mpeg_descr_ac3_sysa_textcode = -1;
+static int hf_mpeg_descr_ac3_sysa_lang1 = -1;
+static int hf_mpeg_descr_ac3_sysa_lang2 = -1;
+static int hf_mpeg_descr_ac3_sysa_lang1_bytes = -1;
+static int hf_mpeg_descr_ac3_sysa_lang2_bytes = -1;
+
+/* ATSC A/52 Annex A Table A4.2*/
+static const value_string mpeg_descr_ac3_sysa_srate_flag_vals[] = {
+ { 0x0, "48 KHz" },
+ { 0x1, "44.1 KHz" },
+ { 0x2, "32 KHz" },
+ { 0x3, "Reserved" },
+ { 0x4, "48 or 44.1 KHz" },
+ { 0x5, "48 or 32 KHz" },
+ { 0x6, "44.1 or 32 KHz" },
+ { 0x7, "48, 44.1 or 32 KHz" },
+ { 0x0, NULL }
+};
+
+/* ATSC A/52 Annex A Table A4.3 */
+static const value_string mpeg_descr_ac3_sysa_bitrate_code_limit_vals[] = {
+ { 0, "Exact bitrate" },
+ { 1, "Upper limit bitrate" },
+ { 0x0, NULL }
+};
+
+static const value_string mpeg_descr_ac3_sysa_bitrate_code_vals[] = {
+ { 0, "32 KHz" },
+ { 1, "40 KHz" },
+ { 2, "48 KHz" },
+ { 3, "56 KHz" },
+ { 4, "64 KHz" },
+ { 5, "80 KHz" },
+ { 6, "96 KHz" },
+ { 7, "112 KHz" },
+ { 8, "128 KHz" },
+ { 9, "160 KHz" },
+ { 10, "192 KHz" },
+ { 11, "224 KHz" },
+ { 12, "256 KHz" },
+ { 13, "320 KHz" },
+ { 14, "384 KHz" },
+ { 15, "448 KHz" },
+ { 16, "512 KHz" },
+ { 17, "576 KHz" },
+ { 18, "640 KHz" },
+ { 0x0, NULL }
+};
+
+/* ATSC A/52 Annex A Table A4.4 */
+static const value_string mpeg_descr_ac3_sysa_surround_mode_vals[] = {
+ { 0x0, "Not indicated" },
+ { 0x1, "NOT Dolby Surround Sound" },
+ { 0x2, "Dolby Surround Sound" },
+ { 0x3, "Reserved" },
+ { 0x0, NULL }
+};
+
+/* ATSC A/52 Annex A Table A4.5*/
+static const value_string mpeg_descr_ac3_sysa_num_channels_vals[] = {
+ { 0x0, "1 + 1 channels" },
+ { 0x1, "1/0 channels" },
+ { 0x2, "2/0 channels" },
+ { 0x3, "3/0 channels" },
+ { 0x4, "2/1 channels" },
+ { 0x5, "3/1 channels" },
+ { 0x6, "2/2 channels" },
+ { 0x7, "3/2 channels" },
+ { 0x8, "1 channel" },
+ { 0x9, "<= 2 channels" },
+ { 0xa, "<= 3 channels" },
+ { 0xb, "<= 4 channels" },
+ { 0xc, "<= 5 channels" },
+ { 0xd, "<= 6 channels" },
+ { 0xe, "Reserved" },
+ { 0xf, "Reserved" },
+ { 0x0, NULL }
+};
+
+/* ATSC A/52 Annex A Table A4.6 */
+static const value_string mpeg_descr_ac3_sysa_priority_vals[] = {
+ { 0x0, "Reserved" },
+ { 0x1, "Primary Audio" },
+ { 0x2, "Other Audio" },
+ { 0x3, "Not specified" },
+ { 0x0, NULL }
+};
+
+/* According to ATSC A/52, Annex A, there are two separate ATSC descriptors. "System A" is used
+ by ATSC, and "System B" is used by DVB. See A/52 Sec A.4.1 for the System A definition */
+static void
+proto_mpeg_descriptor_dissect_ac3_system_a(tvbuff_t *tvb, guint offset, guint len, proto_tree *tree)
+{
+ guint end = offset + len;
+ guint8 bsmod_chans_fullsvc, bsmod, num_channels, textlen, lang;
+
+ proto_tree_add_item(tree, hf_mpeg_descr_ac3_sysa_srate, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(tree, hf_mpeg_descr_ac3_sysa_bsid, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset += 1;
+
+ proto_tree_add_item(tree, hf_mpeg_descr_ac3_sysa_bitrate_limit, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(tree, hf_mpeg_descr_ac3_sysa_bitrate, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(tree, hf_mpeg_descr_ac3_sysa_surround, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset += 1;
+
+ bsmod_chans_fullsvc = tvb_get_guint8(tvb, offset);
+ bsmod = (bsmod_chans_fullsvc & 0xe0) >> 5;
+ num_channels = (bsmod_chans_fullsvc & 0x1e) >> 1;
+ proto_tree_add_item(tree, hf_mpeg_descr_ac3_sysa_bsmod, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(tree, hf_mpeg_descr_ac3_sysa_num_channels, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(tree, hf_mpeg_descr_ac3_sysa_full_svc, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset += 1;
+
+ proto_tree_add_item(tree, hf_mpeg_descr_ac3_sysa_langcode, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset += 1;
+
+ if (num_channels == 0) {
+ /* 1+1 mode, so there is the possibility the second mono is in a different language */
+ proto_tree_add_item(tree, hf_mpeg_descr_ac3_sysa_langcode2, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset += 1;
+ }
+
+ if (bsmod < 2) {
+ proto_tree_add_item(tree, hf_mpeg_descr_ac3_sysa_mainid, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(tree, hf_mpeg_descr_ac3_sysa_priority, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(tree, hf_mpeg_descr_ac3_sysa_reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
+ } else {
+ proto_tree_add_item(tree, hf_mpeg_descr_ac3_sysa_asvcflags, tvb, offset, 1, ENC_BIG_ENDIAN);
+ }
+ offset += 1;
+
+ textlen = tvb_get_guint8(tvb, offset) >> 1;
+ proto_tree_add_item(tree, hf_mpeg_descr_ac3_sysa_textlen, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(tree, hf_mpeg_descr_ac3_sysa_textcode, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset += 1;
+ offset += textlen;
+
+ lang = tvb_get_guint8(tvb, offset);
+ proto_tree_add_item(tree, hf_mpeg_descr_ac3_sysa_lang1, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(tree, hf_mpeg_descr_ac3_sysa_lang2, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset += 1;
+
+ if (lang & 0x80) {
+ proto_tree_add_item(tree, hf_mpeg_descr_ac3_sysa_lang1_bytes, tvb, offset, 3, ENC_ASCII|ENC_NA);
+ offset += 3;
+ }
+
+ if (lang & 0x40) {
+ proto_tree_add_item(tree, hf_mpeg_descr_ac3_sysa_lang2_bytes, tvb, offset, 3, ENC_ASCII|ENC_NA);
+ offset += 3;
+ }
+
+ if (offset < end)
+ proto_tree_add_item(tree, hf_mpeg_descr_ac3_additional_info, tvb, offset, end - offset, ENC_NA);
+}
+
/* 0xA2 Logon Initialize Descriptor */
static int hf_mpeg_descr_logon_initialize_group_id = -1;
static int hf_mpeg_descr_logon_initialize_logon_id = -1;
@@ -2841,6 +3031,9 @@ proto_mpeg_descriptor_dissect(tvbuff_t *tvb, guint offset, proto_tree *tree)
case 0x7F: /* Extension Descriptor */
proto_mpeg_descriptor_dissect_extension(tvb, offset, len, descriptor_tree);
break;
+ case 0x81: /* ATSC A/52 AC-3 Audio Descriptor */
+ proto_mpeg_descriptor_dissect_ac3_system_a(tvb, offset, len, descriptor_tree);
+ break;
case 0xA2: /* Logon Initialize Descriptor */
proto_mpeg_descriptor_dissect_logon_initialize(tvb, offset, len, descriptor_tree);
break;
@@ -4093,6 +4286,113 @@ proto_register_mpeg_descriptor(void)
FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL
} },
+ /* 0x81 ATSC A/52 AC-3 Descriptor */
+ { &hf_mpeg_descr_ac3_sysa_srate, {
+ "Sample Rate", "mpeg_descr.ac3.sysa_sample_rate",
+ FT_UINT8, BASE_HEX, VALS(mpeg_descr_ac3_sysa_srate_flag_vals),
+ MPEG_DESCR_AC3_SYSA_SRATE_MASK, NULL, HFILL
+ } },
+
+ { &hf_mpeg_descr_ac3_sysa_bsid, {
+ "bsid", "mpeg_descr.ac3.sysa_bsid",
+ FT_UINT8, BASE_HEX, NULL, MPEG_DESCR_AC3_SYSA_BSID_MASK, NULL, HFILL
+ } },
+
+ { &hf_mpeg_descr_ac3_sysa_bitrate_limit, {
+ "Bitrate Code limit type", "mpeg_descr.ac3.sysa_bitrate_code_limit",
+ FT_UINT8, BASE_HEX, VALS(mpeg_descr_ac3_sysa_bitrate_code_limit_vals),
+ MPEG_DESCR_AC3_SYSA_BITRATE_CODE_LIMIT_MASK, NULL, HFILL
+ } },
+
+ { &hf_mpeg_descr_ac3_sysa_bitrate, {
+ "Bitrate Code", "mpeg_descr.ac3.sysa_bitrate_code",
+ FT_UINT8, BASE_HEX, VALS(mpeg_descr_ac3_sysa_bitrate_code_vals),
+ MPEG_DESCR_AC3_SYSA_BITRATE_CODE_MASK, NULL, HFILL
+ } },
+
+ { &hf_mpeg_descr_ac3_sysa_surround, {
+ "Surround Mode", "mpeg_descr.ac3.sysa_surround_mode",
+ FT_UINT8, BASE_HEX, VALS(mpeg_descr_ac3_sysa_surround_mode_vals),
+ MPEG_DESCR_AC3_SYSA_SURROUND_MODE_MASK, NULL, HFILL
+ } },
+
+ { &hf_mpeg_descr_ac3_sysa_bsmod, {
+ "Bsmod", "mpeg_descr.ac3.sysa_bsmod",
+ FT_UINT8, BASE_HEX, NULL, MPEG_DESCR_AC3_SYSA_BSMOD_MASK, NULL, HFILL
+ } },
+
+ { &hf_mpeg_descr_ac3_sysa_num_channels, {
+ "Number of Channels", "mpeg_descr.ac3.sysa_num_channels",
+ FT_UINT8, BASE_HEX, VALS(mpeg_descr_ac3_sysa_num_channels_vals),
+ MPEG_DESCR_AC3_SYSA_NUM_CHANNELS_MASK, NULL, HFILL
+ } },
+
+ { &hf_mpeg_descr_ac3_sysa_full_svc, {
+ "Full Service", "mpeg_descr.ac3.sysa_full_svc",
+ FT_UINT8, BASE_HEX, NULL, MPEG_DESCR_AC3_SYSA_FULL_SVC_MASK, NULL, HFILL
+ } },
+
+ { &hf_mpeg_descr_ac3_sysa_langcode, {
+ "Language Code (Deprecated)", "mpeg_descr.ac3.sysa_langcode",
+ FT_UINT8, BASE_HEX, NULL, 0xff, NULL, HFILL
+ } },
+
+ { &hf_mpeg_descr_ac3_sysa_langcode2, {
+ "Language Code 2 (Deprecated)", "mpeg_descr.ac3.sysa_langcode2",
+ FT_UINT8, BASE_HEX, NULL, 0xff, NULL, HFILL
+ } },
+
+ { &hf_mpeg_descr_ac3_sysa_mainid, {
+ "Main ID", "mpeg_descr.ac3.sysa_mainid",
+ FT_UINT8, BASE_HEX, NULL, MPEG_DESCR_AC3_SYSA_MAINID_MASK, NULL, HFILL
+ } },
+
+ { &hf_mpeg_descr_ac3_sysa_priority, {
+ "Priority", "mpeg_descr.ac3.sysa_priority",
+ FT_UINT8, BASE_HEX, VALS(mpeg_descr_ac3_sysa_priority_vals),
+ MPEG_DESCR_AC3_SYSA_PRIORITY_MASK, NULL, HFILL
+ } },
+
+ { &hf_mpeg_descr_ac3_sysa_reserved, {
+ "Reserved", "mpeg_descr.ac3.sysa_reserved",
+ FT_UINT8, BASE_HEX, NULL, MPEG_DESCR_AC3_SYSA_RESERVED_MASK, NULL, HFILL
+ } },
+
+ { &hf_mpeg_descr_ac3_sysa_asvcflags, {
+ "Associated Service Flags", "mpeg_descr.ac3.sysa_asvcflags",
+ FT_UINT8, BASE_HEX, NULL, 0xff, NULL, HFILL
+ } },
+
+ { &hf_mpeg_descr_ac3_sysa_textlen, {
+ "Text length", "mpeg_descr.ac3.sysa_textlen",
+ FT_UINT8, BASE_HEX, NULL, MPEG_DESCR_AC3_SYSA_TEXTLEN_MASK, NULL, HFILL
+ } },
+
+ { &hf_mpeg_descr_ac3_sysa_textcode, {
+ "Text Code", "mpeg_descr.ac3.sysa_textcode",
+ FT_UINT8, BASE_HEX, NULL, MPEG_DESCR_AC3_SYSA_TEXTCODE_MASK, NULL, HFILL
+ } },
+
+ { &hf_mpeg_descr_ac3_sysa_lang1, {
+ "Language 1 Present", "mpeg_descr.ac3.sysa_lang1",
+ FT_UINT8, BASE_HEX, NULL, MPEG_DESCR_AC3_SYSA_LANG1_MASK, NULL, HFILL
+ } },
+
+ { &hf_mpeg_descr_ac3_sysa_lang2, {
+ "Language 2 Present", "mpeg_descr.ac3.sysa_lang2",
+ FT_UINT8, BASE_HEX, NULL, MPEG_DESCR_AC3_SYSA_LANG2_MASK, NULL, HFILL
+ } },
+
+ { &hf_mpeg_descr_ac3_sysa_lang1_bytes, {
+ "Language 1 ISO 639 language code", "mpeg_descr.ac3.sysa_lang1_bytes",
+ FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL
+ } },
+
+ { &hf_mpeg_descr_ac3_sysa_lang2_bytes, {
+ "Language 2 ISO 639 language code", "mpeg_descr.ac3.sysa_lang2_bytes",
+ FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL
+ } },
+
/* 0xA2 Logon Initialize Descriptor */
{ &hf_mpeg_descr_logon_initialize_group_id, {
"Group ID", "mpeg_descr.logon_init.group_id",