-
Notifications
You must be signed in to change notification settings - Fork 76
/
rtp_ps_assemble.lua
550 lines (506 loc) · 30.5 KB
/
rtp_ps_assemble.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
-- Dissector for rtp payload PS
-- According to RFC2250 to dissector payload of RTP to NALU
-- Author: yangxing ([email protected])
------------------------------------------------------------------------------------------------
do
local version_str = string.match(_VERSION, "%d+[.]%d*")
local version_num = version_str and tonumber(version_str) or 5.1
local bit = (version_num >= 5.2) and require("bit32") or require("bit")
local ps_stream_type_vals = {
[0x0f] = "AAC",
[0x10] = "MPEG-4 Video",
[0x1b] = "H.264",
[0x24] = "H.265",
[0x80] = "SVAC Video",
[0x90] = "G.711A",
[0x91] = "G.711U",
[0x92] = "G.722.1",
[0x93] = "G.723.1",
[0x99] = "G.729",
[0x9b] = "SVAC Audio",
}
local ps_stream_id_vals = {
[0xbc] = "Program Stream Map",
[0xbd] = "Private Stream-1",
[0xbe] = "Padding Stream",
[0xbf] = "Private Stream-2",
-- [0xc0 .. 0xdf] = "Audio stream",
-- [0xe0 .. 0xef] = "Video stream",
[0xf0] = "ECM Stream",
[0xf1] = "EMM Stream",
[0xf2] = "DSMCC Stream",
[0xf3] = "ISO/IEC 13522 Stream",
[0xf4] = "ITU-T Rec. H.222.1 Type A",
[0xf5] = "ITU-T Rec. H.222.1 Type B",
[0xf6] = "ITU-T Rec. H.222.1 Type C",
[0xf7] = "ITU-T Rec. H.222.1 Type D",
[0xf8] = "ITU-T Rec. H.222.1 Type E",
[0xf9] = "Ancillary Stream",
[0xff] = "Program Stream Directory",
}
for i=0xc0,0xdf do
ps_stream_id_vals[i] = "Audio stream"
end
for i=0xe0,0xef do
ps_stream_id_vals[i] = "Video stream"
end
local function get_enum_name(list, index)
local value = list[index]
return value and value or string.format("Unknown (%d)",index)
end
local function get_int64_string(high_int32, low_int32)
return string.format("%x%x",high_int32,low_int32)
end
local proto_ps = Proto("ps", "PS")
local ps_hdr = ProtoField.none("ps.pack_header", "PS Header")
local ps_start_code = ProtoField.bytes("ps.pack_start_code", "Start code", base.SPACE)
local ps_scr_base = ProtoField.none("ps.scr_base", "SCR base")
local ps_scr_ext = ProtoField.none("ps.scr_ext", "SCR extension")
local ps_multiplex_rate = ProtoField.new("Multiplex rate", "ps.multiplex_rate", ftypes.UINT24, nil, base.DEC, 0xfffffc)
local ps_stuffing_length = ProtoField.new("Stuffing length", "ps.stuffing_length", ftypes.UINT8, nil, base.DEC, 0x07)
local ps_stuffing_bytes = ProtoField.bytes("ps.stuffing_bytes", "Stuffing bytes")
local ps_system_header = ProtoField.none("ps.system_header", "System Header")
local ps_system_header_start_code = ProtoField.bytes("ps.system_header.start_code", "Start code", base.SPACE)
local ps_system_header_length = ProtoField.new("Header length", "ps.system_header.header_length", ftypes.UINT16, nil, base.DEC)
local ps_system_header_rate_bound = ProtoField.new("Rate bound", "ps.system_header.rate_bound", ftypes.UINT24, nil, base.DEC, 0x7ffffe)
local ps_system_header_audio_bound = ProtoField.new("Audio bound", "ps.system_header.audio_bound", ftypes.UINT8, nil, base.DEC, 0xfc)
local ps_system_header_fixed_flag = ProtoField.new("Fixed flag", "ps.system_header.fixed_flag", ftypes.UINT8, nil, base.DEC, 0x02)
local ps_system_header_CSPS_flag = ProtoField.new("CSPS flag", "ps.system_header.csps_flag", ftypes.UINT8, nil, base.DEC, 0x01)
local ps_system_header_system_audio_lock_flag = ProtoField.new("System audio lock flag", "ps.system_header.system_audio_lock_flag", ftypes.UINT8, nil, base.DEC, 0x80)
local ps_system_header_system_video_lock_flag = ProtoField.new("System video lock flag", "ps.system_header.system_video_lock_flag", ftypes.UINT8, nil, base.DEC, 0x40)
local ps_system_header_vedio_bound = ProtoField.new("Vedio bound", "ps.system_header.vedio_bound", ftypes.UINT8, nil, base.DEC, 0x1f)
local ps_system_header_packet_rate_restriction_flag = ProtoField.new("Packet rate restriction flag", "ps.system_header.packet_rate_restriction_flag", ftypes.UINT8, nil, base.DEC, 0x80)
local ps_system_header_stream_id = ProtoField.new("Stream ID", "ps.system_header.stream_id", ftypes.UINT8, ps_stream_id_vals, base.HEX)
local ps_system_header_P_STD_scale = ProtoField.new("P-STD buffer bound scale", "ps.system_header.buffer_bound_scale", ftypes.UINT16, nil, base.DEC, 0x2000)
local ps_system_header_P_STD_bound = ProtoField.new("P-STD buffer size bound", "ps.system_header.buffer_size_bound", ftypes.UINT16, nil, base.DEC, 0x1fff)
local ps_program_stream = ProtoField.none("ps.program_map", "Program Stream Map")
local ps_program_stream_start_code = ProtoField.bytes("ps.program_map.start_code", "Start code", base.SPACE)
local ps_program_stream_id = ProtoField.new("Stream ID", "ps.program_map.stream_id", ftypes.UINT8, ps_stream_id_vals, base.HEX)
local ps_program_stream_length = ProtoField.new("Header length", "ps.program_map.header_length", ftypes.UINT16, nil, base.DEC)
local ps_program_stream_current_next_indicator = ProtoField.new("Current next indicator", "ps.program_map.current_next_indicator", ftypes.UINT8, nil, base.DEC, 0x80)
local ps_program_stream_map_version = ProtoField.new("Version", "ps.program_map.version", ftypes.UINT8, nil, base.DEC, 0x1f)
local ps_program_stream_info_length = ProtoField.new("Info length", "ps.program_map.info_length", ftypes.UINT16, nil, base.DEC)
local ps_program_stream_map_length = ProtoField.new("Map length", "ps.program_map.map_length", ftypes.UINT16, nil, base.DEC)
local ps_program_stream_map_stream_type = ProtoField.new("Elementary Stream type", "ps.program_map.map.stream_type", ftypes.UINT8, ps_stream_type_vals, base.DEC)
local ps_program_stream_map_stream_id = ProtoField.new("Elementary Stream ID", "ps.program_map.map.stream_id", ftypes.UINT8, ps_stream_id_vals, base.HEX)
local ps_program_stream_map_info_length = ProtoField.new("Elementary Stream info length", "ps.program_map.map.stream_info_length", ftypes.UINT16, nil, base.DEC)
local ps_program_stream_CRC = ProtoField.bytes("ps.program_map.crc", "CRC", base.SPACE)
local ps_pes = ProtoField.none("ps.pes", "PES Packet")
local ps_pes_start_code = ProtoField.bytes("ps.pes.start_code", "Start code", base.SPACE)
local ps_pes_stream_id = ProtoField.new("Stream ID", "ps.pes.stream_id", ftypes.UINT8, ps_stream_id_vals, base.HEX)
local ps_pes_length = ProtoField.new("Length", "ps.pes.packet_length", ftypes.UINT16, nil, base.DEC)
local ps_pes_scrambing_control = ProtoField.new("Scrambing control", "ps.pes.scrambing_control", ftypes.UINT8, nil, base.DEC, 0x30)
local ps_pes_priority = ProtoField.new("Priority", "ps.pes.priority", ftypes.UINT8, nil, base.DEC, 0x08)
local ps_pes_alignment = ProtoField.new("Alignment", "ps.pes.alignment", ftypes.UINT8, nil, base.DEC, 0x04)
local ps_pes_copyright = ProtoField.new("Copyright", "ps.pes.copyright", ftypes.UINT8, nil, base.DEC, 0x02)
local ps_pes_original = ProtoField.new("Original", "ps.pes.original", ftypes.UINT8, nil, base.DEC, 0x01)
local ps_pes_pts_dts_flag = ProtoField.new("PTS DTS flag", "ps.pes.pts_dts_flag", ftypes.UINT8, nil, base.DEC, 0xc0)
local ps_pes_escr_flag = ProtoField.new("ESCR flag", "ps.pes.escr_flag", ftypes.UINT8, nil, base.DEC, 0x20)
local ps_pes_es_rate_flag = ProtoField.new("ES rate flag", "ps.pes.es_rate_flag", ftypes.UINT8, nil, base.DEC, 0x10)
local ps_pes_dsm_trick_mode_flag = ProtoField.new("DSM trick mode flag", "ps.pes.dsm_trick_mode_flag", ftypes.UINT8, nil, base.DEC, 0x08)
local ps_pes_additional_info_flag = ProtoField.new("Additional info flag", "ps.pes.additional_info_flag", ftypes.UINT8, nil, base.DEC, 0x04)
local ps_pes_crc_flag = ProtoField.new("CRC flag", "ps.pes.crc_flag", ftypes.UINT8, nil, base.DEC, 0x02)
local ps_pes_extension_flag = ProtoField.new("Extension flag", "ps.pes.extension_flag", ftypes.UINT8, nil, base.DEC, 0x01)
local ps_pes_header_data_length = ProtoField.new("Header Data Length", "ps.pes.header_data_length", ftypes.UINT8, nil, base.DEC)
local ps_pes_header_data_bytes = ProtoField.bytes("ps.pes.header_data_bytes", "Header Data bytes", base.SPACE)
local ps_pes_pts = ProtoField.none("ps.pes.pts", "PTS")
local ps_pes_dts = ProtoField.none("ps.pes.dts", "DTS")
local ps_pes_escr = ProtoField.none("ps.pes.escr", "ESCR")
local ps_pes_es_rate = ProtoField.none("ps.pes.es_rate", "ES rate")
local ps_pes_dsm_trick_mode = ProtoField.new("DSM trick mode", "ps.pes.dsm_trick_mode", ftypes.UINT8, nil, base.HEX)
local ps_pes_additional_info = ProtoField.new("Copyright Info", "ps.pes.additional_info", ftypes.UINT8, nil, base.HEX)
local ps_pes_crc = ProtoField.new("CRC", "ps.pes.crc", ftypes.UINT16, nil, base.HEX)
local ps_pes_extension = ProtoField.new("Extension", "ps.pes.extension", ftypes.UINT8, nil, base.HEX)
local ps_pes_data_bytes = ProtoField.bytes("ps.pes.data_bytes", "Data bytes")
-- local ps_data = ProtoField.bytes("ps.data", "Data")
proto_ps.fields = {
ps_hdr,ps_start_code,ps_scr_base,ps_scr_ext,ps_multiplex_rate,ps_stuffing_length,ps_stuffing_bytes,
ps_system_header,ps_system_header_start_code,ps_system_header_length,ps_system_header_rate_bound,ps_system_header_audio_bound,ps_system_header_fixed_flag,ps_system_header_CSPS_flag,ps_system_header_system_audio_lock_flag,ps_system_header_system_video_lock_flag,ps_system_header_vedio_bound,ps_system_header_packet_rate_restriction_flag,ps_system_header_stream_id,ps_system_header_P_STD_scale,ps_system_header_P_STD_bound,
ps_program_stream,ps_program_stream_start_code,ps_program_stream_id,ps_program_stream_length,ps_program_stream_current_next_indicator,ps_program_stream_map_version,ps_program_stream_info_length,ps_program_stream_map_length,ps_program_stream_map_stream_type,ps_program_stream_map_stream_id,ps_program_stream_map_info_length,ps_program_stream_CRC,
ps_pes,ps_pes_start_code,ps_pes_stream_id,ps_pes_length,ps_pes_scrambing_control,ps_pes_priority,ps_pes_alignment,ps_pes_copyright,ps_pes_original,ps_pes_pts_dts_flag,ps_pes_escr_flag,ps_pes_es_rate_flag,ps_pes_dsm_trick_mode_flag,ps_pes_additional_info_flag,ps_pes_crc_flag,ps_pes_extension_flag,
ps_pes_header_data_length,ps_pes_header_data_bytes,ps_pes_pts,ps_pes_dts,ps_pes_escr,ps_pes_es_rate,ps_pes_dsm_trick_mode,ps_pes_additional_info,ps_pes_crc,ps_pes_extension,ps_pes_data_bytes,
-- ps_data
}
function isInTable(item, tbl)
for k,v in ipairs(tbl) do
if v == item then
return true
end
end
return false
end
-- local frame_num = Field.new("frame.number")
local h264_dis = Dissector.get("h264")
local h265_dis = Dissector.get("h265")
local pcma_dis = nil
local pcmu_dis = nil
if isInTable("pcma", Dissector.list()) then
pcma_dis = Dissector.get("pcma")
end
if isInTable("pcmu", Dissector.list()) then
pcmu_dis = Dissector.get("pcmu")
end
-- variable for storing stream info
local stream_info_map = {}
function is_ps_header(tvb, offset)
if (tvb:len() < (offset+4)) then
return false
end
if ((tvb:range(offset, 1):uint() == 0x00) and (tvb:range(offset+1, 1):uint() == 0x00)
and (tvb:range(offset+2, 1):uint() == 0x01) and (tvb:range(offset+3, 1):uint() == 0xba)) then
return true
else
return false
end
end
function is_system_header(tvb, offset)
if (tvb:len() < (offset+4)) then
return false
end
--print(string.format("start code %x %x %x %x",tvb:range(offset, 1):uint(),tvb:range(offset+1, 1):uint(),tvb:range(offset+2, 1):uint(),tvb:range(offset+3, 1):uint()))
if ((tvb:range(offset, 1):uint() == 0x00) and (tvb:range(offset+1, 1):uint() == 0x00)
and (tvb:range(offset+2, 1):uint() == 0x01) and (tvb:range(offset+3, 1):uint() == 0xbb)) then
return true
else
return false
end
end
function is_pes_header(tvb, offset)
if (tvb:len() < (offset+4)) then
return false
end
if ((tvb:range(offset, 1):uint() == 0x00) and (tvb:range(offset+1, 1):uint() == 0x00)
and (tvb:range(offset+2, 1):uint() == 0x01)) then
return true
else
return false
end
end
function is_raw_start(tvb, offset)
if (tvb:len() < (offset+4)) then
return false
end
if ((tvb:range(offset, 1):uint() == 0x00) and (tvb:range(offset+1, 1):uint() == 0x00)
and (tvb:range(offset+2, 1):uint() == 0x00) and (tvb:range(offset+3, 1):uint() == 0x01)) then
return true
else
return false
end
end
function dis_ps_packet_header(tvb, tree, offset)
-- PS packet header
local stuffing_size = tvb:range(offset+13,1):bitfield(5, 3)
local ps_hdr_tree = tree:add(ps_hdr, tvb:range(offset,14+stuffing_size))
ps_hdr_tree:add(ps_start_code, tvb:range(offset,4))
local scr_1 = tvb:range(offset+4,1):bitfield(2,3)
local scr_2 = tvb:range(offset+4,3):bitfield(6,15)
local scr_3 = tvb:range(offset+6,3):bitfield(6,15)
local scr_e = tvb:range(offset+8,2):bitfield(6,9)
local scr = bit.lshift(scr_1,30)+bit.lshift(scr_2,15)+scr_3
ps_hdr_tree:add(ps_scr_base, tvb:range(offset+4,6)):append_text(string.format(": %u",scr))
ps_hdr_tree:add(ps_scr_ext, tvb:range(offset+4,6)):append_text(string.format(": %u",scr_e))
ps_hdr_tree:add(ps_multiplex_rate, tvb:range(offset+10,3))
ps_hdr_tree:add(ps_stuffing_length, tvb:range(offset+13,1))
if (stuffing_size > 0) then
ps_hdr_tree:add(ps_stuffing_bytes, tvb:range(offset+14,stuffing_size))
end
end
function dis_system_header(tvb, tree, offset)
-- System header
local system_header_length = tvb:range(offset+4, 2):uint()
local ps_system_header_tree = tree:add(ps_system_header, tvb:range(offset,system_header_length+4+2))
ps_system_header_tree:add(ps_system_header_start_code, tvb:range(offset,4))
ps_system_header_tree:add(ps_system_header_length, tvb:range(offset+4,2))
ps_system_header_tree:add(ps_system_header_rate_bound, tvb:range(offset+6,3))
ps_system_header_tree:add(ps_system_header_audio_bound, tvb:range(offset+9,1))
ps_system_header_tree:add(ps_system_header_fixed_flag, tvb:range(offset+9,1))
ps_system_header_tree:add(ps_system_header_CSPS_flag, tvb:range(offset+9,1))
ps_system_header_tree:add(ps_system_header_system_audio_lock_flag, tvb:range(offset+10,1))
ps_system_header_tree:add(ps_system_header_system_video_lock_flag, tvb:range(offset+10,1))
ps_system_header_tree:add(ps_system_header_vedio_bound, tvb:range(offset+10,1))
ps_system_header_tree:add(ps_system_header_packet_rate_restriction_flag, tvb:range(offset+11,1))
if (system_header_length>6) then
local remain_length = system_header_length-6
local shif = offset+12
repeat
ps_system_header_tree:add(ps_system_header_stream_id, tvb:range(shif,1))
ps_system_header_tree:add(ps_system_header_P_STD_scale, tvb:range(shif+1,2))
ps_system_header_tree:add(ps_system_header_P_STD_bound, tvb:range(shif+1,2))
shif = shif+3
remain_length = remain_length-3
until(remain_length<=0)
end
end
function dis_stream_map(tvb, tree, offset)
-- Program stream map
local program_map_length = tvb:range(offset+4, 2):uint()
local ps_program_map_tree = tree:add(ps_program_stream, tvb:range(offset,program_map_length+4+2))
ps_program_map_tree:add(ps_program_stream_start_code, tvb:range(offset,3))
ps_program_map_tree:add(ps_program_stream_id, tvb:range(offset+3,1))
ps_program_map_tree:add(ps_program_stream_length, tvb:range(offset+4,2))
ps_program_map_tree:add(ps_program_stream_current_next_indicator, tvb:range(offset+6,1))
ps_program_map_tree:add(ps_program_stream_map_version, tvb:range(offset+6,1))
ps_program_map_tree:add(ps_program_stream_info_length, tvb:range(offset+8,2))
local info_len = tvb:range(offset+8, 2):uint()
ps_program_map_tree:add(ps_program_stream_map_length, tvb:range(offset+10+info_len,2)) --10 = 8+2(info len)
local map_len = tvb:range(offset+10+info_len, 2):uint()
local remain_length = map_len
local shif = offset+12+info_len
repeat
ps_program_map_tree:add(ps_program_stream_map_stream_type, tvb:range(shif,1))
ps_program_map_tree:add(ps_program_stream_map_stream_id, tvb:range(shif+1,1))
local stream_type = tvb:range(shif,1):uint()
local stream_id = tvb:range(shif+1,1):uint()
stream_info_map[stream_id] = get_enum_name(ps_stream_type_vals, stream_type)
ps_program_map_tree:add(ps_program_stream_map_info_length, tvb:range(shif+2,2))
local map_info_len = tvb:range(shif+2, 2):uint()
shif = shif+4+map_info_len
remain_length = remain_length-4-map_info_len
until(remain_length<=0)
ps_program_map_tree:add(ps_program_stream_CRC, tvb:range(offset+12+info_len+map_len,4)) --12 = 8+2(info len)+2(map len)
end
function dis_pes(tvb, tree, offset, pinfo)
-- PES header
local pes_length = tvb:range(offset+4, 2):uint()
local tvb_len = tvb:len()
local complete_packet = tvb_len>=(offset+pes_length+6)
local ps_pes_tree = tree:add(ps_pes, tvb:range(offset,complete_packet and (pes_length+4+2) or (tvb_len-offset)))
ps_pes_tree:add(ps_pes_start_code, tvb:range(offset,3))
ps_pes_tree:add(ps_pes_stream_id, tvb:range(offset+3,1))
local pes_length_tree = ps_pes_tree:add(ps_pes_length, tvb:range(offset+4,2))
ps_pes_tree:add(ps_pes_scrambing_control, tvb:range(offset+6,1))
ps_pes_tree:add(ps_pes_priority, tvb:range(offset+6,1))
ps_pes_tree:add(ps_pes_alignment, tvb:range(offset+6,1))
ps_pes_tree:add(ps_pes_copyright, tvb:range(offset+6,1))
ps_pes_tree:add(ps_pes_original, tvb:range(offset+6,1))
ps_pes_tree:add(ps_pes_pts_dts_flag, tvb:range(offset+7,1))
ps_pes_tree:add(ps_pes_escr_flag, tvb:range(offset+7,1))
ps_pes_tree:add(ps_pes_es_rate_flag, tvb:range(offset+7,1))
ps_pes_tree:add(ps_pes_dsm_trick_mode_flag, tvb:range(offset+7,1))
ps_pes_tree:add(ps_pes_additional_info_flag, tvb:range(offset+7,1))
ps_pes_tree:add(ps_pes_crc_flag, tvb:range(offset+7,1))
ps_pes_tree:add(ps_pes_extension_flag, tvb:range(offset+7,1))
local pes_header_data_len = tvb:range(offset+8, 1):uint()
local header_data_tree = ps_pes_tree:add(ps_pes_header_data_length, tvb:range(offset+8,1))
if complete_packet then
pes_length_tree:append_text(string.format(" (Data Len: %u)",pes_length-pes_header_data_len-3))
else
pes_length_tree:append_text(string.format(" (Data Len: %u|Actual Len: %u)",pes_length-pes_header_data_len-3,tvb_len-offset-9-pes_header_data_len))
end
if pes_header_data_len>0 then
header_data_tree:add(ps_pes_header_data_bytes, tvb:range(offset+9,pes_header_data_len))
local index = offset+9
local pts_dts_flag = tvb:range(offset+7,1):bitfield(0,2)
if pts_dts_flag == 0x2 then
-- local pts_1 = tvb:range(index,1):bitfield(4,3)
local pts_high = tvb:range(index,1):bitfield(4,1)
local pts_1 = tvb:range(index,1):bitfield(5,2)
local pts_2 = tvb:range(index+1,2):bitfield(0,15)
local pts_3 = tvb:range(index+3,2):bitfield(0,15)
local pts = bit.lshift(pts_1,30)+bit.lshift(pts_2,15)+pts_3
-- ps_pes_tree:add(ps_pes_pts, tvb:range(index,5)):append_text(string.format(": %u",pts))
ps_pes_tree:add(ps_pes_pts, tvb:range(index,5)):append_text(string.format(": 0x%s",get_int64_string(pts_high,pts)))
index = index + 5
elseif pts_dts_flag == 0x3 then
-- local pts_1 = tvb:range(index,1):bitfield(4,3)
local pts_high = tvb:range(index,1):bitfield(4,1)
local pts_1 = tvb:range(index,1):bitfield(5,2)
local pts_2 = tvb:range(index+1,2):bitfield(0,15)
local pts_3 = tvb:range(index+3,2):bitfield(0,15)
local pts = bit.lshift(pts_1,30)+bit.lshift(pts_2,15)+pts_3
ps_pes_tree:add(ps_pes_pts, tvb:range(index,5)):append_text(string.format(": 0x%s",get_int64_string(pts_high,pts)))
-- local dts_1 = tvb:range(index+5,1):bitfield(4,3)
local dts_high = tvb:range(index+5,1):bitfield(4,1)
local dts_1 = tvb:range(index+5,1):bitfield(5,2)
local dts_2 = tvb:range(index+6,2):bitfield(0,15)
local dts_3 = tvb:range(index+8,2):bitfield(0,15)
local dts = bit.lshift(dts_1,30)+bit.lshift(dts_2,15)+dts_3
ps_pes_tree:add(ps_pes_dts, tvb:range(index+5,5)):append_text(string.format(": 0x%s",get_int64_string(dts_high,dts)))
index = index + 10
end
local escr_flag = tvb:range(offset+7,1):bitfield(2,1)
if escr_flag == 1 then
-- local escr_1 = tvb:range(index,1):bitfield(2,3)
local escr_high = tvb:range(index,1):bitfield(2,1)
local escr_1 = tvb:range(index,1):bitfield(3,2)
local escr_2 = tvb:range(index,3):bitfield(6,15)
local escr_3 = tvb:range(index+2,3):bitfield(6,15)
local escr_e = tvb:range(index+4,2):bitfield(6,9)
local escr = bit.lshift(escr_1,30)+bit.lshift(escr_2,15)+escr_3
ps_pes_tree:add(ps_pes_escr, tvb:range(index,6)):append_text(string.format(": 0x%s, extension: %u",get_int64_string(escr_high,escr),escr_e))
index = index + 6
end
local es_rate_flag = tvb:range(offset+7,1):bitfield(3,1)
if es_rate_flag == 1 then
local es_rate = tvb:range(index,3):bitfield(1,22)
ps_pes_tree:add(ps_pes_es_rate, tvb:range(index,3)):append_text(string.format(": %u",dts))
index = index + 3
end
local dsm_trick_mode_flag = tvb:range(offset+7,1):bitfield(4,1)
if dsm_trick_mode_flag == 1 then
ps_pes_tree:add(ps_pes_dsm_trick_mode, tvb:range(index,1))
index = index + 1
end
local additional_info_flag = tvb:range(offset+7,1):bitfield(5,1)
if additional_info_flag == 1 then
ps_pes_tree:add(ps_pes_additional_info, tvb:range(index,1))
index = index + 1
end
local crc_flag = tvb:range(offset+7,1):bitfield(6,1)
if crc_flag == 1 then
ps_pes_tree:add(ps_pes_crc, tvb:range(index,2))
index = index + 2
end
local extension_flag = tvb:range(offset+7,1):bitfield(7,1)
if extension_flag == 1 then
ps_pes_tree:add(ps_pes_extension, tvb:range(index,1))
index = index + 1
end
end
local stream_id = tvb:range(offset+3,1):uint()
local stream_id_name = stream_info_map[stream_id]
-- Start code 3, stream id 1, packet length 2, scrambing|PTS 2, Header length 1
if offset+9+pes_header_data_len>=tvb_len then
return
end
local date_len = complete_packet and (pes_length-3-pes_header_data_len) or (tvb_len-offset-9-pes_header_data_len)
local shif = offset+9+pes_header_data_len
local dec_tvb = tvb:bytes(shif,date_len):tvb()
if "H.264" == stream_id_name then
-- h264/h265 not contain start code 00 00 00 01
h264_dis:call(dec_tvb:bytes(4):tvb(), pinfo, ps_pes_tree)
elseif "H.265" == stream_id_name then
h265_dis:call(dec_tvb:bytes(4):tvb(), pinfo, ps_pes_tree)
elseif "G.711A" == stream_id_name and pcma_dis ~= nil then
pcma_dis:call(dec_tvb, pinfo, ps_pes_tree)
elseif "G.711U" == stream_id_name and pcmu_dis ~= nil then
pcmu_dis:call(dec_tvb, pinfo, ps_pes_tree)
else
local media_raw_tree = ps_pes_tree:add(ps_pes_data_bytes, tvb:range(offset+9+pes_header_data_len, date_len))
if stream_id_name then
media_raw_tree:set_text(stream_id_name)
media_raw_tree:append_text(string.format(" (%d)",date_len))
else
media_raw_tree:set_text(string.format("0x%x",stream_id))
media_raw_tree:append_text(string.format(" (%d)",date_len))
end
end
end
local lastNumber = 0
local tempArray = nil
local completeRTP = {}
-- PS dissector for rtp payload
function proto_ps.dissector(tvb, pinfo, tree)
-- local frame_seqs = frame_num()
-- if (frame_seqs.value == 1)
if pinfo.visited == false then
if (is_ps_header(tvb, 0)) then
tempArray = nil
end
if (tempArray == nil) then
tempArray = ByteArray.new()
tempArray:append(tvb:bytes())
else
tempArray:append(tvb:bytes())
end
completeRTP[pinfo.number] = tempArray
-- clean not complete buffer
if (is_ps_header(tvb, 0) == false) then
if (lastNumber > 0) then
completeRTP[lastNumber] = nil
end
end
lastNumber = pinfo.number
return
end
-- add proto item to tree
if (completeRTP[pinfo.number] ~= nil) then
local rtp_tvb = completeRTP[pinfo.number]:tvb()
local proto_tree = tree:add(proto_ps, rtp_tvb:range())
local offset = 0
if (is_ps_header(rtp_tvb, offset)) then
local stuffing_size = rtp_tvb:range(offset+13,1):bitfield(5, 3)
dis_ps_packet_header(rtp_tvb, proto_tree, offset)
offset = offset + 14 + stuffing_size
if (is_system_header(rtp_tvb, offset)) then
local system_header_length = rtp_tvb:range(offset+4, 2):uint()
dis_system_header(rtp_tvb, proto_tree, offset)
offset = offset + 4 + 2 + system_header_length
-- program stream map
local program_map_length = rtp_tvb:range(offset+4, 2):uint()
dis_stream_map(rtp_tvb, proto_tree, offset)
offset = offset + 4 + 2 + program_map_length
end
while (is_pes_header(rtp_tvb, offset))
do
local pes_length = rtp_tvb:range(offset+4, 2):uint()
dis_pes(rtp_tvb, proto_tree, offset, pinfo)
offset = offset + 4 + 2 + pes_length
end
else
while (is_pes_header(rtp_tvb, offset))
do
local pes_length = rtp_tvb:range(offset+4, 2):uint()
dis_pes(rtp_tvb, proto_tree, offset, pinfo)
offset = offset + 4 + 2 + pes_length
end
end
pinfo.columns.protocol = "PS"
else
pinfo.columns.protocol = "PS"
end
end
-- set this protocal preferences
local prefs = proto_ps.prefs
prefs.dyn_pt = Pref.range("PS dynamic payload type", "", "Dynamic payload types which will be interpreted as PS; Values must be in the range 96 - 127", 127)
-- register this dissector to dynamic payload type dissectorTable
local dyn_payload_type_table = DissectorTable.get("rtp_dyn_payload_type")
dyn_payload_type_table:add("ps", proto_ps)
-- register this dissector to specific payload type (specified in preferences windows)
local payload_type_table = DissectorTable.get("rtp.pt")
local old_dyn_pt = nil
local old_dissector = nil
function proto_ps.init()
if (prefs.dyn_pt ~= old_dyn_pt) then
-- reset old dissector
if (old_dyn_pt ~= nil and string.len(old_dyn_pt) > 0) then
local pt_numbers = getArray(tostring(old_dyn_pt))
for index,pt_number in pairs(pt_numbers) do
-- replace this proto with old proto on old payload type
if old_dissector ~= nil and old_dissector[index] ~= nil then
payload_type_table:add(pt_number, old_dissector[index])
else -- just remove this proto
payload_type_table:remove(pt_number, proto_ps)
end
end
end
old_dyn_pt = prefs.dyn_pt -- save current payload type's dissector
if (prefs.dyn_pt ~= nil and string.len(prefs.dyn_pt) > 0) then
local pt_numbers = getArray(tostring(prefs.dyn_pt))
old_dissector = {}
for index,pt_number in pairs(pt_numbers) do
local dissector = payload_type_table:get_dissector(pt_number)
-- table.insert(old_dissector,index,dissector)
old_dissector[index] = dissector
payload_type_table:add(pt_number, proto_ps)
end
end
end
end
function getArray(str)
local strList = {}
string.gsub(str, '[^,]+',function (w)
local pos = string.find(w,'-')
if not pos then
table.insert(strList,tonumber(w))
else
local begin_index = string.sub(w,1,pos-1)
local end_index = string.sub(w,pos+1,#w)
for index = begin_index,end_index do
table.insert(strList,index)
end
end
end)
return strList
end
end