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-vp8.c
Line
Count
Source
1
/* packet-vp8.c
2
 * Routines for VP8 dissection
3
 * Copyright 2014, Owen Williams williams.owen@gmail.com
4
 *
5
 * Wireshark - Network traffic analyzer
6
 * By Gerald Combs <gerald@wireshark.org>
7
 * Copyright 1998 Gerald Combs
8
 *
9
 * SPDX-License-Identifier: GPL-2.0-or-later
10
 */
11
12
/*
13
 * RFC 6386 - VP8 Data Format and Decoding Guide
14
 * RFC 7741 - RTP Payload Format for VP8 Video
15
 */
16
17
18
#include "config.h"
19
20
#include <epan/packet.h>
21
#include <epan/prefs.h>
22
#include <epan/expert.h>
23
#include <epan/tfs.h>
24
#include <wsutil/array.h>
25
26
void proto_reg_handoff_vp8(void);
27
void proto_register_vp8(void);
28
29
28
#define BIT_1_MASK              0x80
30
28
#define BIT_2_MASK              0x40
31
42
#define BIT_3_MASK              0x20
32
42
#define BIT_4_MASK              0x10
33
#define BIT_5_MASK              0x08
34
#define BIT_6_MASK              0x04
35
#define BIT_7_MASK              0x02
36
14
#define BIT_8_MASK              0x01
37
0
#define BIT_123_MASK            0xE0
38
#define BIT_234_MASK            0x70
39
28
#define BIT_5678_MASK           0x0F
40
14
#define BIT_567_MASK            0x0E
41
14
#define BIT_45678_MASK          0x1F
42
42
#define BIT_12_MASK             0xC0
43
28
#define BIT_NO_MASK             0x0
44
45
28
#define BIT_2BYTE_NO_MASK       0x0
46
14
#define BIT_3BYTE_NO_MASK       0x0
47
14
#define BIT_EXT_PICTURE_MASK    0x7FFF
48
14
#define BIT_PARTITION_SIZE_MASK 0xFFFFE0
49
50
static dissector_handle_t vp8_handle;
51
52
/* Initialize the protocol and registered fields */
53
static int proto_vp8;
54
static int hf_vp8_pld_x_bit;
55
static int hf_vp8_pld_r_bit;
56
static int hf_vp8_pld_n_bit;
57
static int hf_vp8_pld_s_bit;
58
static int hf_vp8_pld_part_id;
59
static int hf_vp8_pld_i_bit;
60
static int hf_vp8_pld_l_bit;
61
static int hf_vp8_pld_t_bit;
62
static int hf_vp8_pld_k_bit;
63
static int hf_vp8_pld_rsv_a;
64
static int hf_vp8_pld_picture_id;
65
static int hf_vp8_pld_extended_picture_id;
66
static int hf_vp8_pld_tl0picidx;
67
static int hf_vp8_pld_tid;
68
static int hf_vp8_pld_y_bit;
69
static int hf_vp8_pld_keyidx;
70
71
/* payload header fields */
72
static int hf_vp8_hdr_frametype;
73
static int hf_vp8_hdr_version;
74
static int hf_vp8_hdr_show_bit;
75
static int hf_vp8_hdr_first_partition_size;
76
77
/* keyframe fields */
78
static int hf_vp8_keyframe_start_code;
79
static int hf_vp8_keyframe_width;
80
static int hf_vp8_keyframe_horizontal_scale;
81
static int hf_vp8_keyframe_height;
82
static int hf_vp8_keyframe_vertical_scale;
83
84
/* Initialize the subtree pointers */
85
static int ett_vp8;
86
static int ett_vp8_payload_descriptor;
87
static int ett_vp8_payload_header;
88
static int ett_vp8_payload;
89
static int ett_vp8_keyframe;
90
91
static expert_field ei_vp8_startcode;
92
static expert_field ei_vp8_undecoded;
93
static expert_field ei_vp8_continuation;
94
static expert_field ei_vp8_first_partition_split;
95
static expert_field ei_vp8_first_partition_plus;
96
97
static void
98
dissect_vp8_payload_descriptor(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *vp8_tree, int *offset, bool *hasHeader);
99
100
static void
101
dissect_vp8_payload_header(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *vp8_tree, int *offset, int *frametype, int *partition1_size);
102
103
static void
104
dissect_vp8_payload(tvbuff_t *tvb, packet_info *pinfo, proto_tree *vp8_tree, int *offset, int *frametype, int *partition1_size);
105
106
static int *ett[] = {
107
    &ett_vp8,
108
    &ett_vp8_payload_descriptor,
109
    &ett_vp8_payload_header,
110
    &ett_vp8_payload,
111
    &ett_vp8_keyframe
112
};
113
114
static const value_string vp8_type_values[] = {
115
    {  0,   "Keyframe" },
116
    {  1,   "Interframe" },
117
    {  2,   "Continuation" },
118
    {  0, NULL }
119
};
120
121
static const range_string vp8_hdr_version_vals[] = {
122
    {  0, 0,   "Bicubic  (Loop Filter=Normal)" },
123
    {  1, 1,   "Bilinear (Loop Filter=Simple)" },
124
    {  2, 2,   "Bilinear (Loop Filter=None)" },
125
    {  3, 3,   "No filters" },
126
    {  4, 7,   "Reserved for future use" },
127
    {  0, 0,  NULL }
128
};
129
130
static const true_false_string vp8_x_bit_vals = {
131
    "Extended control bits present (I L T K)",
132
    "Extended control bits not present"
133
};
134
135
static const true_false_string vp8_r_bit_vals = {
136
    "Reserved for future use (error: should be zero)",
137
    "Reserved for future use"
138
};
139
140
static const true_false_string vp8_n_bit_vals = {
141
    "Non-reference frame",
142
    "Reference frame"
143
};
144
145
static const true_false_string vp8_s_bit_vals = {
146
    "Start of VP8 partition",
147
    "Continuation of VP8 partition"
148
};
149
150
static const true_false_string vp8_i_bit_vals = {
151
    "Picture ID byte present",
152
    "No Picture byte ID"
153
};
154
155
static const true_false_string vp8_l_bit_vals = {
156
    "TL0PICIDX byte present",
157
    "TL0PICIDX byte not present"
158
};
159
160
static const true_false_string vp8_t_bit_vals = {
161
    "TID (temporal layer index) present",
162
    "TID (temporal layer index) not present"
163
};
164
165
static const true_false_string vp8_k_bit_vals = {
166
    "KEYIDX present",
167
    "KEYIDX not present"
168
};
169
170
static const true_false_string vp8_hdr_frametype_vals = {
171
    "interframe",
172
    "keyframe"
173
};
174
175
static int
176
dissect_vp8(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
177
0
{
178
179
0
    proto_item *item;
180
0
    int offset = 0, frametype = 0, partition1_size = -1;
181
0
    proto_tree *vp8_tree;
182
0
    bool hasHeader = false;
183
184
0
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "VP8");
185
186
0
    item = proto_tree_add_item(tree, proto_vp8, tvb, 0, -1, ENC_NA);
187
0
    vp8_tree = proto_item_add_subtree(item, ett_vp8);
188
189
0
    frametype = 2; /*continuation, will get overridden if there is a payload header*/
190
191
0
    dissect_vp8_payload_descriptor(tvb, pinfo, vp8_tree, &offset, &hasHeader);
192
0
    if (hasHeader)
193
0
    {
194
0
        dissect_vp8_payload_header(tvb, pinfo, vp8_tree, &offset, &frametype, &partition1_size);
195
0
    }
196
197
0
    dissect_vp8_payload(tvb, pinfo, vp8_tree, &offset, &frametype, &partition1_size);
198
199
0
    col_append_fstr(pinfo->cinfo, COL_INFO, " - %s",
200
0
        val_to_str(pinfo->pool, frametype, vp8_type_values, "Unknown Type (%u)"));
201
202
0
    return tvb_captured_length(tvb);
203
0
}
204
205
static void
206
dissect_vp8_payload_descriptor(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *vp8_tree, int *offset, bool *hasHeader)
207
0
{
208
0
    proto_item *item_descriptor;
209
0
    uint8_t     extended_bit, s_bit, partId;
210
0
    proto_tree *vp8_payload_descriptor_tree;
211
212
/*
213
The first octets after the RTP header are the VP8 payload descriptor,
214
   with the following structure.
215
216
         0 1 2 3 4 5 6 7
217
        +-+-+-+-+-+-+-+-+
218
        |X|R|N|S|R| PID | (REQUIRED), second R bit is parsed as part of PID
219
        +-+-+-+-+-+-+-+-+
220
   X:   |I|L|T|K| RSV   | (OPTIONAL)
221
        +-+-+-+-+-+-+-+-+
222
   I:   |M|  PictureID  | (OPTIONAL)
223
        +-+-+-+-+-+-+-+-+
224
   L:   |   TL0PICIDX   | (OPTIONAL)
225
        +-+-+-+-+-+-+-+-+
226
   T/K: |TID|Y| KEYIDX  | (OPTIONAL)
227
        +-+-+-+-+-+-+-+-+
228
*/
229
230
0
    vp8_payload_descriptor_tree = proto_tree_add_subtree(vp8_tree, tvb, *offset, -1, ett_vp8_payload_descriptor,
231
0
                                                         &item_descriptor, "Payload descriptor");
232
233
0
    proto_tree_add_item(vp8_payload_descriptor_tree, hf_vp8_pld_x_bit,   tvb, *offset, 1, ENC_BIG_ENDIAN);
234
0
    proto_tree_add_item(vp8_payload_descriptor_tree, hf_vp8_pld_r_bit,   tvb, *offset, 1, ENC_BIG_ENDIAN);
235
0
    proto_tree_add_item(vp8_payload_descriptor_tree, hf_vp8_pld_n_bit,   tvb, *offset, 1, ENC_BIG_ENDIAN);
236
0
    proto_tree_add_item(vp8_payload_descriptor_tree, hf_vp8_pld_s_bit,   tvb, *offset, 1, ENC_BIG_ENDIAN);
237
0
    proto_tree_add_item(vp8_payload_descriptor_tree, hf_vp8_pld_part_id, tvb, *offset, 1, ENC_BIG_ENDIAN);
238
0
    extended_bit = tvb_get_uint8(tvb, *offset) & BIT_1_MASK;
239
0
    s_bit  = tvb_get_uint8(tvb, *offset) & BIT_4_MASK;
240
0
    partId = tvb_get_uint8(tvb, *offset) & BIT_5678_MASK;
241
242
0
    if ((s_bit > 0) && (partId == 0)) {
243
0
        *hasHeader=true;
244
0
    }
245
246
0
    if (extended_bit)
247
0
    {
248
0
        uint8_t i_bit, l_bit, t_bit, k_bit;
249
0
        (*offset)++;
250
0
        proto_tree_add_item(vp8_payload_descriptor_tree, hf_vp8_pld_i_bit, tvb, *offset, 1, ENC_BIG_ENDIAN);
251
0
        proto_tree_add_item(vp8_payload_descriptor_tree, hf_vp8_pld_l_bit, tvb, *offset, 1, ENC_BIG_ENDIAN);
252
0
        proto_tree_add_item(vp8_payload_descriptor_tree, hf_vp8_pld_t_bit, tvb, *offset, 1, ENC_BIG_ENDIAN);
253
0
        proto_tree_add_item(vp8_payload_descriptor_tree, hf_vp8_pld_k_bit, tvb, *offset, 1, ENC_BIG_ENDIAN);
254
0
        proto_tree_add_item(vp8_payload_descriptor_tree, hf_vp8_pld_rsv_a, tvb, *offset, 1, ENC_BIG_ENDIAN);
255
256
0
        i_bit = tvb_get_uint8(tvb, *offset) & BIT_1_MASK;
257
0
        l_bit = tvb_get_uint8(tvb, *offset) & BIT_2_MASK;
258
0
        t_bit = tvb_get_uint8(tvb, *offset) & BIT_3_MASK;
259
0
        k_bit = tvb_get_uint8(tvb, *offset) & BIT_4_MASK;
260
0
        if (i_bit)
261
0
        {
262
0
            (*offset)++;
263
0
            if(tvb_get_uint8(tvb, *offset) & BIT_1_MASK)
264
0
            {
265
0
                proto_tree_add_item(vp8_payload_descriptor_tree, hf_vp8_pld_extended_picture_id, tvb, *offset, 2, ENC_BIG_ENDIAN);
266
0
                (*offset)++;
267
0
            }
268
0
            else
269
0
            {
270
0
                proto_tree_add_item(vp8_payload_descriptor_tree, hf_vp8_pld_picture_id, tvb, *offset, 1, ENC_BIG_ENDIAN);
271
0
            }
272
273
0
        }
274
0
        if (l_bit)
275
0
        {
276
0
            (*offset)++;
277
0
            proto_tree_add_item(vp8_payload_descriptor_tree, hf_vp8_pld_tl0picidx, tvb, *offset, 1, ENC_BIG_ENDIAN);
278
0
        }
279
0
        if (t_bit || k_bit)
280
0
        {
281
0
             (*offset)++;
282
0
             proto_tree_add_item(vp8_payload_descriptor_tree, hf_vp8_pld_tid, tvb, *offset, 1, ENC_BIG_ENDIAN);
283
0
             proto_tree_add_item(vp8_payload_descriptor_tree, hf_vp8_pld_y_bit, tvb, *offset, 1, ENC_BIG_ENDIAN);
284
0
             proto_tree_add_item(vp8_payload_descriptor_tree, hf_vp8_pld_keyidx, tvb, *offset, 1, ENC_BIG_ENDIAN);
285
0
        }
286
0
    }
287
0
    (*offset)++;
288
    /* now we know the length of payload descriptor */
289
0
    proto_item_set_len(item_descriptor, *offset);
290
0
}
291
292
static void
293
dissect_vp8_payload_header(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *vp8_tree, int *offset, int *frametype, int *partition1_size)
294
0
{
295
0
    proto_item *item_header;
296
0
    proto_tree *vp8_payload_header_tree;
297
0
    int size0, size1, size2;
298
299
/*
300
The first three octets of an encoded VP8 frame are referred to as an
301
   "uncompressed data chunk" in [RFC6386], and co-serve as payload
302
   header in this RTP format.  The codec bitstream format specifies two
303
   different variants of the uncompressed data chunk: a 3 octet version
304
   for interframes and a 10 octet version for key frames.  The first 3
305
   octets are common to both variants.  In the case of a key frame the
306
   remaining 7 octets are considered to be part of the remaining payload
307
   in this RTP format.  Note that the header is present only in packets
308
   which have the S bit equal to one and the PartID equal to zero in the
309
   payload descriptor.  Subsequent packets for the same frame do not
310
   carry the payload header.
311
312
313
      0 1 2 3 4 5 6 7
314
     +-+-+-+-+-+-+-+-+
315
     |Size0|H| VER |P|
316
     +-+-+-+-+-+-+-+-+
317
     |     Size1     |
318
     +-+-+-+-+-+-+-+-+
319
     |     Size2     |
320
     +-+-+-+-+-+-+-+-+
321
     | Bytes 4..N of |
322
     | VP8 payload   |
323
     :               :
324
     +-+-+-+-+-+-+-+-+
325
     | OPTIONAL RTP  |
326
     | padding       |
327
     :               :
328
     +-+-+-+-+-+-+-+-+
329
330
*/
331
332
0
    vp8_payload_header_tree = proto_tree_add_subtree(vp8_tree, tvb, *offset, 3, ett_vp8_payload_header, &item_header, "Payload header");
333
0
    proto_tree_add_item(vp8_payload_header_tree, hf_vp8_hdr_frametype, tvb, *offset, 1, ENC_BIG_ENDIAN);
334
0
    proto_tree_add_item(vp8_payload_header_tree, hf_vp8_hdr_version,   tvb, *offset, 1, ENC_BIG_ENDIAN);
335
0
    proto_tree_add_item(vp8_payload_header_tree, hf_vp8_hdr_show_bit,  tvb, *offset, 1, ENC_BIG_ENDIAN);
336
337
0
    *frametype = tvb_get_uint8(tvb, *offset) & BIT_8_MASK;
338
339
0
    size0 = (tvb_get_uint8(tvb, *offset) & BIT_123_MASK) >> 5;
340
0
    size1 = tvb_get_uint8(tvb, *offset + 1);
341
0
    size2 = tvb_get_uint8(tvb, *offset + 2);
342
0
    (*partition1_size) = size0 + (size1*8) + (size2*2048);
343
0
    proto_tree_add_uint(vp8_payload_header_tree, hf_vp8_hdr_first_partition_size, tvb, *offset, 3, *partition1_size);
344
0
    (*offset) += 3;
345
0
}
346
347
static void
348
dissect_vp8_payload(tvbuff_t *tvb, packet_info *pinfo, proto_tree *vp8_tree, int *offset, int *frametype, int *partition1_size)
349
0
{
350
0
    proto_tree *vp8_payload_tree;
351
0
    proto_item *payload_item;
352
0
    int remainder;
353
354
0
    vp8_payload_tree = proto_tree_add_subtree(vp8_tree, tvb, *offset, -1, ett_vp8_payload, &payload_item, "Payload");
355
356
0
    if (*frametype == 0)
357
0
    {
358
0
        uint16_t width, height;
359
0
        int start1, start2, start3, horizontal_scale, vertical_scale;
360
0
        proto_tree *vp8_keyframe_tree;
361
362
0
        vp8_keyframe_tree = proto_tree_add_subtree(vp8_payload_tree, tvb, *offset, -1, ett_vp8_keyframe, NULL, "Keyframe header");
363
364
0
        proto_tree_add_item(vp8_keyframe_tree, hf_vp8_keyframe_start_code, tvb, *offset, 3, ENC_BIG_ENDIAN);
365
0
        start1 = tvb_get_uint8(tvb, *offset);
366
0
        start2 = tvb_get_uint8(tvb, *offset + 1);
367
0
        start3 = tvb_get_uint8(tvb, *offset + 2);
368
369
        /* check start code is correct */
370
0
        if ((start1 != 0x9d) || (start2 != 0x01) || (start3 != 0x2a))
371
0
        {
372
0
            expert_add_info(pinfo, vp8_keyframe_tree, &ei_vp8_startcode);
373
0
        }
374
375
0
        (*offset)++;
376
0
        (*offset)++;
377
0
        (*offset)++;
378
0
        width = tvb_get_letohs(tvb, *offset) & 0x3FFF;
379
0
        horizontal_scale = tvb_get_letohs(tvb, *offset)>>14;
380
381
0
        proto_tree_add_uint(vp8_keyframe_tree, hf_vp8_keyframe_horizontal_scale, tvb, *offset, 2, horizontal_scale);
382
0
        proto_tree_add_uint(vp8_keyframe_tree, hf_vp8_keyframe_width, tvb, *offset, 2, width);
383
0
        (*offset)++;
384
0
        (*offset)++;
385
386
0
        height = tvb_get_letohs(tvb, *offset) & 0x3FFF;
387
0
        vertical_scale = tvb_get_letohs(tvb, *offset)>>14;
388
0
        proto_tree_add_uint(vp8_keyframe_tree, hf_vp8_keyframe_vertical_scale, tvb, *offset, 2, vertical_scale);
389
0
        proto_tree_add_uint(vp8_keyframe_tree, hf_vp8_keyframe_height, tvb, *offset, 2, height);
390
0
        (*offset)++;
391
0
        (*offset)++;
392
0
    }
393
394
0
    remainder = tvb_reported_length_remaining(tvb, (*offset));
395
0
    if ((*partition1_size) == -1)
396
0
    {
397
        /*no header, continuation?*/
398
0
        proto_tree_add_expert_format(vp8_payload_tree, pinfo, &ei_vp8_continuation, tvb, *offset, -1, "Continuation of partition fragment (%d bytes)", remainder);
399
0
    }
400
0
    else
401
0
    {
402
0
        if (remainder < *partition1_size)
403
0
        {
404
            /* partition size has already been added to vp8 header tree, but it would be useful to provide additional explanation */
405
0
            proto_tree_add_expert_format(vp8_payload_tree, pinfo, &ei_vp8_first_partition_split, tvb, *offset, -1,
406
0
                "First partition is split with %d bytes in this packet and %d bytes in subsequent frames", remainder, ((*partition1_size)-remainder));
407
0
        }
408
0
        else
409
0
        {
410
0
            (*offset)= (*offset) + (*partition1_size);
411
0
            proto_tree_add_expert_format(vp8_payload_tree, pinfo, &ei_vp8_first_partition_plus, tvb, *offset, -1,
412
0
                                "This frame contains all of first partition (%d bytes) and also %d bytes from other partitions",
413
0
                                *partition1_size, remainder);
414
0
        }
415
0
    }
416
0
    expert_add_info(pinfo, payload_item, &ei_vp8_undecoded);
417
0
}
418
419
void
420
proto_register_vp8(void)
421
14
{
422
14
    module_t *vp8_module;
423
14
    expert_module_t* expert_vp8;
424
425
14
    static hf_register_info hf[] = {
426
14
        { &hf_vp8_pld_x_bit,
427
14
            { "X bit",           "vp8.pld.x",
428
14
            FT_BOOLEAN, 8, TFS(&vp8_x_bit_vals), BIT_1_MASK,
429
14
            NULL, HFILL }
430
14
        },
431
14
        { &hf_vp8_pld_r_bit,
432
14
            { "R bit",           "vp8.pld.r",
433
14
            FT_BOOLEAN, 8, TFS(&vp8_r_bit_vals), BIT_2_MASK,
434
14
            NULL, HFILL }
435
14
        },
436
14
        { &hf_vp8_pld_n_bit,
437
14
            { "N bit",           "vp8.pld.n",
438
14
            FT_BOOLEAN, 8, TFS(&vp8_n_bit_vals), BIT_3_MASK,
439
14
            NULL, HFILL }
440
14
        },
441
14
        { &hf_vp8_pld_s_bit,
442
14
            { "S bit",           "vp8.pld.s",
443
14
            FT_BOOLEAN, 8, TFS(&vp8_s_bit_vals), BIT_4_MASK,
444
14
            NULL, HFILL }
445
14
        },
446
14
        { &hf_vp8_pld_part_id,
447
14
            { "2nd R bit and Part Id",           "vp8.pld.partid",
448
14
            FT_UINT8, BASE_DEC, NULL, BIT_5678_MASK,
449
14
            NULL, HFILL }
450
14
        },
451
14
        { &hf_vp8_pld_i_bit,
452
14
            { "I bit",           "vp8.pld.i",
453
14
            FT_BOOLEAN, 8, TFS(&vp8_i_bit_vals), BIT_1_MASK,
454
14
            NULL, HFILL }
455
14
        },
456
14
        { &hf_vp8_pld_l_bit,
457
14
            { "L bit",           "vp8.pld.l",
458
14
            FT_BOOLEAN, 8, TFS(&vp8_l_bit_vals), BIT_2_MASK,
459
14
            NULL, HFILL }
460
14
        },
461
14
        { &hf_vp8_pld_t_bit,
462
14
            { "T bit",           "vp8.pld.t",
463
14
            FT_BOOLEAN, 8, TFS(&vp8_t_bit_vals), BIT_3_MASK,
464
14
            NULL, HFILL }
465
14
        },
466
14
        { &hf_vp8_pld_k_bit,
467
14
            { "K bit",           "vp8.pld.k",
468
14
            FT_BOOLEAN, 8, TFS(&vp8_k_bit_vals), BIT_4_MASK,
469
14
            NULL, HFILL }
470
14
        },
471
14
        { &hf_vp8_pld_rsv_a,
472
14
            { "Reserved A",           "vp8.pld.rsva",
473
14
            FT_UINT8, BASE_DEC, NULL, BIT_5678_MASK,
474
14
            NULL, HFILL }
475
14
        },
476
14
        { &hf_vp8_pld_picture_id,
477
14
            { "Picture ID",           "vp8.pld.pictureid",
478
14
            FT_UINT8, BASE_DEC, NULL, BIT_NO_MASK,
479
14
            NULL, HFILL }
480
14
        },
481
14
        { &hf_vp8_pld_extended_picture_id,
482
14
            { "Extended Picture ID",           "vp8.pld.pictureid",
483
14
            FT_UINT16, BASE_DEC, NULL, BIT_EXT_PICTURE_MASK,
484
14
            NULL, HFILL }
485
14
        },
486
14
        { &hf_vp8_pld_tl0picidx,
487
14
            { "Temporal layer zero Picture Index (TL0PICIDX)",           "vp8.pld.tl0picidx",
488
14
            FT_UINT8, BASE_DEC, NULL, BIT_NO_MASK,
489
14
            NULL, HFILL }
490
14
        },
491
14
        { &hf_vp8_pld_tid,
492
14
            { "Temporal layer Index (TID)",           "vp8.pld.tid",
493
14
            FT_UINT8, BASE_DEC, NULL, BIT_12_MASK,
494
14
            NULL, HFILL }
495
14
        },
496
14
        { &hf_vp8_pld_y_bit,
497
14
            { "1 layer sync bit (Y)",           "vp8.pld.y",
498
14
            FT_BOOLEAN, 8, NULL, BIT_3_MASK,
499
14
            NULL, HFILL }
500
14
        },
501
14
        { &hf_vp8_pld_keyidx,
502
14
            { "Temporal Key Frame Index (KEYIDX)",           "vp8.pld.keyidx",
503
14
            FT_UINT8, BASE_DEC, NULL, BIT_45678_MASK,
504
14
            NULL, HFILL }
505
14
        },
506
14
        { &hf_vp8_hdr_frametype,
507
14
            { "frametype",           "vp8.hdr.frametype",
508
14
            FT_BOOLEAN, 8, TFS(&vp8_hdr_frametype_vals), BIT_8_MASK,
509
14
            NULL, HFILL }
510
14
        },
511
14
        { &hf_vp8_hdr_version,
512
14
            { "version",           "vp8.hdr.version",
513
14
            FT_UINT8, BASE_DEC | BASE_RANGE_STRING, RVALS(vp8_hdr_version_vals), BIT_567_MASK,
514
14
            NULL, HFILL }
515
14
        },
516
14
        { &hf_vp8_hdr_show_bit,
517
14
            { "Show bit",           "vp8.hdr.show",
518
14
            FT_BOOLEAN, 8, NULL, BIT_4_MASK,
519
14
            "Set when current frame is for display", HFILL }
520
14
        },
521
14
        { &hf_vp8_hdr_first_partition_size,
522
14
            { "First partition size",           "vp8.hdr.partition_size",
523
14
            FT_UINT24, BASE_DEC, NULL, BIT_PARTITION_SIZE_MASK,
524
14
            NULL, HFILL }
525
14
        },
526
14
        { &hf_vp8_keyframe_start_code,
527
14
            { "VP8 Start code",           "vp8.keyframe.start_code",
528
14
            FT_UINT24, BASE_HEX, NULL, BIT_3BYTE_NO_MASK,
529
14
            NULL, HFILL }
530
14
        },
531
14
        { &hf_vp8_keyframe_width,
532
14
            { "Width",           "vp8.keyframe.width",
533
14
            FT_UINT16, BASE_DEC, NULL, BIT_2BYTE_NO_MASK,
534
14
            NULL, HFILL }
535
14
        },
536
14
        { &hf_vp8_keyframe_height,
537
14
            { "Height",           "vp8.keyframe.height",
538
14
            FT_UINT16, BASE_DEC, NULL, BIT_2BYTE_NO_MASK,
539
14
            NULL, HFILL }
540
14
        },
541
14
        { &hf_vp8_keyframe_horizontal_scale,
542
14
            { "Horizontal Scale",           "vp8.keyframe.horizontal_scale",
543
14
            FT_UINT8, BASE_DEC, NULL, BIT_12_MASK,
544
14
            NULL, HFILL }
545
14
        },
546
14
        { &hf_vp8_keyframe_vertical_scale,
547
14
            { "Vertical Scale",           "vp8.keyframe.vertical_scale",
548
14
            FT_UINT8, BASE_DEC, NULL, BIT_12_MASK,
549
14
            NULL, HFILL }
550
14
        }
551
552
14
    };
553
554
14
    static ei_register_info ei[] = {
555
14
        { &ei_vp8_startcode, { "vp8.keyframe.startcode", PI_PROTOCOL, PI_ERROR, "Startcode is incorrect", EXPFILL }},
556
14
        { &ei_vp8_undecoded, { "vp8.undecoded", PI_UNDECODED, PI_NOTE, "Payload not fully decoded", EXPFILL }},
557
14
        { &ei_vp8_continuation, { "vp8.continuation", PI_REASSEMBLE, PI_CHAT, "Continuation of partition fragment", EXPFILL }},
558
14
        { &ei_vp8_first_partition_split, { "vp8.first_partition_split", PI_REASSEMBLE, PI_CHAT, "First partition is split", EXPFILL }},
559
14
        { &ei_vp8_first_partition_plus, { "vp8.first_partition_plus", PI_REASSEMBLE, PI_CHAT, "This frame contains all of first partition and also bytes from other partitions", EXPFILL }},
560
14
    };
561
562
14
    proto_vp8 = proto_register_protocol (
563
14
        "VP8", /* name       */
564
14
        "VP8",      /* short name */
565
14
        "vp8"       /* abbrev     */
566
14
        );
567
568
14
    proto_register_field_array(proto_vp8, hf, array_length(hf));
569
14
    proto_register_subtree_array(ett, array_length(ett));
570
571
14
    vp8_module = prefs_register_protocol(proto_vp8, NULL);
572
573
14
    expert_vp8 = expert_register_protocol(proto_vp8);
574
14
    expert_register_field_array(expert_vp8, ei, array_length(ei));
575
576
14
    prefs_register_obsolete_preference(vp8_module, "dynamic.payload.type");
577
578
14
    vp8_handle = register_dissector("vp8", dissect_vp8, proto_vp8);
579
14
}
580
581
void
582
proto_reg_handoff_vp8(void)
583
14
{
584
14
    dissector_add_string("rtp_dyn_payload_type" , "VP8", vp8_handle);
585
586
14
    dissector_add_uint_range_with_preference("rtp.pt", "", vp8_handle);
587
14
}
588
589
/*
590
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
591
 *
592
 * Local variables:
593
 * c-basic-offset: 4
594
 * tab-width: 8
595
 * indent-tabs-mode: nil
596
 * End:
597
 *
598
 * vi: set shiftwidth=4 tabstop=8 expandtab:
599
 * :indentSize=4:tabSize=8:noTabs=true:
600
 */