Wireshark-dev: [Wireshark-dev] [PATCH 2/2] asn1: New MPEG dissector
From: "Shaun Jackman" <sjackman@xxxxxxxxx>
Date: Thu, 15 Mar 2007 18:13:17 -0600
On 8/25/06, Shaun Jackman <sjackman@xxxxxxxxx> wrote:
> 2, dont read straight into a bitfield struct. > c does not define the packing order or padding of fields in a bitfield > and this would be nonportable. > please change to read into an array of char and then add code to > manually unmarshall it into the fields of the bitfield Not yet done.
Fixed now! The updated patch is attached. The decoder now dissects both MPEG audio and MPEG video! So, for example, it's possible to see the interleaving of MPEG video I, P, and B frames with MPEG audio. Cheers, Shaun 2006-08-25 Shaun Jackman <sjackman@xxxxxxxxx> * asn1/Makefile.am (EXTRA_DIST): Add mpeg. * asn1/mpeg/Makefile: New file. * asn1/mpeg/mpeg-audio.asn: Ditto. * asn1/mpeg/mpeg-audio.cnf: Ditto. * asn1/mpeg/mpeg-pes.asn: Ditto. * asn1/mpeg/mpeg-pes.cnf: Ditto. * asn1/mpeg/packet-mpeg-audio-template.c: Ditto. * asn1/mpeg/packet-mpeg-pes-template.c: Ditto. * epan/dissectors/Makefile.common (DISSECTOR_SRC): Add packet-mpeg-audio.c and packet-mpeg-pes.c.
2006-08-25 Shaun Jackman <sjackman@xxxxxxxxx> * asn1/Makefile.am (EXTRA_DIST): Add mpeg. * asn1/mpeg/Makefile: New file. * asn1/mpeg/mpeg-audio.asn: Ditto. * asn1/mpeg/mpeg-audio.cnf: Ditto. * asn1/mpeg/mpeg-pes.asn: Ditto. * asn1/mpeg/mpeg-pes.cnf: Ditto. * asn1/mpeg/packet-mpeg-audio-template.c: Ditto. * asn1/mpeg/packet-mpeg-pes-template.c: Ditto. * epan/dissectors/Makefile.common (DISSECTOR_SRC): Add packet-mpeg-audio.c and packet-mpeg-pes.c. Index: asn1/mpeg/mpeg-pes.cnf =================================================================== --- asn1/mpeg/mpeg-pes.cnf (revision 0) +++ asn1/mpeg/mpeg-pes.cnf (revision 0) @@ -0,0 +1,5 @@ +#.TYPE_ATTR +PES/stream TYPE=FT_UINT8 DISPLAY=BASE_HEX +Pack/program-mux-rate TYPE=FT_UINT32 DISPLAY=BASE_DEC +Stream/length TYPE=FT_UINT16 DISPLAY=BASE_DEC +#.END Index: asn1/mpeg/packet-mpeg-audio-template.c =================================================================== --- asn1/mpeg/packet-mpeg-audio-template.c (revision 0) +++ asn1/mpeg/packet-mpeg-audio-template.c (revision 0) @@ -0,0 +1,186 @@ +/* MPEG audio packet decoder. + * Written by Shaun Jackman <sjackman@xxxxxxxxx>. + * Copyright 2007 Shaun Jackman + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include <stdio.h> +#include <string.h> + +#include <glib.h> + +#include <epan/packet.h> +#include <epan/prefs.h> + +#include <wiretap/mpeg-audio.h> + +#include "packet-per.h" + +#include "packet-mpeg-audio-hf.c" +#include "packet-mpeg-audio-ett.c" +#include "packet-mpeg-audio-fn.c" + +static int hf_mpeg_audio = -1; +static int hf_mpeg_audio_data = -1; +static int hf_mpeg_audio_padbytes = -1; +static int hf_id3v1 = -1; +static int hf_id3v2 = -1; + +static size_t +read_header(tvbuff_t *tvb, packet_info *pinfo, struct mpa *mpa) +{ + size_t data_size = 0; + uint32_t h = tvb_get_ntohl(tvb, 0); + MPA_MARSHAL(mpa, h); + if (MPA_SYNC_VALID(mpa)) { + if (MPA_VERSION_VALID(mpa) && MPA_LAYER_VALID(mpa)) { + if (check_col(pinfo->cinfo, COL_PROTOCOL)) { + static const char *version_names[] = { "1", "2", "2.5" }; + col_add_fstr(pinfo->cinfo, COL_PROTOCOL, + "MPEG-%s", version_names[MPA_VERSION(mpa)]); + } + if (check_col(pinfo->cinfo, COL_INFO)) + col_add_fstr(pinfo->cinfo, COL_INFO, + "Audio Layer %d", MPA_LAYER(mpa) + 1); + if (MPA_BITRATE_VALID(mpa) && MPA_FREQUENCY_VALID(mpa)) { + data_size = MPA_DATA_BYTES(mpa) - sizeof mpa; + if (check_col(pinfo->cinfo, COL_DEF_SRC)) { + SET_ADDRESS(&pinfo->src, AT_NONE, 0, NULL); + col_add_fstr(pinfo->cinfo, COL_DEF_SRC, + "%d kb/s", MPA_BITRATE(mpa) / 1000); + } + if (check_col(pinfo->cinfo, COL_DEF_DST)) { + SET_ADDRESS(&pinfo->dst, AT_NONE, 0, NULL); + col_add_fstr(pinfo->cinfo, COL_DEF_DST, + "%g kHz", MPA_FREQUENCY(mpa) / (float)1000); + } + } + } else { + if (check_col(pinfo->cinfo, COL_PROTOCOL)) + col_add_str(pinfo->cinfo, COL_PROTOCOL, "MPEG"); + } + } + return data_size; +} + +static gboolean +dissect_mpeg_audio_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ + struct mpa mpa; + size_t data_size = read_header(tvb, pinfo, &mpa); + if (!MPA_SYNC_VALID(&mpa)) + return FALSE; + + if (tree == NULL) + return TRUE; + asn1_ctx_t asn1_ctx; + asn1_ctx_init(&asn1_ctx, ASN1_ENC_PER, TRUE, pinfo); + int offset = 0; + offset = dissect_mpeg_audio_Audio(tvb, offset, &asn1_ctx, + tree, hf_mpeg_audio); + if (data_size > 0) { + proto_tree_add_item(tree, hf_mpeg_audio_data, tvb, + offset / 8, data_size, FALSE); + offset += data_size * 8; + unsigned padding = MPA_PADDING(&mpa); + if (padding > 0) { + proto_tree_add_item(tree, hf_mpeg_audio_padbytes, tvb, + offset / 8, padding, FALSE); + offset += padding * 8; + } + } + return TRUE; +} + +static void +dissect_id3v1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ + if (check_col(pinfo->cinfo, COL_PROTOCOL)) + col_set_str(pinfo->cinfo, COL_PROTOCOL, "ID3v1"); + if (tree == NULL) + return; + asn1_ctx_t asn1_ctx; + asn1_ctx_init(&asn1_ctx, ASN1_ENC_PER, TRUE, pinfo); + dissect_mpeg_audio_ID3v1(tvb, 0, &asn1_ctx, + tree, hf_id3v1); +} + +static void +dissect_id3v2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ + if (check_col(pinfo->cinfo, COL_PROTOCOL)) + col_set_str(pinfo->cinfo, COL_PROTOCOL, "ID3v2"); + proto_tree_add_item(tree, hf_id3v2, tvb, + 0, -1, FALSE); +} + +static gboolean +dissect_mpeg_audio(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ + if (check_col(pinfo->cinfo, COL_PROTOCOL)) + col_clear(pinfo->cinfo, COL_PROTOCOL); + if (check_col(pinfo->cinfo, COL_INFO)) + col_clear(pinfo->cinfo, COL_INFO); + + int magic = tvb_get_ntoh24(tvb, 0); + switch (magic) { + case 0x544147: /* TAG */ + dissect_id3v1(tvb, pinfo, tree); + return TRUE; + case 0x494433: /* ID3 */ + dissect_id3v2(tvb, pinfo, tree); + return TRUE; + default: + return dissect_mpeg_audio_frame(tvb, pinfo, tree); + } +} + +static int proto_mpeg_audio = -1; + +void +proto_register_mpeg_audio(void) +{ + static hf_register_info hf[] = { +#include "packet-mpeg-audio-hfarr.c" + { &hf_mpeg_audio, + { "MPEG Audio", "mpeg.audio", + FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL }}, + { &hf_mpeg_audio_data, + { "Data", "mpeg.audio.data", + FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }}, + { &hf_mpeg_audio_padbytes, + { "Padding", "mpeg.audio.padbytes", + FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }}, + + { &hf_id3v1, + { "ID3v1", "id3v1", + FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL }}, + { &hf_id3v2, + { "ID3v2", "id3v2", + FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL }}, + }; + + static gint *ett[] = { +#include "packet-mpeg-audio-ettarr.c" + }; + + if (proto_mpeg_audio != -1) + return; + + proto_mpeg_audio = proto_register_protocol( + "Moving Picture Experts Group Audio", "MPEG Audio", "mpeg.audio"); + proto_register_field_array(proto_mpeg_audio, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); +} + +void +proto_reg_handoff_mpeg_audio(void) +{ + heur_dissector_add("mpeg", dissect_mpeg_audio, proto_mpeg_audio); +} Index: asn1/mpeg/mpeg-audio.asn =================================================================== --- asn1/mpeg/mpeg-audio.asn (revision 0) +++ asn1/mpeg/mpeg-audio.asn (revision 0) @@ -0,0 +1,75 @@ +-- ASN description of MPEG Audio +-- Written by Shaun Jackman <sjackman@xxxxxxxxx> +-- Copyright 2007 Shaun Jackman +-- +-- This program is free software; you can redistribute it and/or +-- modify it under the terms of the GNU General Public License. + +MPEG DEFINITIONS ::= BEGIN + +Audio ::= SEQUENCE { + sync BIT STRING (SIZE (11)), + version ENUMERATED + { mpeg-2-5(0), reserved(1), mpeg-2(2), mpeg-1(3) }, + layer ENUMERATED + { reserved(0), layer-3(1), layer-2(2), layer-1(3) }, + protection ENUMERATED { crc(0), none(1) }, + bitrate INTEGER (0..15), + frequency INTEGER (0..3), + padding BOOLEAN, + private BOOLEAN, + channel-mode ENUMERATED + { stereo(0), joint-stereo(1), dual-channel(2), single-channel(3) }, + mode-extension INTEGER (0..3), + copyright BOOLEAN, + original BOOLEAN, + emphasis ENUMERATED + { none(0), em-50-15-ms(1), reserved(2), ccit-j-17(3) } +} + +ID3v1 ::= SEQUENCE { + tag OCTET STRING (SIZE (3)), + title OCTET STRING (SIZE (30)), + artist OCTET STRING (SIZE (30)), + album OCTET STRING (SIZE (30)), + year OCTET STRING (SIZE (4)), + comment OCTET STRING (SIZE (28)), + must-be-zero INTEGER (0..255), + track INTEGER (0..255), + genre INTEGER { + blues(0), classic-rock(1), country(2), dance(3), disco(4), + funk(5), grunge(6), hip-hop(7), jazz(8), metal(9), + new-age(10), oldies(11), other(12), pop(13), r-and-b(14), + rap(15), reggae(16), rock(17), techno(18), industrial(19), + alternative(20), ska(21), death-metal(22), pranks(23), + soundtrack(24), euro-techno(25), ambient(26), trip-hop(27), + vocal(28), jazz-and-funk(29), fusion(30), trance(31), + classical(32), instrumental(33), acid(34), house(35), + game(36), sound-clip(37), gospel(38), noise(39), + alternative-rock(40), bass(41), soul(42), punk(43), space(44), + meditative(45), instrumental-pop(46), instrumental-rock(47), + ethnic(48), gothic(49), darkwave(50), techno-industrial(51), + electronic(52), pop-folk(53), eurodance(54), dream(55), + southern-rock(56), comedy(57), cult(58), gangsta(59), + top-40(60), christian-rap(61), pop-funk(62), jungle(63), + native-american(64), cabaret(65), new-wave(66), + psychadelic(67), rave(68), showtunes(69), trailer(70), + lo-fi(71), tribal(72), acid-punk(73), acid-jazz(74), + polka(75), retro(76), musical(77), rock-and-roll(78), + hard-rock(79), folk(80), folk-rock(81), national-folk(82), + swing(83), fast-fusion(84), bebob(85), latin(86), revival(87), + celtic(88), bluegrass(89), avantgarde(90), gothic-rock(91), + progressive-rock(92), psychedelic-rock(93), + symphonic-rock(94), slow-rock(95), big-band(96), chorus(97), + easy-listening(98), acoustic(99), humour(100), speech(101), + chanson(102), opera(103), chamber-music(104), sonata(105), + symphony(106), booty-bass(107), primus(108), porn-groove(109), + satire(110), slow-jam(111), club(112), tango(113), samba(114), + folklore(115), ballad(116), power-ballad(117), + rhythmic-soul(118), freestyle(119), duet(120), punk-rock(121), + drum-solo(122), a-cappella(123), euro-house(124), + dance-hall(125) + } (0..255) +} + +END Index: asn1/mpeg/mpeg-audio.cnf =================================================================== --- asn1/mpeg/mpeg-audio.cnf (revision 0) +++ asn1/mpeg/mpeg-audio.cnf (revision 0) @@ -0,0 +1,8 @@ +#.TYPE_ATTR +ID3v1/tag TYPE=FT_STRING +ID3v1/title TYPE=FT_STRING +ID3v1/artist TYPE=FT_STRING +ID3v1/album TYPE=FT_STRING +ID3v1/year TYPE=FT_STRING +ID3v1/comment TYPE=FT_STRING +#.END Index: asn1/mpeg/packet-mpeg-pes-template.c =================================================================== --- asn1/mpeg/packet-mpeg-pes-template.c (revision 0) +++ asn1/mpeg/packet-mpeg-pes-template.c (revision 0) @@ -0,0 +1,262 @@ +/* MPEG Packetized Elementary Stream (PES) packet decoder. + * Written by Shaun Jackman <sjackman@xxxxxxxxx>. + * Copyright 2007 Shaun Jackman + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include <stdio.h> +#include <string.h> + +#include <glib.h> + +#include <epan/packet.h> +#include <epan/prefs.h> + +#include "packet-per.h" + +#include "packet-mpeg-pes-hf.c" +#include "packet-mpeg-pes-ett.c" +#include "packet-mpeg-pes-fn.c" + +static int proto_mpeg = -1; +static int proto_mpeg_pes = -1; +static int hf_mpeg_pes_pack_header = -1; +static int hf_mpeg_pes_stuffing = -1; +static int hf_mpeg_pes_extension = -1; +static int hf_mpeg_pes_header_data = -1; +static int hf_mpeg_pes_padding = -1; + +static int hf_mpeg_pes_data = -1; + +static int hf_mpeg_video_sequence_header = -1; +static int hf_mpeg_video_sequence_extension = -1; +static int hf_mpeg_video_group_of_pictures = -1; +static int hf_mpeg_video_picture = -1; +static int hf_mpeg_video_quantization_matrix = -1; +static int hf_mpeg_video_data = -1; + +enum { PES_PREFIX = 1 }; +enum { + STREAM_PICTURE = 0x00, + STREAM_SEQUENCE = 0xb3, + STREAM_SEQUENCE_EXTENSION = 0xb5, + STREAM_GOP = 0xb8, + STREAM_END = 0xb9, + STREAM_PACK = 0xba, + STREAM_SYSTEM = 0xbb, + STREAM_PROGRAM = 0xbc, + STREAM_PRIVATE1 = 0xbd, + STREAM_PADDING = 0xbe, + STREAM_PRIVATE2 = 0xbf, + STREAM_AUDIO = 0xc0, + STREAM_VIDEO = 0xe0, +}; + +void +dissect_mpeg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree); + +static gboolean +dissect_mpeg_pes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ + int prefix = tvb_get_ntoh24(tvb, 0); + if (prefix != PES_PREFIX) + return FALSE; + if (check_col(pinfo->cinfo, COL_PROTOCOL)) + col_set_str(pinfo->cinfo, COL_PROTOCOL, "MPEG PES"); + + int stream = tvb_get_guint8(tvb, 3); + if (check_col(pinfo->cinfo, COL_INFO)) { + const char *s = match_strval(stream, mpeg_pes_T_stream_vals); + if (s != NULL) + col_set_str(pinfo->cinfo, COL_INFO, s); + } + +#if 0 + if (tree == NULL) + return TRUE; +#endif + asn1_ctx_t asn1_ctx; + asn1_ctx_init(&asn1_ctx, ASN1_ENC_PER, TRUE, pinfo); + int offset = 0; + offset = dissect_mpeg_pes_PES(tvb, offset, &asn1_ctx, + tree, proto_mpeg_pes); + + if (stream == STREAM_PICTURE) { + int frame_type = tvb_get_guint8(tvb, 5) >> 3 & 0x07; + if (check_col(pinfo->cinfo, COL_INFO)) { + const char *s = match_strval(frame_type, + mpeg_pes_T_frame_type_vals); + if (s != NULL) + col_set_str(pinfo->cinfo, COL_INFO, s); + } + + offset = dissect_mpeg_pes_Picture(tvb, offset, &asn1_ctx, + tree, hf_mpeg_video_picture); + proto_tree_add_item(tree, hf_mpeg_video_data, tvb, + offset / 8, -1, FALSE); + } else if (stream == STREAM_SEQUENCE) { + offset = dissect_mpeg_pes_Sequence_header(tvb, offset, &asn1_ctx, + tree, hf_mpeg_video_sequence_header); + + proto_tree_add_item(tree, hf_mpeg_video_quantization_matrix, tvb, + offset / 8, 64, FALSE); + offset += 64 * 8; + + tvbuff_t *es = tvb_new_subset(tvb, offset / 8, -1, -1); + dissect_mpeg_pes(es, pinfo, tree); + } else if (stream == STREAM_SEQUENCE_EXTENSION) { + offset = dissect_mpeg_pes_Sequence_extension(tvb, offset, &asn1_ctx, + tree, hf_mpeg_video_sequence_extension); + + tvbuff_t *es = tvb_new_subset(tvb, offset / 8, -1, -1); + dissect_mpeg_pes(es, pinfo, tree); + } else if (stream == STREAM_GOP) { + offset = dissect_mpeg_pes_Group_of_pictures(tvb, offset, &asn1_ctx, + tree, hf_mpeg_video_group_of_pictures); + + tvbuff_t *es = tvb_new_subset(tvb, offset / 8, -1, -1); + dissect_mpeg_pes(es, pinfo, tree); + } else if (stream == STREAM_PACK) { + int length; + switch (tvb_get_guint8(tvb, 4) >> 6) { + case 1: + length = tvb_get_guint8(tvb, 13) & 0x07; + offset = dissect_mpeg_pes_Pack(tvb, offset, &asn1_ctx, + tree, hf_mpeg_pes_pack_header); + if (length > 0) + proto_tree_add_item(tree, hf_mpeg_pes_stuffing, tvb, + offset / 8, length, FALSE); + break; + default: + length = 8; + proto_tree_add_item(tree, hf_mpeg_pes_data, tvb, + offset / 8, length, FALSE); + } + offset += length * 8; + } else if (stream == STREAM_SYSTEM) { + offset = dissect_mpeg_pes_Stream(tvb, offset, &asn1_ctx, + tree, hf_mpeg_pes_extension); + proto_tree_add_item(tree, hf_mpeg_pes_data, tvb, + offset / 8, -1, FALSE); + } else if (stream == STREAM_PADDING) { + int padding_length = tvb_get_ntohs(tvb, 4); + proto_tree_add_item(tree, hf_mpeg_pes_length, tvb, + offset / 8, 2, FALSE); + offset += 2 * 8; + + proto_tree_add_item(tree, hf_mpeg_pes_padding, tvb, + offset / 8, padding_length, FALSE); + } else if (stream == STREAM_PRIVATE1 + || stream >= STREAM_AUDIO) { + int length = tvb_get_ntohs(tvb, 4); + + offset = dissect_mpeg_pes_Stream(tvb, offset, &asn1_ctx, + tree, hf_mpeg_pes_extension); + length -= 5 * 8; + + int header_length = tvb_get_guint8(tvb, 8); + if (header_length > 0) { + proto_tree_add_item(tree, hf_mpeg_pes_header_data, tvb, + offset / 8, header_length, FALSE); + offset += header_length * 8; + length -= header_length * 8; + } + + tvbuff_t *es = tvb_new_subset(tvb, offset / 8, -1, length / 8); + if (tvb_get_ntoh24(es, 0) == PES_PREFIX) + dissect_mpeg_pes(es, pinfo, tree); + else if (tvb_get_guint8(es, 0) == 0xff) + dissect_mpeg(es, pinfo, tree); + else + proto_tree_add_item(tree, hf_mpeg_pes_data, es, + 0, -1, FALSE); + } else { + proto_tree_add_item(tree, hf_mpeg_pes_data, tvb, + offset / 8, -1, FALSE); + } + return TRUE; +} + +static heur_dissector_list_t heur_subdissector_list; + +void +dissect_mpeg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ + dissector_try_heuristic(heur_subdissector_list, tvb, pinfo, tree); +} + +void +proto_register_mpeg_pes(void) +{ + proto_mpeg = proto_register_protocol( + "Moving Picture Experts Group", "MPEG", "mpeg"); + register_heur_dissector_list("mpeg", &heur_subdissector_list); + + static hf_register_info hf[] = { +#include "packet-mpeg-pes-hfarr.c" + { &hf_mpeg_pes_pack_header, + { "Pack header", "mpeg-pes.pack", + FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL }}, + { &hf_mpeg_pes_stuffing, + { "PES stuffing bytes", "mpeg-pes.stuffing", + FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }}, + { &hf_mpeg_pes_extension, + { "PES extension", "mpeg-pes.extension", + FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL }}, + { &hf_mpeg_pes_header_data, + { "PES header data", "mpeg-pes.header-data", + FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }}, + { &hf_mpeg_pes_padding, + { "PES padding", "mpeg-pes.padding", + FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }}, + { &hf_mpeg_pes_data, + { "PES data", "mpeg-pes.data", + FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }}, + { &hf_mpeg_video_sequence_header, + { "MPEG sequence header", "mpeg-video.sequence", + FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL }}, + { &hf_mpeg_video_sequence_extension, + { "MPEG sequence extension", "mpeg-video.sequence-ext", + FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL }}, + { &hf_mpeg_video_group_of_pictures, + { "MPEG group of pictures", "mpeg-video.gop", + FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL }}, + { &hf_mpeg_video_picture, + { "MPEG picture", "mpeg-video.picture", + FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL }}, + { &hf_mpeg_video_quantization_matrix, + { "MPEG quantization matrix", "mpeg-video.quant", + FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }}, + { &hf_mpeg_video_data, + { "MPEG picture data", "mpeg-video.data", + FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }}, + }; + + static gint *ett[] = { +#include "packet-mpeg-pes-ettarr.c" + }; + + if (proto_mpeg_pes != -1) + return; + + proto_mpeg_pes = proto_register_protocol( + "Packetized Elementary Stream", "MPEG PES", "mpeg-pes"); + proto_register_field_array(proto_mpeg_pes, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); +} + +void +proto_reg_handoff_mpeg_pes(void) +{ + dissector_handle_t mpeg_handle = create_dissector_handle( + dissect_mpeg, proto_mpeg); + dissector_add("wtap_encap", WTAP_ENCAP_MPEG, mpeg_handle); + + heur_dissector_add("mpeg", dissect_mpeg_pes, proto_mpeg_pes); +} Index: asn1/mpeg/Makefile =================================================================== --- asn1/mpeg/Makefile (revision 0) +++ asn1/mpeg/Makefile (revision 0) @@ -0,0 +1,14 @@ +DISSECTOR_FILES=packet-mpeg-audio.c packet-mpeg-pes.c + +all: $(DISSECTOR_FILES) + +clean: + rm -f parsetab.py parsetab.pyc $(DISSECTOR_FILES) + +copy_files: all + cp $(DISSECTOR_FILES) ../../epan/dissectors + +.PHONY: all clean copy_files + +packet-%.c: ../../tools/asn2wrs.py %.asn %.cnf packet-%-template.c + python ../../tools/asn2wrs.py -e -p $* -c $*.cnf -s packet-$*-template $*.asn Index: asn1/mpeg/mpeg-pes.asn =================================================================== --- asn1/mpeg/mpeg-pes.asn (revision 0) +++ asn1/mpeg/mpeg-pes.asn (revision 0) @@ -0,0 +1,135 @@ +-- ASN description of MPEG Packetized Elementary Stream (PES) +-- Written by Shaun Jackman <sjackman@xxxxxxxxx> +-- Copyright 2007 Shaun Jackman +-- +-- This program is free software; you can redistribute it and/or +-- modify it under the terms of the GNU General Public License. + +MPEG DEFINITIONS ::= BEGIN + +PES ::= SEQUENCE { + prefix OCTET STRING (SIZE (3)), + stream INTEGER { + picture (0), + sequence-header (179), + sequence-header-extension (181), + group-of-pictures (184), + program-end (185), + pack-header (186), + system-header (187), + program-stream-map (188), + private-stream-1 (189), + padding-stream (190), + private-stream-2 (191), + audio-stream (192), + video-stream (224) + } (0..255) +} + +Pack ::= SEQUENCE { + must-be-zero BOOLEAN, + must-be-one0 BOOLEAN, + scr30 BIT STRING (SIZE (3)), + must-be-one1 BOOLEAN, + scr15 BIT STRING (SIZE (15)), + must-be-one2 BOOLEAN, + scr0 BIT STRING (SIZE (15)), + must-be-one3 BOOLEAN, + scr-ext BIT STRING (SIZE (9)), + must-be-one4 BOOLEAN, + program-mux-rate BIT STRING (SIZE (22)), + must-be-one5 BOOLEAN, + must-be-one6 BOOLEAN, + reserved BIT STRING (SIZE (5)), + stuffing-length INTEGER (0..7) +} + +Stream ::= SEQUENCE { + length INTEGER (0..65535), + must-be-one BOOLEAN, + must-be-zero BOOLEAN, + scrambling-control INTEGER { + not-scrambled (0) + } (0..3), + priority BOOLEAN, + data-alignment BOOLEAN, + copyright BOOLEAN, + original BOOLEAN, + pts-flag BOOLEAN, + dts-flag BOOLEAN, + escr-flag BOOLEAN, + es-rate-flag BOOLEAN, + dsm-trick-mode-flag BOOLEAN, + additional-copy-info-flag BOOLEAN, + crc-flag BOOLEAN, + extension-flag BOOLEAN, + header-data-length INTEGER (0..255) +} + +Sequence-header ::= SEQUENCE { + horizontal-size BIT STRING (SIZE (12)), + vertical-size BIT STRING (SIZE (12)), + aspect-ratio INTEGER { + aspect-1to1 (1), + aspect-4to3 (2), + aspect-16to9 (3), + aspect-2-21to1 (4) + } (0..15), + frame-rate ENUMERATED { + reserved (0), + fr (23976), + fr (24000), + fr (25000), + fr (29970), + fr (30000), + fr (50000), + fr (59940), + fr (60000) + }, + bit-rate BIT STRING (SIZE (18)), + must-be-one BOOLEAN, + vbv-buffer-size BIT STRING (SIZE (10)), + constrained-parameters-flag BOOLEAN, + load-intra-quantiser-matrix BOOLEAN, + load-non-intra-quantiser-matrix BOOLEAN +} + +Sequence-extension ::= SEQUENCE { + must-be-0001 BIT STRING (SIZE (4)), + profile-and-level INTEGER (0..255), + progressive-sequence BOOLEAN, + chroma-format INTEGER (0..3), + horizontal-size-extension INTEGER (0..3), + vertical-size-extension INTEGER (0..3), + bit-rate-extension BIT STRING (SIZE (12)), + must-be-one BOOLEAN, + vbv-buffer-size-extension INTEGER (0..255), + low-delay BOOLEAN, + frame-rate-extension-n INTEGER (0..3), + frame-rate-extension-d INTEGER (0..3) +} + +Group-of-pictures ::= SEQUENCE { + drop-frame-flag BOOLEAN, + hour INTEGER (0..32), + minute INTEGER (0..64), + must-be-one BOOLEAN, + second INTEGER (0..64), + frame INTEGER (0..64), + closed-gop BOOLEAN, + broken-gop BOOLEAN, + must-be-zero BIT STRING (SIZE (5)) +} + +Picture ::= SEQUENCE { + temporal-sequence-number BIT STRING (SIZE (10)), + frame-type INTEGER { + i-frame (1), + p-frame (2), + b-frame (3), + d-frame (4) + } (0..7), + vbv-delay BIT STRING (SIZE (16)) +} + +END Index: asn1/Makefile.am =================================================================== --- asn1/Makefile.am (revision 21033) +++ asn1/Makefile.am (working copy) @@ -203,6 +203,13 @@ mms/mms-exp.cnf \ mms/packet-mms-template.c \ mms/packet-mms-template.h \ + mpeg/Makefile \ + mpeg/mpeg-audio.asn \ + mpeg/mpeg-audio.cnf \ + mpeg/mpeg-pes.asn \ + mpeg/mpeg-pes.cnf \ + mpeg/packet-mpeg-audio-template.c \ + mpeg/packet-mpeg-pes-template.c \ nbap/Makefile \ nbap/Makefile.nmake \ nbap/nbap.asn \ Index: epan/dissectors/Makefile.common =================================================================== --- epan/dissectors/Makefile.common (revision 21033) +++ epan/dissectors/Makefile.common (working copy) @@ -463,6 +463,8 @@ packet-mount.c \ packet-mp2t.c \ packet-mpeg1.c \ + packet-mpeg-audio.c \ + packet-mpeg-pes.c \ packet-mpls.c \ packet-mpls-echo.c \ packet-mq.c \
- Follow-Ups:
- Re: [Wireshark-dev] [PATCH 2/2] asn1: New MPEG dissector
- From: ronnie sahlberg
- Re: [Wireshark-dev] [PATCH 2/2] asn1: New MPEG dissector
- Prev by Date: [Wireshark-dev] [PATCH 1/2] wiretap: New MPEG file format
- Next by Date: Re: [Wireshark-dev] Opinions on solving bug #1375: Capture Options with many IP addresses scrolls off screen
- Previous by thread: Re: [Wireshark-dev] [PATCH 1/2] wiretap: New MPEG file format
- Next by thread: Re: [Wireshark-dev] [PATCH 2/2] asn1: New MPEG dissector
- Index(es):