forked from osmocom/wireshark
Dissect part ofconfiguration parameter in SDP for MP4V-ES.
svn path=/trunk/; revision=26754
This commit is contained in:
parent
23e9b1de65
commit
93b9635a41
|
@ -1027,6 +1027,7 @@ DISSECTOR_INCLUDES = \
|
|||
packet-mip6.h \
|
||||
packet-mms.h \
|
||||
packet-mount.h \
|
||||
packet-mp4ves.h \
|
||||
packet-mpls.h \
|
||||
packet-mq.h \
|
||||
packet-mrdisc.h \
|
||||
|
|
|
@ -50,6 +50,12 @@ static int hf_mp4ves_config = -1;
|
|||
static int hf_mp4ves_start_code_prefix = -1;
|
||||
static int hf_mp4ves_start_code = -1;
|
||||
static int hf_mp4ves_vop_coding_type = -1;
|
||||
static int hf_mp4ves_profile_and_level_indication = -1;
|
||||
static int hf_mp4ves_is_visual_object_identifier = -1;
|
||||
static int hf_mp4ves_visual_object_type = -1;
|
||||
static int hf_mp4ves_video_signal_type = -1;
|
||||
static int hf_mp4ves_stuffing = -1;
|
||||
static int hf_mp4ves_video_object_type_indication = -1;
|
||||
|
||||
/* Initialize the subtree pointers */
|
||||
static int ett_mp4ves = -1;
|
||||
|
@ -64,7 +70,7 @@ static guint global_dynamic_payload_type = 0;
|
|||
14496-2, Annex G, Table G-1.
|
||||
Table G-1 FLC table for profile_and_level_indication Profile/Level Code
|
||||
*/
|
||||
static const value_string mp4ves_level_indication_vals[] =
|
||||
const value_string mp4ves_level_indication_vals[] =
|
||||
{
|
||||
{ 0, "Reserved" },
|
||||
{ 1, "Simple Profile/Level 1" },
|
||||
|
@ -150,7 +156,7 @@ static const value_string mp4ves_level_indication_vals[] =
|
|||
{ 0, NULL },
|
||||
};
|
||||
static const range_string mp4ves_startcode_vals[] = {
|
||||
{ 0, 0x1f, "video_object_start_code" },
|
||||
{ 0x00, 0x1f, "video_object_start_code" },
|
||||
{ 0x20, 0x2f, "video_object_layer_start_code" },
|
||||
{ 0x30, 0xaf, "reserved" },
|
||||
{ 0xb0, 0xb0, "visual_object_sequence_start_code" },
|
||||
|
@ -205,9 +211,295 @@ static const value_string mp4ves_video_object_type_vals[] = {
|
|||
{ 0xe, "Simple FBA" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
/* Visual object type */
|
||||
static const value_string mp4ves_visual_object_type_vals[] = {
|
||||
{ 0x0, "reserved" },
|
||||
{ 0x1, "video ID" },
|
||||
{ 0x2, "still texture ID" },
|
||||
{ 0x3, "mesh ID" },
|
||||
{ 0x4, "FBA ID" },
|
||||
{ 0x5, "3D mesh ID" },
|
||||
{ 0x6, "reserved" },
|
||||
{ 0x7, "reserved" },
|
||||
{ 0x8, "reserved" },
|
||||
{ 0x9, "reserved" },
|
||||
{ 0xa, "reserved" },
|
||||
{ 0xb, "reserved" },
|
||||
{ 0xc, "reserved" },
|
||||
{ 0xd, "reserved" },
|
||||
{ 0xe, "reserved" },
|
||||
{ 0xf, "reserved" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
#if 0
|
||||
To be called from packet-sdp.c
|
||||
static const value_string mp4ves_video_object_type_indication_vals[] = {
|
||||
{ 0x0, "Reserved" },
|
||||
{ 0x1, "Simple Object Type" },
|
||||
{ 0x2, "Simple Scalable Object Type" },
|
||||
{ 0x3, "Core Object Type" },
|
||||
{ 0x4, "Main Object Type" },
|
||||
{ 0x5, "N-bit Object Type" },
|
||||
{ 0x6, "Basic Anim. 2D Texture" },
|
||||
{ 0x7, "Anim. 2D Mesh" },
|
||||
{ 0x8, "Simple Face" },
|
||||
{ 0x9, "Still Scalable Texture" },
|
||||
{ 0xa, "Advanced Real Time Simple" },
|
||||
{ 0xb, "Core Scalable" },
|
||||
{ 0xc, "Advanced Coding Efficiency" },
|
||||
{ 0xd, "Advanced Scalable Texture" },
|
||||
{ 0xe, "Simple FBA" },
|
||||
{ 0xf, "Reserved" },
|
||||
/* Reserved 00001111 – 11111111 */
|
||||
{ 0, NULL }
|
||||
};
|
||||
/* 6.2.2.1 User data */
|
||||
static int
|
||||
dissect_mp4ves_user_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int bit_offset)
|
||||
{
|
||||
int start_bit_offset;
|
||||
|
||||
/* user_data_start_code */
|
||||
proto_tree_add_bits_item(tree, hf_mp4ves_start_code_prefix, tvb, bit_offset, 24, FALSE);
|
||||
bit_offset+=24;
|
||||
proto_tree_add_bits_item(tree, hf_mp4ves_start_code, tvb, bit_offset, 8, FALSE);
|
||||
bit_offset+=8;
|
||||
start_bit_offset = bit_offset;
|
||||
/* while( next_bits() != ‘0000 0000 0000 0000 0000 0001’ ) { */
|
||||
while ( tvb_get_bits32(tvb,bit_offset, 24, FALSE) != 1){
|
||||
bit_offset+=8;
|
||||
/* user_data 8 bits */
|
||||
}
|
||||
proto_tree_add_text(tree, tvb, start_bit_offset>>3, (bit_offset - start_bit_offset)>>2, "User data");
|
||||
|
||||
return bit_offset;
|
||||
}
|
||||
/*
|
||||
next_start_code() {
|
||||
zero_bit
|
||||
while (!bytealigned())
|
||||
one_bit
|
||||
}
|
||||
*/
|
||||
static int
|
||||
dissect_mp4ves_next_start_code(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int bit_offset)
|
||||
{
|
||||
guint8 zero_bit;
|
||||
int start_bit_offset;
|
||||
|
||||
start_bit_offset = bit_offset;
|
||||
|
||||
zero_bit = tvb_get_bits8(tvb,bit_offset,1);
|
||||
if (zero_bit != 0){
|
||||
/* Error */
|
||||
}
|
||||
bit_offset++;
|
||||
|
||||
/* zero stuffing bits */
|
||||
if(bit_offset %8 == 0)
|
||||
return bit_offset;
|
||||
|
||||
while(bit_offset %8 != 0){
|
||||
bit_offset++;
|
||||
}
|
||||
|
||||
proto_tree_add_bits_item(tree, hf_mp4ves_stuffing, tvb, start_bit_offset, bit_offset-start_bit_offset, FALSE);
|
||||
|
||||
return bit_offset;
|
||||
}
|
||||
|
||||
/*
|
||||
video_signal_type() {
|
||||
video_signal_type
|
||||
if (video_signal_type) {
|
||||
video_format 3 uimsbf
|
||||
video_range 1 bslbf
|
||||
colour_description 1 bslbf
|
||||
if (colour_description) {
|
||||
colour_primaries 8 uimsbf
|
||||
transfer_characteristics 8 uimsbf
|
||||
matrix_coefficients 8 uimsbf
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
static int
|
||||
dissect_mp4ves_visual_object_type(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int bit_offset)
|
||||
{
|
||||
guint8 video_signal_type, colour_description;
|
||||
|
||||
video_signal_type = tvb_get_bits8(tvb,bit_offset,1);
|
||||
proto_tree_add_bits_item(tree, hf_mp4ves_video_signal_type, tvb, bit_offset, 1, FALSE);
|
||||
bit_offset++;
|
||||
if (video_signal_type) {
|
||||
/* video_format 3 bits */
|
||||
bit_offset+=3;
|
||||
/* video_range 1 bit */
|
||||
bit_offset++;
|
||||
/* colour_description 1 bit */
|
||||
colour_description = tvb_get_bits8(tvb,bit_offset,1);
|
||||
if (colour_description) {
|
||||
/* colour_primaries 8 bits */
|
||||
bit_offset+=8;
|
||||
/* transfer_characteristics 8 bits */
|
||||
bit_offset+=8;
|
||||
/* matrix_coefficients 8 bits*/
|
||||
bit_offset+=8;
|
||||
}
|
||||
}
|
||||
|
||||
return bit_offset;
|
||||
}
|
||||
/*
|
||||
* 6.2.3 Video Object Layer
|
||||
*/
|
||||
static int
|
||||
dissect_mp4ves_VideoObjectLayer(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int bit_offset)
|
||||
{
|
||||
guint32 dword;
|
||||
guint8 octet;
|
||||
|
||||
/* if(next_bits() == video_object_layer_start_code) { */
|
||||
dword = tvb_get_bits32(tvb,bit_offset, 24, FALSE);
|
||||
if (dword != 1){
|
||||
return bit_offset;
|
||||
}
|
||||
octet = tvb_get_bits8(tvb,bit_offset+24, 8);
|
||||
if((octet>=0x20)&&(octet<=0x2f)){
|
||||
/* Continue */
|
||||
}else{
|
||||
return -1;
|
||||
}
|
||||
/* video_object_layer_start_code */
|
||||
proto_tree_add_bits_item(tree, hf_mp4ves_start_code_prefix, tvb, bit_offset, 24, FALSE);
|
||||
bit_offset+=24;
|
||||
proto_tree_add_bits_item(tree, hf_mp4ves_start_code, tvb, bit_offset, 8, FALSE);
|
||||
bit_offset+= 8;
|
||||
|
||||
/* short_video_header = 0 */
|
||||
/* random_accessible_vol 1 */
|
||||
bit_offset++;
|
||||
/* video_object_type_indication 8 */
|
||||
proto_tree_add_bits_item(tree, hf_mp4ves_video_object_type_indication, tvb, bit_offset, 8, FALSE);
|
||||
bit_offset+= 8;
|
||||
/* is_object_layer_identifier 1 */
|
||||
bit_offset++;
|
||||
/* if (is_object_layer_identifier) { */
|
||||
/* video_object_layer_verid 4 uimsbf */
|
||||
/* video_object_layer_priority 3 uimsbf */
|
||||
/* }
|
||||
/* aspect_ratio_info 4 uimsbf */
|
||||
/* if (aspect_ratio_info == “extended_PAR”) { */
|
||||
/* par_width 8 uimsbf */
|
||||
/* par_height 8 uimsbf */
|
||||
/* } */
|
||||
/* vol_control_parameters 1 bslbf */
|
||||
/* if (vol_control_parameters) { */
|
||||
/* chroma_format 2 uimsbf */
|
||||
/* low_delay 1 uimsbf */
|
||||
/* vbv_parameters 1 blsbf */
|
||||
|
||||
|
||||
return bit_offset;
|
||||
}
|
||||
/* Visual object */
|
||||
/*
|
||||
VisualObject() {
|
||||
visual_object_start_code
|
||||
is_visual_object_identifier
|
||||
if (is_visual_object_identifier) {
|
||||
visual_object_verid
|
||||
visual_object_priority
|
||||
}
|
||||
visual_object_type
|
||||
if (visual_object_type == “video ID” || visual_object_type == “still textureID“) {
|
||||
video_signal_type()
|
||||
}
|
||||
next_start_code()
|
||||
while ( next_bits()== user_data_start_code){
|
||||
user_data()
|
||||
}
|
||||
if (visual_object_type == “video ID”) {
|
||||
video_object_start_code
|
||||
VideoObjectLayer()
|
||||
}
|
||||
else if (visual_object_type == “still texture ID”) {
|
||||
StillTextureObject()
|
||||
}
|
||||
else if (visual_object_type == “mesh ID”) {
|
||||
MeshObject()
|
||||
}
|
||||
else if (visual_object_type == “FBA ID”) {
|
||||
FBAObject()
|
||||
}
|
||||
else if (visual_object_type == “3D mesh ID”) {
|
||||
3D_Mesh_Object()
|
||||
}
|
||||
if (next_bits() != “0000 0000 0000 0000 0000 0001”)
|
||||
next_start_code()
|
||||
}
|
||||
*/
|
||||
static int
|
||||
dissect_mp4ves_VisualObject(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int bit_offset)
|
||||
{
|
||||
guint8 is_visual_object_identifier, visual_object_type;
|
||||
guint32 dword;
|
||||
guint8 octet;
|
||||
|
||||
is_visual_object_identifier = tvb_get_bits8(tvb,bit_offset,1);
|
||||
proto_tree_add_bits_item(tree, hf_mp4ves_is_visual_object_identifier, tvb, bit_offset, 1, FALSE);
|
||||
bit_offset++;
|
||||
if(is_visual_object_identifier){
|
||||
/* visual_object_verid 4 bits*/
|
||||
bit_offset+=4;
|
||||
/* visual_object_priority 3 bits*/
|
||||
bit_offset+=3;
|
||||
}
|
||||
/* visual_object_type 4 bits*/
|
||||
visual_object_type = tvb_get_bits8(tvb,bit_offset,4);
|
||||
proto_tree_add_bits_item(tree, hf_mp4ves_visual_object_type, tvb, bit_offset, 4, FALSE);
|
||||
bit_offset+=4;
|
||||
if ((visual_object_type == 1/*“video ID”*/) || (visual_object_type == 2/*“still textureID“*/)) {
|
||||
/* video_signal_type() */
|
||||
bit_offset = dissect_mp4ves_visual_object_type(tvb, pinfo, tree, bit_offset);
|
||||
}
|
||||
/* next_start_code() */
|
||||
bit_offset = dissect_mp4ves_next_start_code(tvb, pinfo, tree, bit_offset);
|
||||
dword = tvb_get_bits32(tvb,bit_offset, 32, FALSE);
|
||||
/*
|
||||
while ( next_bits()== user_data_start_code){
|
||||
user_data()
|
||||
}
|
||||
*/
|
||||
while(dword==0x1b2){
|
||||
bit_offset = dissect_mp4ves_user_data(tvb, pinfo, tree, bit_offset);
|
||||
dword = tvb_get_bits32(tvb,bit_offset, 32, FALSE);
|
||||
}
|
||||
if (visual_object_type == 1/*“video ID”*/) {
|
||||
/*
|
||||
* video_object_start_code
|
||||
*/
|
||||
dword = tvb_get_bits32(tvb,bit_offset, 24, FALSE);
|
||||
if (dword != 1){
|
||||
/* no start code */
|
||||
return -1;
|
||||
}
|
||||
octet = tvb_get_bits8(tvb,bit_offset+24, 8);
|
||||
if(octet>0x20){
|
||||
/* Error */
|
||||
return -1;
|
||||
}
|
||||
proto_tree_add_bits_item(tree, hf_mp4ves_start_code_prefix, tvb, bit_offset, 24, FALSE);
|
||||
bit_offset+=24;
|
||||
proto_tree_add_bits_item(tree, hf_mp4ves_start_code, tvb, bit_offset, 8, FALSE);
|
||||
bit_offset+= 8;
|
||||
/*
|
||||
VideoObjectLayer()
|
||||
*/
|
||||
bit_offset = dissect_mp4ves_VideoObjectLayer(tvb, pinfo, tree, bit_offset);
|
||||
}
|
||||
|
||||
return bit_offset;
|
||||
}
|
||||
void
|
||||
dissect_mp4ves_config(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
||||
{
|
||||
|
@ -219,25 +511,60 @@ dissect_mp4ves_config(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|||
item = proto_tree_add_item(tree, hf_mp4ves_config, tvb, 0, -1, FALSE);
|
||||
mp4ves_tree = proto_item_add_subtree(item, ett_mp4ves_config);
|
||||
|
||||
/* Get start code prefix */
|
||||
dword = tvb_get_bits32(tvb,bit_offset, 24, FALSE);
|
||||
if (dword == 1){
|
||||
/*VisualObjectSequence() {
|
||||
do {
|
||||
visual_object_sequence_start_code
|
||||
*/
|
||||
|
||||
}else{
|
||||
/* Get start code prefix */
|
||||
dword = tvb_get_bits32(tvb,bit_offset, 32, FALSE);
|
||||
if ((dword & 0x00000100) != 0x00000100){
|
||||
/* No start code prefix */
|
||||
return;
|
||||
}
|
||||
|
||||
proto_tree_add_bits_item(tree, hf_mp4ves_start_code_prefix, tvb, bit_offset, 24, FALSE);
|
||||
bit_offset = bit_offset+24;
|
||||
bit_offset+= 24;
|
||||
|
||||
/* We are byte aligned no stuffing */
|
||||
dword = tvb_get_bits8(tvb,bit_offset, 8);
|
||||
proto_tree_add_bits_item(tree, hf_mp4ves_start_code, tvb, bit_offset, 8, FALSE);
|
||||
bit_offset+= 8;
|
||||
|
||||
/* Expect visual_object_sequence_start_code */
|
||||
if(dword != 0x1b0)
|
||||
return;
|
||||
/* profile_and_level_indication */
|
||||
proto_tree_add_bits_item(tree, hf_mp4ves_profile_and_level_indication, tvb, bit_offset, 8, FALSE);
|
||||
bit_offset+= 8;
|
||||
|
||||
/* while ( next_bits()== user_data_start_code){
|
||||
user_data()
|
||||
}
|
||||
*/
|
||||
dword = tvb_get_bits32(tvb,bit_offset, 32, FALSE);
|
||||
bit_offset+= 32;
|
||||
if ((dword & 0x00000100) != 0x00000100){
|
||||
/* No start code prefix */
|
||||
return;
|
||||
}
|
||||
if(dword==0x1b2){
|
||||
/*
|
||||
* user_data_start_code
|
||||
* XXX call user data dissection here
|
||||
*/
|
||||
return;
|
||||
}
|
||||
if(dword==0x1b5){
|
||||
/*
|
||||
* VisualObject()
|
||||
*/
|
||||
bit_offset = dissect_mp4ves_VisualObject(tvb, pinfo, tree, bit_offset);
|
||||
}
|
||||
/*
|
||||
} while ( next_bits() != visual_object_sequence_end_code)
|
||||
visual_object_sequence_end_code
|
||||
}
|
||||
#endif
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
dissect_mp4ves(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
||||
|
@ -384,6 +711,9 @@ static mp4ves_capability_t mp4ves_capability_tab[] = {
|
|||
/* ITU-T H.245 capabilities ISO/IEC 14496-2(m*/
|
||||
{ "GenericCapability/0.0.8.245.1.0.0/nonCollapsing/0", "profileAndLevel", dissect_mp4ves_par_profile },
|
||||
{ "GenericCapability/0.0.8.245.1.0.0/nonCollapsing/1", "object", dissect_mp4ves_par_video_object_type },
|
||||
{ "GenericCapability/0.0.8.245.1.0.0/nonCollapsing/2", "decoderConfigurationInformation", NULL },
|
||||
{ "GenericCapability/0.0.8.245.1.0.0/nonCollapsing/3", "drawingOrder", NULL },
|
||||
{ "GenericCapability/0.0.8.245.1.0.0/collapsing/4", "visualBackChannelHandle", NULL },
|
||||
{ NULL, NULL, NULL },
|
||||
};
|
||||
|
||||
|
@ -469,7 +799,7 @@ proto_register_mp4ves(void)
|
|||
},
|
||||
{ &hf_mp4ves_start_code,
|
||||
{ "Start code", "mp4ves.start_code",
|
||||
FT_UINT32, BASE_HEX, RVALS(&mp4ves_startcode_vals), 0x0,
|
||||
FT_UINT8, BASE_RANGE_STRING|BASE_HEX, RVALS(&mp4ves_startcode_vals), 0x0,
|
||||
"Start code", HFILL }
|
||||
},
|
||||
{ &hf_mp4ves_vop_coding_type,
|
||||
|
@ -477,6 +807,36 @@ proto_register_mp4ves(void)
|
|||
FT_UINT8, BASE_DEC, VALS(mp4ves_vop_coding_type_vals), 0x0,
|
||||
"Start code", HFILL }
|
||||
},
|
||||
{&hf_mp4ves_profile_and_level_indication,
|
||||
{ "profile_and_level_indication", "mp4ves.profile_and_level_indication",
|
||||
FT_UINT8, BASE_DEC,VALS(mp4ves_level_indication_vals), 0x0,
|
||||
"profile_and_level_indication", HFILL }
|
||||
},
|
||||
{ &hf_mp4ves_is_visual_object_identifier,
|
||||
{ "visual_object_identifier", "mp4ves.visual_object_identifier",
|
||||
FT_UINT8, BASE_DEC, NULL, 0x0,
|
||||
"visual_object_identifier", HFILL }
|
||||
},
|
||||
{ &hf_mp4ves_visual_object_type,
|
||||
{ "visual_object_type", "mp4ves.visual_object_type",
|
||||
FT_UINT32, BASE_DEC, VALS(mp4ves_visual_object_type_vals), 0x0,
|
||||
"visual_object_type", HFILL }
|
||||
},
|
||||
{ &hf_mp4ves_video_signal_type,
|
||||
{ "video_signal_type", "mp4ves.video_signal_type",
|
||||
FT_UINT8, BASE_DEC, NULL, 0x0,
|
||||
"video_signal_type", HFILL }
|
||||
},
|
||||
{ &hf_mp4ves_stuffing,
|
||||
{ "Stuffing", "mp4ves.stuffing",
|
||||
FT_UINT8, BASE_DEC, NULL, 0x0,
|
||||
"Stuffing", HFILL }
|
||||
},
|
||||
{ &hf_mp4ves_video_object_type_indication,
|
||||
{ "video_object_type_indication", "mp4ves.video_object_type_indication",
|
||||
FT_UINT8, BASE_DEC, VALS(mp4ves_video_object_type_indication_vals), 0x0,
|
||||
"video_object_type_indication", HFILL }
|
||||
},
|
||||
};
|
||||
|
||||
/* Setup protocol subtree array */
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
/* packet-mp4ves.h
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright 2008, Anders Broman <anders.broman[at]ericsson.com>
|
||||
*
|
||||
* Wireshark - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@wireshark.org>
|
||||
* Copyright 1998 Gerald Combs
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef PACKET_MP4VES_H
|
||||
#define PACKET_MP4VES_H
|
||||
|
||||
extern const value_string mp4ves_level_indication_vals[];
|
||||
|
||||
void dissect_mp4ves_config(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
|
||||
#endif /* PACKET_MP4VES_H */
|
|
@ -73,12 +73,14 @@
|
|||
#include "packet-per.h"
|
||||
#include "packet-h245.h"
|
||||
#include "packet-h264.h"
|
||||
#include "packet-mp4ves.h"
|
||||
|
||||
static dissector_handle_t rtp_handle=NULL;
|
||||
static dissector_handle_t rtcp_handle=NULL;
|
||||
static dissector_handle_t t38_handle=NULL;
|
||||
static dissector_handle_t msrp_handle=NULL;
|
||||
static dissector_handle_t h264_handle = NULL;
|
||||
static dissector_handle_t mp4ves_handle = NULL;
|
||||
|
||||
static int sdp_tap = -1;
|
||||
|
||||
|
@ -1213,95 +1215,7 @@ tvbuff_t *ascii_bytes_to_tvb(tvbuff_t *tvb, packet_info *pinfo, gint len, gchar
|
|||
}
|
||||
return NULL;
|
||||
}
|
||||
/*
|
||||
14496-2, Annex G, Table G-1.
|
||||
Table G-1 FLC table for profile_and_level_indication Profile/Level Code
|
||||
*/
|
||||
static const value_string mpeg4es_level_indication_vals[] =
|
||||
{
|
||||
{ 0, "Reserved" },
|
||||
{ 1, "Simple Profile/Level 1" },
|
||||
{ 2, "Simple Profile/Level 2" },
|
||||
{ 3, "Reserved" },
|
||||
{ 4, "Reserved" },
|
||||
{ 5, "Reserved" },
|
||||
{ 6, "Reserved" },
|
||||
{ 7, "Reserved" },
|
||||
{ 8, "Simple Profile/Level 0" },
|
||||
{ 9, "Simple Profile/Level 0b" },
|
||||
/* Reserved 00001001 - 00010000 */
|
||||
{ 0x11, "Simple Scalable Profile/Level 1" },
|
||||
{ 0x12, "Simple Scalable Profile/Level 2" },
|
||||
/* Reserved 00010011 - 00100000 */
|
||||
{ 0x21, "Core Profile/Level 1" },
|
||||
{ 0x22, "Core Profile/Level 2" },
|
||||
/* Reserved 00100011 - 00110001 */
|
||||
{ 0x32, "Main Profile/Level 2" },
|
||||
{ 0x33, "Main Profile/Level 3" },
|
||||
{ 0x34, "Main Profile/Level 4" },
|
||||
/* Reserved 00110101 - 01000001 */
|
||||
{ 0x42, "N-bit Profile/Level 2" },
|
||||
/* Reserved 01000011 - 01010000 */
|
||||
{ 0x51, "Scalable Texture Profile/Level 1" },
|
||||
/* Reserved 01010010 - 01100000 */
|
||||
{ 0x61, "Simple Face Animation Profile/Level 1" },
|
||||
{ 0x62, "Simple Face Animation Profile/Level 2" },
|
||||
{ 0x63, "Simple FBA Profile/Level 1" },
|
||||
{ 0x64, "Simple FBA Profile/Level 2" },
|
||||
/* Reserved 01100101 - 01110000 */
|
||||
{ 0x71, "Basic Animated Texture Profile/Level 1" },
|
||||
{ 0x72, "Basic Animated Texture Profile/Level 2" },
|
||||
/* Reserved 01110011 - 10000000 */
|
||||
{ 0x81, "Hybrid Profile/Level 1" },
|
||||
{ 0x82, "Hybrid Profile/Level 2" },
|
||||
/* Reserved 10000011 - 10010000 */
|
||||
{ 0x91, "Advanced Real Time Simple Profile/Level 1" },
|
||||
{ 0x92, "Advanced Real Time Simple Profile/Level 2" },
|
||||
{ 0x93, "Advanced Real Time Simple Profile/Level 3" },
|
||||
{ 0x94, "Advanced Real Time Simple Profile/Level 4" },
|
||||
/* Reserved 10010101 - 10100000 */
|
||||
{ 0xa1, "Core Scalable Profile/Level 1" },
|
||||
{ 0xa2, "Core Scalable Profile/Level 2" },
|
||||
{ 0xa3, "Core Scalable Profile/Level 3" },
|
||||
/* Reserved 10100100 - 10110000 */
|
||||
{ 0xb1, "Advanced Coding Efficiency Profile/Level 1" },
|
||||
{ 0xb2, "Advanced Coding Efficiency Profile/Level 2" },
|
||||
{ 0xb3, "Advanced Coding Efficiency Profile/Level 3" },
|
||||
{ 0xb4, "Advanced Coding Efficiency Profile/Level 4" },
|
||||
/* Reserved 10110101 - 11000000 */
|
||||
{ 0xc1, "Advanced Core Profile/Level 1" },
|
||||
{ 0xc2, "Advanced Core Profile/Level 2" },
|
||||
/* Reserved 11000011 - 11010000 */
|
||||
{ 0xd1, "Advanced Scalable Texture/Level 1" },
|
||||
{ 0xd2, "Advanced Scalable Texture/Level 2" },
|
||||
{ 0xd3, "Advanced Scalable Texture/Level 3" },
|
||||
/* Reserved 11010100 - 11100000 */
|
||||
{ 0xe1, "Simple Studio Profile/Level 1" },
|
||||
{ 0xe2, "Simple Studio Profile/Level 2" },
|
||||
{ 0xe3, "Simple Studio Profile/Level 3" },
|
||||
{ 0xe4, "Simple Studio Profile/Level 4" },
|
||||
{ 0xe5, "Core Studio Profile/Level 1" },
|
||||
{ 0xe6, "Core Studio Profile/Level 2" },
|
||||
{ 0xe7, "Core Studio Profile/Level 3" },
|
||||
{ 0xe8, "Core Studio Profile/Level 4" },
|
||||
/* Reserved 11101001 - 11101111 */
|
||||
{ 0xf0, "Advanced Simple Profile/Level 0" },
|
||||
{ 0xf1, "Advanced Simple Profile/Level 1" },
|
||||
{ 0xf2, "Advanced Simple Profile/Level 2" },
|
||||
{ 0xf3, "Advanced Simple Profile/Level 3" },
|
||||
{ 0xf4, "Advanced Simple Profile/Level 4" },
|
||||
{ 0xf5, "Advanced Simple Profile/Level 5" },
|
||||
/* Reserved 11110110 - 11110111 */
|
||||
{ 0xf8, "Fine Granularity Scalable Profile/Level 0" },
|
||||
{ 0xf9, "Fine Granularity Scalable Profile/Level 1" },
|
||||
{ 0xfa, "Fine Granularity Scalable Profile/Level 2" },
|
||||
{ 0xfb, "Fine Granularity Scalable Profile/Level 3" },
|
||||
{ 0xfc, "Fine Granularity Scalable Profile/Level 4" },
|
||||
{ 0xfd, "Fine Granularity Scalable Profile/Level 5" },
|
||||
{ 0xfe, "Reserved" },
|
||||
{ 0xff, "Reserved for Escape" },
|
||||
{ 0, NULL },
|
||||
};
|
||||
|
||||
/* Annex X Profiles and levels definition */
|
||||
static const value_string h263_profile_vals[] =
|
||||
{
|
||||
|
@ -1363,7 +1277,16 @@ decode_sdp_fmtp(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, gint offset
|
|||
item = proto_tree_add_uint(tree, hf_sdp_fmtp_mpeg4_profile_level_id, tvb, offset, tokenlen,
|
||||
atol((char*)format_specific_parameter));
|
||||
PROTO_ITEM_SET_GENERATED(item);
|
||||
}
|
||||
}else if(strcmp((char*)field_name, "config") == 0) {
|
||||
/* String including "=" */
|
||||
tokenlen = end_offset - offset;
|
||||
format_specific_parameter = tvb_get_ephemeral_string(tvb, offset, tokenlen);
|
||||
/* ascii_bytes_to_tvb requires the "=" to be in the buffer */
|
||||
data_tvb = ascii_bytes_to_tvb(tvb, pinfo, tokenlen, format_specific_parameter);
|
||||
if(mp4ves_handle && data_tvb){
|
||||
dissect_mp4ves_config(data_tvb, pinfo, tree);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Dissect the H263-2000 profile parameter if present */
|
||||
|
@ -1379,16 +1302,34 @@ decode_sdp_fmtp(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, gint offset
|
|||
}
|
||||
|
||||
|
||||
/* Dissect the H264 profile-level-id parameter */
|
||||
/* Dissect the H264 profile-level-id parameter
|
||||
* RFC 3984:
|
||||
* A base16 [6] (hexadecimal) representation of
|
||||
* the following three bytes in the sequence
|
||||
* parameter set NAL unit specified in [1]: 1)
|
||||
* profile_idc, 2) a byte herein referred to as
|
||||
* profile-iop, composed of the values of
|
||||
* constraint_set0_flag, constraint_set1_flag,
|
||||
* constraint_set2_flag, and reserved_zero_5bits
|
||||
* in bit-significance order, starting from the
|
||||
* most significant bit, and 3) level_idc.
|
||||
*/
|
||||
if (mime_type != NULL && strcmp(mime_type, "H264") == 0) {
|
||||
if (strcmp(field_name, "profile-level-id") == 0) {
|
||||
int length;
|
||||
|
||||
/* Length includes "=" */
|
||||
/* Length includes "=" as it's required by ascii_bytes_to_tvb()*/
|
||||
tokenlen = end_offset - offset;
|
||||
format_specific_parameter = tvb_get_ephemeral_string(tvb, offset, tokenlen);
|
||||
data_tvb = ascii_bytes_to_tvb(tvb, pinfo, tokenlen, format_specific_parameter);
|
||||
if(h264_handle && data_tvb){
|
||||
dissect_h264_profile(data_tvb, pinfo, tree);
|
||||
length = tvb_length(data_tvb);
|
||||
if (length == 3){
|
||||
if(h264_handle && data_tvb){
|
||||
dissect_h264_profile(data_tvb, pinfo, tree);
|
||||
}
|
||||
}else{
|
||||
item = proto_tree_add_text(tree, tvb, offset, tokenlen, "Incorrectly coded, must be three bytes");
|
||||
PROTO_ITEM_SET_GENERATED(item);
|
||||
}
|
||||
}else if (strcmp(field_name, "packetization-mode") == 0) {
|
||||
offset++;
|
||||
|
@ -1399,13 +1340,13 @@ decode_sdp_fmtp(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, gint offset
|
|||
|
||||
}else if (strcmp(field_name, "sprop-parameter-sets") == 0) {
|
||||
/* The value of the parameter is the
|
||||
base64 [6] representation of the initial
|
||||
parameter set NAL units as specified in
|
||||
sections 7.3.2.1 and 7.3.2.2 of [1]. The
|
||||
parameter sets are conveyed in decoding order,
|
||||
and no framing of the parameter set NAL units
|
||||
takes place. A comma is used to separate any
|
||||
pair of parameter sets in the list.
|
||||
base64 [6] representation of the initial
|
||||
parameter set NAL units as specified in
|
||||
sections 7.3.2.1 and 7.3.2.2 of [1]. The
|
||||
parameter sets are conveyed in decoding order,
|
||||
and no framing of the parameter set NAL units
|
||||
takes place. A comma is used to separate any
|
||||
pair of parameter sets in the list.
|
||||
*/
|
||||
gchar *data = NULL;
|
||||
gint comma_offset;
|
||||
|
@ -1935,7 +1876,7 @@ proto_register_sdp(void)
|
|||
"IPBCP Command Type", HFILL }},
|
||||
{&hf_sdp_fmtp_mpeg4_profile_level_id,
|
||||
{ "Level Code",
|
||||
"sdp.fmtp.profile_level_id",FT_UINT32, BASE_DEC,VALS(mpeg4es_level_indication_vals), 0x0,
|
||||
"sdp.fmtp.profile_level_id",FT_UINT32, BASE_DEC,VALS(mp4ves_level_indication_vals), 0x0,
|
||||
"Level Code", HFILL }},
|
||||
{ &hf_sdp_fmtp_h263_profile,
|
||||
{ "Profile",
|
||||
|
@ -2022,6 +1963,7 @@ proto_reg_handoff_sdp(void)
|
|||
msrp_handle = find_dissector("msrp");
|
||||
t38_handle = find_dissector("t38");
|
||||
h264_handle = find_dissector("h264");
|
||||
mp4ves_handle = find_dissector("mp4ves");
|
||||
|
||||
sdp_handle = find_dissector("sdp");
|
||||
dissector_add_string("media_type", "application/sdp", sdp_handle);
|
||||
|
|
Loading…
Reference in New Issue