Common handling of picture layer.
authoretxrab <etxrab@f5534014-38df-0310-8fa8-9805f1628bb7>
Tue, 27 Mar 2007 21:10:35 +0000 (21:10 +0000)
committeretxrab <etxrab@f5534014-38df-0310-8fa8-9805f1628bb7>
Tue, 27 Mar 2007 21:10:35 +0000 (21:10 +0000)
git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@21229 f5534014-38df-0310-8fa8-9805f1628bb7

epan/dissectors/packet-h263.c

index 5c40209037321d3c297597ae91016437f18ba91f..13db67b5d5267037c0035a4bfed3a9319d8ac942 100644 (file)
@@ -45,6 +45,7 @@
 #include <stdio.h>
 #include <string.h>
 
+#include <epan/emem.h>
 #include <epan/rtp_pt.h>
 #include <epan/iax2_codec_type.h>
 
@@ -91,9 +92,11 @@ static int hf_h263_opt_unres_motion_vector_mode = -1;
 static int hf_h263_syntax_based_arithmetic_coding_mode = -1;
 static int hf_h263_optional_advanced_prediction_mode = -1;
 static int hf_h263_PB_frames_mode = -1;
-static int hf_h263_data        = -1;
-static int hf_h263_payload     = -1;
-static int hf_h263_GN          = -1;
+static int hf_h263_data                        = -1;
+static int hf_h263_payload             = -1;
+static int hf_h263_GN                  = -1;
+static int hf_h263_UFEP                        = -1;
+static int hf_h263_opptype             = -1;
 
 
 /* H.263 RFC 4629 fields */
@@ -111,21 +114,31 @@ static int hf_h263P_PSC = -1;
 static int hf_h263P_TR = -1;
 
 /* Source format types */
-#define SRCFORMAT_FORB   0  /* forbidden */
-#define SRCFORMAT_SQCIF  1
-#define SRCFORMAT_QCIF   2
-#define SRCFORMAT_CIF    3
-#define SRCFORMAT_4CIF   4
-#define SRCFORMAT_16CIF  5
+#define H263_SRCFORMAT_FORB            0  /* forbidden */
+#define H263_SRCFORMAT_SQCIF   1
+#define H263_SRCFORMAT_QCIF            2
+#define H263_SRCFORMAT_CIF             3
+#define H263_SRCFORMAT_4CIF            4
+#define H263_SRCFORMAT_16CIF   5
+#define H263_PLUSPTYPE                 7
 
 static const value_string srcformat_vals[] =
 {
-  { SRCFORMAT_FORB,            "forbidden" },
-  { SRCFORMAT_SQCIF,   "sub-QCIF 128x96" },
-  { SRCFORMAT_QCIF,            "QCIF 176x144" },
-  { SRCFORMAT_CIF,             "CIF 352x288" },
-  { SRCFORMAT_4CIF,            "4CIF 704x576" },
-  { SRCFORMAT_16CIF,   "16CIF 1408x1152" },
+  { H263_SRCFORMAT_FORB,               "forbidden" },
+  { H263_SRCFORMAT_SQCIF,              "sub-QCIF 128x96" },
+  { H263_SRCFORMAT_QCIF,               "QCIF 176x144" },
+  { H263_SRCFORMAT_CIF,                        "CIF 352x288" },
+  { H263_SRCFORMAT_4CIF,               "4CIF 704x576" },
+  { H263_SRCFORMAT_16CIF,              "16CIF 1408x1152" },
+  { 6,                                                 "Reserved",},
+  { H263_PLUSPTYPE,                            "extended PTYPE" },
+  { 0,         NULL },
+};
+
+static const value_string h263_ufep_vals[] =
+{
+  { 0,         "Only MPPTYPE included" },
+  { 1,         "All extended PTYPE fields are included" },
   { 0,         NULL },
 };
 
