Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-vp9.c
bloba5ef010beded297a9cc11759a39f436c2f53e9ac
1 /* packet-vp9.c
2 * Routines for VP9 dissection
3 * Copyright 2023, Noan Perrot <noan.perrot@gmail.com>
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * SPDX-License-Identifier: GPL-2.0-or-later
13 * vp9-bitstream-specification-v0.6-20160331-draft - VP9 Bitstream & Decoding Process Specification
14 * draft-ietf-payload-vp9-16 - RTP Payload Format for VP9 Video
17 #include "config.h"
18 /* Define the name for the logging domain (try to avoid collisions with existing domains) */
19 #define WS_LOG_DOMAIN "vp9"
21 /* Global header providing a minimum base set of required macros and APIs */
22 #include <wireshark.h>
24 #include <epan/packet.h> /* Required dissection API header */
25 #include <epan/expert.h> /* Include only as needed */
26 #include <epan/prefs.h> /* Include only as needed */
28 #define STRING_SIZE 50
29 #define VP9_1_BIT_MASK 0x80
30 #define VP9_2_BIT_MASK 0x40
31 #define VP9_3_BIT_MASK 0x20
32 #define VP9_4_BIT_MASK 0x10
33 #define VP9_5_BIT_MASK 0x08
34 #define VP9_6_BIT_MASK 0x04
35 #define VP9_7_BIT_MASK 0x02
36 #define VP9_8_BIT_MASK 0x01
37 #define VP9_2_BITS_MASK 0xC0
38 #define VP9_3_BITS_MASK 0xE0
39 #define VP9_7_BITS_MASK 0xFE
40 #define VP9_8_BITS_MASK 0xFF
41 #define VP9_16_BITS_MASK 0xFFFF
42 #define VP9_EXTENDED_PID 0x7FFF
44 static int proto_vp9;
46 static int hf_vp9_pld_i_bit;
47 static int hf_vp9_pld_p_bit;
48 static int hf_vp9_pld_l_bit;
49 static int hf_vp9_pld_f_bit;
50 static int hf_vp9_pld_b_bit;
51 static int hf_vp9_pld_e_bit;
52 static int hf_vp9_pld_v_bit;
53 static int hf_vp9_pld_z_bit;
54 static int hf_vp9_pld_u_bit;
55 static int hf_vp9_pld_m_bit;
56 static int hf_vp9_pld_d_bit;
57 static int hf_vp9_pld_n_bit;
58 static int hf_vp9_pld_y_bit;
59 static int hf_vp9_pld_g_bit;
60 static int hf_vp9_pld_pg_bits;
61 static int hf_vp9_pld_n_s_bits;
62 static int hf_vp9_pld_n_g_bits;
63 static int hf_vp9_pld_sid_bits;
64 static int hf_vp9_pld_pid_bits;
65 static int hf_vp9_pld_tid_bits;
66 static int hf_vp9_pld_width_bits;
67 static int hf_vp9_pld_height_bits;
68 static int hf_vp9_pld_n_s_numbers;
69 static int hf_vp9_pld_p_diff_bits;
70 static int hf_vp9_pld_tl0picidx_bits;
71 static int hf_vp9_pld_pg_extended_bits;
72 static int hf_vp9_pld_pid_extended_bits;
74 static int ett_vp9;
75 static int ett_vp9_descriptor;
77 static int *ett[] = {
78 &ett_vp9,
79 &ett_vp9_descriptor
82 static int
83 dissect_vp9(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree _U_, void *data _U_)
85 col_set_str(pinfo->cinfo, COL_PROTOCOL, "VP9");
87 proto_item *vp9_item = proto_tree_add_item(tree, proto_vp9, tvb, 0, -1, ENC_NA);
88 proto_tree *vp9_tree = proto_item_add_subtree(vp9_item, ett_vp9);
90 proto_item *vp9_descriptor_item;
91 proto_tree *vp9_descriptor_tree = proto_tree_add_subtree(vp9_tree, tvb, 0, 1, ett_vp9_descriptor, &vp9_descriptor_item, "Payload Descriptor");
93 int offset = 0;
96 0 1 2 3 4 5 6 7
97 +-+-+-+-+-+-+-+-+
98 |I|P|L|F|B|E|V|Z| (REQUIRED)
99 +-+-+-+-+-+-+-+-+
101 uint8_t i = tvb_get_uint8(tvb, offset) & VP9_1_BIT_MASK;
102 uint8_t p = tvb_get_uint8(tvb, offset) & VP9_2_BIT_MASK;
103 uint8_t l = tvb_get_uint8(tvb, offset) & VP9_3_BIT_MASK;
104 uint8_t f = tvb_get_uint8(tvb, offset) & VP9_4_BIT_MASK;
105 uint8_t v = tvb_get_uint8(tvb, offset) & VP9_7_BIT_MASK;
106 proto_tree_add_item(vp9_descriptor_tree, hf_vp9_pld_i_bit, tvb, offset, 1, ENC_BIG_ENDIAN);
107 proto_tree_add_item(vp9_descriptor_tree, hf_vp9_pld_p_bit, tvb, offset, 1, ENC_BIG_ENDIAN);
108 proto_tree_add_item(vp9_descriptor_tree, hf_vp9_pld_l_bit, tvb, offset, 1, ENC_BIG_ENDIAN);
109 proto_tree_add_item(vp9_descriptor_tree, hf_vp9_pld_f_bit, tvb, offset, 1, ENC_BIG_ENDIAN);
110 proto_tree_add_item(vp9_descriptor_tree, hf_vp9_pld_b_bit, tvb, offset, 1, ENC_BIG_ENDIAN);
111 proto_tree_add_item(vp9_descriptor_tree, hf_vp9_pld_e_bit, tvb, offset, 1, ENC_BIG_ENDIAN);
112 proto_tree_add_item(vp9_descriptor_tree, hf_vp9_pld_v_bit, tvb, offset, 1, ENC_BIG_ENDIAN);
113 proto_tree_add_item(vp9_descriptor_tree, hf_vp9_pld_z_bit, tvb, offset, 1, ENC_BIG_ENDIAN);
115 offset++;
118 +-+-+-+-+-+-+-+-+
119 I: |M| PICTURE ID | (REQUIRED)
120 +-+-+-+-+-+-+-+-+
121 M: | EXTENDED PID | (RECOMMENDED)
122 +-+-+-+-+-+-+-+-+
124 uint8_t m = tvb_get_uint8(tvb, offset) & VP9_1_BIT_MASK;
125 proto_tree_add_item(vp9_descriptor_tree, hf_vp9_pld_m_bit, tvb, offset, 1, ENC_BIG_ENDIAN);
126 if (f)
128 // Flexible mode
129 if (m == i)
131 if (m)
133 // Extended PID
134 proto_tree_add_item(vp9_descriptor_tree, hf_vp9_pld_pid_extended_bits, tvb, offset, 2, ENC_BIG_ENDIAN);
135 offset += 2;
137 else
139 // PID
140 proto_tree_add_item(vp9_descriptor_tree, hf_vp9_pld_pid_bits, tvb, offset, 1, ENC_BIG_ENDIAN);
141 offset++;
144 else
146 // Malformed packet
149 else
151 // Non-flexible mode
152 if (m == i)
154 if (m)
156 // Extended PID
157 proto_tree_add_item(vp9_descriptor_tree, hf_vp9_pld_pg_extended_bits, tvb, offset, 2, ENC_BIG_ENDIAN);
158 offset += 2;
160 else
162 // PID
163 proto_tree_add_item(vp9_descriptor_tree, hf_vp9_pld_pg_bits, tvb, offset, 1, ENC_BIG_ENDIAN);
164 offset++;
167 else
169 // Malformed packet
174 +-+-+-+-+-+-+-+-+
175 L: | TID |U| SID |D| (Conditionally RECOMMENDED)
176 +-+-+-+-+-+-+-+-+
178 if (l)
180 // Layer indices present
181 proto_tree_add_item(vp9_descriptor_tree, hf_vp9_pld_tid_bits, tvb, offset, 1, ENC_BIG_ENDIAN);
182 proto_tree_add_item(vp9_descriptor_tree, hf_vp9_pld_u_bit, tvb, offset, 1, ENC_BIG_ENDIAN);
183 proto_tree_add_item(vp9_descriptor_tree, hf_vp9_pld_sid_bits, tvb, offset, 1, ENC_BIG_ENDIAN);
184 proto_tree_add_item(vp9_descriptor_tree, hf_vp9_pld_d_bit, tvb, offset, 1, ENC_BIG_ENDIAN);
185 offset++;
187 if (f)
189 // 1 octet is present for the layer indices
190 proto_item_set_len(vp9_descriptor_item, 4);
192 else
194 // 2 octets are present for the layer indices
195 proto_tree_add_item(vp9_descriptor_tree, hf_vp9_pld_tl0picidx_bits, tvb, offset, 1, ENC_BIG_ENDIAN);
196 proto_item_set_len(vp9_descriptor_item, 5);
197 offset++;
202 +-+-+-+-+-+-+-+-+ -\
203 P,F: | P_DIFF |N| (Conditionally REQUIRED) - up to 3 times
204 +-+-+-+-+-+-+-+-+ -/
206 if (p && f)
208 uint8_t n = tvb_get_uint8(tvb, offset) & (VP9_1_BIT_MASK >> 7);
209 int idx = 0;
210 int max_p_diff = 3;
211 while (n && idx < max_p_diff)
213 proto_tree_add_item(vp9_descriptor_tree, hf_vp9_pld_p_diff_bits, tvb, offset, 1, ENC_BIG_ENDIAN);
214 proto_tree_add_item(vp9_descriptor_tree, hf_vp9_pld_n_bit, tvb, offset, 1, ENC_BIG_ENDIAN);
215 proto_item_set_len(vp9_descriptor_item, 6);
216 offset++;
217 n = tvb_get_uint8(tvb, offset) & (VP9_1_BIT_MASK >> 7);
218 idx++;
219 if (n && idx == max_p_diff)
221 // Malformed packet
227 +-+-+-+-+-+-+-+-+
228 V: | SS |
229 | .. |
230 +-+-+-+-+-+-+-+-+
232 if (v)
235 +-+-+-+-+-+-+-+-+
236 V: | N_S |Y|G|-|-|-|
237 +-+-+-+-+-+-+-+-+
239 proto_item* n_s_numbers_field;
240 uint8_t n_s = (tvb_get_uint8(tvb, offset) & (VP9_3_BITS_MASK)) >> 5;
241 uint8_t y = tvb_get_uint8(tvb, offset) & (VP9_1_BIT_MASK >> 3);
242 uint8_t g = tvb_get_uint8(tvb, offset) & (VP9_1_BIT_MASK >> 4);
243 uint8_t number_of_spatial_layers = n_s + 1;
245 proto_tree_add_item(vp9_descriptor_tree, hf_vp9_pld_n_s_bits, tvb, offset, 1, ENC_BIG_ENDIAN);
246 n_s_numbers_field = proto_tree_add_uint(vp9_descriptor_tree, hf_vp9_pld_n_s_numbers, tvb, offset, 1, number_of_spatial_layers);
247 proto_tree_add_item(vp9_descriptor_tree, hf_vp9_pld_y_bit, tvb, offset, 1, ENC_BIG_ENDIAN);
248 proto_tree_add_item(vp9_descriptor_tree, hf_vp9_pld_g_bit, tvb, offset, 1, ENC_BIG_ENDIAN);
249 proto_item_set_generated(n_s_numbers_field);
251 offset++;
254 +-+-+-+-+-+-+-+-+ -\
255 Y: | WIDTH | (OPTIONAL) .
256 + + .
257 | | (OPTIONAL) .
258 +-+-+-+-+-+-+-+-+ . - N_S + 1 times
259 | HEIGHT | (OPTIONAL) .
260 + + .
261 | | (OPTIONAL) .
262 +-+-+-+-+-+-+-+-+ -/
264 uint8_t spatial_layer = 0;
265 while (spatial_layer < number_of_spatial_layers)
267 if (y)
269 // TODO: Add subtree for spatial layers
270 proto_tree_add_item(vp9_descriptor_tree, hf_vp9_pld_width_bits, tvb, offset, 2, ENC_BIG_ENDIAN);
271 offset += 2;
272 proto_tree_add_item(vp9_descriptor_tree, hf_vp9_pld_height_bits, tvb, offset, 2, ENC_BIG_ENDIAN);
273 offset += 2;
275 spatial_layer++;
279 +-+-+-+-+-+-+-+-+
280 G: | N_G | (OPTIONAL)
281 +-+-+-+-+-+-+-+-+
283 if (g)
286 +-+-+-+-+-+-+-+-+ -\
287 N_G: | TID |U| R |-|-| (OPTIONAL) .
288 +-+-+-+-+-+-+-+-+ -\ . - N_G times
289 | P_DIFF | (OPTIONAL) . - R times .
290 +-+-+-+-+-+-+-+-+ -/ -/
292 proto_tree_add_item(vp9_descriptor_tree, hf_vp9_pld_n_g_bits, tvb, offset, 1, ENC_BIG_ENDIAN);
293 offset++;
294 // TODO: handle N_G
298 return tvb_captured_length(tvb);
301 void proto_register_vp9(void)
303 static hf_register_info hf[] = {
304 {&hf_vp9_pld_i_bit,
305 {"Picture ID present (I)", "vp9.pld.i",
306 FT_BOOLEAN, 8,
307 NULL, VP9_1_BIT_MASK,
308 NULL, HFILL}},
309 {&hf_vp9_pld_p_bit,
310 {"Inter-picture predicted frame (P)", "vp9.pld.p",
311 FT_BOOLEAN, 8,
312 NULL, VP9_2_BIT_MASK,
313 NULL, HFILL}},
314 {&hf_vp9_pld_l_bit,
315 {"Layer indices present (L)", "vp9.pld.l",
316 FT_BOOLEAN, 8,
317 NULL, VP9_3_BIT_MASK,
318 NULL, HFILL}},
319 {&hf_vp9_pld_f_bit,
320 {"Flexible mode (F)", "vp9.pld.f",
321 FT_BOOLEAN, 8,
322 NULL, VP9_4_BIT_MASK,
323 NULL, HFILL}},
324 {&hf_vp9_pld_b_bit,
325 {"Start of a frame (B)", "vp9.pld.b",
326 FT_BOOLEAN, 8,
327 NULL, VP9_5_BIT_MASK,
328 NULL, HFILL}},
329 {&hf_vp9_pld_e_bit,
330 {"End of a frame (E)", "vp9.pld.e",
331 FT_BOOLEAN, 8,
332 NULL, VP9_6_BIT_MASK,
333 NULL, HFILL}},
334 {&hf_vp9_pld_v_bit,
335 {"Scalability structure (SS) data present (V)", "vp9.pld.v",
336 FT_BOOLEAN, 8,
337 NULL, VP9_7_BIT_MASK,
338 NULL, HFILL}},
339 {&hf_vp9_pld_z_bit,
340 {"Not a reference frame for upper spatial layers (Z)", "vp9.pld.z",
341 FT_BOOLEAN, 8,
342 NULL, VP9_8_BIT_MASK,
343 NULL, HFILL}},
344 {&hf_vp9_pld_m_bit,
345 {"Extension flag (M)", "vp9.pld.m",
346 FT_BOOLEAN, 8,
347 NULL, VP9_1_BIT_MASK,
348 NULL, HFILL}},
349 {&hf_vp9_pld_pid_bits,
350 {"Picture ID (PID)", "vp9.pld.pid",
351 FT_UINT8, BASE_DEC,
352 NULL, VP9_7_BITS_MASK >> 1,
353 NULL, HFILL}},
354 {&hf_vp9_pld_pid_extended_bits,
355 {"Picture ID (PID) Extended", "vp9.pld.pid_ext",
356 FT_UINT16, BASE_DEC,
357 NULL, VP9_EXTENDED_PID,
358 NULL, HFILL}},
359 {&hf_vp9_pld_pg_bits,
360 {"Picture Group Index (PG)", "vp9.pld.pg",
361 FT_UINT8, BASE_DEC,
362 NULL, VP9_7_BITS_MASK >> 1,
363 NULL, HFILL}},
364 {&hf_vp9_pld_pg_extended_bits,
365 {"Picture Group Index (PG) Extended", "vp9.pld.pg_ext",
366 FT_UINT16, BASE_DEC,
367 NULL, VP9_EXTENDED_PID,
368 NULL, HFILL}},
369 {&hf_vp9_pld_tid_bits,
370 {"Temporal layer ID", "vp9.pld.tid",
371 FT_UINT8, BASE_DEC,
372 NULL, VP9_3_BITS_MASK,
373 NULL, HFILL}},
374 {&hf_vp9_pld_u_bit,
375 {"Switching up point (U)", "vp9.pld.u",
376 FT_BOOLEAN, 8,
377 NULL, VP9_1_BIT_MASK >> 3,
378 NULL, HFILL}},
379 {&hf_vp9_pld_sid_bits,
380 {"Spatial Layer ID", "vp9.pld.sid",
381 FT_UINT8, BASE_DEC,
382 NULL, VP9_3_BITS_MASK >> 4,
383 NULL, HFILL}},
384 {&hf_vp9_pld_d_bit,
385 {"Inter-layer dependency used (D)", "vp9.pld.d",
386 FT_BOOLEAN, 8,
387 NULL, VP9_1_BIT_MASK >> 7,
388 NULL, HFILL}},
389 {&hf_vp9_pld_tl0picidx_bits,
390 {"Temporal layer zero index", "vp9.pld.tl0picidx",
391 FT_UINT8, BASE_DEC,
392 NULL, 0,
393 NULL, HFILL}},
394 {&hf_vp9_pld_p_diff_bits,
395 {"Reference index (P_DIFF)", "vp9.pld.p_diff",
396 FT_UINT8, BASE_DEC,
397 NULL, VP9_7_BITS_MASK,
398 NULL, HFILL}},
399 {&hf_vp9_pld_n_bit,
400 {"Additional reference index (N)", "vp9.pld.n",
401 FT_BOOLEAN, 8,
402 NULL, VP9_1_BIT_MASK >> 7,
403 NULL, HFILL}},
404 {&hf_vp9_pld_n_s_bits,
405 {"Spatial layers minus 1 (N_S)", "vp9.pld.n_s",
406 FT_UINT8, BASE_DEC,
407 NULL, VP9_3_BITS_MASK,
408 NULL, HFILL}},
409 {&hf_vp9_pld_n_s_numbers,
410 {"Number of spatial layers", "vp9.pld.spatial_layers_number",
411 FT_UINT8, BASE_DEC,
412 NULL, 0,
413 NULL, HFILL}},
414 {&hf_vp9_pld_y_bit,
415 {"Spatial layer's frame resolution present (Y)", "vp9.pld.y",
416 FT_BOOLEAN, 8,
417 NULL, VP9_1_BIT_MASK >> 3,
418 NULL, HFILL}},
419 {&hf_vp9_pld_g_bit,
420 {"PG description flag (G)", "vp9.pld.g",
421 FT_BOOLEAN, 8,
422 NULL, VP9_1_BIT_MASK >> 4,
423 NULL, HFILL}},
424 {&hf_vp9_pld_height_bits,
425 {"Height", "vp9.pld.height",
426 FT_UINT16, BASE_DEC,
427 NULL, 0,
428 NULL, HFILL}},
429 {&hf_vp9_pld_width_bits,
430 {"Width", "vp9.pld.width",
431 FT_UINT16, BASE_DEC,
432 NULL, 0,
433 NULL, HFILL}},
434 {&hf_vp9_pld_n_g_bits,
435 {"Number of pictures (N_G)", "vp9.pld.n_g",
436 FT_UINT8, BASE_DEC,
437 NULL, 0,
438 NULL, HFILL}}};
440 proto_vp9 = proto_register_protocol("VP9", "VP9", "vp9");
442 proto_register_field_array(proto_vp9, hf, array_length(hf));
443 proto_register_subtree_array(ett, array_length(ett));
446 void proto_reg_handoff_vp9(void)
448 static dissector_handle_t vp9_handle;
450 vp9_handle = register_dissector("vp9", dissect_vp9, proto_vp9);
452 dissector_add_string("rtp_dyn_payload_type", "vp9", vp9_handle);
453 dissector_add_uint_range_with_preference("rtp.pt", "", vp9_handle);
457 * Editor modelines - https://www.wireshark.org/tools/modelines.html
459 * Local variables:
460 * c-basic-offset: 4
461 * tab-width: 8
462 * indent-tabs-mode: nil
463 * End:
465 * vi: set shiftwidth=4 tabstop=8 expandtab:
466 * :indentSize=4:tabSize=8:noTabs=true: