-
Notifications
You must be signed in to change notification settings - Fork 5
/
SMPTE-2022-6.lua
132 lines (122 loc) · 7.17 KB
/
SMPTE-2022-6.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
-- Lua Dissector for SMPTE 2022-6
-- Author: Thomas Edwards ([email protected])
--
-- to use in Wireshark:
-- 1) Ensure your Wireshark works with Lua plugins - "About Wireshark" should say it is compiled with Lua
-- 2) Install this dissector in the proper plugin directory - see "About Wireshark/Folders" to see Personal
-- and Global plugin directories. After putting this dissector in the proper folder, "About Wireshark/Plugins"
-- should list "SMPTE-2022-6.lua"
-- 3) In Wireshark Preferences, under "Protocols", set SMPTE_2022_6 as dynamic payload type 98
-- 4) Capture packets of SMPTE 2022-6
-- 5) "Decode As" those UDP packets as RTP
-- 6) You will now see the SMPTE 2022-6 Data dissection of the RTP payload
--
-- This program is free software; you can redistribute it and/or
-- modify it under the terms of the GNU General Public License
-- as published by the Free Software Foundation; either version 2
-- of the License, or (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
------------------------------------------------------------------------------------------------
do
local smpte_2022_6 = Proto("smpte_2022_6", "SMPTE 2022-6")
local prefs = smpte_2022_6.prefs
prefs.dyn_pt = Pref.uint("SMPTE 2022-6 dynamic payload type", 0, "The value > 95")
local F = smpte_2022_6.fields
F.Ext = ProtoField.uint8("smpte_2022_6.Ext","Extension field (Ext)",base.HEX,nil,0xF0)
F.F = ProtoField.bool("smpte_2022_6.F","Video source format flag (F)",8,{"Present","Not Present"},0x08)
F.VSID = ProtoField.uint8("smpte_2022_6.VSID","Video source ID (VSID)",base.HEX,{[0]="primary stream",[1]="protect stream",[2]="reserved",[3]="reserved",[4]="reserved",[5]="reserved",[6]="reserved",[7]="reserved"},0x07)
F.FRCount = ProtoField.uint8("smpte_2022_6.FRCount","Frame Count (FRCount)")
F.R = ProtoField.uint8("smpte_2022_6.R","Reference for time stamp (R)",base.HEX,{[0]="not locked",[1]="reserved",[2]="locked to UTC time/frequency reference",[3]="localed to a private time/frequency reference"},0xC0)
F.S = ProtoField.uint8("smpte_2022_6.S","Video Payload Scrambing (S)",base.HEX,{[0]="not scrambled",[1]="reserved",[2]="reserved",[3]="reserved"},0x30)
F.FEC = ProtoField.uint8("smpte_2022_6.FEC","FEC usage (FEC)",base.HEX,{[0]="No FEC stream",[1]="L(Column) FEC utilized",[2]="L&D (Column & Row) FEC utilized",[3]="reserved",[4]="reserved",[5]="reserved",[6]="reserved",[7]="reserved"},0x0E)
F.CF = ProtoField.uint16("smpte_2022_6.CF","Clock Frequency (CF)",base.HEX,{[0]="No time stamp",[1]="27 MHz",[2]="148.5 MHz",[3]="148.5/1.001 MHz",[4]="297 MHz",[5]="297/1.001 MHz"},0x01E0)
F.MAP = ProtoField.uint8("smpte_2022_6.MAP","Video source format (MAP)",base.HEX,{[0]="Direct sample structure",[1]="SMPTE ST 425-1 Level B-DL Mapping of 372 Dual-Link",[2]="SMPTE ST 425-1 Level B-DS Mapping of two ST 292-1 Streams"},0xF0)
F.FRAME = ProtoField.uint16("smpte_2022_6.FRAME","Frame structure (FRAME)",base.HEX,{[0x10]="720x486 active, interlaced",[0x11]="720x576 active, interlaced",[0x20]="1920x1080 active, interlaced",[0x21]="1920x1080 active, progressive",[0x22]="1920x1080 active, PsF",[0x23]="2048x1080 active, progressive",[0x24]="2048x1080, PsF",[0x30]="1280x720 active, progressive"},0x0FF0)
frame_rates={
[0x00]="Unknown/Unspecified frame rate 2.970 GHz signal",[0x01]="Unknown/Unspecified frame rate 2.970/1.001 GHz signal",
[0x02]="Unknown/Unspecified frame rate 1.485 GHz signal",[0x03]="Unknown/Unspecified frame rate 1.485/1.001 GHz signal",
[0x04]="Unknown/Unspecified frame rate 0.270 GHz signal",
[0x10]="60",[0x11]="60/1.001",[0x12]="50",[0x13]="reserved",[0x14]="48",[0x15]="48/1.001",[0x16]="30",[0x17]="30/1.001",
[0x18]="25",[0x19]="reserved",[0x1A]="24",[0x1B]="24/1.001"}
F.FRATE = ProtoField.uint16("smpte_2022_6.FRATE","Frame rate (FRATE)",base.HEX,frame_rates,0x0FF0)
sampling={
[0x00]="Unknown/Unspecified",[0x01]="4:2:2 10 bits",[0x02]="4:4:4 10 bits",[0x03]="4:4:4:4 10 bits",[0x04]="Reserved",[0x05]="4:2:2 12 bits",
[0x06]="4:4:4 12 bits",[0x07]="4:4:4:4 12 bits",[0x08]="4:2:2:4 12 bits"
}
F.SAMPLE= ProtoField.uint8("smpte_2022_6.SAMPLE","Picture samping (SAMPLE)",base.HEX,sampling,0x0F)
F.video_ts=ProtoField.uint32("smpte_2022_6.video_ts","Video timestamp (video_ts)")
F.header_ext_tag=ProtoField.uint8("smpte_2022_6.header_ext_tag","Header extension tag (header_ext_tag)",base.HEX)
F.header_ext_len=ProtoField.uint8("smpte_2022_6.header_ext_len","Header extension length (header_ext_len)")
F.header_ext_val=ProtoField.bytes("smpte_2022_6.header_ext_val","Header extension value")
F.HBRM_payload=ProtoField.bytes("smpte_2022_6.HBRM_payload","HBRM_payload")
function smpte_2022_6.dissector(tvb, pinfo, tree)
local subtree = tree:add(smpte_2022_6, tvb(),"SMPTE 2022-6 Data")
subtree:add(F.Ext, tvb(0,1))
local EXT=tvb(0,1):bitfield(0,4)
subtree:add(F.F, tvb(0,1))
subtree:add(F.VSID, tvb(0,1))
subtree:add(F.FRCount,tvb(1,1))
subtree:add(F.R,tvb(2,1))
subtree:add(F.S,tvb(2,1))
subtree:add(F.FEC,tvb(2,1))
subtree:add(F.CF,tvb(2,2))
local CF=tvb(2,2):bitfield(7,4)
subtree:add(F.MAP,tvb(4,1))
subtree:add(F.FRAME,tvb(4,2))
subtree:add(F.FRATE,tvb(5,2))
subtree:add(F.SAMPLE,tvb(6,1))
local offset=8
if CF>0 then
subtree:add(F.video_ts,tvb(8,4))
offset=offset+4
end
local ext_start = offset
local ext_bytes_left = EXT*4
if EXT>0 then
while ext_bytes_left>0 do
local ext_tag = tvb(offset,1):uint()
if ext_tag>0 then
subtree:add(F.header_ext_tag,tvb(offset,1))
subtree:add(F.header_ext_len,tvb(offset+1,1))
local ext_len=tvb(offset+1,1):uint()
subtree:add(F.header_ext_val,tvb(offset+2,ext_len))
offset=offset+2+ext_len
ext_bytes_left=ext_bytes_left-2-ext_len
else
-- PAD tag detected, skip over all remaining extension bytes
ext_bytes_left=0
end
end
-- ensure word alignment at end of header extension
offset=ext_start+EXT*4
end
subtree:add(F.HBRM_payload,tvb(offset,1376))
end
-- register dissector to dynamic payload type dissectorTable
local dyn_payload_type_table = DissectorTable.get("rtp_dyn_payload_type")
dyn_payload_type_table:add("SMPTE_2022_6", smpte_2022_6)
-- register dissector to RTP payload type
local payload_type_table = DissectorTable.get("rtp.pt")
local old_dissector = nil
local old_dyn_pt = 0
function smpte_2022_6.init()
if (prefs.dyn_pt ~= old_dyn_pt) then
if (old_dyn_pt > 0) then
if (old_dissector == nil) then
payload_type_table:remove(old_dyn_pt, smpte_2022_6)
else
payload_type_table:add(old_dyn_pt, old_dissector)
end
end
old_dyn_pt = prefs.dyn_pt
old_dissector = payload_type_table:get_dissector(old_dyn_pt)
if (prefs.dyn_pt > 0) then
payload_type_table:add(prefs.dyn_pt, smpte_2022_6)
end
end
end
end