@@ -153,9 +166,11 @@ static const true_false_string PB_frames_mode_flg = {
 /* H.263 fields defining a sub tree */
 static gint ett_h263                   = -1;
 static gint ett_h263_payload   = -1;
+static gint ett_h263_optype            = -1;
 
 /* H.263-1998 fields defining a sub tree */
 static gint ett_h263P                  = -1;
+static gint ett_h263P_extra_hdr = -1;
 static gint ett_h263P_payload  = -1;
 static gint ett_h263P_data = -1;
 
@@ -310,23 +325,349 @@ dissect_h263( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
        }
 }
 
+#define cVALS(x) (const value_string*)(x)
+
+proto_item *
+h263_proto_tree_add_bits(proto_tree *tree, int hf_index, tvbuff_t *tvb, gint bit_offset, gint no_of_bits)
+{
+       gint offset;
+       guint length;
+       char *str;
+       header_field_info *hfinfo;
+       guint32 value = 0;
+       int bit;
+       guint32 mask, tmp;
+       gboolean is_bytealigned = FALSE;
+       guint8 mask8    = 0xff;
+       guint16 mask16  = 0xffff;
+       guint32 mask24  = 0xffffff;
+       guint32 mask32  = 0xffffffff;
+       guint8 shift;
+       int i;
+       const char *format = NULL;
+
+       if((bit_offset&0x7)==0)
+               is_bytealigned = TRUE;
+
+       hfinfo = proto_registrar_get_nth(hf_index);
+
+       offset = bit_offset>>3;
+       length = ((bit_offset&0x7)+no_of_bits)>>3;
+       length = length +1;
+
+       if (no_of_bits < 2){
+               /* Single bit */
+               mask8 = mask8 >>(bit_offset&0x7);
+               value = tvb_get_guint8(tvb,offset) & mask8;
+               mask = 0x80;
+               shift = 8-((bit_offset + no_of_bits)&0x7);
+               value = value >> shift;
+               mask = mask >> shift;
+       }else if(no_of_bits < 9){
+               /* One or 2 bytes */
+               if(length == 1){
+                       /* Spans 1 byte */
+                       mask8 = mask8>>(bit_offset&0x7);
+                       value = tvb_get_guint8(tvb,offset)&mask8;
+                       mask = 0x80;
+               }else{
+                       /* Spans 2 bytes */     
+                       mask16 = mask16>>(bit_offset&0x7);
+                       value = tvb_get_ntohs(tvb,offset) & mask16;
+                       mask = 0x8000;
+               }
+               shift = 8-((bit_offset + no_of_bits)&0x7);
+               value = value >> shift;
+               mask = mask >> shift;
+               
+       }else if (no_of_bits < 17){
+               /* 2 or 3 bytes */
+               if(length == 2){
+                       /* Spans 2 bytes */
+                       mask16 = mask16>>(bit_offset&0x7);
+                       value = tvb_get_ntohs(tvb,offset) & mask16;
+                       mask = 0x8000;
+               }else{
+                       /* Spans 3 bytes */     
+                       mask24 = mask24>>(bit_offset&0x7);
+                       value = tvb_get_ntoh24(tvb,offset) & mask24;
+                       mask = 0x800000;
+               }
+               shift = 8-((bit_offset + no_of_bits)&0x7);
+
+               value = value >> shift;
+               mask = mask >> shift;
+
+       }else if (no_of_bits < 25){
+               /* 3 or 4 bytes */
+               if(length == 3){
+                       /* Spans 3 bytes */
+                       mask24 = mask24>>(bit_offset&0x7);
+                       value = tvb_get_ntoh24(tvb,offset) & mask24;
+                       mask = 0x800000;
+               }else{
+                       /* Spans 4 bytes */     
+                       mask32 = mask32>>(bit_offset&0x7);
+                       value = tvb_get_ntohl(tvb,offset) & mask32;
+                       mask = 0x80000000;
+               }
+               shift = 8-((bit_offset + no_of_bits)&0x7);
+
+               value = value >> shift;
+               mask = mask >> shift;
+
+       }else if (no_of_bits < 33){
+               /* 4 or 5 bytes */
+               if(length == 4){
+                       /* Spans 4 bytes */     
+                       mask32 = mask32>>(bit_offset&0x7);
+                       value = tvb_get_ntohl(tvb,offset) & mask32;
+                       mask = 0x80000000;
+               }else{
+                       /* Spans 5 bytes
+                        * Does not handle unaligned bits over 24
+                        */
+                       DISSECTOR_ASSERT_NOT_REACHED();
+               }
+               shift = 8-((bit_offset + no_of_bits)&0x7);
+
+               value = value >> shift;
+               mask = mask >> shift;
+
+       }else{
+               g_assert_not_reached();
+       }
+
+       /* prepare the string */
+       str=ep_alloc(256);
+       g_snprintf(str, 256, "");
+       for(bit=0;bit<((int)(bit_offset&0x07));bit++){
+               if(bit&&(!(bit%4))){
+                       strcat(str, " ");
+               }
+               strcat(str,".");
+               mask = mask>>1;
+       }
+       /* read the bits for the int */
+       for(i=0;i<no_of_bits;i++){
+               if(bit&&(!(bit%4))){
+                       strcat(str, " ");
+               }
+               if(bit&&(!(bit%8))){
+                       strcat(str, " ");
+               }
+               bit++;
+               tmp = value & mask;
+               if(tmp != 0){
+                       strcat(str, "1");
+               } else {
+                       strcat(str, "0");
+               }
+               mask = mask>>1;
+       }
+       for(;bit%8;bit++){
+               if(bit&&(!(bit%4))){
+                       strcat(str, " ");
+               }
+               strcat(str,".");
+       }
+
+
+       strcat(str," = ");
+       strcat(str,hfinfo->name);
+       if (no_of_bits== 1){
+               /* Boolean field */
+               if (hfinfo->strings) {
+                       const true_false_string         *tfstring = &tfs_true_false;
+                       tfstring = (const struct true_false_string*) hfinfo->strings;
+
+                       return proto_tree_add_boolean_format(tree, hf_index, tvb, offset, length, value,
+                               "%s: %s",
+                               str,
+                               value ? tfstring->true_string : tfstring->false_string);
+               }
+
+       }
+       /* 2 - 32 bits field */
+
+       if (hfinfo->strings) {
+               return proto_tree_add_uint_format(tree, hf_index, tvb, offset, length, value,
+                      "%s: %s",
+                                         str,
+                                         val_to_str(value, cVALS(hfinfo->strings), "Unknown"), value);
+       }
+       switch(hfinfo->display){
+       case BASE_DEC:
+               return proto_tree_add_uint_format(tree, hf_index, tvb, offset, length, value,
+                        "%s: %u",
+                                         str,
+                                         value);
+               break;
+       case BASE_HEX:
+               return proto_tree_add_uint_format(tree, hf_index, tvb, offset, length, value,
+                        "%s: %x",
+                                         str,
+                                         value);
+               break;
+       default:
+               DISSECTOR_ASSERT_NOT_REACHED();
+               return NULL;
+               ;
+       }
+
+}
+
+/*
+ * Length is used for the "Extra header" otherwise set to -1.
+ */
+int
+dissect_h263_picture_layer( tvbuff_t *tvb, proto_tree *tree, gint offset, gint length, gboolean is_rfc4626)
+{
+       proto_tree *h263_opptype_tree   = NULL;
+       proto_item *opptype_item                = NULL;
+       unsigned int offset_in_bits             = offset << 3;
+       guint8 source_format;
+       guint16 ufep;
+
+       if(is_rfc4626){
+               /* PC 1000 00xx */ 
+               h263_proto_tree_add_bits(tree, hf_h263_psc, tvb, offset_in_bits, 6);
+               offset_in_bits = offset_in_bits +6;
+
+       }else{
+       /* Check for PSC, PSC is a word of 22 bits. 
+        * Its value is 0000 0000 0000 0000' 1000 00xx xxxx xxxx.
+        */
+               h263_proto_tree_add_bits(tree, hf_h263_psc, tvb, offset_in_bits, 22);
+               offset_in_bits = offset_in_bits +22;
+
+       }
+       h263_proto_tree_add_bits(tree, hf_h263_TR, tvb, offset_in_bits, 8);
+       offset_in_bits = offset_in_bits +8;
+       /*
+        * Bit 1: Always "1", in order to avoid start code emulation. 
+        * Bit 2: Always "0", for distinction with Recommendation H.261.
+        */
+       offset_in_bits = offset_in_bits +2;
+       /* Bit 3: Split screen indicator, "0" off, "1" on. */
+       h263_proto_tree_add_bits( tree, hf_h263_split_screen_indicator, tvb, offset_in_bits, 1);
+       offset_in_bits++;
+       /* Bit 4: Document camera indicator, */
+       h263_proto_tree_add_bits( tree, hf_h263_document_camera_indicator, tvb, offset_in_bits, 1);
+       offset_in_bits++;
+       /* Bit 5: Full Picture Freeze Release, "0" off, "1" on. */
+       h263_proto_tree_add_bits( tree, hf_h263_full_picture_freeze_release, tvb, offset_in_bits, 1);
+       offset_in_bits++;
+       /* Bits 6-8: Source Format, "000" forbidden, "001" sub-QCIF, "010" QCIF, "011" CIF,
+        * "100" 4CIF, "101" 16CIF, "110" reserved, "111" extended PTYPE.
+        */
+       h263_proto_tree_add_bits( tree, hf_h263_source_format, tvb, offset_in_bits, 3);
+       offset_in_bits = offset_in_bits +3;
+       source_format = (tvb_get_guint8(tvb,(offset_in_bits>>3)& 0x1c)>>2);
+       if (source_format != H263_PLUSPTYPE){
+               /* Not extended PTYPE */
+               /* Bit 9: Picture Coding Type, "0" INTRA (I-picture), "1" INTER (P-picture). */
+               h263_proto_tree_add_bits( tree, hf_h263_payload_picture_coding_type, tvb, offset_in_bits, 1);
+               offset_in_bits++;
+               /* Bit 10: Optional Unrestricted Motion Vector mode (see Annex D), "0" off, "1" on. */
+               h263_proto_tree_add_bits( tree, hf_h263_opt_unres_motion_vector_mode, tvb, offset_in_bits, 1);
+               offset_in_bits++;
+               /* Bit 11: Optional Syntax-based Arithmetic Coding mode (see Annex E), "0" off, "1" on.*/
+               h263_proto_tree_add_bits( tree, hf_h263_syntax_based_arithmetic_coding_mode, tvb, offset_in_bits, 1);
+               offset_in_bits++;
+               /* Bit 12: Optional Advanced Prediction mode (see Annex F), "0" off, "1" on.*/
+               h263_proto_tree_add_bits( tree, hf_h263_optional_advanced_prediction_mode, tvb, offset_in_bits, 1);
+               offset_in_bits++;
+               /* Bit 13: Optional PB-frames mode (see Annex G), "0" normal I- or P-picture, "1" PB-frame.*/
+               h263_proto_tree_add_bits( tree, hf_h263_PB_frames_mode, tvb, offset_in_bits, 1);
+               offset_in_bits++;
+       }else{
+               /* Extended PTYPE 
+                * Update Full Extended PTYPE (UFEP) (3 bits)
+                */
+               ufep = (tvb_get_ntohs(tvb,offset)&0x0380)>>7;
+               /* .... ..xx x... .... */
+               h263_proto_tree_add_bits( tree, hf_h263_UFEP, tvb, offset_in_bits, 3);
+               offset_in_bits = offset_in_bits +3;
+               if(ufep==1){
+                       /* The Optional Part of PLUSPTYPE (OPPTYPE) (18 bits) 
+                        */
+                        /*  .xxx xxxx  xxxx xxxx  xxx. .... */
+                       opptype_item = h263_proto_tree_add_bits( tree, hf_h263_opptype, tvb, offset_in_bits, 18);
+                       h263_opptype_tree = proto_item_add_subtree( opptype_item, ett_h263_optype );
+                       /*
+                        * If UFEP is "001", then the following bits are present in PLUSPTYPE:
+                        *  Bits 1-3 Source Format, "000" reserved, "001" sub-QCIF, "010" QCIF, "011" CIF,
+                        * "100" 4CIF, "101" 16CIF, "110" custom source format, "111" reserved;
+                        */
+                       h263_proto_tree_add_bits( h263_opptype_tree, hf_h263_source_format, tvb, offset_in_bits, 3);
+                       offset_in_bits = offset_in_bits +3;
+                       offset_in_bits = offset_in_bits +15;/* 18-3 */
+                       /*
+                        *  Bit 4 Optional Custom PCF, "0" CIF PCF, "1" custom PCF;
+                        *  Bit 5 Optional Unrestricted Motion Vector (UMV) mode (see Annex D), "0" off, "1" on;
+                        *  Bit 6 Optional Syntax-based Arithmetic Coding (SAC) mode (see Annex E), "0" off, "1" on;
+                        *  Bit 7 Optional Advanced Prediction (AP) mode (see Annex F), "0" off, "1" on;
+                        *  Bit 8 Optional Advanced INTRA Coding (AIC) mode (see Annex I), "0" off, "1" on;
+                        *  Bit 9 Optional Deblocking Filter (DF) mode (see Annex J), "0" off, "1" on;
+                        *  Bit 10 Optional Slice Structured (SS) mode (see Annex K), "0" off, "1" on;
+                        *  Bit 11 Optional Reference Picture Selection (RPS) mode (see Annex N), "0" off, "1" on;
+                        *  Bit 12 Optional Independent Segment Decoding (ISD) mode (see Annex R), "0" off,"1" on;
+                        *  Bit 13 Optional Alternative INTER VLC (AIV) mode (see Annex S), "0" off, "1" on;
+                        *  Bit 14 Optional Modified Quantization (MQ) mode (see Annex T), "0" off, "1" on;
+                        *  Bit 15 Equal to "1" to prevent start code emulation;
+                        *  Bit 16 Reserved, shall be equal to "0";
+                        *  Bit 17 Reserved, shall be equal to "0";
+                        *  Bit 18 Reserved, shall be equal to "0".
+                        */
+               }
+               /*
+                * 5.1.4.3 The mandatory part of PLUSPTYPE when PLUSPTYPE present (MPPTYPE) (9 bits)
+                * Regardless of the value of UFEP, the following 9 bits are also present in PLUSPTYPE:
+                * \96 Bits 1-3 Picture Type Code:
+                * "000" I-picture (INTRA);
+                * "001" P-picture (INTER);
+                * "010" Improved PB-frame (see Annex M);
+                * "011" B-picture (see Annex O);
+                * "100" EI-picture (see Annex O);
+                * "101" EP-picture (see Annex O);
+                * "110" Reserved;
+                * "111" Reserved;
+                * \96 Bit 4 Optional Reference Picture Resampling (RPR) mode (see Annex P), "0" off, "1" on;
+                * \96 Bit 5 Optional Reduced-Resolution Update (RRU) mode (see Annex Q), "0" off, "1" on;
+                * \96 Bit 6 Rounding Type (RTYPE) (see 6.1.2);
+                * \96 Bit 7 Reserved, shall be equal to "0";
+                * \96 Bit 8 Reserved, shall be equal to "0";
+                * \96 Bit 9 Equal to "1" to prevent start code emulation.
+                */
+               offset_in_bits = offset_in_bits +9;
+       }
+
+       return offset_in_bits>>3;
+
+}
+
 /* RFC 4629 */
 static void
 dissect_h263P( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
 {
-       proto_item *ti                          = NULL;
-       proto_item *data_item           = NULL;
-       proto_tree *h263P_tree          = NULL;
+       proto_item *ti                                  = NULL;
+       proto_item *data_item                   = NULL;
+       proto_item *extra_hdr_item              = NULL;
+       proto_tree *h263P_tree                  = NULL;
+       proto_tree *h263P_extr_hdr_tree = NULL;
        proto_tree *h263P_data_tree             = NULL;
-       unsigned int offset                     = 0;
+       unsigned int offset                             = 0;
+       unsigned int start_offset               = 0;
        guint16 data16, plen;
        guint8 octet;
+
        /*
        tvbuff_t *next_tvb;
        */
 
        if ( check_col( pinfo->cinfo, COL_PROTOCOL ) )   {
-               col_set_str( pinfo->cinfo, COL_PROTOCOL, "H.263-1998 " );
+               col_set_str( pinfo->cinfo, COL_PROTOCOL, "H.263 RFC4629 " );
        }
 
        if ( tree ) {
@@ -389,11 +730,16 @@ dissect_h263P( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
                  offset++;
          }
 
+         /* Length, in bytes, of the extra picture header. */
          plen = (data16 & 0x01f8) >> 3;
          if (plen != 0){
-                 /* Length, in bytes, of the extra picture header. */
-                 proto_tree_add_item( h263P_tree, hf_h263P_extra_hdr, tvb, offset, plen, FALSE );
-                 offset = offset + plen;               
+                 start_offset = offset;
+                 extra_hdr_item = proto_tree_add_item( h263P_tree, hf_h263P_extra_hdr, tvb, offset, plen, FALSE );
+                 h263P_extr_hdr_tree = proto_item_add_subtree( extra_hdr_item, ett_h263P_extra_hdr );
+                 
+                 dissect_h263_picture_layer( tvb, h263P_extr_hdr_tree, offset, plen, TRUE);
+
+                 offset = start_offset + plen;         
          }
          if ((data16&0x0400)!=0){
                  /* P bit = 1 */
@@ -407,47 +753,14 @@ dissect_h263P( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
                        if ( check_col( pinfo->cinfo, COL_INFO) )
                                col_append_str( pinfo->cinfo, COL_INFO, "(PSC) ");
 
-                       proto_tree_add_item( h263P_data_tree, hf_h263P_PSC, tvb, offset, 2, FALSE );
-                       proto_tree_add_item( h263P_data_tree, hf_h263P_TR, tvb, offset, 2, FALSE );
-                       /*
-                        * Bit 1: Always "1", in order to avoid start code emulation. 
-                        * Bit 2: Always "0", for distinction with Recommendation H.261.
-                        */
-                        offset = offset + 2;
-                        /* Bit 3: Split screen indicator, "0" off, "1" on. */
-                        proto_tree_add_item( h263P_data_tree, hf_h263_split_screen_indicator, tvb, offset, 1, FALSE );
-                        /* Bit 4: Document camera indicator, */
-                        proto_tree_add_item( h263P_data_tree, hf_h263_document_camera_indicator, tvb, offset, 1, FALSE );
-                        /* Bit 5: Full Picture Freeze Release, "0" off, "1" on. */
-                        proto_tree_add_item( h263P_data_tree, hf_h263_full_picture_freeze_release, tvb, offset, 1, FALSE );
-                        /* Bits 6-8: Source Format, "000" forbidden, "001" sub-QCIF, "010" QCIF, "011" CIF,
-                         * "100" 4CIF, "101" 16CIF, "110" reserved, "111" extended PTYPE.
-                         */
-                        proto_tree_add_item( h263P_data_tree, hf_h263_source_format, tvb, offset, 1, TRUE );
-                        octet = tvb_get_guint8(tvb,offset);
-                        if (( octet & 0x1c) != 0x1c){
-                                /* Not extended PTYPE */
-                                /* Bit 9: Picture Coding Type, "0" INTRA (I-picture), "1" INTER (P-picture). */
-                                proto_tree_add_item( h263P_data_tree, hf_h263_payload_picture_coding_type, tvb, offset, 1, FALSE );
-                                if ( check_col( pinfo->cinfo, COL_INFO) )
-                                        col_append_fstr(pinfo->cinfo, COL_INFO, val_to_str((octet & 0x02)>>1, picture_coding_type_vals, "Unknown (%u)"));
-
-                                /* Bit 10: Optional Unrestricted Motion Vector mode (see Annex D), "0" off, "1" on. */
-                                proto_tree_add_item( h263P_data_tree, hf_h263_opt_unres_motion_vector_mode, tvb, offset, 1, FALSE );
-                                offset++;
-                                /* Bit 11: Optional Syntax-based Arithmetic Coding mode (see Annex E), "0" off, "1" on.*/
-                                proto_tree_add_item( h263P_data_tree, hf_h263_syntax_based_arithmetic_coding_mode, tvb, offset, 1, FALSE );
-                                /* Bit 12: Optional Advanced Prediction mode (see Annex F), "0" off, "1" on.*/
-                                proto_tree_add_item( h263P_data_tree, hf_h263_optional_advanced_prediction_mode, tvb, offset, 1, FALSE );
-                                /* Bit 13: Optional PB-frames mode (see Annex G), "0" normal I- or P-picture, "1" PB-frame.*/
-                                proto_tree_add_item( h263P_data_tree, hf_h263_PB_frames_mode, tvb, offset, 1, FALSE );
-                        }
-                        return;
+                       offset = dissect_h263_picture_layer( tvb, h263P_data_tree, offset, -1, TRUE);
+                       return;
                  }else{
                          /*
                        if ( check_col( pinfo->cinfo, COL_INFO) )
                          col_append_str( pinfo->cinfo, COL_INFO, "(GBSC) ");
                          */
+                         return;
                  }
          }
          proto_tree_add_item( h263P_tree, hf_h263P_payload, tvb, offset, -1, FALSE );
@@ -473,7 +786,6 @@ static void dissect_h263_data( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
        proto_item *h263_payload_item   = NULL;
        proto_tree *h263_payload_tree   = NULL;
        guint32 data;
-       guint8 octet;
 
        if ( check_col( pinfo->cinfo, COL_INFO) ) {
          col_append_str( pinfo->cinfo, COL_INFO, "H263 payload ");
@@ -492,42 +804,7 @@ static void dissect_h263_data( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
                        if ( check_col( pinfo->cinfo, COL_INFO) )
                          col_append_str( pinfo->cinfo, COL_INFO, "(PSC) ");
                        if( tree ) {
-                         proto_tree_add_uint(h263_payload_tree, hf_h263_psc,tvb, offset,3,data);
-                         offset = offset + 2;
-                         proto_tree_add_uint(h263_payload_tree, hf_h263_TR,tvb, offset,2,data);
-                         /* Last two bits in the 32 bits fetched
-                          * Bit 1: Always "1", in order to avoid start code emulation. 
-                          * Bit 2: Always "0", for distinction with Recommendation H.261.
-                          */
-                         offset = offset + 2;
-                         /* Bit 3: Split screen indicator, "0" off, "1" on. */
-                         proto_tree_add_item( h263_payload_tree, hf_h263_split_screen_indicator, tvb, offset, 1, FALSE );
-                         /* Bit 4: Document camera indicator, */
-                         proto_tree_add_item( h263_payload_tree, hf_h263_document_camera_indicator, tvb, offset, 1, FALSE );
-                         /* Bit 5: Full Picture Freeze Release, "0" off, "1" on. */
-                         proto_tree_add_item( h263_payload_tree, hf_h263_full_picture_freeze_release, tvb, offset, 1, FALSE );
-                         /* Bits 6-8: Source Format, "000" forbidden, "001" sub-QCIF, "010" QCIF, "011" CIF,
-                          * "100" 4CIF, "101" 16CIF, "110" reserved, "111" extended PTYPE.
-                          */
-                         proto_tree_add_item( h263_payload_tree, hf_h263_source_format, tvb, offset, 1, TRUE );
-                         octet = tvb_get_guint8(tvb,offset);
-                         if (( octet & 0x1c) != 0x1c){
-                                 /* Not extended PTYPE */
-                                 /* Bit 9: Picture Coding Type, "0" INTRA (I-picture), "1" INTER (P-picture). */
-                                 proto_tree_add_item( h263_payload_tree, hf_h263_payload_picture_coding_type, tvb, offset, 1, FALSE );
-                                 if ( check_col( pinfo->cinfo, COL_INFO) )
-                                        col_append_fstr(pinfo->cinfo, COL_INFO, val_to_str((octet & 0x02)>>1, picture_coding_type_vals, "Unknown (%u)"));
-
-                                 /* Bit 10: Optional Unrestricted Motion Vector mode (see Annex D), "0" off, "1" on. */
-                                 proto_tree_add_item( h263_payload_tree, hf_h263_opt_unres_motion_vector_mode, tvb, offset, 1, FALSE );
-                                 offset++;
-                                 /* Bit 11: Optional Syntax-based Arithmetic Coding mode (see Annex E), "0" off, "1" on.*/
-                                 proto_tree_add_item( h263_payload_tree, hf_h263_syntax_based_arithmetic_coding_mode, tvb, offset, 1, FALSE );
-                                 /* Bit 12: Optional Advanced Prediction mode (see Annex F), "0" off, "1" on.*/
-                                 proto_tree_add_item( h263_payload_tree, hf_h263_optional_advanced_prediction_mode, tvb, offset, 1, FALSE );
-                                 /* Bit 13: Optional PB-frames mode (see Annex G), "0" normal I- or P-picture, "1" PB-frame.*/
-                                 proto_tree_add_item( h263_payload_tree, hf_h263_PB_frames_mode, tvb, offset, 1, FALSE );
-                         }
+                               offset = dissect_h263_picture_layer( tvb, h263_payload_tree, offset, -1, FALSE);
                        }
                } else { /* GBSC found */
                        if ( check_col( pinfo->cinfo, COL_INFO) )
@@ -917,6 +1194,30 @@ proto_register_h263(void)
                                "Source Format", HFILL
                        }
                },
+               {
+                       &hf_h263_UFEP,
+                       {
+                               "H.263 Update Full Extended PTYPE",
+                               "h263.ufep",
+                               FT_UINT16,
+                               BASE_DEC,
+                               VALS(h263_ufep_vals),
+                               0x0380,
+                               "Update Full Extended PTYPE", HFILL
+                       }
+               },
+               {
+                       &hf_h263_opptype,
+                       {
+                               "H.263 Optional Part of PLUSPTYPE",
+                               "h263.opptype",
+                               FT_UINT24,
+                               BASE_DEC,
+                               NULL,
+                               0x7fffe0,
+                               "Optional Part of PLUSPTYPE", HFILL
+                       }
+               },
                {
                        &hf_h263_payload_picture_coding_type,
                        {
@@ -995,6 +1296,7 @@ proto_register_h263(void)
        {
                &ett_h263,
                &ett_h263_payload,
+               &ett_h263_optype,
        };
 
 
@@ -1016,13 +1318,13 @@ proto_register_h263P(void)
                {
                        &hf_h263P_payload,
                        {
-                               "H.263-1998 payload",
+                               "H.263 RFC4629 payload",
                                "h263P.payload",
                                FT_NONE,
                                BASE_NONE,
                                NULL,
                                0x0,
-                               "The actual H.263-1998 data", HFILL
+                               "The actual H.263 RFC4629 data", HFILL
                        }
                },
                {
@@ -1165,13 +1467,14 @@ proto_register_h263P(void)
        static gint *ett[] =
        {
                &ett_h263P,
+               &ett_h263P_extra_hdr,
                &ett_h263P_payload,
                &ett_h263P_data,
        };
 
 
        proto_h263P = proto_register_protocol("ITU-T Recommendation H.263 RTP Payload header (RFC4629)",
-           "H.263P", "h.263p");
+           "H263P", "h263p");
 
        proto_register_field_array(proto_h263P, hf, array_length(hf));
        proto_register_subtree_array(ett, array_length(ett));