update media layer.
This commit is contained in:
parent
7113453686
commit
fffaac33e4
|
@ -33,6 +33,7 @@
|
|||
/* == tinyMEDIA == */
|
||||
#include "tinymedia/tmedia_codec_dummy.h"
|
||||
#include "tinymedia/tmedia_session_dummy.h"
|
||||
#include "tinymedia/tmedia_session_ghost.h"
|
||||
|
||||
/* == tinySAK == */
|
||||
#include "tsk.h"
|
||||
|
|
|
@ -149,15 +149,16 @@ typedef struct tmedia_codec_plugin_def_s
|
|||
const char* format;
|
||||
//! whether the pay. type is dyn. or not
|
||||
tsk_bool_t dyn;
|
||||
int32_t rate;
|
||||
|
||||
struct{
|
||||
int32_t rate;
|
||||
int8_t channels;
|
||||
/* ...to be continued */
|
||||
} audio;
|
||||
|
||||
struct{
|
||||
int32_t rate;
|
||||
unsigned width;
|
||||
unsigned height;
|
||||
/* ...to be continued */
|
||||
} video;
|
||||
|
||||
|
|
|
@ -32,20 +32,25 @@
|
|||
|
||||
#include "tinymedia_config.h"
|
||||
|
||||
#include "tinysdp/tsdp_message.h"
|
||||
|
||||
TMEDIA_BEGIN_DECLS
|
||||
|
||||
/** List of all supported media types */
|
||||
typedef enum tmedia_type_e
|
||||
{
|
||||
tmedia_none = 0,
|
||||
tmedia_none = 0x00,
|
||||
tmedia_ghost = (0x01 << 0),
|
||||
|
||||
tmedia_audio = (0x01 << 0),
|
||||
tmedia_video = (0x01 << 1),
|
||||
tmedia_msrp = (0x01 << 2),
|
||||
tmedia_t38 = (0x01 << 3)
|
||||
tmedia_audio = (0x01 << 1),
|
||||
tmedia_video = (0x01 << 2),
|
||||
tmedia_msrp = (0x01 << 3),
|
||||
tmedia_t38 = (0x01 << 4)
|
||||
}
|
||||
tmedia_type_t;
|
||||
|
||||
tmedia_type_t tmedia_type_from_sdp(const tsdp_message_t* sdp);
|
||||
int tmedia_parse_rtpmap(const char* rtpmap, char** name, int32_t* rate, int32_t* channels);
|
||||
|
||||
TMEDIA_END_DECLS
|
||||
|
||||
|
|
|
@ -55,6 +55,7 @@ typedef struct tmedia_session_s
|
|||
tmedia_codecs_L_t* codecs;
|
||||
//! whether the session has been prepared
|
||||
tsk_bool_t prepared;
|
||||
unsigned initialized:1;
|
||||
|
||||
struct{
|
||||
tsdp_header_M_t* lo;
|
||||
|
@ -92,6 +93,7 @@ tmedia_session_plugin_def_t;
|
|||
TINYMEDIA_API int tmedia_session_init(tmedia_session_t* self, tmedia_type_t type);
|
||||
TINYMEDIA_API int tmedia_session_cmp(const tsk_object_t* sess1, const tsk_object_t* sess2);
|
||||
TINYMEDIA_API int tmedia_session_plugin_register(const tmedia_session_plugin_def_t* plugin);
|
||||
TINYMEDIA_API const tmedia_session_plugin_def_t* tmedia_session_plugin_find_by_media(const char* media);
|
||||
TINYMEDIA_API int tmedia_session_plugin_unregister(const tmedia_session_plugin_def_t* plugin);
|
||||
TINYMEDIA_API tmedia_session_t* tmedia_session_create(tmedia_type_t type);
|
||||
TINYMEDIA_API int tmedia_session_deinit(tmedia_session_t* self);
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Copyright (C) 2009 Mamadou Diop.
|
||||
*
|
||||
* Contact: Mamadou Diop <diopmamadou(at)doubango.org>
|
||||
*
|
||||
* This file is part of Open Source Doubango Framework.
|
||||
*
|
||||
* DOUBANGO 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* DOUBANGO 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 DOUBANGO.
|
||||
*
|
||||
*/
|
||||
|
||||
/**@file tmedia_session_ghost.h
|
||||
* @brief Ghost session.
|
||||
*
|
||||
* @author Mamadou Diop <diopmamadou(at)doubango.org>
|
||||
*
|
||||
* @date Created: Sat Nov 8 16:54:58 2009 mdiop
|
||||
*/
|
||||
#ifndef TINYMEDIA_SESSION_GHOST_H
|
||||
#define TINYMEDIA_SESSION_GHOST_H
|
||||
|
||||
#include "tinymedia_config.h"
|
||||
|
||||
#include "tmedia_session.h"
|
||||
|
||||
#include "tsk_object.h"
|
||||
|
||||
TMEDIA_BEGIN_DECLS
|
||||
|
||||
/** Ghost session */
|
||||
typedef struct tmedia_session_ghost_s
|
||||
{
|
||||
TMEDIA_DECLARE_SESSION;
|
||||
char* media;
|
||||
}
|
||||
tmedia_session_ghost_t;
|
||||
|
||||
TINYMEDIA_GEXTERN const tmedia_session_plugin_def_t *tmedia_session_ghost_plugin_def_t;
|
||||
|
||||
TMEDIA_END_DECLS
|
||||
|
||||
#endif /* TINYMEDIA_SESSION_GHOST_H */
|
|
@ -55,7 +55,6 @@ int tmedia_codec_init(tmedia_codec_t* self, tmedia_type_t type, const char* name
|
|||
return -1;
|
||||
}
|
||||
self->type = type;
|
||||
self->dyn = tsk_true; /* this is the default value. up to the caller to update it */
|
||||
tsk_strupdate(&self->name, name);
|
||||
tsk_strupdate(&self->desc,desc);
|
||||
tsk_strupdate(&self->format, format);
|
||||
|
@ -167,7 +166,7 @@ tmedia_codec_t* tmedia_codec_create(const char* format)
|
|||
/* initialize the newly created codec */
|
||||
codec->dyn = plugin->dyn;
|
||||
codec->plugin = plugin;
|
||||
switch(codec->type){
|
||||
switch(plugin->type){
|
||||
case tmedia_audio:
|
||||
{ /* Audio codec */
|
||||
tmedia_codec_audio_t* audio = TMEDIA_CODEC_AUDIO(codec);
|
||||
|
@ -218,7 +217,7 @@ char* tmedia_codec_get_rtpmap(const tmedia_codec_t* self)
|
|||
{ /* audio codecs */
|
||||
/* const tmedia_codec_audio_t* audioCodec = (const tmedia_codec_audio_t*)self; */
|
||||
if(self->plugin->audio.channels > 0){
|
||||
tsk_sprintf(&rtpmap, "%s %s/%d/%d", self->format, self->name, self->plugin->audio.rate, self->plugin->audio.channels);
|
||||
tsk_sprintf(&rtpmap, "%s %s/%d/%d", self->format, self->name, self->plugin->rate, self->plugin->audio.channels);
|
||||
}
|
||||
else{
|
||||
tsk_sprintf(&rtpmap, "%s %s/%d", self->format, self->name, self->plugin->audio);
|
||||
|
@ -228,7 +227,7 @@ char* tmedia_codec_get_rtpmap(const tmedia_codec_t* self)
|
|||
case tmedia_video:
|
||||
{ /* video codecs */
|
||||
/* const tmedia_codec_video_t* videoCodec = (const tmedia_codec_video_t*)self; */
|
||||
tsk_sprintf(&rtpmap, "%s %s/%d", self->format, self->name, self->plugin->video.rate);
|
||||
tsk_sprintf(&rtpmap, "%s %s/%d", self->format, self->name, self->plugin->rate);
|
||||
break;
|
||||
}
|
||||
/* all others */
|
||||
|
|
|
@ -88,14 +88,14 @@ static const tmedia_codec_plugin_def_t tmedia_codec_dpcmu_plugin_def_s =
|
|||
"Dummy G.711u codec",
|
||||
TMEDIA_CODEC_FORMAT_G711u,
|
||||
tsk_false,
|
||||
8000, // rate
|
||||
|
||||
{ /* audio */
|
||||
8000, // rate
|
||||
1 // channels
|
||||
},
|
||||
|
||||
/* video */
|
||||
{ tsk_null },
|
||||
{{0}},
|
||||
|
||||
tmedia_codec_dpcmu_fmtp_match,
|
||||
tmedia_codec_dpcmu_fmtp_get,
|
||||
|
@ -145,14 +145,14 @@ static const tmedia_codec_plugin_def_t tmedia_codec_dpcma_plugin_def_s =
|
|||
"Dummy G.711a codec",
|
||||
TMEDIA_CODEC_FORMAT_G711a,
|
||||
tsk_false,
|
||||
8000, // rate
|
||||
|
||||
{ /* audio */
|
||||
8000, // rate
|
||||
1 // channels
|
||||
},
|
||||
|
||||
/* video */
|
||||
{ tsk_null },
|
||||
{{0}},
|
||||
|
||||
tmedia_codec_dpcma_fmtp_match,
|
||||
tmedia_codec_dpcma_fmtp_get,
|
||||
|
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* Copyright (C) 2009 Mamadou Diop.
|
||||
*
|
||||
* Contact: Mamadou Diop <diopmamadou(at)doubango.org>
|
||||
*
|
||||
* This file is part of Open Source Doubango Framework.
|
||||
*
|
||||
* DOUBANGO 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* DOUBANGO 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 DOUBANGO.
|
||||
*
|
||||
*/
|
||||
|
||||
/**@file tmedia_common.c
|
||||
* @brief Common functions and definitions.
|
||||
*
|
||||
* @author Mamadou Diop <diopmamadou(at)doubango.org>
|
||||
*
|
||||
* @date Created: Sat Nov 8 16:54:58 2009 mdiop
|
||||
*/
|
||||
#include "tinymedia/tmedia_common.h"
|
||||
|
||||
#include "tinymedia/tmedia_session.h"
|
||||
|
||||
#include "tsk_debug.h"
|
||||
|
||||
#include <stdlib.h> /* atoi() */
|
||||
|
||||
tmedia_type_t tmedia_type_from_sdp(const tsdp_message_t* sdp)
|
||||
{
|
||||
tmedia_type_t type = tmedia_none;
|
||||
const tsdp_header_M_t* M;
|
||||
tsk_size_t index = 0;
|
||||
const tmedia_session_plugin_def_t* plugin;
|
||||
|
||||
if(!sdp){
|
||||
TSK_DEBUG_ERROR("Invalid parameter");
|
||||
return tmedia_none;
|
||||
}
|
||||
|
||||
while((M = (const tsdp_header_M_t*)tsdp_message_get_headerAt(sdp, tsdp_htype_M, index++))){
|
||||
if((plugin = tmedia_session_plugin_find_by_media(M->media))){
|
||||
type |= plugin->type;
|
||||
}
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
|
||||
int tmedia_parse_rtpmap(const char* rtpmap, char** name, int32_t* rate, int32_t* channels)
|
||||
{
|
||||
/* e.g. AMR-WB/16000/2 */
|
||||
|
||||
size_t len;
|
||||
|
||||
if(tsk_strnullORempty(rtpmap)){
|
||||
TSK_DEBUG_ERROR("Invalid parameter");
|
||||
return -1;
|
||||
}
|
||||
|
||||
*name = tsk_null;
|
||||
*rate = *channels = 0;
|
||||
len = tsk_strlen(rtpmap);
|
||||
|
||||
/* e.g. AMR-WB/16000/2 */
|
||||
if(sscanf(rtpmap, "%*s/%*d/%*d")){
|
||||
int index = tsk_strindexOf(rtpmap, len, "/");
|
||||
*name = tsk_strndup(rtpmap, index);
|
||||
sscanf(&rtpmap[index+1], "%d/%d", rate, channels);
|
||||
}
|
||||
/* e.g. AMR-WB/16000 */
|
||||
else if(sscanf(rtpmap, "%*s/%*d")){
|
||||
int index = tsk_strindexOf(rtpmap, len, "/");
|
||||
*name = tsk_strndup(rtpmap, index);
|
||||
*rate = atoi(&rtpmap[index+1]);
|
||||
}
|
||||
/* e.g. AMR-WB */
|
||||
else{
|
||||
*name = tsk_strdup(rtpmap);
|
||||
return 0;
|
||||
}
|
||||
return -2;
|
||||
}
|
||||
|
||||
|
|
@ -29,6 +29,8 @@
|
|||
*/
|
||||
#include "tinymedia/tmedia_session.h"
|
||||
|
||||
#include "tinymedia/tmedia_session_ghost.h"
|
||||
|
||||
#include "tsk_memory.h"
|
||||
#include "tsk_debug.h"
|
||||
|
||||
|
@ -43,10 +45,21 @@ const tmedia_session_plugin_def_t* __tmedia_session_plugins[TMED_SESSION_MAX_PLU
|
|||
/* === local functions === */
|
||||
int tmedia_session_mgr_prepare(tmedia_session_mgr_t* self);
|
||||
|
||||
const char* tmedia_session_get_media(const tmedia_session_t* self);
|
||||
const tsdp_header_M_t* tmedia_session_get_lo(tmedia_session_t* self);
|
||||
const tsdp_header_M_t* tmedia_session_get_no(tmedia_session_t* self);
|
||||
int tmedia_session_set_ro(tmedia_session_t* self, const tsdp_header_M_t* m);
|
||||
|
||||
|
||||
/*== Predicate function to find session object by media. */
|
||||
int __pred_find_session_by_media(const tsk_list_item_t *item, const void *media)
|
||||
{
|
||||
if(item && item->data){
|
||||
return tsk_stricmp(tmedia_session_get_media((tmedia_session_t *)item->data), (const char*)media);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**@ingroup tmedia_session_group
|
||||
* Initializes a newly created media session.
|
||||
* @param self the media session to initialize.
|
||||
|
@ -60,8 +73,11 @@ int tmedia_session_init(tmedia_session_t* self, tmedia_type_t type)
|
|||
return -1;
|
||||
}
|
||||
|
||||
/* set values */
|
||||
self->type = type;
|
||||
if(!self->initialized){
|
||||
/* set values */
|
||||
self->type = type;
|
||||
self->initialized = tsk_true;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -106,6 +122,27 @@ int tmedia_session_plugin_register(const tmedia_session_plugin_def_t* plugin)
|
|||
return -2;
|
||||
}
|
||||
|
||||
/**@ingroup tmedia_session_group
|
||||
* Finds a plugin by media.
|
||||
*/
|
||||
const tmedia_session_plugin_def_t* tmedia_session_plugin_find_by_media(const char* media)
|
||||
{
|
||||
tsk_size_t i = 0;
|
||||
if(!tsk_strnullORempty(media)){
|
||||
TSK_DEBUG_ERROR("Invalid parameter");
|
||||
return tsk_null;
|
||||
}
|
||||
|
||||
/* add or replace the plugin */
|
||||
while((i<TMED_SESSION_MAX_PLUGINS) && (__tmedia_session_plugins[i])){
|
||||
if(tsk_striequals(__tmedia_session_plugins[i]->media, media)){
|
||||
return __tmedia_session_plugins[i];
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return tsk_null;
|
||||
}
|
||||
|
||||
/**@ingroup tmedia_session_group
|
||||
* UnRegisters a session plugin.
|
||||
* @param plugin the definition of the plugin.
|
||||
|
@ -157,7 +194,9 @@ tmedia_session_t* tmedia_session_create(tmedia_type_t type)
|
|||
while((i < TMED_SESSION_MAX_PLUGINS) && (plugin = __tmedia_session_plugins[i++])){
|
||||
if(plugin->objdef && (plugin->type == type)){
|
||||
if((session = tsk_object_new(plugin->objdef))){
|
||||
tmedia_session_init(session, type);
|
||||
if(!session->initialized){
|
||||
tmedia_session_init(session, type);
|
||||
}
|
||||
session->plugin = plugin;
|
||||
}
|
||||
break;
|
||||
|
@ -180,6 +219,22 @@ int tmedia_session_prepare_lo(tmedia_session_t* self)
|
|||
return self->plugin->prepare(self);
|
||||
}
|
||||
|
||||
/* internal function: get media */
|
||||
const char* tmedia_session_get_media(const tmedia_session_t* self)
|
||||
{
|
||||
if(!self || !self->plugin){
|
||||
TSK_DEBUG_ERROR("Invalid parameter");
|
||||
return tsk_null;
|
||||
}
|
||||
|
||||
/* ghost? */
|
||||
if(self->plugin == tmedia_session_ghost_plugin_def_t){
|
||||
return ((const tmedia_session_ghost_t*)self)->media;
|
||||
}
|
||||
else{
|
||||
return self->plugin->media;
|
||||
}
|
||||
}
|
||||
/* internal function: get local offer */
|
||||
const tsdp_header_M_t* tmedia_session_get_lo(tmedia_session_t* self)
|
||||
{
|
||||
|
@ -262,6 +317,77 @@ int _tmedia_session_load_codecs(tmedia_session_t* self)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* internal function used to match a codec */
|
||||
const tmedia_codec_t* _tmedia_session_match_codec(tmedia_session_t* self, const tsdp_header_M_t* M)
|
||||
{
|
||||
const tmedia_codec_t *codec;
|
||||
char *rtpmap = tsk_null, *fmtp = tsk_null;
|
||||
const tsdp_fmt_t* fmt;
|
||||
const tsk_list_item_t *it1, *it2;
|
||||
tsk_bool_t found = tsk_false;
|
||||
|
||||
if(!self || !M){
|
||||
TSK_DEBUG_ERROR("Invalid parameter");
|
||||
return tsk_null;
|
||||
}
|
||||
|
||||
/* foreach format */
|
||||
tsk_list_foreach(it1, M->FMTs){
|
||||
fmt = it1->data;
|
||||
|
||||
/* foreach codec */
|
||||
tsk_list_foreach(it2, self->codecs){
|
||||
if(!(codec = it2->data) || !codec->plugin){
|
||||
continue;
|
||||
}
|
||||
|
||||
// Dyn. payload type
|
||||
if(codec->dyn && (rtpmap = tsdp_header_M_get_rtpmap(M, fmt->value))){
|
||||
char* name = tsk_null;
|
||||
int32_t rate, channels;
|
||||
/* parse rtpmap */
|
||||
if(tmedia_parse_rtpmap(rtpmap, &name, &rate, &channels)){
|
||||
TSK_FREE(name);
|
||||
TSK_DEBUG_ERROR("Failed to parse rtpmap(%s)", rtpmap);
|
||||
goto next;
|
||||
}
|
||||
/* compare name and rate. what about channels? */
|
||||
if(tsk_striequals(name, codec->name) && (!rate || (codec->plugin->rate == rate))){
|
||||
goto compare_fmtp;
|
||||
}
|
||||
}
|
||||
// Fixed payload type
|
||||
else{
|
||||
if(tsk_striequals(fmt->value, codec->format)){
|
||||
goto compare_fmtp;
|
||||
}
|
||||
}
|
||||
|
||||
/* free strings and try next */
|
||||
goto next;
|
||||
|
||||
compare_fmtp:
|
||||
if((fmtp = tsdp_header_M_get_fmtp(M, fmt->value))){ /* have fmtp? */
|
||||
if(tmedia_codec_match_fmtp(codec, fmtp)){ /* fmtp matches? */
|
||||
found = tsk_true;
|
||||
}
|
||||
}
|
||||
else{ /* no fmtp -> always match */
|
||||
found = tsk_true;
|
||||
}
|
||||
next:
|
||||
TSK_FREE(fmtp);
|
||||
TSK_FREE(rtpmap);
|
||||
if(found){
|
||||
return codec;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return tsk_null;
|
||||
}
|
||||
|
||||
/**@ingroup tmedia_session_group
|
||||
* Creates new session manager.
|
||||
* @param type the type of the session to create. For example, (@ref tmed_sess_type_audio | @ref tmed_sess_type_video).
|
||||
|
@ -360,10 +486,10 @@ tsdp_message_t* tmedia_session_mgr_get_no(tmedia_session_mgr_t* self)
|
|||
*/
|
||||
int tmedia_session_mgr_set_ro(tmedia_session_mgr_t* self, const tsdp_message_t* sdp)
|
||||
{
|
||||
const tsk_list_item_t* it1, *it2;
|
||||
const tmedia_session_t* ms;
|
||||
const tmedia_codec_t* codec;
|
||||
const tsdp_header_M_t* M;
|
||||
tsk_size_t index = 0;
|
||||
tsk_bool_t found;
|
||||
|
||||
if(!self || !sdp){
|
||||
TSK_DEBUG_ERROR("Invalid parameter");
|
||||
|
@ -374,7 +500,8 @@ int tmedia_session_mgr_set_ro(tmedia_session_mgr_t* self, const tsdp_message_t*
|
|||
TSK_OBJECT_SAFE_FREE(self->sdp.ro);
|
||||
self->sdp.ro = tsk_object_ref((void*)sdp);
|
||||
|
||||
/* prepare the session manager if not already done (create all sessions) */
|
||||
/* prepare the session manager if not already done (create all sessions with their codecs)
|
||||
* if net-initiated: think about tmedia_type_from_sdp() before creating the manager */
|
||||
if(!self->prepared){
|
||||
if(tmedia_session_mgr_prepare(self)){
|
||||
TSK_DEBUG_ERROR("Failed to prepare the session manager");
|
||||
|
@ -382,37 +509,63 @@ int tmedia_session_mgr_set_ro(tmedia_session_mgr_t* self, const tsdp_message_t*
|
|||
}
|
||||
}
|
||||
|
||||
tsk_list_foreach(it1, sdp->headers){
|
||||
if(!(it1->data) || (TSDP_HEADER(it1->data)->type != tsdp_htype_M)){
|
||||
continue;
|
||||
}
|
||||
M = (const tsdp_header_M_t*)(it1->data);
|
||||
}
|
||||
|
||||
/* foreach session */
|
||||
tsk_list_foreach(it1, self->sessions){
|
||||
if(!(ms = it1->data)){
|
||||
continue;
|
||||
/* foreach "m=" line in the remote offer create a session*/
|
||||
while((M = (const tsdp_header_M_t*)tsdp_message_get_headerAt(sdp, tsdp_htype_M, index++))){
|
||||
found = tsk_false;
|
||||
/* Find session by media */
|
||||
if((ms = tsk_list_find_data_by_pred(self->sessions, __pred_find_session_by_media, M->media))){
|
||||
/* set remote ro at session-level */
|
||||
if(tmedia_session_set_ro(TMEDIA_SESSION(ms), M) == 0){
|
||||
found = tsk_true;
|
||||
}
|
||||
}
|
||||
|
||||
/* for each codec in the curr. session */
|
||||
tsk_list_foreach(it2, ms->codecs){
|
||||
if(!(codec = it2->data)){
|
||||
if(!found){
|
||||
/* Session not supported ==> add ghost session */
|
||||
tmedia_session_ghost_t* ghost;
|
||||
if((ghost = (tmedia_session_ghost_t*)tmedia_session_create(tmedia_ghost))){
|
||||
tsk_strupdate(&ghost->media, M->media); /* copy media */
|
||||
tsk_list_push_back_data(self->sessions, (void**)&ghost);
|
||||
}
|
||||
else{
|
||||
TSK_DEBUG_ERROR("Failed to create ghost session");
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Codec with fixed payload type */
|
||||
if(!codec->dyn){
|
||||
|
||||
}
|
||||
/* codec with dyn. payload type */
|
||||
else{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* update negociated offer */
|
||||
if(self->sdp.lo && self->sdp.ro){
|
||||
TSK_OBJECT_SAFE_FREE(self->sdp.no);
|
||||
//...
|
||||
}
|
||||
|
||||
///* foreach session */
|
||||
//tsk_list_foreach(it1, self->sessions){
|
||||
// if(!(ms = it1->data)){
|
||||
// continue;
|
||||
// }
|
||||
//
|
||||
//
|
||||
|
||||
// /* foreach codec in the curr. session */
|
||||
// tsk_list_foreach(it2, ms->codecs){
|
||||
// if(!(codec = it2->data)){
|
||||
// continue;
|
||||
// }
|
||||
|
||||
// /* Codec with fixed payload type */
|
||||
// if(!codec->dyn){
|
||||
//
|
||||
// }
|
||||
// /* codec with dyn. payload type */
|
||||
// else{
|
||||
|
||||
// }
|
||||
// }
|
||||
//
|
||||
//}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -423,13 +576,16 @@ int tmedia_session_mgr_prepare(tmedia_session_mgr_t* self)
|
|||
tmedia_session_t* session;
|
||||
const tmedia_session_plugin_def_t* plugin;
|
||||
|
||||
/* for each registered plugin create a session instance */
|
||||
while((i < TMED_SESSION_MAX_PLUGINS) && (plugin = __tmedia_session_plugins[i++])){
|
||||
if((plugin->type & self->type) == plugin->type){
|
||||
if((session = tmedia_session_create(plugin->type))){
|
||||
tsk_list_push_back_data(self->sessions, (void**)(&session));
|
||||
if(!self->prepared){
|
||||
/* for each registered plugin create a session instance */
|
||||
while((i < TMED_SESSION_MAX_PLUGINS) && (plugin = __tmedia_session_plugins[i++])){
|
||||
if((plugin->type & self->type) == plugin->type){
|
||||
if((session = tmedia_session_create(plugin->type))){
|
||||
tsk_list_push_back_data(self->sessions, (void**)(&session));
|
||||
}
|
||||
}
|
||||
}
|
||||
self->prepared = tsk_true;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include "tsk_debug.h"
|
||||
|
||||
extern int _tmedia_session_load_codecs(tmedia_session_t* self);
|
||||
extern const tmedia_codec_t* _tmedia_session_match_codec(tmedia_session_t* self, const tsdp_header_M_t* M);
|
||||
|
||||
/* ============ Audio Session ================= */
|
||||
|
||||
|
@ -132,8 +133,18 @@ const tsdp_header_M_t* tmedia_session_daudio_get_no(tmedia_session_t* self)
|
|||
|
||||
int tmedia_session_daudio_set_ro(tmedia_session_t* self, const tsdp_header_M_t* m)
|
||||
{
|
||||
const tmedia_codec_t* codec;
|
||||
|
||||
TSK_DEBUG_INFO("tmedia_session_daudio_set_ro");
|
||||
return tsk_null;
|
||||
|
||||
if((codec = _tmedia_session_match_codec(self, m))){
|
||||
/* update remote offer */
|
||||
TSK_OBJECT_SAFE_FREE(self->M.ro);
|
||||
self->M.ro = tsk_object_ref((void*)m);
|
||||
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* ============ Video Session ================= */
|
||||
|
@ -147,19 +158,19 @@ int tmedia_session_dvideo_prepare(tmedia_session_t* self)
|
|||
int tmedia_session_dvideo_start(tmedia_session_t* self)
|
||||
{
|
||||
TSK_DEBUG_INFO("tmedia_session_dvideo_start");
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int tmedia_session_dvideo_stop(tmedia_session_t* self)
|
||||
{
|
||||
TSK_DEBUG_INFO("tmedia_session_dvideo_stop");
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int tmedia_session_dvideo_pause(tmedia_session_t* self)
|
||||
{
|
||||
TSK_DEBUG_INFO("tmedia_session_dvideo_pause");
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
const tsdp_header_M_t* tmedia_session_dvideo_get_lo(tmedia_session_t* self)
|
||||
|
@ -177,7 +188,7 @@ const tsdp_header_M_t* tmedia_session_dvideo_get_no(tmedia_session_t* self)
|
|||
int tmedia_session_dvideo_set_ro(tmedia_session_t* self, const tsdp_header_M_t* m)
|
||||
{
|
||||
TSK_DEBUG_INFO("tmedia_session_dvideo_set_ro");
|
||||
return tsk_null;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* ============ Msrp Session ================= */
|
||||
|
@ -185,25 +196,25 @@ int tmedia_session_dvideo_set_ro(tmedia_session_t* self, const tsdp_header_M_t*
|
|||
int tmedia_session_dmsrp_prepare(tmedia_session_t* self)
|
||||
{
|
||||
TSK_DEBUG_INFO("tmedia_session_dmsrp_prepare");
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int tmedia_session_dmsrp_start(tmedia_session_t* self)
|
||||
{
|
||||
TSK_DEBUG_INFO("tmedia_session_dmsrp_start");
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int tmedia_session_dmsrp_stop(tmedia_session_t* self)
|
||||
{
|
||||
TSK_DEBUG_INFO("tmedia_session_dmsrp_stop");
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int tmedia_session_dmsrp_pause(tmedia_session_t* self)
|
||||
{
|
||||
TSK_DEBUG_INFO("tmedia_session_dmsrp_pause");
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
const tsdp_header_M_t* tmedia_session_dmsrp_get_lo(tmedia_session_t* self)
|
||||
|
@ -221,7 +232,7 @@ const tsdp_header_M_t* tmedia_session_dmsrp_get_no(tmedia_session_t* self)
|
|||
int tmedia_session_dmsrp_set_ro(tmedia_session_t* self, const tsdp_header_M_t* m)
|
||||
{
|
||||
TSK_DEBUG_INFO("tmedia_session_dmsrp_set_ro");
|
||||
return tsk_null;
|
||||
return -1;
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
|
@ -243,6 +254,7 @@ static tsk_object_t* tmedia_session_daudio_dtor(tsk_object_t * self)
|
|||
tmedia_session_daudio_t *session = self;
|
||||
if(session){
|
||||
/* deinit base */
|
||||
tmedia_session_deinit(self);
|
||||
/* deinit self */
|
||||
}
|
||||
|
||||
|
@ -295,6 +307,7 @@ static tsk_object_t* tmedia_session_dvideo_dtor(tsk_object_t * self)
|
|||
tmedia_session_dvideo_t *session = self;
|
||||
if(session){
|
||||
/* deinit base */
|
||||
tmedia_session_deinit(self);
|
||||
/* deinit self */
|
||||
}
|
||||
|
||||
|
@ -347,6 +360,7 @@ static tsk_object_t* tmedia_session_dmsrp_dtor(tsk_object_t * self)
|
|||
tmedia_session_dmsrp_t *session = self;
|
||||
if(session){
|
||||
/* deinit base */
|
||||
tmedia_session_deinit(self);
|
||||
/* deinit self */
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,136 @@
|
|||
/*
|
||||
* Copyright (C) 2009 Mamadou Diop.
|
||||
*
|
||||
* Contact: Mamadou Diop <diopmamadou(at)doubango.org>
|
||||
*
|
||||
* This file is part of Open Source Doubango Framework.
|
||||
*
|
||||
* DOUBANGO 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* DOUBANGO 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 DOUBANGO.
|
||||
*
|
||||
*/
|
||||
|
||||
/**@file tmedia_session_ghost.c
|
||||
* @brief Ghost session.
|
||||
*
|
||||
* @author Mamadou Diop <diopmamadou(at)doubango.org>
|
||||
*
|
||||
* @date Created: Sat Nov 8 16:54:58 2009 mdiop
|
||||
*/
|
||||
#include "tinymedia/tmedia_session_ghost.h"
|
||||
|
||||
#include "tsk_memory.h"
|
||||
#include "tsk_debug.h"
|
||||
|
||||
/* ============ Ghost Session ================= */
|
||||
|
||||
int tmedia_session_ghost_prepare(tmedia_session_t* self)
|
||||
{
|
||||
TSK_DEBUG_INFO("tmedia_session_ghost_prepare");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tmedia_session_ghost_start(tmedia_session_t* self)
|
||||
{
|
||||
TSK_DEBUG_INFO("tmedia_session_ghost_start");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tmedia_session_ghost_stop(tmedia_session_t* self)
|
||||
{
|
||||
TSK_DEBUG_INFO("tmedia_session_ghost_stop");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tmedia_session_ghost_pause(tmedia_session_t* self)
|
||||
{
|
||||
TSK_DEBUG_INFO("tmedia_session_ghost_pause");
|
||||
return 0;
|
||||
}
|
||||
|
||||
const tsdp_header_M_t* tmedia_session_ghost_get_lo(tmedia_session_t* self)
|
||||
{
|
||||
TSK_DEBUG_INFO("tmedia_session_ghost_get_lo");
|
||||
return tsk_null;
|
||||
}
|
||||
|
||||
const tsdp_header_M_t* tmedia_session_ghost_get_no(tmedia_session_t* self)
|
||||
{
|
||||
TSK_DEBUG_INFO("tmedia_session_ghost_get_no");
|
||||
return tsk_null;
|
||||
}
|
||||
|
||||
int tmedia_session_ghost_set_ro(tmedia_session_t* self, const tsdp_header_M_t* m)
|
||||
{
|
||||
TSK_DEBUG_INFO("tmedia_session_ghost_set_ro");
|
||||
return tsk_null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//=================================================================================================
|
||||
// Ghost session object definition
|
||||
//
|
||||
/* constructor */
|
||||
static tsk_object_t* tmedia_session_ghost_ctor(tsk_object_t * self, va_list * app)
|
||||
{
|
||||
tmedia_session_ghost_t *session = self;
|
||||
if(session){
|
||||
/* init base */
|
||||
tmedia_session_init(TMEDIA_SESSION(session), tmedia_none);
|
||||
/* init self */
|
||||
}
|
||||
return self;
|
||||
}
|
||||
/* destructor */
|
||||
static tsk_object_t* tmedia_session_ghost_dtor(tsk_object_t * self)
|
||||
{
|
||||
tmedia_session_ghost_t *session = self;
|
||||
if(session){
|
||||
/* deinit base */
|
||||
tmedia_session_deinit(TMEDIA_SESSION(session));
|
||||
/* deinit self */
|
||||
TSK_FREE(session->media);
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
/* object definition */
|
||||
static const tsk_object_def_t tmedia_session_ghost_def_s =
|
||||
{
|
||||
sizeof(tmedia_session_ghost_t),
|
||||
tmedia_session_ghost_ctor,
|
||||
tmedia_session_ghost_dtor,
|
||||
tmedia_codec_cmp,
|
||||
};
|
||||
/* plugin definition*/
|
||||
static const tmedia_session_plugin_def_t tmedia_session_ghost_plugin_def_s =
|
||||
{
|
||||
&tmedia_session_ghost_def_s,
|
||||
|
||||
tmedia_ghost,
|
||||
"ghost",
|
||||
|
||||
tmedia_session_ghost_prepare,
|
||||
tmedia_session_ghost_start,
|
||||
tmedia_session_ghost_stop,
|
||||
tmedia_session_ghost_pause,
|
||||
|
||||
tmedia_session_ghost_get_lo,
|
||||
tmedia_session_ghost_get_no,
|
||||
tmedia_session_ghost_set_ro
|
||||
};
|
||||
const tmedia_session_plugin_def_t *tmedia_session_ghost_plugin_def_t = &tmedia_session_ghost_plugin_def_s;
|
|
@ -30,7 +30,7 @@
|
|||
#define RUN_TEST_LOOP 1
|
||||
|
||||
#define RUN_TEST_ALL 0
|
||||
#define RUN_TEST_CODECS 1
|
||||
#define RUN_TEST_CODECS 0
|
||||
#define RUN_TEST_SESSIONS 1
|
||||
|
||||
void test_register_dummy_plugins();
|
||||
|
@ -75,6 +75,9 @@ void test_register_dummy_plugins()
|
|||
if((ret = tmedia_session_plugin_register(tmedia_session_dmsrp_plugin_def_t))){
|
||||
TSK_DEBUG_ERROR("Failed to register msrp plugin");
|
||||
}
|
||||
if((ret = tmedia_session_plugin_register(tmedia_session_ghost_plugin_def_t))){
|
||||
TSK_DEBUG_ERROR("Failed to register ghost plugin");
|
||||
}
|
||||
|
||||
/* === Codecs === */
|
||||
if((ret = tmedia_codec_plugin_register(tmedia_codec_dpcma_plugin_def_t))){
|
||||
|
|
|
@ -22,6 +22,46 @@
|
|||
#ifndef _TEST_SESSIONS_H_
|
||||
#define _TEST_SESSIONS_H_
|
||||
|
||||
#define SDP_RO \
|
||||
"v=0\r\n" \
|
||||
"o=alice 2890844526 2890844526 IN IP4 host.atlanta.example.com\r\n" \
|
||||
"s=\r\n" \
|
||||
"i=A Seminar on the session description protocol\r\n" \
|
||||
"u=http://www.example.com/seminars/sdp.pdf\r\n" \
|
||||
"e=j.doe@example.com (Jane Doe)\r\n" \
|
||||
"p=+1 617 555-6011\r\n" \
|
||||
"c=IN IP4 host.atlanta.example.com\r\n" \
|
||||
"b=X-YZ:128\r\n" \
|
||||
"z=2882844526 -1h 2898848070 0\r\n" \
|
||||
"k=base64:ZWFzdXJlLg==\r\n" \
|
||||
"t=3034423619 3042462419\r\n" \
|
||||
"r=7d 1h 0 25h\r\n" \
|
||||
"r=604800 3600 0 90000\r\n" \
|
||||
"w=my dummy header\r\n" \
|
||||
"m=audio 49170 RTP/AVP 0 8 97 98\r\n" \
|
||||
"i=Audio line\r\n" \
|
||||
"c=IN IP4 otherhost.biloxi.example.com\r\n" \
|
||||
"k=base64:ZWFzdXJlLgdddddddddddddddddddddd==\r\n" \
|
||||
"a=rtpmap:0 PCMU/8000\r\n" \
|
||||
"a=rtpmap:8 PCMA/8000\r\n" \
|
||||
"a=rtpmap:97 iLBC/8000\r\n" \
|
||||
"a=rtpmap:98 AMR-WB/16000\r\n" \
|
||||
"a=fmtp:98 octet-align=1\r\n" \
|
||||
"m=video 51372 RTP/AVP 31 32\r\n" \
|
||||
"i=Video line\r\n" \
|
||||
"b=A-YZ:92\r\n" \
|
||||
"b=B-YZ:256\r\n" \
|
||||
"a=rtpmap:31 H261/90000\r\n" \
|
||||
"a=rtpmap:32 MPV/90000\r\n" \
|
||||
"a=recvonly\r\n" \
|
||||
"m=toto 51372 RTP/AVP 31 32\r\n" \
|
||||
"i=Video line\r\n" \
|
||||
"b=A-YZ:92\r\n" \
|
||||
"b=B-YZ:256\r\n" \
|
||||
"a=rtpmap:31 H261/90000\r\n" \
|
||||
"a=rtpmap:32 MPV/90000\r\n" \
|
||||
"a=recvonly\r\n"
|
||||
|
||||
void test_sessions()
|
||||
{
|
||||
tmedia_session_mgr_t* mgr;
|
||||
|
@ -33,12 +73,18 @@ void test_sessions()
|
|||
mgr = tmedia_session_mgr_create((tmedia_audio | tmedia_video | tmedia_msrp | tmedia_t38),
|
||||
"192.168.16.82", tsk_false);
|
||||
|
||||
/* get local sdp */
|
||||
/* get lo */
|
||||
sdp_lo = tmedia_session_mgr_get_lo(mgr);
|
||||
if((temp = tsdp_message_tostring(sdp_lo))){
|
||||
TSK_DEBUG_INFO("sdp_lo=%s", temp);
|
||||
TSK_FREE(temp);
|
||||
}
|
||||
|
||||
/* set ro */
|
||||
if((sdp_ro = tsdp_message_parse(SDP_RO, tsk_strlen(SDP_RO)))){
|
||||
tmedia_session_mgr_set_ro(mgr, sdp_ro);
|
||||
TSK_OBJECT_SAFE_FREE(sdp_ro);
|
||||
}
|
||||
|
||||
TSK_OBJECT_SAFE_FREE(mgr);
|
||||
}
|
||||
|
|
|
@ -178,6 +178,10 @@
|
|||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\include\tinymedia.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\include\tinymedia_config.h"
|
||||
>
|
||||
|
@ -206,6 +210,10 @@
|
|||
RelativePath=".\include\tinymedia\tmedia_session_dummy.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\include\tinymedia\tmedia_session_ghost.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="source(*.c)"
|
||||
|
@ -224,6 +232,10 @@
|
|||
RelativePath=".\src\tmedia_codec_dummy.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\tmedia_common.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\tmedia_session.c"
|
||||
>
|
||||
|
@ -232,6 +244,10 @@
|
|||
RelativePath=".\src\tmedia_session_dummy.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\tmedia_session_ghost.c"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
|
|
|
@ -395,6 +395,7 @@ const tsk_list_item_t* tsk_list_find_item_by_data(const tsk_list_t* list, const
|
|||
* @param predicate the predicate against which to test each item
|
||||
* @param data data passed to the predicate function for comparaison
|
||||
* @retval the item which match the criteria and NULL otherwise
|
||||
* @sa @ref tsk_list_find_data_by_pred
|
||||
*/
|
||||
const tsk_list_item_t* tsk_list_find_item_by_pred(const tsk_list_t* list, tsk_list_func_predicate predicate, const void* data)
|
||||
{
|
||||
|
@ -412,6 +413,25 @@ const tsk_list_item_t* tsk_list_find_item_by_pred(const tsk_list_t* list, tsk_li
|
|||
return tsk_null;
|
||||
}
|
||||
|
||||
/**@ingroup tsk_list_group
|
||||
* Find first item matching criteria defined by the @a predicate.
|
||||
* @param list the list to query
|
||||
* @param predicate the predicate against which to test each item
|
||||
* @param data data passed to the predicate function for comparaison
|
||||
* @retval the data holded by the item which match the criteria and NULL otherwise
|
||||
* @sa @ref tsk_list_find_item_by_pred
|
||||
*/
|
||||
const tsk_object_t* tsk_list_find_data_by_pred(const tsk_list_t* list, tsk_list_func_predicate predicate, const void* data)
|
||||
{
|
||||
const tsk_list_item_t *item;
|
||||
if((item = tsk_list_find_item_by_pred(list, predicate, data))){
|
||||
return item->data;
|
||||
}
|
||||
else{
|
||||
return tsk_null;
|
||||
}
|
||||
}
|
||||
|
||||
/**@ingroup tsk_list_group
|
||||
* Counts the number of item matching the predicate.
|
||||
* @param list The list containing the items to count
|
||||
|
|
|
@ -114,6 +114,7 @@ TINYSAK_API int tsk_list_push_filtered_data(tsk_list_t* list, void** data, tsk_b
|
|||
|
||||
TINYSAK_API const tsk_list_item_t* tsk_list_find_item_by_data(const tsk_list_t* list, const tsk_object_t * tskobj);
|
||||
TINYSAK_API const tsk_list_item_t* tsk_list_find_item_by_pred(const tsk_list_t* list, tsk_list_func_predicate predicate, const void* data);
|
||||
TINYSAK_API const tsk_object_t* tsk_list_find_data_by_pred(const tsk_list_t* list, tsk_list_func_predicate predicate, const void* data);
|
||||
TINYSAK_API tsk_size_t tsk_list_count(const tsk_list_t* list, tsk_list_func_predicate predicate, const void* data);
|
||||
|
||||
TINYSAK_GEXTERN const tsk_object_def_t *tsk_list_def_t;
|
||||
|
|
|
@ -35,6 +35,8 @@
|
|||
#include "tinysdp/headers/tsdp_header_T.h"
|
||||
#include "tinysdp/headers/tsdp_header_V.h"
|
||||
|
||||
#include "tsk_debug.h"
|
||||
|
||||
#define TSDP_LINE_S_VALUE_DEFAULT "-" /* as per RFC 3264 subclause 5 */
|
||||
|
||||
#define TSDP_LINE_O_USERNAME_DEFAULT "doubango"
|
||||
|
@ -44,8 +46,7 @@
|
|||
/*== Predicate function to find tsdp_header_t object by type. */
|
||||
int __pred_find_header_by_type(const tsk_list_item_t *item, const void *tsdp_htype)
|
||||
{
|
||||
if(item && item->data)
|
||||
{
|
||||
if(item && item->data){
|
||||
tsdp_header_t *header = item->data;
|
||||
tsdp_header_type_t htype = *((tsdp_header_type_t*)tsdp_htype);
|
||||
return (header->type - htype);
|
||||
|
@ -56,8 +57,7 @@ int __pred_find_header_by_type(const tsk_list_item_t *item, const void *tsdp_hty
|
|||
/*== Predicate function to find tsdp_header_t object by name. */
|
||||
int __pred_find_header_by_name(const tsk_list_item_t *item, const void *name)
|
||||
{
|
||||
if(item && item->data && name)
|
||||
{
|
||||
if(item && item->data && name){
|
||||
tsdp_header_t *header = item->data;
|
||||
return tsdp_header_get_nameex(header) - *((const char*)name);
|
||||
}
|
||||
|
@ -67,8 +67,7 @@ int __pred_find_header_by_name(const tsk_list_item_t *item, const void *name)
|
|||
/*== Predicate function to find media object by name. */
|
||||
int __pred_find_media_by_name(const tsk_list_item_t *item, const void *name)
|
||||
{
|
||||
if(item && item->data && name)
|
||||
{
|
||||
if(item && item->data && name){
|
||||
tsdp_header_t *header = item->data;
|
||||
if(header->type == tsdp_htype_M){
|
||||
return tsk_stricmp(((tsdp_header_M_t*)header)->media, (const char*)name);
|
||||
|
@ -171,13 +170,13 @@ const tsdp_header_t *tsdp_message_get_header(const tsdp_message_t *self, tsdp_he
|
|||
|
||||
const tsdp_header_t *tsdp_message_get_headerByName(const tsdp_message_t *self, char name)
|
||||
{
|
||||
if(self && self->headers){
|
||||
const tsk_list_item_t* item;
|
||||
if((item = tsk_list_find_item_by_pred(self->headers, __pred_find_header_by_name, &name))){
|
||||
return item->data;
|
||||
}
|
||||
if(self){
|
||||
return tsk_list_find_data_by_pred(self->headers, __pred_find_header_by_name, &name);
|
||||
}
|
||||
else{
|
||||
TSK_DEBUG_ERROR("Invalid parameter");
|
||||
return tsk_null;
|
||||
}
|
||||
return tsk_null;
|
||||
}
|
||||
|
||||
int tsdp_message_serialize(const tsdp_message_t *self, tsk_buffer_t *output)
|
||||
|
|
Loading…
Reference in New Issue