/src/wireshark/epan/dissectors/packet-mp4ves.c
Line | Count | Source |
1 | | /* |
2 | | * packet-mp4ves.c |
3 | | * Routines for MPEG4 dissection |
4 | | * Copyright 2007-2008, Anders Broman <anders.broman[at]ericsson.com> |
5 | | * |
6 | | * Wireshark - Network traffic analyzer |
7 | | * By Gerald Combs <gerald@wireshark.org> |
8 | | * Copyright 1998 Gerald Combs |
9 | | * |
10 | | * SPDX-License-Identifier: GPL-2.0-or-later |
11 | | * |
12 | | * References: |
13 | | * https://tools.ietf.org/html/rfc3016 |
14 | | */ |
15 | | |
16 | | #include "config.h" |
17 | | |
18 | | |
19 | | #include <epan/packet.h> |
20 | | #include <epan/expert.h> |
21 | | #include <epan/asn1.h> |
22 | | |
23 | | #include <epan/prefs.h> |
24 | | |
25 | | #include "packet-mp4ves.h" |
26 | | |
27 | | void proto_register_mp4ves(void); |
28 | | void proto_reg_handoff_mp4ves(void); |
29 | | |
30 | | /* Initialize the protocol and registered fields */ |
31 | | static int proto_mp4ves; |
32 | | |
33 | | static int hf_mp4ves_config; |
34 | | static int hf_mp4ves_start_code_prefix; |
35 | | static int hf_mp4ves_start_code; |
36 | | static int hf_mp4ves_vop_coding_type; |
37 | | static int hf_mp4ves_profile_and_level_indication; |
38 | | static int hf_mp4ves_is_visual_object_identifier; |
39 | | static int hf_mp4ves_visual_object_type; |
40 | | static int hf_mp4ves_video_signal_type; |
41 | | static int hf_mp4ves_stuffing; |
42 | | static int hf_mp4ves_video_object_type_indication; |
43 | | static int hf_mp4ves_random_accessible_vol; |
44 | | static int hf_mp4ves_is_object_layer_identifier; |
45 | | static int hf_mp4ves_aspect_ratio_info; |
46 | | static int hf_mp4ves_vol_control_parameters; |
47 | | static int hf_mp4ves_video_object_layer_shape; |
48 | | static int hf_mp4ves_user_data; |
49 | | static int hf_mp4ves_data; |
50 | | |
51 | | /* Initialize the subtree pointers */ |
52 | | static int ett_mp4ves; |
53 | | static int ett_mp4ves_config; |
54 | | |
55 | | static expert_field ei_mp4ves_config_too_short; |
56 | | static expert_field ei_mp4ves_not_dissected_bits; |
57 | | |
58 | | static dissector_handle_t mp4ves_name_handle; |
59 | | |
60 | | static dissector_handle_t mp4ves_handle; |
61 | | |
62 | | /* |
63 | | 14496-2, Annex G, Table G-1. |
64 | | Table G-1 FLC table for profile_and_level_indication Profile/Level Code |
65 | | */ |
66 | | const value_string mp4ves_level_indication_vals[] = |
67 | | { |
68 | | { 0, "Reserved" }, |
69 | | { 1, "Simple Profile/Level 1" }, |
70 | | { 2, "Simple Profile/Level 2" }, |
71 | | { 3, "Reserved" }, |
72 | | { 4, "Reserved" }, |
73 | | { 5, "Reserved" }, |
74 | | { 6, "Reserved" }, |
75 | | { 7, "Reserved" }, |
76 | | { 8, "Simple Profile/Level 0" }, |
77 | | { 9, "Simple Profile/Level 0b" }, |
78 | | /* Reserved 00001001 - 00010000 */ |
79 | | { 0x11, "Simple Scalable Profile/Level 1" }, |
80 | | { 0x12, "Simple Scalable Profile/Level 2" }, |
81 | | /* Reserved 00010011 - 00100000 */ |
82 | | { 0x21, "Core Profile/Level 1" }, |
83 | | { 0x22, "Core Profile/Level 2" }, |
84 | | /* Reserved 00100011 - 00110001 */ |
85 | | { 0x32, "Main Profile/Level 2" }, |
86 | | { 0x33, "Main Profile/Level 3" }, |
87 | | { 0x34, "Main Profile/Level 4" }, |
88 | | /* Reserved 00110101 - 01000001 */ |
89 | | { 0x42, "N-bit Profile/Level 2" }, |
90 | | /* Reserved 01000011 - 01010000 */ |
91 | | { 0x51, "Scalable Texture Profile/Level 1" }, |
92 | | /* Reserved 01010010 - 01100000 */ |
93 | | { 0x61, "Simple Face Animation Profile/Level 1" }, |
94 | | { 0x62, "Simple Face Animation Profile/Level 2" }, |
95 | | { 0x63, "Simple FBA Profile/Level 1" }, |
96 | | { 0x64, "Simple FBA Profile/Level 2" }, |
97 | | /* Reserved 01100101 - 01110000 */ |
98 | | { 0x71, "Basic Animated Texture Profile/Level 1" }, |
99 | | { 0x72, "Basic Animated Texture Profile/Level 2" }, |
100 | | /* Reserved 01110011 - 10000000 */ |
101 | | { 0x81, "Hybrid Profile/Level 1" }, |
102 | | { 0x82, "Hybrid Profile/Level 2" }, |
103 | | /* Reserved 10000011 - 10010000 */ |
104 | | { 0x91, "Advanced Real Time Simple Profile/Level 1" }, |
105 | | { 0x92, "Advanced Real Time Simple Profile/Level 2" }, |
106 | | { 0x93, "Advanced Real Time Simple Profile/Level 3" }, |
107 | | { 0x94, "Advanced Real Time Simple Profile/Level 4" }, |
108 | | /* Reserved 10010101 - 10100000 */ |
109 | | { 0xa1, "Core Scalable Profile/Level 1" }, |
110 | | { 0xa2, "Core Scalable Profile/Level 2" }, |
111 | | { 0xa3, "Core Scalable Profile/Level 3" }, |
112 | | /* Reserved 10100100 - 10110000 */ |
113 | | { 0xb1, "Advanced Coding Efficiency Profile/Level 1" }, |
114 | | { 0xb2, "Advanced Coding Efficiency Profile/Level 2" }, |
115 | | { 0xb3, "Advanced Coding Efficiency Profile/Level 3" }, |
116 | | { 0xb4, "Advanced Coding Efficiency Profile/Level 4" }, |
117 | | /* Reserved 10110101 - 11000000 */ |
118 | | { 0xc1, "Advanced Core Profile/Level 1" }, |
119 | | { 0xc2, "Advanced Core Profile/Level 2" }, |
120 | | /* Reserved 11000011 - 11010000 */ |
121 | | { 0xd1, "Advanced Scalable Texture/Level 1" }, |
122 | | { 0xd2, "Advanced Scalable Texture/Level 2" }, |
123 | | { 0xd3, "Advanced Scalable Texture/Level 3" }, |
124 | | /* Reserved 11010100 - 11100000 */ |
125 | | { 0xe1, "Simple Studio Profile/Level 1" }, |
126 | | { 0xe2, "Simple Studio Profile/Level 2" }, |
127 | | { 0xe3, "Simple Studio Profile/Level 3" }, |
128 | | { 0xe4, "Simple Studio Profile/Level 4" }, |
129 | | { 0xe5, "Core Studio Profile/Level 1" }, |
130 | | { 0xe6, "Core Studio Profile/Level 2" }, |
131 | | { 0xe7, "Core Studio Profile/Level 3" }, |
132 | | { 0xe8, "Core Studio Profile/Level 4" }, |
133 | | /* Reserved 11101001 - 11101111 */ |
134 | | { 0xf0, "Advanced Simple Profile/Level 0" }, |
135 | | { 0xf1, "Advanced Simple Profile/Level 1" }, |
136 | | { 0xf2, "Advanced Simple Profile/Level 2" }, |
137 | | { 0xf3, "Advanced Simple Profile/Level 3" }, |
138 | | { 0xf4, "Advanced Simple Profile/Level 4" }, |
139 | | { 0xf5, "Advanced Simple Profile/Level 5" }, |
140 | | /* Reserved 11110110 - 11110111 */ |
141 | | { 0xf8, "Fine Granularity Scalable Profile/Level 0" }, |
142 | | { 0xf9, "Fine Granularity Scalable Profile/Level 1" }, |
143 | | { 0xfa, "Fine Granularity Scalable Profile/Level 2" }, |
144 | | { 0xfb, "Fine Granularity Scalable Profile/Level 3" }, |
145 | | { 0xfc, "Fine Granularity Scalable Profile/Level 4" }, |
146 | | { 0xfd, "Fine Granularity Scalable Profile/Level 5" }, |
147 | | { 0xfe, "Reserved" }, |
148 | | { 0xff, "Reserved for Escape" }, |
149 | | { 0, NULL }, |
150 | | }; |
151 | | static const range_string mp4ves_startcode_vals[] = { |
152 | | { 0x00, 0x1f, "video_object_start_code" }, |
153 | | { 0x20, 0x2f, "video_object_layer_start_code" }, |
154 | | { 0x30, 0xaf, "reserved" }, |
155 | | { 0xb0, 0xb0, "visual_object_sequence_start_code" }, |
156 | | { 0xb1, 0xb1, "visual_object_sequence_end_code" }, |
157 | | { 0xb2, 0xb2, "user_data_start_code" }, |
158 | | { 0xb3, 0xb3, "group_of_vop_start_code" }, |
159 | | { 0xb4, 0xb4, "video_session_error_code" }, |
160 | | { 0xb5, 0xb5, "visual_object_start_code" }, |
161 | | { 0xb6, 0xb6, "vop_start_code" }, |
162 | | { 0xb7, 0xb9, "reserved" }, |
163 | | { 0xba, 0xba, "fba_object_start_code" }, |
164 | | { 0xbb, 0xbb, "fba_object_plane_start_code" }, |
165 | | { 0xbc, 0xbc, "mesh_object_start_code" }, |
166 | | { 0xbd, 0xbd, "mesh_object_plane_start_code" }, |
167 | | { 0xbe, 0xbe, "still_texture_object_start_code" }, |
168 | | { 0xbf, 0xbf, "texture_spatial_layer_start_code" }, |
169 | | { 0xc0, 0xc0, "texture_snr_layer_start_code" }, |
170 | | { 0xc1, 0xc1, "texture_tile_start_code" }, |
171 | | { 0xc2, 0xc2, "texture_shape_layer_start_code" }, |
172 | | { 0xc3, 0xc3, "stuffing_start_code" }, |
173 | | { 0xc4, 0xc5, "reserved" }, |
174 | | { 0xc6, 0xcf, "System start codes" }, /* NOTE System start codes are defined in ISO/IEC 14496-1:1999 */ |
175 | | { 0, 0, NULL } |
176 | | }; |
177 | | |
178 | | static const value_string mp4ves_vop_coding_type_vals[] = { |
179 | | { 0, "intra-coded (I)" }, |
180 | | { 1, "predictive-coded (P)" }, |
181 | | { 2, "bidirectionally-predictive-coded (B)" }, |
182 | | { 3, "sprite (S)" }, |
183 | | { 0, NULL } |
184 | | }; |
185 | | |
186 | | /* |
187 | | * FLC table for video_object_type indication |
188 | | */ |
189 | | static const value_string mp4ves_video_object_type_vals[] = { |
190 | | { 0x0, "Reserved" }, |
191 | | { 0x1, "Simple Object Type" }, |
192 | | { 0x2, "Simple Scalable Object Type" }, |
193 | | { 0x3, "Core Object Type" }, |
194 | | { 0x4, "Main Object Type" }, |
195 | | { 0x5, "N-bit Object Type" }, |
196 | | { 0x6, "Basic Anim. 2D Texture" }, |
197 | | { 0x7, "Anim. 2D Mesh" }, |
198 | | { 0x8, "Simple Face" }, |
199 | | { 0x9, "Still Scalable Texture" }, |
200 | | { 0xa, "Advanced Real Time Simple" }, |
201 | | { 0xb, "Core Scalable" }, |
202 | | { 0xc, "Advanced Coding Efficiency" }, |
203 | | { 0xd, "Advanced Scalable Texture" }, |
204 | | { 0xe, "Simple FBA" }, |
205 | | { 0, NULL } |
206 | | }; |
207 | | /* Visual object type */ |
208 | | static const value_string mp4ves_visual_object_type_vals[] = { |
209 | | { 0x0, "reserved" }, |
210 | | { 0x1, "video ID" }, |
211 | | { 0x2, "still texture ID" }, |
212 | | { 0x3, "mesh ID" }, |
213 | | { 0x4, "FBA ID" }, |
214 | | { 0x5, "3D mesh ID" }, |
215 | | { 0x6, "reserved" }, |
216 | | { 0x7, "reserved" }, |
217 | | { 0x8, "reserved" }, |
218 | | { 0x9, "reserved" }, |
219 | | { 0xa, "reserved" }, |
220 | | { 0xb, "reserved" }, |
221 | | { 0xc, "reserved" }, |
222 | | { 0xd, "reserved" }, |
223 | | { 0xe, "reserved" }, |
224 | | { 0xf, "reserved" }, |
225 | | { 0, NULL } |
226 | | }; |
227 | | |
228 | | static const value_string mp4ves_video_object_type_indication_vals[] = { |
229 | | { 0x0, "Reserved" }, |
230 | | { 0x1, "Simple Object Type" }, |
231 | | { 0x2, "Simple Scalable Object Type" }, |
232 | | { 0x3, "Core Object Type" }, |
233 | | { 0x4, "Main Object Type" }, |
234 | | { 0x5, "N-bit Object Type" }, |
235 | | { 0x6, "Basic Anim. 2D Texture" }, |
236 | | { 0x7, "Anim. 2D Mesh" }, |
237 | | { 0x8, "Simple Face" }, |
238 | | { 0x9, "Still Scalable Texture" }, |
239 | | { 0xa, "Advanced Real Time Simple" }, |
240 | | { 0xb, "Core Scalable" }, |
241 | | { 0xc, "Advanced Coding Efficiency" }, |
242 | | { 0xd, "Advanced Scalable Texture" }, |
243 | | { 0xe, "Simple FBA" }, |
244 | | { 0xf, "Reserved" }, |
245 | | /* Reserved 00001111 - 11111111 */ |
246 | | { 0, NULL } |
247 | | }; |
248 | | /* 6.2.2.1 User data */ |
249 | | static int |
250 | | dissect_mp4ves_user_data(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int bit_offset) |
251 | 0 | { |
252 | 0 | int start_bit_offset; |
253 | | |
254 | | /* user_data_start_code */ |
255 | 0 | proto_tree_add_bits_item(tree, hf_mp4ves_start_code_prefix, tvb, bit_offset, 24, ENC_BIG_ENDIAN); |
256 | 0 | bit_offset+=24; |
257 | 0 | proto_tree_add_bits_item(tree, hf_mp4ves_start_code, tvb, bit_offset, 8, ENC_BIG_ENDIAN); |
258 | 0 | bit_offset+=8; |
259 | 0 | start_bit_offset = bit_offset; |
260 | | /* while( next_bits() != '000 0000 0000 0000 0000 0001') { */ |
261 | 0 | while ( tvb_get_bits32(tvb,bit_offset, 24, ENC_BIG_ENDIAN) != 1){ |
262 | 0 | bit_offset+=8; |
263 | | /* user_data 8 bits */ |
264 | 0 | } |
265 | 0 | proto_tree_add_item(tree, hf_mp4ves_user_data, tvb, start_bit_offset>>3, (bit_offset - start_bit_offset)>>2, ENC_NA); |
266 | |
|
267 | 0 | return bit_offset; |
268 | 0 | } |
269 | | /* |
270 | | next_start_code() { |
271 | | zero_bit |
272 | | while (!bytealigned()) |
273 | | one_bit |
274 | | } |
275 | | */ |
276 | | static int |
277 | | dissect_mp4ves_next_start_code(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int bit_offset) |
278 | 0 | { |
279 | 0 | uint8_t zero_bit; |
280 | 0 | int start_bit_offset; |
281 | |
|
282 | 0 | start_bit_offset = bit_offset; |
283 | |
|
284 | 0 | zero_bit = tvb_get_bits8(tvb,bit_offset,1); |
285 | 0 | if (zero_bit != 0){ |
286 | | /* Error */ |
287 | 0 | } |
288 | 0 | bit_offset++; |
289 | | |
290 | | /* zero stuffing bits */ |
291 | 0 | if(bit_offset %8 == 0) |
292 | 0 | return bit_offset; |
293 | | |
294 | 0 | while(bit_offset %8 != 0){ |
295 | 0 | bit_offset++; |
296 | 0 | } |
297 | |
|
298 | 0 | proto_tree_add_bits_item(tree, hf_mp4ves_stuffing, tvb, start_bit_offset, bit_offset-start_bit_offset, ENC_BIG_ENDIAN); |
299 | |
|
300 | 0 | return bit_offset; |
301 | 0 | } |
302 | | |
303 | | #if 0 |
304 | | video_signal_type() { |
305 | | video_signal_type |
306 | | if (video_signal_type) { |
307 | | video_format 3 uimsbf |
308 | | video_range 1 bslbf |
309 | | colour_description 1 bslbf |
310 | | if (colour_description) { |
311 | | colour_primaries 8 uimsbf |
312 | | transfer_characteristics 8 uimsbf |
313 | | matrix_coefficients 8 uimsbf |
314 | | } |
315 | | } |
316 | | } |
317 | | #endif |
318 | | |
319 | | static int |
320 | | dissect_mp4ves_visual_object_type(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int bit_offset) |
321 | 0 | { |
322 | 0 | uint8_t video_signal_type, colour_description; |
323 | |
|
324 | 0 | video_signal_type = tvb_get_bits8(tvb,bit_offset,1); |
325 | 0 | proto_tree_add_bits_item(tree, hf_mp4ves_video_signal_type, tvb, bit_offset, 1, ENC_BIG_ENDIAN); |
326 | 0 | bit_offset++; |
327 | 0 | if (video_signal_type) { |
328 | | /* video_format 3 bits */ |
329 | 0 | bit_offset+=3; |
330 | | /* video_range 1 bit */ |
331 | 0 | bit_offset++; |
332 | | /* colour_description 1 bit */ |
333 | 0 | colour_description = tvb_get_bits8(tvb,bit_offset,1); |
334 | 0 | if (colour_description) { |
335 | | /* colour_primaries 8 bits */ |
336 | 0 | bit_offset+=8; |
337 | | /* transfer_characteristics 8 bits */ |
338 | 0 | bit_offset+=8; |
339 | | /* matrix_coefficients 8 bits*/ |
340 | 0 | bit_offset+=8; |
341 | 0 | } |
342 | 0 | } |
343 | |
|
344 | 0 | return bit_offset; |
345 | 0 | } |
346 | | /* |
347 | | * 6.2.3 Video Object Layer |
348 | | */ |
349 | | |
350 | | /* |
351 | | * Table 6-12 -- Meaning of pixel aspect ratio |
352 | | */ |
353 | | |
354 | | static const value_string mp4ves_aspect_ratio_info_vals[] = { |
355 | | { 0x0, "Forbidden" }, |
356 | | { 0x1, "1:1 (Square)" }, |
357 | | { 0x2, "12:11 (625-type for 4:3 picture)" }, |
358 | | { 0x3, "10:11 (525-type for 4:3 picture)" }, |
359 | | { 0x4, "16:11 (625-type stretched for 16:9 picture)" }, |
360 | | { 0x5, "40:33 (525-type stretched for 16:9 picture)" }, |
361 | | { 0x6, "Reserved" }, |
362 | | { 0x7, "Reserved" }, |
363 | | { 0x8, "Reserved" }, |
364 | | { 0x9, "Reserved" }, |
365 | | { 0xa, "Reserved" }, |
366 | | { 0xb, "Reserved" }, |
367 | | { 0xc, "Reserved" }, |
368 | | { 0xd, "Reserved" }, |
369 | | { 0xe, "Reserved" }, |
370 | | { 0xf, "Extended PAR" }, |
371 | | { 0, NULL } |
372 | | }; |
373 | | |
374 | | /* Table 6-14 Video Object Layer shape type */ |
375 | | static const value_string mp4ves_video_object_layer_shape_vals[] = { |
376 | | { 0x0, "rectangular" }, |
377 | | { 0x1, "binary" }, |
378 | | { 0x2, "binary only" }, |
379 | | { 0x3, "grayscale" }, |
380 | | { 0, NULL } |
381 | | }; |
382 | | |
383 | | static int |
384 | | dissect_mp4ves_VideoObjectLayer(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int bit_offset) |
385 | 0 | { |
386 | 0 | uint32_t dword; |
387 | 0 | int current_bit_offset; |
388 | 0 | uint8_t octet, is_object_layer_identifier, aspect_ratio_info, vol_control_parameters, vbv_parameters; |
389 | 0 | uint8_t video_object_layer_shape, video_object_layer_verid = 0; |
390 | | |
391 | | /* if(next_bits() == video_object_layer_start_code) { */ |
392 | 0 | dword = tvb_get_bits32(tvb,bit_offset, 24, ENC_BIG_ENDIAN); |
393 | 0 | if (dword != 1){ |
394 | 0 | return bit_offset; |
395 | 0 | } |
396 | 0 | octet = tvb_get_bits8(tvb,bit_offset+24, 8); |
397 | 0 | if((octet>=0x20)&&(octet<=0x2f)){ |
398 | | /* Continue */ |
399 | 0 | }else{ |
400 | 0 | return bit_offset; |
401 | 0 | } |
402 | | /* video_object_layer_start_code */ |
403 | 0 | proto_tree_add_bits_item(tree, hf_mp4ves_start_code_prefix, tvb, bit_offset, 24, ENC_BIG_ENDIAN); |
404 | 0 | bit_offset+=24; |
405 | 0 | proto_tree_add_bits_item(tree, hf_mp4ves_start_code, tvb, bit_offset, 8, ENC_BIG_ENDIAN); |
406 | 0 | bit_offset+= 8; |
407 | | |
408 | | /* short_video_header = 0 */ |
409 | | /* random_accessible_vol 1 */ |
410 | 0 | proto_tree_add_bits_item(tree, hf_mp4ves_random_accessible_vol, tvb, bit_offset, 1, ENC_BIG_ENDIAN); |
411 | 0 | bit_offset++; |
412 | | /* video_object_type_indication 8 */ |
413 | 0 | proto_tree_add_bits_item(tree, hf_mp4ves_video_object_type_indication, tvb, bit_offset, 8, ENC_BIG_ENDIAN); |
414 | 0 | bit_offset+= 8; |
415 | | /* is_object_layer_identifier 1 */ |
416 | 0 | is_object_layer_identifier = tvb_get_bits8(tvb,bit_offset, 1); |
417 | 0 | proto_tree_add_bits_item(tree, hf_mp4ves_is_object_layer_identifier, tvb, bit_offset, 1, ENC_BIG_ENDIAN); |
418 | 0 | bit_offset++; |
419 | 0 | if(is_object_layer_identifier) { |
420 | | /* video_object_layer_verid 4 uimsbf */ |
421 | 0 | bit_offset+=4; |
422 | | /* video_object_layer_priority 3 uimsbf */ |
423 | 0 | bit_offset+=3; |
424 | 0 | } |
425 | | /* aspect_ratio_info 4 uimsbf */ |
426 | 0 | aspect_ratio_info = tvb_get_bits8(tvb,bit_offset, 1); |
427 | 0 | proto_tree_add_bits_item(tree, hf_mp4ves_aspect_ratio_info, tvb, bit_offset, 4, ENC_BIG_ENDIAN); |
428 | 0 | if (aspect_ratio_info == 0xf /*"extended_PAR"*/ ) { |
429 | | /* par_width 8 uimsbf */ |
430 | 0 | bit_offset+=8; |
431 | | /* par_height 8 uimsbf */ |
432 | 0 | bit_offset+=8; |
433 | 0 | } |
434 | | /* vol_control_parameters 1 bslbf */ |
435 | | /* vol_control_parameters 1 bslbf */ |
436 | 0 | vol_control_parameters = tvb_get_bits8(tvb,bit_offset, 1); |
437 | 0 | proto_tree_add_bits_item(tree, hf_mp4ves_vol_control_parameters, tvb, bit_offset, 1, ENC_BIG_ENDIAN); |
438 | 0 | bit_offset++; |
439 | 0 | current_bit_offset = bit_offset; |
440 | 0 | if (vol_control_parameters) { |
441 | | /* chroma_format 2 uimsbf */ |
442 | 0 | bit_offset+=2; |
443 | | /* low_delay 1 uimsbf */ |
444 | 0 | bit_offset++; |
445 | | /* vbv_parameters 1 blsbf */ |
446 | 0 | vbv_parameters = tvb_get_bits8(tvb,bit_offset, 1); |
447 | 0 | bit_offset++; |
448 | 0 | if (vbv_parameters) { |
449 | | /* first_half_bit_rate 15 uimsbf */ |
450 | 0 | bit_offset+=15; |
451 | | /* marker_bit 1 bslbf */ |
452 | 0 | bit_offset++; |
453 | | /* latter_half_bit_rate 15 uimsbf */ |
454 | 0 | bit_offset+=15; |
455 | | /* marker_bit 1 bslbf */ |
456 | 0 | bit_offset++; |
457 | | /* first_half_vbv_buffer_size 15 uimsbf */ |
458 | 0 | bit_offset+=15; |
459 | | /* marker_bit 1 bslbf */ |
460 | 0 | bit_offset++; |
461 | | /* latter_half_vbv_buffer_size 3 uimsbf */ |
462 | 0 | bit_offset+=3; |
463 | | /* first_half_vbv_occupancy 11 uimsbf */ |
464 | 0 | bit_offset+=11; |
465 | | /* marker_bit 1 blsbf */ |
466 | 0 | bit_offset++; |
467 | | /* latter_half_vbv_occupancy 15 uimsbf */ |
468 | 0 | bit_offset+=15; |
469 | | /* marker_bit 1 blsbf */ |
470 | 0 | bit_offset++; |
471 | 0 | } |
472 | 0 | } |
473 | 0 | if(bit_offset-current_bit_offset > 0) |
474 | 0 | proto_tree_add_expert(tree, pinfo, &ei_mp4ves_not_dissected_bits, tvb, current_bit_offset>>3, (bit_offset+7)>>3); |
475 | | /* video_object_layer_shape 2 uimsbf */ |
476 | 0 | video_object_layer_shape = tvb_get_bits8(tvb,bit_offset, 2); |
477 | 0 | proto_tree_add_bits_item(tree, hf_mp4ves_video_object_layer_shape, tvb, bit_offset, 2, ENC_BIG_ENDIAN); |
478 | 0 | bit_offset+=2; |
479 | 0 | if (video_object_layer_shape == 3/*"grayscale"*/&& video_object_layer_verid != 1){ |
480 | | /* video_object_layer_shape_extension 4 uimsbf */ |
481 | 0 | bit_offset+=4; |
482 | 0 | } |
483 | | /* marker_bit 1 bslbf */ |
484 | 0 | bit_offset++; |
485 | | /* vop_time_increment_resolution 16 uimsbf */ |
486 | 0 | bit_offset+=16; |
487 | | /* marker_bit 1 bslbf */ |
488 | 0 | bit_offset++; |
489 | | /* fixed_vop_rate 1 bslbf */ |
490 | 0 | bit_offset++; |
491 | | |
492 | |
|
493 | 0 | return bit_offset; |
494 | 0 | } |
495 | | /* Visual object */ |
496 | | /* |
497 | | VisualObject() { |
498 | | visual_object_start_code |
499 | | is_visual_object_identifier |
500 | | if (is_visual_object_identifier) { |
501 | | visual_object_verid |
502 | | visual_object_priority |
503 | | } |
504 | | visual_object_type |
505 | | if (visual_object_type == "Video ID" || visual_object_type == "still textureID") { |
506 | | video_signal_type() |
507 | | } |
508 | | next_start_code() |
509 | | while ( next_bits()== user_data_start_code){ |
510 | | user_data() |
511 | | } |
512 | | if (visual_object_type == "Video ID") { |
513 | | video_object_start_code |
514 | | VideoObjectLayer() |
515 | | } |
516 | | else if (visual_object_type == "still texture ID") { |
517 | | StillTextureObject() |
518 | | } |
519 | | else if (visual_object_type == "mesh ID") { |
520 | | MeshObject() |
521 | | } |
522 | | else if (visual_object_type == "FBA ID") { |
523 | | FBAObject() |
524 | | } |
525 | | else if (visual_object_type == "3D mesh ID") { |
526 | | 3D_Mesh_Object() |
527 | | } |
528 | | if (next_bits() != "0000 0000 0000 0000 0000 0001") |
529 | | next_start_code() |
530 | | } |
531 | | */ |
532 | | static int |
533 | | dissect_mp4ves_VisualObject(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int bit_offset) |
534 | 0 | { |
535 | 0 | uint8_t is_visual_object_identifier, visual_object_type; |
536 | 0 | uint32_t dword; |
537 | 0 | uint8_t octet; |
538 | |
|
539 | 0 | is_visual_object_identifier = tvb_get_bits8(tvb,bit_offset,1); |
540 | 0 | proto_tree_add_bits_item(tree, hf_mp4ves_is_visual_object_identifier, tvb, bit_offset, 1, ENC_BIG_ENDIAN); |
541 | 0 | bit_offset++; |
542 | 0 | if(is_visual_object_identifier){ |
543 | | /* visual_object_verid 4 bits*/ |
544 | 0 | bit_offset+=4; |
545 | | /* visual_object_priority 3 bits*/ |
546 | 0 | bit_offset+=3; |
547 | 0 | } |
548 | | /* visual_object_type 4 bits*/ |
549 | 0 | visual_object_type = tvb_get_bits8(tvb,bit_offset,4); |
550 | 0 | proto_tree_add_bits_item(tree, hf_mp4ves_visual_object_type, tvb, bit_offset, 4, ENC_BIG_ENDIAN); |
551 | 0 | bit_offset+=4; |
552 | 0 | if ((visual_object_type == 1/*"Video ID"*/) || (visual_object_type == 2/*"still textureID"*/)) { |
553 | | /* video_signal_type() */ |
554 | 0 | bit_offset = dissect_mp4ves_visual_object_type(tvb, pinfo, tree, bit_offset); |
555 | 0 | } |
556 | | /* next_start_code() */ |
557 | 0 | bit_offset = dissect_mp4ves_next_start_code(tvb, pinfo, tree, bit_offset); |
558 | 0 | dword = tvb_get_bits32(tvb,bit_offset, 32, ENC_BIG_ENDIAN); |
559 | | /* |
560 | | while ( next_bits()== user_data_start_code){ |
561 | | user_data() |
562 | | } |
563 | | */ |
564 | 0 | while(dword==0x1b2){ |
565 | 0 | bit_offset = dissect_mp4ves_user_data(tvb, pinfo, tree, bit_offset); |
566 | 0 | dword = tvb_get_bits32(tvb,bit_offset, 32, ENC_BIG_ENDIAN); |
567 | 0 | } |
568 | 0 | if (visual_object_type == 1/*"Video ID"*/) { |
569 | | /* |
570 | | * video_object_start_code |
571 | | */ |
572 | 0 | dword = tvb_get_bits32(tvb,bit_offset, 24, ENC_BIG_ENDIAN); |
573 | 0 | if (dword != 1){ |
574 | | /* no start code */ |
575 | 0 | return -1; |
576 | 0 | } |
577 | 0 | octet = tvb_get_bits8(tvb,bit_offset+24, 8); |
578 | 0 | if(octet>0x20){ |
579 | | /* Error */ |
580 | 0 | return -1; |
581 | 0 | } |
582 | 0 | proto_tree_add_bits_item(tree, hf_mp4ves_start_code_prefix, tvb, bit_offset, 24, ENC_BIG_ENDIAN); |
583 | 0 | bit_offset+=24; |
584 | 0 | proto_tree_add_bits_item(tree, hf_mp4ves_start_code, tvb, bit_offset, 8, ENC_BIG_ENDIAN); |
585 | 0 | bit_offset+= 8; |
586 | 0 | if(tvb_reported_length_remaining(tvb,(bit_offset>>3))<=0){ |
587 | 0 | proto_tree_add_expert(tree, pinfo, &ei_mp4ves_config_too_short, tvb, 0, -1); |
588 | 0 | return -1; |
589 | 0 | } |
590 | | /* |
591 | | VideoObjectLayer() |
592 | | */ |
593 | 0 | bit_offset = dissect_mp4ves_VideoObjectLayer(tvb, pinfo, tree, bit_offset); |
594 | 0 | } |
595 | | |
596 | 0 | return bit_offset; |
597 | 0 | } |
598 | | |
599 | | static int |
600 | | dissect_mp4ves_VisualObjectSequence(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int bit_offset) |
601 | 0 | { |
602 | 0 | uint32_t dword; |
603 | | |
604 | | /*VisualObjectSequence() { |
605 | | do { |
606 | | visual_object_sequence_start_code |
607 | | */ |
608 | | |
609 | | /* Get start code prefix */ |
610 | 0 | dword = tvb_get_bits32(tvb,bit_offset, 32, ENC_BIG_ENDIAN); |
611 | 0 | if ((dword & 0x00000100) != 0x00000100){ |
612 | | /* No start code prefix */ |
613 | 0 | return -1; |
614 | 0 | } |
615 | 0 | proto_tree_add_bits_item(tree, hf_mp4ves_start_code_prefix, tvb, bit_offset, 24, ENC_BIG_ENDIAN); |
616 | 0 | bit_offset+= 24; |
617 | |
|
618 | 0 | proto_tree_add_bits_item(tree, hf_mp4ves_start_code, tvb, bit_offset, 8, ENC_BIG_ENDIAN); |
619 | 0 | bit_offset+= 8; |
620 | | |
621 | | /* Expect visual_object_sequence_start_code */ |
622 | 0 | if(dword != 0x1b0) |
623 | 0 | return -1; |
624 | | /* profile_and_level_indication */ |
625 | 0 | proto_tree_add_bits_item(tree, hf_mp4ves_profile_and_level_indication, tvb, bit_offset, 8, ENC_BIG_ENDIAN); |
626 | 0 | bit_offset+= 8; |
627 | | |
628 | | /* while ( next_bits()== user_data_start_code){ |
629 | | user_data() |
630 | | } |
631 | | */ |
632 | 0 | dword = tvb_get_bits32(tvb,bit_offset, 32, ENC_BIG_ENDIAN); |
633 | 0 | bit_offset+= 32; |
634 | 0 | if ((dword & 0x00000100) != 0x00000100){ |
635 | | /* No start code prefix */ |
636 | 0 | return -1; |
637 | 0 | } |
638 | 0 | if(dword==0x1b2){ |
639 | | /* |
640 | | * user_data_start_code |
641 | | * XXX call user data dissection here |
642 | | */ |
643 | 0 | return -1; |
644 | 0 | } |
645 | 0 | if(dword==0x1b5){ |
646 | | /* |
647 | | * VisualObject() |
648 | | */ |
649 | 0 | bit_offset = dissect_mp4ves_VisualObject(tvb, pinfo, tree, bit_offset); |
650 | 0 | } |
651 | | /* |
652 | | } while ( next_bits() != visual_object_sequence_end_code) |
653 | | visual_object_sequence_end_code |
654 | | */ |
655 | 0 | return bit_offset; |
656 | 0 | } |
657 | | |
658 | | static int |
659 | | dissect_mp4ves_config(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) |
660 | 0 | { |
661 | 0 | proto_item *item; |
662 | 0 | proto_tree *mp4ves_tree; |
663 | |
|
664 | 0 | item = proto_tree_add_item(tree, hf_mp4ves_config, tvb, 0, -1, ENC_NA); |
665 | 0 | mp4ves_tree = proto_item_add_subtree(item, ett_mp4ves_config); |
666 | |
|
667 | 0 | dissect_mp4ves_VisualObjectSequence(tvb, pinfo, mp4ves_tree, 0); |
668 | 0 | return tvb_captured_length(tvb); |
669 | 0 | } |
670 | | |
671 | | static int |
672 | | dissect_mp4ves(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) |
673 | 0 | { |
674 | 0 | int bit_offset = 0; |
675 | 0 | proto_item *item; |
676 | 0 | proto_tree *mp4ves_tree; |
677 | 0 | uint32_t dword; |
678 | | |
679 | | /* Make entries in Protocol column and Info column on summary display */ |
680 | 0 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "MP4V-ES"); |
681 | 0 | if (tree) { |
682 | 0 | item = proto_tree_add_item(tree, proto_mp4ves, tvb, 0, -1, ENC_NA); |
683 | 0 | mp4ves_tree = proto_item_add_subtree(item, ett_mp4ves); |
684 | | /* |
685 | | +------+------+------+------+ |
686 | | (a) | RTP | VS | VO | VOL | |
687 | | |header|header|header|header| |
688 | | +------+------+------+------+ |
689 | | |
690 | | +------+------+------+------+------------+ |
691 | | (b) | RTP | VS | VO | VOL |Video Packet| |
692 | | |header|header|header|header| | |
693 | | +------+------+------+------+------------+ |
694 | | |
695 | | +------+-----+------------------+ |
696 | | (c) | RTP | GOV |Video Object Plane| |
697 | | |header| | | |
698 | | +------+-----+------------------+ |
699 | | |
700 | | +------+------+------------+ +------+------+------------+ |
701 | | (d) | RTP | VOP |Video Packet| | RTP | VP |Video Packet| |
702 | | |header|header| (1) | |header|header| (2) | |
703 | | +------+------+------------+ +------+------+------------+ |
704 | | |
705 | | +------+------+------------+------+------------+------+------------+ |
706 | | (e) | RTP | VP |Video Packet| VP |Video Packet| VP |Video Packet| |
707 | | |header|header| (1) |header| (2) |header| (3) | |
708 | | +------+------+------------+------+------------+------+------------+ |
709 | | |
710 | | +------+------+------------+ +------+------------+ |
711 | | (f) | RTP | VOP |VOP fragment| | RTP |VOP fragment| |
712 | | |header|header| (1) | |header| (2) | ___ |
713 | | +------+------+------------+ +------+------------+ |
714 | | |
715 | | Figure 2 - Examples of RTP packetized MPEG-4 Visual bitstream |
716 | | |
717 | | So a valid packet should start with |
718 | | VS - Visual Object Sequence Header |
719 | | GOV - Group_of_VideoObjectPlane |
720 | | VOP - Video Object Plane |
721 | | VP - Video Plane |
722 | | Otherwise it's a VOP fragment. |
723 | | |
724 | | visual_object_sequence_start_code: The visual_object_sequence_start_code is |
725 | | the bit string '000001B0' in hexadecimal. It initiates a visual session. |
726 | | |
727 | | group_of_vop_start_code: The group_of_vop_start_code is the bit string '000001B3' in hexadecimal. It identifies |
728 | | the beginning of a GOV header. |
729 | | |
730 | | vop_start_code: This is the bit string '000001B6' in hexadecimal. |
731 | | |
732 | | |
733 | | */ |
734 | 0 | if (tvb_reported_length(tvb)< 4){ |
735 | | /* To short to be a start code */ |
736 | 0 | proto_tree_add_item(mp4ves_tree, hf_mp4ves_data, tvb, bit_offset>>3, -1, ENC_NA); |
737 | 0 | return tvb_captured_length(tvb); |
738 | 0 | } |
739 | 0 | dword = tvb_get_bits32(tvb,bit_offset, 24, ENC_BIG_ENDIAN); |
740 | 0 | if (dword != 1){ |
741 | | /* if it's not 23 zeros followed by 1 it isn't a start code */ |
742 | 0 | proto_tree_add_item(mp4ves_tree, hf_mp4ves_data, tvb, bit_offset>>3, -1, ENC_NA); |
743 | 0 | return tvb_captured_length(tvb); |
744 | 0 | } |
745 | 0 | dword = tvb_get_bits8(tvb,24, 8); |
746 | 0 | bit_offset = bit_offset+8; |
747 | 0 | switch(dword){ |
748 | | /* vop_start_code */ |
749 | 0 | case 0xb6: |
750 | 0 | proto_tree_add_bits_item(mp4ves_tree, hf_mp4ves_start_code_prefix, tvb, bit_offset, 24, ENC_BIG_ENDIAN); |
751 | 0 | bit_offset = bit_offset+24; |
752 | | /* vop_coding_type 2 bits */ |
753 | 0 | proto_tree_add_bits_item(mp4ves_tree, hf_mp4ves_vop_coding_type, tvb, bit_offset, 2, ENC_BIG_ENDIAN); |
754 | 0 | break; |
755 | 0 | case 0xb0: |
756 | | /* VS start code */ |
757 | 0 | /*bit_offset = */dissect_mp4ves_VisualObjectSequence(tvb, pinfo, mp4ves_tree, 0); |
758 | 0 | break; |
759 | 0 | default: |
760 | 0 | proto_tree_add_bits_item(mp4ves_tree, hf_mp4ves_start_code_prefix, tvb, bit_offset, 24, ENC_BIG_ENDIAN); |
761 | | /*bit_offset = bit_offset+24;*/ |
762 | 0 | break; |
763 | 0 | } |
764 | 0 | } |
765 | | |
766 | 0 | return tvb_captured_length(tvb); |
767 | 0 | } |
768 | | /* |
769 | | * Parameter name profileAndLevel |
770 | | * Parameter description This is a nonCollapsing GenericParameter |
771 | | * Parameter identifier value 0 |
772 | | * Parameter status Mandatory |
773 | | * Parameter type unsignedMax. Shall be in the range 0..255. |
774 | | * H245: |
775 | | * unsignedMax INTEGER(0..65535), -- Look for max |
776 | | */ |
777 | | static int |
778 | | dissect_mp4ves_par_profile(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree _U_, void *data) |
779 | 0 | { |
780 | 0 | int offset = 0; |
781 | 0 | uint16_t lvl; |
782 | 0 | const char *p = NULL; |
783 | 0 | asn1_ctx_t *actx; |
784 | | |
785 | | /* Reject the packet if data is NULL */ |
786 | 0 | if (data == NULL) |
787 | 0 | return 0; |
788 | 0 | actx = get_asn1_ctx(data); |
789 | 0 | DISSECTOR_ASSERT(actx); |
790 | |
|
791 | 0 | lvl = tvb_get_ntohs(tvb, offset); |
792 | 0 | p = try_val_to_str(lvl, VALS(mp4ves_level_indication_vals)); |
793 | 0 | if (p) { |
794 | 0 | proto_item_append_text(actx->created_item, " - profileAndLevel %s", p); |
795 | 0 | } |
796 | 0 | offset += 2; |
797 | 0 | return offset; |
798 | 0 | } |
799 | | static int |
800 | | dissect_mp4ves_par_video_object_type(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree _U_, void *data) |
801 | 0 | { |
802 | 0 | int offset = 0; |
803 | 0 | uint16_t lvl; |
804 | 0 | const char *p = NULL; |
805 | 0 | asn1_ctx_t *actx; |
806 | | |
807 | | /* Reject the packet if data is NULL */ |
808 | 0 | if (data == NULL) |
809 | 0 | return 0; |
810 | 0 | actx = get_asn1_ctx(data); |
811 | 0 | DISSECTOR_ASSERT(actx); |
812 | |
|
813 | 0 | lvl = tvb_get_ntohs(tvb, offset); |
814 | 0 | p = try_val_to_str(lvl, VALS(mp4ves_video_object_type_vals)); |
815 | 0 | if (p) { |
816 | 0 | proto_item_append_text(actx->created_item, " - video_object_type %s", p); |
817 | 0 | } |
818 | 0 | offset += 2; |
819 | 0 | return offset; |
820 | 0 | } |
821 | | |
822 | | static int |
823 | | dissect_mp4ves_par_decoderConfigurationInformation(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) |
824 | 0 | { |
825 | 0 | asn1_ctx_t *actx; |
826 | | |
827 | | /* Reject the packet if data is NULL */ |
828 | 0 | if (data == NULL) |
829 | 0 | return 0; |
830 | 0 | actx = get_asn1_ctx(data); |
831 | 0 | DISSECTOR_ASSERT(actx); |
832 | |
|
833 | 0 | dissect_mp4ves_config(tvb, pinfo, tree, data); |
834 | |
|
835 | 0 | return tvb_reported_length(tvb); |
836 | 0 | } |
837 | | |
838 | | typedef struct _mp4ves_capability_t { |
839 | | const char *id; |
840 | | const char *name; |
841 | | dissector_t content_pdu; |
842 | | } mp4ves_capability_t; |
843 | | |
844 | | static mp4ves_capability_t mp4ves_capability_tab[] = { |
845 | | /* ITU-T H.245 capabilities ISO/IEC 14496-2(m*/ |
846 | | { "GenericCapability/0.0.8.245.1.0.0/nonCollapsing/0", "profileAndLevel", dissect_mp4ves_par_profile }, |
847 | | { "GenericCapability/0.0.8.245.1.0.0/nonCollapsing/1", "object", dissect_mp4ves_par_video_object_type }, |
848 | | { "GenericCapability/0.0.8.245.1.0.0/nonCollapsing/2", "decoderConfigurationInformation", dissect_mp4ves_par_decoderConfigurationInformation }, |
849 | | { "GenericCapability/0.0.8.245.1.0.0/nonCollapsing/3", "drawingOrder", NULL }, |
850 | | { "GenericCapability/0.0.8.245.1.0.0/collapsing/4", "visualBackChannelHandle", NULL }, |
851 | | { NULL, NULL, NULL }, |
852 | | }; |
853 | | |
854 | 0 | static mp4ves_capability_t *find_cap(const char *id) { |
855 | 0 | mp4ves_capability_t *ftr = NULL; |
856 | 0 | mp4ves_capability_t *f; |
857 | |
|
858 | 0 | for (f=mp4ves_capability_tab; f->id; f++) { |
859 | 0 | if (!strcmp(id, f->id)) { ftr = f; break; } |
860 | 0 | } |
861 | 0 | return ftr; |
862 | 0 | } |
863 | | |
864 | | static int |
865 | | dissect_mp4ves_name(tvbuff_t *tvb _U_, packet_info *pinfo, proto_tree *tree, void* data) |
866 | 0 | { |
867 | 0 | asn1_ctx_t *actx; |
868 | 0 | mp4ves_capability_t *ftr; |
869 | | |
870 | | /* Reject the packet if data is NULL */ |
871 | 0 | if (data == NULL) |
872 | 0 | return 0; |
873 | 0 | actx = get_asn1_ctx(data); |
874 | 0 | DISSECTOR_ASSERT(actx); |
875 | |
|
876 | 0 | if (tree) { |
877 | 0 | ftr = find_cap(pinfo->match_string); |
878 | 0 | if (ftr) { |
879 | 0 | proto_item_append_text(actx->created_item, " - %s", ftr->name); |
880 | 0 | proto_item_append_text(proto_item_get_parent(proto_tree_get_parent(tree)), ": %s", ftr->name); |
881 | 0 | } else { |
882 | 0 | proto_item_append_text(actx->created_item, " - unknown(%s)", pinfo->match_string); |
883 | 0 | } |
884 | 0 | } |
885 | |
|
886 | 0 | return tvb_reported_length(tvb); |
887 | 0 | } |
888 | | |
889 | | void |
890 | | proto_register_mp4ves(void) |
891 | 14 | { |
892 | | |
893 | | |
894 | | /* Setup list of header fields See Section 1.6.1 for details*/ |
895 | 14 | static hf_register_info hf[] = { |
896 | 14 | { &hf_mp4ves_config, |
897 | 14 | { "Configuration", "mp4ves.configuration", |
898 | 14 | FT_BYTES, BASE_NONE, NULL, 0x0, |
899 | 14 | NULL, HFILL } |
900 | 14 | }, |
901 | 14 | { &hf_mp4ves_start_code_prefix, |
902 | 14 | { "start code prefix", "mp4ves.start_code_prefix", |
903 | 14 | FT_UINT32, BASE_HEX, NULL, 0x0, |
904 | 14 | NULL, HFILL } |
905 | 14 | }, |
906 | 14 | { &hf_mp4ves_start_code, |
907 | 14 | { "Start code", "mp4ves.start_code", |
908 | 14 | FT_UINT8, BASE_RANGE_STRING|BASE_HEX, RVALS(mp4ves_startcode_vals), 0x0, |
909 | 14 | NULL, HFILL } |
910 | 14 | }, |
911 | 14 | { &hf_mp4ves_vop_coding_type, |
912 | 14 | { "vop_coding_type", "mp4ves.vop_coding_type", |
913 | 14 | FT_UINT8, BASE_DEC, VALS(mp4ves_vop_coding_type_vals), 0x0, |
914 | 14 | "Start code", HFILL } |
915 | 14 | }, |
916 | 14 | {&hf_mp4ves_profile_and_level_indication, |
917 | 14 | { "profile_and_level_indication", "mp4ves.profile_and_level_indication", |
918 | 14 | FT_UINT8, BASE_DEC,VALS(mp4ves_level_indication_vals), 0x0, |
919 | 14 | NULL, HFILL } |
920 | 14 | }, |
921 | 14 | { &hf_mp4ves_is_visual_object_identifier, |
922 | 14 | { "visual_object_identifier", "mp4ves.visual_object_identifier", |
923 | 14 | FT_UINT8, BASE_DEC, NULL, 0x0, |
924 | 14 | NULL, HFILL } |
925 | 14 | }, |
926 | 14 | { &hf_mp4ves_visual_object_type, |
927 | 14 | { "visual_object_type", "mp4ves.visual_object_type", |
928 | 14 | FT_UINT32, BASE_DEC, VALS(mp4ves_visual_object_type_vals), 0x0, |
929 | 14 | NULL, HFILL } |
930 | 14 | }, |
931 | 14 | { &hf_mp4ves_video_signal_type, |
932 | 14 | { "video_signal_type", "mp4ves.video_signal_type", |
933 | 14 | FT_UINT8, BASE_DEC, NULL, 0x0, |
934 | 14 | NULL, HFILL } |
935 | 14 | }, |
936 | 14 | { &hf_mp4ves_stuffing, |
937 | 14 | { "Stuffing", "mp4ves.stuffing", |
938 | 14 | FT_UINT8, BASE_DEC, NULL, 0x0, |
939 | 14 | NULL, HFILL } |
940 | 14 | }, |
941 | 14 | { &hf_mp4ves_video_object_type_indication, |
942 | 14 | { "video_object_type_indication", "mp4ves.video_object_type_indication", |
943 | 14 | FT_UINT8, BASE_DEC, VALS(mp4ves_video_object_type_indication_vals), 0x0, |
944 | 14 | NULL, HFILL } |
945 | 14 | }, |
946 | 14 | { &hf_mp4ves_random_accessible_vol, |
947 | 14 | { "random_accessible_vol", "mp4ves.random_accessible_vol", |
948 | 14 | FT_UINT8, BASE_DEC, NULL, 0x0, |
949 | 14 | "video_object_type_indication", HFILL } |
950 | 14 | }, |
951 | 14 | { &hf_mp4ves_is_object_layer_identifier, |
952 | 14 | { "is_object_layer_identifier", "mp4ves.is_object_layer_identifier", |
953 | 14 | FT_UINT8, BASE_DEC, NULL, 0x0, |
954 | 14 | NULL, HFILL } |
955 | 14 | }, |
956 | 14 | { &hf_mp4ves_aspect_ratio_info, |
957 | 14 | { "aspect_ratio_info", "mp4ves.aspect_ratio_info", |
958 | 14 | FT_UINT8, BASE_DEC, VALS(mp4ves_aspect_ratio_info_vals), 0x0, |
959 | 14 | NULL, HFILL } |
960 | 14 | }, |
961 | 14 | { &hf_mp4ves_vol_control_parameters, |
962 | 14 | { "vol_control_parameters", "mp4ves.vol_control_parameters", |
963 | 14 | FT_UINT8, BASE_DEC, NULL, 0x0, |
964 | 14 | NULL, HFILL } |
965 | 14 | }, |
966 | 14 | { &hf_mp4ves_video_object_layer_shape, |
967 | 14 | { "video_object_layer_shape", "mp4ves.video_object_layer_shape", |
968 | 14 | FT_UINT8, BASE_DEC, VALS(mp4ves_video_object_layer_shape_vals), 0x0, |
969 | 14 | NULL, HFILL } |
970 | 14 | }, |
971 | 14 | { &hf_mp4ves_user_data, |
972 | 14 | { "User data", "mp4ves.user_data", |
973 | 14 | FT_BYTES, BASE_NONE, NULL, 0x0, |
974 | 14 | NULL, HFILL } |
975 | 14 | }, |
976 | 14 | { &hf_mp4ves_data, |
977 | 14 | { "Data", "mp4ves.data", |
978 | 14 | FT_BYTES, BASE_NONE, NULL, 0x0, |
979 | 14 | NULL, HFILL } |
980 | 14 | }, |
981 | 14 | }; |
982 | | |
983 | | /* Setup protocol subtree array */ |
984 | 14 | static int *ett[] = { |
985 | 14 | &ett_mp4ves, |
986 | 14 | &ett_mp4ves_config, |
987 | 14 | }; |
988 | | |
989 | 14 | static ei_register_info ei[] = { |
990 | 14 | { &ei_mp4ves_config_too_short, { "mp4ves.config_too_short", PI_MALFORMED, PI_ERROR, "Config string too short", EXPFILL }}, |
991 | 14 | { &ei_mp4ves_not_dissected_bits, { "mp4ves.not_dissected_bits", PI_UNDECODED, PI_WARN, "Not dissected bits", EXPFILL }}, |
992 | 14 | }; |
993 | | |
994 | 14 | module_t *mp4ves_module; |
995 | 14 | expert_module_t* expert_mp4ves; |
996 | | |
997 | | /* Register the protocol name and description */ |
998 | 14 | proto_mp4ves = proto_register_protocol("MP4V-ES","MP4V-ES", "mp4v-es"); |
999 | | |
1000 | | /* Required function calls to register the header fields and subtrees used */ |
1001 | 14 | proto_register_field_array(proto_mp4ves, hf, array_length(hf)); |
1002 | 14 | proto_register_subtree_array(ett, array_length(ett)); |
1003 | 14 | expert_mp4ves = expert_register_protocol(proto_mp4ves); |
1004 | 14 | expert_register_field_array(expert_mp4ves, ei, array_length(ei)); |
1005 | | /* Register a configuration option for port */ |
1006 | | |
1007 | 14 | mp4ves_handle = register_dissector("mp4ves", dissect_mp4ves, proto_mp4ves); |
1008 | 14 | register_dissector("mp4ves_config", dissect_mp4ves_config, proto_mp4ves); |
1009 | | |
1010 | | /* Register a configuration option for port */ |
1011 | 14 | mp4ves_module = prefs_register_protocol(proto_mp4ves, NULL); |
1012 | | |
1013 | 14 | prefs_register_obsolete_preference(mp4ves_module, "dynamic.payload.type"); |
1014 | | |
1015 | 14 | } |
1016 | | |
1017 | | void |
1018 | | proto_reg_handoff_mp4ves(void) |
1019 | 14 | { |
1020 | 14 | mp4ves_capability_t *ftr; |
1021 | | |
1022 | 14 | dissector_add_string("rtp_dyn_payload_type","MP4V-ES", mp4ves_handle); |
1023 | | |
1024 | 14 | mp4ves_name_handle = create_dissector_handle(dissect_mp4ves_name, proto_mp4ves); |
1025 | 84 | for (ftr=mp4ves_capability_tab; ftr->id; ftr++) { |
1026 | 70 | if (ftr->name) |
1027 | 70 | dissector_add_string("h245.gef.name", ftr->id, mp4ves_name_handle); |
1028 | 70 | if (ftr->content_pdu) |
1029 | 42 | dissector_add_string("h245.gef.content", ftr->id, create_dissector_handle(ftr->content_pdu, proto_mp4ves)); |
1030 | 70 | } |
1031 | | |
1032 | 14 | dissector_add_uint_range_with_preference("rtp.pt", "", mp4ves_handle); |
1033 | 14 | } |
1034 | | |
1035 | | /* |
1036 | | * Editor modelines - https://www.wireshark.org/tools/modelines.html |
1037 | | * |
1038 | | * Local variables: |
1039 | | * c-basic-offset: 8 |
1040 | | * tab-width: 8 |
1041 | | * indent-tabs-mode: t |
1042 | | * End: |
1043 | | * |
1044 | | * vi: set shiftwidth=8 tabstop=8 noexpandtab: |
1045 | | * :indentSize=8:tabSize=8:noTabs=false: |
1046 | | */ |