Coverage Report

Created: 2025-12-27 06:52

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
 */