There's no need to keep a "FILE *" for the file being printed to in a
[obnox/wireshark/wip.git] / packet-h263.c
1 /* packet-h263.c
2  *
3  * Routines for ITU-T Recommendation H.263 dissection
4  *
5  * Copyright 2003 Niklas Ă–gren <niklas.ogren@7l.se>
6  * Seven Levels Consultants AB
7  *
8  * $Id: packet-h263.c,v 1.4 2003/08/25 21:48:44 guy Exp $
9  *
10  * Ethereal - Network traffic analyzer
11  * By Gerald Combs <gerald@ethereal.com>
12  * Copyright 1998 Gerald Combs
13  *
14  * Copied structure from packet-h261.c
15  *
16  * This program is free software; you can redistribute it and/or
17  * modify it under the terms of the GNU General Public License
18  * as published by the Free Software Foundation; either version 2
19  * of the License, or (at your option) any later version.
20  *
21  * This program is distributed in the hope that it will be useful,
22  * but WITHOUT ANY WARRANTY; without even the implied warranty of
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24  * GNU General Public License for more details.
25  *
26  * You should have received a copy of the GNU General Public License
27  * along with this program; if not, write to the Free Software
28  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
29  */
30
31 /*
32  * This dissector tries to dissect the H.263 protocol according to
33  * ITU-T Recommendations and RFC 2190
34  */
35
36
37 #ifdef HAVE_CONFIG_H
38 # include "config.h"
39 #endif
40
41 #include <glib.h>
42 #include <epan/packet.h>
43
44 #include <stdio.h>
45 #include <string.h>
46
47 #include "rtp_pt.h"
48
49 /* H.263 header fields             */
50 static int proto_h263          = -1;
51
52 /* Mode A header */
53 static int hf_h263_ftype = -1;
54 static int hf_h263_pbframes = -1;
55 static int hf_h263_sbit = -1;
56 static int hf_h263_ebit = -1;
57 static int hf_h263_srcformat = -1;
58 static int hf_h263_picture_coding_type = -1;    
59 static int hf_h263_unrestricted_motion_vector = -1;
60 static int hf_h263_syntax_based_arithmetic = -1;
61 static int hf_h263_advanced_prediction = -1;
62 static int hf_h263_r = -1;
63 static int hf_h263_rr = -1;
64 static int hf_h263_dbq = -1;
65 static int hf_h263_trb = -1;
66 static int hf_h263_tr = -1;
67 /* Additional fields for Mode B or C header */
68 static int hf_h263_quant = -1;
69 static int hf_h263_gobn = -1;
70 static int hf_h263_mba = -1;
71 static int hf_h263_hmv1 = -1;
72 static int hf_h263_vmv1 = -1;
73 static int hf_h263_hmv2 = -1;
74 static int hf_h263_vmv2 = -1;
75
76 static int hf_h263_data        = -1;
77
78 /* Source format types */
79 #define SRCFORMAT_FORB   0  /* forbidden */
80 #define SRCFORMAT_SQCIF  1
81 #define SRCFORMAT_QCIF   2
82 #define SRCFORMAT_CIF    3
83 #define SRCFORMAT_4CIF   4
84 #define SRCFORMAT_16CIF  5
85
86 static const value_string srcformat_vals[] =
87 {
88   { SRCFORMAT_FORB,     "forbidden" },
89   { SRCFORMAT_SQCIF,    "sub-QCIF 128x96" },
90   { SRCFORMAT_QCIF,     "QCIF 176x144" },
91   { SRCFORMAT_CIF,      "CIF 352x288" },
92   { SRCFORMAT_4CIF,     "4CIF 704x576" },
93   { SRCFORMAT_16CIF,    "16CIF 1408x1152" },
94   { 0,          NULL },
95 };
96
97 /* H.263 fields defining a sub tree */
98 static gint ett_h263           = -1;
99
100 static void
101 dissect_h263( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
102 {
103         proto_item *ti            = NULL;
104         proto_tree *h263_tree     = NULL;
105         unsigned int offset       = 0;
106         unsigned int h263_version = 0;
107
108         h263_version = (tvb_get_guint8( tvb, offset ) & 0xc0 ) >> 6;
109
110         if ( check_col( pinfo->cinfo, COL_PROTOCOL ) )   {
111                 col_set_str( pinfo->cinfo, COL_PROTOCOL, "H.263" );
112         }
113
114         if( h263_version == 0x00) {
115           if ( check_col( pinfo->cinfo, COL_INFO) ) {
116             col_append_str( pinfo->cinfo, COL_INFO, " MODE A");
117           }
118         }
119         else if( h263_version == 0x02) {
120           if ( check_col( pinfo->cinfo, COL_INFO) ) {
121             col_append_str( pinfo->cinfo, COL_INFO, " MODE B");
122           }
123         }
124         else if( h263_version == 0x03) {
125           if ( check_col( pinfo->cinfo, COL_INFO) ) {
126             col_append_str( pinfo->cinfo, COL_INFO, " MODE C");
127           }
128         }
129
130         if ( tree ) {
131           ti = proto_tree_add_item( tree, proto_h263, tvb, offset, -1, FALSE );
132           h263_tree = proto_item_add_subtree( ti, ett_h263 );
133
134           /* FBIT 1st octet, 1 bit */
135           proto_tree_add_boolean( h263_tree, hf_h263_ftype, tvb, offset, 1, tvb_get_guint8( tvb, offset ) & 0x80 );
136           /* PBIT 1st octet, 1 bit */
137           proto_tree_add_boolean( h263_tree, hf_h263_pbframes, tvb, offset, 1, tvb_get_guint8( tvb, offset ) & 0x40 );
138           /* SBIT 1st octet, 3 bits */
139           proto_tree_add_uint( h263_tree, hf_h263_sbit, tvb, offset, 1, ( tvb_get_guint8( tvb, offset ) & 0x38 ) >> 3 );
140           /* EBIT 1st octet, 3 bits */
141           proto_tree_add_uint( h263_tree, hf_h263_ebit, tvb, offset, 1, tvb_get_guint8( tvb, offset )  & 0x7 );
142
143           offset++;
144
145           /* SRC 2nd octet, 3 bits */
146           proto_tree_add_uint( h263_tree, hf_h263_srcformat, tvb, offset, 1, tvb_get_guint8( tvb, offset ) >> 5 );
147
148           if(h263_version == 0x00) { /* MODE A */
149             /* I flag, 1 bit */
150             proto_tree_add_boolean( h263_tree, hf_h263_picture_coding_type, tvb, offset, 1, tvb_get_guint8( tvb, offset ) & 0x10 );
151             /* U flag, 1 bit */
152             proto_tree_add_boolean( h263_tree, hf_h263_unrestricted_motion_vector, tvb, offset, 1, tvb_get_guint8( tvb, offset ) & 0x08 );
153             /* S flag, 1 bit */
154             proto_tree_add_boolean( h263_tree, hf_h263_syntax_based_arithmetic, tvb, offset, 1, tvb_get_guint8( tvb, offset ) & 0x04 );
155             /* A flag, 1 bit */
156             proto_tree_add_boolean( h263_tree, hf_h263_advanced_prediction, tvb, offset, 1, tvb_get_guint8( tvb, offset ) & 0x02 );
157
158             /* Reserved 2nd octect, 1 bit + 3rd octect 3 bits */
159             proto_tree_add_uint( h263_tree, hf_h263_r, tvb, offset, 2, ( ( tvb_get_guint8( tvb, offset ) & 0x1 ) << 3 ) + ( ( tvb_get_guint8( tvb, offset + 1 ) & 0xe0 ) >> 5 ) );
160
161             offset++;
162
163             /* DBQ 3 octect, 2 bits */
164             proto_tree_add_uint( h263_tree, hf_h263_dbq, tvb, offset, 1, ( tvb_get_guint8( tvb, offset ) & 0x18 ) >> 3 );
165             /* TRB 3 octect, 3 bits */
166             proto_tree_add_uint( h263_tree, hf_h263_trb, tvb, offset, 1, ( tvb_get_guint8( tvb, offset ) & 0x07 ) );
167
168             offset++;
169             
170             /* TR 4 octect, 8 bits */
171             proto_tree_add_uint( h263_tree, hf_h263_tr, tvb, offset, 1, tvb_get_guint8( tvb, offset ) );
172             
173             offset++;
174
175           } else { /* MODE B or MODE C */
176
177             /* QUANT 2 octect, 5 bits */
178             proto_tree_add_uint( h263_tree, hf_h263_quant, tvb, offset, 1, tvb_get_guint8( tvb, offset ) & 0x1f );
179
180             offset++;
181
182             /* GOBN 3 octect, 5 bits */
183             proto_tree_add_uint( h263_tree, hf_h263_gobn, tvb, offset, 1, ( tvb_get_guint8( tvb, offset ) & 0xf8 ) >> 3);
184             /* MBA 3 octect, 3 bits + 4 octect 6 bits */
185             proto_tree_add_uint( h263_tree, hf_h263_mba, tvb, offset, 2, ( ( tvb_get_guint8( tvb, offset ) & 0x7 ) << 6 ) + ( ( tvb_get_guint8( tvb, offset + 1 ) & 0xfc ) >> 2 ) );
186             
187             offset++;
188
189             /* Reserved 4th octect, 2 bits */
190             proto_tree_add_uint( h263_tree, hf_h263_r, tvb, offset, 1, ( tvb_get_guint8( tvb, offset ) & 0x3 ) );
191
192             offset++;
193
194             /* I flag, 1 bit */
195             proto_tree_add_boolean( h263_tree, hf_h263_picture_coding_type, tvb, offset, 1, tvb_get_guint8( tvb, offset ) & 0x80 );
196             /* U flag, 1 bit */
197             proto_tree_add_boolean( h263_tree, hf_h263_unrestricted_motion_vector, tvb, offset, 1, tvb_get_guint8( tvb, offset ) & 0x40 );
198             /* S flag, 1 bit */
199             proto_tree_add_boolean( h263_tree, hf_h263_syntax_based_arithmetic, tvb, offset, 1, tvb_get_guint8( tvb, offset ) & 0x20 );
200             /* A flag, 1 bit */
201             proto_tree_add_boolean( h263_tree, hf_h263_advanced_prediction, tvb, offset, 1, tvb_get_guint8( tvb, offset ) & 0x10 );
202
203             /* HMV1 5th octect, 4 bits + 6th octect 3 bits*/
204             proto_tree_add_uint( h263_tree, hf_h263_hmv1, tvb, offset, 2,( ( tvb_get_guint8( tvb, offset ) & 0xf ) << 3 ) + ( ( tvb_get_guint8( tvb, offset+1 ) & 0xe0 ) >> 5) );
205
206             offset++;
207             
208             /* VMV1 6th octect, 5 bits + 7th octect 2 bits*/
209             proto_tree_add_uint( h263_tree, hf_h263_vmv1, tvb, offset, 2,( ( tvb_get_guint8( tvb, offset ) & 0x1f ) << 2 ) + ( ( tvb_get_guint8( tvb, offset+1 ) & 0xc0 ) >> 6) );
210             
211             offset++;
212
213             /* HMV2 7th octect, 6 bits + 8th octect 1 bit*/
214             proto_tree_add_uint( h263_tree, hf_h263_hmv2, tvb, offset, 2,( ( tvb_get_guint8( tvb, offset ) & 0x3f ) << 1 ) + ( ( tvb_get_guint8( tvb, offset+1 ) & 0xf0 ) >> 7) );
215             
216             offset++;
217
218             /* VMV2 8th octect, 7 bits*/
219             proto_tree_add_uint( h263_tree, hf_h263_vmv2, tvb, offset, 1, tvb_get_guint8( tvb, offset ) & 0x7f );
220                   
221             offset++;
222
223             if(h263_version == 0x03) { /* MODE C */
224               /* Reserved 9th to 11th octect, 8 + 8 + 3 bits */
225               proto_tree_add_uint( h263_tree, hf_h263_rr, tvb, offset, 3, ( tvb_get_guint8( tvb, offset ) << 11 ) + ( tvb_get_guint8( tvb, offset + 1 ) << 3 ) + ( ( tvb_get_guint8( tvb, offset + 2 ) & 0xe0 ) >> 5 ) );
226
227               offset+=2;
228
229               /* DBQ 11th octect, 2 bits */
230               proto_tree_add_uint( h263_tree, hf_h263_dbq, tvb, offset, 1, ( tvb_get_guint8( tvb, offset ) & 0x18 ) >>3 );
231               /* TRB 11th octect, 3 bits */
232               proto_tree_add_uint( h263_tree, hf_h263_trb, tvb, offset, 1, tvb_get_guint8( tvb, offset ) & 0x07 );
233               
234               offset++;
235               
236               /* TR 12th octect, 8 bits */
237               proto_tree_add_uint( h263_tree, hf_h263_tr, tvb, offset, 1, tvb_get_guint8( tvb, offset ) );
238               
239               offset++;
240             } /* end mode c */
241           } /* end not mode a */
242
243           /* The rest of the packet is the H.263 stream */
244           proto_tree_add_item( h263_tree, hf_h263_data, tvb, offset, -1, FALSE );
245         }
246 }
247
248 void
249 proto_register_h263(void)
250 {
251         static hf_register_info hf[] =
252         {
253                 {
254                         &hf_h263_ftype,
255                         {
256                                 "F",
257                                 "h263.sbit",
258                                 FT_BOOLEAN,
259                                 BASE_NONE,
260                                 NULL,
261                                 0x0,
262                                 "Indicates the mode of the payload header (MODE A or B/C)", HFILL
263                         }
264                 },
265                 {
266                         &hf_h263_pbframes,
267                         {
268                                 "p/b frame",
269                                 "h263.pbframes",
270                                 FT_BOOLEAN,
271                                 BASE_NONE,
272                                 NULL,
273                                 0x0,
274                                 "Optional PB-frames mode as defined by H.263 (MODE C)", HFILL
275                         }
276                 },
277                 {
278                         &hf_h263_sbit,
279                         {
280                                 "Start bit position",
281                                 "h263.sbit",
282                                 FT_UINT8,
283                                 BASE_DEC,
284                                 NULL,
285                                 0x0,
286                                 "Start bit position specifies number of most significant bits that shall be ignored in the first data byte.", HFILL
287                         }
288                 },
289                 {
290                         &hf_h263_ebit,
291                         {
292                                 "End bit position",
293                                 "h263.ebit",
294                                 FT_UINT8,
295                                 BASE_DEC,
296                                 NULL,
297                                 0x0,
298                                 "End bit position specifies number of least significant bits that shall be ignored in the last data byte.", HFILL
299                         }
300                 },
301                 {
302                         &hf_h263_srcformat,
303                         {
304                                 "SRC format",
305                                 "h263.srcformat",
306                                 FT_UINT8,
307                                 BASE_DEC,
308                                 VALS(srcformat_vals),
309                                 0x0,
310                                 "Source format specifies the resolution of the current picture.", HFILL
311                         }
312                 },
313                 {
314                         &hf_h263_picture_coding_type,
315                         {
316                                 "Inter-coded frame",
317                                 "h263.picture_coding_type",
318                                 FT_BOOLEAN,
319                                 BASE_NONE,
320                                 NULL,
321                                 0x0,
322                                 "Picture coding type, intra-coded (false) or inter-coded (true)", HFILL
323                         }
324                 },
325                 {
326                         &hf_h263_unrestricted_motion_vector,
327                         {
328                                 "Motion vector",
329                                 "h263.unrestricted_motion_vector",
330                                 FT_BOOLEAN,
331                                 BASE_NONE,
332                                 NULL,
333                                 0x0,
334                                 "Unrestricted Motion Vector option for current picture", HFILL
335                         }
336                 },
337                 {
338                         &hf_h263_syntax_based_arithmetic,
339                         {
340                                 "Syntax-based arithmetic coding",
341                                 "h263.syntax_based_arithmetic",
342                                 FT_BOOLEAN,
343                                 BASE_NONE,
344                                 NULL,
345                                 0x0,
346                                 "Syntax-based Arithmetic Coding option for current picture", HFILL
347                         }
348                 },
349                 {
350                         &hf_h263_advanced_prediction,
351                         {
352                                 "Advanced prediction option",
353                                 "h263.advanced_prediction",
354                                 FT_BOOLEAN,
355                                 BASE_NONE,
356                                 NULL,
357                                 0x0,
358                                 "Advanced Prediction option for current picture", HFILL
359                         }
360                 },
361                 {
362                         &hf_h263_dbq,
363                         {
364                                 "Differential quantization parameter",
365                                 "h263.dbq",
366                                 FT_UINT8,
367                                 BASE_DEC,
368                                 NULL,
369                                 0x0,
370                                 "Differential quantization parameter used to calculate quantizer for the B frame based on quantizer for the P frame, when PB-frames option is used.", HFILL
371                         }
372                 },
373                 {
374                         &hf_h263_trb,
375                         {
376                                 "Temporal Reference for B frames",
377                                 "h263.trb",
378                                 FT_UINT8,
379                                 BASE_DEC,
380                                 NULL,
381                                 0x0,
382                                 "Temporal Reference for the B frame as defined by H.263", HFILL
383                         }
384                 },
385                 {
386                         &hf_h263_tr,
387                         {
388                                 "Temporal Reference for P frames",
389                                 "h263.tr",
390                                 FT_UINT8,
391                                 BASE_DEC,
392                                 NULL,
393                                 0x0,
394                                 "Temporal Reference for the P frame as defined by H.263", HFILL
395                         }
396                 },
397                 {
398                         &hf_h263_quant,
399                         {
400                                 "Quantizer",
401                                 "h263.quant",
402                                 FT_UINT8,
403                                 BASE_DEC,
404                                 NULL,
405                                 0x0,
406                                 "Quantization value for the first MB coded at the starting of the packet.", HFILL
407                         }
408                 },
409                 {
410                         &hf_h263_gobn,
411                         {
412                                 "GOB Number",
413                                 "h263.gobn",
414                                 FT_UINT8,
415                                 BASE_DEC,
416                                 NULL,
417                                 0x0,
418                                 "GOB number in effect at the start of the packet.", HFILL
419                         }
420                 },
421                 {
422                         &hf_h263_mba,
423                         {
424                                 "Macroblock address",
425                                 "h263.mba",
426                                 FT_UINT16,
427                                 BASE_DEC,
428                                 NULL,
429                                 0x0,
430                                 "The address within the GOB of the first MB in the packet, counting from zero in scan order.", HFILL
431                         }
432                 },
433                 {
434                         &hf_h263_hmv1,
435                         {
436                                 "Horizontal motion vector 1",
437                                 "h263.hmv1",
438                                 FT_UINT8,
439                                 BASE_DEC,
440                                 NULL,
441                                 0x0,
442                                 "Horizontal motion vector predictor for the first MB in this packet ", HFILL
443                         }
444                 },
445                 {
446                         &hf_h263_vmv1,
447                         {
448                                 "Vertical motion vector 1",
449                                 "h263.vmv1",
450                                 FT_UINT8,
451                                 BASE_DEC,
452                                 NULL,
453                                 0x0,
454                                 "Vertical motion vector predictor for the first MB in this packet ", HFILL
455                         }
456                 },
457                 {
458                         &hf_h263_hmv2,
459                         {
460                                 "Horizontal motion vector 2",
461                                 "h263.hmv2",
462                                 FT_UINT8,
463                                 BASE_DEC,
464                                 NULL,
465                                 0x0,
466                                 "Horizontal motion vector predictor for block number 3 in the first MB in this packet when four motion vectors are used with the advanced prediction option.", HFILL
467                         }
468                 },
469                 {
470                         &hf_h263_vmv2,
471                         {
472                                 "Vertical motion vector 2",
473                                 "h263.vmv2",
474                                 FT_UINT8,
475                                 BASE_DEC,
476                                 NULL,
477                                 0x0,
478                                 "Vertical motion vector predictor for block number 3 in the first MB in this packet when four motion vectors are used with the advanced prediction option.", HFILL
479                         }
480                 },
481                 {
482                         &hf_h263_r,
483                         {
484                                 "Reserved field",
485                                 "h263.r",
486                                 FT_UINT8,
487                                 BASE_DEC,
488                                 NULL,
489                                 0x0,
490                                 "Reserved field that houls contain zeroes", HFILL
491                         }
492                 },
493                 {
494                         &hf_h263_rr,
495                         {
496                                 "Reserved field 2",
497                                 "h263.rr",
498                                 FT_UINT16,
499                                 BASE_DEC,
500                                 NULL,
501                                 0x0,
502                                 "Reserved field that should contain zeroes", HFILL
503                         }
504                 },
505                 {
506                         &hf_h263_data,
507                         {
508                                 "H.263 stream",
509                                 "h263.stream",
510                                 FT_BYTES,
511                                 BASE_NONE,
512                                 NULL,
513                                 0x0,
514                                 "The H.263 stream including its Picture, GOB or Macro block start code.", HFILL
515                         }
516                 },
517 };
518
519         static gint *ett[] =
520         {
521                 &ett_h263,
522         };
523
524
525         proto_h263 = proto_register_protocol("ITU-T Recommendation H.263 RTP Payload header (RFC2190)",
526             "H.263", "h263");
527         proto_register_field_array(proto_h263, hf, array_length(hf));
528         proto_register_subtree_array(ett, array_length(ett));
529 }
530
531 void
532 proto_reg_handoff_h263(void)
533 {
534         dissector_handle_t h263_handle;
535
536         h263_handle = create_dissector_handle(dissect_h263, proto_h263);
537         dissector_add("rtp.pt", PT_H263, h263_handle);
538 }