diff options
author | Mamadou DIOP <bossiel@yahoo.fr> | 2016-02-23 22:00:35 +0100 |
---|---|---|
committer | Mamadou DIOP <bossiel@yahoo.fr> | 2016-02-23 22:00:35 +0100 |
commit | 50dfb4359619563012997bc3ddafb7667741066c (patch) | |
tree | db234c1edc3240a653363b5735fc4077af4b8720 /tinyMEDIA | |
parent | 94b2219209038e05dd26395f6fb700be4d1062c0 (diff) | |
download | doubango-50dfb4359619563012997bc3ddafb7667741066c.zip doubango-50dfb4359619563012997bc3ddafb7667741066c.tar.gz |
Add new QoS implementation
Code formatting
Diffstat (limited to 'tinyMEDIA')
48 files changed, 8902 insertions, 8595 deletions
diff --git a/tinyMEDIA/include/tinymedia.h b/tinyMEDIA/include/tinymedia.h index bdee2d8..f781014 100755 --- a/tinyMEDIA/include/tinymedia.h +++ b/tinyMEDIA/include/tinymedia.h @@ -2,19 +2,19 @@ * Copyright (C) 2010-2011 Mamadou Diop. * * Contact: Mamadou Diop <diopmamadou(at)doubango[dot]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. * diff --git a/tinyMEDIA/include/tinymedia/content/tmedia_content.h b/tinyMEDIA/include/tinymedia/content/tmedia_content.h index 41b1ecb..d0d6f5c 100755 --- a/tinyMEDIA/include/tinymedia/content/tmedia_content.h +++ b/tinyMEDIA/include/tinymedia/content/tmedia_content.h @@ -2,19 +2,19 @@ * Copyright (C) 2010-2011 Mamadou Diop. * * Contact: Mamadou Diop <diopmamadou(at)doubango[dot]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. * @@ -44,27 +44,25 @@ TMEDIA_BEGIN_DECLS #define TMEDIA_CONTENT(self) ((tmedia_content_t*)(self)) /** Base object for all contents */ -typedef struct tmedia_content_s -{ - TSK_DECLARE_OBJECT; +typedef struct tmedia_content_s { + TSK_DECLARE_OBJECT; - const char* type; - //! plugin used to create the codec - const struct tmedia_content_plugin_def_s* plugin; + const char* type; + //! plugin used to create the codec + const struct tmedia_content_plugin_def_s* plugin; } tmedia_content_t; /** Virtual table used to define a content plugin */ -typedef struct tmedia_content_plugin_def_s -{ - //! object definition used to create an instance of the codec - const tsk_object_def_t* objdef; +typedef struct tmedia_content_plugin_def_s { + //! object definition used to create an instance of the codec + const tsk_object_def_t* objdef; - //! e.g. 'message/CPIM' - const char* type; + //! e.g. 'message/CPIM' + const char* type; - int (*parse) (tmedia_content_t*, const void* in_data, tsk_size_t in_size); - tsk_buffer_t* (*get_data) (tmedia_content_t*); + int (*parse) (tmedia_content_t*, const void* in_data, tsk_size_t in_size); + tsk_buffer_t* (*get_data) (tmedia_content_t*); } tmedia_content_plugin_def_t; @@ -86,11 +84,10 @@ TINYMEDIA_API int tmedia_content_deinit(tmedia_content_t* self); TINYMEDIA_API tsk_buffer_t* tmedia_content_get_data(tmedia_content_t* self); /** dummy content */ -typedef struct tmedia_content_dummy_s -{ - TMEDIA_DECLARE_CONTENT; - - tsk_buffer_t* data; +typedef struct tmedia_content_dummy_s { + TMEDIA_DECLARE_CONTENT; + + tsk_buffer_t* data; } tmedia_content_dummy_t; @@ -101,13 +98,12 @@ TINYMEDIA_GEXTERN const tmedia_content_plugin_def_t *tmedia_content_dummy_plugin /** content header */ -typedef struct tmedia_content_header_s -{ - TSK_DECLARE_OBJECT; +typedef struct tmedia_content_header_s { + TSK_DECLARE_OBJECT; - char* name; - char* value; - tsk_params_L_t* params; + char* name; + char* value; + tsk_params_L_t* params; } tmedia_content_header_t; diff --git a/tinyMEDIA/include/tinymedia/content/tmedia_content_cpim.h b/tinyMEDIA/include/tinymedia/content/tmedia_content_cpim.h index db1aa02..625ffc3 100755 --- a/tinyMEDIA/include/tinymedia/content/tmedia_content_cpim.h +++ b/tinyMEDIA/include/tinymedia/content/tmedia_content_cpim.h @@ -2,19 +2,19 @@ * Copyright (C) 2010-2011 Mamadou Diop. * * Contact: Mamadou Diop <diopmamadou(at)doubango[dot]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. * @@ -38,14 +38,13 @@ TMEDIA_BEGIN_DECLS #define TMEDIA_CONTENT_CPIM_TYPE "message/CPIM" /** message/CPIM content */ -typedef struct tmedia_content_cpim_s -{ - TMEDIA_DECLARE_CONTENT; - - tmedia_content_headers_L_t* m_headers; /**< MIME headers for the overall message */ - tmedia_content_headers_L_t* h_headers; /**< message headers */ - tsk_buffer_t* e; /**< encapsulated MIME object containing the message content */ - tsk_buffer_t* x; /**< MIME security multipart message wrapper */ +typedef struct tmedia_content_cpim_s { + TMEDIA_DECLARE_CONTENT; + + tmedia_content_headers_L_t* m_headers; /**< MIME headers for the overall message */ + tmedia_content_headers_L_t* h_headers; /**< message headers */ + tsk_buffer_t* e; /**< encapsulated MIME object containing the message content */ + tsk_buffer_t* x; /**< MIME security multipart message wrapper */ } tmedia_content_cpim_t; diff --git a/tinyMEDIA/include/tinymedia/tmedia.h b/tinyMEDIA/include/tinymedia/tmedia.h index d10ee69..66afc80 100755 --- a/tinyMEDIA/include/tinymedia/tmedia.h +++ b/tinyMEDIA/include/tinymedia/tmedia.h @@ -2,19 +2,19 @@ * Copyright (C) 2010-2011 Mamadou Diop. * * Contact: Mamadou Diop <diopmamadou(at)doubango[dot]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. * @@ -47,51 +47,48 @@ TMEDIA_BEGIN_DECLS #define TMEDIA(self) ((tmedia_t*)(self)) -typedef enum tmedia_action_e -{ - // Dummy - tma_dummy_say_hello, +typedef enum tmedia_action_e { + // Dummy + tma_dummy_say_hello, - // MSRP - tma_msrp_send_data, - tma_msrp_send_file, + // MSRP + tma_msrp_send_data, + tma_msrp_send_file, - // Audio / Video + // Audio / Video - // T.38 + // T.38 } tmedia_action_t; -typedef struct tmedia_s -{ - TSK_DECLARE_OBJECT; +typedef struct tmedia_s { + TSK_DECLARE_OBJECT; + + const struct tmedia_plugin_def_s* plugin; - const struct tmedia_plugin_def_s* plugin; - - char* name; - uint32_t port; - char* protocol; + char* name; + uint32_t port; + char* protocol; } tmedia_t; typedef tsk_list_t tmedias_L_t; #define TMED_DECLARE_MEDIA tmedia_t media -typedef struct tmedia_plugin_def_s -{ - const tsk_object_def_t* objdef; - const char* name; - const char* media; - - int (* start) (tmedia_t* ); - int (* pause) (tmedia_t* ); - int (* stop) (tmedia_t* ); - - const tsdp_header_M_t* (* get_local_offer) (tmedia_t* , va_list* ); - const tsdp_header_M_t* (* get_negotiated_offer) (tmedia_t* ); - int (* set_remote_offer) (tmedia_t* , const tsdp_message_t* ); - - int (* perform) (tmedia_t* , tmedia_action_t action, const tsk_params_L_t* ); +typedef struct tmedia_plugin_def_s { + const tsk_object_def_t* objdef; + const char* name; + const char* media; + + int (* start) (tmedia_t* ); + int (* pause) (tmedia_t* ); + int (* stop) (tmedia_t* ); + + const tsdp_header_M_t* (* get_local_offer) (tmedia_t* , va_list* ); + const tsdp_header_M_t* (* get_negotiated_offer) (tmedia_t* ); + int (* set_remote_offer) (tmedia_t* , const tsdp_message_t* ); + + int (* perform) (tmedia_t* , tmedia_action_t action, const tsk_params_L_t* ); } tmedia_plugin_def_t; diff --git a/tinyMEDIA/include/tinymedia/tmedia_codec.h b/tinyMEDIA/include/tinymedia/tmedia_codec.h index f29abf6..6dcd2be 100755 --- a/tinyMEDIA/include/tinymedia/tmedia_codec.h +++ b/tinyMEDIA/include/tinymedia/tmedia_codec.h @@ -1,18 +1,18 @@ /* * Copyright (C) 2010-2015 Mamadou DIOP. -* +* * 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. * @@ -35,7 +35,7 @@ TMEDIA_BEGIN_DECLS /* ===== -* http://www.iana.org/assignments/rtp-parameters +* http://www.iana.org/assignments/rtp-parameters * http://www.networksorcery.com/enp/protocol/rtp.htm =====*/ /******* Fixed Payload Type *************/ @@ -68,7 +68,7 @@ TMEDIA_BEGIN_DECLS #define TMEDIA_CODEC_FORMAT_MP2T "33" #define TMEDIA_CODEC_FORMAT_H263 "34" -/******* Dynamic Payload Type +/******* Dynamic Payload Type Must starts at 96 to be conform to RFC 5761 (rtcp-mux) **********/ @@ -115,51 +115,50 @@ Must starts at 96 to be conform to RFC 5761 (rtcp-mux) // @tinyWRAP -typedef enum tmedia_codec_id_e -{ - tmedia_codec_id_none = 0x00000000, - - tmedia_codec_id_amr_nb_oa = 0x00000001<<0, - tmedia_codec_id_amr_nb_be = 0x00000001<<1, - tmedia_codec_id_amr_wb_oa = 0x00000001<<2, - tmedia_codec_id_amr_wb_be = 0x00000001<<3, - tmedia_codec_id_gsm = 0x00000001<<4, - tmedia_codec_id_pcma = 0x00000001<<5, - tmedia_codec_id_pcmu = 0x00000001<<6, - tmedia_codec_id_ilbc = 0x00000001<<7, - tmedia_codec_id_speex_nb = 0x00000001<<8, - tmedia_codec_id_speex_wb = 0x00000001<<9, - tmedia_codec_id_speex_uwb = 0x00000001<<10, - tmedia_codec_id_bv16 = 0x00000001<<11, - tmedia_codec_id_bv32 = 0x00000001<<12, - tmedia_codec_id_opus = 0x00000001<<13, - tmedia_codec_id_g729ab = 0x00000001<<14, - tmedia_codec_id_g722 = 0x00000001<<15, - - /* room for new Audio codecs */ - - tmedia_codec_id_h261 = 0x00010000<<0, - tmedia_codec_id_h263 = 0x00010000<<1, - tmedia_codec_id_h263p = 0x00010000<<2, - tmedia_codec_id_h263pp = 0x00010000<<3, - tmedia_codec_id_h264_bp = 0x00010000<<4, - tmedia_codec_id_h264_mp = 0x00010000<<5, - tmedia_codec_id_h264_hp = 0x00010000<<6, - tmedia_codec_id_h264_bp10 = tmedia_codec_id_h264_bp, // @deprecated - tmedia_codec_id_h264_bp20 = tmedia_codec_id_h264_bp, // @deprecated - tmedia_codec_id_h264_bp30 = tmedia_codec_id_h264_bp, // @deprecated - tmedia_codec_id_h264_svc = 0x00010000<<7, - tmedia_codec_id_theora = 0x00010000<<8, - tmedia_codec_id_mp4ves_es = 0x00010000<<9, - tmedia_codec_id_vp8 = 0x00010000<<10, - - /* room for new Video codecs */ - - tmedia_codec_id_t140 = 0x00010000<<14, - tmedia_codec_id_red = 0x00010000<<15, - - - tmedia_codec_id_all = 0xffffffff, +typedef enum tmedia_codec_id_e { + tmedia_codec_id_none = 0x00000000, + + tmedia_codec_id_amr_nb_oa = 0x00000001<<0, + tmedia_codec_id_amr_nb_be = 0x00000001<<1, + tmedia_codec_id_amr_wb_oa = 0x00000001<<2, + tmedia_codec_id_amr_wb_be = 0x00000001<<3, + tmedia_codec_id_gsm = 0x00000001<<4, + tmedia_codec_id_pcma = 0x00000001<<5, + tmedia_codec_id_pcmu = 0x00000001<<6, + tmedia_codec_id_ilbc = 0x00000001<<7, + tmedia_codec_id_speex_nb = 0x00000001<<8, + tmedia_codec_id_speex_wb = 0x00000001<<9, + tmedia_codec_id_speex_uwb = 0x00000001<<10, + tmedia_codec_id_bv16 = 0x00000001<<11, + tmedia_codec_id_bv32 = 0x00000001<<12, + tmedia_codec_id_opus = 0x00000001<<13, + tmedia_codec_id_g729ab = 0x00000001<<14, + tmedia_codec_id_g722 = 0x00000001<<15, + + /* room for new Audio codecs */ + + tmedia_codec_id_h261 = 0x00010000<<0, + tmedia_codec_id_h263 = 0x00010000<<1, + tmedia_codec_id_h263p = 0x00010000<<2, + tmedia_codec_id_h263pp = 0x00010000<<3, + tmedia_codec_id_h264_bp = 0x00010000<<4, + tmedia_codec_id_h264_mp = 0x00010000<<5, + tmedia_codec_id_h264_hp = 0x00010000<<6, + tmedia_codec_id_h264_bp10 = tmedia_codec_id_h264_bp, // @deprecated + tmedia_codec_id_h264_bp20 = tmedia_codec_id_h264_bp, // @deprecated + tmedia_codec_id_h264_bp30 = tmedia_codec_id_h264_bp, // @deprecated + tmedia_codec_id_h264_svc = 0x00010000<<7, + tmedia_codec_id_theora = 0x00010000<<8, + tmedia_codec_id_mp4ves_es = 0x00010000<<9, + tmedia_codec_id_vp8 = 0x00010000<<10, + + /* room for new Video codecs */ + + tmedia_codec_id_t140 = 0x00010000<<14, + tmedia_codec_id_red = 0x00010000<<15, + + + tmedia_codec_id_all = 0xffffffff, } tmedia_codec_id_t; @@ -196,108 +195,105 @@ typedef int (*tmedia_codec_video_dec_cb_f)(const tmedia_video_decode_result_xt* struct tmedia_param_s; struct tsdp_header_M_s; -typedef enum tmedia_codec_action_e -{ - tmedia_codec_action_encode_idr, - tmedia_codec_action_bw_down, - tmedia_codec_action_bw_up, +typedef enum tmedia_codec_action_e { + tmedia_codec_action_encode_idr, + tmedia_codec_action_bw_down, + tmedia_codec_action_bw_up, } tmedia_codec_action_t; /** Base object for all Codecs */ -typedef struct tmedia_codec_s -{ - TSK_DECLARE_OBJECT; - - //! the type of the codec - tmedia_type_t type; - //! the codec identifier - tmedia_codec_id_t id; - //! whether the codec is opened - tsk_bool_t opened; - //! whether the pay. type is dyn. or not - tsk_bool_t dyn; - //! the name of the codec. e.g. "G.711U" or "G.711A" etc used in the sdp - char* name; - //! full description - char* desc; - //! the format. e.g. "0" for PCMU or "8" for PCMA or "*" for MSRP. - char* format; - //! bandwidth level - tmedia_bandwidth_level_t bl; // @deprecated - //! maximum bandwidth to use for outgoing RTP (INT_MAX or <=0 means undefined) - int32_t bandwidth_max_upload; - //! maximum bandwidth to use for incoming RTP (INT_MAX or <=0 means undefined) - int32_t bandwidth_max_download; - //! the negociated format (only useful for codecs with dyn. payload type) - char* neg_format; - //! whether this is a passthrough codec - tsk_bool_t passthrough; - - struct{ - // !negotiated decoding rate (for codecs with dynamic rate, e.g. opus) - uint32_t rate; - } in; //decoding direction - struct{ - // !negotiated encoding rate (for codecs with dynamic rate, e.g. opus) - uint32_t rate; - } out; //encoding direction - - //! plugin used to create the codec - const struct tmedia_codec_plugin_def_s* plugin; +typedef struct tmedia_codec_s { + TSK_DECLARE_OBJECT; + + //! the type of the codec + tmedia_type_t type; + //! the codec identifier + tmedia_codec_id_t id; + //! whether the codec is opened + tsk_bool_t opened; + //! whether the pay. type is dyn. or not + tsk_bool_t dyn; + //! the name of the codec. e.g. "G.711U" or "G.711A" etc used in the sdp + char* name; + //! full description + char* desc; + //! the format. e.g. "0" for PCMU or "8" for PCMA or "*" for MSRP. + char* format; + //! bandwidth level + tmedia_bandwidth_level_t bl; // @deprecated + //! maximum bandwidth to use for outgoing RTP (INT_MAX or <=0 means undefined) + int32_t bandwidth_max_upload; + //! maximum bandwidth to use for incoming RTP (INT_MAX or <=0 means undefined) + int32_t bandwidth_max_download; + //! the negociated format (only useful for codecs with dyn. payload type) + char* neg_format; + //! whether this is a passthrough codec + tsk_bool_t passthrough; + + struct { + // !negotiated decoding rate (for codecs with dynamic rate, e.g. opus) + uint32_t rate; + } in; //decoding direction + struct { + // !negotiated encoding rate (for codecs with dynamic rate, e.g. opus) + uint32_t rate; + } out; //encoding direction + + //! plugin used to create the codec + const struct tmedia_codec_plugin_def_s* plugin; } tmedia_codec_t; #define TMEDIA_CODEC(self) ((tmedia_codec_t*)(self)) /** Virtual table used to define a codec plugin */ -typedef struct tmedia_codec_plugin_def_s -{ - //! object definition used to create an instance of the codec - const tsk_object_def_t* objdef; - - //! the type of the codec - tmedia_type_t type; - //! the codec identifier - tmedia_codec_id_t codec_id; - //! the name of the codec. e.g. "G.711U" or "G.711A" etc using in the sdp. - const char* name; - //! full description - const char* desc; - //! the format. e.g. "0" for PCMU or "8" for PCMA or "*" for MSRP. - const char* format; - //! whether the pay. type is dyn. or not - tsk_bool_t dyn; - uint32_t rate; - - /* default values could be updated at any time */ - struct{ - int8_t channels; - uint8_t ptime; - /* ...to be continued */ - } audio; - - /* default values could be updated at any time */ - struct{ - unsigned width; - unsigned height; - unsigned fps; - /* ...to be continued */ - } video; - - //! set parameters - int (*set) (tmedia_codec_t* , const struct tmedia_param_s*); - //! open the codec - int (*open) (tmedia_codec_t*); - //! close the codec - int (*close) (tmedia_codec_t*); - //! encode data - tsk_size_t (*encode) (tmedia_codec_t*, const void* in_data, tsk_size_t in_size, void** out_data, tsk_size_t* out_max_size); - //! decode data - tsk_size_t (*decode) (tmedia_codec_t*, const void* in_data, tsk_size_t in_size, void** out_data, tsk_size_t* out_max_size, const tsk_object_t* proto_hdr); - //! whether the codec can handle this sdp attribute - tsk_bool_t (* sdp_att_match) (const tmedia_codec_t*, const char* att_name, const char* att_value); - //! gets sdp attribute value. e.g. "mode-set=0,2,5,7; mode-change-period=2; mode-change-neighbor=1" - char* (* sdp_att_get) (const tmedia_codec_t*, const char* att_name); +typedef struct tmedia_codec_plugin_def_s { + //! object definition used to create an instance of the codec + const tsk_object_def_t* objdef; + + //! the type of the codec + tmedia_type_t type; + //! the codec identifier + tmedia_codec_id_t codec_id; + //! the name of the codec. e.g. "G.711U" or "G.711A" etc using in the sdp. + const char* name; + //! full description + const char* desc; + //! the format. e.g. "0" for PCMU or "8" for PCMA or "*" for MSRP. + const char* format; + //! whether the pay. type is dyn. or not + tsk_bool_t dyn; + uint32_t rate; + + /* default values could be updated at any time */ + struct { + int8_t channels; + uint8_t ptime; + /* ...to be continued */ + } audio; + + /* default values could be updated at any time */ + struct { + unsigned width; + unsigned height; + unsigned fps; + /* ...to be continued */ + } video; + + //! set parameters + int (*set) (tmedia_codec_t* , const struct tmedia_param_s*); + //! open the codec + int (*open) (tmedia_codec_t*); + //! close the codec + int (*close) (tmedia_codec_t*); + //! encode data + tsk_size_t (*encode) (tmedia_codec_t*, const void* in_data, tsk_size_t in_size, void** out_data, tsk_size_t* out_max_size); + //! decode data + tsk_size_t (*decode) (tmedia_codec_t*, const void* in_data, tsk_size_t in_size, void** out_data, tsk_size_t* out_max_size, const tsk_object_t* proto_hdr); + //! whether the codec can handle this sdp attribute + tsk_bool_t (* sdp_att_match) (const tmedia_codec_t*, const char* att_name, const char* att_value); + //! gets sdp attribute value. e.g. "mode-set=0,2,5,7; mode-change-period=2; mode-change-neighbor=1" + char* (* sdp_att_get) (const tmedia_codec_t*, const char* att_name); } tmedia_codec_plugin_def_t; @@ -331,26 +327,25 @@ TINYMEDIA_API int tmedia_codec_parse_fmtp(const char* fmtp, unsigned* maxbr, uns TINYMEDIA_API int tmedia_codec_deinit(tmedia_codec_t* self); /** Audio codec */ -typedef struct tmedia_codec_audio_s -{ - TMEDIA_DECLARE_CODEC; - - struct{ - // !negotiated decoding ptime - uint8_t ptime; - // !negotiated decoding channels - int8_t channels; - // ! timestamp multiplier - float timestamp_multiplier; - } in; //decoding direction - struct{ - // !negotiated decoding ptime - uint8_t ptime; - // !negotiated encoding channels - int8_t channels; - // ! timestamp multiplier - float timestamp_multiplier; - } out; //encoding direction +typedef struct tmedia_codec_audio_s { + TMEDIA_DECLARE_CODEC; + + struct { + // !negotiated decoding ptime + uint8_t ptime; + // !negotiated decoding channels + int8_t channels; + // ! timestamp multiplier + float timestamp_multiplier; + } in; //decoding direction + struct { + // !negotiated decoding ptime + uint8_t ptime; + // !negotiated encoding channels + int8_t channels; + // ! timestamp multiplier + float timestamp_multiplier; + } out; //encoding direction } tmedia_codec_audio_t; @@ -373,37 +368,36 @@ tmedia_codec_audio_t; TINYMEDIA_API float tmedia_codec_audio_get_timestamp_multiplier(tmedia_codec_id_t id, uint32_t sample_rate); /** Video codec */ -typedef struct tmedia_codec_video_s -{ - TMEDIA_DECLARE_CODEC; - - struct{ - unsigned width; - unsigned height; - unsigned fps; - unsigned max_br; - unsigned max_mbps; - tmedia_chroma_t chroma; - tsk_bool_t flip; - - tmedia_codec_video_dec_cb_f callback; - tmedia_video_decode_result_xt result; - }in;// decoded - struct{ - unsigned width; - unsigned height; - unsigned fps; - unsigned max_br; - unsigned max_mbps; - tmedia_chroma_t chroma; - tsk_bool_t flip; - - tmedia_codec_video_enc_cb_f callback; - tmedia_video_encode_result_xt result; - }out;// encoded - - //! preferred video size - tmedia_pref_video_size_t pref_size; +typedef struct tmedia_codec_video_s { + TMEDIA_DECLARE_CODEC; + + struct { + unsigned width; + unsigned height; + unsigned fps; + unsigned max_br; + unsigned max_mbps; + tmedia_chroma_t chroma; + tsk_bool_t flip; + + tmedia_codec_video_dec_cb_f callback; + tmedia_video_decode_result_xt result; + } in; // decoded + struct { + unsigned width; + unsigned height; + unsigned fps; + unsigned max_br; + unsigned max_mbps; + tmedia_chroma_t chroma; + tsk_bool_t flip; + + tmedia_codec_video_enc_cb_f callback; + tmedia_video_encode_result_xt result; + } out; // encoded + + //! preferred video size + tmedia_pref_video_size_t pref_size; } tmedia_codec_video_t; @@ -424,13 +418,13 @@ tmedia_codec_video_t; #define tmedia_codec_video_init(self, name, desc, format) tmedia_codec_init(TMEDIA_CODEC(self), tmedia_video, name, desc, format) TINYMEDIA_API int tmedia_codec_video_set_enc_callback(tmedia_codec_video_t *self, tmedia_codec_video_enc_cb_f callback, const void* callback_data); TINYMEDIA_API int tmedia_codec_video_set_dec_callback(tmedia_codec_video_t *self, tmedia_codec_video_dec_cb_f callback, const void* callback_data); +TINYMEDIA_API int tmedia_codec_video_clamp_out_size_to_range_max(tmedia_codec_video_t *self); #define tmedia_codec_video_deinit(self) tmedia_codec_deinit(TMEDIA_CODEC(self)) /** MSRP codec */ -typedef struct tmedia_codec_msrp_s -{ - TMEDIA_DECLARE_CODEC; +typedef struct tmedia_codec_msrp_s { + TMEDIA_DECLARE_CODEC; } tmedia_codec_msrp_t; @@ -453,9 +447,8 @@ tmedia_codec_msrp_t; /** BFCP codec */ -typedef struct tmedia_codec_bfcp_s -{ - TMEDIA_DECLARE_CODEC; +typedef struct tmedia_codec_bfcp_s { + TMEDIA_DECLARE_CODEC; } tmedia_codec_bfcp_t; #define TMEDIA_DECLARE_CODEC_BFCP tmedia_codec_bfcp_t __bfcp__ diff --git a/tinyMEDIA/include/tinymedia/tmedia_codec_dummy.h b/tinyMEDIA/include/tinymedia/tmedia_codec_dummy.h index 9957eba..f3d592e 100755 --- a/tinyMEDIA/include/tinymedia/tmedia_codec_dummy.h +++ b/tinyMEDIA/include/tinymedia/tmedia_codec_dummy.h @@ -2,19 +2,19 @@ * Copyright (C) 2010-2011 Mamadou Diop. * * Contact: Mamadou Diop <diopmamadou(at)doubango[dot]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. * @@ -39,30 +39,26 @@ TMEDIA_BEGIN_DECLS /** Dummy PCMU codec */ -typedef struct tmedia_codec_dpcmu_s -{ - TMEDIA_DECLARE_CODEC_AUDIO; +typedef struct tmedia_codec_dpcmu_s { + TMEDIA_DECLARE_CODEC_AUDIO; } tmedia_codec_dpcmu_t; /** Dummy PCMA codec */ -typedef struct tmedia_codec_dpcma_s -{ - TMEDIA_DECLARE_CODEC_AUDIO; +typedef struct tmedia_codec_dpcma_s { + TMEDIA_DECLARE_CODEC_AUDIO; } tmedia_codec_dpcma_t; /** Dummy H.263 codec */ -typedef struct tmedia_codec_dh263_s -{ - TMEDIA_DECLARE_CODEC_VIDEO; +typedef struct tmedia_codec_dh263_s { + TMEDIA_DECLARE_CODEC_VIDEO; } tmedia_codec_dh263_t; /** Dummy H.264 codec */ -typedef struct tmedia_codec_dh264_s -{ - TMEDIA_DECLARE_CODEC_VIDEO; +typedef struct tmedia_codec_dh264_s { + TMEDIA_DECLARE_CODEC_VIDEO; } tmedia_codec_dh264_t; diff --git a/tinyMEDIA/include/tinymedia/tmedia_common.h b/tinyMEDIA/include/tinymedia/tmedia_common.h index 411007b..e786146 100755 --- a/tinyMEDIA/include/tinymedia/tmedia_common.h +++ b/tinyMEDIA/include/tinymedia/tmedia_common.h @@ -2,19 +2,19 @@ * Copyright (C) 2010-2011 Mamadou Diop. * * Contact: Mamadou Diop <diopmamadou(at)doubango[dot]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. * @@ -42,150 +42,140 @@ struct tsdp_header_M_s; /** List of all supported media types */ // @tinyWRAP -typedef enum tmedia_type_e -{ - tmedia_none = 0x00, - tmedia_ghost = (0x01 << 0), - - tmedia_audio = (0x01 << 1), - tmedia_video = (0x01 << 2), - tmedia_chat = (0x01 << 3), - tmedia_file = (0x01 << 4), - tmedia_t38 = (0x01 << 5), - tmedia_t140 = (0x01 << 6), - tmedia_bfcp = (0x01 << 7), - tmedia_bfcp_audio = (0x01 << 8)/*must*/ | tmedia_bfcp, /* do not add "| audio". Otherwise it will be impossible to start an "video+bfcp-audio" session. */ - tmedia_bfcp_video = (0x01 << 9)/*must*/ | tmedia_bfcp, /* do not add "| video". Otherwise it will be impossible to start an "audio+bfcp-video" session. */ +typedef enum tmedia_type_e { + tmedia_none = 0x00, + tmedia_ghost = (0x01 << 0), - tmedia_msrp = (tmedia_chat | tmedia_file), - tmedia_audiovideo = (tmedia_audio | tmedia_video), + tmedia_audio = (0x01 << 1), + tmedia_video = (0x01 << 2), + tmedia_chat = (0x01 << 3), + tmedia_file = (0x01 << 4), + tmedia_t38 = (0x01 << 5), + tmedia_t140 = (0x01 << 6), + tmedia_bfcp = (0x01 << 7), + tmedia_bfcp_audio = (0x01 << 8)/*must*/ | tmedia_bfcp, /* do not add "| audio". Otherwise it will be impossible to start an "video+bfcp-audio" session. */ + tmedia_bfcp_video = (0x01 << 9)/*must*/ | tmedia_bfcp, /* do not add "| video". Otherwise it will be impossible to start an "audio+bfcp-video" session. */ - tmedia_all = 0xff + tmedia_msrp = (tmedia_chat | tmedia_file), + tmedia_audiovideo = (tmedia_audio | tmedia_video), + + tmedia_all = 0xff } tmedia_type_t; // @tinyWRAP -typedef enum tmedia_mode_e -{ - tmedia_mode_none, - tmedia_mode_optional, - tmedia_mode_mandatory +typedef enum tmedia_mode_e { + tmedia_mode_none, + tmedia_mode_optional, + tmedia_mode_mandatory } tmedia_mode_t; // @tinyWRAP -typedef enum tmedia_srtp_mode_e -{ - tmedia_srtp_mode_none, - tmedia_srtp_mode_optional, - tmedia_srtp_mode_mandatory +typedef enum tmedia_srtp_mode_e { + tmedia_srtp_mode_none, + tmedia_srtp_mode_optional, + tmedia_srtp_mode_mandatory } tmedia_srtp_mode_t; // @tinyWRAP -typedef enum tmedia_srtp_type_e -{ - tmedia_srtp_type_none = 0x00, - tmedia_srtp_type_sdes = 0x01, - tmedia_srtp_type_dtls = 0x02, - tmedia_srtp_type_sdes_dtls = (tmedia_srtp_type_sdes | tmedia_srtp_type_dtls) +typedef enum tmedia_srtp_type_e { + tmedia_srtp_type_none = 0x00, + tmedia_srtp_type_sdes = 0x01, + tmedia_srtp_type_dtls = 0x02, + tmedia_srtp_type_sdes_dtls = (tmedia_srtp_type_sdes | tmedia_srtp_type_dtls) } tmedia_srtp_type_t; // @tinyWRAP -typedef enum tmedia_t140_data_type_e -{ - tmedia_t140_data_type_utf8, - tmedia_t140_data_type_zero_width_no_break_space = 0xefbbbf, - tmedia_t140_data_type_backspace = 0x08, - tmedia_t140_data_type_esc = 0x1b, - tmedia_t140_data_type_cr = 0x0d, - tmedia_t140_data_type_lf = 0x0a, - tmedia_t140_data_type_cr_lf = 0x0d0a, - tmedia_t140_data_type_bell = 0x07, - tmedia_t140_data_type_sos = 0x98, - tmedia_t140_data_type_string_term = 0x9c, - tmedia_t140_data_type_graphic_start = 0x9b, - tmedia_t140_data_type_graphic_end = 0x6d, - tmedia_t140_data_type_loss_char_char = 0xfffd, - tmedia_t140_data_type_loss_utf8 = 0xefbfbd, +typedef enum tmedia_t140_data_type_e { + tmedia_t140_data_type_utf8, + tmedia_t140_data_type_zero_width_no_break_space = 0xefbbbf, + tmedia_t140_data_type_backspace = 0x08, + tmedia_t140_data_type_esc = 0x1b, + tmedia_t140_data_type_cr = 0x0d, + tmedia_t140_data_type_lf = 0x0a, + tmedia_t140_data_type_cr_lf = 0x0d0a, + tmedia_t140_data_type_bell = 0x07, + tmedia_t140_data_type_sos = 0x98, + tmedia_t140_data_type_string_term = 0x9c, + tmedia_t140_data_type_graphic_start = 0x9b, + tmedia_t140_data_type_graphic_end = 0x6d, + tmedia_t140_data_type_loss_char_char = 0xfffd, + tmedia_t140_data_type_loss_utf8 = 0xefbfbd, } tmedia_t140_data_type_t; // @tinyWRAP -typedef enum tmedia_rtcp_event_type_e -{ - tmedia_rtcp_event_type_fir, // Full Intra Refresh +typedef enum tmedia_rtcp_event_type_e { + tmedia_rtcp_event_type_fir, // Full Intra Refresh } tmedia_rtcp_event_type_t; // @tinyWRAP -typedef enum tmedia_profile_e -{ - tmedia_profile_default, - // Enable all RTCWeb specifications: - // ICE, DTLS-SRTP, RTP/AVPF, FEC, RED, SDPCapNeg, RTCP-MUX, imageattr... - tmedia_profile_rtcweb +typedef enum tmedia_profile_e { + tmedia_profile_default, + // Enable all RTCWeb specifications: + // ICE, DTLS-SRTP, RTP/AVPF, FEC, RED, SDPCapNeg, RTCP-MUX, imageattr... + tmedia_profile_rtcweb } tmedia_profile_t; // @tinyWRAP -typedef enum tmedia_pref_video_size_s -{ /* must be sorted like this */ - tmedia_pref_video_size_sqcif, // 128 x 98 - tmedia_pref_video_size_qcif, // 176 x 144 - tmedia_pref_video_size_qvga, // 320 x 240 - tmedia_pref_video_size_cif, // 352 x 288 - tmedia_pref_video_size_hvga, // 480 x 320 - tmedia_pref_video_size_vga, // 640 x 480 - tmedia_pref_video_size_4cif, // 704 x 576 - tmedia_pref_video_size_wvga, // 800 x 480 - tmedia_pref_video_size_svga, // 800 x 600 - tmedia_pref_video_size_480p, // 852 x 480 - tmedia_pref_video_size_xga, // 1024 x 768 - tmedia_pref_video_size_720p, // 1280 x 720 - tmedia_pref_video_size_16cif, // 1408 x 1152 - tmedia_pref_video_size_1080p, // 1920 x 1080 - tmedia_pref_video_size_2160p, // 3840 x 2160 +typedef enum tmedia_pref_video_size_s { + /* must be sorted like this */ + tmedia_pref_video_size_sqcif, // 128 x 98 + tmedia_pref_video_size_qcif, // 176 x 144 + tmedia_pref_video_size_qvga, // 320 x 240 + tmedia_pref_video_size_cif, // 352 x 288 + tmedia_pref_video_size_hvga, // 480 x 320 + tmedia_pref_video_size_vga, // 640 x 480 + tmedia_pref_video_size_4cif, // 704 x 576 + tmedia_pref_video_size_wvga, // 800 x 480 + tmedia_pref_video_size_svga, // 800 x 600 + tmedia_pref_video_size_480p, // 852 x 480 + tmedia_pref_video_size_xga, // 1024 x 768 + tmedia_pref_video_size_720p, // 1280 x 720 + tmedia_pref_video_size_16cif, // 1408 x 1152 + tmedia_pref_video_size_1080p, // 1920 x 1080 + tmedia_pref_video_size_2160p, // 3840 x 2160 } tmedia_pref_video_size_t; -typedef enum tmedia_rtcweb_type_e -{ - tmedia_rtcweb_type_none, - tmedia_rtcweb_type_firefox, - tmedia_rtcweb_type_chrome, - tmedia_rtcweb_type_ie, - tmedia_rtcweb_type_safari, - tmedia_rtcweb_type_opera, - tmedia_rtcweb_type_ericsson, - tmedia_rtcweb_type_doubango +typedef enum tmedia_rtcweb_type_e { + tmedia_rtcweb_type_none, + tmedia_rtcweb_type_firefox, + tmedia_rtcweb_type_chrome, + tmedia_rtcweb_type_ie, + tmedia_rtcweb_type_safari, + tmedia_rtcweb_type_opera, + tmedia_rtcweb_type_ericsson, + tmedia_rtcweb_type_doubango } tmedia_rtcweb_type_t; -typedef enum tmedia_video_encode_result_type_e -{ - tmedia_video_encode_result_type_none = 0x00, - tmedia_video_encode_result_type_params = (0x01 << 0), // e.g. SPS or PPS, DCT coeff., Quant params.... - tmedia_video_encode_result_type_intra = (0x01 << 1), - tmedia_video_encode_result_type_key = tmedia_video_encode_result_type_intra, - tmedia_video_encode_result_type_gold = tmedia_video_encode_result_type_intra, - tmedia_video_encode_result_type_predicted = (0x01 << 2), - tmedia_video_encode_result_type_bipredicted = (0x01 << 3) +typedef enum tmedia_video_encode_result_type_e { + tmedia_video_encode_result_type_none = 0x00, + tmedia_video_encode_result_type_params = (0x01 << 0), // e.g. SPS or PPS, DCT coeff., Quant params.... + tmedia_video_encode_result_type_intra = (0x01 << 1), + tmedia_video_encode_result_type_key = tmedia_video_encode_result_type_intra, + tmedia_video_encode_result_type_gold = tmedia_video_encode_result_type_intra, + tmedia_video_encode_result_type_predicted = (0x01 << 2), + tmedia_video_encode_result_type_bipredicted = (0x01 << 3) } tmedia_video_encode_result_type_t; -typedef struct tmedia_video_encode_result_xs -{ - tmedia_video_encode_result_type_t type; - const void* usr_data; - struct{ - const void* ptr; - tsk_size_t size; - } buffer; - uint32_t duration; - tsk_bool_t last_chunck; - const tsk_object_t* proto_hdr; +typedef struct tmedia_video_encode_result_xs { + tmedia_video_encode_result_type_t type; + const void* usr_data; + struct { + const void* ptr; + tsk_size_t size; + } buffer; + uint32_t duration; + tsk_bool_t last_chunck; + const tsk_object_t* proto_hdr; } tmedia_video_encode_result_xt; @@ -198,21 +188,19 @@ tmedia_video_encode_result_xt; (result)->duration = 0; \ (result)->last_chunck = tsk_false; \ (result)->proto_hdr = tsk_null; \ + +typedef enum tmedia_video_decode_result_type_e { + tmedia_video_decode_result_type_none, -typedef enum tmedia_video_decode_result_type_e -{ - tmedia_video_decode_result_type_none, - - tmedia_video_decode_result_type_error, - tmedia_video_decode_result_type_idr, + tmedia_video_decode_result_type_error, + tmedia_video_decode_result_type_idr, } tmedia_video_decode_result_type_t; -typedef struct tmedia_video_decode_result_xs -{ - tmedia_video_decode_result_type_t type; - const void* usr_data; - const tsk_object_t* proto_hdr; // RTP, RTSP.... +typedef struct tmedia_video_decode_result_xs { + tmedia_video_decode_result_type_t type; + const void* usr_data; + const tsk_object_t* proto_hdr; // RTP, RTSP.... } tmedia_video_decode_result_xt; @@ -220,45 +208,42 @@ tmedia_video_decode_result_xt; (result)->type = tmedia_video_decode_result_type_none; \ (result)->usr_data = tsk_null; \ (result)->proto_hdr = tsk_null; \ - + // @tinyWRAP -typedef enum tmedia_chroma_e -{ - tmedia_chroma_none=0, - tmedia_chroma_rgb24, // will be stored as bgr24 on x86 (little endians) machines; e.g. WindowsPhone7 - tmedia_chroma_bgr24, // used by windows consumer (DirectShow) - - tmedia_chroma_rgb32, // used by iOS4 consumer (iPhone and iPod touch) - tmedia_chroma_rgb565le, // (used by both android and wince consumers) - tmedia_chroma_rgb565be, - tmedia_chroma_nv12, // used by iOS4 producer (iPhone and iPod Touch 3GS and 4) - tmedia_chroma_nv21, // Yuv420 SP (used by android producer) - tmedia_chroma_yuv422p, - tmedia_chroma_uyvy422, // used by iOS4 producer (iPhone and iPod Touch 3G) - Microsoft: MFVideoFormat_YUY2 - tmedia_chroma_yuv420p, // Default - tmedia_chroma_mjpeg, // VirtualBox default camera mode (Windows as host and Linux as guest) - tmedia_chroma_yuyv422, // YUYV422 (V4L2 preferred format) +typedef enum tmedia_chroma_e { + tmedia_chroma_none=0, + tmedia_chroma_rgb24, // will be stored as bgr24 on x86 (little endians) machines; e.g. WindowsPhone7 + tmedia_chroma_bgr24, // used by windows consumer (DirectShow) - + tmedia_chroma_rgb32, // used by iOS4 consumer (iPhone and iPod touch) + tmedia_chroma_rgb565le, // (used by both android and wince consumers) + tmedia_chroma_rgb565be, + tmedia_chroma_nv12, // used by iOS4 producer (iPhone and iPod Touch 3GS and 4) + tmedia_chroma_nv21, // Yuv420 SP (used by android producer) + tmedia_chroma_yuv422p, + tmedia_chroma_uyvy422, // used by iOS4 producer (iPhone and iPod Touch 3G) - Microsoft: MFVideoFormat_YUY2 + tmedia_chroma_yuv420p, // Default + tmedia_chroma_mjpeg, // VirtualBox default camera mode (Windows as host and Linux as guest) + tmedia_chroma_yuyv422, // YUYV422 (V4L2 preferred format) } tmedia_chroma_t; // @tinyWRAP // @deprecated // keep order (low->unrestricted) -typedef enum tmedia_bandwidth_level_e -{ - tmedia_bl_low, - tmedia_bl_medium, - tmedia_bl_hight, - tmedia_bl_unrestricted +typedef enum tmedia_bandwidth_level_e { + tmedia_bl_low, + tmedia_bl_medium, + tmedia_bl_hight, + tmedia_bl_unrestricted } tmedia_bandwidth_level_t; -typedef enum tmedia_ro_type_e -{ - tmedia_ro_type_none = 0x00, - tmedia_ro_type_offer = (0x01 << 0), - tmedia_ro_type_answer = (0x01 << 1), - tmedia_ro_type_provisional = tmedia_ro_type_answer | (0x01 << 2), +typedef enum tmedia_ro_type_e { + tmedia_ro_type_none = 0x00, + tmedia_ro_type_offer = (0x01 << 0), + tmedia_ro_type_answer = (0x01 << 1), + tmedia_ro_type_provisional = tmedia_ro_type_answer | (0x01 << 2), } tmedia_ro_type_t; diff --git a/tinyMEDIA/include/tinymedia/tmedia_consumer.h b/tinyMEDIA/include/tinymedia/tmedia_consumer.h index 0e88f45..9d347f1 100755 --- a/tinyMEDIA/include/tinymedia/tmedia_consumer.h +++ b/tinyMEDIA/include/tinymedia/tmedia_consumer.h @@ -4,17 +4,17 @@ * Contact: Mamadou Diop <diopmamadou(at)doubango[dot]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. * @@ -56,73 +56,71 @@ TMEDIA_BEGIN_DECLS #endif /** Base object for all Consumers */ -typedef struct tmedia_consumer_s -{ - TSK_DECLARE_OBJECT; - - tmedia_type_t type; - const char* desc; - - struct{ - int fps; - struct { - tmedia_chroma_t chroma; - tsk_size_t width; - tsk_size_t height; - } in; - struct { - tmedia_chroma_t chroma; - tsk_size_t width; - tsk_size_t height; - tsk_bool_t auto_resize; // auto_resize to "in.width, in.height" - } display; - } video; - - struct{ - uint8_t bits_per_sample; - uint8_t ptime; - uint8_t gain; - struct{ - uint8_t channels; - uint32_t rate; - } in; - struct{ - uint8_t channels; - uint32_t rate; - } out; - int32_t volume; - } audio; - - tsk_bool_t is_started; - tsk_bool_t is_prepared; - uint64_t session_id; - - struct{ - enum tmedia_codec_id_e codec_id; - // other options to be added - } decoder; - - const struct tmedia_consumer_plugin_def_s* plugin; +typedef struct tmedia_consumer_s { + TSK_DECLARE_OBJECT; + + tmedia_type_t type; + const char* desc; + + struct { + int fps; + struct { + tmedia_chroma_t chroma; + tsk_size_t width; + tsk_size_t height; + } in; + struct { + tmedia_chroma_t chroma; + tsk_size_t width; + tsk_size_t height; + tsk_bool_t auto_resize; // auto_resize to "in.width, in.height" + } display; + } video; + + struct { + uint8_t bits_per_sample; + uint8_t ptime; + uint8_t gain; + struct { + uint8_t channels; + uint32_t rate; + } in; + struct { + uint8_t channels; + uint32_t rate; + } out; + int32_t volume; + } audio; + + tsk_bool_t is_started; + tsk_bool_t is_prepared; + uint64_t session_id; + + struct { + enum tmedia_codec_id_e codec_id; + // other options to be added + } decoder; + + const struct tmedia_consumer_plugin_def_s* plugin; } tmedia_consumer_t; /** Virtual table used to define a consumer plugin */ -typedef struct tmedia_consumer_plugin_def_s -{ - //! object definition used to create an instance of the consumer - const tsk_object_def_t* objdef; - - //! the type of the consumer - tmedia_type_t type; - //! full description (usefull for debugging) - const char* desc; - - int (*set) (tmedia_consumer_t* , const tmedia_param_t*); - int (* prepare) (tmedia_consumer_t*, const tmedia_codec_t* ); - int (* start) (tmedia_consumer_t* ); - int (* consume) (tmedia_consumer_t*, const void* buffer, tsk_size_t size, const tsk_object_t* proto_hdr); - int (* pause) (tmedia_consumer_t* ); - int (* stop) (tmedia_consumer_t* ); +typedef struct tmedia_consumer_plugin_def_s { + //! object definition used to create an instance of the consumer + const tsk_object_def_t* objdef; + + //! the type of the consumer + tmedia_type_t type; + //! full description (usefull for debugging) + const char* desc; + + int (*set) (tmedia_consumer_t* , const tmedia_param_t*); + int (* prepare) (tmedia_consumer_t*, const tmedia_codec_t* ); + int (* start) (tmedia_consumer_t* ); + int (* consume) (tmedia_consumer_t*, const void* buffer, tsk_size_t size, const tsk_object_t* proto_hdr); + int (* pause) (tmedia_consumer_t* ); + int (* stop) (tmedia_consumer_t* ); } tmedia_consumer_plugin_def_t; diff --git a/tinyMEDIA/include/tinymedia/tmedia_converter_video.h b/tinyMEDIA/include/tinymedia/tmedia_converter_video.h index 133dfab..6af98d6 100755 --- a/tinyMEDIA/include/tinymedia/tmedia_converter_video.h +++ b/tinyMEDIA/include/tinymedia/tmedia_converter_video.h @@ -2,17 +2,17 @@ * Copyright (C) 2012 Doubango Telecom <http://www.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. * @@ -40,26 +40,25 @@ TMEDIA_BEGIN_DECLS # define TMED_CONVERTER_VIDEO_MAX_PLUGINS 0x0F #endif -typedef struct tmedia_converter_video_s -{ - TSK_DECLARE_OBJECT; - - tsk_size_t srcWidth; - tsk_size_t srcHeight; +typedef struct tmedia_converter_video_s { + TSK_DECLARE_OBJECT; + + tsk_size_t srcWidth; + tsk_size_t srcHeight; - tsk_size_t dstWidth; - tsk_size_t dstHeight; + tsk_size_t dstWidth; + tsk_size_t dstHeight; - tmedia_chroma_t srcChroma; - tmedia_chroma_t dstChroma; + tmedia_chroma_t srcChroma; + tmedia_chroma_t dstChroma; - // one shot parameters - int rotation; - tsk_bool_t flip; - tsk_bool_t mirror; - tsk_bool_t scale_rotated_frames; + // one shot parameters + int rotation; + tsk_bool_t flip; + tsk_bool_t mirror; + tsk_bool_t scale_rotated_frames; - const struct tmedia_converter_video_plugin_def_s* plugin; + const struct tmedia_converter_video_plugin_def_s* plugin; } tmedia_converter_video_t; @@ -93,13 +92,12 @@ tmedia_converter_video_t; (_self)->plugin->process((_self), (_buffer), (_size), (_output), (_output_max_size)) /** Virtual table used to define a consumer plugin */ -typedef struct tmedia_converter_video_plugin_def_s -{ - //! object definition used to create an instance of the converter - const tsk_object_def_t* objdef; +typedef struct tmedia_converter_video_plugin_def_s { + //! object definition used to create an instance of the converter + const tsk_object_def_t* objdef; - int (* init) ( struct tmedia_converter_video_s* self, tsk_size_t srcWidth, tsk_size_t srcHeight, tmedia_chroma_t srcChroma, tsk_size_t dstWidth, tsk_size_t dstHeight, tmedia_chroma_t dstChroma ); - tsk_size_t (* process) ( struct tmedia_converter_video_s* self, const void* buffer, tsk_size_t buffer_size, void** output, tsk_size_t* output_max_size ); + int (* init) ( struct tmedia_converter_video_s* self, tsk_size_t srcWidth, tsk_size_t srcHeight, tmedia_chroma_t srcChroma, tsk_size_t dstWidth, tsk_size_t dstHeight, tmedia_chroma_t dstChroma ); + tsk_size_t (* process) ( struct tmedia_converter_video_s* self, const void* buffer, tsk_size_t buffer_size, void** output, tsk_size_t* output_max_size ); } tmedia_converter_video_plugin_def_t; diff --git a/tinyMEDIA/include/tinymedia/tmedia_defaults.h b/tinyMEDIA/include/tinymedia/tmedia_defaults.h index 324c241..91a1ae8 100755 --- a/tinyMEDIA/include/tinymedia/tmedia_defaults.h +++ b/tinyMEDIA/include/tinymedia/tmedia_defaults.h @@ -2,19 +2,19 @@ * Copyright (C) 2010-2011 Mamadou Diop. * * Contact: Mamadou Diop <diopmamadou(at)doubango[dot]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. * @@ -45,6 +45,10 @@ TINYMEDIA_API int tmedia_defaults_set_bandwidth_video_download_max(int32_t bw_vi TINYMEDIA_API int32_t tmedia_defaults_get_bandwidth_video_download_max(); TINYMEDIA_API int tmedia_defaults_set_pref_video_size(tmedia_pref_video_size_t pref_video_size); TINYMEDIA_API tmedia_pref_video_size_t tmedia_defaults_get_pref_video_size(); +TINYMEDIA_API int tmedia_defaults_set_pref_video_size_range(tmedia_pref_video_size_t min, tmedia_pref_video_size_t max); +TINYMEDIA_API int tmedia_defaults_get_pref_video_size_range(tmedia_pref_video_size_t *min, tmedia_pref_video_size_t* max); +TINYMEDIA_API int tmedia_defaults_set_adapt_video_size_range_enabled(tsk_bool_t enabled); +TINYMEDIA_API tsk_bool_t tmedia_defaults_get_adapt_video_size_range_enabled(); TINYMEDIA_API int tmedia_defaults_set_jb_margin(int32_t jb_margin_ms); TINYMEDIA_API int32_t tmedia_defaults_get_jb_margin(); TINYMEDIA_API int tmedia_defaults_set_jb_max_late_rate(int32_t jb_max_late_rate_percent); diff --git a/tinyMEDIA/include/tinymedia/tmedia_denoise.h b/tinyMEDIA/include/tinymedia/tmedia_denoise.h index d8818f4..522ef48 100755 --- a/tinyMEDIA/include/tinymedia/tmedia_denoise.h +++ b/tinyMEDIA/include/tinymedia/tmedia_denoise.h @@ -1,18 +1,18 @@ /* * Copyright (C) 2010-2015 Mamadou DIOP. -* +* * 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. * @@ -36,45 +36,43 @@ TMEDIA_BEGIN_DECLS #define TMEDIA_DENOISE(self) ((tmedia_denoise_t*)(self)) /** Base object for all Denoisers */ -typedef struct tmedia_denoise_s -{ - TSK_DECLARE_OBJECT; - - tsk_bool_t opened; - - uint32_t echo_tail; - uint32_t echo_skew; - tsk_bool_t echo_supp_enabled; - tsk_bool_t agc_enabled ; - float agc_level; - tsk_bool_t vad_enabled; - tsk_bool_t noise_supp_enabled; - int32_t noise_supp_level; +typedef struct tmedia_denoise_s { + TSK_DECLARE_OBJECT; + + tsk_bool_t opened; + + uint32_t echo_tail; + uint32_t echo_skew; + tsk_bool_t echo_supp_enabled; + tsk_bool_t agc_enabled ; + float agc_level; + tsk_bool_t vad_enabled; + tsk_bool_t noise_supp_enabled; + int32_t noise_supp_level; tsk_buffer_t *record_frame; - tsk_buffer_t *playback_frame; - const struct tmedia_denoise_plugin_def_s* plugin; + tsk_buffer_t *playback_frame; + const struct tmedia_denoise_plugin_def_s* plugin; } tmedia_denoise_t; #define TMEDIA_DECLARE_DENOISE tmedia_denoise_t __denoise__ /** Virtual table used to define a consumer plugin */ -typedef struct tmedia_denoise_plugin_def_s -{ - //! object definition used to create an instance of the denoiser - const tsk_object_def_t* objdef; - - //! full description (usefull for debugging) - const char* desc; - - int (*set) (tmedia_denoise_t* , const tmedia_param_t*); - int (* open) (tmedia_denoise_t*, uint32_t record_frame_size_samples, uint32_t record_sampling_rate, uint32_t record_channels, uint32_t playback_frame_size_samples, uint32_t playback_sampling_rate, uint32_t playback_channels); - int (*echo_playback) (tmedia_denoise_t* self, const void* echo_frame, uint32_t echo_frame_size_bytes); - //! aec, vad, noise suppression, echo cancellation before sending packet over network - int (* process_record) (tmedia_denoise_t*, void* audio_frame, uint32_t audio_frame_size_bytes, tsk_bool_t* silence_or_noise); - //! noise suppression before playing sound - int (* process_playback) (tmedia_denoise_t*, void* audio_frame, uint32_t audio_frame_size_bytes); - int (* close) (tmedia_denoise_t* ); +typedef struct tmedia_denoise_plugin_def_s { + //! object definition used to create an instance of the denoiser + const tsk_object_def_t* objdef; + + //! full description (usefull for debugging) + const char* desc; + + int (*set) (tmedia_denoise_t* , const tmedia_param_t*); + int (* open) (tmedia_denoise_t*, uint32_t record_frame_size_samples, uint32_t record_sampling_rate, uint32_t record_channels, uint32_t playback_frame_size_samples, uint32_t playback_sampling_rate, uint32_t playback_channels); + int (*echo_playback) (tmedia_denoise_t* self, const void* echo_frame, uint32_t echo_frame_size_bytes); + //! aec, vad, noise suppression, echo cancellation before sending packet over network + int (* process_record) (tmedia_denoise_t*, void* audio_frame, uint32_t audio_frame_size_bytes, tsk_bool_t* silence_or_noise); + //! noise suppression before playing sound + int (* process_playback) (tmedia_denoise_t*, void* audio_frame, uint32_t audio_frame_size_bytes); + int (* close) (tmedia_denoise_t* ); } tmedia_denoise_plugin_def_t; @@ -94,4 +92,4 @@ TINYMEDIA_API tmedia_denoise_t* tmedia_denoise_create(); TMEDIA_END_DECLS -#endif /* TINYMEDIA_DENOISE_H */ +#endif /* TINYMEDIA_DENOISE_H */ diff --git a/tinyMEDIA/include/tinymedia/tmedia_imageattr.h b/tinyMEDIA/include/tinymedia/tmedia_imageattr.h index c709a17..c187da3 100755 --- a/tinyMEDIA/include/tinymedia/tmedia_imageattr.h +++ b/tinyMEDIA/include/tinymedia/tmedia_imageattr.h @@ -2,19 +2,19 @@ * Copyright (C) 2012 Doubango Telecom <http://www.doubango.org> * * Contact: Mamadou Diop <diopmamadou(at)doubango[dot]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. * @@ -41,63 +41,59 @@ typedef int32_t xyvalue_t; typedef double qvalue_t; typedef double spvalue_t; -typedef struct tmedia_imageattr_srange_xs -{ - unsigned is_range:1; - union{ - struct{ - spvalue_t start; - spvalue_t end; - }range; - struct{ - spvalue_t values[TMEDIA_imageattr_ARRAY_MAX_SIZE + 1]; - tsk_size_t count; - }array; - }; +typedef struct tmedia_imageattr_srange_xs { + unsigned is_range:1; + union { + struct { + spvalue_t start; + spvalue_t end; + } range; + struct { + spvalue_t values[TMEDIA_imageattr_ARRAY_MAX_SIZE + 1]; + tsk_size_t count; + } array; + }; } tmedia_imageattr_srange_xt; -typedef struct tmedia_imageattr_xyrange_xs -{ - unsigned is_range:1; - union{ - struct{ - xyvalue_t start; - xyvalue_t step; - xyvalue_t end; - }range; - struct{ - xyvalue_t values[TMEDIA_imageattr_ARRAY_MAX_SIZE + 1]; - tsk_size_t count; - }array; - }; +typedef struct tmedia_imageattr_xyrange_xs { + unsigned is_range:1; + union { + struct { + xyvalue_t start; + xyvalue_t step; + xyvalue_t end; + } range; + struct { + xyvalue_t values[TMEDIA_imageattr_ARRAY_MAX_SIZE + 1]; + tsk_size_t count; + } array; + }; } tmedia_imageattr_xyrange_xt; -typedef struct tmedia_imageattr_set_xs -{ - tmedia_imageattr_xyrange_xt xrange; - tmedia_imageattr_xyrange_xt yrange; - tmedia_imageattr_srange_xt srange; - struct{ - unsigned is_present:1; - spvalue_t start; - spvalue_t end; - }prange; - qvalue_t qvalue; +typedef struct tmedia_imageattr_set_xs { + tmedia_imageattr_xyrange_xt xrange; + tmedia_imageattr_xyrange_xt yrange; + tmedia_imageattr_srange_xt srange; + struct { + unsigned is_present:1; + spvalue_t start; + spvalue_t end; + } prange; + qvalue_t qvalue; } tmedia_imageattr_set_xt; -typedef struct tmedia_imageattr_xs -{ - struct{ - tmedia_imageattr_set_xt sets[TMEDIA_imageattr_ARRAY_MAX_SIZE + 1]; - tsk_size_t count; - }send; - struct{ - tmedia_imageattr_set_xt sets[TMEDIA_imageattr_ARRAY_MAX_SIZE + 1]; - tsk_size_t count; - }recv; +typedef struct tmedia_imageattr_xs { + struct { + tmedia_imageattr_set_xt sets[TMEDIA_imageattr_ARRAY_MAX_SIZE + 1]; + tsk_size_t count; + } send; + struct { + tmedia_imageattr_set_xt sets[TMEDIA_imageattr_ARRAY_MAX_SIZE + 1]; + tsk_size_t count; + } recv; } tmedia_imageattr_xt; diff --git a/tinyMEDIA/include/tinymedia/tmedia_jitterbuffer.h b/tinyMEDIA/include/tinymedia/tmedia_jitterbuffer.h index fb0f8ef..3a62ae2 100755 --- a/tinyMEDIA/include/tinymedia/tmedia_jitterbuffer.h +++ b/tinyMEDIA/include/tinymedia/tmedia_jitterbuffer.h @@ -2,19 +2,19 @@ * Copyright (C) 2011 Mamadou Diop. * * Contact: Mamadou Diop <diopmamadou(at)doubango[dot]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. * @@ -47,37 +47,35 @@ TMEDIA_BEGIN_DECLS #endif /** Base object for all JitterBuffers */ -typedef struct tmedia_jitterbuffer_s -{ - TSK_DECLARE_OBJECT; +typedef struct tmedia_jitterbuffer_s { + TSK_DECLARE_OBJECT; - tsk_bool_t opened; + tsk_bool_t opened; - const struct tmedia_jitterbuffer_plugin_def_s* plugin; + const struct tmedia_jitterbuffer_plugin_def_s* plugin; } tmedia_jitterbuffer_t; #define TMEDIA_DECLARE_JITTER_BUFFER tmedia_jitterbuffer_t __jitterbuffer__ /** Virtual table used to define a consumer plugin */ -typedef struct tmedia_jitterbuffer_plugin_def_s -{ - //! object definition used to create an instance of the jitterbufferr - const tsk_object_def_t* objdef; - - //! the type of the jitter buffer - tmedia_type_t type; - - //! full description (usefull for debugging) - const char* desc; - - int (*set) (tmedia_jitterbuffer_t* , const tmedia_param_t*); - int (* open) (tmedia_jitterbuffer_t*, uint32_t frame_duration, uint32_t rate, uint32_t channels); - int (* tick) (tmedia_jitterbuffer_t*); - int (* put) (tmedia_jitterbuffer_t*, void* data, tsk_size_t data_size, const tsk_object_t* proto_hdr); - tsk_size_t (* get) (tmedia_jitterbuffer_t*, void* out_data, tsk_size_t out_size); - int (* reset) (tmedia_jitterbuffer_t* ); - int (* close) (tmedia_jitterbuffer_t* ); +typedef struct tmedia_jitterbuffer_plugin_def_s { + //! object definition used to create an instance of the jitterbufferr + const tsk_object_def_t* objdef; + + //! the type of the jitter buffer + tmedia_type_t type; + + //! full description (usefull for debugging) + const char* desc; + + int (*set) (tmedia_jitterbuffer_t* , const tmedia_param_t*); + int (* open) (tmedia_jitterbuffer_t*, uint32_t frame_duration, uint32_t rate, uint32_t channels); + int (* tick) (tmedia_jitterbuffer_t*); + int (* put) (tmedia_jitterbuffer_t*, void* data, tsk_size_t data_size, const tsk_object_t* proto_hdr); + tsk_size_t (* get) (tmedia_jitterbuffer_t*, void* out_data, tsk_size_t out_size); + int (* reset) (tmedia_jitterbuffer_t* ); + int (* close) (tmedia_jitterbuffer_t* ); } tmedia_jitterbuffer_plugin_def_t; @@ -99,4 +97,4 @@ TINYMEDIA_API tmedia_jitterbuffer_t* tmedia_jitterbuffer_create(tmedia_type_t ty TMEDIA_END_DECLS -#endif /* TINYMEDIA_JITTER_BUFFER_H */ +#endif /* TINYMEDIA_JITTER_BUFFER_H */ diff --git a/tinyMEDIA/include/tinymedia/tmedia_params.h b/tinyMEDIA/include/tinymedia/tmedia_params.h index 549552c..baec140 100755 --- a/tinyMEDIA/include/tinymedia/tmedia_params.h +++ b/tinyMEDIA/include/tinymedia/tmedia_params.h @@ -2,19 +2,19 @@ * Copyright (C) 2010-2011 Mamadou Diop. * * Contact: Mamadou Diop <diopmamadou(at)doubango[dot]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. * @@ -40,50 +40,46 @@ TMEDIA_BEGIN_DECLS #define TMEDIA_PARAM(self) ((tmedia_param_t*)(self)) -typedef enum tmedia_param_access_type_e -{ - tmedia_pat_get, - tmedia_pat_set +typedef enum tmedia_param_access_type_e { + tmedia_pat_get, + tmedia_pat_set } tmedia_param_access_type_t; -typedef enum tmedia_param_plugin_type_e -{ - tmedia_ppt_consumer, - tmedia_ppt_producer, - tmedia_ppt_codec, - tmedia_ppt_session, - tmedia_ppt_manager +typedef enum tmedia_param_plugin_type_e { + tmedia_ppt_consumer, + tmedia_ppt_producer, + tmedia_ppt_codec, + tmedia_ppt_session, + tmedia_ppt_manager } tmedia_param_plugin_type_t; -typedef enum tmedia_param_value_type_e -{ - tmedia_pvt_int32, - tmedia_pvt_bool = tmedia_pvt_int32, - tmedia_pvt_pobject, - tmedia_pvt_pchar, - tmedia_pvt_int64, +typedef enum tmedia_param_value_type_e { + tmedia_pvt_int32, + tmedia_pvt_bool = tmedia_pvt_int32, + tmedia_pvt_pobject, + tmedia_pvt_pchar, + tmedia_pvt_int64, } tmedia_param_value_type_t; #define TMEDIA_PARAM_VALUE_TYPE_IS_PTR(self) ((self) == tmedia_pvt_pobject || (self) == tmedia_pvt_pchar) -typedef struct tmedia_param_s -{ - TSK_DECLARE_OBJECT; - - tmedia_param_access_type_t access_type; - tmedia_type_t media_type; - tmedia_param_plugin_type_t plugin_type; - tmedia_param_value_type_t value_type; - - char* key; - /* Because setting parameters could be deferred - * ==> MUST copy the value for later use. - * e.g. TMEDIA_SESSION_MANAGER_SET_INT32("width", 1234); 1234 will be lost when we exit the block code - */ - void* value; +typedef struct tmedia_param_s { + TSK_DECLARE_OBJECT; + + tmedia_param_access_type_t access_type; + tmedia_type_t media_type; + tmedia_param_plugin_type_t plugin_type; + tmedia_param_value_type_t value_type; + + char* key; + /* Because setting parameters could be deferred + * ==> MUST copy the value for later use. + * e.g. TMEDIA_SESSION_MANAGER_SET_INT32("width", 1234); 1234 will be lost when we exit the block code + */ + void* value; } tmedia_param_t; @@ -91,12 +87,12 @@ typedef tsk_list_t tmedia_params_L_t; /**< List of @ref tsk_param_t elements. */ #define tmedia_params_create() tsk_list_create() -TINYMEDIA_API tmedia_param_t* tmedia_param_create(tmedia_param_access_type_t access_type, - tmedia_type_t media_type, - tmedia_param_plugin_type_t plugin_type, - tmedia_param_value_type_t value_type, - const char* key, - void* value); +TINYMEDIA_API tmedia_param_t* tmedia_param_create(tmedia_param_access_type_t access_type, + tmedia_type_t media_type, + tmedia_param_plugin_type_t plugin_type, + tmedia_param_value_type_t value_type, + const char* key, + void* value); #define tmedia_param_create_get(media_type, plugin_type, value_type, key, value) tmedia_param_create(tmedia_pat_get, (media_type), (plugin_type), (value_type), (key), (value)) #define tmedia_param_create_get_session(media_type, value_type, key, value) tmedia_param_create_get((media_type), tmedia_ppt_session, (value_type), (key), (value)) #define tmedia_param_create_get_codec(media_type, value_type, key, value) tmedia_param_create_get((media_type), tmedia_ppt_codec, (value_type), (key), (value)) @@ -104,13 +100,13 @@ TINYMEDIA_API tmedia_param_t* tmedia_param_create(tmedia_param_access_type_t acc TINYMEDIA_API tmedia_params_L_t* tmedia_params_create_2(va_list *app); -TINYMEDIA_API int tmedia_params_add_param(tmedia_params_L_t **self, - tmedia_param_access_type_t access_type, - tmedia_type_t media_type, - tmedia_param_plugin_type_t plugin_type, - tmedia_param_value_type_t value_type, - const char* key, - void* value); +TINYMEDIA_API int tmedia_params_add_param(tmedia_params_L_t **self, + tmedia_param_access_type_t access_type, + tmedia_type_t media_type, + tmedia_param_plugin_type_t plugin_type, + tmedia_param_value_type_t value_type, + const char* key, + void* value); TINYMEDIA_GEXTERN const tsk_object_def_t *tmedia_param_def_t; diff --git a/tinyMEDIA/include/tinymedia/tmedia_producer.h b/tinyMEDIA/include/tinymedia/tmedia_producer.h index 0817821..3cfc4c6 100755 --- a/tinyMEDIA/include/tinymedia/tmedia_producer.h +++ b/tinyMEDIA/include/tinymedia/tmedia_producer.h @@ -2,19 +2,19 @@ * Copyright (C) 2010-2011 Mamadou Diop. * * Contact: Mamadou Diop <diopmamadou(at)doubango[dot]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. * @@ -55,70 +55,68 @@ typedef int (*tmedia_producer_raw_cb_f)(const tmedia_video_encode_result_xt* chu #define TMEDIA_PRODUCER_CHROMA_DEFAULT tmedia_chroma_yuv420p /** Base object for all Producers */ -typedef struct tmedia_producer_s -{ - TSK_DECLARE_OBJECT; - - tmedia_type_t type; - const char* desc; - - struct{ - tmedia_chroma_t chroma; - int fps; - int rotation; - tsk_bool_t mirror; - tsk_size_t width; - tsk_size_t height; - } video; - - struct{ - uint8_t bits_per_sample; - uint8_t channels; - uint32_t rate; - uint8_t ptime; - uint8_t gain; - int32_t volume; - } audio; - - const struct tmedia_producer_plugin_def_s* plugin; - - tsk_bool_t is_prepared; - tsk_bool_t is_started; - uint64_t session_id; - - struct{ - enum tmedia_codec_id_e codec_id; - // other options to be added - } encoder; - - struct{ - tmedia_producer_enc_cb_f callback; - const void* callback_data; - } enc_cb; - - struct{ - tmedia_producer_raw_cb_f callback; - tmedia_video_encode_result_xt chunck_curr; - } raw_cb; +typedef struct tmedia_producer_s { + TSK_DECLARE_OBJECT; + + tmedia_type_t type; + const char* desc; + + struct { + tmedia_chroma_t chroma; + int fps; + int rotation; + tsk_bool_t mirror; + tsk_size_t width; + tsk_size_t height; + } video; + + struct { + uint8_t bits_per_sample; + uint8_t channels; + uint32_t rate; + uint8_t ptime; + uint8_t gain; + int32_t volume; + } audio; + + const struct tmedia_producer_plugin_def_s* plugin; + + tsk_bool_t is_prepared; + tsk_bool_t is_started; + uint64_t session_id; + + struct { + enum tmedia_codec_id_e codec_id; + // other options to be added + } encoder; + + struct { + tmedia_producer_enc_cb_f callback; + const void* callback_data; + } enc_cb; + + struct { + tmedia_producer_raw_cb_f callback; + tmedia_video_encode_result_xt chunck_curr; + } raw_cb; } tmedia_producer_t; /** Virtual table used to define a producer plugin */ -typedef struct tmedia_producer_plugin_def_s -{ - //! object definition used to create an instance of the producer - const tsk_object_def_t* objdef; - - //! the type of the producer - tmedia_type_t type; - //! full description (usefull for debugging) - const char* desc; - - int (*set) (tmedia_producer_t* , const tmedia_param_t*); - int (* prepare) (tmedia_producer_t* , const tmedia_codec_t*); - int (* start) (tmedia_producer_t* ); - int (* pause) (tmedia_producer_t* ); - int (* stop) (tmedia_producer_t* ); +typedef struct tmedia_producer_plugin_def_s { + //! object definition used to create an instance of the producer + const tsk_object_def_t* objdef; + + //! the type of the producer + tmedia_type_t type; + //! full description (usefull for debugging) + const char* desc; + + int (*set) (tmedia_producer_t* , const tmedia_param_t*); + int (* prepare) (tmedia_producer_t* , const tmedia_codec_t*); + int (* start) (tmedia_producer_t* ); + int (* pause) (tmedia_producer_t* ); + int (* stop) (tmedia_producer_t* ); } tmedia_producer_plugin_def_t; diff --git a/tinyMEDIA/include/tinymedia/tmedia_qos.h b/tinyMEDIA/include/tinymedia/tmedia_qos.h index 7ff8e97..a9f2b7c 100755 --- a/tinyMEDIA/include/tinymedia/tmedia_qos.h +++ b/tinyMEDIA/include/tinymedia/tmedia_qos.h @@ -2,19 +2,19 @@ * Copyright (C) 2010-2011 Mamadou Diop. * * Contact: Mamadou Diop <diopmamadou(at)doubango[dot]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. * @@ -41,61 +41,55 @@ TMEDIA_BEGIN_DECLS #define TMEDIA_QOS_TLINE(self) ((tmedia_qos_tline_t*)(self)) /** List of all supported statues*/ -typedef enum tmedia_qos_status_e -{ - //! current-status - tmedia_qos_status_curr, - //! desired-status - tmedia_qos_status_des, - //! confirm-status - tmedia_qos_status_conf +typedef enum tmedia_qos_status_e { + //! current-status + tmedia_qos_status_curr, + //! desired-status + tmedia_qos_status_des, + //! confirm-status + tmedia_qos_status_conf } tmedia_qos_status_t; /** List of all supported precondition types */ -typedef enum tmedia_qos_ptype_e -{ - tmedia_qos_ptype_qos +typedef enum tmedia_qos_ptype_e { + tmedia_qos_ptype_qos } tmedia_qos_ptype_t; /** List of all supported status types */ -typedef enum tmedia_qos_stype_e -{ - tmedia_qos_stype_none,/* not part of the RFC */ +typedef enum tmedia_qos_stype_e { + tmedia_qos_stype_none,/* not part of the RFC */ - tmedia_qos_stype_segmented, - tmedia_qos_stype_e2e, + tmedia_qos_stype_segmented, + tmedia_qos_stype_e2e, } tmedia_qos_stype_t; /** strengths */ -typedef enum tmedia_qos_strength_e -{ - /* do no change the order (none -> optional -> manadatory) */ - tmedia_qos_strength_none, - tmedia_qos_strength_failure, - tmedia_qos_strength_unknown, - tmedia_qos_strength_optional, - tmedia_qos_strength_mandatory +typedef enum tmedia_qos_strength_e { + /* do no change the order (none -> optional -> manadatory) */ + tmedia_qos_strength_none, + tmedia_qos_strength_failure, + tmedia_qos_strength_unknown, + tmedia_qos_strength_optional, + tmedia_qos_strength_mandatory } tmedia_qos_strength_t; /** directions */ -typedef enum tmedia_qos_direction_e -{ - tmedia_qos_direction_none = 0x01, - tmedia_qos_direction_send = (0x01 << 1), - tmedia_qos_direction_recv = (0x01 << 2), - tmedia_qos_direction_sendrecv = (tmedia_qos_direction_send | tmedia_qos_direction_recv) +typedef enum tmedia_qos_direction_e { + tmedia_qos_direction_none = 0x01, + tmedia_qos_direction_send = (0x01 << 1), + tmedia_qos_direction_recv = (0x01 << 2), + tmedia_qos_direction_sendrecv = (tmedia_qos_direction_send | tmedia_qos_direction_recv) } tmedia_qos_direction_t; /* QoS table-line */ -typedef struct tmedia_qos_tline_s -{ - TSK_DECLARE_OBJECT; - tmedia_qos_stype_t type; +typedef struct tmedia_qos_tline_s { + TSK_DECLARE_OBJECT; + tmedia_qos_stype_t type; } tmedia_qos_tline_t; #define TMEDIA_DECLARE_QOS_TLINE tmedia_qos_tline_t __tline__ @@ -108,28 +102,27 @@ TINYMEDIA_API int tmedia_qos_tline_set_ro(tmedia_qos_tline_t* self, const tmedia TINYMEDIA_API tsk_bool_t tmedia_qos_tline_canresume(const tmedia_qos_tline_t* self); /* QoS table-line for E2E type*/ -typedef struct tmedia_qos_tline_e2e_s -{ - TMEDIA_DECLARE_QOS_TLINE; - - /* RFC 3312 - 5.1 Generating an offer - - Direction Current Desired Strength - ____________________________________ - send no mandatory - recv no mandatory - */ - struct{ - unsigned current:1; - unsigned confirm:1; - tmedia_qos_strength_t strength; - } send; - - struct{ - unsigned current:1; - unsigned confirm:1; - tmedia_qos_strength_t strength; - } recv; +typedef struct tmedia_qos_tline_e2e_s { + TMEDIA_DECLARE_QOS_TLINE; + + /* RFC 3312 - 5.1 Generating an offer + + Direction Current Desired Strength + ____________________________________ + send no mandatory + recv no mandatory + */ + struct { + unsigned current:1; + unsigned confirm:1; + tmedia_qos_strength_t strength; + } send; + + struct { + unsigned current:1; + unsigned confirm:1; + tmedia_qos_strength_t strength; + } recv; } tmedia_qos_tline_e2e_t; @@ -140,42 +133,41 @@ TINYMEDIA_API int tmedia_qos_tline_e2e_set_ro(tmedia_qos_tline_e2e_t* self, cons TINYMEDIA_API tsk_bool_t tmedia_qos_tline_e2e_canresume(const tmedia_qos_tline_e2e_t* self); /* QoS table-line for Segented type*/ -typedef struct tmedia_qos_tline_segmented_s -{ - TMEDIA_DECLARE_QOS_TLINE; - - /* RFC 3312 - 5.1 Generating an offer - Direction Current Desired Strength - ______________________________________ - local send no none - local recv no none - remote send no optional - remote recv no none - */ - /* can be done in two lines but I prefer doing it like this (easier) */ - struct{ - unsigned current:1; - unsigned confirm:1; - tmedia_qos_strength_t strength; - } local_send; - - struct{ - unsigned current:1; - unsigned confirm:1; - tmedia_qos_strength_t strength; - } local_recv; - - struct{ - unsigned current:1; - unsigned confirm:1; - tmedia_qos_strength_t strength; - } remote_send; - - struct{ - unsigned current:1; - unsigned confirm:1; - tmedia_qos_strength_t strength; - } remote_recv; +typedef struct tmedia_qos_tline_segmented_s { + TMEDIA_DECLARE_QOS_TLINE; + + /* RFC 3312 - 5.1 Generating an offer + Direction Current Desired Strength + ______________________________________ + local send no none + local recv no none + remote send no optional + remote recv no none + */ + /* can be done in two lines but I prefer doing it like this (easier) */ + struct { + unsigned current:1; + unsigned confirm:1; + tmedia_qos_strength_t strength; + } local_send; + + struct { + unsigned current:1; + unsigned confirm:1; + tmedia_qos_strength_t strength; + } local_recv; + + struct { + unsigned current:1; + unsigned confirm:1; + tmedia_qos_strength_t strength; + } remote_send; + + struct { + unsigned current:1; + unsigned confirm:1; + tmedia_qos_strength_t strength; + } remote_recv; } tmedia_qos_tline_segmented_t; diff --git a/tinyMEDIA/include/tinymedia/tmedia_resampler.h b/tinyMEDIA/include/tinymedia/tmedia_resampler.h index 5093bc6..fd89b87 100755 --- a/tinyMEDIA/include/tinymedia/tmedia_resampler.h +++ b/tinyMEDIA/include/tinymedia/tmedia_resampler.h @@ -2,19 +2,19 @@ * Copyright (C) 2010-2011 Mamadou Diop. * * Contact: Mamadou Diop <diopmamadou(at)doubango[dot]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. * @@ -42,31 +42,29 @@ TMEDIA_BEGIN_DECLS #define TMEDIA_RESAMPLER(self) ((tmedia_resampler_t*)(self)) /** Base object for all resamplers */ -typedef struct tmedia_resampler_s -{ - TSK_DECLARE_OBJECT; +typedef struct tmedia_resampler_s { + TSK_DECLARE_OBJECT; - tsk_bool_t opened; + tsk_bool_t opened; - const struct tmedia_resampler_plugin_def_s* plugin; + const struct tmedia_resampler_plugin_def_s* plugin; } tmedia_resampler_t; #define TMEDIA_DECLARE_RESAMPLER tmedia_resampler_t __resampler__ /** Virtual table used to define a consumer plugin */ -typedef struct tmedia_resampler_plugin_def_s -{ - //! object definition used to create an instance of the resamplerr - const tsk_object_def_t* objdef; - - //! full description (usefull for debugging) - const char* desc; - - // ! quality is from 0-10 - int (* open) (tmedia_resampler_t* self, uint32_t in_freq, uint32_t out_freq, uint32_t frame_duration, uint32_t in_channels, uint32_t out_channels, uint32_t quality, uint32_t bits_per_sample); - tsk_size_t (* process) (tmedia_resampler_t*, const void* in_data, tsk_size_t in_size_in_sample, void* out_data, tsk_size_t out_size_in_sample); - int (* close) (tmedia_resampler_t* ); +typedef struct tmedia_resampler_plugin_def_s { + //! object definition used to create an instance of the resamplerr + const tsk_object_def_t* objdef; + + //! full description (usefull for debugging) + const char* desc; + + // ! quality is from 0-10 + int (* open) (tmedia_resampler_t* self, uint32_t in_freq, uint32_t out_freq, uint32_t frame_duration, uint32_t in_channels, uint32_t out_channels, uint32_t quality, uint32_t bits_per_sample); + tsk_size_t (* process) (tmedia_resampler_t*, const void* in_data, tsk_size_t in_size_in_sample, void* out_data, tsk_size_t out_size_in_sample); + int (* close) (tmedia_resampler_t* ); } tmedia_resampler_plugin_def_t; @@ -83,4 +81,4 @@ TINYMEDIA_API tmedia_resampler_t* tmedia_resampler_create(); TMEDIA_END_DECLS -#endif /* TINYMEDIA_RESAMPLER_H */ +#endif /* TINYMEDIA_RESAMPLER_H */ diff --git a/tinyMEDIA/include/tinymedia/tmedia_session.h b/tinyMEDIA/include/tinymedia/tmedia_session.h index 743a7a5..698f61f 100755 --- a/tinyMEDIA/include/tinymedia/tmedia_session.h +++ b/tinyMEDIA/include/tinymedia/tmedia_session.h @@ -2,19 +2,19 @@ * Copyright (C) 2010-2011 Mamadou Diop. * * Contact: Mamadou Diop <diopmamadou(at)doubango[dot]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. * @@ -50,30 +50,28 @@ TMEDIA_BEGIN_DECLS struct tmedia_session_s; // rfc5168 (XML Schema for Media Control) commands -typedef enum tmedia_session_rfc5168_cmd_e -{ - tmedia_session_rfc5168_cmd_picture_fast_update, +typedef enum tmedia_session_rfc5168_cmd_e { + tmedia_session_rfc5168_cmd_picture_fast_update, } tmedia_session_rfc5168_cmd_t; // BFCP (rfc4582) events -typedef enum tmedia_session_bfcp_evt_type_e -{ - tmedia_session_bfcp_evt_type_err, // Global error - tmedia_session_bfcp_evt_type_flreq_status, // FloorRequestStatus +typedef enum tmedia_session_bfcp_evt_type_e { + tmedia_session_bfcp_evt_type_err, // Global error + tmedia_session_bfcp_evt_type_flreq_status, // FloorRequestStatus } tmedia_session_bfcp_evt_type_t; typedef struct tmedia_session_bfcp_evt_xs { - tmedia_session_bfcp_evt_type_t type; - const char* reason; - union { - struct { - int code; - } err; - struct { - uint16_t status; - } flreq; - }; + tmedia_session_bfcp_evt_type_t type; + const char* reason; + union { + struct { + int code; + } err; + struct { + uint16_t status; + } flreq; + }; } tmedia_session_bfcp_evt_xt; #define TMEDIA_SESSION(self) ((tmedia_session_t*)(self)) @@ -91,106 +89,123 @@ typedef int (*tmedia_session_bfcp_cb_f)(const void* usrdata, const struct tmedia #define TMED_SESSION_MAX_PLUGINS 0x0F /** Base objct used for all media sessions */ -typedef struct tmedia_session_s -{ - TSK_DECLARE_OBJECT; - - //! unique id. If you want to modifiy this field then you must use @ref tmedia_session_get_unique_id() - uint64_t id; - //! session type - tmedia_type_t type; - //! list of codec ids used as filter on the enabled codecs - tmedia_codec_id_t codecs_allowed; - //! list of codecs managed by this session (enabled) - tmedia_codecs_L_t* codecs; - //! negociated codec - tmedia_codecs_L_t* neg_codecs; - //! whether the ro have been prepared (up to the manager to update the value) - tsk_bool_t ro_changed; - //! whether the session have been initialized (up to the manager to update the value) - tsk_bool_t initialized; - //! whether the session have been prepared (up to the manager to update the value) - tsk_bool_t prepared; - //! whether the session is localy held - tsk_bool_t lo_held; - //! whether the session is remotely held - tsk_bool_t ro_held; - //! QoS - tmedia_qos_tline_t* qos; - //! bandwidth level - tmedia_bandwidth_level_t bl; - //! error callback function: not part of the plugin (likes .t140 or .rtcp) because it's not part of the API - struct{ - tmedia_session_onerror_cb_f fun; - const void* usrdata; - } onerror_cb; - //! rfc5168 (XML Schema for Media Control) callback function: not part of the plugin (likes .t140 or .rtcp) because it's not part of the API. - struct { - tmedia_session_rfc5168_cb_f fun; - const void* usrdata; - } rfc5168_cb; - //! BFCP (rfc4582) - struct { - tmedia_session_bfcp_cb_f fun; - const void* usrdata; - } bfcp_cb; - - tsk_bool_t bypass_encoding; - tsk_bool_t bypass_decoding; - - struct{ - char* file_ca; - char* file_pbk; - char* file_pvk; - tsk_bool_t verify; - } dtls; - - struct{ - tsdp_header_M_t* lo; - tsdp_header_M_t* ro; - } M; - - //! plugin used to create the session - const struct tmedia_session_plugin_def_s* plugin; +typedef struct tmedia_session_s { + TSK_DECLARE_OBJECT; + + //! unique id. If you want to modifiy this field then you must use @ref tmedia_session_get_unique_id() + uint64_t id; + //! session type + tmedia_type_t type; + //! list of codec ids used as filter on the enabled codecs + tmedia_codec_id_t codecs_allowed; + //! list of codecs managed by this session (enabled) + tmedia_codecs_L_t* codecs; + //! negociated codec + tmedia_codecs_L_t* neg_codecs; + //! whether the ro have been prepared (up to the manager to update the value) + tsk_bool_t ro_changed; + //! whether the session have been initialized (up to the manager to update the value) + tsk_bool_t initialized; + //! whether the session have been prepared (up to the manager to update the value) + tsk_bool_t prepared; + //! whether the session is localy held + tsk_bool_t lo_held; + //! whether the session is remotely held + tsk_bool_t ro_held; + //! QoS + tmedia_qos_tline_t* qos; + //! bandwidth level + tmedia_bandwidth_level_t bl; + //! error callback function: not part of the plugin (likes .t140 or .rtcp) because it's not part of the API + struct { + tmedia_session_onerror_cb_f fun; + const void* usrdata; + } onerror_cb; + //! rfc5168 (XML Schema for Media Control) callback function: not part of the plugin (likes .t140 or .rtcp) because it's not part of the API. + struct { + tmedia_session_rfc5168_cb_f fun; + const void* usrdata; + } rfc5168_cb; + //! BFCP (rfc4582) + struct { + tmedia_session_bfcp_cb_f fun; + const void* usrdata; + } bfcp_cb; + + tsk_bool_t bypass_encoding; + tsk_bool_t bypass_decoding; + + struct { + char* file_ca; + char* file_pbk; + char* file_pvk; + tsk_bool_t verify; + } dtls; + + struct { + float q1; /**< 2.1.Packet loss recovery */ + float q2; /**< 2.2.Global packet loss estimation */ + float q3; /**< 2.3.Receiver Estimated Maximum Bitrate */ + float q4; /**< 2.4.Latency estimation */ + float q5; /**< 2.5. Jitter buffer congestion estimation */ + float qvag; + unsigned bw_up_est_kbps; + unsigned bw_down_est_kbps; + unsigned video_out_width; + unsigned video_out_height; + unsigned video_in_width; + unsigned video_in_height; + unsigned video_in_avg_fps; + unsigned video_dec_avg_time; + unsigned video_enc_avg_time; + uint64_t last_update_time; + } qos_metrics; + + struct { + tsdp_header_M_t* lo; + tsdp_header_M_t* ro; + } M; + + //! plugin used to create the session + const struct tmedia_session_plugin_def_s* plugin; } tmedia_session_t; /** Virtual table used to define a session plugin */ -typedef struct tmedia_session_plugin_def_s -{ - //! object definition used to create an instance of the session - const tsk_object_def_t* objdef; - - //! the type of the session - tmedia_type_t type; - //! the media name. e.g. "audio", "video", "message", "image" etc. - const char* media; - - int (*set) (tmedia_session_t* , const tmedia_param_t*); - int (*get) (tmedia_session_t* , tmedia_param_t*); - int (* prepare) (tmedia_session_t* ); - int (* start) (tmedia_session_t* ); - int (* pause) (tmedia_session_t* ); - int (* stop) (tmedia_session_t* ); - - struct{ /* Special case */ - int (* send_dtmf) (tmedia_session_t*, uint8_t ); - } audio; - - const tsdp_header_M_t* (* get_local_offer) (tmedia_session_t* ); - /* return zero if can handle the ro and non-zero otherwise */ - int (* set_remote_offer) (tmedia_session_t* , const tsdp_header_M_t* ); - - struct{ /* Special case */ - int (* set_ondata_cbfn) (tmedia_session_t*, const void* usrdata, tmedia_session_t140_ondata_cb_f func); - int (* send_data) (tmedia_session_t*, enum tmedia_t140_data_type_e data_type, const void* data_ptr, unsigned data_size); - } t140; - - struct{ /* Handles both SIP INFO and RTCP-FB: should be called by end-user only when transcoding is disabled */ - int (* set_onevent_cbfn) (tmedia_session_t*, const void* usrdata, tmedia_session_rtcp_onevent_cb_f func); - int (* send_event) (tmedia_session_t*, enum tmedia_rtcp_event_type_e event_type, uint32_t ssrc_media); - int (* recv_event) (tmedia_session_t*, enum tmedia_rtcp_event_type_e event_type, uint32_t ssrc_media); - } rtcp; +typedef struct tmedia_session_plugin_def_s { + //! object definition used to create an instance of the session + const tsk_object_def_t* objdef; + + //! the type of the session + tmedia_type_t type; + //! the media name. e.g. "audio", "video", "message", "image" etc. + const char* media; + + int (*set) (tmedia_session_t* , const tmedia_param_t*); + int (*get) (tmedia_session_t* , tmedia_param_t*); + int (* prepare) (tmedia_session_t* ); + int (* start) (tmedia_session_t* ); + int (* pause) (tmedia_session_t* ); + int (* stop) (tmedia_session_t* ); + + struct { /* Special case */ + int (* send_dtmf) (tmedia_session_t*, uint8_t ); + } audio; + + const tsdp_header_M_t* (* get_local_offer) (tmedia_session_t* ); + /* return zero if can handle the ro and non-zero otherwise */ + int (* set_remote_offer) (tmedia_session_t* , const tsdp_header_M_t* ); + + struct { /* Special case */ + int (* set_ondata_cbfn) (tmedia_session_t*, const void* usrdata, tmedia_session_t140_ondata_cb_f func); + int (* send_data) (tmedia_session_t*, enum tmedia_t140_data_type_e data_type, const void* data_ptr, unsigned data_size); + } t140; + + struct { /* Handles both SIP INFO and RTCP-FB: should be called by end-user only when transcoding is disabled */ + int (* set_onevent_cbfn) (tmedia_session_t*, const void* usrdata, tmedia_session_rtcp_onevent_cb_f func); + int (* send_event) (tmedia_session_t*, enum tmedia_rtcp_event_type_e event_type, uint32_t ssrc_media); + int (* recv_event) (tmedia_session_t*, enum tmedia_rtcp_event_type_e event_type, uint32_t ssrc_media); + } rtcp; } tmedia_session_plugin_def_t; @@ -216,9 +231,8 @@ typedef tsk_list_t tmedia_sessions_L_t; /**< List of @ref tmedia_session_t objec #define TMEDIA_DECLARE_SESSION tmedia_session_t __session__ /** Audio Session */ -typedef struct tmedia_session_audio_s -{ - TMEDIA_DECLARE_SESSION; +typedef struct tmedia_session_audio_s { + TMEDIA_DECLARE_SESSION; } tmedia_session_audio_t; #define tmedia_session_audio_init(self) tmedia_session_init(TMEDIA_SESSION(self), tmedia_audio) @@ -228,9 +242,8 @@ TINYMEDIA_API int tmedia_session_audio_send_dtmf(tmedia_session_audio_t* self, u #define TMEDIA_DECLARE_SESSION_AUDIO tmedia_session_audio_t __session_audio__ /** Video Session */ -typedef struct tmedia_session_video_s -{ - TMEDIA_DECLARE_SESSION; +typedef struct tmedia_session_video_s { + TMEDIA_DECLARE_SESSION; } tmedia_session_video_t; #define tmedia_session_video_init(self) tmedia_session_init(TMEDIA_SESSION(self), tmedia_video) @@ -243,17 +256,16 @@ struct tmedia_session_msrp_s; struct tmsrp_event_s; // use "struct tmsrp_event_s" instead of "tmsrp_event_t" to avoid linking aginst tinyMSRP typedef int (*tmedia_session_msrp_cb_f)(const struct tmsrp_event_s* event); -typedef struct tmedia_session_msrp_s -{ - TMEDIA_DECLARE_SESSION; - - struct { - tmedia_session_msrp_cb_f func; - const void* data; - } callback; - - int (* send_file) (struct tmedia_session_msrp_s*, const char* path, va_list *app); - int (* send_message) (struct tmedia_session_msrp_s*, const void* data, tsk_size_t size, const tmedia_params_L_t *params); +typedef struct tmedia_session_msrp_s { + TMEDIA_DECLARE_SESSION; + + struct { + tmedia_session_msrp_cb_f func; + const void* data; + } callback; + + int (* send_file) (struct tmedia_session_msrp_s*, const char* path, va_list *app); + int (* send_message) (struct tmedia_session_msrp_s*, const void* data, tsk_size_t size, const tmedia_params_L_t *params); } tmedia_session_msrp_t; #define tmedia_session_msrp_init(self) tmedia_session_init(TMEDIA_SESSION(self), tmedia_msrp) @@ -264,18 +276,17 @@ tmedia_session_msrp_t; /** BFCP Session */ struct tmedia_session_bfcp_s; struct tbfcp_event_s; -typedef struct tmedia_session_bfcp_s -{ - TMEDIA_DECLARE_SESSION; - - struct { - // use "struct tbfcp_event_s" instead of "tbfcp_event_t" to avoid linking aginst tinyBFCP - int (*fun)(const struct tbfcp_event_s* event); - const void* data; - } callback; - - // int (* share_file) (struct tmedia_session_bfcp_s*, const char* path, va_list *app); - // int (* share_screen) (struct tmedia_session_bfcp_s*, const tmedia_params_L_t *params); +typedef struct tmedia_session_bfcp_s { + TMEDIA_DECLARE_SESSION; + + struct { + // use "struct tbfcp_event_s" instead of "tbfcp_event_t" to avoid linking aginst tinyBFCP + int (*fun)(const struct tbfcp_event_s* event); + const void* data; + } callback; + + // int (* share_file) (struct tmedia_session_bfcp_s*, const char* path, va_list *app); + // int (* share_screen) (struct tmedia_session_bfcp_s*, const tmedia_params_L_t *params); } tmedia_session_bfcp_t; #define tmedia_session_bfcp_init(self) tmedia_session_init(TMEDIA_SESSION(self), tmedia_bfcp) @@ -288,80 +299,78 @@ int tmedia_session_t140_set_ondata_cbfn(tmedia_session_t* self, const void* cont int tmedia_session_t140_send_data(tmedia_session_t* self, enum tmedia_t140_data_type_e data_type, const void* data_ptr, unsigned data_size); /** Session manager */ -typedef struct tmedia_session_mgr_s -{ - TSK_DECLARE_OBJECT; - - //! whether we are the offerer or not - tsk_bool_t offerer; - //! local IP address or FQDN - char* addr; - //! public IP address or FQDN - char* public_addr; - //! whether the @a addr is IPv6 or not (useful when @addr is a FQDN) - tsk_bool_t ipv6; - - struct{ - uint32_t lo_ver; - tsdp_message_t* lo; - - int32_t ro_ver; - tsdp_message_t* ro; - } sdp; - - tsk_bool_t started; - tsk_bool_t ro_changed; - tsk_bool_t ro_provisional; - tsk_bool_t state_changed; - tsk_bool_t mediaType_changed; - - //! session type - tmedia_type_t type; - //! QoS type - struct { - tmedia_qos_stype_t type; - tmedia_qos_strength_t strength; - } qos; - - //! bandwidth level - tmedia_bandwidth_level_t bl; - - /* NAT Traversal context */ - struct tnet_nat_ctx_s* natt_ctx; - struct { - struct tnet_ice_ctx_s *ctx_audio; - struct tnet_ice_ctx_s *ctx_video; - struct tnet_ice_ctx_s *ctx_bfcpvid; - } ice; - - /* session error callback */ - struct{ - tmedia_session_onerror_cb_f fun; - const void* usrdata; - } onerror_cb; - - /* rfc5168 callback */ - struct { - tmedia_session_rfc5168_cb_f fun; - const void* usrdata; - } rfc5168_cb; - - //! List of all sessions - tmedia_sessions_L_t* sessions; - - //! User's parameters used to confugure plugins - tmedia_params_L_t* params; - - TSK_DECLARE_SAFEOBJ; +typedef struct tmedia_session_mgr_s { + TSK_DECLARE_OBJECT; + + //! whether we are the offerer or not + tsk_bool_t offerer; + //! local IP address or FQDN + char* addr; + //! public IP address or FQDN + char* public_addr; + //! whether the @a addr is IPv6 or not (useful when @addr is a FQDN) + tsk_bool_t ipv6; + + struct { + uint32_t lo_ver; + tsdp_message_t* lo; + + int32_t ro_ver; + tsdp_message_t* ro; + } sdp; + + tsk_bool_t started; + tsk_bool_t ro_changed; + tsk_bool_t ro_provisional; + tsk_bool_t state_changed; + tsk_bool_t mediaType_changed; + + //! session type + tmedia_type_t type; + //! QoS type + struct { + tmedia_qos_stype_t type; + tmedia_qos_strength_t strength; + } qos; + + //! bandwidth level + tmedia_bandwidth_level_t bl; + + /* NAT Traversal context */ + struct tnet_nat_ctx_s* natt_ctx; + struct { + struct tnet_ice_ctx_s *ctx_audio; + struct tnet_ice_ctx_s *ctx_video; + struct tnet_ice_ctx_s *ctx_bfcpvid; + } ice; + + /* session error callback */ + struct { + tmedia_session_onerror_cb_f fun; + const void* usrdata; + } onerror_cb; + + /* rfc5168 callback */ + struct { + tmedia_session_rfc5168_cb_f fun; + const void* usrdata; + } rfc5168_cb; + + //! List of all sessions + tmedia_sessions_L_t* sessions; + + //! User's parameters used to confugure plugins + tmedia_params_L_t* params; + + TSK_DECLARE_SAFEOBJ; } tmedia_session_mgr_t; -typedef enum tmedia_session_param_type_e -{ - tmedia_sptype_null = 0, - - tmedia_sptype_set, - tmedia_sptype_get +typedef enum tmedia_session_param_type_e { + tmedia_sptype_null = 0, + + tmedia_sptype_set, + tmedia_sptype_get } tmedia_session_param_type_t; diff --git a/tinyMEDIA/include/tinymedia/tmedia_session_dummy.h b/tinyMEDIA/include/tinymedia/tmedia_session_dummy.h index a795677..6c3b696 100755 --- a/tinyMEDIA/include/tinymedia/tmedia_session_dummy.h +++ b/tinyMEDIA/include/tinymedia/tmedia_session_dummy.h @@ -2,19 +2,19 @@ * Copyright (C) 2010-2011 Mamadou Diop. * * Contact: Mamadou Diop <diopmamadou(at)doubango[dot]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. * @@ -39,29 +39,26 @@ TMEDIA_BEGIN_DECLS /** Dummy Audio session */ -typedef struct tmedia_session_daudio_s -{ - TMEDIA_DECLARE_SESSION_AUDIO; - uint16_t local_port; - uint16_t remote_port; +typedef struct tmedia_session_daudio_s { + TMEDIA_DECLARE_SESSION_AUDIO; + uint16_t local_port; + uint16_t remote_port; } tmedia_session_daudio_t; /** Dummy Video session */ -typedef struct tmedia_session_dvideo_s -{ - TMEDIA_DECLARE_SESSION_VIDEO; - uint16_t local_port; - uint16_t remote_port; +typedef struct tmedia_session_dvideo_s { + TMEDIA_DECLARE_SESSION_VIDEO; + uint16_t local_port; + uint16_t remote_port; } tmedia_session_dvideo_t; /** Dummy Msrp session */ -typedef struct tmedia_session_dmsrp_s -{ - TMEDIA_DECLARE_SESSION_MSRP; - uint16_t local_port; - uint16_t remote_port; +typedef struct tmedia_session_dmsrp_s { + TMEDIA_DECLARE_SESSION_MSRP; + uint16_t local_port; + uint16_t remote_port; } tmedia_session_dmsrp_t; diff --git a/tinyMEDIA/include/tinymedia/tmedia_session_ghost.h b/tinyMEDIA/include/tinymedia/tmedia_session_ghost.h index e4b0ac8..46507da 100755 --- a/tinyMEDIA/include/tinymedia/tmedia_session_ghost.h +++ b/tinyMEDIA/include/tinymedia/tmedia_session_ghost.h @@ -2,19 +2,19 @@ * Copyright (C) 2010-2011 Mamadou Diop. * * Contact: Mamadou Diop <diopmamadou(at)doubango[dot]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. * @@ -39,12 +39,11 @@ TMEDIA_BEGIN_DECLS /** Ghost session */ -typedef struct tmedia_session_ghost_s -{ - TMEDIA_DECLARE_SESSION; - char* media; - char* proto; - char* first_format; +typedef struct tmedia_session_ghost_s { + TMEDIA_DECLARE_SESSION; + char* media; + char* proto; + char* first_format; } tmedia_session_ghost_t; diff --git a/tinyMEDIA/include/tinymedia_config.h b/tinyMEDIA/include/tinymedia_config.h index 7416017..758d97b 100755 --- a/tinyMEDIA/include/tinymedia_config.h +++ b/tinyMEDIA/include/tinymedia_config.h @@ -2,19 +2,19 @@ * Copyright (C) 2010-2011 Mamadou Diop. * * Contact: Mamadou Diop <diopmamadou(at)doubango[dot]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. * @@ -62,13 +62,13 @@ # define TINYMEDIA_GEXTERN extern #endif -/* Guards against C++ name mangling +/* Guards against C++ name mangling */ #ifdef __cplusplus # define TMEDIA_BEGIN_DECLS extern "C" { # define TMEDIA_END_DECLS } #else -# define TMEDIA_BEGIN_DECLS +# define TMEDIA_BEGIN_DECLS # define TMEDIA_END_DECLS #endif @@ -92,7 +92,7 @@ #endif #if HAVE_CONFIG_H - #include <config.h> +#include <config.h> #endif #endif // TINYMEDIA_CONFIG_H diff --git a/tinyMEDIA/src/content/tmedia_content.c b/tinyMEDIA/src/content/tmedia_content.c index bcdf275..0e06d21 100755 --- a/tinyMEDIA/src/content/tmedia_content.c +++ b/tinyMEDIA/src/content/tmedia_content.c @@ -32,10 +32,9 @@ /**@defgroup tmedia_content_group Contents */ -typedef struct tmedia_content_plugin_entry_s -{ - const char* type; - const tmedia_content_plugin_def_t* plugin; +typedef struct tmedia_content_plugin_entry_s { + const char* type; + const tmedia_content_plugin_def_t* plugin; } tmedia_content_plugin_entry_t; @@ -45,156 +44,156 @@ tmedia_content_plugin_entry_t __tmedia_content_plugin_entries[TMEDIA_CONTENT_MAX int tmedia_content_plugin_register(const char* type, const tmedia_content_plugin_def_t* plugin) { - tsk_size_t i; - //-- int a = sizeof(__tmedia_content_plugin_entries); - if (!plugin || !plugin){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - - /* add or replace the plugin */ - for (i = 0; i < TMEDIA_CONTENT_MAX_PLUGINS; i++){ - if (!__tmedia_content_plugin_entries[i]->plugin || (__tmedia_content_plugin_entries[i]->plugin == plugin && tsk_striequals(type, __tmedia_content_plugin_entries[i]->type))){ - __tmedia_content_plugin_entries[i]->type = type; - __tmedia_content_plugin_entries[i]->plugin = plugin; - return 0; - } - } - - - TSK_DEBUG_ERROR("There are already %d plugins.", TMEDIA_CONTENT_MAX_PLUGINS); - return -2; + tsk_size_t i; + //-- int a = sizeof(__tmedia_content_plugin_entries); + if (!plugin || !plugin) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + + /* add or replace the plugin */ + for (i = 0; i < TMEDIA_CONTENT_MAX_PLUGINS; i++) { + if (!__tmedia_content_plugin_entries[i]->plugin || (__tmedia_content_plugin_entries[i]->plugin == plugin && tsk_striequals(type, __tmedia_content_plugin_entries[i]->type))) { + __tmedia_content_plugin_entries[i]->type = type; + __tmedia_content_plugin_entries[i]->plugin = plugin; + return 0; + } + } + + + TSK_DEBUG_ERROR("There are already %d plugins.", TMEDIA_CONTENT_MAX_PLUGINS); + return -2; } int tmedia_content_plugin_unregister(const char* type, const tmedia_content_plugin_def_t* plugin) { - tsk_size_t i; - tsk_bool_t found = tsk_false; - if (!plugin){ - TSK_DEBUG_ERROR("Invalid Parameter"); - return -1; - } - - /* find the plugin to unregister */ - for (i = 0; i < TMEDIA_CONTENT_MAX_PLUGINS && __tmedia_content_plugin_entries[i]->plugin; i++){ - if (__tmedia_content_plugin_entries[i]->plugin == plugin && tsk_striequals(type, __tmedia_content_plugin_entries[i]->type)){ - __tmedia_content_plugin_entries[i]->type = tsk_null, - __tmedia_content_plugin_entries[i]->plugin = tsk_null; - found = tsk_true; - break; - } - } - - /* compact */ - if (found){ - for (; i < (TMEDIA_CONTENT_MAX_PLUGINS - 1); i++){ - if (__tmedia_content_plugin_entries[i + 1]->plugin){ - __tmedia_content_plugin_entries[i]->type = __tmedia_content_plugin_entries[i + 1]->type, - __tmedia_content_plugin_entries[i]->plugin = __tmedia_content_plugin_entries[i + 1]->plugin; - } - else{ - break; - } - } - __tmedia_content_plugin_entries[i]->type = tsk_null, - __tmedia_content_plugin_entries[i]->plugin = tsk_null; - } - return (found ? 0 : -2); + tsk_size_t i; + tsk_bool_t found = tsk_false; + if (!plugin) { + TSK_DEBUG_ERROR("Invalid Parameter"); + return -1; + } + + /* find the plugin to unregister */ + for (i = 0; i < TMEDIA_CONTENT_MAX_PLUGINS && __tmedia_content_plugin_entries[i]->plugin; i++) { + if (__tmedia_content_plugin_entries[i]->plugin == plugin && tsk_striequals(type, __tmedia_content_plugin_entries[i]->type)) { + __tmedia_content_plugin_entries[i]->type = tsk_null, + __tmedia_content_plugin_entries[i]->plugin = tsk_null; + found = tsk_true; + break; + } + } + + /* compact */ + if (found) { + for (; i < (TMEDIA_CONTENT_MAX_PLUGINS - 1); i++) { + if (__tmedia_content_plugin_entries[i + 1]->plugin) { + __tmedia_content_plugin_entries[i]->type = __tmedia_content_plugin_entries[i + 1]->type, + __tmedia_content_plugin_entries[i]->plugin = __tmedia_content_plugin_entries[i + 1]->plugin; + } + else { + break; + } + } + __tmedia_content_plugin_entries[i]->type = tsk_null, + __tmedia_content_plugin_entries[i]->plugin = tsk_null; + } + return (found ? 0 : -2); } int tmedia_content_plugin_unregister_all() { - tsk_size_t i; - for (i = 0; i < TMEDIA_CONTENT_MAX_PLUGINS && __tmedia_content_plugin_entries[i]->plugin; i++){ - __tmedia_content_plugin_entries[i]->type = tsk_null, - __tmedia_content_plugin_entries[i]->plugin = tsk_null; - } - return 0; + tsk_size_t i; + for (i = 0; i < TMEDIA_CONTENT_MAX_PLUGINS && __tmedia_content_plugin_entries[i]->plugin; i++) { + __tmedia_content_plugin_entries[i]->type = tsk_null, + __tmedia_content_plugin_entries[i]->plugin = tsk_null; + } + return 0; } tmedia_content_t* tmedia_content_create(const char* type) { - tmedia_content_t* content = tsk_null; - const tmedia_content_plugin_entry_t* entry; - tsk_size_t i = 0; - - while (i < TMEDIA_CONTENT_MAX_PLUGINS){ - entry = __tmedia_content_plugin_entries[i]; - if (!entry->plugin || !entry->type){ - break; - } - if (entry->plugin->objdef && tsk_striequals(entry->type, type)){ - if ((content = tsk_object_new(entry->plugin->objdef))){ - content->plugin = entry->plugin; - content->type = entry->type; - return content; - } - } - ++i; - } - - TSK_DEBUG_WARN("Failed to find content type (%s) will be added as dummy", type); - if (tmedia_content_dummy_plugin_def_t){ - content = tsk_object_new(tmedia_content_dummy_plugin_def_t->objdef); - content->plugin = tmedia_content_dummy_plugin_def_t; - content->type = type; - } - - return content; + tmedia_content_t* content = tsk_null; + const tmedia_content_plugin_entry_t* entry; + tsk_size_t i = 0; + + while (i < TMEDIA_CONTENT_MAX_PLUGINS) { + entry = __tmedia_content_plugin_entries[i]; + if (!entry->plugin || !entry->type) { + break; + } + if (entry->plugin->objdef && tsk_striequals(entry->type, type)) { + if ((content = tsk_object_new(entry->plugin->objdef))) { + content->plugin = entry->plugin; + content->type = entry->type; + return content; + } + } + ++i; + } + + TSK_DEBUG_WARN("Failed to find content type (%s) will be added as dummy", type); + if (tmedia_content_dummy_plugin_def_t) { + content = tsk_object_new(tmedia_content_dummy_plugin_def_t->objdef); + content->plugin = tmedia_content_dummy_plugin_def_t; + content->type = type; + } + + return content; } tmedia_content_t* tmedia_content_parse(const void* data, tsk_size_t size, const char* type) { - tmedia_content_t* content = tmedia_content_create(type); - if (content){ - if (content->plugin->parse){ - int ret; - if ((ret = content->plugin->parse(content, data, size))){ - TSK_DEBUG_ERROR("Failed to parse the content(%d)", ret); - TSK_OBJECT_SAFE_FREE(content); - return tsk_null; - } - return content; - } - else{ - TSK_DEBUG_ERROR("No parser function for this content (%s)", type); - TSK_OBJECT_SAFE_FREE(content); - return tsk_null; - } - } - else{ - TSK_DEBUG_ERROR("Failed to to find content(%s)", type); - return tsk_null; - } + tmedia_content_t* content = tmedia_content_create(type); + if (content) { + if (content->plugin->parse) { + int ret; + if ((ret = content->plugin->parse(content, data, size))) { + TSK_DEBUG_ERROR("Failed to parse the content(%d)", ret); + TSK_OBJECT_SAFE_FREE(content); + return tsk_null; + } + return content; + } + else { + TSK_DEBUG_ERROR("No parser function for this content (%s)", type); + TSK_OBJECT_SAFE_FREE(content); + return tsk_null; + } + } + else { + TSK_DEBUG_ERROR("Failed to to find content(%s)", type); + return tsk_null; + } } int tmedia_content_init(tmedia_content_t* self) { - if (!self || !self->plugin){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } + if (!self || !self->plugin) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } - return 0; + return 0; } int tmedia_content_deinit(tmedia_content_t* self) { - if (!self || !self->plugin){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } + if (!self || !self->plugin) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } - return 0; + return 0; } tsk_buffer_t* tmedia_content_get_data(tmedia_content_t* self) { - if (!self || !self->plugin){ - TSK_DEBUG_ERROR("Invalid parameter"); - return tsk_null; - } - return self->plugin->get_data(self); + if (!self || !self->plugin) { + TSK_DEBUG_ERROR("Invalid parameter"); + return tsk_null; + } + return self->plugin->get_data(self); } @@ -202,19 +201,19 @@ tsk_buffer_t* tmedia_content_get_data(tmedia_content_t* self) static int tmedia_content_dummy_parse(tmedia_content_t* self, const void* in_data, tsk_size_t in_size) { - tmedia_content_dummy_t *dummy = TMEDIA_CONTENT_DUMMY(self); - if (!dummy || dummy->data){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - - dummy->data = tsk_buffer_create(in_data, in_size); - return 0; + tmedia_content_dummy_t *dummy = TMEDIA_CONTENT_DUMMY(self); + if (!dummy || dummy->data) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + + dummy->data = tsk_buffer_create(in_data, in_size); + return 0; } static tsk_buffer_t* tmedia_content_dummy_get_data(tmedia_content_t* self) { - return tsk_object_ref(TMEDIA_CONTENT_DUMMY(self)->data); + return tsk_object_ref(TMEDIA_CONTENT_DUMMY(self)->data); } @@ -228,42 +227,40 @@ static tsk_buffer_t* tmedia_content_dummy_get_data(tmedia_content_t* self) /* constructor */ static tsk_object_t* tmedia_content_dummy_ctor(tsk_object_t * self, va_list * app) { - tmedia_content_dummy_t *dummy = self; - if (dummy){ - /* init base: called by tmedia_content_create() */ - /* init self */ - } - return self; + tmedia_content_dummy_t *dummy = self; + if (dummy) { + /* init base: called by tmedia_content_create() */ + /* init self */ + } + return self; } /* destructor */ static tsk_object_t* tmedia_content_dummy_dtor(tsk_object_t * self) { - tmedia_content_dummy_t *dummy = self; - if (dummy){ - /* deinit base */ - tmedia_content_deinit(TMEDIA_CONTENT(dummy)); - /* deinit self */ - TSK_OBJECT_SAFE_FREE(dummy->data); - } - - return self; + tmedia_content_dummy_t *dummy = self; + if (dummy) { + /* deinit base */ + tmedia_content_deinit(TMEDIA_CONTENT(dummy)); + /* deinit self */ + TSK_OBJECT_SAFE_FREE(dummy->data); + } + + return self; } /* object definition */ -static const tsk_object_def_t tmedia_content_dummy_def_s = -{ - sizeof(tmedia_content_dummy_t), - tmedia_content_dummy_ctor, - tmedia_content_dummy_dtor, - tsk_null, +static const tsk_object_def_t tmedia_content_dummy_def_s = { + sizeof(tmedia_content_dummy_t), + tmedia_content_dummy_ctor, + tmedia_content_dummy_dtor, + tsk_null, }; /* plugin definition*/ -static const tmedia_content_plugin_def_t tmedia_content_dummy_plugin_def_s = -{ - &tmedia_content_dummy_def_s, +static const tmedia_content_plugin_def_t tmedia_content_dummy_plugin_def_s = { + &tmedia_content_dummy_def_s, - "dummy", - tmedia_content_dummy_parse, - tmedia_content_dummy_get_data + "dummy", + tmedia_content_dummy_parse, + tmedia_content_dummy_get_data }; const tmedia_content_plugin_def_t *tmedia_content_dummy_plugin_def_t = &tmedia_content_dummy_plugin_def_s; @@ -275,83 +272,82 @@ const tmedia_content_plugin_def_t *tmedia_content_dummy_plugin_def_t = &tmedia_c tmedia_content_header_t* tmedia_content_header_create(const char* name, const char* value) { - tmedia_content_header_t* header = tsk_object_new(tmedia_content_header_def_t); - const char* str; - - if (!header){ - TSK_DEBUG_ERROR("Failed to create new header object"); - return tsk_null; - } - header->name = tsk_strdup(name); - if (value && (str = strstr(value, ";"))){ - header->value = tsk_strndup(value, (tsk_size_t)(str - value)); - header->params = tsk_params_fromstring((str + 1), ";", tsk_true); - } - else{ - header->value = tsk_strdup(value); - } - - return header; + tmedia_content_header_t* header = tsk_object_new(tmedia_content_header_def_t); + const char* str; + + if (!header) { + TSK_DEBUG_ERROR("Failed to create new header object"); + return tsk_null; + } + header->name = tsk_strdup(name); + if (value && (str = strstr(value, ";"))) { + header->value = tsk_strndup(value, (tsk_size_t)(str - value)); + header->params = tsk_params_fromstring((str + 1), ";", tsk_true); + } + else { + header->value = tsk_strdup(value); + } + + return header; } int tmedia_content_header_deinit(tmedia_content_header_t* self) { - if (!self){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } + if (!self) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } - TSK_FREE(self->name); - TSK_FREE(self->value); - TSK_OBJECT_SAFE_FREE(self->params); + TSK_FREE(self->name); + TSK_FREE(self->value); + TSK_OBJECT_SAFE_FREE(self->params); - return 0; + return 0; } char* tmedia_content_header_tostring(const tmedia_content_header_t* self) { - char* string = tsk_null; - - if (!self){ - TSK_DEBUG_ERROR("Invalid parameter"); - return tsk_null; - } - - tsk_sprintf(&string, "%s: %s", self->name, self->value); - if (self->params){ - const tsk_list_item_t* item; - tsk_list_foreach(item, self->params){ - tsk_strcat_2(&string, ";%s=%s", TSK_PARAM(item->data)->name, TSK_PARAM(item->data)->value); - } - } - - return string; + char* string = tsk_null; + + if (!self) { + TSK_DEBUG_ERROR("Invalid parameter"); + return tsk_null; + } + + tsk_sprintf(&string, "%s: %s", self->name, self->value); + if (self->params) { + const tsk_list_item_t* item; + tsk_list_foreach(item, self->params) { + tsk_strcat_2(&string, ";%s=%s", TSK_PARAM(item->data)->name, TSK_PARAM(item->data)->value); + } + } + + return string; } /* constructor */ static tsk_object_t* tmedia_content_header_ctor(tsk_object_t * self, va_list * app) { - tmedia_content_header_t *header = self; - if (header){ - } - return self; + tmedia_content_header_t *header = self; + if (header) { + } + return self; } /* destructor */ static tsk_object_t* tmedia_content_header_dtor(tsk_object_t * self) { - tmedia_content_header_t *header = self; - if (header){ - tmedia_content_header_deinit(header); - } + tmedia_content_header_t *header = self; + if (header) { + tmedia_content_header_deinit(header); + } - return self; + return self; } /* object definition */ -static const tsk_object_def_t tmedia_content_header_def_s = -{ - sizeof(tmedia_content_header_t), - tmedia_content_header_ctor, - tmedia_content_header_dtor, - tsk_null, +static const tsk_object_def_t tmedia_content_header_def_s = { + sizeof(tmedia_content_header_t), + tmedia_content_header_ctor, + tmedia_content_header_dtor, + tsk_null, }; const tsk_object_def_t *tmedia_content_header_def_t = &tmedia_content_header_def_s; diff --git a/tinyMEDIA/src/content/tmedia_content_cpim.c b/tinyMEDIA/src/content/tmedia_content_cpim.c index 8b36727..6fb9f32 100755 --- a/tinyMEDIA/src/content/tmedia_content_cpim.c +++ b/tinyMEDIA/src/content/tmedia_content_cpim.c @@ -2,19 +2,19 @@ /* #line 1 "./ragel/tmedia_content_cpim.rl" */ /* * Copyright (C) 2010-2015 Mamadou DIOP. -* +* * 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. * @@ -67,337 +67,349 @@ A complete message looks something like this: static int tmedia_content_cpim_parse(tmedia_content_t* self, const void* in_data, tsk_size_t in_size) { - int cs = 0; - const char *p = in_data; - const char *pe = p + in_size; - const char *eof = pe; - - const char *tag_start = tsk_null; - - char* hname = tsk_null; - char* hvalue = tsk_null; - tsk_bool_t parsing_mime_headers = tsk_true; - - TSK_RAGEL_DISABLE_WARNINGS_BEGIN() - -/* #line 84 "./src/content/tmedia_content_cpim.c" */ -static const char _tmedia_machine_content_cpim_actions[] = { - 0, 1, 0, 1, 3, 1, 4, 1, - 5, 2, 0, 4, 2, 0, 5, 2, - 1, 0, 2, 2, 0 -}; - -static const char _tmedia_machine_content_cpim_key_offsets[] = { - 0, 0, 14, 30, 32, 34, 35, 36, - 51, 52, 66, 82, 84, 86, 87, 88, - 103, 104, 104 -}; - -static const char _tmedia_machine_content_cpim_trans_keys[] = { - 33, 37, 39, 126, 42, 43, 45, 46, - 48, 57, 65, 90, 95, 122, 32, 33, - 37, 39, 58, 126, 42, 43, 45, 46, - 48, 57, 65, 90, 95, 122, 32, 58, - 13, 32, 13, 10, 13, 33, 37, 39, - 126, 42, 43, 45, 46, 48, 57, 65, - 90, 95, 122, 10, 33, 37, 39, 126, - 42, 43, 45, 46, 48, 57, 65, 90, - 95, 122, 32, 33, 37, 39, 58, 126, - 42, 43, 45, 46, 48, 57, 65, 90, - 95, 122, 32, 58, 13, 32, 13, 10, - 13, 33, 37, 39, 126, 42, 43, 45, - 46, 48, 57, 65, 90, 95, 122, 10, - 0 -}; - -static const char _tmedia_machine_content_cpim_single_lengths[] = { - 0, 4, 6, 2, 2, 1, 1, 5, - 1, 4, 6, 2, 2, 1, 1, 5, - 1, 0, 0 -}; - -static const char _tmedia_machine_content_cpim_range_lengths[] = { - 0, 5, 5, 0, 0, 0, 0, 5, - 0, 5, 5, 0, 0, 0, 0, 5, - 0, 0, 0 -}; - -static const char _tmedia_machine_content_cpim_index_offsets[] = { - 0, 0, 10, 22, 25, 28, 30, 32, - 43, 45, 55, 67, 70, 73, 75, 77, - 88, 90, 91 -}; - -static const char _tmedia_machine_content_cpim_indicies[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 2, 3, 3, 3, 4, 3, - 3, 3, 3, 3, 3, 1, 5, 6, - 1, 8, 6, 7, 10, 9, 11, 1, - 12, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 1, 14, 1, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 1, 16, - 17, 17, 17, 18, 17, 17, 17, 17, - 17, 17, 1, 19, 20, 1, 22, 20, - 21, 24, 23, 25, 1, 26, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 1, - 28, 1, 29, 30, 0 -}; - -static const char _tmedia_machine_content_cpim_trans_targs[] = { - 2, 0, 3, 2, 4, 3, 4, 5, - 6, 5, 6, 7, 8, 2, 9, 10, - 11, 10, 12, 11, 12, 13, 14, 13, - 14, 15, 16, 10, 17, 18, 18 -}; - -static const char _tmedia_machine_content_cpim_trans_actions[] = { - 15, 0, 3, 0, 3, 0, 0, 1, - 9, 0, 5, 0, 0, 1, 0, 18, - 3, 0, 3, 0, 0, 1, 9, 0, - 5, 0, 0, 1, 0, 1, 0 -}; - -static const char _tmedia_machine_content_cpim_eof_actions[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 12, 7 -}; - -static const int tmedia_machine_content_cpim_start = 1; -static const int tmedia_machine_content_cpim_first_final = 17; -static const int tmedia_machine_content_cpim_error = 0; - -static const int tmedia_machine_content_cpim_en_main = 1; - - -/* #line 142 "./ragel/tmedia_content_cpim.rl" */ - (void)(eof); - (void)(tmedia_machine_content_cpim_first_final); - (void)(tmedia_machine_content_cpim_error); - (void)(tmedia_machine_content_cpim_en_main); - -/* #line 180 "./src/content/tmedia_content_cpim.c" */ - { - cs = tmedia_machine_content_cpim_start; - } - -/* #line 147 "./ragel/tmedia_content_cpim.rl" */ - -/* #line 187 "./src/content/tmedia_content_cpim.c" */ - { - int _klen; - unsigned int _trans; - const char *_acts; - unsigned int _nacts; - const char *_keys; - - if ( p == pe ) - goto _test_eof; - if ( cs == 0 ) - goto _out; + int cs = 0; + const char *p = in_data; + const char *pe = p + in_size; + const char *eof = pe; + + const char *tag_start = tsk_null; + + char* hname = tsk_null; + char* hvalue = tsk_null; + tsk_bool_t parsing_mime_headers = tsk_true; + + TSK_RAGEL_DISABLE_WARNINGS_BEGIN() + + /* #line 84 "./src/content/tmedia_content_cpim.c" */ + static const char _tmedia_machine_content_cpim_actions[] = { + 0, 1, 0, 1, 3, 1, 4, 1, + 5, 2, 0, 4, 2, 0, 5, 2, + 1, 0, 2, 2, 0 + }; + + static const char _tmedia_machine_content_cpim_key_offsets[] = { + 0, 0, 14, 30, 32, 34, 35, 36, + 51, 52, 66, 82, 84, 86, 87, 88, + 103, 104, 104 + }; + + static const char _tmedia_machine_content_cpim_trans_keys[] = { + 33, 37, 39, 126, 42, 43, 45, 46, + 48, 57, 65, 90, 95, 122, 32, 33, + 37, 39, 58, 126, 42, 43, 45, 46, + 48, 57, 65, 90, 95, 122, 32, 58, + 13, 32, 13, 10, 13, 33, 37, 39, + 126, 42, 43, 45, 46, 48, 57, 65, + 90, 95, 122, 10, 33, 37, 39, 126, + 42, 43, 45, 46, 48, 57, 65, 90, + 95, 122, 32, 33, 37, 39, 58, 126, + 42, 43, 45, 46, 48, 57, 65, 90, + 95, 122, 32, 58, 13, 32, 13, 10, + 13, 33, 37, 39, 126, 42, 43, 45, + 46, 48, 57, 65, 90, 95, 122, 10, + 0 + }; + + static const char _tmedia_machine_content_cpim_single_lengths[] = { + 0, 4, 6, 2, 2, 1, 1, 5, + 1, 4, 6, 2, 2, 1, 1, 5, + 1, 0, 0 + }; + + static const char _tmedia_machine_content_cpim_range_lengths[] = { + 0, 5, 5, 0, 0, 0, 0, 5, + 0, 5, 5, 0, 0, 0, 0, 5, + 0, 0, 0 + }; + + static const char _tmedia_machine_content_cpim_index_offsets[] = { + 0, 0, 10, 22, 25, 28, 30, 32, + 43, 45, 55, 67, 70, 73, 75, 77, + 88, 90, 91 + }; + + static const char _tmedia_machine_content_cpim_indicies[] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 2, 3, 3, 3, 4, 3, + 3, 3, 3, 3, 3, 1, 5, 6, + 1, 8, 6, 7, 10, 9, 11, 1, + 12, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 1, 14, 1, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 1, 16, + 17, 17, 17, 18, 17, 17, 17, 17, + 17, 17, 1, 19, 20, 1, 22, 20, + 21, 24, 23, 25, 1, 26, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 1, + 28, 1, 29, 30, 0 + }; + + static const char _tmedia_machine_content_cpim_trans_targs[] = { + 2, 0, 3, 2, 4, 3, 4, 5, + 6, 5, 6, 7, 8, 2, 9, 10, + 11, 10, 12, 11, 12, 13, 14, 13, + 14, 15, 16, 10, 17, 18, 18 + }; + + static const char _tmedia_machine_content_cpim_trans_actions[] = { + 15, 0, 3, 0, 3, 0, 0, 1, + 9, 0, 5, 0, 0, 1, 0, 18, + 3, 0, 3, 0, 0, 1, 9, 0, + 5, 0, 0, 1, 0, 1, 0 + }; + + static const char _tmedia_machine_content_cpim_eof_actions[] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 12, 7 + }; + + static const int tmedia_machine_content_cpim_start = 1; + static const int tmedia_machine_content_cpim_first_final = 17; + static const int tmedia_machine_content_cpim_error = 0; + + static const int tmedia_machine_content_cpim_en_main = 1; + + + /* #line 142 "./ragel/tmedia_content_cpim.rl" */ + (void)(eof); + (void)(tmedia_machine_content_cpim_first_final); + (void)(tmedia_machine_content_cpim_error); + (void)(tmedia_machine_content_cpim_en_main); + + /* #line 180 "./src/content/tmedia_content_cpim.c" */ + { + cs = tmedia_machine_content_cpim_start; + } + + /* #line 147 "./ragel/tmedia_content_cpim.rl" */ + + /* #line 187 "./src/content/tmedia_content_cpim.c" */ + { + int _klen; + unsigned int _trans; + const char *_acts; + unsigned int _nacts; + const char *_keys; + + if ( p == pe ) { + goto _test_eof; + } + if ( cs == 0 ) { + goto _out; + } _resume: - _keys = _tmedia_machine_content_cpim_trans_keys + _tmedia_machine_content_cpim_key_offsets[cs]; - _trans = _tmedia_machine_content_cpim_index_offsets[cs]; - - _klen = _tmedia_machine_content_cpim_single_lengths[cs]; - if ( _klen > 0 ) { - const char *_lower = _keys; - const char *_mid; - const char *_upper = _keys + _klen - 1; - while (1) { - if ( _upper < _lower ) - break; - - _mid = _lower + ((_upper-_lower) >> 1); - if ( (*p) < *_mid ) - _upper = _mid - 1; - else if ( (*p) > *_mid ) - _lower = _mid + 1; - else { - _trans += (_mid - _keys); - goto _match; - } - } - _keys += _klen; - _trans += _klen; - } - - _klen = _tmedia_machine_content_cpim_range_lengths[cs]; - if ( _klen > 0 ) { - const char *_lower = _keys; - const char *_mid; - const char *_upper = _keys + (_klen<<1) - 2; - while (1) { - if ( _upper < _lower ) - break; - - _mid = _lower + (((_upper-_lower) >> 1) & ~1); - if ( (*p) < _mid[0] ) - _upper = _mid - 2; - else if ( (*p) > _mid[1] ) - _lower = _mid + 2; - else { - _trans += ((_mid - _keys)>>1); - goto _match; - } - } - _trans += _klen; - } + _keys = _tmedia_machine_content_cpim_trans_keys + _tmedia_machine_content_cpim_key_offsets[cs]; + _trans = _tmedia_machine_content_cpim_index_offsets[cs]; + + _klen = _tmedia_machine_content_cpim_single_lengths[cs]; + if ( _klen > 0 ) { + const char *_lower = _keys; + const char *_mid; + const char *_upper = _keys + _klen - 1; + while (1) { + if ( _upper < _lower ) { + break; + } + + _mid = _lower + ((_upper-_lower) >> 1); + if ( (*p) < *_mid ) { + _upper = _mid - 1; + } + else if ( (*p) > *_mid ) { + _lower = _mid + 1; + } + else { + _trans += (_mid - _keys); + goto _match; + } + } + _keys += _klen; + _trans += _klen; + } + + _klen = _tmedia_machine_content_cpim_range_lengths[cs]; + if ( _klen > 0 ) { + const char *_lower = _keys; + const char *_mid; + const char *_upper = _keys + (_klen<<1) - 2; + while (1) { + if ( _upper < _lower ) { + break; + } + + _mid = _lower + (((_upper-_lower) >> 1) & ~1); + if ( (*p) < _mid[0] ) { + _upper = _mid - 2; + } + else if ( (*p) > _mid[1] ) { + _lower = _mid + 2; + } + else { + _trans += ((_mid - _keys)>>1); + goto _match; + } + } + _trans += _klen; + } _match: - _trans = _tmedia_machine_content_cpim_indicies[_trans]; - cs = _tmedia_machine_content_cpim_trans_targs[_trans]; - - if ( _tmedia_machine_content_cpim_trans_actions[_trans] == 0 ) - goto _again; - - _acts = _tmedia_machine_content_cpim_actions + _tmedia_machine_content_cpim_trans_actions[_trans]; - _nacts = (unsigned int) *_acts++; - while ( _nacts-- > 0 ) - { - switch ( *_acts++ ) - { - case 0: -/* #line 67 "./ragel/tmedia_content_cpim.rl" */ - { - tag_start = p; - } - break; - case 1: -/* #line 71 "./ragel/tmedia_content_cpim.rl" */ - { - parsing_mime_headers = tsk_true; - } - break; - case 2: -/* #line 75 "./ragel/tmedia_content_cpim.rl" */ - { - parsing_mime_headers = tsk_false; - } - break; - case 3: -/* #line 79 "./ragel/tmedia_content_cpim.rl" */ - { - TSK_PARSER_SET_STRING(hname); - } - break; - case 4: -/* #line 83 "./ragel/tmedia_content_cpim.rl" */ - { - tmedia_content_header_t* header; - TSK_PARSER_SET_STRING(hvalue); - header = tmedia_content_header_create(hname, hvalue); - TSK_FREE(hname); TSK_FREE(hvalue); - - if(parsing_mime_headers){ - if(!TMEDIA_CONTENT_CPIM(self)->m_headers){ - TMEDIA_CONTENT_CPIM(self)->m_headers = tsk_list_create(); - } - tsk_list_push_back_data(TMEDIA_CONTENT_CPIM(self)->m_headers, (void**)&header); - } - else{ - if(!TMEDIA_CONTENT_CPIM(self)->h_headers){ - TMEDIA_CONTENT_CPIM(self)->h_headers = tsk_list_create(); - } - tsk_list_push_back_data(TMEDIA_CONTENT_CPIM(self)->h_headers, (void**)&header); - } - } - break; -/* #line 307 "./src/content/tmedia_content_cpim.c" */ - } - } + _trans = _tmedia_machine_content_cpim_indicies[_trans]; + cs = _tmedia_machine_content_cpim_trans_targs[_trans]; + + if ( _tmedia_machine_content_cpim_trans_actions[_trans] == 0 ) { + goto _again; + } + + _acts = _tmedia_machine_content_cpim_actions + _tmedia_machine_content_cpim_trans_actions[_trans]; + _nacts = (unsigned int) *_acts++; + while ( _nacts-- > 0 ) { + switch ( *_acts++ ) { + case 0: + /* #line 67 "./ragel/tmedia_content_cpim.rl" */ + { + tag_start = p; + } + break; + case 1: + /* #line 71 "./ragel/tmedia_content_cpim.rl" */ + { + parsing_mime_headers = tsk_true; + } + break; + case 2: + /* #line 75 "./ragel/tmedia_content_cpim.rl" */ + { + parsing_mime_headers = tsk_false; + } + break; + case 3: + /* #line 79 "./ragel/tmedia_content_cpim.rl" */ + { + TSK_PARSER_SET_STRING(hname); + } + break; + case 4: + /* #line 83 "./ragel/tmedia_content_cpim.rl" */ + { + tmedia_content_header_t* header; + TSK_PARSER_SET_STRING(hvalue); + header = tmedia_content_header_create(hname, hvalue); + TSK_FREE(hname); + TSK_FREE(hvalue); + + if(parsing_mime_headers) { + if(!TMEDIA_CONTENT_CPIM(self)->m_headers) { + TMEDIA_CONTENT_CPIM(self)->m_headers = tsk_list_create(); + } + tsk_list_push_back_data(TMEDIA_CONTENT_CPIM(self)->m_headers, (void**)&header); + } + else { + if(!TMEDIA_CONTENT_CPIM(self)->h_headers) { + TMEDIA_CONTENT_CPIM(self)->h_headers = tsk_list_create(); + } + tsk_list_push_back_data(TMEDIA_CONTENT_CPIM(self)->h_headers, (void**)&header); + } + } + break; + /* #line 307 "./src/content/tmedia_content_cpim.c" */ + } + } _again: - if ( cs == 0 ) - goto _out; - if ( ++p != pe ) - goto _resume; - _test_eof: {} - if ( p == eof ) - { - const char *__acts = _tmedia_machine_content_cpim_actions + _tmedia_machine_content_cpim_eof_actions[cs]; - unsigned int __nacts = (unsigned int) *__acts++; - while ( __nacts-- > 0 ) { - switch ( *__acts++ ) { - case 0: -/* #line 67 "./ragel/tmedia_content_cpim.rl" */ - { - tag_start = p; - } - break; - case 5: -/* #line 103 "./ragel/tmedia_content_cpim.rl" */ - { - int len = (int)(p - tag_start); - if(len && tag_start){ - if(TMEDIA_CONTENT_CPIM(self)->e){ - TSK_OBJECT_SAFE_FREE(TMEDIA_CONTENT_CPIM(self)->e); \ - } - TMEDIA_CONTENT_CPIM(self)->e = tsk_buffer_create(tag_start, len); - } - } - break; -/* #line 341 "./src/content/tmedia_content_cpim.c" */ - } - } - } - - _out: {} - } - -/* #line 148 "./ragel/tmedia_content_cpim.rl" */ - TSK_RAGEL_DISABLE_WARNINGS_END() - - TSK_FREE(hname); - TSK_FREE(hvalue); - - if( cs < -/* #line 356 "./src/content/tmedia_content_cpim.c" */ -17 -/* #line 153 "./ragel/tmedia_content_cpim.rl" */ - ){ - TSK_DEBUG_ERROR("Failed to parse CPIM content"); - return -1; - } - - return 0; + if ( cs == 0 ) { + goto _out; + } + if ( ++p != pe ) { + goto _resume; + } +_test_eof: { + } + if ( p == eof ) { + const char *__acts = _tmedia_machine_content_cpim_actions + _tmedia_machine_content_cpim_eof_actions[cs]; + unsigned int __nacts = (unsigned int) *__acts++; + while ( __nacts-- > 0 ) { + switch ( *__acts++ ) { + case 0: + /* #line 67 "./ragel/tmedia_content_cpim.rl" */ + { + tag_start = p; + } + break; + case 5: + /* #line 103 "./ragel/tmedia_content_cpim.rl" */ + { + int len = (int)(p - tag_start); + if(len && tag_start) { + if(TMEDIA_CONTENT_CPIM(self)->e) { + TSK_OBJECT_SAFE_FREE(TMEDIA_CONTENT_CPIM(self)->e); + \ + } + TMEDIA_CONTENT_CPIM(self)->e = tsk_buffer_create(tag_start, len); + } + } + break; + /* #line 341 "./src/content/tmedia_content_cpim.c" */ + } + } + } + +_out: { + } + } + + /* #line 148 "./ragel/tmedia_content_cpim.rl" */ + TSK_RAGEL_DISABLE_WARNINGS_END() + + TSK_FREE(hname); + TSK_FREE(hvalue); + + if( cs < + /* #line 356 "./src/content/tmedia_content_cpim.c" */ + 17 + /* #line 153 "./ragel/tmedia_content_cpim.rl" */ + ) { + TSK_DEBUG_ERROR("Failed to parse CPIM content"); + return -1; + } + + return 0; } static tsk_buffer_t* tmedia_content_cpim_get_data(tmedia_content_t* self) { - tsk_buffer_t* data = tsk_buffer_create_null(); - tmedia_content_cpim_t *cpim = TMEDIA_CONTENT_CPIM(self); - const tsk_list_item_t* item; - /* - m: Content-type: Message/CPIM - s: - h: (message-metadata-headers) - s: - e: (encapsulated MIME message-body) - x: MIME security multipart message wrapper - */ - if(cpim->m_headers){ - tsk_list_foreach(item, cpim->m_headers){ - char* hstring = tmedia_content_header_tostring(TMEDIA_CONTENT_HEADER(item->data)); - tsk_buffer_append_2(data, TSK_LIST_IS_LAST(cpim->m_headers, item) ? "%s\r\n\r\n" : "%s\r\n", hstring); - TSK_FREE(hstring); - } - } - if(cpim->h_headers){ - tsk_list_foreach(item, cpim->h_headers){ - char* hstring = tmedia_content_header_tostring(TMEDIA_CONTENT_HEADER(item->data)); - tsk_buffer_append_2(data, TSK_LIST_IS_LAST(cpim->h_headers, item) ? "%s\r\n\r\n" : "%s\r\n", hstring); - TSK_FREE(hstring); - } - } - if(cpim->e){ - tsk_buffer_append(data, TSK_BUFFER_DATA(cpim->e), TSK_BUFFER_SIZE(cpim->e)); - } - if(cpim->x){ - tsk_buffer_append(data, TSK_BUFFER_DATA(cpim->x), TSK_BUFFER_SIZE(cpim->x)); - } - - return data; + tsk_buffer_t* data = tsk_buffer_create_null(); + tmedia_content_cpim_t *cpim = TMEDIA_CONTENT_CPIM(self); + const tsk_list_item_t* item; + /* + m: Content-type: Message/CPIM + s: + h: (message-metadata-headers) + s: + e: (encapsulated MIME message-body) + x: MIME security multipart message wrapper + */ + if(cpim->m_headers) { + tsk_list_foreach(item, cpim->m_headers) { + char* hstring = tmedia_content_header_tostring(TMEDIA_CONTENT_HEADER(item->data)); + tsk_buffer_append_2(data, TSK_LIST_IS_LAST(cpim->m_headers, item) ? "%s\r\n\r\n" : "%s\r\n", hstring); + TSK_FREE(hstring); + } + } + if(cpim->h_headers) { + tsk_list_foreach(item, cpim->h_headers) { + char* hstring = tmedia_content_header_tostring(TMEDIA_CONTENT_HEADER(item->data)); + tsk_buffer_append_2(data, TSK_LIST_IS_LAST(cpim->h_headers, item) ? "%s\r\n\r\n" : "%s\r\n", hstring); + TSK_FREE(hstring); + } + } + if(cpim->e) { + tsk_buffer_append(data, TSK_BUFFER_DATA(cpim->e), TSK_BUFFER_SIZE(cpim->e)); + } + if(cpim->x) { + tsk_buffer_append(data, TSK_BUFFER_DATA(cpim->x), TSK_BUFFER_SIZE(cpim->x)); + } + + return data; } //================================================================================================= @@ -406,44 +418,42 @@ static tsk_buffer_t* tmedia_content_cpim_get_data(tmedia_content_t* self) /* constructor */ static tsk_object_t* tmedia_content_cpim_ctor(tsk_object_t * self, va_list * app) { - tmedia_content_cpim_t *cpim = self; - if(cpim){ - /* init base: called by tmedia_content_create() */ - /* init self */ - } - return self; + tmedia_content_cpim_t *cpim = self; + if(cpim) { + /* init base: called by tmedia_content_create() */ + /* init self */ + } + return self; } /* destructor */ static tsk_object_t* tmedia_content_cpim_dtor(tsk_object_t * self) -{ - tmedia_content_cpim_t *cpim = self; - if(cpim){ - /* deinit base */ - tmedia_content_deinit(TMEDIA_CONTENT(cpim)); - /* deinit self */ - TSK_OBJECT_SAFE_FREE(cpim->m_headers); - TSK_OBJECT_SAFE_FREE(cpim->h_headers); - TSK_OBJECT_SAFE_FREE(cpim->e); - TSK_OBJECT_SAFE_FREE(cpim->x); - } - - return self; +{ + tmedia_content_cpim_t *cpim = self; + if(cpim) { + /* deinit base */ + tmedia_content_deinit(TMEDIA_CONTENT(cpim)); + /* deinit self */ + TSK_OBJECT_SAFE_FREE(cpim->m_headers); + TSK_OBJECT_SAFE_FREE(cpim->h_headers); + TSK_OBJECT_SAFE_FREE(cpim->e); + TSK_OBJECT_SAFE_FREE(cpim->x); + } + + return self; } /* object definition */ -static const tsk_object_def_t tmedia_content_cpim_def_s = -{ - sizeof(tmedia_content_cpim_t), - tmedia_content_cpim_ctor, - tmedia_content_cpim_dtor, - tsk_null, +static const tsk_object_def_t tmedia_content_cpim_def_s = { + sizeof(tmedia_content_cpim_t), + tmedia_content_cpim_ctor, + tmedia_content_cpim_dtor, + tsk_null, }; /* plugin definition*/ -static const tmedia_content_plugin_def_t tmedia_content_cpim_plugin_def_s = -{ - &tmedia_content_cpim_def_s, +static const tmedia_content_plugin_def_t tmedia_content_cpim_plugin_def_s = { + &tmedia_content_cpim_def_s, - TMEDIA_CONTENT_CPIM_TYPE, - tmedia_content_cpim_parse, - tmedia_content_cpim_get_data + TMEDIA_CONTENT_CPIM_TYPE, + tmedia_content_cpim_parse, + tmedia_content_cpim_get_data }; const tmedia_content_plugin_def_t *tmedia_content_cpim_plugin_def_t = &tmedia_content_cpim_plugin_def_s;
\ No newline at end of file diff --git a/tinyMEDIA/src/tmedia.c b/tinyMEDIA/src/tmedia.c index f43b4fa..daa907f 100755 --- a/tinyMEDIA/src/tmedia.c +++ b/tinyMEDIA/src/tmedia.c @@ -2,19 +2,19 @@ * Copyright (C) 2010-2011 Mamadou Diop. * * Contact: Mamadou Diop <diopmamadou(at)doubango[dot]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. * @@ -40,201 +40,201 @@ const tmedia_plugin_def_t* __tmedia_plugins[TMED_MAX_PLUGINS] = {0}; tmedia_t* tmedia_create(const char* name, const char* host, tnet_socket_type_t socket_type) { - return tsk_object_new(TMEDIA_VA_ARGS(name, host, socket_type)); + return tsk_object_new(TMEDIA_VA_ARGS(name, host, socket_type)); } tmedia_t* tmedia_create_null() { - return tmedia_create(tsk_null, TNET_SOCKET_HOST_ANY, tnet_socket_type_invalid); + return tmedia_create(tsk_null, TNET_SOCKET_HOST_ANY, tnet_socket_type_invalid); } int tmedia_init(tmedia_t* self, const char* name) { - if(!self){ - return -1; - } + if(!self) { + return -1; + } - tsk_strupdate(&self->name, name); + tsk_strupdate(&self->name, name); - return 0; + return 0; } int tmedia_deinit(tmedia_t* self) { - if(!self){ - return -1; - } + if(!self) { + return -1; + } - TSK_FREE(self->name); - TSK_FREE(self->protocol); + TSK_FREE(self->name); + TSK_FREE(self->protocol); - return 0; + return 0; } int tmedia_plugin_register(const tmedia_plugin_def_t* plugin) { - tsk_size_t i; - if(!plugin){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - - for(i=0; i<TMED_MAX_PLUGINS; i++){ - if(!__tmedia_plugins[i] || __tmedia_plugins[i] == plugin){ - __tmedia_plugins[i] = plugin; - return 0; - } - } - - TSK_DEBUG_ERROR("There are already %d plugins.", TMED_MAX_PLUGINS); - return -2; + tsk_size_t i; + if(!plugin) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + + for(i=0; i<TMED_MAX_PLUGINS; i++) { + if(!__tmedia_plugins[i] || __tmedia_plugins[i] == plugin) { + __tmedia_plugins[i] = plugin; + return 0; + } + } + + TSK_DEBUG_ERROR("There are already %d plugins.", TMED_MAX_PLUGINS); + return -2; } tmedia_t* tmedia_factory_create(const char* name, const char* host, tnet_socket_type_t socket_type) { - tmedia_t* ret = tsk_null; - const tmedia_plugin_def_t* plugin; - tsk_size_t i = 0; - - while((i < TMED_MAX_PLUGINS) && (plugin = __tmedia_plugins[i++])){ - if(plugin->objdef && tsk_strequals(plugin->name, name)){ - if((ret = tsk_object_new(plugin->objdef, name, host, socket_type))){ - ret->plugin = plugin; - break; - } - } - } - - return ret; + tmedia_t* ret = tsk_null; + const tmedia_plugin_def_t* plugin; + tsk_size_t i = 0; + + while((i < TMED_MAX_PLUGINS) && (plugin = __tmedia_plugins[i++])) { + if(plugin->objdef && tsk_strequals(plugin->name, name)) { + if((ret = tsk_object_new(plugin->objdef, name, host, socket_type))) { + ret->plugin = plugin; + break; + } + } + } + + return ret; } int tmedia_start(tmedia_t* self) { - if(!self || !self->plugin){ - return -1; - } - - if(!self->plugin->start){ - return -2; - } - else{ - return self->plugin->start(self); - } + if(!self || !self->plugin) { + return -1; + } + + if(!self->plugin->start) { + return -2; + } + else { + return self->plugin->start(self); + } } int tmedia_pause(tmedia_t*self ) { - if(!self || !self->plugin){ - return -1; - } - - if(!self->plugin->pause){ - return -2; - } - else{ - return self->plugin->pause(self); - } + if(!self || !self->plugin) { + return -1; + } + + if(!self->plugin->pause) { + return -2; + } + else { + return self->plugin->pause(self); + } } int tmedia_stop(tmedia_t* self) { - if(!self || !self->plugin){ - return -1; - } - - if(!self->plugin->stop){ - return -2; - } - else{ - return self->plugin->stop(self); - } + if(!self || !self->plugin) { + return -1; + } + + if(!self->plugin->stop) { + return -2; + } + else { + return self->plugin->stop(self); + } } // Only SDP headers const tsdp_header_M_t* tmedia_get_local_offer(tmedia_t* self, ...) { - - if(!self || !self->plugin){ - return tsk_null; - } - - if(!self->plugin->get_local_offer){ - return tsk_null; - } - else{ - va_list ap; - const tsdp_header_M_t* M; - va_start(ap, self); - M = self->plugin->get_local_offer(self, &ap); - va_end(ap); - return M; - } + + if(!self || !self->plugin) { + return tsk_null; + } + + if(!self->plugin->get_local_offer) { + return tsk_null; + } + else { + va_list ap; + const tsdp_header_M_t* M; + va_start(ap, self); + M = self->plugin->get_local_offer(self, &ap); + va_end(ap); + return M; + } } const tsdp_header_M_t* tmedia_get_negotiated_offer(tmedia_t* self) { - if(!self || !self->plugin){ - return tsk_null; - } - - if(!self->plugin->get_negotiated_offer){ - return tsk_null; - } - else{ - return self->plugin->get_negotiated_offer(self); - } + if(!self || !self->plugin) { + return tsk_null; + } + + if(!self->plugin->get_negotiated_offer) { + return tsk_null; + } + else { + return self->plugin->get_negotiated_offer(self); + } } int tmedia_set_remote_offer(tmedia_t* self, const tsdp_message_t* offer) { - if(!self || !self->plugin){ - return -1; - } - - if(!self->plugin->set_remote_offer){ - return -2; - } - else{ - return self->plugin->set_remote_offer(self, offer); - } + if(!self || !self->plugin) { + return -1; + } + + if(!self->plugin->set_remote_offer) { + return -2; + } + else { + return self->plugin->set_remote_offer(self, offer); + } } int tmedia_perform(tmedia_t* self, tmedia_action_t action, ... ) { - int ret = -1; - - if(!self || !self->plugin){ - return -1; - } - - if(!self->plugin->perform){ - return -2; - } - else{ - const tsk_object_def_t* objdef; - tsk_param_t *param; - tsk_params_L_t* params; - va_list ap; - - va_start(ap, action); - params = tsk_list_create(); - while((objdef = va_arg(ap, const tsk_object_def_t*))){ - if(objdef != tsk_param_def_t){ // sanity check - break; - } - if((param = tsk_object_new_2(objdef, &ap))){ - tsk_params_add_param_2(¶ms, param); - TSK_OBJECT_SAFE_FREE(param); - } - } - - // Perform - ret = self->plugin->perform(self, action, params); - - TSK_OBJECT_SAFE_FREE(params); - va_end(ap); - - return ret; - } + int ret = -1; + + if(!self || !self->plugin) { + return -1; + } + + if(!self->plugin->perform) { + return -2; + } + else { + const tsk_object_def_t* objdef; + tsk_param_t *param; + tsk_params_L_t* params; + va_list ap; + + va_start(ap, action); + params = tsk_list_create(); + while((objdef = va_arg(ap, const tsk_object_def_t*))) { + if(objdef != tsk_param_def_t) { // sanity check + break; + } + if((param = tsk_object_new_2(objdef, &ap))) { + tsk_params_add_param_2(¶ms, param); + TSK_OBJECT_SAFE_FREE(param); + } + } + + // Perform + ret = self->plugin->perform(self, action, params); + + TSK_OBJECT_SAFE_FREE(params); + va_end(ap); + + return ret; + } } //======================================================== @@ -243,44 +243,43 @@ int tmedia_perform(tmedia_t* self, tmedia_action_t action, ... ) static void* tmedia_ctor(tsk_object_t *self, va_list * app) { - tmedia_t *media = self; - if(media){ - const char* name = va_arg(*app, const char*); - const char* host = va_arg(*app, const char*); - tnet_socket_type_t socket_type = va_arg(*app, tnet_socket_type_t); - - tmedia_init(media, name); - } - else{ - TSK_DEBUG_ERROR("Failed to create new media."); - } - return self; + tmedia_t *media = self; + if(media) { + const char* name = va_arg(*app, const char*); + const char* host = va_arg(*app, const char*); + tnet_socket_type_t socket_type = va_arg(*app, tnet_socket_type_t); + + tmedia_init(media, name); + } + else { + TSK_DEBUG_ERROR("Failed to create new media."); + } + return self; } static void* tmedia_dtor(tsk_object_t *self) { - tmedia_t *media = self; - if(media){ - tmedia_deinit(media); - } - else{ - TSK_DEBUG_ERROR("Null media."); - } - - return self; + tmedia_t *media = self; + if(media) { + tmedia_deinit(media); + } + else { + TSK_DEBUG_ERROR("Null media."); + } + + return self; } static int tmedia_cmp(const tsk_object_t *obj1, const tsk_object_t *obj2) { - return -1; + return -1; } -static const tsk_object_def_t tmedia_def_s = -{ - sizeof(tmedia_t), - tmedia_ctor, - tmedia_dtor, - tmedia_cmp +static const tsk_object_def_t tmedia_def_s = { + sizeof(tmedia_t), + tmedia_ctor, + tmedia_dtor, + tmedia_cmp }; const void *tmedia_def_t = &tmedia_def_s; diff --git a/tinyMEDIA/src/tmedia_codec.c b/tinyMEDIA/src/tmedia_codec.c index 2b2b140..a5fb8e2 100755 --- a/tinyMEDIA/src/tmedia_codec.c +++ b/tinyMEDIA/src/tmedia_codec.c @@ -2,19 +2,19 @@ * Copyright (C) 2010-2011 Mamadou Diop. * * Contact: Mamadou Diop <diopmamadou(at)doubango[dot]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. * @@ -48,23 +48,23 @@ const tmedia_codec_plugin_def_t* __tmedia_codec_plugins[TMED_CODEC_MAX_PLUGINS] /*== Predicate function to find a codec object by format */ static int __pred_find_codec_by_format(const tsk_list_item_t *item, const void *format) { - if(item && item->data){ - return tsk_strcmp(((tmedia_codec_t *)item->data)->format, format); - } - return -1; + if(item && item->data) { + return tsk_strcmp(((tmedia_codec_t *)item->data)->format, format); + } + return -1; } /*== Predicate function to find a codec object by negociated format */ static int __pred_find_codec_by_neg_format(const tsk_list_item_t *item, const void *format) { - if(item && item->data){ - return tsk_strcmp(((tmedia_codec_t *)item->data)->neg_format, format); - } - return -1; + if(item && item->data) { + return tsk_strcmp(((tmedia_codec_t *)item->data)->neg_format, format); + } + return -1; } /**@ingroup tmedia_codec_group -* Initialize a Codec +* Initialize a Codec * @param self The codec to initialize. Could be any type of codec (e.g. @ref tmedia_codec_audio_t or @ref tmedia_codec_video_t). * @param type * @param name the name of the codec. e.g. "G.711u" or "G.711a" etc used in the sdp. @@ -74,71 +74,107 @@ static int __pred_find_codec_by_neg_format(const tsk_list_item_t *item, const vo */ int tmedia_codec_init(tmedia_codec_t* self, tmedia_type_t type, const char* name, const char* desc, const char* format) { - if(!self || tsk_strnullORempty(name)){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - self->type = type; - tsk_strupdate(&self->name, name); - tsk_strupdate(&self->desc,desc); - tsk_strupdate(&self->format, format); - if(!self->bandwidth_max_upload) self->bandwidth_max_upload = (type == tmedia_video ? tmedia_defaults_get_bandwidth_video_upload_max() : INT_MAX); // INT_MAX or <=0 means undefined - if(!self->bandwidth_max_download) self->bandwidth_max_download = (type == tmedia_video ? tmedia_defaults_get_bandwidth_video_download_max() : INT_MAX); // INT_MAX or <=0 means undefined - if(!self->in.rate) self->in.rate = self->plugin->rate; - if(!self->out.rate) self->out.rate = self->plugin->rate; - - if(type & tmedia_audio){ - tmedia_codec_audio_t* audio = TMEDIA_CODEC_AUDIO(self); - if(!audio->in.ptime) audio->in.ptime = (self->plugin->audio.ptime ? self->plugin->audio.ptime : tmedia_defaults_get_audio_ptime()); - if(!audio->out.ptime) audio->out.ptime = (self->plugin->audio.ptime ? self->plugin->audio.ptime : tmedia_defaults_get_audio_ptime()); - if(!audio->in.channels) audio->in.channels = self->plugin->audio.channels; - if(!audio->out.channels) audio->out.channels = self->plugin->audio.channels; - if(!audio->in.timestamp_multiplier) audio->in.timestamp_multiplier = tmedia_codec_audio_get_timestamp_multiplier(self->id, self->in.rate); - if(!audio->out.timestamp_multiplier) audio->out.timestamp_multiplier = tmedia_codec_audio_get_timestamp_multiplier(self->id, self->out.rate); - } - // Video flipping: For backward compatibility we have to initialize the default values - // according to the CFLAGS: 'FLIP_ENCODED_PICT' and 'FLIP_DECODED_PICT'. At any time you - // can update thse values (e.g. when the device switch from landscape to portrait) using video_session->set(); - else if(type & tmedia_video){ - tmedia_codec_video_t* video = TMEDIA_CODEC_VIDEO(self); + if(!self || tsk_strnullORempty(name)) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + self->type = type; + tsk_strupdate(&self->name, name); + tsk_strupdate(&self->desc,desc); + tsk_strupdate(&self->format, format); + if(!self->bandwidth_max_upload) { + self->bandwidth_max_upload = (type == tmedia_video ? tmedia_defaults_get_bandwidth_video_upload_max() : INT_MAX); // INT_MAX or <=0 means undefined + } + if(!self->bandwidth_max_download) { + self->bandwidth_max_download = (type == tmedia_video ? tmedia_defaults_get_bandwidth_video_download_max() : INT_MAX); // INT_MAX or <=0 means undefined + } + if(!self->in.rate) { + self->in.rate = self->plugin->rate; + } + if(!self->out.rate) { + self->out.rate = self->plugin->rate; + } + + if(type & tmedia_audio) { + tmedia_codec_audio_t* audio = TMEDIA_CODEC_AUDIO(self); + if(!audio->in.ptime) { + audio->in.ptime = (self->plugin->audio.ptime ? self->plugin->audio.ptime : tmedia_defaults_get_audio_ptime()); + } + if(!audio->out.ptime) { + audio->out.ptime = (self->plugin->audio.ptime ? self->plugin->audio.ptime : tmedia_defaults_get_audio_ptime()); + } + if(!audio->in.channels) { + audio->in.channels = self->plugin->audio.channels; + } + if(!audio->out.channels) { + audio->out.channels = self->plugin->audio.channels; + } + if(!audio->in.timestamp_multiplier) { + audio->in.timestamp_multiplier = tmedia_codec_audio_get_timestamp_multiplier(self->id, self->in.rate); + } + if(!audio->out.timestamp_multiplier) { + audio->out.timestamp_multiplier = tmedia_codec_audio_get_timestamp_multiplier(self->id, self->out.rate); + } + } + // Video flipping: For backward compatibility we have to initialize the default values + // according to the CFLAGS: 'FLIP_ENCODED_PICT' and 'FLIP_DECODED_PICT'. At any time you + // can update thse values (e.g. when the device switch from landscape to portrait) using video_session->set(); + else if(type & tmedia_video) { + tmedia_codec_video_t* video = TMEDIA_CODEC_VIDEO(self); #if FLIP_ENCODED_PICT - video->out.flip = tsk_true; + video->out.flip = tsk_true; #endif #if FLIP_DECODED_PICT - video->in.flip = tsk_true; + video->in.flip = tsk_true; #endif - if(!video->in.fps) video->in.fps = self->plugin->video.fps ? self->plugin->video.fps : tmedia_defaults_get_video_fps(); - if(!video->out.fps) video->out.fps = self->plugin->video.fps ? self->plugin->video.fps : tmedia_defaults_get_video_fps(); - if(video->in.chroma == tmedia_chroma_none) video->in.chroma = tmedia_chroma_yuv420p; - if(video->out.chroma == tmedia_chroma_none) video->out.chroma = tmedia_chroma_yuv420p; - - if(0){ // @deprecated - if(!video->in.width) video->in.width = video->out.width = self->plugin->video.width; - if(!video->in.height) video->in.height = video->out.height = self->plugin->video.height; - } - else{ - int ret; - unsigned width, height; - video->pref_size = tmedia_defaults_get_pref_video_size(); - if((ret = tmedia_video_get_size(video->pref_size, &width, &height)) != 0){ - width = self->plugin->video.width; - height = self->plugin->video.height; - } - if(!video->in.width) video->in.width = video->out.width = width; - if(!video->in.height) video->in.height = video->out.height = height; - } - - } - - return 0; + if(!video->in.fps) { + video->in.fps = self->plugin->video.fps ? self->plugin->video.fps : tmedia_defaults_get_video_fps(); + } + if(!video->out.fps) { + video->out.fps = self->plugin->video.fps ? self->plugin->video.fps : tmedia_defaults_get_video_fps(); + } + if(video->in.chroma == tmedia_chroma_none) { + video->in.chroma = tmedia_chroma_yuv420p; + } + if(video->out.chroma == tmedia_chroma_none) { + video->out.chroma = tmedia_chroma_yuv420p; + } + + if(0) { // @deprecated + if(!video->in.width) { + video->in.width = video->out.width = self->plugin->video.width; + } + if(!video->in.height) { + video->in.height = video->out.height = self->plugin->video.height; + } + } + else { + int ret; + unsigned width, height; + video->pref_size = tmedia_defaults_get_pref_video_size(); + if((ret = tmedia_video_get_size(video->pref_size, &width, &height)) != 0) { + width = self->plugin->video.width; + height = self->plugin->video.height; + } + if(!video->in.width) { + video->in.width = video->out.width = width; + } + if(!video->in.height) { + video->in.height = video->out.height = height; + } + } + + } + + return 0; } int tmedia_codec_set(tmedia_codec_t* self, const struct tmedia_param_s* param) { - if(self && self->plugin && self->plugin->set && param){ - return self->plugin->set(self, param); - } - return 0; + if(self && self->plugin && self->plugin->set && param) { + return self->plugin->set(self, param); + } + return 0; } /**@ingroup tmedia_codec_group @@ -149,30 +185,30 @@ int tmedia_codec_set(tmedia_codec_t* self, const struct tmedia_param_s* param) */ int tmedia_codec_open(tmedia_codec_t* self) { - if(!self || !self->plugin){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - if(self->opened){ - TSK_DEBUG_WARN("Codec already opened"); - return 0; - } - - if(self->plugin->open){ - int ret; - if((ret = self->plugin->open(self))){ - TSK_DEBUG_ERROR("Failed to open [%s] codec", self->plugin->desc); - return ret; - } - else{ - self->opened = tsk_true; - return 0; - } - } - else{ - self->opened = tsk_true; - return 0; - } + if(!self || !self->plugin) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + if(self->opened) { + TSK_DEBUG_WARN("Codec already opened"); + return 0; + } + + if(self->plugin->open) { + int ret; + if((ret = self->plugin->open(self))) { + TSK_DEBUG_ERROR("Failed to open [%s] codec", self->plugin->desc); + return ret; + } + else { + self->opened = tsk_true; + return 0; + } + } + else { + self->opened = tsk_true; + return 0; + } } /**@ingroup tmedia_codec_group @@ -183,30 +219,30 @@ int tmedia_codec_open(tmedia_codec_t* self) */ int tmedia_codec_close(tmedia_codec_t* self) { - if(!self || !self->plugin){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - if(!self->opened){ - return 0; - } - - if(self->plugin->close){ - int ret; - - if((ret = self->plugin->close(self))){ - TSK_DEBUG_ERROR("Failed to close [%s] codec", self->plugin->desc); - return ret; - } - else{ - self->opened = tsk_false; - return 0; - } - } - else{ - self->opened = tsk_false; - return 0; - } + if(!self || !self->plugin) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + if(!self->opened) { + return 0; + } + + if(self->plugin->close) { + int ret; + + if((ret = self->plugin->close(self))) { + TSK_DEBUG_ERROR("Failed to close [%s] codec", self->plugin->desc); + return ret; + } + else { + self->opened = tsk_false; + return 0; + } + } + else { + self->opened = tsk_false; + return 0; + } } /**@ingroup tmedia_codec_group @@ -220,17 +256,17 @@ int tmedia_codec_close(tmedia_codec_t* self) */ int tmedia_codec_cmp(const tsk_object_t* codec1, const tsk_object_t* codec2) { - const tmedia_codec_t* _c1 = codec1; - const tmedia_codec_t* _c2 = codec2; - - if((_c1 && _c2) && (_c1->type == _c2->type)){ - /* Do not compare names. For example, H264 base profile 1.0 will have the - * same name than H264 base profile 3.0. */ - return tsk_stricmp(_c1->format, _c2->format); - } - else{ - return -1; - } + const tmedia_codec_t* _c1 = codec1; + const tmedia_codec_t* _c2 = codec2; + + if((_c1 && _c2) && (_c1->type == _c2->type)) { + /* Do not compare names. For example, H264 base profile 1.0 will have the + * same name than H264 base profile 3.0. */ + return tsk_stricmp(_c1->format, _c2->format); + } + else { + return -1; + } } /**@ingroup tmedia_codec_group @@ -241,65 +277,65 @@ int tmedia_codec_cmp(const tsk_object_t* codec1, const tsk_object_t* codec2) */ int tmedia_codec_plugin_register(const tmedia_codec_plugin_def_t* plugin) { - tsk_size_t i; - if(!plugin || tsk_strnullORempty(plugin->name) || tsk_strnullORempty(plugin->format)){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - - /* add or replace the plugin */ - for(i = 0; i<TMED_CODEC_MAX_PLUGINS; i++){ - if(!__tmedia_codec_plugins[i] || (__tmedia_codec_plugins[i] == plugin)){ - __tmedia_codec_plugins[i] = plugin; - TSK_DEBUG_INFO("Register codec: %s, %s", plugin->name, plugin->desc); - return 0; - } - if(__tmedia_codec_plugins[i]->codec_id == plugin->codec_id && plugin->codec_id != tmedia_codec_id_none){ // 'tmedia_codec_id_none' is used for fake codecs - TSK_DEBUG_INFO("Codec Registration: '%s' ignored because '%s' already registered", plugin->desc, __tmedia_codec_plugins[i]->desc); - return -3; - } - } - - TSK_DEBUG_ERROR("There are already %d plugins.", TMED_CODEC_MAX_PLUGINS); - return -2; + tsk_size_t i; + if(!plugin || tsk_strnullORempty(plugin->name) || tsk_strnullORempty(plugin->format)) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + + /* add or replace the plugin */ + for(i = 0; i<TMED_CODEC_MAX_PLUGINS; i++) { + if(!__tmedia_codec_plugins[i] || (__tmedia_codec_plugins[i] == plugin)) { + __tmedia_codec_plugins[i] = plugin; + TSK_DEBUG_INFO("Register codec: %s, %s", plugin->name, plugin->desc); + return 0; + } + if(__tmedia_codec_plugins[i]->codec_id == plugin->codec_id && plugin->codec_id != tmedia_codec_id_none) { // 'tmedia_codec_id_none' is used for fake codecs + TSK_DEBUG_INFO("Codec Registration: '%s' ignored because '%s' already registered", plugin->desc, __tmedia_codec_plugins[i]->desc); + return -3; + } + } + + TSK_DEBUG_ERROR("There are already %d plugins.", TMED_CODEC_MAX_PLUGINS); + return -2; } int tmedia_codec_plugin_register_2(const tmedia_codec_plugin_def_t* plugin, int prio) { - tsk_size_t count = 0; - tsk_bool_t already_registered = tsk_false; - const tmedia_codec_plugin_def_t* tmp; - if(!plugin || tsk_strnullORempty(plugin->name) || tsk_strnullORempty(plugin->format) || (prio + 1) >= TMED_CODEC_MAX_PLUGINS){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - - // count codecs and found if already registered - while(__tmedia_codec_plugins[count]){ - if(__tmedia_codec_plugins[count] == plugin){ - already_registered = tsk_true; - } - ++count; - } - - if(count >= TMED_CODEC_MAX_PLUGINS){ - TSK_DEBUG_ERROR("No room"); - return -1; - } - - // unregister and compact - if(already_registered){ - if(tmedia_codec_plugin_unregister(plugin) == 0){ - --count; - } - } - - // put current plugin at prio and old (which was at prio) at the end - tmp = __tmedia_codec_plugins[prio]; - __tmedia_codec_plugins[count] = tmp;// put old codec add prio to the end of the list - __tmedia_codec_plugins[prio] = plugin; - - return 0; + tsk_size_t count = 0; + tsk_bool_t already_registered = tsk_false; + const tmedia_codec_plugin_def_t* tmp; + if(!plugin || tsk_strnullORempty(plugin->name) || tsk_strnullORempty(plugin->format) || (prio + 1) >= TMED_CODEC_MAX_PLUGINS) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + + // count codecs and found if already registered + while(__tmedia_codec_plugins[count]) { + if(__tmedia_codec_plugins[count] == plugin) { + already_registered = tsk_true; + } + ++count; + } + + if(count >= TMED_CODEC_MAX_PLUGINS) { + TSK_DEBUG_ERROR("No room"); + return -1; + } + + // unregister and compact + if(already_registered) { + if(tmedia_codec_plugin_unregister(plugin) == 0) { + --count; + } + } + + // put current plugin at prio and old (which was at prio) at the end + tmp = __tmedia_codec_plugins[prio]; + __tmedia_codec_plugins[count] = tmp;// put old codec add prio to the end of the list + __tmedia_codec_plugins[prio] = plugin; + + return 0; } /**@ingroup tmedia_codec_group @@ -310,15 +346,15 @@ int tmedia_codec_plugin_register_2(const tmedia_codec_plugin_def_t* plugin, int */ tsk_bool_t tmedia_codec_plugin_is_registered(const tmedia_codec_plugin_def_t* plugin) { - if(plugin){ - tsk_size_t i; - for(i = 0; i < TMED_CODEC_MAX_PLUGINS && __tmedia_codec_plugins[i]; i++){ - if(__tmedia_codec_plugins[i] == plugin){ - return tsk_true; - } - } - } - return tsk_false; + if(plugin) { + tsk_size_t i; + for(i = 0; i < TMED_CODEC_MAX_PLUGINS && __tmedia_codec_plugins[i]; i++) { + if(__tmedia_codec_plugins[i] == plugin) { + return tsk_true; + } + } + } + return tsk_false; } /**@ingroup tmedia_codec_group @@ -329,7 +365,7 @@ tsk_bool_t tmedia_codec_plugin_is_registered(const tmedia_codec_plugin_def_t* pl */ tsk_bool_t tmedia_codec_plugin_is_registered_2(tmedia_codec_id_t codec_id) { - return (tmedia_codec_plugin_registered_get_const(codec_id) != tsk_null); + return (tmedia_codec_plugin_registered_get_const(codec_id) != tsk_null); } /**@ingroup tmedia_codec_group @@ -340,26 +376,26 @@ tsk_bool_t tmedia_codec_plugin_is_registered_2(tmedia_codec_id_t codec_id) */ int tmedia_codec_plugin_registered_get_all(const struct tmedia_codec_plugin_def_s*(** plugins)[TMED_CODEC_MAX_PLUGINS], tsk_size_t* count) { - if(!plugins || !count) { - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - *plugins = &__tmedia_codec_plugins; - *count = sizeof(__tmedia_codec_plugins)/sizeof(__tmedia_codec_plugins[0]); - return 0; + if(!plugins || !count) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + *plugins = &__tmedia_codec_plugins; + *count = sizeof(__tmedia_codec_plugins)/sizeof(__tmedia_codec_plugins[0]); + return 0; } /**@ingroup tmedia_codec_group */ const struct tmedia_codec_plugin_def_s* tmedia_codec_plugin_registered_get_const(tmedia_codec_id_t codec_id) { - tsk_size_t i; - for(i = 0; i < TMED_CODEC_MAX_PLUGINS && __tmedia_codec_plugins[i]; i++){ - if(__tmedia_codec_plugins[i]->codec_id == codec_id){ - return __tmedia_codec_plugins[i]; - } - } - return tsk_null; + tsk_size_t i; + for(i = 0; i < TMED_CODEC_MAX_PLUGINS && __tmedia_codec_plugins[i]; i++) { + if(__tmedia_codec_plugins[i]->codec_id == codec_id) { + return __tmedia_codec_plugins[i]; + } + } + return tsk_null; } /**@ingroup tmedia_codec_group @@ -369,36 +405,36 @@ const struct tmedia_codec_plugin_def_s* tmedia_codec_plugin_registered_get_const */ int tmedia_codec_plugin_unregister(const tmedia_codec_plugin_def_t* plugin) { - tsk_size_t i; - tsk_bool_t found = tsk_false; - if(!plugin){ - TSK_DEBUG_ERROR("Invalid Parameter"); - return -1; - } - - /* find the plugin to unregister */ - for(i = 0; i<TMED_CODEC_MAX_PLUGINS && __tmedia_codec_plugins[i]; i++){ - if(__tmedia_codec_plugins[i] == plugin){ - TSK_DEBUG_INFO("UnRegister codec: %s, %s", plugin->name, plugin->desc); - __tmedia_codec_plugins[i] = tsk_null; - found = tsk_true; - break; - } - } - - /* compact */ - if(found){ - for(; i<(TMED_CODEC_MAX_PLUGINS - 1); i++){ - if(__tmedia_codec_plugins[i+1]){ - __tmedia_codec_plugins[i] = __tmedia_codec_plugins[i+1]; - } - else{ - break; - } - } - __tmedia_codec_plugins[i] = tsk_null; - } - return (found ? 0 : -2); + tsk_size_t i; + tsk_bool_t found = tsk_false; + if(!plugin) { + TSK_DEBUG_ERROR("Invalid Parameter"); + return -1; + } + + /* find the plugin to unregister */ + for(i = 0; i<TMED_CODEC_MAX_PLUGINS && __tmedia_codec_plugins[i]; i++) { + if(__tmedia_codec_plugins[i] == plugin) { + TSK_DEBUG_INFO("UnRegister codec: %s, %s", plugin->name, plugin->desc); + __tmedia_codec_plugins[i] = tsk_null; + found = tsk_true; + break; + } + } + + /* compact */ + if(found) { + for(; i<(TMED_CODEC_MAX_PLUGINS - 1); i++) { + if(__tmedia_codec_plugins[i+1]) { + __tmedia_codec_plugins[i] = __tmedia_codec_plugins[i+1]; + } + else { + break; + } + } + __tmedia_codec_plugins[i] = tsk_null; + } + return (found ? 0 : -2); } /**@ingroup tmedia_codec_group @@ -407,8 +443,8 @@ int tmedia_codec_plugin_unregister(const tmedia_codec_plugin_def_t* plugin) */ int tmedia_codec_plugin_unregister_all() { - memset((void*)__tmedia_codec_plugins, 0, sizeof(__tmedia_codec_plugins)); - return 0; + memset((void*)__tmedia_codec_plugins, 0, sizeof(__tmedia_codec_plugins)); + return 0; } /**@ingroup tmedia_codec_group @@ -418,48 +454,48 @@ int tmedia_codec_plugin_unregister_all() */ tmedia_codec_t* tmedia_codec_create(const char* format) { - tmedia_codec_t* codec = tsk_null; - const tmedia_codec_plugin_def_t* plugin; - tsk_size_t i = 0; - - while((i < TMED_CODEC_MAX_PLUGINS) && (plugin = __tmedia_codec_plugins[i++])){ - if(plugin->objdef && tsk_striequals(plugin->format, format)){ - if((codec = tsk_object_new(plugin->objdef))){ - /* initialize the newly created codec */ - codec->id = plugin->codec_id; - codec->dyn = plugin->dyn; - codec->plugin = plugin; - codec->bl = tmedia_bl_medium; - switch(plugin->type){ - case tmedia_audio: - { /* Audio codec */ - tmedia_codec_audio_t* audio = TMEDIA_CODEC_AUDIO(codec); - tmedia_codec_audio_init(TMEDIA_CODEC(audio), plugin->name, plugin->desc, plugin->format); - break; - } - case tmedia_video: - { /* Video codec */ - tmedia_codec_video_t* video = TMEDIA_CODEC_VIDEO(codec); - tmedia_codec_video_init(TMEDIA_CODEC(video), plugin->name, plugin->desc, plugin->format); - break; - } - case tmedia_msrp: - { /* Msrp codec */ - tmedia_codec_msrp_init(codec, plugin->name, plugin->desc); - break; - } - default: - { /* Any other codec */ - tmedia_codec_init(codec, plugin->type, plugin->name, plugin->desc, plugin->format); - break; - } - } - break; - } - } - } - - return codec; + tmedia_codec_t* codec = tsk_null; + const tmedia_codec_plugin_def_t* plugin; + tsk_size_t i = 0; + + while((i < TMED_CODEC_MAX_PLUGINS) && (plugin = __tmedia_codec_plugins[i++])) { + if(plugin->objdef && tsk_striequals(plugin->format, format)) { + if((codec = tsk_object_new(plugin->objdef))) { + /* initialize the newly created codec */ + codec->id = plugin->codec_id; + codec->dyn = plugin->dyn; + codec->plugin = plugin; + codec->bl = tmedia_bl_medium; + switch(plugin->type) { + case tmedia_audio: { + /* Audio codec */ + tmedia_codec_audio_t* audio = TMEDIA_CODEC_AUDIO(codec); + tmedia_codec_audio_init(TMEDIA_CODEC(audio), plugin->name, plugin->desc, plugin->format); + break; + } + case tmedia_video: { + /* Video codec */ + tmedia_codec_video_t* video = TMEDIA_CODEC_VIDEO(codec); + tmedia_codec_video_init(TMEDIA_CODEC(video), plugin->name, plugin->desc, plugin->format); + break; + } + case tmedia_msrp: { + /* Msrp codec */ + tmedia_codec_msrp_init(codec, plugin->name, plugin->desc); + break; + } + default: { + /* Any other codec */ + tmedia_codec_init(codec, plugin->type, plugin->name, plugin->desc, plugin->format); + break; + } + } + break; + } + } + } + + return codec; } /**@ingroup tmedia_codec_group @@ -470,46 +506,46 @@ tmedia_codec_t* tmedia_codec_create(const char* format) */ char* tmedia_codec_get_rtpmap(const tmedia_codec_t* self) { - char* rtpmap = tsk_null; - - if(!self || !self->plugin){ - TSK_DEBUG_ERROR("invalid parameter"); - return tsk_null; - } - if(self->type & tmedia_video){ - /* const tmedia_codec_video_t* videoCodec = (const tmedia_codec_video_t*)self; */ - tsk_sprintf(&rtpmap, "%s %s", self->neg_format? self->neg_format : self->format, self->name); - if(self->plugin->rate){ - tsk_strcat_2(&rtpmap, "/%d", self->plugin->rate); - } - } - else if(self->type & tmedia_audio){ - /* const tmedia_codec_audio_t* audioCodec = (const tmedia_codec_audio_t*)self; */ - - // special case for G.722 which has fake rate - if(tsk_strequals(self->plugin->format,TMEDIA_CODEC_FORMAT_G722)){ - tsk_sprintf(&rtpmap, "%s %s/8000/%d", self->neg_format? self->neg_format : self->format, self->name, self->plugin->audio.channels); - } - else{ - tsk_sprintf(&rtpmap, "%s %s", self->neg_format? self->neg_format : self->format, self->name); - if(self->plugin->rate){ - tsk_strcat_2(&rtpmap, "/%d", self->plugin->rate); - } - if(self->plugin->audio.channels > 0){ - tsk_strcat_2(&rtpmap, "/%d", self->plugin->audio.channels); - } - } - } - else if(self->type & tmedia_t140){ - tsk_sprintf(&rtpmap, "%s %s", self->neg_format? self->neg_format : self->format, self->name); - if(self->plugin->rate){ - tsk_strcat_2(&rtpmap, "/%d", self->plugin->rate); - } - } - else{ - } - - return rtpmap; + char* rtpmap = tsk_null; + + if(!self || !self->plugin) { + TSK_DEBUG_ERROR("invalid parameter"); + return tsk_null; + } + if(self->type & tmedia_video) { + /* const tmedia_codec_video_t* videoCodec = (const tmedia_codec_video_t*)self; */ + tsk_sprintf(&rtpmap, "%s %s", self->neg_format? self->neg_format : self->format, self->name); + if(self->plugin->rate) { + tsk_strcat_2(&rtpmap, "/%d", self->plugin->rate); + } + } + else if(self->type & tmedia_audio) { + /* const tmedia_codec_audio_t* audioCodec = (const tmedia_codec_audio_t*)self; */ + + // special case for G.722 which has fake rate + if(tsk_strequals(self->plugin->format,TMEDIA_CODEC_FORMAT_G722)) { + tsk_sprintf(&rtpmap, "%s %s/8000/%d", self->neg_format? self->neg_format : self->format, self->name, self->plugin->audio.channels); + } + else { + tsk_sprintf(&rtpmap, "%s %s", self->neg_format? self->neg_format : self->format, self->name); + if(self->plugin->rate) { + tsk_strcat_2(&rtpmap, "/%d", self->plugin->rate); + } + if(self->plugin->audio.channels > 0) { + tsk_strcat_2(&rtpmap, "/%d", self->plugin->audio.channels); + } + } + } + else if(self->type & tmedia_t140) { + tsk_sprintf(&rtpmap, "%s %s", self->neg_format? self->neg_format : self->format, self->name); + if(self->plugin->rate) { + tsk_strcat_2(&rtpmap, "/%d", self->plugin->rate); + } + } + else { + } + + return rtpmap; } /**@ingroup tmedia_codec_group @@ -520,19 +556,19 @@ char* tmedia_codec_get_rtpmap(const tmedia_codec_t* self) */ tsk_bool_t tmedia_codec_sdp_att_match(const tmedia_codec_t* self, const char* att_name, const char* att_value) { - /* checks */ - if(!self || !self->plugin || !self->plugin->sdp_att_match || !att_name){ - TSK_DEBUG_ERROR("invalid parameter"); - return tsk_false; - } - - /* if attribute value is null or empty -> always match */ - if(tsk_strnullORempty(att_value)){ - return tsk_true; - } - else{ - return self->plugin->sdp_att_match(self, att_name, att_value); - } + /* checks */ + if(!self || !self->plugin || !self->plugin->sdp_att_match || !att_name) { + TSK_DEBUG_ERROR("invalid parameter"); + return tsk_false; + } + + /* if attribute value is null or empty -> always match */ + if(tsk_strnullORempty(att_value)) { + return tsk_true; + } + else { + return self->plugin->sdp_att_match(self, att_name, att_value); + } } /**@ingroup tmedia_codec_group @@ -544,14 +580,14 @@ tsk_bool_t tmedia_codec_sdp_att_match(const tmedia_codec_t* self, const char* at */ char* tmedia_codec_sdp_att_get(const tmedia_codec_t* self, const char* att_name) { - if(!self || !self->plugin || !att_name){ - TSK_DEBUG_ERROR("invalid parameter"); - return tsk_null; - } - if(self->plugin->sdp_att_get){ /* some codecs, like G711, won't produce fmtp */ - return self->plugin->sdp_att_get(self, att_name); - } - return tsk_null; + if(!self || !self->plugin || !att_name) { + TSK_DEBUG_ERROR("invalid parameter"); + return tsk_null; + } + if(self->plugin->sdp_att_get) { /* some codecs, like G711, won't produce fmtp */ + return self->plugin->sdp_att_get(self, att_name); + } + return tsk_null; } @@ -563,19 +599,19 @@ char* tmedia_codec_sdp_att_get(const tmedia_codec_t* self, const char* att_name) */ int tmedia_codec_removeAll_exceptThese(tmedia_codecs_L_t* codecs, const tmedia_codecs_L_t * codecs2keep) { - tsk_list_item_t* item; - if(!codecs || !codecs2keep){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } + tsk_list_item_t* item; + if(!codecs || !codecs2keep) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } again: - tsk_list_foreach(item, codecs){ - if(!tsk_list_find_item_by_pred(codecs2keep, __pred_find_codec_by_format, ((tmedia_codec_t*)item->data)->format)){ - tsk_list_remove_item(codecs, item); - goto again; - } - } - return 0; + tsk_list_foreach(item, codecs) { + if(!tsk_list_find_item_by_pred(codecs2keep, __pred_find_codec_by_format, ((tmedia_codec_t*)item->data)->format)) { + tsk_list_remove_item(codecs, item); + goto again; + } + } + return 0; } /**@ingroup tmedia_codec_group @@ -587,78 +623,78 @@ again: */ int tmedia_codec_to_sdp(const tmedia_codecs_L_t* codecs, tsdp_header_M_t* m) { - const tsk_list_item_t* item; - const tmedia_codec_t* codec; - char *fmtp, *rtpmap, *imageattr; - tsk_bool_t is_audio, is_video, is_text; - int ret; - - if(!m){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - - is_audio = tsk_striequals(m->media, "audio"); - is_video = tsk_striequals(m->media, "video"); - is_text = tsk_striequals(m->media, "text"); - - tsk_list_foreach(item, codecs){ - const char *neg_format; - codec = item->data; - /* add fmt */ - neg_format = codec->neg_format? codec->neg_format : codec->format; - if((ret = tsdp_header_M_add_fmt(m, neg_format))){ - TSK_DEBUG_ERROR("Failed to add format"); - return ret; - } - - if(is_audio || is_video || is_text){ - char* temp = tsk_null; - /* add rtpmap attributes */ - if((rtpmap = tmedia_codec_get_rtpmap(codec))){ - tsdp_header_M_add_headers(m, - TSDP_HEADER_A_VA_ARGS("rtpmap", rtpmap), - tsk_null); - TSK_FREE(rtpmap); - } - /* add 'imageattr' attributes */ - if((imageattr = tmedia_codec_sdp_att_get(codec, "imageattr"))){ - tsk_sprintf(&temp, "%s %s", neg_format, imageattr); - tsdp_header_M_add_headers(m, - TSDP_HEADER_A_VA_ARGS("imageattr", temp), - tsk_null); - TSK_FREE(temp); - TSK_FREE(imageattr); - } - /* add fmtp attributes */ - if((fmtp = tmedia_codec_sdp_att_get(codec, "fmtp"))){ - if(is_video && tmedia_defaults_get_screen_x() > 0 && tmedia_defaults_get_screen_y() > 0){ - tsk_sprintf(&temp, "%s %s;sx=%d;sy=%d", neg_format, fmtp, tmedia_defaults_get_screen_x(), tmedia_defaults_get_screen_y());//doubango clients - } - else{ - tsk_sprintf(&temp, "%s %s", neg_format, fmtp); - } - tsdp_header_M_add_headers(m, - TSDP_HEADER_A_VA_ARGS("fmtp", temp), - tsk_null); - TSK_FREE(temp); - TSK_FREE(fmtp); - } - /* special case for T.140 + red */ - if(is_text && tsk_striequals(codec->format, TMEDIA_CODEC_FORMAT_RED)){ - const tmedia_codec_t* codec_t140 = tsk_list_find_object_by_pred(codecs, __pred_find_codec_by_format, TMEDIA_CODEC_FORMAT_T140); - if(codec_t140){ - const char* neg_format_t140 = codec_t140->neg_format? codec_t140->neg_format : codec_t140->format; - tsk_sprintf(&temp, "%s %s/%s/%s/%s", neg_format, neg_format_t140, neg_format_t140, neg_format_t140, neg_format_t140); - tsdp_header_M_add_headers(m, - TSDP_HEADER_A_VA_ARGS("fmtp", temp), - tsk_null); - TSK_FREE(temp); - } - } - } - } - return 0; + const tsk_list_item_t* item; + const tmedia_codec_t* codec; + char *fmtp, *rtpmap, *imageattr; + tsk_bool_t is_audio, is_video, is_text; + int ret; + + if(!m) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + + is_audio = tsk_striequals(m->media, "audio"); + is_video = tsk_striequals(m->media, "video"); + is_text = tsk_striequals(m->media, "text"); + + tsk_list_foreach(item, codecs) { + const char *neg_format; + codec = item->data; + /* add fmt */ + neg_format = codec->neg_format? codec->neg_format : codec->format; + if((ret = tsdp_header_M_add_fmt(m, neg_format))) { + TSK_DEBUG_ERROR("Failed to add format"); + return ret; + } + + if(is_audio || is_video || is_text) { + char* temp = tsk_null; + /* add rtpmap attributes */ + if((rtpmap = tmedia_codec_get_rtpmap(codec))) { + tsdp_header_M_add_headers(m, + TSDP_HEADER_A_VA_ARGS("rtpmap", rtpmap), + tsk_null); + TSK_FREE(rtpmap); + } + /* add 'imageattr' attributes */ + if((imageattr = tmedia_codec_sdp_att_get(codec, "imageattr"))) { + tsk_sprintf(&temp, "%s %s", neg_format, imageattr); + tsdp_header_M_add_headers(m, + TSDP_HEADER_A_VA_ARGS("imageattr", temp), + tsk_null); + TSK_FREE(temp); + TSK_FREE(imageattr); + } + /* add fmtp attributes */ + if((fmtp = tmedia_codec_sdp_att_get(codec, "fmtp"))) { + if(is_video && tmedia_defaults_get_screen_x() > 0 && tmedia_defaults_get_screen_y() > 0) { + tsk_sprintf(&temp, "%s %s;sx=%d;sy=%d", neg_format, fmtp, tmedia_defaults_get_screen_x(), tmedia_defaults_get_screen_y());//doubango clients + } + else { + tsk_sprintf(&temp, "%s %s", neg_format, fmtp); + } + tsdp_header_M_add_headers(m, + TSDP_HEADER_A_VA_ARGS("fmtp", temp), + tsk_null); + TSK_FREE(temp); + TSK_FREE(fmtp); + } + /* special case for T.140 + red */ + if(is_text && tsk_striequals(codec->format, TMEDIA_CODEC_FORMAT_RED)) { + const tmedia_codec_t* codec_t140 = tsk_list_find_object_by_pred(codecs, __pred_find_codec_by_format, TMEDIA_CODEC_FORMAT_T140); + if(codec_t140) { + const char* neg_format_t140 = codec_t140->neg_format? codec_t140->neg_format : codec_t140->format; + tsk_sprintf(&temp, "%s %s/%s/%s/%s", neg_format, neg_format_t140, neg_format_t140, neg_format_t140, neg_format_t140); + tsdp_header_M_add_headers(m, + TSDP_HEADER_A_VA_ARGS("fmtp", temp), + tsk_null); + TSK_FREE(temp); + } + } + } + } + return 0; } /**@ingroup tmedia_codec_group @@ -669,88 +705,88 @@ int tmedia_codec_to_sdp(const tmedia_codecs_L_t* codecs, tsdp_header_M_t* m) */ tmedia_codec_t* tmedia_codec_find_by_format(tmedia_codecs_L_t* codecs, const char* format) { - const tmedia_codec_t* codec = tsk_null; - - if(!codecs || !format){ - TSK_DEBUG_ERROR("Inalid parameter"); - return tsk_null; - } - - if((codec = tsk_list_find_object_by_pred(codecs, __pred_find_codec_by_format, format)) || - (codec = tsk_list_find_object_by_pred(codecs, __pred_find_codec_by_neg_format, format))){ - return tsk_object_ref((void*)codec); - } - else{ - return tsk_null; - } + const tmedia_codec_t* codec = tsk_null; + + if(!codecs || !format) { + TSK_DEBUG_ERROR("Inalid parameter"); + return tsk_null; + } + + if((codec = tsk_list_find_object_by_pred(codecs, __pred_find_codec_by_format, format)) || + (codec = tsk_list_find_object_by_pred(codecs, __pred_find_codec_by_neg_format, format))) { + return tsk_object_ref((void*)codec); + } + else { + return tsk_null; + } } /**@ingroup tmedia_codec_group */ int tmedia_codec_parse_fmtp(const char* fmtp, unsigned* maxbr, unsigned* fps, unsigned *width, unsigned *height) { - char *copy, *pch, *saveptr; - tsk_bool_t found = tsk_false; - - if(tsk_strnullORempty(fmtp)){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - - copy = tsk_strdup(fmtp); - pch = tsk_strtok_r(copy, "; /", &saveptr); - - while(pch){ - unsigned div = 0; - - if(sscanf(pch, "QCIF=%u", &div) == 1 && div){ - *fps = 30/div; - *width = 176; - *height = 144; - found = tsk_true; - } - else if(sscanf(pch, "CIF=%u", &div) == 1 && div){ - *fps = 30/div; - *width = 352; - *height = 288; - found = tsk_true; - } - else if(sscanf(pch, "SQCIF=%u", &div) == 1 && div){ - *fps = 30/div; - *width = 128; - *height = 96; - found = tsk_true; - } - else if(sscanf(pch, "QVGA=%u", &div) == 1 && div){ - *fps = 30/div; - *width = 320; - *height = 240; - found = tsk_true; - } - // to be continued - - if(found){ - //found = tsk_false; - pch = tsk_strtok_r(tsk_null, "; ", &saveptr); - while(pch){ - if(sscanf(pch, "MaxBR=%u", maxbr) == 1){ - //found = tsk_true; - break; - } - pch = tsk_strtok_r(tsk_null, "; /", &saveptr); - } - } - - if(found){ - break; - } - - pch = tsk_strtok_r(tsk_null, "; /", &saveptr); - } - - TSK_FREE(copy); - - return found ? 0 : -2; + char *copy, *pch, *saveptr; + tsk_bool_t found = tsk_false; + + if(tsk_strnullORempty(fmtp)) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + + copy = tsk_strdup(fmtp); + pch = tsk_strtok_r(copy, "; /", &saveptr); + + while(pch) { + unsigned div = 0; + + if(sscanf(pch, "QCIF=%u", &div) == 1 && div) { + *fps = 30/div; + *width = 176; + *height = 144; + found = tsk_true; + } + else if(sscanf(pch, "CIF=%u", &div) == 1 && div) { + *fps = 30/div; + *width = 352; + *height = 288; + found = tsk_true; + } + else if(sscanf(pch, "SQCIF=%u", &div) == 1 && div) { + *fps = 30/div; + *width = 128; + *height = 96; + found = tsk_true; + } + else if(sscanf(pch, "QVGA=%u", &div) == 1 && div) { + *fps = 30/div; + *width = 320; + *height = 240; + found = tsk_true; + } + // to be continued + + if(found) { + //found = tsk_false; + pch = tsk_strtok_r(tsk_null, "; ", &saveptr); + while(pch) { + if(sscanf(pch, "MaxBR=%u", maxbr) == 1) { + //found = tsk_true; + break; + } + pch = tsk_strtok_r(tsk_null, "; /", &saveptr); + } + } + + if(found) { + break; + } + + pch = tsk_strtok_r(tsk_null, "; /", &saveptr); + } + + TSK_FREE(copy); + + return found ? 0 : -2; } /**@ingroup tmedia_codec_group @@ -760,74 +796,104 @@ int tmedia_codec_parse_fmtp(const char* fmtp, unsigned* maxbr, unsigned* fps, un */ int tmedia_codec_deinit(tmedia_codec_t* self) { - if(!self){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } + if(!self) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } - if(self->opened){ - tmedia_codec_close(self); - } + if(self->opened) { + tmedia_codec_close(self); + } - TSK_FREE(self->name); - TSK_FREE(self->desc); - TSK_FREE(self->format); - TSK_FREE(self->neg_format); + TSK_FREE(self->name); + TSK_FREE(self->desc); + TSK_FREE(self->format); + TSK_FREE(self->neg_format); - return 0; + return 0; } int tmedia_codec_video_set_enc_callback(tmedia_codec_video_t *self, tmedia_codec_video_enc_cb_f callback, const void* callback_data) { - if(!self){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - self->out.callback = callback; - self->out.result.usr_data = callback_data; - return 0; + if(!self) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + self->out.callback = callback; + self->out.result.usr_data = callback_data; + return 0; } int tmedia_codec_video_set_dec_callback(tmedia_codec_video_t *self, tmedia_codec_video_dec_cb_f callback, const void* callback_data) { - if(!self){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - self->in.callback = callback; - self->in.result.usr_data = callback_data; - return 0; + if(!self) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + self->in.callback = callback; + self->in.result.usr_data = callback_data; + return 0; +} + +int tmedia_codec_video_clamp_out_size_to_range_max(tmedia_codec_video_t *self) +{ + int ret = 0; + if (!self) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + if (tmedia_defaults_get_adapt_video_size_range_enabled()) { + tmedia_pref_video_size_t min, max; + if ((ret = tmedia_defaults_get_pref_video_size_range(&min, &max)) == 0) { + unsigned width, height; + // clip(max) + if ((ret = tmedia_video_get_size(max, &width, &height)) == 0) { + unsigned new_width = TSK_CLAMP(0, self->out.width, width); + unsigned new_height = TSK_CLAMP(0, self->out.height, height); + TSK_DEBUG_INFO("Pref. video size range defined, video size clipped (%ux%u)->(%ux%u)", + width, height, + self->out.width, self->out.height); + self->out.width = width; + self->out.height = height; + } + // no clip(min) as we cannot increase the size to more than what was negotiated without sending reINVITE + } + } + return ret; } float tmedia_codec_audio_get_timestamp_multiplier(tmedia_codec_id_t id, uint32_t sample_rate) { - switch(id){ - case tmedia_codec_id_opus: - { - // draft-spittka-payload-rtp-opus-03 - 4.1. RTP Header Usage - switch(sample_rate){ - case 8000: return 6.f; - case 12000: return 4.f; - case 16000: return 3.f; - case 24000: return 2.f; - default: case 48000: return 1.f; - } - break; - } - case tmedia_codec_id_g722: - { - /* http://www.ietf.org/rfc/rfc3551.txt - Even though the actual sampling rate for G.722 audio is 16,000 Hz, - the RTP clock rate for the G722 payload format is 8,000 Hz because - that value was erroneously assigned in RFC 1890 and must remain - unchanged for backward compatibility. The octet rate or sample-pair - rate is 8,000 Hz. - */ - return .5f; - } - default: - { - return 1; - } - } + switch(id) { + case tmedia_codec_id_opus: { + // draft-spittka-payload-rtp-opus-03 - 4.1. RTP Header Usage + switch(sample_rate) { + case 8000: + return 6.f; + case 12000: + return 4.f; + case 16000: + return 3.f; + case 24000: + return 2.f; + default: + case 48000: + return 1.f; + } + break; + } + case tmedia_codec_id_g722: { + /* http://www.ietf.org/rfc/rfc3551.txt + Even though the actual sampling rate for G.722 audio is 16,000 Hz, + the RTP clock rate for the G722 payload format is 8,000 Hz because + that value was erroneously assigned in RFC 1890 and must remain + unchanged for backward compatibility. The octet rate or sample-pair + rate is 8,000 Hz. + */ + return .5f; + } + default: { + return 1; + } + } }
\ No newline at end of file diff --git a/tinyMEDIA/src/tmedia_codec_dummy.c b/tinyMEDIA/src/tmedia_codec_dummy.c index 377f629..f84b99d 100755 --- a/tinyMEDIA/src/tmedia_codec_dummy.c +++ b/tinyMEDIA/src/tmedia_codec_dummy.c @@ -2,19 +2,19 @@ * Copyright (C) 2010-2011 Mamadou Diop. * * Contact: Mamadou Diop <diopmamadou(at)doubango[dot]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. * @@ -41,68 +41,67 @@ #define tmedia_codec_dpcmu_fmtp_decode tsk_null tsk_bool_t tmedia_codec_dpcmu_sdp_att_match(const tmedia_codec_t* codec, const char* att_name, const char* att_value) -{ /* always match */ - return tsk_true; +{ + /* always match */ + return tsk_true; } /* constructor */ static tsk_object_t* tmedia_codec_dpcmu_ctor(tsk_object_t * self, va_list * app) { - tmedia_codec_dpcmu_t *dpcmu = self; - if(dpcmu){ - /* init base: called by tmedia_codec_create() */ - /* init self */ - } - return self; + tmedia_codec_dpcmu_t *dpcmu = self; + if(dpcmu) { + /* init base: called by tmedia_codec_create() */ + /* init self */ + } + return self; } /* destructor */ static tsk_object_t* tmedia_codec_dpcmu_dtor(tsk_object_t * self) -{ - tmedia_codec_dpcmu_t *dpcmu = self; - if(dpcmu){ - /* deinit base */ - tmedia_codec_audio_deinit(dpcmu); - /* deinit self */ - } - - return self; +{ + tmedia_codec_dpcmu_t *dpcmu = self; + if(dpcmu) { + /* deinit base */ + tmedia_codec_audio_deinit(dpcmu); + /* deinit self */ + } + + return self; } /* object definition */ -static const tsk_object_def_t tmedia_codec_dpcmu_def_s = -{ - sizeof(tmedia_codec_dpcmu_t), - tmedia_codec_dpcmu_ctor, - tmedia_codec_dpcmu_dtor, - tmedia_codec_cmp, +static const tsk_object_def_t tmedia_codec_dpcmu_def_s = { + sizeof(tmedia_codec_dpcmu_t), + tmedia_codec_dpcmu_ctor, + tmedia_codec_dpcmu_dtor, + tmedia_codec_cmp, }; /* plugin definition*/ -static const tmedia_codec_plugin_def_t tmedia_codec_dpcmu_plugin_def_s = -{ - &tmedia_codec_dpcmu_def_s, - - tmedia_audio, - tmedia_codec_id_pcmu, - "G.711u", - "Dummy G.711u codec", - TMEDIA_CODEC_FORMAT_G711u, - tsk_false, - 8000, // rate - - { /* audio */ - 1, // channels - 20 // ptime - }, - - /* video */ - {0}, - - tsk_null, // set() - tsk_null, // open - tsk_null, // close - tmedia_codec_dpcmu_fmtp_encode, - tmedia_codec_dpcmu_fmtp_decode, - tmedia_codec_dpcmu_sdp_att_match, - tmedia_codec_dpcmu_sdp_att_get, +static const tmedia_codec_plugin_def_t tmedia_codec_dpcmu_plugin_def_s = { + &tmedia_codec_dpcmu_def_s, + + tmedia_audio, + tmedia_codec_id_pcmu, + "G.711u", + "Dummy G.711u codec", + TMEDIA_CODEC_FORMAT_G711u, + tsk_false, + 8000, // rate + + { /* audio */ + 1, // channels + 20 // ptime + }, + + /* video */ + {0}, + + tsk_null, // set() + tsk_null, // open + tsk_null, // close + tmedia_codec_dpcmu_fmtp_encode, + tmedia_codec_dpcmu_fmtp_decode, + tmedia_codec_dpcmu_sdp_att_match, + tmedia_codec_dpcmu_sdp_att_get, }; const tmedia_codec_plugin_def_t *tmedia_codec_dpcmu_plugin_def_t = &tmedia_codec_dpcmu_plugin_def_s; @@ -116,68 +115,67 @@ const tmedia_codec_plugin_def_t *tmedia_codec_dpcmu_plugin_def_t = &tmedia_codec #define tmedia_codec_dpcma_fmtp_decode tsk_null tsk_bool_t tmedia_codec_dpcma_sdp_att_match(const tmedia_codec_t* codec, const char* att_name, const char* att_value) -{ /* always match */ - return tsk_true; +{ + /* always match */ + return tsk_true; } /* constructor */ static tsk_object_t* tmedia_codec_dpcma_ctor(tsk_object_t * self, va_list * app) { - tmedia_codec_dpcma_t *dpcma = self; - if(dpcma){ - /* init base: called by tmedia_codec_create() */ - /* init self */ - } - return self; + tmedia_codec_dpcma_t *dpcma = self; + if(dpcma) { + /* init base: called by tmedia_codec_create() */ + /* init self */ + } + return self; } /* destructor */ static tsk_object_t* tmedia_codec_dpcma_dtor(tsk_object_t * self) -{ - tmedia_codec_dpcma_t *dpcma = self; - if(dpcma){ - /* deinit base */ - tmedia_codec_audio_deinit(dpcma); - /* deinit self */ - } - - return self; +{ + tmedia_codec_dpcma_t *dpcma = self; + if(dpcma) { + /* deinit base */ + tmedia_codec_audio_deinit(dpcma); + /* deinit self */ + } + + return self; } /* object definition */ -static const tsk_object_def_t tmedia_codec_dpcma_def_s = -{ - sizeof(tmedia_codec_dpcma_t), - tmedia_codec_dpcma_ctor, - tmedia_codec_dpcma_dtor, - tmedia_codec_cmp, +static const tsk_object_def_t tmedia_codec_dpcma_def_s = { + sizeof(tmedia_codec_dpcma_t), + tmedia_codec_dpcma_ctor, + tmedia_codec_dpcma_dtor, + tmedia_codec_cmp, }; /* plugin definition*/ -static const tmedia_codec_plugin_def_t tmedia_codec_dpcma_plugin_def_s = -{ - &tmedia_codec_dpcma_def_s, - - tmedia_audio, - tmedia_codec_id_pcma, - "G.711a", - "Dummy G.711a codec", - TMEDIA_CODEC_FORMAT_G711a, - tsk_false, - 8000, // rate - - { /* audio */ - 1, // channels - 20 // ptime - }, - - /* video */ - {0}, - - tsk_null, // set() - tsk_null, // open - tsk_null, // close - tmedia_codec_dpcma_fmtp_encode, - tmedia_codec_dpcma_fmtp_decode, - tmedia_codec_dpcma_sdp_att_match, - tmedia_codec_dpcma_sdp_att_get +static const tmedia_codec_plugin_def_t tmedia_codec_dpcma_plugin_def_s = { + &tmedia_codec_dpcma_def_s, + + tmedia_audio, + tmedia_codec_id_pcma, + "G.711a", + "Dummy G.711a codec", + TMEDIA_CODEC_FORMAT_G711a, + tsk_false, + 8000, // rate + + { /* audio */ + 1, // channels + 20 // ptime + }, + + /* video */ + {0}, + + tsk_null, // set() + tsk_null, // open + tsk_null, // close + tmedia_codec_dpcma_fmtp_encode, + tmedia_codec_dpcma_fmtp_decode, + tmedia_codec_dpcma_sdp_att_match, + tmedia_codec_dpcma_sdp_att_get }; const tmedia_codec_plugin_def_t *tmedia_codec_dpcma_plugin_def_t = &tmedia_codec_dpcma_plugin_def_s; @@ -189,88 +187,86 @@ const tmedia_codec_plugin_def_t *tmedia_codec_dpcma_plugin_def_t = &tmedia_codec tsk_size_t tmedia_codec_dh263_fmtp_encode(tmedia_codec_t* self, const void* in_data, tsk_size_t in_size, void** out_data, tsk_size_t* out_max_size) { - return 0; + return 0; } tsk_size_t tmedia_codec_dh263_fmtp_decode(tmedia_codec_t* self, const void* in_data, tsk_size_t in_size, void** out_data, tsk_size_t* out_max_size, const tsk_object_t* proto_hdr) { - return 0; + return 0; } tsk_bool_t tmedia_codec_dh263_sdp_att_match(const tmedia_codec_t* codec, const char* att_name, const char* att_value) -{ - /* check whether we can match this fmtp with our local - * check size, maxbr, fps ...*/ - return tsk_true; +{ + /* check whether we can match this fmtp with our local + * check size, maxbr, fps ...*/ + return tsk_true; } char* tmedia_codec_dh263_sdp_att_get(const tmedia_codec_t* codec, const char* att_name) { - return tsk_strdup("CIF=2/MaxBR=3840;QCIF=2/MaxBR=1920"); + return tsk_strdup("CIF=2/MaxBR=3840;QCIF=2/MaxBR=1920"); } int tmedia_codec_dh263_fmtp_set(tmedia_codec_t* self, const char* fmtp) { - TSK_DEBUG_INFO("remote fmtp=%s", fmtp); - return 0; + TSK_DEBUG_INFO("remote fmtp=%s", fmtp); + return 0; } /* constructor */ static tsk_object_t* tmedia_codec_dh263_ctor(tsk_object_t * self, va_list * app) { - tmedia_codec_dh263_t *dh263 = self; - if(dh263){ - /* init base: called by tmedia_codec_create() */ - /* init self */ - } - return self; + tmedia_codec_dh263_t *dh263 = self; + if(dh263) { + /* init base: called by tmedia_codec_create() */ + /* init self */ + } + return self; } /* destructor */ static tsk_object_t* tmedia_codec_dh263_dtor(tsk_object_t * self) -{ - tmedia_codec_dh263_t *dh263 = self; - if(dh263){ - /* deinit base */ - tmedia_codec_video_deinit(dh263); - /* deinit self */ - } - - return self; +{ + tmedia_codec_dh263_t *dh263 = self; + if(dh263) { + /* deinit base */ + tmedia_codec_video_deinit(dh263); + /* deinit self */ + } + + return self; } /* object definition */ -static const tsk_object_def_t tmedia_codec_dh263_def_s = -{ - sizeof(tmedia_codec_dh263_t), - tmedia_codec_dh263_ctor, - tmedia_codec_dh263_dtor, - tmedia_codec_cmp, +static const tsk_object_def_t tmedia_codec_dh263_def_s = { + sizeof(tmedia_codec_dh263_t), + tmedia_codec_dh263_ctor, + tmedia_codec_dh263_dtor, + tmedia_codec_cmp, }; /* plugin definition*/ -static const tmedia_codec_plugin_def_t tmedia_codec_dh263_plugin_def_s = -{ - &tmedia_codec_dh263_def_s, - - tmedia_video, - tmedia_codec_id_h263, - "H263", - "Dummy H.263-1996 codec", - TMEDIA_CODEC_FORMAT_H263, - tsk_false, - 90000, // rate - - /* audio */ - { 0 }, - - /* video */ - {176, 144}, - - tsk_null, // set() - tsk_null, // open - tsk_null, // close - tmedia_codec_dh263_fmtp_encode, - tmedia_codec_dh263_fmtp_decode, - tmedia_codec_dh263_sdp_att_match, - tmedia_codec_dh263_sdp_att_get +static const tmedia_codec_plugin_def_t tmedia_codec_dh263_plugin_def_s = { + &tmedia_codec_dh263_def_s, + + tmedia_video, + tmedia_codec_id_h263, + "H263", + "Dummy H.263-1996 codec", + TMEDIA_CODEC_FORMAT_H263, + tsk_false, + 90000, // rate + + /* audio */ + { 0 }, + + /* video */ + {176, 144}, + + tsk_null, // set() + tsk_null, // open + tsk_null, // close + tmedia_codec_dh263_fmtp_encode, + tmedia_codec_dh263_fmtp_decode, + tmedia_codec_dh263_sdp_att_match, + tmedia_codec_dh263_sdp_att_get }; const tmedia_codec_plugin_def_t *tmedia_codec_dh263_plugin_def_t = &tmedia_codec_dh263_plugin_def_s; @@ -283,87 +279,85 @@ const tmedia_codec_plugin_def_t *tmedia_codec_dh263_plugin_def_t = &tmedia_codec tsk_size_t tmedia_codec_dh264_fmtp_encode(tmedia_codec_t* self, const void* in_data, tsk_size_t in_size, void** out_data, tsk_size_t* out_max_size) { - return 0; + return 0; } tsk_size_t tmedia_codec_dh264_fmtp_decode(tmedia_codec_t* self, const void* in_data, tsk_size_t in_size, void** out_data, tsk_size_t* out_max_size, const tsk_object_t* proto_hdr) { - return 0; + return 0; } tsk_bool_t tmedia_codec_dh264_sdp_att_match(const tmedia_codec_t* codec, const char* att_name, const char* att_value) -{ - /* check whether we can match this fmtp with our local - * check size, maxbr, fps, profile-level-id, packetization-mode ...*/ - return tsk_true; +{ + /* check whether we can match this fmtp with our local + * check size, maxbr, fps, profile-level-id, packetization-mode ...*/ + return tsk_true; } char* tmedia_codec_dh264_sdp_att_get(const tmedia_codec_t* codec, const char* att_name) { - return tsk_strdup("profile-level-id=42A01E;sprop-parameter-sets=Z0IACpZTBYmI,aMljiA=="); + return tsk_strdup("profile-level-id=42A01E;sprop-parameter-sets=Z0IACpZTBYmI,aMljiA=="); } int tmedia_codec_dh264_fmtp_set(tmedia_codec_t* self, const char* fmtp) { - TSK_DEBUG_INFO("remote fmtp=%s", fmtp); - return 0; + TSK_DEBUG_INFO("remote fmtp=%s", fmtp); + return 0; } /* constructor */ static tsk_object_t* tmedia_codec_dh264_ctor(tsk_object_t * self, va_list * app) { - tmedia_codec_dh264_t *dh264 = self; - if(dh264){ - /* init base: called by tmedia_codec_create() */ - /* init self */ - } - return self; + tmedia_codec_dh264_t *dh264 = self; + if(dh264) { + /* init base: called by tmedia_codec_create() */ + /* init self */ + } + return self; } /* destructor */ static tsk_object_t* tmedia_codec_dh264_dtor(tsk_object_t * self) -{ - tmedia_codec_dh264_t *dh264 = self; - if(dh264){ - /* deinit base */ - tmedia_codec_video_deinit(dh264); - /* deinit self */ - } - - return self; +{ + tmedia_codec_dh264_t *dh264 = self; + if(dh264) { + /* deinit base */ + tmedia_codec_video_deinit(dh264); + /* deinit self */ + } + + return self; } /* object definition */ -static const tsk_object_def_t tmedia_codec_dh264_def_s = -{ - sizeof(tmedia_codec_dh264_t), - tmedia_codec_dh264_ctor, - tmedia_codec_dh264_dtor, - tmedia_codec_cmp, +static const tsk_object_def_t tmedia_codec_dh264_def_s = { + sizeof(tmedia_codec_dh264_t), + tmedia_codec_dh264_ctor, + tmedia_codec_dh264_dtor, + tmedia_codec_cmp, }; /* plugin definition*/ -static const tmedia_codec_plugin_def_t tmedia_codec_dh264_plugin_def_s = -{ - &tmedia_codec_dh264_def_s, - - tmedia_video, - tmedia_codec_id_h264_bp, - "H264", - "Dummy H.264 (base profile 10) codec", - TMEDIA_CODEC_FORMAT_H264_BP, - tsk_true, - 90000, // rate - - /* audio */ - { 0 }, - - /* video */ - {176, 144}, - - tsk_null, // set() - tsk_null, // open - tsk_null, // close - tmedia_codec_dh264_fmtp_encode, - tmedia_codec_dh264_fmtp_decode, - tmedia_codec_dh264_sdp_att_match, - tmedia_codec_dh264_sdp_att_get +static const tmedia_codec_plugin_def_t tmedia_codec_dh264_plugin_def_s = { + &tmedia_codec_dh264_def_s, + + tmedia_video, + tmedia_codec_id_h264_bp, + "H264", + "Dummy H.264 (base profile 10) codec", + TMEDIA_CODEC_FORMAT_H264_BP, + tsk_true, + 90000, // rate + + /* audio */ + { 0 }, + + /* video */ + {176, 144}, + + tsk_null, // set() + tsk_null, // open + tsk_null, // close + tmedia_codec_dh264_fmtp_encode, + tmedia_codec_dh264_fmtp_decode, + tmedia_codec_dh264_sdp_att_match, + tmedia_codec_dh264_sdp_att_get }; const tmedia_codec_plugin_def_t *tmedia_codec_dh264_plugin_def_t = &tmedia_codec_dh264_plugin_def_s; diff --git a/tinyMEDIA/src/tmedia_common.c b/tinyMEDIA/src/tmedia_common.c index 1e9faef..86832e1 100755 --- a/tinyMEDIA/src/tmedia_common.c +++ b/tinyMEDIA/src/tmedia_common.c @@ -2,19 +2,19 @@ * Copyright (C) 2010-2011 Mamadou Diop. * * Contact: Mamadou Diop <diopmamadou(at)doubango[dot]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. * @@ -43,400 +43,412 @@ #include <stdlib.h> /* atoi() */ -typedef struct fmtp_size_s{ - const char* name; - tmedia_pref_video_size_t pref_vs; - tsk_bool_t cif_family; - unsigned width; - unsigned height; -}fmtp_size_t; -static const fmtp_size_t fmtp_sizes[] = -{ - /* must be sorted like this */ - {"2160P", tmedia_pref_video_size_2160p, tsk_false, 3840, 2160}, - {"1080P", tmedia_pref_video_size_1080p, tsk_false, 1920, 1080}, - {"16CIF", tmedia_pref_video_size_16cif, tsk_true, 1408, 1152}, - {"720P", tmedia_pref_video_size_720p, tsk_false, 1280, 720}, - {"XGA", tmedia_pref_video_size_xga, tsk_false, 1024, 768}, - {"480P", tmedia_pref_video_size_480p, tsk_false, 852, 480}, - {"WVGA", tmedia_pref_video_size_wvga, tsk_false, 800, 480}, - {"SVGA", tmedia_pref_video_size_svga, tsk_false, 800, 600}, - {"4CIF", tmedia_pref_video_size_4cif, tsk_true, 704, 576}, - {"VGA", tmedia_pref_video_size_vga, tsk_false, 640, 480}, - {"HVGA", tmedia_pref_video_size_hvga, tsk_false, 480, 320}, - {"CIF", tmedia_pref_video_size_cif, tsk_true, 352, 288}, - {"QVGA", tmedia_pref_video_size_qvga, tsk_false, 320, 240}, - {"QCIF", tmedia_pref_video_size_qcif, tsk_true, 176, 144}, - {"SQCIF", tmedia_pref_video_size_sqcif, tsk_true, 128, 96} +typedef struct fmtp_size_s { + const char* name; + tmedia_pref_video_size_t pref_vs; + tsk_bool_t cif_family; + unsigned width; + unsigned height; +} fmtp_size_t; +static const fmtp_size_t fmtp_sizes[] = { + /* must be sorted like this */ + {"2160P", tmedia_pref_video_size_2160p, tsk_false, 3840, 2160}, + {"1080P", tmedia_pref_video_size_1080p, tsk_false, 1920, 1080}, + {"16CIF", tmedia_pref_video_size_16cif, tsk_true, 1408, 1152}, + {"720P", tmedia_pref_video_size_720p, tsk_false, 1280, 720}, + {"XGA", tmedia_pref_video_size_xga, tsk_false, 1024, 768}, + {"480P", tmedia_pref_video_size_480p, tsk_false, 852, 480}, + {"WVGA", tmedia_pref_video_size_wvga, tsk_false, 800, 480}, + {"SVGA", tmedia_pref_video_size_svga, tsk_false, 800, 600}, + {"4CIF", tmedia_pref_video_size_4cif, tsk_true, 704, 576}, + {"VGA", tmedia_pref_video_size_vga, tsk_false, 640, 480}, + {"HVGA", tmedia_pref_video_size_hvga, tsk_false, 480, 320}, + {"CIF", tmedia_pref_video_size_cif, tsk_true, 352, 288}, + {"QVGA", tmedia_pref_video_size_qvga, tsk_false, 320, 240}, + {"QCIF", tmedia_pref_video_size_qcif, tsk_true, 176, 144}, + {"SQCIF", tmedia_pref_video_size_sqcif, tsk_true, 128, 96} }; typedef int (*plugin_register)(const void* plugin_def); typedef int (*plugin_unregister)(const void* plugin_def); -typedef struct plugin_decl_s -{ - tsk_plugin_def_type_t type; - plugin_register fn_register; - plugin_unregister fn_unregister; +typedef struct plugin_decl_s { + tsk_plugin_def_type_t type; + plugin_register fn_register; + plugin_unregister fn_unregister; } plugin_decl_t; -static const struct plugin_decl_s __plugin_def_types[] = -{ - {tsk_plugin_def_type_consumer, tmedia_consumer_plugin_register, tmedia_consumer_plugin_unregister }, - {tsk_plugin_def_type_producer, tmedia_producer_plugin_register, tmedia_producer_plugin_unregister }, - {tsk_plugin_def_type_session, tmedia_session_plugin_register, tmedia_session_plugin_unregister }, - {tsk_plugin_def_type_codec, tmedia_codec_plugin_register, tmedia_codec_plugin_unregister }, - {tsk_plugin_def_type_converter, tmedia_converter_video_plugin_register, tmedia_converter_video_plugin_unregister }, - {tsk_plugin_def_type_resampler, tmedia_resampler_plugin_register, tmedia_resampler_plugin_unregister }, - {tsk_plugin_def_type_denoiser, tmedia_denoise_plugin_register, tmedia_denoise_plugin_unregister }, +static const struct plugin_decl_s __plugin_def_types[] = { + {tsk_plugin_def_type_consumer, tmedia_consumer_plugin_register, tmedia_consumer_plugin_unregister }, + {tsk_plugin_def_type_producer, tmedia_producer_plugin_register, tmedia_producer_plugin_unregister }, + {tsk_plugin_def_type_session, tmedia_session_plugin_register, tmedia_session_plugin_unregister }, + {tsk_plugin_def_type_codec, tmedia_codec_plugin_register, tmedia_codec_plugin_unregister }, + {tsk_plugin_def_type_converter, tmedia_converter_video_plugin_register, tmedia_converter_video_plugin_unregister }, + {tsk_plugin_def_type_resampler, tmedia_resampler_plugin_register, tmedia_resampler_plugin_unregister }, + {tsk_plugin_def_type_denoiser, tmedia_denoise_plugin_register, tmedia_denoise_plugin_unregister }, }; static const tsk_size_t __plugin_def_types_count = sizeof(__plugin_def_types)/sizeof(__plugin_def_types[0]); -static const tsk_plugin_def_media_type_t __plugin_def_media_types[] = -{ - tsk_plugin_def_media_type_audio, - tsk_plugin_def_media_type_video, - tsk_plugin_def_media_type_screencast +static const tsk_plugin_def_media_type_t __plugin_def_media_types[] = { + tsk_plugin_def_media_type_audio, + tsk_plugin_def_media_type_video, + tsk_plugin_def_media_type_screencast }; static const tsk_size_t __plugin_def_media_types_count = sizeof(__plugin_def_media_types)/sizeof(__plugin_def_media_types[0]); static tsk_size_t _tmedia_plugin_register_or_unregister(struct tsk_plugin_s* plugin, enum tsk_plugin_def_type_e type, enum tsk_plugin_def_media_type_e media, tsk_bool_t _register) { - tsk_size_t ret = 0, i, j, index; - tsk_plugin_def_ptr_const_t plugin_def_ptr_const; - if(!plugin){ - TSK_DEBUG_ERROR("Invalid parameter"); - return 0; - } - - for(i = 0; i < __plugin_def_types_count; ++i){ - for(j = 0; j < __plugin_def_media_types_count; ++j){ - if((_register ? __plugin_def_types[i].fn_register : __plugin_def_types[i].fn_unregister) && (type & __plugin_def_types[i].type) == __plugin_def_types[i].type && (media & __plugin_def_media_types[j]) == __plugin_def_media_types[j]){ - for(index = 0; (plugin_def_ptr_const = tsk_plugin_get_def_2(plugin, __plugin_def_types[i].type, __plugin_def_media_types[j], index)); ++index){ - if((_register ? __plugin_def_types[i].fn_register : __plugin_def_types[i].fn_unregister)(plugin_def_ptr_const) == 0){ - ++ret; - } - } - } - } - } - - return ret; + tsk_size_t ret = 0, i, j, index; + tsk_plugin_def_ptr_const_t plugin_def_ptr_const; + if(!plugin) { + TSK_DEBUG_ERROR("Invalid parameter"); + return 0; + } + + for(i = 0; i < __plugin_def_types_count; ++i) { + for(j = 0; j < __plugin_def_media_types_count; ++j) { + if((_register ? __plugin_def_types[i].fn_register : __plugin_def_types[i].fn_unregister) && (type & __plugin_def_types[i].type) == __plugin_def_types[i].type && (media & __plugin_def_media_types[j]) == __plugin_def_media_types[j]) { + for(index = 0; (plugin_def_ptr_const = tsk_plugin_get_def_2(plugin, __plugin_def_types[i].type, __plugin_def_media_types[j], index)); ++index) { + if((_register ? __plugin_def_types[i].fn_register : __plugin_def_types[i].fn_unregister)(plugin_def_ptr_const) == 0) { + ++ret; + } + } + } + } + } + + return ret; } tsk_size_t tmedia_plugin_register(struct tsk_plugin_s* plugin, enum tsk_plugin_def_type_e type, enum tsk_plugin_def_media_type_e media) { - return _tmedia_plugin_register_or_unregister(plugin, type, media, tsk_true); + return _tmedia_plugin_register_or_unregister(plugin, type, media, tsk_true); } tsk_size_t tmedia_plugin_unregister(struct tsk_plugin_s* plugin, enum tsk_plugin_def_type_e type, enum tsk_plugin_def_media_type_e media) { - return _tmedia_plugin_register_or_unregister(plugin, type, media, tsk_false); + return _tmedia_plugin_register_or_unregister(plugin, type, media, tsk_false); } 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; - - 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++))) { - type |= tmedia_type_from_sdp_headerM(M); - } - return type; + tmedia_type_t type = tmedia_none; + const tsdp_header_M_t* M; + tsk_size_t index = 0; + + 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++))) { + type |= tmedia_type_from_sdp_headerM(M); + } + return type; } tmedia_type_t tmedia_type_from_sdp_headerM(const tsdp_header_M_t* M) { - const tmedia_session_plugin_def_t* plugin; - const tsdp_header_A_t* A; - if (!M) { - TSK_DEBUG_ERROR("Invalid parameter"); - return tmedia_none; - } - if (M->port && (plugin = tmedia_session_plugin_find_by_media(M->media))) { - if (plugin->type == tmedia_audio || plugin->type == tmedia_video) { - // check if it's BFCP audio/video session - // content attribute described in http://tools.ietf.org/html/rfc4796 - if ((A = tsdp_header_M_findA(M, "content")) && (!tsk_striequals(A->value, "main"))) { - return plugin->type == tmedia_audio ? tmedia_bfcp_audio : tmedia_bfcp_video; - } - } - return plugin->type; - } - return tmedia_none; + const tmedia_session_plugin_def_t* plugin; + const tsdp_header_A_t* A; + if (!M) { + TSK_DEBUG_ERROR("Invalid parameter"); + return tmedia_none; + } + if (M->port && (plugin = tmedia_session_plugin_find_by_media(M->media))) { + if (plugin->type == tmedia_audio || plugin->type == tmedia_video) { + // check if it's BFCP audio/video session + // content attribute described in http://tools.ietf.org/html/rfc4796 + if ((A = tsdp_header_M_findA(M, "content")) && (!tsk_striequals(A->value, "main"))) { + return plugin->type == tmedia_audio ? tmedia_bfcp_audio : tmedia_bfcp_video; + } + } + return plugin->type; + } + return tmedia_none; } int tmedia_parse_rtpmap(const char* rtpmap, char** name, int32_t* rate, int32_t* channels) { - /* e.g. AMR-WB/16000/2 */ - - int len; - int index, pos = 0; - - if(tsk_strnullORempty(rtpmap)){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - - *name = tsk_null; - *rate = *channels = 0; - len = (int)tsk_strlen(rtpmap); - - /* name */ - if((index = tsk_strindexOf(rtpmap, len, "/")) != -1){ - *name = tsk_strndup(rtpmap, index); - len -= (index + 1), pos = (index + 1); - /* rate */ - if(len>0){ - if((index = tsk_strindexOf((rtpmap + pos), len, "/")) != -1){ - *rate = atoi(&rtpmap[pos]); - len -= (index + 1), pos += (index + 1); - /* channels */ - if(len>0){ - *channels = atoi(&rtpmap[pos]); - } - } - else{ - *rate = atoi(&rtpmap[pos]); - } - } - } - else{ - *name = tsk_strdup(rtpmap); - } - - return 0; - - ///* e.g. AMR-WB/16000/2 */ - //if(sscanf(rtpmap, "%*s/%*d/%*d") != EOF){ - // int index = tsk_strindexOf(rtpmap, len, "/"); - // *name = tsk_strndup(rtpmap, index); - // sscanf(&rtpmap[index+1], "%d/%d", rate, channels); - // return 0; - //} - ///* e.g. AMR-WB/16000 */ - //else if(sscanf(rtpmap, "%*s/%*d") != EOF){ - // int index = tsk_strindexOf(rtpmap, len, "/"); - // *name = tsk_strndup(rtpmap, index); - // *rate = atoi(&rtpmap[index+1]); - // return 0; - //} - ///* e.g. AMR-WB */ - //else if(sscanf(rtpmap, "%*s") != EOF){ - // *name = tsk_strdup(rtpmap); - // return 0; - //} - //else{ - // TSK_DEBUG_ERROR("%s is not a valid rtpmap value", rtpmap); - // return -2; - //} + /* e.g. AMR-WB/16000/2 */ + + int len; + int index, pos = 0; + + if(tsk_strnullORempty(rtpmap)) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + + *name = tsk_null; + *rate = *channels = 0; + len = (int)tsk_strlen(rtpmap); + + /* name */ + if((index = tsk_strindexOf(rtpmap, len, "/")) != -1) { + *name = tsk_strndup(rtpmap, index); + len -= (index + 1), pos = (index + 1); + /* rate */ + if(len>0) { + if((index = tsk_strindexOf((rtpmap + pos), len, "/")) != -1) { + *rate = atoi(&rtpmap[pos]); + len -= (index + 1), pos += (index + 1); + /* channels */ + if(len>0) { + *channels = atoi(&rtpmap[pos]); + } + } + else { + *rate = atoi(&rtpmap[pos]); + } + } + } + else { + *name = tsk_strdup(rtpmap); + } + + return 0; + + ///* e.g. AMR-WB/16000/2 */ + //if(sscanf(rtpmap, "%*s/%*d/%*d") != EOF){ + // int index = tsk_strindexOf(rtpmap, len, "/"); + // *name = tsk_strndup(rtpmap, index); + // sscanf(&rtpmap[index+1], "%d/%d", rate, channels); + // return 0; + //} + ///* e.g. AMR-WB/16000 */ + //else if(sscanf(rtpmap, "%*s/%*d") != EOF){ + // int index = tsk_strindexOf(rtpmap, len, "/"); + // *name = tsk_strndup(rtpmap, index); + // *rate = atoi(&rtpmap[index+1]); + // return 0; + //} + ///* e.g. AMR-WB */ + //else if(sscanf(rtpmap, "%*s") != EOF){ + // *name = tsk_strdup(rtpmap); + // return 0; + //} + //else{ + // TSK_DEBUG_ERROR("%s is not a valid rtpmap value", rtpmap); + // return -2; + //} } int tmedia_video_get_size(tmedia_pref_video_size_t pref_vs, unsigned *width, unsigned *height) { - int i; - for(i=0; i<sizeof(fmtp_sizes)/sizeof(fmtp_sizes[0]); i++){ - if(fmtp_sizes[i].pref_vs == pref_vs){ - if(width) *width = fmtp_sizes[i].width; - if(height) *height = fmtp_sizes[i].height; - return 0; - } - } - return -1; + int i; + for(i=0; i<sizeof(fmtp_sizes)/sizeof(fmtp_sizes[0]); i++) { + if(fmtp_sizes[i].pref_vs == pref_vs) { + if(width) { + *width = fmtp_sizes[i].width; + } + if(height) { + *height = fmtp_sizes[i].height; + } + return 0; + } + } + return -1; } int tmedia_video_get_closest_cif_size(tmedia_pref_video_size_t pref_vs, tmedia_pref_video_size_t *cif_vs) { - int i; - if(!cif_vs){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - for(i=0; i<sizeof(fmtp_sizes)/sizeof(fmtp_sizes[0]); i++){ - if(fmtp_sizes[i].pref_vs <= pref_vs && fmtp_sizes[i].cif_family){ - *cif_vs = fmtp_sizes[i].pref_vs; - return 0; - } - } - return -2; + int i; + if(!cif_vs) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + for(i=0; i<sizeof(fmtp_sizes)/sizeof(fmtp_sizes[0]); i++) { + if(fmtp_sizes[i].pref_vs <= pref_vs && fmtp_sizes[i].cif_family) { + *cif_vs = fmtp_sizes[i].pref_vs; + return 0; + } + } + return -2; } int tmedia_video_get_closest_pref_size(unsigned width, unsigned height, tmedia_pref_video_size_t *pref_vs) { - int i; - unsigned size; - if (!pref_vs){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - size = width * height; - for (i = 0; i<sizeof(fmtp_sizes) / sizeof(fmtp_sizes[0]); i++){ - if (size >= fmtp_sizes[i].height * fmtp_sizes[i].width){ - *pref_vs = fmtp_sizes[i].pref_vs; - return 0; - } - } - return -2; + int i; + unsigned size; + if (!pref_vs) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + size = width * height; + for (i = 0; i<sizeof(fmtp_sizes) / sizeof(fmtp_sizes[0]); i++) { + if (size >= fmtp_sizes[i].height * fmtp_sizes[i].width) { + *pref_vs = fmtp_sizes[i].pref_vs; + return 0; + } + } + return -2; } int tmedia_parse_video_fmtp(const char* fmtp, tmedia_pref_video_size_t pref_vs, unsigned* width, unsigned* height, unsigned* fps) { - int ret = -2; - tsk_params_L_t* params = tsk_null; - const tsk_param_t* param = tsk_null; - const tsk_list_item_t* item; - int i; - tmedia_pref_video_size_t best_vs; - - if(!fmtp || !width || !height || !fps){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - - // set default values - best_vs = fmtp_sizes[(sizeof(fmtp_sizes)/sizeof(fmtp_sizes[0])) - 1].pref_vs /* last = lowest resolution */; - ret = tmedia_video_get_size(pref_vs, width, height); - *fps = 15; - - if((params = tsk_params_fromstring(fmtp, ";", tsk_true))){ - // set real values - tsk_list_foreach(item, params){ - if(!(param = TSK_PARAM(item->data)) || !param->name || !param->value){ - continue; - } - for(i=0; i<sizeof(fmtp_sizes)/sizeof(fmtp_sizes[0]); i++){ - if((int)pref_vs >= (int)fmtp_sizes[i].pref_vs && tsk_striequals(fmtp_sizes[i].name, param->name) && ((int)best_vs <= (int)fmtp_sizes[i].pref_vs)){ - *width= fmtp_sizes[i].width; - *height = fmtp_sizes[i].height; - *fps = atoi(param->value); - *fps = *fps ? 30/(*fps) : 15; - ret = 0; - best_vs = fmtp_sizes[i].pref_vs; - // rfc 4629 section 8.2.1: Parameters offered first are the most preferred picture mode to be received. - // /!\ asterisk do not respect this :) - /* goto done */; - } - } - } -/* done: */ - TSK_OBJECT_SAFE_FREE(params); - } - - return ret; + int ret = -2; + tsk_params_L_t* params = tsk_null; + const tsk_param_t* param = tsk_null; + const tsk_list_item_t* item; + int i; + tmedia_pref_video_size_t best_vs; + + if(!fmtp || !width || !height || !fps) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + + // set default values + best_vs = fmtp_sizes[(sizeof(fmtp_sizes)/sizeof(fmtp_sizes[0])) - 1].pref_vs /* last = lowest resolution */; + ret = tmedia_video_get_size(pref_vs, width, height); + *fps = 15; + + if((params = tsk_params_fromstring(fmtp, ";", tsk_true))) { + // set real values + tsk_list_foreach(item, params) { + if(!(param = TSK_PARAM(item->data)) || !param->name || !param->value) { + continue; + } + for(i=0; i<sizeof(fmtp_sizes)/sizeof(fmtp_sizes[0]); i++) { + if((int)pref_vs >= (int)fmtp_sizes[i].pref_vs && tsk_striequals(fmtp_sizes[i].name, param->name) && ((int)best_vs <= (int)fmtp_sizes[i].pref_vs)) { + *width= fmtp_sizes[i].width; + *height = fmtp_sizes[i].height; + *fps = atoi(param->value); + *fps = *fps ? 30/(*fps) : 15; + ret = 0; + best_vs = fmtp_sizes[i].pref_vs; + // rfc 4629 section 8.2.1: Parameters offered first are the most preferred picture mode to be received. + // /!\ asterisk do not respect this :) + /* goto done */; + } + } + } + /* done: */ + TSK_OBJECT_SAFE_FREE(params); + } + + return ret; } static void _imageattr_get_best_size(const tmedia_imageattr_set_xt* set, xyvalue_t *width, xyvalue_t *height) { - tsk_size_t i; - if(set->xrange.is_range){ - *width = TSK_MIN(set->xrange.range.end, *width); - } - else{ - for(i = 0; i < set->xrange.array.count; ++i){ - *width = TSK_MIN(set->xrange.array.values[i], *width); - } - } - if(set->yrange.is_range){ - *height = TSK_MIN(set->yrange.range.end, *height); - } - else{ - for(i = 0; i < set->yrange.array.count; ++i){ - *height = TSK_MIN(set->yrange.array.values[i], *height); - } - } + tsk_size_t i; + if(set->xrange.is_range) { + *width = TSK_MIN(set->xrange.range.end, *width); + } + else { + for(i = 0; i < set->xrange.array.count; ++i) { + *width = TSK_MIN(set->xrange.array.values[i], *width); + } + } + if(set->yrange.is_range) { + *height = TSK_MIN(set->yrange.range.end, *height); + } + else { + for(i = 0; i < set->yrange.array.count; ++i) { + *height = TSK_MIN(set->yrange.array.values[i], *height); + } + } } int tmedia_parse_video_imageattr(const char* imageattr, tmedia_pref_video_size_t pref_vs, unsigned* in_width, unsigned* in_height, unsigned* out_width, unsigned* out_height) { - tmedia_imageattr_xt attr; - int ret; - tsk_size_t i; - - if(!imageattr || !in_width || !in_height || !out_width || !out_height){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - // set default values - ret = tmedia_video_get_size(pref_vs, in_width, in_height); - if(ret != 0){ - TSK_DEBUG_ERROR("tmedia_video_get_size() failed with error code=%d", ret); - return ret; - } - *out_width = *in_width, *out_height = *in_height; - - if((ret = tmedia_imageattr_parse(&attr, imageattr, (tsk_size_t)tsk_strlen(imageattr)))){ - TSK_DEBUG_ERROR("Failed to parse"); - return 0; // use default values - } - - - for(i = 0; i < attr.send.count; ++i) _imageattr_get_best_size(&attr.send.sets[i], (xyvalue_t*)out_width, (xyvalue_t*)out_height); - for(i = 0; i < attr.recv.count; ++i) _imageattr_get_best_size(&attr.recv.sets[i], (xyvalue_t*)in_width, (xyvalue_t*)in_height); - - return 0; + tmedia_imageattr_xt attr; + int ret; + tsk_size_t i; + + if(!imageattr || !in_width || !in_height || !out_width || !out_height) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + // set default values + ret = tmedia_video_get_size(pref_vs, in_width, in_height); + if(ret != 0) { + TSK_DEBUG_ERROR("tmedia_video_get_size() failed with error code=%d", ret); + return ret; + } + *out_width = *in_width, *out_height = *in_height; + + if((ret = tmedia_imageattr_parse(&attr, imageattr, (tsk_size_t)tsk_strlen(imageattr)))) { + TSK_DEBUG_ERROR("Failed to parse"); + return 0; // use default values + } + + + for(i = 0; i < attr.send.count; ++i) { + _imageattr_get_best_size(&attr.send.sets[i], (xyvalue_t*)out_width, (xyvalue_t*)out_height); + } + for(i = 0; i < attr.recv.count; ++i) { + _imageattr_get_best_size(&attr.recv.sets[i], (xyvalue_t*)in_width, (xyvalue_t*)in_height); + } + + return 0; } char* tmedia_get_video_fmtp(tmedia_pref_video_size_t pref_vs) { - tsk_size_t i; - char* fmtp = tsk_null; - - - for(i = 0; i < sizeof(fmtp_sizes)/sizeof(fmtp_sizes[0]); ++i){ - if(fmtp_sizes[i].cif_family && fmtp_sizes[i].pref_vs <= pref_vs){ - if(!fmtp) tsk_strcat_2(&fmtp, "%s=2", fmtp_sizes[i].name); - else tsk_strcat_2(&fmtp, ";%s=2", fmtp_sizes[i].name); - } - } - return fmtp; + tsk_size_t i; + char* fmtp = tsk_null; + + + for(i = 0; i < sizeof(fmtp_sizes)/sizeof(fmtp_sizes[0]); ++i) { + if(fmtp_sizes[i].cif_family && fmtp_sizes[i].pref_vs <= pref_vs) { + if(!fmtp) { + tsk_strcat_2(&fmtp, "%s=2", fmtp_sizes[i].name); + } + else { + tsk_strcat_2(&fmtp, ";%s=2", fmtp_sizes[i].name); + } + } + } + return fmtp; } char* tmedia_get_video_imageattr(tmedia_pref_video_size_t pref_vs, unsigned in_width, unsigned in_height, unsigned out_width, unsigned out_height) { - unsigned width, height; - const fmtp_size_t* size_min = &fmtp_sizes[(sizeof(fmtp_sizes) / sizeof(fmtp_sizes[0]))-1]; - char* ret = tsk_null; - if(tmedia_video_get_size(pref_vs, &width, &height) == 0){ - tsk_sprintf(&ret, "recv [x=[%u:16:%u],y=[%u:16:%u]] send [x=[%u:16:%u],y=[%u:16:%u]]", - size_min->width, in_width, size_min->height, in_height, - size_min->width, out_width, size_min->height, out_height); - } - return ret; + unsigned width, height; + const fmtp_size_t* size_min = &fmtp_sizes[(sizeof(fmtp_sizes) / sizeof(fmtp_sizes[0]))-1]; + char* ret = tsk_null; + if(tmedia_video_get_size(pref_vs, &width, &height) == 0) { + tsk_sprintf(&ret, "recv [x=[%u:16:%u],y=[%u:16:%u]] send [x=[%u:16:%u],y=[%u:16:%u]]", + size_min->width, in_width, size_min->height, in_height, + size_min->width, out_width, size_min->height, out_height); + } + return ret; } // #retval: 1(best)-31(worst) */ int tmedia_get_video_quality(tmedia_bandwidth_level_t bl) { - switch(bl){ - case tmedia_bl_low: - default: return 13; - case tmedia_bl_medium: return 9; - case tmedia_bl_hight: return 5; - case tmedia_bl_unrestricted: return 1; - } + switch(bl) { + case tmedia_bl_low: + default: + return 13; + case tmedia_bl_medium: + return 9; + case tmedia_bl_hight: + return 5; + case tmedia_bl_unrestricted: + return 1; + } } int32_t tmedia_get_video_bandwidth_kbps(unsigned width, unsigned height, unsigned fps, unsigned motion_rank) { - return (int32_t)((width * height * fps * motion_rank * 0.07) / 1024); + return (int32_t)((width * height * fps * motion_rank * 0.07) / 1024); } int32_t tmedia_get_video_bandwidth_kbps_2(unsigned width, unsigned height, unsigned fps) { - return tmedia_get_video_bandwidth_kbps(width, height, fps, tmedia_defaults_get_video_motion_rank()); + return tmedia_get_video_bandwidth_kbps(width, height, fps, tmedia_defaults_get_video_motion_rank()); } int32_t tmedia_get_video_bandwidth_kbps_3() { - unsigned width = 3840; - unsigned height = 2160; - tmedia_video_get_size(tmedia_defaults_get_pref_video_size(), &width, &height); - return tmedia_get_video_bandwidth_kbps(width, height, tmedia_defaults_get_video_fps(), tmedia_defaults_get_video_motion_rank()); + unsigned width = 3840; + unsigned height = 2160; + tmedia_video_get_size(tmedia_defaults_get_pref_video_size(), &width, &height); + return tmedia_get_video_bandwidth_kbps(width, height, tmedia_defaults_get_video_fps(), tmedia_defaults_get_video_motion_rank()); }
\ No newline at end of file diff --git a/tinyMEDIA/src/tmedia_consumer.c b/tinyMEDIA/src/tmedia_consumer.c index 215a959..96f42be 100755 --- a/tinyMEDIA/src/tmedia_consumer.c +++ b/tinyMEDIA/src/tmedia_consumer.c @@ -1,18 +1,18 @@ /* * Copyright (C) 2010-2014 Mamadou DIOP -* +* * 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. * @@ -42,19 +42,19 @@ static const tmedia_consumer_plugin_def_t* __tmedia_consumer_plugins[TMED_CONSUM */ int tmedia_consumer_init(tmedia_consumer_t* self) { - if(!self){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } + if(!self) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } - self->video.in.chroma = TMEDIA_CONSUMER_CHROMA_DEFAULT; - self->video.display.chroma = TMEDIA_CONSUMER_CHROMA_DEFAULT; + self->video.in.chroma = TMEDIA_CONSUMER_CHROMA_DEFAULT; + self->video.display.chroma = TMEDIA_CONSUMER_CHROMA_DEFAULT; - self->audio.bits_per_sample = TMEDIA_CONSUMER_BITS_PER_SAMPLE_DEFAULT; - self->audio.ptime = tmedia_defaults_get_audio_ptime(); - self->audio.volume = tmedia_defaults_get_volume(); + self->audio.bits_per_sample = TMEDIA_CONSUMER_BITS_PER_SAMPLE_DEFAULT; + self->audio.ptime = tmedia_defaults_get_audio_ptime(); + self->audio.volume = tmedia_defaults_get_volume(); - return 0; + return 0; } /**@ingroup tmedia_consumer_group @@ -62,11 +62,11 @@ int tmedia_consumer_init(tmedia_consumer_t* self) */ int tmedia_consumer_set(tmedia_consumer_t *self, const tmedia_param_t* param) { - if(!self || !self->plugin || !self->plugin->set || !param){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - return self->plugin->set(self, param); + if(!self || !self->plugin || !self->plugin->set || !param) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + return self->plugin->set(self, param); } /**@ingroup tmedia_consumer_group @@ -77,15 +77,15 @@ int tmedia_consumer_set(tmedia_consumer_t *self, const tmedia_param_t* param) */ int tmedia_consumer_prepare(tmedia_consumer_t *self, const tmedia_codec_t* codec) { - int ret; - if(!self || !self->plugin || !self->plugin->prepare || !codec){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - if((ret = self->plugin->prepare(self, codec)) == 0){ - self->is_prepared = tsk_true; - } - return ret; + int ret; + if(!self || !self->plugin || !self->plugin->prepare || !codec) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + if((ret = self->plugin->prepare(self, codec)) == 0) { + self->is_prepared = tsk_true; + } + return ret; } /**@ingroup tmedia_consumer_group @@ -95,15 +95,15 @@ int tmedia_consumer_prepare(tmedia_consumer_t *self, const tmedia_codec_t* codec */ int tmedia_consumer_start(tmedia_consumer_t *self) { - int ret; - if (!self || !self->plugin || !self->plugin->start) { - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - if ((ret = self->plugin->start(self)) == 0) { - self->is_started = tsk_true; - } - return ret; + int ret; + if (!self || !self->plugin || !self->plugin->start) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + if ((ret = self->plugin->start(self)) == 0) { + self->is_started = tsk_true; + } + return ret; } /**@ingroup tmedia_consumer_group @@ -114,11 +114,11 @@ int tmedia_consumer_start(tmedia_consumer_t *self) */ int tmedia_consumer_consume(tmedia_consumer_t* self, const void* buffer, tsk_size_t size, const tsk_object_t* proto_hdr) { - if(!self || !self->plugin || !self->plugin->consume){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - return self->plugin->consume(self, buffer, size, proto_hdr); + if(!self || !self->plugin || !self->plugin->consume) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + return self->plugin->consume(self, buffer, size, proto_hdr); } /**@ingroup tmedia_consumer_group @@ -128,11 +128,11 @@ int tmedia_consumer_consume(tmedia_consumer_t* self, const void* buffer, tsk_siz */ int tmedia_consumer_pause(tmedia_consumer_t *self) { - if(!self || !self->plugin || !self->plugin->pause){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - return self->plugin->pause(self); + if(!self || !self->plugin || !self->plugin->pause) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + return self->plugin->pause(self); } @@ -143,15 +143,15 @@ int tmedia_consumer_pause(tmedia_consumer_t *self) */ int tmedia_consumer_stop(tmedia_consumer_t *self) { - int ret; - if (!self || !self->plugin || !self->plugin->stop) { - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - if ((ret = self->plugin->stop(self)) == 0) { - self->is_started = tsk_false; - } - return ret; + int ret; + if (!self || !self->plugin || !self->plugin->stop) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + if ((ret = self->plugin->stop(self)) == 0) { + self->is_started = tsk_false; + } + return ret; } @@ -164,11 +164,11 @@ int tmedia_consumer_stop(tmedia_consumer_t *self) */ int tmedia_consumer_deinit(tmedia_consumer_t* self) { - if(!self){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - return 0; + if(!self) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + return 0; } /**@ingroup tmedia_consumer_group @@ -179,22 +179,22 @@ int tmedia_consumer_deinit(tmedia_consumer_t* self) */ tmedia_consumer_t* tmedia_consumer_create(tmedia_type_t type, uint64_t session_id) { - tmedia_consumer_t* consumer = tsk_null; - const tmedia_consumer_plugin_def_t* plugin; - tsk_size_t i = 0; + tmedia_consumer_t* consumer = tsk_null; + const tmedia_consumer_plugin_def_t* plugin; + tsk_size_t i = 0; - while((i < TMED_CONSUMER_MAX_PLUGINS) && (plugin = __tmedia_consumer_plugins[i++])){ - if(plugin->objdef && plugin->type == type){ - if((consumer = tsk_object_new(plugin->objdef))){ - /* initialize the newly created consumer */ - consumer->plugin = plugin; - consumer->session_id = session_id; - break; - } - } - } + while((i < TMED_CONSUMER_MAX_PLUGINS) && (plugin = __tmedia_consumer_plugins[i++])) { + if(plugin->objdef && plugin->type == type) { + if((consumer = tsk_object_new(plugin->objdef))) { + /* initialize the newly created consumer */ + consumer->plugin = plugin; + consumer->session_id = session_id; + break; + } + } + } - return consumer; + return consumer; } /**@ingroup tmedia_consumer_group @@ -205,22 +205,22 @@ tmedia_consumer_t* tmedia_consumer_create(tmedia_type_t type, uint64_t session_i */ int tmedia_consumer_plugin_register(const tmedia_consumer_plugin_def_t* plugin) { - tsk_size_t i; - if(!plugin){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } + tsk_size_t i; + if(!plugin) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } - /* add or replace the plugin */ - for(i = 0; i<TMED_CONSUMER_MAX_PLUGINS; i++){ - if(!__tmedia_consumer_plugins[i] || (__tmedia_consumer_plugins[i] == plugin)){ - __tmedia_consumer_plugins[i] = plugin; - return 0; - } - } - - TSK_DEBUG_ERROR("There are already %d plugins.", TMED_CONSUMER_MAX_PLUGINS); - return -2; + /* add or replace the plugin */ + for(i = 0; i<TMED_CONSUMER_MAX_PLUGINS; i++) { + if(!__tmedia_consumer_plugins[i] || (__tmedia_consumer_plugins[i] == plugin)) { + __tmedia_consumer_plugins[i] = plugin; + return 0; + } + } + + TSK_DEBUG_ERROR("There are already %d plugins.", TMED_CONSUMER_MAX_PLUGINS); + return -2; } /**@ingroup tmedia_consumer_group @@ -230,35 +230,35 @@ int tmedia_consumer_plugin_register(const tmedia_consumer_plugin_def_t* plugin) */ int tmedia_consumer_plugin_unregister(const tmedia_consumer_plugin_def_t* plugin) { - tsk_size_t i; - tsk_bool_t found = tsk_false; - if(!plugin){ - TSK_DEBUG_ERROR("Invalid Parameter"); - return -1; - } + tsk_size_t i; + tsk_bool_t found = tsk_false; + if(!plugin) { + TSK_DEBUG_ERROR("Invalid Parameter"); + return -1; + } - /* find the plugin to unregister */ - for(i = 0; i<TMED_CONSUMER_MAX_PLUGINS && __tmedia_consumer_plugins[i]; i++){ - if(__tmedia_consumer_plugins[i] == plugin){ - __tmedia_consumer_plugins[i] = tsk_null; - found = tsk_true; - break; - } - } + /* find the plugin to unregister */ + for(i = 0; i<TMED_CONSUMER_MAX_PLUGINS && __tmedia_consumer_plugins[i]; i++) { + if(__tmedia_consumer_plugins[i] == plugin) { + __tmedia_consumer_plugins[i] = tsk_null; + found = tsk_true; + break; + } + } - /* compact */ - if(found){ - for(; i<(TMED_CONSUMER_MAX_PLUGINS - 1); i++){ - if(__tmedia_consumer_plugins[i+1]){ - __tmedia_consumer_plugins[i] = __tmedia_consumer_plugins[i+1]; - } - else{ - break; - } - } - __tmedia_consumer_plugins[i] = tsk_null; - } - return (found ? 0 : -2); + /* compact */ + if(found) { + for(; i<(TMED_CONSUMER_MAX_PLUGINS - 1); i++) { + if(__tmedia_consumer_plugins[i+1]) { + __tmedia_consumer_plugins[i] = __tmedia_consumer_plugins[i+1]; + } + else { + break; + } + } + __tmedia_consumer_plugins[i] = tsk_null; + } + return (found ? 0 : -2); } /**@ingroup tmedia_consumer_group @@ -268,21 +268,21 @@ int tmedia_consumer_plugin_unregister(const tmedia_consumer_plugin_def_t* plugin */ int tmedia_consumer_plugin_unregister_by_type(tmedia_type_t type) { - int i, j; - - /* find the plugin to unregister */ - for (i = 0; i < TMED_CONSUMER_MAX_PLUGINS && __tmedia_consumer_plugins[i]; ) { - if ((__tmedia_consumer_plugins[i]->type & type) == __tmedia_consumer_plugins[i]->type) { - __tmedia_consumer_plugins[i] = tsk_null; - /* compact */ - for (j = i; j < (TMED_CONSUMER_MAX_PLUGINS - 1) && __tmedia_consumer_plugins[j + 1]; ++j) { - __tmedia_consumer_plugins[j] = __tmedia_consumer_plugins[j + 1]; - } - __tmedia_consumer_plugins[j] = tsk_null; - } - else { - ++i; - } - } - return 0; + int i, j; + + /* find the plugin to unregister */ + for (i = 0; i < TMED_CONSUMER_MAX_PLUGINS && __tmedia_consumer_plugins[i]; ) { + if ((__tmedia_consumer_plugins[i]->type & type) == __tmedia_consumer_plugins[i]->type) { + __tmedia_consumer_plugins[i] = tsk_null; + /* compact */ + for (j = i; j < (TMED_CONSUMER_MAX_PLUGINS - 1) && __tmedia_consumer_plugins[j + 1]; ++j) { + __tmedia_consumer_plugins[j] = __tmedia_consumer_plugins[j + 1]; + } + __tmedia_consumer_plugins[j] = tsk_null; + } + else { + ++i; + } + } + return 0; } diff --git a/tinyMEDIA/src/tmedia_converter_video.c b/tinyMEDIA/src/tmedia_converter_video.c index 27cc252..f19830a 100755 --- a/tinyMEDIA/src/tmedia_converter_video.c +++ b/tinyMEDIA/src/tmedia_converter_video.c @@ -2,17 +2,17 @@ * Copyright (C) 2012 Doubango Telecom <http://www.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. * @@ -34,93 +34,93 @@ static const tmedia_converter_video_plugin_def_t* __tmedia_converter_video_plugi tmedia_converter_video_t* tmedia_converter_video_create(tsk_size_t srcWidth, tsk_size_t srcHeight, tmedia_chroma_t srcChroma, tsk_size_t dstWidth, tsk_size_t dstHeight, tmedia_chroma_t dstChroma) { - tmedia_converter_video_t* converter = tsk_null; - const tmedia_converter_video_plugin_def_t* plugin; - tsk_size_t i = 0; + tmedia_converter_video_t* converter = tsk_null; + const tmedia_converter_video_plugin_def_t* plugin; + tsk_size_t i = 0; - while((i < TMED_CONVERTER_VIDEO_MAX_PLUGINS) && (plugin = __tmedia_converter_video_plugins[i++])){ - if(plugin->objdef && (converter = tsk_object_new(plugin->objdef))){ - converter->plugin = plugin; - converter->scale_rotated_frames = tsk_true; - // must not set other values beacause 'zero' is meaningful - if(converter->plugin->init){ - if(converter->plugin->init(converter, srcWidth, srcHeight, srcChroma, dstWidth, dstHeight, dstChroma)){ - TSK_DEBUG_ERROR("Failed to initialized the video converter"); - TSK_OBJECT_SAFE_FREE(converter); - continue; - } - } - converter->srcChroma = srcChroma; - converter->dstChroma = dstChroma; - converter->srcWidth = srcWidth ? srcWidth : dstWidth; - converter->srcHeight = srcHeight ? srcHeight : dstHeight; - converter->dstWidth = dstWidth ? dstWidth : srcWidth; - converter->dstHeight = dstHeight ? dstHeight : srcHeight; - break; - } - } + while((i < TMED_CONVERTER_VIDEO_MAX_PLUGINS) && (plugin = __tmedia_converter_video_plugins[i++])) { + if(plugin->objdef && (converter = tsk_object_new(plugin->objdef))) { + converter->plugin = plugin; + converter->scale_rotated_frames = tsk_true; + // must not set other values beacause 'zero' is meaningful + if(converter->plugin->init) { + if(converter->plugin->init(converter, srcWidth, srcHeight, srcChroma, dstWidth, dstHeight, dstChroma)) { + TSK_DEBUG_ERROR("Failed to initialized the video converter"); + TSK_OBJECT_SAFE_FREE(converter); + continue; + } + } + converter->srcChroma = srcChroma; + converter->dstChroma = dstChroma; + converter->srcWidth = srcWidth ? srcWidth : dstWidth; + converter->srcHeight = srcHeight ? srcHeight : dstHeight; + converter->dstWidth = dstWidth ? dstWidth : srcWidth; + converter->dstHeight = dstHeight ? dstHeight : srcHeight; + break; + } + } - return converter; + return converter; } int tmedia_converter_video_plugin_register(const tmedia_converter_video_plugin_def_t* plugin) { - tsk_size_t i; - if(!plugin){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } + tsk_size_t i; + if(!plugin) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + + /* add or replace the plugin */ + for(i = 0; i<TMED_CONVERTER_VIDEO_MAX_PLUGINS; i++) { + if(!__tmedia_converter_video_plugins[i] || (__tmedia_converter_video_plugins[i] == plugin)) { + __tmedia_converter_video_plugins[i] = plugin; + return 0; + } + } - /* add or replace the plugin */ - for(i = 0; i<TMED_CONVERTER_VIDEO_MAX_PLUGINS; i++){ - if(!__tmedia_converter_video_plugins[i] || (__tmedia_converter_video_plugins[i] == plugin)){ - __tmedia_converter_video_plugins[i] = plugin; - return 0; - } - } - - TSK_DEBUG_ERROR("There are already %d plugins.", TMED_CONVERTER_VIDEO_MAX_PLUGINS); - return -2; + TSK_DEBUG_ERROR("There are already %d plugins.", TMED_CONVERTER_VIDEO_MAX_PLUGINS); + return -2; } tsk_size_t tmedia_converter_video_plugin_registry_count() { - tsk_size_t count; - for(count = 0; - count < TMED_CONVERTER_VIDEO_MAX_PLUGINS && __tmedia_converter_video_plugins[count]; - ++count) ; - return count; + tsk_size_t count; + for(count = 0; + count < TMED_CONVERTER_VIDEO_MAX_PLUGINS && __tmedia_converter_video_plugins[count]; + ++count) ; + return count; } int tmedia_converter_video_plugin_unregister(const tmedia_converter_video_plugin_def_t* plugin) { - tsk_size_t i; - tsk_bool_t found = tsk_false; - if(!plugin){ - TSK_DEBUG_ERROR("Invalid Parameter"); - return -1; - } + tsk_size_t i; + tsk_bool_t found = tsk_false; + if(!plugin) { + TSK_DEBUG_ERROR("Invalid Parameter"); + return -1; + } - /* find the plugin to unregister */ - for(i = 0; i<TMED_CONVERTER_VIDEO_MAX_PLUGINS && __tmedia_converter_video_plugins[i]; i++){ - if(__tmedia_converter_video_plugins[i] == plugin){ - __tmedia_converter_video_plugins[i] = tsk_null; - found = tsk_true; - break; - } - } + /* find the plugin to unregister */ + for(i = 0; i<TMED_CONVERTER_VIDEO_MAX_PLUGINS && __tmedia_converter_video_plugins[i]; i++) { + if(__tmedia_converter_video_plugins[i] == plugin) { + __tmedia_converter_video_plugins[i] = tsk_null; + found = tsk_true; + break; + } + } - /* compact */ - if(found){ - for(; i<(TMED_CONVERTER_VIDEO_MAX_PLUGINS - 1); i++){ - if(__tmedia_converter_video_plugins[i+1]){ - __tmedia_converter_video_plugins[i] = __tmedia_converter_video_plugins[i+1]; - } - else{ - break; - } - } - __tmedia_converter_video_plugins[i] = tsk_null; - } - return (found ? 0 : -2); + /* compact */ + if(found) { + for(; i<(TMED_CONVERTER_VIDEO_MAX_PLUGINS - 1); i++) { + if(__tmedia_converter_video_plugins[i+1]) { + __tmedia_converter_video_plugins[i] = __tmedia_converter_video_plugins[i+1]; + } + else { + break; + } + } + __tmedia_converter_video_plugins[i] = tsk_null; + } + return (found ? 0 : -2); } diff --git a/tinyMEDIA/src/tmedia_defaults.c b/tinyMEDIA/src/tmedia_defaults.c index b24c153..0c33b5b 100755 --- a/tinyMEDIA/src/tmedia_defaults.c +++ b/tinyMEDIA/src/tmedia_defaults.c @@ -2,19 +2,19 @@ * Copyright (C) 2010-2011 Mamadou Diop. * * Contact: Mamadou Diop <diopmamadou(at)doubango[dot]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. * @@ -30,12 +30,15 @@ static tmedia_profile_t __profile = tmedia_profile_default; static tmedia_bandwidth_level_t __bl = tmedia_bl_unrestricted; -static tsk_bool_t __congestion_ctrl_enabled = tsk_false; +static tsk_bool_t __congestion_ctrl_enabled = tsk_true; static int32_t __video_fps = 15; // allowed values: ]0 - 120] static int32_t __video_motion_rank = 2; // allowed values: 1(low), 2(medium) or 4(high) static int32_t __bw_video_up_max_kbps = INT_MAX; // <= 0: unrestricted, Unit: kbps static int32_t __bw_video_down_max_kbps = INT_MAX; // <= 0: unrestricted, Unit: kbps -static tmedia_pref_video_size_t __pref_video_size = tmedia_pref_video_size_cif; // 352 x 288: Android, iOS, WP7 +static tmedia_pref_video_size_t __pref_video_size = tmedia_pref_video_size_cif; // 352 x 288: Android, iOS, WP7 +static tmedia_pref_video_size_t __pref_video_size_range_min = tmedia_pref_video_size_cif; +static tmedia_pref_video_size_t __pref_video_size_range_max = tmedia_pref_video_size_cif; +static tsk_bool_t __pref_video_size_range_enabled = tsk_false; static int32_t __jb_margin_ms = -1; // disable static int32_t __jb_max_late_rate_percent = -1; // -1: disable 4: default for speex static uint32_t __echo_tail = 100; @@ -96,510 +99,692 @@ static unsigned short __webproxy_port = 0; static char* __webproxy_login = tsk_null; static char* __webproxy_password = tsk_null; -int tmedia_defaults_set_profile(tmedia_profile_t profile){ - __profile = profile; - return 0; +int tmedia_defaults_set_profile(tmedia_profile_t profile) +{ + __profile = profile; + return 0; } -tmedia_profile_t tmedia_defaults_get_profile(){ - return __profile; +tmedia_profile_t tmedia_defaults_get_profile() +{ + return __profile; } // @deprecated -int tmedia_defaults_set_bl(tmedia_bandwidth_level_t bl){ - __bl = bl; - return 0; +int tmedia_defaults_set_bl(tmedia_bandwidth_level_t bl) +{ + __bl = bl; + return 0; } // @deprecated -tmedia_bandwidth_level_t tmedia_defaults_get_bl(){ - return __bl; +tmedia_bandwidth_level_t tmedia_defaults_get_bl() +{ + return __bl; } -int tmedia_defaults_set_congestion_ctrl_enabled(tsk_bool_t enabled){ - __congestion_ctrl_enabled = enabled; - return 0; +int tmedia_defaults_set_congestion_ctrl_enabled(tsk_bool_t enabled) +{ + __congestion_ctrl_enabled = enabled; + return 0; } -tsk_bool_t tmedia_defaults_get_congestion_ctrl_enabled(){ - return __congestion_ctrl_enabled; +tsk_bool_t tmedia_defaults_get_congestion_ctrl_enabled() +{ + return __congestion_ctrl_enabled; } -int tmedia_defaults_set_video_fps(int32_t video_fps){ - if(video_fps > 0 && video_fps <= 120){ - __video_fps = video_fps; - return 0; - } - TSK_DEBUG_ERROR("%d not valid for video fps", video_fps); - return -1; +int tmedia_defaults_set_video_fps(int32_t video_fps) +{ + if(video_fps > 0 && video_fps <= 120) { + __video_fps = video_fps; + return 0; + } + TSK_DEBUG_ERROR("%d not valid for video fps", video_fps); + return -1; +} +int32_t tmedia_defaults_get_video_fps() +{ + return __video_fps; } -int32_t tmedia_defaults_get_video_fps(){ - return __video_fps; + +int tmedia_defaults_set_video_motion_rank(int32_t video_motion_rank) +{ + switch(video_motion_rank) { + case 1/*low*/: + case 2/*medium*/: + case 4/*high*/: + __video_motion_rank = video_motion_rank; + return 0; + default: + TSK_DEBUG_ERROR("%d not valid for video motion rank. Must be 1, 2 or 4", video_motion_rank); + return -1; + } +} +int32_t tmedia_defaults_get_video_motion_rank() +{ + return __video_motion_rank; } -int tmedia_defaults_set_video_motion_rank(int32_t video_motion_rank){ - switch(video_motion_rank){ - case 1/*low*/: case 2/*medium*/: case 4/*high*/: __video_motion_rank = video_motion_rank; return 0; - default: TSK_DEBUG_ERROR("%d not valid for video motion rank. Must be 1, 2 or 4", video_motion_rank); return -1; - } +int tmedia_defaults_set_bandwidth_video_upload_max(int32_t bw_video_up_max_kbps) +{ + __bw_video_up_max_kbps = bw_video_up_max_kbps > 0 ? bw_video_up_max_kbps : INT_MAX; + return 0; } -int32_t tmedia_defaults_get_video_motion_rank(){ - return __video_motion_rank; +int32_t tmedia_defaults_get_bandwidth_video_upload_max() +{ + return __bw_video_up_max_kbps; } -int tmedia_defaults_set_bandwidth_video_upload_max(int32_t bw_video_up_max_kbps){ - __bw_video_up_max_kbps = bw_video_up_max_kbps > 0 ? bw_video_up_max_kbps : INT_MAX; - return 0; +int tmedia_defaults_set_bandwidth_video_download_max(int32_t bw_video_down_max_kbps) +{ + __bw_video_down_max_kbps = bw_video_down_max_kbps > 0 ? bw_video_down_max_kbps : INT_MAX; + return 0; } -int32_t tmedia_defaults_get_bandwidth_video_upload_max(){ - return __bw_video_up_max_kbps; +int32_t tmedia_defaults_get_bandwidth_video_download_max() +{ + return __bw_video_down_max_kbps; } -int tmedia_defaults_set_bandwidth_video_download_max(int32_t bw_video_down_max_kbps){ - __bw_video_down_max_kbps = bw_video_down_max_kbps > 0 ? bw_video_down_max_kbps : INT_MAX; - return 0; +int tmedia_defaults_set_pref_video_size(tmedia_pref_video_size_t pref_video_size) +{ + __pref_video_size = pref_video_size; + return 0; } -int32_t tmedia_defaults_get_bandwidth_video_download_max(){ - return __bw_video_down_max_kbps; +tmedia_pref_video_size_t tmedia_defaults_get_pref_video_size() +{ + return __pref_video_size; } -int tmedia_defaults_set_pref_video_size(tmedia_pref_video_size_t pref_video_size){ - __pref_video_size = pref_video_size; - return 0; +int tmedia_defaults_set_pref_video_size_range(tmedia_pref_video_size_t min, tmedia_pref_video_size_t max) +{ + if (min <= max) { + __pref_video_size_range_min = min; + __pref_video_size_range_max = max; + return 0; + } + return -1; +} +int tmedia_defaults_get_pref_video_size_range(tmedia_pref_video_size_t *min, tmedia_pref_video_size_t* max) +{ + if (min) { + *min = __pref_video_size_range_min; + } + if (max) { + *max = __pref_video_size_range_max; + } + return 0; } -tmedia_pref_video_size_t tmedia_defaults_get_pref_video_size(){ - return __pref_video_size; + +int tmedia_defaults_set_adapt_video_size_range_enabled(tsk_bool_t enabled) +{ + __pref_video_size_range_enabled = enabled; + return 0; +} +tsk_bool_t tmedia_defaults_get_adapt_video_size_range_enabled() +{ + return __pref_video_size_range_enabled; } -int tmedia_defaults_set_jb_margin(int32_t jb_margin_ms){ - __jb_margin_ms = jb_margin_ms; - return __jb_margin_ms; +int tmedia_defaults_set_jb_margin(int32_t jb_margin_ms) +{ + __jb_margin_ms = jb_margin_ms; + return __jb_margin_ms; } -int32_t tmedia_defaults_get_jb_margin(){ - return __jb_margin_ms; +int32_t tmedia_defaults_get_jb_margin() +{ + return __jb_margin_ms; } -int tmedia_defaults_set_jb_max_late_rate(int32_t jb_max_late_rate_percent){ - __jb_max_late_rate_percent = jb_max_late_rate_percent; - return 0; +int tmedia_defaults_set_jb_max_late_rate(int32_t jb_max_late_rate_percent) +{ + __jb_max_late_rate_percent = jb_max_late_rate_percent; + return 0; } -int32_t tmedia_defaults_get_jb_max_late_rate(){ - return __jb_max_late_rate_percent; +int32_t tmedia_defaults_get_jb_max_late_rate() +{ + return __jb_max_late_rate_percent; } -int tmedia_defaults_set_echo_tail(uint32_t echo_tail){ - __echo_tail = echo_tail; - return 0; +int tmedia_defaults_set_echo_tail(uint32_t echo_tail) +{ + __echo_tail = echo_tail; + return 0; } -int tmedia_defaults_set_echo_skew(uint32_t echo_skew){ - __echo_skew = echo_skew; - return 0; +int tmedia_defaults_set_echo_skew(uint32_t echo_skew) +{ + __echo_skew = echo_skew; + return 0; } uint32_t tmedia_defaults_get_echo_tail() { - return __echo_tail; + return __echo_tail; } -uint32_t tmedia_defaults_get_echo_skew(){ - return __echo_skew; +uint32_t tmedia_defaults_get_echo_skew() +{ + return __echo_skew; } -int tmedia_defaults_set_echo_supp_enabled(tsk_bool_t echo_supp_enabled){ - __echo_supp_enabled = echo_supp_enabled; - return 0; +int tmedia_defaults_set_echo_supp_enabled(tsk_bool_t echo_supp_enabled) +{ + __echo_supp_enabled = echo_supp_enabled; + return 0; } -tsk_bool_t tmedia_defaults_get_echo_supp_enabled(){ - return __echo_supp_enabled; +tsk_bool_t tmedia_defaults_get_echo_supp_enabled() +{ + return __echo_supp_enabled; } -int tmedia_defaults_set_agc_enabled(tsk_bool_t agc_enabled){ - __agc_enabled = agc_enabled; - return 0; +int tmedia_defaults_set_agc_enabled(tsk_bool_t agc_enabled) +{ + __agc_enabled = agc_enabled; + return 0; } -tsk_bool_t tmedia_defaults_get_agc_enabled(){ - return __agc_enabled; +tsk_bool_t tmedia_defaults_get_agc_enabled() +{ + return __agc_enabled; } -int tmedia_defaults_set_agc_level(float agc_level){ - __agc_level = agc_level; - return 0; +int tmedia_defaults_set_agc_level(float agc_level) +{ + __agc_level = agc_level; + return 0; } float tmedia_defaults_get_agc_level() { - return __agc_level; + return __agc_level; } -int tmedia_defaults_set_vad_enabled(tsk_bool_t vad_enabled){ - __vad_enabled = vad_enabled; - return 0; +int tmedia_defaults_set_vad_enabled(tsk_bool_t vad_enabled) +{ + __vad_enabled = vad_enabled; + return 0; } -tsk_bool_t tmedia_defaults_get_vad_enabled(){ - return __vad_enabled; +tsk_bool_t tmedia_defaults_get_vad_enabled() +{ + return __vad_enabled; } -int tmedia_defaults_set_noise_supp_enabled(tsk_bool_t noise_supp_enabled){ - __noise_supp_enabled = noise_supp_enabled; - return 0; +int tmedia_defaults_set_noise_supp_enabled(tsk_bool_t noise_supp_enabled) +{ + __noise_supp_enabled = noise_supp_enabled; + return 0; } -tsk_bool_t tmedia_defaults_get_noise_supp_enabled(){ - return __noise_supp_enabled; +tsk_bool_t tmedia_defaults_get_noise_supp_enabled() +{ + return __noise_supp_enabled; } -int tmedia_defaults_set_noise_supp_level(int32_t noise_supp_level){ - __noise_supp_level = noise_supp_level; - return 0; +int tmedia_defaults_set_noise_supp_level(int32_t noise_supp_level) +{ + __noise_supp_level = noise_supp_level; + return 0; } -int32_t tmedia_defaults_get_noise_supp_level(){ - return __noise_supp_level; +int32_t tmedia_defaults_get_noise_supp_level() +{ + return __noise_supp_level; } -int tmedia_defaults_set_100rel_enabled(tsk_bool_t _100rel_enabled){ - __100rel_enabled = _100rel_enabled; - return 0; +int tmedia_defaults_set_100rel_enabled(tsk_bool_t _100rel_enabled) +{ + __100rel_enabled = _100rel_enabled; + return 0; } -tsk_bool_t tmedia_defaults_get_100rel_enabled(){ - return __100rel_enabled; +tsk_bool_t tmedia_defaults_get_100rel_enabled() +{ + return __100rel_enabled; } -int tmedia_defaults_set_screen_size(int32_t sx, int32_t sy){ - __sx = sx; - __sy = sy; - return 0; +int tmedia_defaults_set_screen_size(int32_t sx, int32_t sy) +{ + __sx = sx; + __sy = sy; + return 0; } -int32_t tmedia_defaults_get_screen_x(){ - return __sx; +int32_t tmedia_defaults_get_screen_x() +{ + return __sx; } -int32_t tmedia_defaults_get_screen_y(){ - return __sy; +int32_t tmedia_defaults_get_screen_y() +{ + return __sy; } -int tmedia_defaults_set_audio_ptime(int32_t audio_ptime){ - if(audio_ptime > 0){ - __audio_ptime = audio_ptime; - return 0; - } - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; -} -int32_t tmedia_defaults_get_audio_ptime(){ - return __audio_ptime; +int tmedia_defaults_set_audio_ptime(int32_t audio_ptime) +{ + if(audio_ptime > 0) { + __audio_ptime = audio_ptime; + return 0; + } + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; +} +int32_t tmedia_defaults_get_audio_ptime() +{ + return __audio_ptime; } -int tmedia_defaults_set_audio_channels(int32_t channels_playback, int32_t channels_record){ - if(channels_playback != 1 && channels_playback != 2) { TSK_DEBUG_ERROR("Invalid parameter"); return -1; } - if(channels_record != 1 && channels_record != 2) { TSK_DEBUG_ERROR("Invalid parameter"); return -1; } - __audio_channels_playback = channels_playback; - __audio_channels_record = channels_record; - return 0; +int tmedia_defaults_set_audio_channels(int32_t channels_playback, int32_t channels_record) +{ + if(channels_playback != 1 && channels_playback != 2) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + if(channels_record != 1 && channels_record != 2) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + __audio_channels_playback = channels_playback; + __audio_channels_record = channels_record; + return 0; } -int32_t tmedia_defaults_get_audio_channels_playback(){ - return __audio_channels_playback; +int32_t tmedia_defaults_get_audio_channels_playback() +{ + return __audio_channels_playback; } -int32_t tmedia_defaults_get_audio_channels_record(){ - return __audio_channels_record; +int32_t tmedia_defaults_get_audio_channels_record() +{ + return __audio_channels_record; } -int tmedia_defaults_set_audio_gain(int32_t audio_producer_gain, int32_t audio_consumer_gain){ - __audio_producer_gain = audio_producer_gain; - __audio_consumer_gain = audio_consumer_gain; - return 0; +int tmedia_defaults_set_audio_gain(int32_t audio_producer_gain, int32_t audio_consumer_gain) +{ + __audio_producer_gain = audio_producer_gain; + __audio_consumer_gain = audio_consumer_gain; + return 0; } -int32_t tmedia_defaults_get_audio_producer_gain(){ - return __audio_producer_gain; +int32_t tmedia_defaults_get_audio_producer_gain() +{ + return __audio_producer_gain; } -int32_t tmedia_defaults_get_audio_consumer_gain(){ - return __audio_consumer_gain; +int32_t tmedia_defaults_get_audio_consumer_gain() +{ + return __audio_consumer_gain; } -uint16_t tmedia_defaults_get_rtp_port_range_start(){ - return __rtp_port_range_start; +uint16_t tmedia_defaults_get_rtp_port_range_start() +{ + return __rtp_port_range_start; } -uint16_t tmedia_defaults_get_rtp_port_range_stop(){ - return __rtp_port_range_stop; +uint16_t tmedia_defaults_get_rtp_port_range_stop() +{ + return __rtp_port_range_stop; } -int tmedia_defaults_set_rtp_port_range(uint16_t start, uint16_t stop){ - if(start < 1024 || stop < 1024 || start >= stop){ - TSK_DEBUG_ERROR("Invalid parameter: (%u < 1024 || %u < 1024 || %u >= %u)", start, stop, start, stop); - return -1; - } - __rtp_port_range_start = start; - __rtp_port_range_stop = stop; - return 0; +int tmedia_defaults_set_rtp_port_range(uint16_t start, uint16_t stop) +{ + if(start < 1024 || stop < 1024 || start >= stop) { + TSK_DEBUG_ERROR("Invalid parameter: (%u < 1024 || %u < 1024 || %u >= %u)", start, stop, start, stop); + return -1; + } + __rtp_port_range_start = start; + __rtp_port_range_stop = stop; + return 0; } -int tmedia_defaults_set_rtp_symetric_enabled(tsk_bool_t enabled){ - __rtp_symetric_enabled = enabled; - return 0; +int tmedia_defaults_set_rtp_symetric_enabled(tsk_bool_t enabled) +{ + __rtp_symetric_enabled = enabled; + return 0; } -tsk_bool_t tmedia_defaults_get_rtp_symetric_enabled(){ - return __rtp_symetric_enabled; +tsk_bool_t tmedia_defaults_get_rtp_symetric_enabled() +{ + return __rtp_symetric_enabled; } -tmedia_type_t tmedia_defaults_get_media_type(){ - return __media_type; +tmedia_type_t tmedia_defaults_get_media_type() +{ + return __media_type; } -int tmedia_defaults_set_media_type(tmedia_type_t media_type){ - __media_type = media_type; - return 0; +int tmedia_defaults_set_media_type(tmedia_type_t media_type) +{ + __media_type = media_type; + return 0; } -int tmedia_defaults_set_volume(int32_t volume){ - __volume = TSK_CLAMP(0, volume, 100); - return 0; +int tmedia_defaults_set_volume(int32_t volume) +{ + __volume = TSK_CLAMP(0, volume, 100); + return 0; } -int32_t tmedia_defaults_get_volume(){ - return __volume; +int32_t tmedia_defaults_get_volume() +{ + return __volume; } -int tmedia_producer_set_friendly_name(tmedia_type_t media_type, const char* friendly_name) { - if(media_type != tmedia_audio && media_type != tmedia_video && media_type != tmedia_bfcp_video) { - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - tsk_strupdate(&__producer_friendly_name[(media_type == tmedia_audio) ? 0 : (media_type == tmedia_bfcp_video ? 2 : 1)], friendly_name); - return 0; +int tmedia_producer_set_friendly_name(tmedia_type_t media_type, const char* friendly_name) +{ + if(media_type != tmedia_audio && media_type != tmedia_video && media_type != tmedia_bfcp_video) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + tsk_strupdate(&__producer_friendly_name[(media_type == tmedia_audio) ? 0 : (media_type == tmedia_bfcp_video ? 2 : 1)], friendly_name); + return 0; } -const char* tmedia_producer_get_friendly_name(tmedia_type_t media_type){ - if(media_type != tmedia_audio && media_type != tmedia_video && media_type != tmedia_bfcp_video) { - TSK_DEBUG_ERROR("Invalid parameter"); - return tsk_null; - } - return __producer_friendly_name[(media_type == tmedia_audio) ? 0 : (media_type == tmedia_bfcp_video ? 2 : 1)]; +const char* tmedia_producer_get_friendly_name(tmedia_type_t media_type) +{ + if(media_type != tmedia_audio && media_type != tmedia_video && media_type != tmedia_bfcp_video) { + TSK_DEBUG_ERROR("Invalid parameter"); + return tsk_null; + } + return __producer_friendly_name[(media_type == tmedia_audio) ? 0 : (media_type == tmedia_bfcp_video ? 2 : 1)]; } -int32_t tmedia_defaults_get_inv_session_expires(){ - return __inv_session_expires; +int32_t tmedia_defaults_get_inv_session_expires() +{ + return __inv_session_expires; } -int tmedia_defaults_set_inv_session_expires(int32_t timeout){ - if(timeout >= 0){ - __inv_session_expires = timeout; - return 0; - } - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; +int tmedia_defaults_set_inv_session_expires(int32_t timeout) +{ + if(timeout >= 0) { + __inv_session_expires = timeout; + return 0; + } + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; } -const char* tmedia_defaults_get_inv_session_refresher(){ - return __inv_session_refresher; +const char* tmedia_defaults_get_inv_session_refresher() +{ + return __inv_session_refresher; } -int tmedia_defaults_set_inv_session_refresher(const char* refresher){ - tsk_strupdate(&__inv_session_refresher, refresher); - return 0; +int tmedia_defaults_set_inv_session_refresher(const char* refresher) +{ + tsk_strupdate(&__inv_session_refresher, refresher); + return 0; } -tmedia_srtp_mode_t tmedia_defaults_get_srtp_mode(){ - return __srtp_mode; +tmedia_srtp_mode_t tmedia_defaults_get_srtp_mode() +{ + return __srtp_mode; } -int tmedia_defaults_set_srtp_mode(tmedia_srtp_mode_t mode){ - __srtp_mode = mode; - return 0; +int tmedia_defaults_set_srtp_mode(tmedia_srtp_mode_t mode) +{ + __srtp_mode = mode; + return 0; } -tmedia_srtp_type_t tmedia_defaults_get_srtp_type(){ - return __srtp_type; +tmedia_srtp_type_t tmedia_defaults_get_srtp_type() +{ + return __srtp_type; } -int tmedia_defaults_set_srtp_type(tmedia_srtp_type_t srtp_type){ - __srtp_type = srtp_type; - return 0; +int tmedia_defaults_set_srtp_type(tmedia_srtp_type_t srtp_type) +{ + __srtp_type = srtp_type; + return 0; } -tsk_bool_t tmedia_defaults_get_rtcp_enabled(){ - return __rtcp_enabled; +tsk_bool_t tmedia_defaults_get_rtcp_enabled() +{ + return __rtcp_enabled; } -int tmedia_defaults_set_rtcp_enabled(tsk_bool_t rtcp_enabled){ - __rtcp_enabled = rtcp_enabled; - return 0; +int tmedia_defaults_set_rtcp_enabled(tsk_bool_t rtcp_enabled) +{ + __rtcp_enabled = rtcp_enabled; + return 0; } -tsk_bool_t tmedia_defaults_get_rtcpmux_enabled(){ - return __rtcpmux_enabled; +tsk_bool_t tmedia_defaults_get_rtcpmux_enabled() +{ + return __rtcpmux_enabled; } -int tmedia_defaults_set_rtcpmux_enabled(tsk_bool_t rtcpmux_enabled){ - __rtcpmux_enabled = rtcpmux_enabled; - return 0; +int tmedia_defaults_set_rtcpmux_enabled(tsk_bool_t rtcpmux_enabled) +{ + __rtcpmux_enabled = rtcpmux_enabled; + return 0; } -int tmedia_defaults_set_stun_server(const char* server_ip, uint16_t server_port){ - tsk_strupdate(&__stun_server_ip, server_ip); - __stun_server_port = server_port; - return 0; +int tmedia_defaults_set_stun_server(const char* server_ip, uint16_t server_port) +{ + tsk_strupdate(&__stun_server_ip, server_ip); + __stun_server_port = server_port; + return 0; } -int tmedia_defaults_get_stun_server(const char** server_ip, uint16_t*const server_port){ - static const char* __stun_server_ip_default = "numb.viagenie.ca"; // default server for backward compatibility - if(server_ip) *server_ip = tsk_strnullORempty(__stun_server_ip) ? __stun_server_ip_default : __stun_server_ip; - if(server_port) *server_port = __stun_server_port; - return 0; +int tmedia_defaults_get_stun_server(const char** server_ip, uint16_t*const server_port) +{ + static const char* __stun_server_ip_default = "numb.viagenie.ca"; // default server for backward compatibility + if(server_ip) { + *server_ip = tsk_strnullORempty(__stun_server_ip) ? __stun_server_ip_default : __stun_server_ip; + } + if(server_port) { + *server_port = __stun_server_port; + } + return 0; } -int tmedia_defaults_set_stun_cred(const char* usr_name, const char* usr_pwd) { - tsk_strupdate(&__stun_usr_name, usr_name); - tsk_strupdate(&__stun_usr_pwd, usr_pwd); - return 0; +int tmedia_defaults_set_stun_cred(const char* usr_name, const char* usr_pwd) +{ + tsk_strupdate(&__stun_usr_name, usr_name); + tsk_strupdate(&__stun_usr_pwd, usr_pwd); + return 0; } -int tmedia_defaults_get_stun_cred(const char** usr_name, const char** usr_pwd){ - if(usr_name) *usr_name = __stun_usr_name; - if(usr_pwd) *usr_pwd = __stun_usr_pwd; - return 0; +int tmedia_defaults_get_stun_cred(const char** usr_name, const char** usr_pwd) +{ + if(usr_name) { + *usr_name = __stun_usr_name; + } + if(usr_pwd) { + *usr_pwd = __stun_usr_pwd; + } + return 0; } -int tmedia_defaults_set_stun_enabled(tsk_bool_t stun_enabled){ - __stun_enabled = stun_enabled; - return 0; +int tmedia_defaults_set_stun_enabled(tsk_bool_t stun_enabled) +{ + __stun_enabled = stun_enabled; + return 0; } -tsk_bool_t tmedia_defaults_get_stun_enabled(){ - return __stun_enabled; +tsk_bool_t tmedia_defaults_get_stun_enabled() +{ + return __stun_enabled; } -int tmedia_defaults_set_icestun_enabled(tsk_bool_t icestun_enabled){ - __icestun_enabled = icestun_enabled; - return 0; +int tmedia_defaults_set_icestun_enabled(tsk_bool_t icestun_enabled) +{ + __icestun_enabled = icestun_enabled; + return 0; } -tsk_bool_t tmedia_defaults_get_icestun_enabled(){ - return __icestun_enabled; +tsk_bool_t tmedia_defaults_get_icestun_enabled() +{ + return __icestun_enabled; } -int tmedia_defaults_set_iceturn_enabled(tsk_bool_t iceturn_enabled){ - __iceturn_enabled = iceturn_enabled; - return 0; +int tmedia_defaults_set_iceturn_enabled(tsk_bool_t iceturn_enabled) +{ + __iceturn_enabled = iceturn_enabled; + return 0; } -tsk_bool_t tmedia_defaults_get_iceturn_enabled(){ - return __iceturn_enabled; +tsk_bool_t tmedia_defaults_get_iceturn_enabled() +{ + return __iceturn_enabled; } -int tmedia_defaults_set_ice_enabled(tsk_bool_t ice_enabled){ - __ice_enabled = ice_enabled; - return 0; +int tmedia_defaults_set_ice_enabled(tsk_bool_t ice_enabled) +{ + __ice_enabled = ice_enabled; + return 0; } -tsk_bool_t tmedia_defaults_get_ice_enabled(){ - return __ice_enabled; +tsk_bool_t tmedia_defaults_get_ice_enabled() +{ + return __ice_enabled; } -int tmedia_defaults_set_bypass_encoding(tsk_bool_t enabled){ - __bypass_encoding_enabled = enabled; - return 0; +int tmedia_defaults_set_bypass_encoding(tsk_bool_t enabled) +{ + __bypass_encoding_enabled = enabled; + return 0; } -tsk_bool_t tmedia_defaults_get_bypass_encoding(){ - return __bypass_encoding_enabled; +tsk_bool_t tmedia_defaults_get_bypass_encoding() +{ + return __bypass_encoding_enabled; } -int tmedia_defaults_set_bypass_decoding(tsk_bool_t enabled){ - __bypass_decoding_enabled = enabled; - return 0; +int tmedia_defaults_set_bypass_decoding(tsk_bool_t enabled) +{ + __bypass_decoding_enabled = enabled; + return 0; } -tsk_bool_t tmedia_defaults_get_bypass_decoding(){ - return __bypass_decoding_enabled; +tsk_bool_t tmedia_defaults_get_bypass_decoding() +{ + return __bypass_decoding_enabled; } -int tmedia_defaults_set_videojb_enabled(tsk_bool_t enabled){ - __videojb_enabled = enabled; - return 0; +int tmedia_defaults_set_videojb_enabled(tsk_bool_t enabled) +{ + __videojb_enabled = enabled; + return 0; } -tsk_bool_t tmedia_defaults_get_videojb_enabled(){ - return __videojb_enabled; +tsk_bool_t tmedia_defaults_get_videojb_enabled() +{ + return __videojb_enabled; } -int tmedia_defaults_set_video_zeroartifacts_enabled(tsk_bool_t enabled){ - __video_zeroartifacts_enabled = enabled; - return 0; +int tmedia_defaults_set_video_zeroartifacts_enabled(tsk_bool_t enabled) +{ + __video_zeroartifacts_enabled = enabled; + return 0; } -tsk_bool_t tmedia_defaults_get_video_zeroartifacts_enabled(){ - return __video_zeroartifacts_enabled; +tsk_bool_t tmedia_defaults_get_video_zeroartifacts_enabled() +{ + return __video_zeroartifacts_enabled; } -int tmedia_defaults_set_rtpbuff_size(tsk_size_t rtpbuff_size){ - __rtpbuff_size = rtpbuff_size; - return 0; +int tmedia_defaults_set_rtpbuff_size(tsk_size_t rtpbuff_size) +{ + __rtpbuff_size = rtpbuff_size; + return 0; } -tsk_size_t tmedia_defaults_get_rtpbuff_size(){ - return __rtpbuff_size; +tsk_size_t tmedia_defaults_get_rtpbuff_size() +{ + return __rtpbuff_size; } -int tmedia_defaults_set_avpf_tail(tsk_size_t tail_min, tsk_size_t tail_max){ - __avpf_tail_min = tail_min; - __avpf_tail_max = tail_max; - return 0; +int tmedia_defaults_set_avpf_tail(tsk_size_t tail_min, tsk_size_t tail_max) +{ + __avpf_tail_min = tail_min; + __avpf_tail_max = tail_max; + return 0; } -tsk_size_t tmedia_defaults_get_avpf_tail_min(){ - return __avpf_tail_min; +tsk_size_t tmedia_defaults_get_avpf_tail_min() +{ + return __avpf_tail_min; } -tsk_size_t tmedia_defaults_get_avpf_tail_max(){ - return __avpf_tail_max; +tsk_size_t tmedia_defaults_get_avpf_tail_max() +{ + return __avpf_tail_max; } -int tmedia_defaults_set_avpf_mode(enum tmedia_mode_e mode) { - __avpf_mode = mode; - return 0; +int tmedia_defaults_set_avpf_mode(enum tmedia_mode_e mode) +{ + __avpf_mode = mode; + return 0; } -enum tmedia_mode_e tmedia_defaults_get_avpf_mode() { - return __avpf_mode; +enum tmedia_mode_e tmedia_defaults_get_avpf_mode() +{ + return __avpf_mode; } -int tmedia_defaults_set_opus_maxcapturerate(uint32_t opus_maxcapturerate){ - switch(opus_maxcapturerate){ - case 8000: case 12000: case 16000: case 24000: case 48000: __opus_maxcapturerate = opus_maxcapturerate; return 0; - default: TSK_DEBUG_ERROR("%u not valid for opus_maxcapturerate", opus_maxcapturerate); return -1; - } -} -uint32_t tmedia_defaults_get_opus_maxcapturerate(){ - return __opus_maxcapturerate; +int tmedia_defaults_set_opus_maxcapturerate(uint32_t opus_maxcapturerate) +{ + switch(opus_maxcapturerate) { + case 8000: + case 12000: + case 16000: + case 24000: + case 48000: + __opus_maxcapturerate = opus_maxcapturerate; + return 0; + default: + TSK_DEBUG_ERROR("%u not valid for opus_maxcapturerate", opus_maxcapturerate); + return -1; + } +} +uint32_t tmedia_defaults_get_opus_maxcapturerate() +{ + return __opus_maxcapturerate; } -int tmedia_defaults_set_opus_maxplaybackrate(uint32_t opus_maxplaybackrate){ - switch(opus_maxplaybackrate){ - case 8000: case 12000: case 16000: case 24000: case 48000: __opus_maxplaybackrate = opus_maxplaybackrate; return 0; - default: TSK_DEBUG_ERROR("%u not valid for opus_maxplaybackrate", opus_maxplaybackrate); return -1; - } -} -uint32_t tmedia_defaults_get_opus_maxplaybackrate(){ - return __opus_maxplaybackrate; +int tmedia_defaults_set_opus_maxplaybackrate(uint32_t opus_maxplaybackrate) +{ + switch(opus_maxplaybackrate) { + case 8000: + case 12000: + case 16000: + case 24000: + case 48000: + __opus_maxplaybackrate = opus_maxplaybackrate; + return 0; + default: + TSK_DEBUG_ERROR("%u not valid for opus_maxplaybackrate", opus_maxplaybackrate); + return -1; + } +} +uint32_t tmedia_defaults_get_opus_maxplaybackrate() +{ + return __opus_maxplaybackrate; } -int tmedia_defaults_set_ssl_certs(const char* priv_path, const char* pub_path, const char* ca_path, tsk_bool_t verify){ - tsk_strupdate(&__ssl_certs_priv_path, priv_path); - tsk_strupdate(&__ssl_certs_pub_path, pub_path); - tsk_strupdate(&__ssl_certs_ca_path, ca_path); - __ssl_certs_verify = verify; - return 0; +int tmedia_defaults_set_ssl_certs(const char* priv_path, const char* pub_path, const char* ca_path, tsk_bool_t verify) +{ + tsk_strupdate(&__ssl_certs_priv_path, priv_path); + tsk_strupdate(&__ssl_certs_pub_path, pub_path); + tsk_strupdate(&__ssl_certs_ca_path, ca_path); + __ssl_certs_verify = verify; + return 0; } -int tmedia_defaults_get_ssl_certs(const char** priv_path, const char** pub_path, const char** ca_path, tsk_bool_t *verify){ - if(priv_path) *priv_path = __ssl_certs_priv_path; - if(pub_path) *pub_path = __ssl_certs_pub_path; - if(ca_path) *ca_path = __ssl_certs_ca_path; - if(verify) *verify = __ssl_certs_verify; - return 0; +int tmedia_defaults_get_ssl_certs(const char** priv_path, const char** pub_path, const char** ca_path, tsk_bool_t *verify) +{ + if(priv_path) { + *priv_path = __ssl_certs_priv_path; + } + if(pub_path) { + *pub_path = __ssl_certs_pub_path; + } + if(ca_path) { + *ca_path = __ssl_certs_ca_path; + } + if(verify) { + *verify = __ssl_certs_verify; + } + return 0; } -int tmedia_defaults_set_max_fds(int32_t max_fds) { - if (max_fds > 0 && max_fds < 0xFFFF) { - __max_fds = (tsk_size_t)max_fds; - return 0; - } - return -1; +int tmedia_defaults_set_max_fds(int32_t max_fds) +{ + if (max_fds > 0 && max_fds < 0xFFFF) { + __max_fds = (tsk_size_t)max_fds; + return 0; + } + return -1; } -tsk_size_t tmedia_defaults_get_max_fds() { - return __max_fds; +tsk_size_t tmedia_defaults_get_max_fds() +{ + return __max_fds; } -int tmedia_defaults_set_webproxy_auto_detect(tsk_bool_t auto_detect) { +int tmedia_defaults_set_webproxy_auto_detect(tsk_bool_t auto_detect) +{ __webproxy_auto_detect = auto_detect; return 0; } -tsk_bool_t tmedia_defaults_get_webproxy_auto_detect() { +tsk_bool_t tmedia_defaults_get_webproxy_auto_detect() +{ return __webproxy_auto_detect; } -int tmedia_defaults_set_webproxy_info(const char* type, const char* host, unsigned short port, const char* login, const char* password) { +int tmedia_defaults_set_webproxy_info(const char* type, const char* host, unsigned short port, const char* login, const char* password) +{ tsk_strupdate(&__webproxy_type, type); tsk_strupdate(&__webproxy_host, host); tsk_strupdate(&__webproxy_login, login); @@ -608,11 +793,22 @@ int tmedia_defaults_set_webproxy_info(const char* type, const char* host, unsign return 0; } -int tmedia_defaults_get_webproxy_info(const char** type, const char** host, unsigned short* port, const char** login, const char** password) { - if (type) *type = __webproxy_type; - if (host) *host = __webproxy_host; - if (port) *port = __webproxy_port; - if (login) *login = __webproxy_login; - if (password) *password = __webproxy_password; +int tmedia_defaults_get_webproxy_info(const char** type, const char** host, unsigned short* port, const char** login, const char** password) +{ + if (type) { + *type = __webproxy_type; + } + if (host) { + *host = __webproxy_host; + } + if (port) { + *port = __webproxy_port; + } + if (login) { + *login = __webproxy_login; + } + if (password) { + *password = __webproxy_password; + } return 0; } diff --git a/tinyMEDIA/src/tmedia_denoise.c b/tinyMEDIA/src/tmedia_denoise.c index 4c0f74b..7149e35 100755 --- a/tinyMEDIA/src/tmedia_denoise.c +++ b/tinyMEDIA/src/tmedia_denoise.c @@ -2,19 +2,19 @@ * Copyright (C) 2010-2011 Mamadou Diop. * * Contact: Mamadou Diop <diopmamadou(at)doubango[dot]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. * @@ -36,207 +36,207 @@ static const tmedia_denoise_plugin_def_t* __tmedia_denoise_plugin = tsk_null; int tmedia_denoise_init(tmedia_denoise_t* self) { - if(!self){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - - self->echo_tail = tmedia_defaults_get_echo_tail(); - self->echo_skew = tmedia_defaults_get_echo_skew(); - self->echo_supp_enabled = tmedia_defaults_get_echo_supp_enabled(); - self->agc_enabled = tmedia_defaults_get_agc_enabled(); - self->agc_level = tmedia_defaults_get_agc_level(); - self->vad_enabled = tmedia_defaults_get_vad_enabled(); - self->noise_supp_enabled = tmedia_defaults_get_noise_supp_enabled(); - self->noise_supp_level = tmedia_defaults_get_noise_supp_level(); - - return 0; + if(!self) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + + self->echo_tail = tmedia_defaults_get_echo_tail(); + self->echo_skew = tmedia_defaults_get_echo_skew(); + self->echo_supp_enabled = tmedia_defaults_get_echo_supp_enabled(); + self->agc_enabled = tmedia_defaults_get_agc_enabled(); + self->agc_level = tmedia_defaults_get_agc_level(); + self->vad_enabled = tmedia_defaults_get_vad_enabled(); + self->noise_supp_enabled = tmedia_defaults_get_noise_supp_enabled(); + self->noise_supp_level = tmedia_defaults_get_noise_supp_level(); + + return 0; } int tmedia_denoise_set(tmedia_denoise_t* self, const tmedia_param_t* param) { - if(!self || !self->plugin){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - - if(self->plugin->set){ - return self->plugin->set(self, param); - } - return 0; + if(!self || !self->plugin) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + + if(self->plugin->set) { + return self->plugin->set(self, param); + } + return 0; } int tmedia_denoise_open(tmedia_denoise_t* self, uint32_t record_frame_size_samples, uint32_t record_sampling_rate, uint32_t record_channels, uint32_t playback_frame_size_samples, uint32_t playback_sampling_rate, uint32_t playback_channels) { - if (!self || !self->plugin) { - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - if (self->opened) { - TSK_DEBUG_WARN("Denoiser already opened"); - return 0; - } - - if (self->plugin->open) { - int ret; - - TSK_OBJECT_SAFE_FREE(self->record_frame); - TSK_OBJECT_SAFE_FREE(self->playback_frame); - if (!(self->record_frame = tsk_buffer_create(tsk_null, (record_frame_size_samples * sizeof(int16_t))))) { - TSK_DEBUG_ERROR("Failed to create record the buffer"); - return -2; - } - if (!(self->playback_frame = tsk_buffer_create(tsk_null, (playback_frame_size_samples * sizeof(int16_t))))) { - TSK_DEBUG_ERROR("Failed to create playback the buffer"); - return -2; - } - if ((ret = self->plugin->open(self, record_frame_size_samples, record_sampling_rate, record_channels, playback_frame_size_samples, playback_sampling_rate, playback_channels))) { - TSK_DEBUG_ERROR("Failed to open [%s] denoiser", self->plugin->desc); - return ret; - } - else { - self->opened = tsk_true; - return 0; - } - } - else{ - self->opened = tsk_true; - return 0; - } + if (!self || !self->plugin) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + if (self->opened) { + TSK_DEBUG_WARN("Denoiser already opened"); + return 0; + } + + if (self->plugin->open) { + int ret; + + TSK_OBJECT_SAFE_FREE(self->record_frame); + TSK_OBJECT_SAFE_FREE(self->playback_frame); + if (!(self->record_frame = tsk_buffer_create(tsk_null, (record_frame_size_samples * sizeof(int16_t))))) { + TSK_DEBUG_ERROR("Failed to create record the buffer"); + return -2; + } + if (!(self->playback_frame = tsk_buffer_create(tsk_null, (playback_frame_size_samples * sizeof(int16_t))))) { + TSK_DEBUG_ERROR("Failed to create playback the buffer"); + return -2; + } + if ((ret = self->plugin->open(self, record_frame_size_samples, record_sampling_rate, record_channels, playback_frame_size_samples, playback_sampling_rate, playback_channels))) { + TSK_DEBUG_ERROR("Failed to open [%s] denoiser", self->plugin->desc); + return ret; + } + else { + self->opened = tsk_true; + return 0; + } + } + else { + self->opened = tsk_true; + return 0; + } } int tmedia_denoise_echo_playback(tmedia_denoise_t* self, const void* echo_frame, uint32_t echo_frame_size_bytes) { - if(!self || !self->plugin){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - - if(!self->opened){ - TSK_DEBUG_ERROR("Denoiser not opened"); - return -2; - } - - if(self->plugin->echo_playback){ - return self->plugin->echo_playback(self, echo_frame, echo_frame_size_bytes); - } - else{ - return 0; - } + if(!self || !self->plugin) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + + if(!self->opened) { + TSK_DEBUG_ERROR("Denoiser not opened"); + return -2; + } + + if(self->plugin->echo_playback) { + return self->plugin->echo_playback(self, echo_frame, echo_frame_size_bytes); + } + else { + return 0; + } } int tmedia_denoise_process_record(tmedia_denoise_t* self, void* audio_frame, uint32_t audio_frame_size_bytes, tsk_bool_t* silence_or_noise) { - if(!self || !self->plugin || !silence_or_noise){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - - if(!self->opened){ - TSK_DEBUG_ERROR("Denoiser not opened"); - return -2; - } - - if(self->plugin->process_record){ - return self->plugin->process_record(self, audio_frame, audio_frame_size_bytes, silence_or_noise); - } - else{ - *silence_or_noise = tsk_false; - return 0; - } + if(!self || !self->plugin || !silence_or_noise) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + + if(!self->opened) { + TSK_DEBUG_ERROR("Denoiser not opened"); + return -2; + } + + if(self->plugin->process_record) { + return self->plugin->process_record(self, audio_frame, audio_frame_size_bytes, silence_or_noise); + } + else { + *silence_or_noise = tsk_false; + return 0; + } } int tmedia_denoise_process_playback(tmedia_denoise_t* self, void* audio_frame, uint32_t audio_frame_size_bytes) { - if(!self || !self->plugin){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - - if(!self->opened){ - TSK_DEBUG_ERROR("Denoiser not opened"); - return -2; - } - - if(self->plugin->process_playback){ - return self->plugin->process_playback(self, audio_frame, audio_frame_size_bytes); - } - return 0; + if(!self || !self->plugin) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + + if(!self->opened) { + TSK_DEBUG_ERROR("Denoiser not opened"); + return -2; + } + + if(self->plugin->process_playback) { + return self->plugin->process_playback(self, audio_frame, audio_frame_size_bytes); + } + return 0; } int tmedia_denoise_close(tmedia_denoise_t* self) { - if(!self || !self->plugin){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - if(!self->opened){ - return 0; - } - - if(self->plugin->close){ - int ret; - - if((ret = self->plugin->close(self))){ - TSK_DEBUG_ERROR("Failed to close [%s] denoiser", self->plugin->desc); - return ret; - } - else{ - self->opened = tsk_false; - return 0; - } - } - else{ - self->opened = tsk_false; - return 0; - } + if(!self || !self->plugin) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + if(!self->opened) { + return 0; + } + + if(self->plugin->close) { + int ret; + + if((ret = self->plugin->close(self))) { + TSK_DEBUG_ERROR("Failed to close [%s] denoiser", self->plugin->desc); + return ret; + } + else { + self->opened = tsk_false; + return 0; + } + } + else { + self->opened = tsk_false; + return 0; + } } int tmedia_denoise_deinit(tmedia_denoise_t* self) { - if (!self) { - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - - if (self->opened) { - tmedia_denoise_close(self); - } - - TSK_OBJECT_SAFE_FREE(self->record_frame); - TSK_OBJECT_SAFE_FREE(self->playback_frame); - - return 0; + if (!self) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + + if (self->opened) { + tmedia_denoise_close(self); + } + + TSK_OBJECT_SAFE_FREE(self->record_frame); + TSK_OBJECT_SAFE_FREE(self->playback_frame); + + return 0; } int tmedia_denoise_plugin_register(const tmedia_denoise_plugin_def_t* plugin) { - if(!plugin){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - if(!__tmedia_denoise_plugin) { - TSK_DEBUG_INFO("Register denoiser: %s", plugin->desc); - __tmedia_denoise_plugin = plugin; - } - return 0; + if(!plugin) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + if(!__tmedia_denoise_plugin) { + TSK_DEBUG_INFO("Register denoiser: %s", plugin->desc); + __tmedia_denoise_plugin = plugin; + } + return 0; } int tmedia_denoise_plugin_unregister(const tmedia_denoise_plugin_def_t* plugin) { - (void)(plugin); - __tmedia_denoise_plugin = tsk_null; - return 0; + (void)(plugin); + __tmedia_denoise_plugin = tsk_null; + return 0; } tmedia_denoise_t* tmedia_denoise_create() { - tmedia_denoise_t* denoise = tsk_null; - - if(__tmedia_denoise_plugin){ - if((denoise = tsk_object_new(__tmedia_denoise_plugin->objdef))){ - denoise->plugin = __tmedia_denoise_plugin; - } - } - return denoise; + tmedia_denoise_t* denoise = tsk_null; + + if(__tmedia_denoise_plugin) { + if((denoise = tsk_object_new(__tmedia_denoise_plugin->objdef))) { + denoise->plugin = __tmedia_denoise_plugin; + } + } + return denoise; } diff --git a/tinyMEDIA/src/tmedia_imageattr.c b/tinyMEDIA/src/tmedia_imageattr.c index 07440c4..9cc3543 100755 --- a/tinyMEDIA/src/tmedia_imageattr.c +++ b/tinyMEDIA/src/tmedia_imageattr.c @@ -2,19 +2,19 @@ /* #line 1 "./ragel/tmedia_imageattr.rl" */ /* * Copyright (C) 2012-2015 Doubango Telecom <http://www.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. * @@ -39,916 +39,952 @@ static int tmedia_imageattr_reset(tmedia_imageattr_xt* self) { - if(self){ - tsk_size_t i; - memset(self, 0, sizeof(*self)); - for(i = 0; i < TMEDIA_imageattr_ARRAY_MAX_SIZE; ++i){ - self->send.sets[i].qvalue = 0.5; - self->recv.sets[i].qvalue = 0.5; - } - return 0; - } - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; + if(self) { + tsk_size_t i; + memset(self, 0, sizeof(*self)); + for(i = 0; i < TMEDIA_imageattr_ARRAY_MAX_SIZE; ++i) { + self->send.sets[i].qvalue = 0.5; + self->recv.sets[i].qvalue = 0.5; + } + return 0; + } + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; } int tmedia_imageattr_parse(tmedia_imageattr_xt* self, const void* in_data, tsk_size_t in_size) { - int cs = 0; - const char *p = in_data; - const char *pe = p + in_size; - const char *eof = pe; - - const char *tag_start = tsk_null; - - tmedia_imageattr_set_xt* sets = tsk_null; - tsk_size_t* sets_count = tsk_null; - tmedia_imageattr_xyrange_xt* xyrange = tsk_null; - tmedia_imageattr_srange_xt* srange = tsk_null; - - TSK_RAGEL_DISABLE_WARNINGS_BEGIN() - -/* #line 72 "./src/tmedia_imageattr.c" */ -static const char _tmedia_machine_imageattr_actions[] = { - 0, 1, 0, 1, 1, 1, 2, 1, - 3, 1, 4, 1, 5, 1, 6, 1, - 7, 1, 8, 1, 9, 1, 10, 1, - 11, 1, 12, 1, 13, 1, 14, 1, - 15, 1, 16, 1, 17, 1, 18, 1, - 19, 1, 20, 2, 3, 0, 2, 4, - 0, 2, 6, 11, 2, 15, 0, 2, - 16, 13 -}; - -static const short _tmedia_machine_imageattr_key_offsets[] = { - 0, 0, 6, 8, 10, 12, 14, 18, - 20, 22, 24, 26, 30, 32, 33, 36, - 39, 41, 42, 45, 49, 55, 57, 59, - 60, 61, 64, 65, 67, 70, 73, 74, - 76, 79, 82, 85, 86, 88, 91, 92, - 94, 97, 100, 101, 102, 104, 105, 107, - 108, 110, 114, 116, 117, 118, 121, 123, - 125, 126, 130, 131, 133, 137, 141, 145, - 147, 148, 150, 153, 154, 156, 160, 163, - 164, 166, 170, 174, 178, 180, 182, 183, - 185, 188, 189, 191, 194, 197, 200, 201, - 203, 204, 206, 210, 214, 216, 217, 219, - 223, 227, 231, 235, 237, 239, 243, 245, - 249, 253, 257, 261, 265, 267, 269, 273, - 277, 281, 285, 287, 289, 293, 297, 301, - 305, 309, 311, 313, 316, 319, 322, 325, - 328, 329, 331, 334, 337, 340, 343, 344, - 346, 350, 352, 356, 360, 364, 368, 372, - 374, 375, 379, 383, 387, 391, 393, 395, - 399, 403, 407, 411, 415, 417, 419, 422, - 425, 428, 431, 434, 435, 436, 438, 440, - 442, 444, 446, 447, 450, 453, 455, 456, - 459, 463, 469, 471, 473, 474, 475, 478, - 479, 481, 484, 487, 488, 490, 493, 496, - 499, 500, 502, 503, 505, 508, 511, 512, - 513, 515, 516, 518, 519, 521, 525, 527, - 528, 529, 532, 534, 536, 537, 541, 542, - 544, 548, 552, 556, 558, 559, 561, 564, - 565, 567, 571, 574, 575, 577, 581, 585, - 589, 591, 593, 594, 596, 599, 600, 602, - 605, 608, 611, 612, 614, 615, 617, 621, - 625, 627, 628, 630, 634, 638, 642, 646, - 648, 650, 654, 656, 660, 664, 668, 672, - 676, 678, 680, 684, 688, 692, 696, 698, - 700, 704, 708, 712, 716, 720, 722, 724, - 727, 730, 733, 736, 739, 740, 742, 745, - 748, 751, 754, 755, 757, 761, 763, 767, - 771, 775, 779, 783, 785, 786, 790, 794, - 798, 802, 804, 806, 810, 814, 818, 822, - 826, 828, 830, 833, 836, 839, 842, 845, - 846, 847, 849, 851, 853, 855, 861, 861, - 863, 869 -}; - -static const char _tmedia_machine_imageattr_trans_keys[] = { - 9, 32, 82, 83, 114, 115, 69, 101, - 67, 99, 86, 118, 9, 32, 9, 32, - 42, 91, 69, 101, 67, 99, 86, 118, - 9, 32, 9, 32, 42, 91, 88, 120, - 61, 91, 49, 57, 44, 48, 57, 89, - 121, 61, 91, 49, 57, 44, 93, 48, - 57, 80, 81, 83, 112, 113, 115, 65, - 97, 82, 114, 61, 91, 48, 49, 57, - 46, 49, 57, 45, 48, 57, 48, 49, - 57, 46, 49, 57, 93, 48, 57, 93, - 48, 57, 93, 48, 57, 93, 44, 93, - 9, 32, 91, 46, 48, 57, 45, 48, - 57, 45, 48, 57, 45, 46, 48, 57, - 61, 48, 49, 46, 48, 57, 44, 93, - 48, 57, 44, 93, 46, 48, 44, 48, - 93, 65, 97, 82, 114, 61, 48, 91, - 49, 57, 46, 49, 57, 44, 93, 48, - 57, 44, 93, 48, 57, 44, 93, 48, - 57, 44, 93, 46, 48, 57, 48, 49, - 57, 46, 49, 57, 44, 45, 48, 57, - 48, 49, 57, 46, 49, 57, 44, 93, - 48, 57, 44, 93, 48, 57, 44, 93, - 48, 57, 44, 93, 44, 93, 46, 48, - 57, 48, 49, 57, 46, 49, 57, 93, - 48, 57, 93, 48, 57, 93, 48, 57, - 93, 44, 93, 46, 48, 57, 44, 45, - 48, 57, 44, 45, 48, 57, 44, 45, - 46, 48, 57, 44, 93, 48, 57, 44, - 93, 48, 57, 44, 93, 48, 57, 44, - 93, 48, 57, 44, 93, 49, 57, 44, - 58, 48, 57, 49, 57, 44, 93, 48, - 57, 44, 93, 48, 57, 44, 93, 48, - 57, 44, 93, 48, 57, 44, 93, 48, - 57, 44, 93, 44, 93, 44, 58, 48, - 57, 44, 58, 48, 57, 44, 58, 48, - 57, 44, 58, 48, 57, 44, 58, 49, - 57, 58, 93, 48, 57, 58, 93, 48, - 57, 58, 93, 48, 57, 58, 93, 48, - 57, 58, 93, 48, 57, 58, 93, 49, - 57, 93, 48, 57, 93, 48, 57, 93, - 48, 57, 93, 48, 57, 93, 48, 57, - 93, 44, 93, 44, 48, 57, 44, 48, - 57, 44, 48, 57, 44, 48, 57, 44, - 49, 57, 44, 58, 48, 57, 49, 57, - 44, 93, 48, 57, 44, 93, 48, 57, - 44, 93, 48, 57, 44, 93, 48, 57, - 44, 93, 48, 57, 44, 93, 44, 44, - 58, 48, 57, 44, 58, 48, 57, 44, - 58, 48, 57, 44, 58, 48, 57, 44, - 58, 49, 57, 58, 93, 48, 57, 58, - 93, 48, 57, 58, 93, 48, 57, 58, - 93, 48, 57, 58, 93, 48, 57, 58, - 93, 49, 57, 93, 48, 57, 93, 48, - 57, 93, 48, 57, 93, 48, 57, 93, - 48, 57, 93, 44, 69, 101, 78, 110, - 68, 100, 9, 32, 88, 120, 61, 91, - 49, 57, 44, 48, 57, 89, 121, 61, - 91, 49, 57, 44, 93, 48, 57, 80, - 81, 83, 112, 113, 115, 65, 97, 82, - 114, 61, 91, 48, 49, 57, 46, 49, - 57, 45, 48, 57, 48, 49, 57, 46, - 49, 57, 93, 48, 57, 93, 48, 57, - 93, 48, 57, 93, 44, 93, 46, 48, - 57, 45, 48, 57, 45, 48, 57, 45, - 46, 48, 57, 61, 48, 49, 46, 48, - 57, 44, 93, 48, 57, 44, 93, 46, - 48, 44, 48, 93, 65, 97, 82, 114, - 61, 48, 91, 49, 57, 46, 49, 57, - 44, 93, 48, 57, 44, 93, 48, 57, - 44, 93, 48, 57, 44, 93, 46, 48, - 57, 48, 49, 57, 46, 49, 57, 44, - 45, 48, 57, 48, 49, 57, 46, 49, - 57, 44, 93, 48, 57, 44, 93, 48, - 57, 44, 93, 48, 57, 44, 93, 44, - 93, 46, 48, 57, 48, 49, 57, 46, - 49, 57, 93, 48, 57, 93, 48, 57, - 93, 48, 57, 93, 44, 93, 46, 48, - 57, 44, 45, 48, 57, 44, 45, 48, - 57, 44, 45, 46, 48, 57, 44, 93, - 48, 57, 44, 93, 48, 57, 44, 93, - 48, 57, 44, 93, 48, 57, 44, 93, - 49, 57, 44, 58, 48, 57, 49, 57, - 44, 93, 48, 57, 44, 93, 48, 57, - 44, 93, 48, 57, 44, 93, 48, 57, - 44, 93, 48, 57, 44, 93, 44, 93, - 44, 58, 48, 57, 44, 58, 48, 57, - 44, 58, 48, 57, 44, 58, 48, 57, - 44, 58, 49, 57, 58, 93, 48, 57, - 58, 93, 48, 57, 58, 93, 48, 57, - 58, 93, 48, 57, 58, 93, 48, 57, - 58, 93, 49, 57, 93, 48, 57, 93, - 48, 57, 93, 48, 57, 93, 48, 57, - 93, 48, 57, 93, 44, 93, 44, 48, - 57, 44, 48, 57, 44, 48, 57, 44, - 48, 57, 44, 49, 57, 44, 58, 48, - 57, 49, 57, 44, 93, 48, 57, 44, - 93, 48, 57, 44, 93, 48, 57, 44, - 93, 48, 57, 44, 93, 48, 57, 44, - 93, 44, 44, 58, 48, 57, 44, 58, - 48, 57, 44, 58, 48, 57, 44, 58, - 48, 57, 44, 58, 49, 57, 58, 93, - 48, 57, 58, 93, 48, 57, 58, 93, - 48, 57, 58, 93, 48, 57, 58, 93, - 48, 57, 58, 93, 49, 57, 93, 48, - 57, 93, 48, 57, 93, 48, 57, 93, - 48, 57, 93, 48, 57, 93, 44, 69, - 101, 78, 110, 68, 100, 9, 32, 9, - 32, 82, 83, 114, 115, 9, 32, 9, - 32, 82, 83, 114, 115, 9, 32, 82, - 83, 91, 114, 115, 0 -}; - -static const char _tmedia_machine_imageattr_single_lengths[] = { - 0, 6, 2, 2, 2, 2, 4, 2, - 2, 2, 2, 4, 2, 1, 1, 1, - 2, 1, 1, 2, 6, 2, 2, 1, - 1, 1, 1, 0, 1, 1, 1, 0, - 1, 1, 1, 1, 2, 3, 1, 0, - 1, 1, 1, 1, 0, 1, 2, 1, - 0, 2, 2, 1, 1, 3, 2, 2, - 1, 2, 1, 0, 2, 2, 2, 2, - 1, 0, 1, 1, 0, 2, 1, 1, - 0, 2, 2, 2, 2, 2, 1, 0, - 1, 1, 0, 1, 1, 1, 1, 2, - 1, 0, 2, 2, 2, 1, 0, 2, - 2, 2, 2, 2, 0, 2, 0, 2, - 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 0, 2, 2, 2, 2, - 2, 2, 0, 1, 1, 1, 1, 1, - 1, 2, 1, 1, 1, 1, 1, 0, - 2, 0, 2, 2, 2, 2, 2, 2, - 1, 2, 2, 2, 2, 2, 0, 2, - 2, 2, 2, 2, 2, 0, 1, 1, - 1, 1, 1, 1, 1, 2, 2, 2, - 2, 2, 1, 1, 1, 2, 1, 1, - 2, 6, 2, 2, 1, 1, 1, 1, - 0, 1, 1, 1, 0, 1, 1, 1, - 1, 2, 1, 0, 1, 1, 1, 1, - 0, 1, 2, 1, 0, 2, 2, 1, - 1, 3, 2, 2, 1, 2, 1, 0, - 2, 2, 2, 2, 1, 0, 1, 1, - 0, 2, 1, 1, 0, 2, 2, 2, - 2, 2, 1, 0, 1, 1, 0, 1, - 1, 1, 1, 2, 1, 0, 2, 2, - 2, 1, 0, 2, 2, 2, 2, 2, - 0, 2, 0, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 0, - 2, 2, 2, 2, 2, 2, 0, 1, - 1, 1, 1, 1, 1, 2, 1, 1, - 1, 1, 1, 0, 2, 0, 2, 2, - 2, 2, 2, 2, 1, 2, 2, 2, - 2, 2, 0, 2, 2, 2, 2, 2, - 2, 0, 1, 1, 1, 1, 1, 1, - 1, 2, 2, 2, 2, 6, 0, 2, - 6, 7 -}; - -static const char _tmedia_machine_imageattr_range_lengths[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 1, - 0, 0, 1, 1, 0, 0, 0, 0, - 0, 1, 0, 1, 1, 1, 0, 1, - 1, 1, 1, 0, 0, 0, 0, 1, - 1, 1, 0, 0, 1, 0, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 1, 1, 1, 1, 0, - 0, 1, 1, 0, 1, 1, 1, 0, - 1, 1, 1, 1, 0, 0, 0, 1, - 1, 0, 1, 1, 1, 1, 0, 0, - 0, 1, 1, 1, 0, 0, 1, 1, - 1, 1, 1, 0, 1, 1, 1, 1, - 1, 1, 1, 1, 0, 0, 1, 1, - 1, 1, 0, 1, 1, 1, 1, 1, - 1, 0, 1, 1, 1, 1, 1, 1, - 0, 0, 1, 1, 1, 1, 0, 1, - 1, 1, 1, 1, 1, 1, 1, 0, - 0, 1, 1, 1, 1, 0, 1, 1, - 1, 1, 1, 1, 0, 1, 1, 1, - 1, 1, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 1, - 1, 0, 0, 0, 0, 0, 1, 0, - 1, 1, 1, 0, 1, 1, 1, 1, - 0, 0, 0, 1, 1, 1, 0, 0, - 1, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 1, 0, 1, - 1, 1, 1, 0, 0, 1, 1, 0, - 1, 1, 1, 0, 1, 1, 1, 1, - 0, 0, 0, 1, 1, 0, 1, 1, - 1, 1, 0, 0, 0, 1, 1, 1, - 0, 0, 1, 1, 1, 1, 1, 0, - 1, 1, 1, 1, 1, 1, 1, 1, - 0, 0, 1, 1, 1, 1, 0, 1, - 1, 1, 1, 1, 1, 0, 1, 1, - 1, 1, 1, 1, 0, 0, 1, 1, - 1, 1, 0, 1, 1, 1, 1, 1, - 1, 1, 1, 0, 0, 1, 1, 1, - 1, 0, 1, 1, 1, 1, 1, 1, - 0, 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0 -}; - -static const short _tmedia_machine_imageattr_index_offsets[] = { - 0, 0, 7, 10, 13, 16, 19, 24, - 27, 30, 33, 36, 41, 44, 46, 49, - 52, 55, 57, 60, 64, 71, 74, 77, - 79, 81, 84, 86, 88, 91, 94, 96, - 98, 101, 104, 107, 109, 112, 116, 118, - 120, 123, 126, 128, 130, 132, 134, 137, - 139, 141, 145, 148, 150, 152, 156, 159, - 162, 164, 168, 170, 172, 176, 180, 184, - 187, 189, 191, 194, 196, 198, 202, 205, - 207, 209, 213, 217, 221, 224, 227, 229, - 231, 234, 236, 238, 241, 244, 247, 249, - 252, 254, 256, 260, 264, 267, 269, 271, - 275, 279, 283, 287, 290, 292, 296, 298, - 302, 306, 310, 314, 318, 321, 324, 328, - 332, 336, 340, 343, 345, 349, 353, 357, - 361, 365, 368, 370, 373, 376, 379, 382, - 385, 387, 390, 393, 396, 399, 402, 404, - 406, 410, 412, 416, 420, 424, 428, 432, - 435, 437, 441, 445, 449, 453, 456, 458, - 462, 466, 470, 474, 478, 481, 483, 486, - 489, 492, 495, 498, 500, 502, 505, 508, - 511, 514, 517, 519, 522, 525, 528, 530, - 533, 537, 544, 547, 550, 552, 554, 557, - 559, 561, 564, 567, 569, 571, 574, 577, - 580, 582, 585, 587, 589, 592, 595, 597, - 599, 601, 603, 606, 608, 610, 614, 617, - 619, 621, 625, 628, 631, 633, 637, 639, - 641, 645, 649, 653, 656, 658, 660, 663, - 665, 667, 671, 674, 676, 678, 682, 686, - 690, 693, 696, 698, 700, 703, 705, 707, - 710, 713, 716, 718, 721, 723, 725, 729, - 733, 736, 738, 740, 744, 748, 752, 756, - 759, 761, 765, 767, 771, 775, 779, 783, - 787, 790, 793, 797, 801, 805, 809, 812, - 814, 818, 822, 826, 830, 834, 837, 839, - 842, 845, 848, 851, 854, 856, 859, 862, - 865, 868, 871, 873, 875, 879, 881, 885, - 889, 893, 897, 901, 904, 906, 910, 914, - 918, 922, 925, 927, 931, 935, 939, 943, - 947, 950, 952, 955, 958, 961, 964, 967, - 969, 971, 974, 977, 980, 983, 990, 991, - 994, 1001 -}; - -static const short _tmedia_machine_imageattr_trans_targs[] = { - 1, 1, 2, 321, 2, 321, 0, 3, - 3, 0, 4, 4, 0, 5, 5, 0, - 6, 6, 0, 6, 6, 325, 169, 0, - 8, 8, 0, 9, 9, 0, 10, 10, - 0, 11, 11, 0, 11, 11, 326, 12, - 0, 13, 13, 0, 14, 0, 135, 15, - 0, 16, 130, 0, 17, 17, 0, 18, - 0, 100, 19, 0, 20, 327, 95, 0, - 21, 45, 54, 21, 45, 54, 0, 22, - 22, 0, 23, 23, 0, 24, 0, 25, - 0, 26, 43, 0, 27, 0, 28, 0, - 29, 40, 0, 30, 38, 0, 31, 0, - 32, 0, 36, 33, 0, 36, 34, 0, - 36, 35, 0, 36, 0, 20, 327, 0, - 37, 37, 12, 0, 39, 0, 32, 0, - 29, 41, 0, 29, 42, 0, 29, 0, - 44, 0, 28, 0, 46, 0, 47, 51, - 0, 48, 0, 49, 0, 20, 327, 50, - 0, 20, 327, 0, 52, 0, 53, 0, - 20, 50, 327, 0, 55, 55, 0, 56, - 56, 0, 57, 0, 58, 66, 64, 0, - 59, 0, 60, 0, 20, 327, 61, 0, - 20, 327, 62, 0, 20, 327, 63, 0, - 20, 327, 0, 65, 0, 60, 0, 67, - 93, 0, 68, 0, 69, 0, 70, 80, - 90, 0, 71, 78, 0, 72, 0, 73, - 0, 70, 77, 74, 0, 70, 77, 75, - 0, 70, 77, 76, 0, 70, 77, 0, - 20, 327, 0, 79, 0, 73, 0, 81, - 88, 0, 82, 0, 83, 0, 87, 84, - 0, 87, 85, 0, 87, 86, 0, 87, - 0, 20, 327, 0, 89, 0, 83, 0, - 70, 80, 91, 0, 70, 80, 92, 0, - 70, 80, 0, 94, 0, 69, 0, 20, - 327, 96, 0, 20, 327, 97, 0, 20, - 327, 98, 0, 20, 327, 99, 0, 20, - 327, 0, 101, 0, 102, 115, 110, 0, - 103, 0, 102, 109, 104, 0, 102, 109, - 105, 0, 102, 109, 106, 0, 102, 109, - 107, 0, 102, 109, 108, 0, 102, 109, - 0, 20, 327, 0, 102, 115, 111, 0, - 102, 115, 112, 0, 102, 115, 113, 0, - 102, 115, 114, 0, 102, 115, 0, 116, - 0, 122, 129, 117, 0, 122, 129, 118, - 0, 122, 129, 119, 0, 122, 129, 120, - 0, 122, 129, 121, 0, 122, 129, 0, - 123, 0, 129, 124, 0, 129, 125, 0, - 129, 126, 0, 129, 127, 0, 129, 128, - 0, 129, 0, 20, 327, 0, 16, 131, - 0, 16, 132, 0, 16, 133, 0, 16, - 134, 0, 16, 0, 136, 0, 137, 150, - 145, 0, 138, 0, 137, 144, 139, 0, - 137, 144, 140, 0, 137, 144, 141, 0, - 137, 144, 142, 0, 137, 144, 143, 0, - 137, 144, 0, 16, 0, 137, 150, 146, - 0, 137, 150, 147, 0, 137, 150, 148, - 0, 137, 150, 149, 0, 137, 150, 0, - 151, 0, 157, 164, 152, 0, 157, 164, - 153, 0, 157, 164, 154, 0, 157, 164, - 155, 0, 157, 164, 156, 0, 157, 164, - 0, 158, 0, 164, 159, 0, 164, 160, - 0, 164, 161, 0, 164, 162, 0, 164, - 163, 0, 164, 0, 16, 0, 166, 166, - 0, 167, 167, 0, 168, 168, 0, 11, - 11, 0, 170, 170, 0, 171, 0, 291, - 172, 0, 173, 286, 0, 174, 174, 0, - 175, 0, 256, 176, 0, 177, 328, 251, - 0, 178, 201, 210, 178, 201, 210, 0, - 179, 179, 0, 180, 180, 0, 181, 0, - 182, 0, 183, 199, 0, 184, 0, 185, - 0, 186, 196, 0, 187, 194, 0, 188, - 0, 189, 0, 193, 190, 0, 193, 191, - 0, 193, 192, 0, 193, 0, 177, 328, - 0, 195, 0, 189, 0, 186, 197, 0, - 186, 198, 0, 186, 0, 200, 0, 185, - 0, 202, 0, 203, 207, 0, 204, 0, - 205, 0, 177, 328, 206, 0, 177, 328, - 0, 208, 0, 209, 0, 177, 206, 328, - 0, 211, 211, 0, 212, 212, 0, 213, - 0, 214, 222, 220, 0, 215, 0, 216, - 0, 177, 328, 217, 0, 177, 328, 218, - 0, 177, 328, 219, 0, 177, 328, 0, - 221, 0, 216, 0, 223, 249, 0, 224, - 0, 225, 0, 226, 236, 246, 0, 227, - 234, 0, 228, 0, 229, 0, 226, 233, - 230, 0, 226, 233, 231, 0, 226, 233, - 232, 0, 226, 233, 0, 177, 328, 0, - 235, 0, 229, 0, 237, 244, 0, 238, - 0, 239, 0, 243, 240, 0, 243, 241, - 0, 243, 242, 0, 243, 0, 177, 328, - 0, 245, 0, 239, 0, 226, 236, 247, - 0, 226, 236, 248, 0, 226, 236, 0, - 250, 0, 225, 0, 177, 328, 252, 0, - 177, 328, 253, 0, 177, 328, 254, 0, - 177, 328, 255, 0, 177, 328, 0, 257, - 0, 258, 271, 266, 0, 259, 0, 258, - 265, 260, 0, 258, 265, 261, 0, 258, - 265, 262, 0, 258, 265, 263, 0, 258, - 265, 264, 0, 258, 265, 0, 177, 328, - 0, 258, 271, 267, 0, 258, 271, 268, - 0, 258, 271, 269, 0, 258, 271, 270, - 0, 258, 271, 0, 272, 0, 278, 285, - 273, 0, 278, 285, 274, 0, 278, 285, - 275, 0, 278, 285, 276, 0, 278, 285, - 277, 0, 278, 285, 0, 279, 0, 285, - 280, 0, 285, 281, 0, 285, 282, 0, - 285, 283, 0, 285, 284, 0, 285, 0, - 177, 328, 0, 173, 287, 0, 173, 288, - 0, 173, 289, 0, 173, 290, 0, 173, - 0, 292, 0, 293, 306, 301, 0, 294, - 0, 293, 300, 295, 0, 293, 300, 296, - 0, 293, 300, 297, 0, 293, 300, 298, - 0, 293, 300, 299, 0, 293, 300, 0, - 173, 0, 293, 306, 302, 0, 293, 306, - 303, 0, 293, 306, 304, 0, 293, 306, - 305, 0, 293, 306, 0, 307, 0, 313, - 320, 308, 0, 313, 320, 309, 0, 313, - 320, 310, 0, 313, 320, 311, 0, 313, - 320, 312, 0, 313, 320, 0, 314, 0, - 320, 315, 0, 320, 316, 0, 320, 317, - 0, 320, 318, 0, 320, 319, 0, 320, - 0, 173, 0, 322, 322, 0, 323, 323, - 0, 324, 324, 0, 6, 6, 0, 325, - 325, 7, 165, 7, 165, 0, 0, 37, - 37, 0, 329, 329, 7, 165, 7, 165, - 0, 329, 329, 7, 165, 169, 7, 165, - 0, 0 -}; - -static const char _tmedia_machine_imageattr_trans_actions[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 5, 5, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 5, 5, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 7, 43, - 0, 49, 0, 0, 0, 0, 0, 0, - 0, 9, 46, 0, 49, 49, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, 0, - 39, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 41, 0, 0, 41, 0, 0, - 41, 0, 0, 41, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 39, 0, 0, 39, 0, 0, 39, 0, - 0, 0, 0, 0, 0, 0, 1, 1, - 0, 0, 0, 0, 0, 25, 25, 0, - 0, 25, 25, 0, 0, 0, 0, 0, - 25, 0, 25, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 52, 31, 52, 0, - 0, 0, 0, 0, 55, 55, 0, 0, - 55, 55, 0, 0, 55, 55, 0, 0, - 55, 55, 0, 0, 0, 0, 0, 1, - 1, 0, 0, 0, 0, 0, 33, 35, - 0, 0, 1, 1, 0, 0, 0, 0, - 0, 33, 33, 0, 0, 33, 33, 0, - 0, 33, 33, 0, 0, 33, 33, 0, - 27, 27, 0, 0, 0, 0, 0, 1, - 1, 0, 0, 0, 0, 0, 37, 0, - 0, 37, 0, 0, 37, 0, 0, 37, - 0, 29, 29, 0, 0, 0, 0, 0, - 33, 35, 0, 0, 33, 35, 0, 0, - 33, 35, 0, 0, 0, 0, 0, 49, - 49, 0, 0, 49, 49, 0, 0, 49, - 49, 0, 0, 49, 49, 0, 0, 49, - 49, 0, 1, 0, 23, 17, 0, 0, - 1, 0, 23, 23, 0, 0, 23, 23, - 0, 0, 23, 23, 0, 0, 23, 23, - 0, 0, 23, 23, 0, 0, 23, 23, - 0, 13, 13, 0, 23, 17, 0, 0, - 23, 17, 0, 0, 23, 17, 0, 0, - 23, 17, 0, 0, 23, 17, 0, 1, - 0, 19, 21, 0, 0, 19, 21, 0, - 0, 19, 21, 0, 0, 19, 21, 0, - 0, 19, 21, 0, 0, 19, 21, 0, - 1, 0, 21, 0, 0, 21, 0, 0, - 21, 0, 0, 21, 0, 0, 21, 0, - 0, 21, 0, 15, 15, 0, 49, 0, - 0, 49, 0, 0, 49, 0, 0, 49, - 0, 0, 49, 0, 1, 0, 23, 17, - 0, 0, 1, 0, 23, 23, 0, 0, - 23, 23, 0, 0, 23, 23, 0, 0, - 23, 23, 0, 0, 23, 23, 0, 0, - 23, 23, 0, 13, 0, 23, 17, 0, - 0, 23, 17, 0, 0, 23, 17, 0, - 0, 23, 17, 0, 0, 23, 17, 0, - 1, 0, 19, 21, 0, 0, 19, 21, - 0, 0, 19, 21, 0, 0, 19, 21, - 0, 0, 19, 21, 0, 0, 19, 21, - 0, 1, 0, 21, 0, 0, 21, 0, - 0, 21, 0, 0, 21, 0, 0, 21, - 0, 0, 21, 0, 15, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 3, - 3, 0, 0, 0, 0, 0, 0, 7, - 43, 0, 49, 0, 0, 0, 0, 0, - 0, 0, 9, 46, 0, 49, 49, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, - 0, 39, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 41, 0, 0, 41, 0, - 0, 41, 0, 0, 41, 0, 0, 0, - 0, 0, 0, 0, 0, 39, 0, 0, - 39, 0, 0, 39, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 25, 25, 0, 0, 25, 25, - 0, 0, 0, 0, 0, 25, 0, 25, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 52, 31, 52, 0, 0, 0, 0, - 0, 55, 55, 0, 0, 55, 55, 0, - 0, 55, 55, 0, 0, 55, 55, 0, - 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 33, 35, 0, 0, 1, - 1, 0, 0, 0, 0, 0, 33, 33, - 0, 0, 33, 33, 0, 0, 33, 33, - 0, 0, 33, 33, 0, 27, 27, 0, - 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 37, 0, 0, 37, 0, - 0, 37, 0, 0, 37, 0, 29, 29, - 0, 0, 0, 0, 0, 33, 35, 0, - 0, 33, 35, 0, 0, 33, 35, 0, - 0, 0, 0, 0, 49, 49, 0, 0, - 49, 49, 0, 0, 49, 49, 0, 0, - 49, 49, 0, 0, 49, 49, 0, 1, - 0, 23, 17, 0, 0, 1, 0, 23, - 23, 0, 0, 23, 23, 0, 0, 23, - 23, 0, 0, 23, 23, 0, 0, 23, - 23, 0, 0, 23, 23, 0, 13, 13, - 0, 23, 17, 0, 0, 23, 17, 0, - 0, 23, 17, 0, 0, 23, 17, 0, - 0, 23, 17, 0, 1, 0, 19, 21, - 0, 0, 19, 21, 0, 0, 19, 21, - 0, 0, 19, 21, 0, 0, 19, 21, - 0, 0, 19, 21, 0, 1, 0, 21, - 0, 0, 21, 0, 0, 21, 0, 0, - 21, 0, 0, 21, 0, 0, 21, 0, - 15, 15, 0, 49, 0, 0, 49, 0, - 0, 49, 0, 0, 49, 0, 0, 49, - 0, 1, 0, 23, 17, 0, 0, 1, - 0, 23, 23, 0, 0, 23, 23, 0, - 0, 23, 23, 0, 0, 23, 23, 0, - 0, 23, 23, 0, 0, 23, 23, 0, - 13, 0, 23, 17, 0, 0, 23, 17, - 0, 0, 23, 17, 0, 0, 23, 17, - 0, 0, 23, 17, 0, 1, 0, 19, - 21, 0, 0, 19, 21, 0, 0, 19, - 21, 0, 0, 19, 21, 0, 0, 19, - 21, 0, 0, 19, 21, 0, 1, 0, - 21, 0, 0, 21, 0, 0, 21, 0, - 0, 21, 0, 0, 21, 0, 0, 21, - 0, 15, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 3, 3, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 11, - 11, 0, 11, 11, 11, 11, 11, 11, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0 -}; - -static const char _tmedia_machine_imageattr_eof_actions[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 11, - 11, 0 -}; - -static const int tmedia_machine_imageattr_start = 1; -static const int tmedia_machine_imageattr_first_final = 325; -static const int tmedia_machine_imageattr_error = 0; - -static const int tmedia_machine_imageattr_en_main = 1; - - -/* #line 168 "./ragel/tmedia_imageattr.rl" */ - (void)(eof); - (void)(tmedia_machine_imageattr_first_final); - (void)(tmedia_machine_imageattr_error); - (void)(tmedia_machine_imageattr_en_main); - -/* #line 695 "./src/tmedia_imageattr.c" */ - { - cs = tmedia_machine_imageattr_start; - } - -/* #line 173 "./ragel/tmedia_imageattr.rl" */ - tmedia_imageattr_reset(self); - -/* #line 703 "./src/tmedia_imageattr.c" */ - { - int _klen; - unsigned int _trans; - const char *_acts; - unsigned int _nacts; - const char *_keys; - - if ( p == pe ) - goto _test_eof; - if ( cs == 0 ) - goto _out; + int cs = 0; + const char *p = in_data; + const char *pe = p + in_size; + const char *eof = pe; + + const char *tag_start = tsk_null; + + tmedia_imageattr_set_xt* sets = tsk_null; + tsk_size_t* sets_count = tsk_null; + tmedia_imageattr_xyrange_xt* xyrange = tsk_null; + tmedia_imageattr_srange_xt* srange = tsk_null; + + TSK_RAGEL_DISABLE_WARNINGS_BEGIN() + + /* #line 72 "./src/tmedia_imageattr.c" */ + static const char _tmedia_machine_imageattr_actions[] = { + 0, 1, 0, 1, 1, 1, 2, 1, + 3, 1, 4, 1, 5, 1, 6, 1, + 7, 1, 8, 1, 9, 1, 10, 1, + 11, 1, 12, 1, 13, 1, 14, 1, + 15, 1, 16, 1, 17, 1, 18, 1, + 19, 1, 20, 2, 3, 0, 2, 4, + 0, 2, 6, 11, 2, 15, 0, 2, + 16, 13 + }; + + static const short _tmedia_machine_imageattr_key_offsets[] = { + 0, 0, 6, 8, 10, 12, 14, 18, + 20, 22, 24, 26, 30, 32, 33, 36, + 39, 41, 42, 45, 49, 55, 57, 59, + 60, 61, 64, 65, 67, 70, 73, 74, + 76, 79, 82, 85, 86, 88, 91, 92, + 94, 97, 100, 101, 102, 104, 105, 107, + 108, 110, 114, 116, 117, 118, 121, 123, + 125, 126, 130, 131, 133, 137, 141, 145, + 147, 148, 150, 153, 154, 156, 160, 163, + 164, 166, 170, 174, 178, 180, 182, 183, + 185, 188, 189, 191, 194, 197, 200, 201, + 203, 204, 206, 210, 214, 216, 217, 219, + 223, 227, 231, 235, 237, 239, 243, 245, + 249, 253, 257, 261, 265, 267, 269, 273, + 277, 281, 285, 287, 289, 293, 297, 301, + 305, 309, 311, 313, 316, 319, 322, 325, + 328, 329, 331, 334, 337, 340, 343, 344, + 346, 350, 352, 356, 360, 364, 368, 372, + 374, 375, 379, 383, 387, 391, 393, 395, + 399, 403, 407, 411, 415, 417, 419, 422, + 425, 428, 431, 434, 435, 436, 438, 440, + 442, 444, 446, 447, 450, 453, 455, 456, + 459, 463, 469, 471, 473, 474, 475, 478, + 479, 481, 484, 487, 488, 490, 493, 496, + 499, 500, 502, 503, 505, 508, 511, 512, + 513, 515, 516, 518, 519, 521, 525, 527, + 528, 529, 532, 534, 536, 537, 541, 542, + 544, 548, 552, 556, 558, 559, 561, 564, + 565, 567, 571, 574, 575, 577, 581, 585, + 589, 591, 593, 594, 596, 599, 600, 602, + 605, 608, 611, 612, 614, 615, 617, 621, + 625, 627, 628, 630, 634, 638, 642, 646, + 648, 650, 654, 656, 660, 664, 668, 672, + 676, 678, 680, 684, 688, 692, 696, 698, + 700, 704, 708, 712, 716, 720, 722, 724, + 727, 730, 733, 736, 739, 740, 742, 745, + 748, 751, 754, 755, 757, 761, 763, 767, + 771, 775, 779, 783, 785, 786, 790, 794, + 798, 802, 804, 806, 810, 814, 818, 822, + 826, 828, 830, 833, 836, 839, 842, 845, + 846, 847, 849, 851, 853, 855, 861, 861, + 863, 869 + }; + + static const char _tmedia_machine_imageattr_trans_keys[] = { + 9, 32, 82, 83, 114, 115, 69, 101, + 67, 99, 86, 118, 9, 32, 9, 32, + 42, 91, 69, 101, 67, 99, 86, 118, + 9, 32, 9, 32, 42, 91, 88, 120, + 61, 91, 49, 57, 44, 48, 57, 89, + 121, 61, 91, 49, 57, 44, 93, 48, + 57, 80, 81, 83, 112, 113, 115, 65, + 97, 82, 114, 61, 91, 48, 49, 57, + 46, 49, 57, 45, 48, 57, 48, 49, + 57, 46, 49, 57, 93, 48, 57, 93, + 48, 57, 93, 48, 57, 93, 44, 93, + 9, 32, 91, 46, 48, 57, 45, 48, + 57, 45, 48, 57, 45, 46, 48, 57, + 61, 48, 49, 46, 48, 57, 44, 93, + 48, 57, 44, 93, 46, 48, 44, 48, + 93, 65, 97, 82, 114, 61, 48, 91, + 49, 57, 46, 49, 57, 44, 93, 48, + 57, 44, 93, 48, 57, 44, 93, 48, + 57, 44, 93, 46, 48, 57, 48, 49, + 57, 46, 49, 57, 44, 45, 48, 57, + 48, 49, 57, 46, 49, 57, 44, 93, + 48, 57, 44, 93, 48, 57, 44, 93, + 48, 57, 44, 93, 44, 93, 46, 48, + 57, 48, 49, 57, 46, 49, 57, 93, + 48, 57, 93, 48, 57, 93, 48, 57, + 93, 44, 93, 46, 48, 57, 44, 45, + 48, 57, 44, 45, 48, 57, 44, 45, + 46, 48, 57, 44, 93, 48, 57, 44, + 93, 48, 57, 44, 93, 48, 57, 44, + 93, 48, 57, 44, 93, 49, 57, 44, + 58, 48, 57, 49, 57, 44, 93, 48, + 57, 44, 93, 48, 57, 44, 93, 48, + 57, 44, 93, 48, 57, 44, 93, 48, + 57, 44, 93, 44, 93, 44, 58, 48, + 57, 44, 58, 48, 57, 44, 58, 48, + 57, 44, 58, 48, 57, 44, 58, 49, + 57, 58, 93, 48, 57, 58, 93, 48, + 57, 58, 93, 48, 57, 58, 93, 48, + 57, 58, 93, 48, 57, 58, 93, 49, + 57, 93, 48, 57, 93, 48, 57, 93, + 48, 57, 93, 48, 57, 93, 48, 57, + 93, 44, 93, 44, 48, 57, 44, 48, + 57, 44, 48, 57, 44, 48, 57, 44, + 49, 57, 44, 58, 48, 57, 49, 57, + 44, 93, 48, 57, 44, 93, 48, 57, + 44, 93, 48, 57, 44, 93, 48, 57, + 44, 93, 48, 57, 44, 93, 44, 44, + 58, 48, 57, 44, 58, 48, 57, 44, + 58, 48, 57, 44, 58, 48, 57, 44, + 58, 49, 57, 58, 93, 48, 57, 58, + 93, 48, 57, 58, 93, 48, 57, 58, + 93, 48, 57, 58, 93, 48, 57, 58, + 93, 49, 57, 93, 48, 57, 93, 48, + 57, 93, 48, 57, 93, 48, 57, 93, + 48, 57, 93, 44, 69, 101, 78, 110, + 68, 100, 9, 32, 88, 120, 61, 91, + 49, 57, 44, 48, 57, 89, 121, 61, + 91, 49, 57, 44, 93, 48, 57, 80, + 81, 83, 112, 113, 115, 65, 97, 82, + 114, 61, 91, 48, 49, 57, 46, 49, + 57, 45, 48, 57, 48, 49, 57, 46, + 49, 57, 93, 48, 57, 93, 48, 57, + 93, 48, 57, 93, 44, 93, 46, 48, + 57, 45, 48, 57, 45, 48, 57, 45, + 46, 48, 57, 61, 48, 49, 46, 48, + 57, 44, 93, 48, 57, 44, 93, 46, + 48, 44, 48, 93, 65, 97, 82, 114, + 61, 48, 91, 49, 57, 46, 49, 57, + 44, 93, 48, 57, 44, 93, 48, 57, + 44, 93, 48, 57, 44, 93, 46, 48, + 57, 48, 49, 57, 46, 49, 57, 44, + 45, 48, 57, 48, 49, 57, 46, 49, + 57, 44, 93, 48, 57, 44, 93, 48, + 57, 44, 93, 48, 57, 44, 93, 44, + 93, 46, 48, 57, 48, 49, 57, 46, + 49, 57, 93, 48, 57, 93, 48, 57, + 93, 48, 57, 93, 44, 93, 46, 48, + 57, 44, 45, 48, 57, 44, 45, 48, + 57, 44, 45, 46, 48, 57, 44, 93, + 48, 57, 44, 93, 48, 57, 44, 93, + 48, 57, 44, 93, 48, 57, 44, 93, + 49, 57, 44, 58, 48, 57, 49, 57, + 44, 93, 48, 57, 44, 93, 48, 57, + 44, 93, 48, 57, 44, 93, 48, 57, + 44, 93, 48, 57, 44, 93, 44, 93, + 44, 58, 48, 57, 44, 58, 48, 57, + 44, 58, 48, 57, 44, 58, 48, 57, + 44, 58, 49, 57, 58, 93, 48, 57, + 58, 93, 48, 57, 58, 93, 48, 57, + 58, 93, 48, 57, 58, 93, 48, 57, + 58, 93, 49, 57, 93, 48, 57, 93, + 48, 57, 93, 48, 57, 93, 48, 57, + 93, 48, 57, 93, 44, 93, 44, 48, + 57, 44, 48, 57, 44, 48, 57, 44, + 48, 57, 44, 49, 57, 44, 58, 48, + 57, 49, 57, 44, 93, 48, 57, 44, + 93, 48, 57, 44, 93, 48, 57, 44, + 93, 48, 57, 44, 93, 48, 57, 44, + 93, 44, 44, 58, 48, 57, 44, 58, + 48, 57, 44, 58, 48, 57, 44, 58, + 48, 57, 44, 58, 49, 57, 58, 93, + 48, 57, 58, 93, 48, 57, 58, 93, + 48, 57, 58, 93, 48, 57, 58, 93, + 48, 57, 58, 93, 49, 57, 93, 48, + 57, 93, 48, 57, 93, 48, 57, 93, + 48, 57, 93, 48, 57, 93, 44, 69, + 101, 78, 110, 68, 100, 9, 32, 9, + 32, 82, 83, 114, 115, 9, 32, 9, + 32, 82, 83, 114, 115, 9, 32, 82, + 83, 91, 114, 115, 0 + }; + + static const char _tmedia_machine_imageattr_single_lengths[] = { + 0, 6, 2, 2, 2, 2, 4, 2, + 2, 2, 2, 4, 2, 1, 1, 1, + 2, 1, 1, 2, 6, 2, 2, 1, + 1, 1, 1, 0, 1, 1, 1, 0, + 1, 1, 1, 1, 2, 3, 1, 0, + 1, 1, 1, 1, 0, 1, 2, 1, + 0, 2, 2, 1, 1, 3, 2, 2, + 1, 2, 1, 0, 2, 2, 2, 2, + 1, 0, 1, 1, 0, 2, 1, 1, + 0, 2, 2, 2, 2, 2, 1, 0, + 1, 1, 0, 1, 1, 1, 1, 2, + 1, 0, 2, 2, 2, 1, 0, 2, + 2, 2, 2, 2, 0, 2, 0, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 0, 2, 2, 2, 2, + 2, 2, 0, 1, 1, 1, 1, 1, + 1, 2, 1, 1, 1, 1, 1, 0, + 2, 0, 2, 2, 2, 2, 2, 2, + 1, 2, 2, 2, 2, 2, 0, 2, + 2, 2, 2, 2, 2, 0, 1, 1, + 1, 1, 1, 1, 1, 2, 2, 2, + 2, 2, 1, 1, 1, 2, 1, 1, + 2, 6, 2, 2, 1, 1, 1, 1, + 0, 1, 1, 1, 0, 1, 1, 1, + 1, 2, 1, 0, 1, 1, 1, 1, + 0, 1, 2, 1, 0, 2, 2, 1, + 1, 3, 2, 2, 1, 2, 1, 0, + 2, 2, 2, 2, 1, 0, 1, 1, + 0, 2, 1, 1, 0, 2, 2, 2, + 2, 2, 1, 0, 1, 1, 0, 1, + 1, 1, 1, 2, 1, 0, 2, 2, + 2, 1, 0, 2, 2, 2, 2, 2, + 0, 2, 0, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 0, + 2, 2, 2, 2, 2, 2, 0, 1, + 1, 1, 1, 1, 1, 2, 1, 1, + 1, 1, 1, 0, 2, 0, 2, 2, + 2, 2, 2, 2, 1, 2, 2, 2, + 2, 2, 0, 2, 2, 2, 2, 2, + 2, 0, 1, 1, 1, 1, 1, 1, + 1, 2, 2, 2, 2, 6, 0, 2, + 6, 7 + }; + + static const char _tmedia_machine_imageattr_range_lengths[] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 1, + 0, 0, 1, 1, 0, 0, 0, 0, + 0, 1, 0, 1, 1, 1, 0, 1, + 1, 1, 1, 0, 0, 0, 0, 1, + 1, 1, 0, 0, 1, 0, 0, 0, + 1, 1, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 1, 1, 1, 1, 0, + 0, 1, 1, 0, 1, 1, 1, 0, + 1, 1, 1, 1, 0, 0, 0, 1, + 1, 0, 1, 1, 1, 1, 0, 0, + 0, 1, 1, 1, 0, 0, 1, 1, + 1, 1, 1, 0, 1, 1, 1, 1, + 1, 1, 1, 1, 0, 0, 1, 1, + 1, 1, 0, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 1, + 0, 0, 1, 1, 1, 1, 0, 1, + 1, 1, 1, 1, 1, 1, 1, 0, + 0, 1, 1, 1, 1, 0, 1, 1, + 1, 1, 1, 1, 0, 1, 1, 1, + 1, 1, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 1, + 1, 0, 0, 0, 0, 0, 1, 0, + 1, 1, 1, 0, 1, 1, 1, 1, + 0, 0, 0, 1, 1, 1, 0, 0, + 1, 0, 0, 0, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 1, 0, 1, + 1, 1, 1, 0, 0, 1, 1, 0, + 1, 1, 1, 0, 1, 1, 1, 1, + 0, 0, 0, 1, 1, 0, 1, 1, + 1, 1, 0, 0, 0, 1, 1, 1, + 0, 0, 1, 1, 1, 1, 1, 0, + 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 1, 1, 1, 1, 0, 1, + 1, 1, 1, 1, 1, 0, 1, 1, + 1, 1, 1, 1, 0, 0, 1, 1, + 1, 1, 0, 1, 1, 1, 1, 1, + 1, 1, 1, 0, 0, 1, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 1, + 0, 1, 1, 1, 1, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0 + }; + + static const short _tmedia_machine_imageattr_index_offsets[] = { + 0, 0, 7, 10, 13, 16, 19, 24, + 27, 30, 33, 36, 41, 44, 46, 49, + 52, 55, 57, 60, 64, 71, 74, 77, + 79, 81, 84, 86, 88, 91, 94, 96, + 98, 101, 104, 107, 109, 112, 116, 118, + 120, 123, 126, 128, 130, 132, 134, 137, + 139, 141, 145, 148, 150, 152, 156, 159, + 162, 164, 168, 170, 172, 176, 180, 184, + 187, 189, 191, 194, 196, 198, 202, 205, + 207, 209, 213, 217, 221, 224, 227, 229, + 231, 234, 236, 238, 241, 244, 247, 249, + 252, 254, 256, 260, 264, 267, 269, 271, + 275, 279, 283, 287, 290, 292, 296, 298, + 302, 306, 310, 314, 318, 321, 324, 328, + 332, 336, 340, 343, 345, 349, 353, 357, + 361, 365, 368, 370, 373, 376, 379, 382, + 385, 387, 390, 393, 396, 399, 402, 404, + 406, 410, 412, 416, 420, 424, 428, 432, + 435, 437, 441, 445, 449, 453, 456, 458, + 462, 466, 470, 474, 478, 481, 483, 486, + 489, 492, 495, 498, 500, 502, 505, 508, + 511, 514, 517, 519, 522, 525, 528, 530, + 533, 537, 544, 547, 550, 552, 554, 557, + 559, 561, 564, 567, 569, 571, 574, 577, + 580, 582, 585, 587, 589, 592, 595, 597, + 599, 601, 603, 606, 608, 610, 614, 617, + 619, 621, 625, 628, 631, 633, 637, 639, + 641, 645, 649, 653, 656, 658, 660, 663, + 665, 667, 671, 674, 676, 678, 682, 686, + 690, 693, 696, 698, 700, 703, 705, 707, + 710, 713, 716, 718, 721, 723, 725, 729, + 733, 736, 738, 740, 744, 748, 752, 756, + 759, 761, 765, 767, 771, 775, 779, 783, + 787, 790, 793, 797, 801, 805, 809, 812, + 814, 818, 822, 826, 830, 834, 837, 839, + 842, 845, 848, 851, 854, 856, 859, 862, + 865, 868, 871, 873, 875, 879, 881, 885, + 889, 893, 897, 901, 904, 906, 910, 914, + 918, 922, 925, 927, 931, 935, 939, 943, + 947, 950, 952, 955, 958, 961, 964, 967, + 969, 971, 974, 977, 980, 983, 990, 991, + 994, 1001 + }; + + static const short _tmedia_machine_imageattr_trans_targs[] = { + 1, 1, 2, 321, 2, 321, 0, 3, + 3, 0, 4, 4, 0, 5, 5, 0, + 6, 6, 0, 6, 6, 325, 169, 0, + 8, 8, 0, 9, 9, 0, 10, 10, + 0, 11, 11, 0, 11, 11, 326, 12, + 0, 13, 13, 0, 14, 0, 135, 15, + 0, 16, 130, 0, 17, 17, 0, 18, + 0, 100, 19, 0, 20, 327, 95, 0, + 21, 45, 54, 21, 45, 54, 0, 22, + 22, 0, 23, 23, 0, 24, 0, 25, + 0, 26, 43, 0, 27, 0, 28, 0, + 29, 40, 0, 30, 38, 0, 31, 0, + 32, 0, 36, 33, 0, 36, 34, 0, + 36, 35, 0, 36, 0, 20, 327, 0, + 37, 37, 12, 0, 39, 0, 32, 0, + 29, 41, 0, 29, 42, 0, 29, 0, + 44, 0, 28, 0, 46, 0, 47, 51, + 0, 48, 0, 49, 0, 20, 327, 50, + 0, 20, 327, 0, 52, 0, 53, 0, + 20, 50, 327, 0, 55, 55, 0, 56, + 56, 0, 57, 0, 58, 66, 64, 0, + 59, 0, 60, 0, 20, 327, 61, 0, + 20, 327, 62, 0, 20, 327, 63, 0, + 20, 327, 0, 65, 0, 60, 0, 67, + 93, 0, 68, 0, 69, 0, 70, 80, + 90, 0, 71, 78, 0, 72, 0, 73, + 0, 70, 77, 74, 0, 70, 77, 75, + 0, 70, 77, 76, 0, 70, 77, 0, + 20, 327, 0, 79, 0, 73, 0, 81, + 88, 0, 82, 0, 83, 0, 87, 84, + 0, 87, 85, 0, 87, 86, 0, 87, + 0, 20, 327, 0, 89, 0, 83, 0, + 70, 80, 91, 0, 70, 80, 92, 0, + 70, 80, 0, 94, 0, 69, 0, 20, + 327, 96, 0, 20, 327, 97, 0, 20, + 327, 98, 0, 20, 327, 99, 0, 20, + 327, 0, 101, 0, 102, 115, 110, 0, + 103, 0, 102, 109, 104, 0, 102, 109, + 105, 0, 102, 109, 106, 0, 102, 109, + 107, 0, 102, 109, 108, 0, 102, 109, + 0, 20, 327, 0, 102, 115, 111, 0, + 102, 115, 112, 0, 102, 115, 113, 0, + 102, 115, 114, 0, 102, 115, 0, 116, + 0, 122, 129, 117, 0, 122, 129, 118, + 0, 122, 129, 119, 0, 122, 129, 120, + 0, 122, 129, 121, 0, 122, 129, 0, + 123, 0, 129, 124, 0, 129, 125, 0, + 129, 126, 0, 129, 127, 0, 129, 128, + 0, 129, 0, 20, 327, 0, 16, 131, + 0, 16, 132, 0, 16, 133, 0, 16, + 134, 0, 16, 0, 136, 0, 137, 150, + 145, 0, 138, 0, 137, 144, 139, 0, + 137, 144, 140, 0, 137, 144, 141, 0, + 137, 144, 142, 0, 137, 144, 143, 0, + 137, 144, 0, 16, 0, 137, 150, 146, + 0, 137, 150, 147, 0, 137, 150, 148, + 0, 137, 150, 149, 0, 137, 150, 0, + 151, 0, 157, 164, 152, 0, 157, 164, + 153, 0, 157, 164, 154, 0, 157, 164, + 155, 0, 157, 164, 156, 0, 157, 164, + 0, 158, 0, 164, 159, 0, 164, 160, + 0, 164, 161, 0, 164, 162, 0, 164, + 163, 0, 164, 0, 16, 0, 166, 166, + 0, 167, 167, 0, 168, 168, 0, 11, + 11, 0, 170, 170, 0, 171, 0, 291, + 172, 0, 173, 286, 0, 174, 174, 0, + 175, 0, 256, 176, 0, 177, 328, 251, + 0, 178, 201, 210, 178, 201, 210, 0, + 179, 179, 0, 180, 180, 0, 181, 0, + 182, 0, 183, 199, 0, 184, 0, 185, + 0, 186, 196, 0, 187, 194, 0, 188, + 0, 189, 0, 193, 190, 0, 193, 191, + 0, 193, 192, 0, 193, 0, 177, 328, + 0, 195, 0, 189, 0, 186, 197, 0, + 186, 198, 0, 186, 0, 200, 0, 185, + 0, 202, 0, 203, 207, 0, 204, 0, + 205, 0, 177, 328, 206, 0, 177, 328, + 0, 208, 0, 209, 0, 177, 206, 328, + 0, 211, 211, 0, 212, 212, 0, 213, + 0, 214, 222, 220, 0, 215, 0, 216, + 0, 177, 328, 217, 0, 177, 328, 218, + 0, 177, 328, 219, 0, 177, 328, 0, + 221, 0, 216, 0, 223, 249, 0, 224, + 0, 225, 0, 226, 236, 246, 0, 227, + 234, 0, 228, 0, 229, 0, 226, 233, + 230, 0, 226, 233, 231, 0, 226, 233, + 232, 0, 226, 233, 0, 177, 328, 0, + 235, 0, 229, 0, 237, 244, 0, 238, + 0, 239, 0, 243, 240, 0, 243, 241, + 0, 243, 242, 0, 243, 0, 177, 328, + 0, 245, 0, 239, 0, 226, 236, 247, + 0, 226, 236, 248, 0, 226, 236, 0, + 250, 0, 225, 0, 177, 328, 252, 0, + 177, 328, 253, 0, 177, 328, 254, 0, + 177, 328, 255, 0, 177, 328, 0, 257, + 0, 258, 271, 266, 0, 259, 0, 258, + 265, 260, 0, 258, 265, 261, 0, 258, + 265, 262, 0, 258, 265, 263, 0, 258, + 265, 264, 0, 258, 265, 0, 177, 328, + 0, 258, 271, 267, 0, 258, 271, 268, + 0, 258, 271, 269, 0, 258, 271, 270, + 0, 258, 271, 0, 272, 0, 278, 285, + 273, 0, 278, 285, 274, 0, 278, 285, + 275, 0, 278, 285, 276, 0, 278, 285, + 277, 0, 278, 285, 0, 279, 0, 285, + 280, 0, 285, 281, 0, 285, 282, 0, + 285, 283, 0, 285, 284, 0, 285, 0, + 177, 328, 0, 173, 287, 0, 173, 288, + 0, 173, 289, 0, 173, 290, 0, 173, + 0, 292, 0, 293, 306, 301, 0, 294, + 0, 293, 300, 295, 0, 293, 300, 296, + 0, 293, 300, 297, 0, 293, 300, 298, + 0, 293, 300, 299, 0, 293, 300, 0, + 173, 0, 293, 306, 302, 0, 293, 306, + 303, 0, 293, 306, 304, 0, 293, 306, + 305, 0, 293, 306, 0, 307, 0, 313, + 320, 308, 0, 313, 320, 309, 0, 313, + 320, 310, 0, 313, 320, 311, 0, 313, + 320, 312, 0, 313, 320, 0, 314, 0, + 320, 315, 0, 320, 316, 0, 320, 317, + 0, 320, 318, 0, 320, 319, 0, 320, + 0, 173, 0, 322, 322, 0, 323, 323, + 0, 324, 324, 0, 6, 6, 0, 325, + 325, 7, 165, 7, 165, 0, 0, 37, + 37, 0, 329, 329, 7, 165, 7, 165, + 0, 329, 329, 7, 165, 169, 7, 165, + 0, 0 + }; + + static const char _tmedia_machine_imageattr_trans_actions[] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 5, 5, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 5, 5, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 7, 43, + 0, 49, 0, 0, 0, 0, 0, 0, + 0, 9, 46, 0, 49, 49, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 0, 0, 0, 0, 0, + 39, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 41, 0, 0, 41, 0, 0, + 41, 0, 0, 41, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 39, 0, 0, 39, 0, 0, 39, 0, + 0, 0, 0, 0, 0, 0, 1, 1, + 0, 0, 0, 0, 0, 25, 25, 0, + 0, 25, 25, 0, 0, 0, 0, 0, + 25, 0, 25, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 52, 31, 52, 0, + 0, 0, 0, 0, 55, 55, 0, 0, + 55, 55, 0, 0, 55, 55, 0, 0, + 55, 55, 0, 0, 0, 0, 0, 1, + 1, 0, 0, 0, 0, 0, 33, 35, + 0, 0, 1, 1, 0, 0, 0, 0, + 0, 33, 33, 0, 0, 33, 33, 0, + 0, 33, 33, 0, 0, 33, 33, 0, + 27, 27, 0, 0, 0, 0, 0, 1, + 1, 0, 0, 0, 0, 0, 37, 0, + 0, 37, 0, 0, 37, 0, 0, 37, + 0, 29, 29, 0, 0, 0, 0, 0, + 33, 35, 0, 0, 33, 35, 0, 0, + 33, 35, 0, 0, 0, 0, 0, 49, + 49, 0, 0, 49, 49, 0, 0, 49, + 49, 0, 0, 49, 49, 0, 0, 49, + 49, 0, 1, 0, 23, 17, 0, 0, + 1, 0, 23, 23, 0, 0, 23, 23, + 0, 0, 23, 23, 0, 0, 23, 23, + 0, 0, 23, 23, 0, 0, 23, 23, + 0, 13, 13, 0, 23, 17, 0, 0, + 23, 17, 0, 0, 23, 17, 0, 0, + 23, 17, 0, 0, 23, 17, 0, 1, + 0, 19, 21, 0, 0, 19, 21, 0, + 0, 19, 21, 0, 0, 19, 21, 0, + 0, 19, 21, 0, 0, 19, 21, 0, + 1, 0, 21, 0, 0, 21, 0, 0, + 21, 0, 0, 21, 0, 0, 21, 0, + 0, 21, 0, 15, 15, 0, 49, 0, + 0, 49, 0, 0, 49, 0, 0, 49, + 0, 0, 49, 0, 1, 0, 23, 17, + 0, 0, 1, 0, 23, 23, 0, 0, + 23, 23, 0, 0, 23, 23, 0, 0, + 23, 23, 0, 0, 23, 23, 0, 0, + 23, 23, 0, 13, 0, 23, 17, 0, + 0, 23, 17, 0, 0, 23, 17, 0, + 0, 23, 17, 0, 0, 23, 17, 0, + 1, 0, 19, 21, 0, 0, 19, 21, + 0, 0, 19, 21, 0, 0, 19, 21, + 0, 0, 19, 21, 0, 0, 19, 21, + 0, 1, 0, 21, 0, 0, 21, 0, + 0, 21, 0, 0, 21, 0, 0, 21, + 0, 0, 21, 0, 15, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 3, + 3, 0, 0, 0, 0, 0, 0, 7, + 43, 0, 49, 0, 0, 0, 0, 0, + 0, 0, 9, 46, 0, 49, 49, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 1, 0, 0, 0, 0, + 0, 39, 0, 0, 1, 1, 0, 0, + 0, 0, 0, 41, 0, 0, 41, 0, + 0, 41, 0, 0, 41, 0, 0, 0, + 0, 0, 0, 0, 0, 39, 0, 0, + 39, 0, 0, 39, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 25, 25, 0, 0, 25, 25, + 0, 0, 0, 0, 0, 25, 0, 25, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 52, 31, 52, 0, 0, 0, 0, + 0, 55, 55, 0, 0, 55, 55, 0, + 0, 55, 55, 0, 0, 55, 55, 0, + 0, 0, 0, 0, 1, 1, 0, 0, + 0, 0, 0, 33, 35, 0, 0, 1, + 1, 0, 0, 0, 0, 0, 33, 33, + 0, 0, 33, 33, 0, 0, 33, 33, + 0, 0, 33, 33, 0, 27, 27, 0, + 0, 0, 0, 0, 1, 1, 0, 0, + 0, 0, 0, 37, 0, 0, 37, 0, + 0, 37, 0, 0, 37, 0, 29, 29, + 0, 0, 0, 0, 0, 33, 35, 0, + 0, 33, 35, 0, 0, 33, 35, 0, + 0, 0, 0, 0, 49, 49, 0, 0, + 49, 49, 0, 0, 49, 49, 0, 0, + 49, 49, 0, 0, 49, 49, 0, 1, + 0, 23, 17, 0, 0, 1, 0, 23, + 23, 0, 0, 23, 23, 0, 0, 23, + 23, 0, 0, 23, 23, 0, 0, 23, + 23, 0, 0, 23, 23, 0, 13, 13, + 0, 23, 17, 0, 0, 23, 17, 0, + 0, 23, 17, 0, 0, 23, 17, 0, + 0, 23, 17, 0, 1, 0, 19, 21, + 0, 0, 19, 21, 0, 0, 19, 21, + 0, 0, 19, 21, 0, 0, 19, 21, + 0, 0, 19, 21, 0, 1, 0, 21, + 0, 0, 21, 0, 0, 21, 0, 0, + 21, 0, 0, 21, 0, 0, 21, 0, + 15, 15, 0, 49, 0, 0, 49, 0, + 0, 49, 0, 0, 49, 0, 0, 49, + 0, 1, 0, 23, 17, 0, 0, 1, + 0, 23, 23, 0, 0, 23, 23, 0, + 0, 23, 23, 0, 0, 23, 23, 0, + 0, 23, 23, 0, 0, 23, 23, 0, + 13, 0, 23, 17, 0, 0, 23, 17, + 0, 0, 23, 17, 0, 0, 23, 17, + 0, 0, 23, 17, 0, 1, 0, 19, + 21, 0, 0, 19, 21, 0, 0, 19, + 21, 0, 0, 19, 21, 0, 0, 19, + 21, 0, 0, 19, 21, 0, 1, 0, + 21, 0, 0, 21, 0, 0, 21, 0, + 0, 21, 0, 0, 21, 0, 0, 21, + 0, 15, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 11, + 11, 0, 11, 11, 11, 11, 11, 11, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0 + }; + + static const char _tmedia_machine_imageattr_eof_actions[] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 11, + 11, 0 + }; + + static const int tmedia_machine_imageattr_start = 1; + static const int tmedia_machine_imageattr_first_final = 325; + static const int tmedia_machine_imageattr_error = 0; + + static const int tmedia_machine_imageattr_en_main = 1; + + + /* #line 168 "./ragel/tmedia_imageattr.rl" */ + (void)(eof); + (void)(tmedia_machine_imageattr_first_final); + (void)(tmedia_machine_imageattr_error); + (void)(tmedia_machine_imageattr_en_main); + + /* #line 695 "./src/tmedia_imageattr.c" */ + { + cs = tmedia_machine_imageattr_start; + } + + /* #line 173 "./ragel/tmedia_imageattr.rl" */ + tmedia_imageattr_reset(self); + + /* #line 703 "./src/tmedia_imageattr.c" */ + { + int _klen; + unsigned int _trans; + const char *_acts; + unsigned int _nacts; + const char *_keys; + + if ( p == pe ) { + goto _test_eof; + } + if ( cs == 0 ) { + goto _out; + } _resume: - _keys = _tmedia_machine_imageattr_trans_keys + _tmedia_machine_imageattr_key_offsets[cs]; - _trans = _tmedia_machine_imageattr_index_offsets[cs]; - - _klen = _tmedia_machine_imageattr_single_lengths[cs]; - if ( _klen > 0 ) { - const char *_lower = _keys; - const char *_mid; - const char *_upper = _keys + _klen - 1; - while (1) { - if ( _upper < _lower ) - break; - - _mid = _lower + ((_upper-_lower) >> 1); - if ( (*p) < *_mid ) - _upper = _mid - 1; - else if ( (*p) > *_mid ) - _lower = _mid + 1; - else { - _trans += (_mid - _keys); - goto _match; - } - } - _keys += _klen; - _trans += _klen; - } - - _klen = _tmedia_machine_imageattr_range_lengths[cs]; - if ( _klen > 0 ) { - const char *_lower = _keys; - const char *_mid; - const char *_upper = _keys + (_klen<<1) - 2; - while (1) { - if ( _upper < _lower ) - break; - - _mid = _lower + (((_upper-_lower) >> 1) & ~1); - if ( (*p) < _mid[0] ) - _upper = _mid - 2; - else if ( (*p) > _mid[1] ) - _lower = _mid + 2; - else { - _trans += ((_mid - _keys)>>1); - goto _match; - } - } - _trans += _klen; - } + _keys = _tmedia_machine_imageattr_trans_keys + _tmedia_machine_imageattr_key_offsets[cs]; + _trans = _tmedia_machine_imageattr_index_offsets[cs]; + + _klen = _tmedia_machine_imageattr_single_lengths[cs]; + if ( _klen > 0 ) { + const char *_lower = _keys; + const char *_mid; + const char *_upper = _keys + _klen - 1; + while (1) { + if ( _upper < _lower ) { + break; + } + + _mid = _lower + ((_upper-_lower) >> 1); + if ( (*p) < *_mid ) { + _upper = _mid - 1; + } + else if ( (*p) > *_mid ) { + _lower = _mid + 1; + } + else { + _trans += (_mid - _keys); + goto _match; + } + } + _keys += _klen; + _trans += _klen; + } + + _klen = _tmedia_machine_imageattr_range_lengths[cs]; + if ( _klen > 0 ) { + const char *_lower = _keys; + const char *_mid; + const char *_upper = _keys + (_klen<<1) - 2; + while (1) { + if ( _upper < _lower ) { + break; + } + + _mid = _lower + (((_upper-_lower) >> 1) & ~1); + if ( (*p) < _mid[0] ) { + _upper = _mid - 2; + } + else if ( (*p) > _mid[1] ) { + _lower = _mid + 2; + } + else { + _trans += ((_mid - _keys)>>1); + goto _match; + } + } + _trans += _klen; + } _match: - cs = _tmedia_machine_imageattr_trans_targs[_trans]; - - if ( _tmedia_machine_imageattr_trans_actions[_trans] == 0 ) - goto _again; - - _acts = _tmedia_machine_imageattr_actions + _tmedia_machine_imageattr_trans_actions[_trans]; - _nacts = (unsigned int) *_acts++; - while ( _nacts-- > 0 ) - { - switch ( *_acts++ ) - { - case 0: -/* #line 40 "./ragel/tmedia_imageattr.rl" */ - { - tag_start = p; - } - break; - case 1: -/* #line 44 "./ragel/tmedia_imageattr.rl" */ - { - sets = &self->send.sets[0]; - sets_count = &self->send.count; - *sets_count = 0; - } - break; - case 2: -/* #line 50 "./ragel/tmedia_imageattr.rl" */ - { - sets = &self->recv.sets[0]; - sets_count = &self->recv.count; - *sets_count = 0; - } - break; - case 3: -/* #line 56 "./ragel/tmedia_imageattr.rl" */ - { - xyrange = (*sets_count < TMEDIA_imageattr_ARRAY_MAX_SIZE) ? &sets[*sets_count].xrange : tsk_null; - } - break; - case 4: -/* #line 59 "./ragel/tmedia_imageattr.rl" */ - { - xyrange = (*sets_count < TMEDIA_imageattr_ARRAY_MAX_SIZE) ? &sets[*sets_count].yrange : tsk_null; - } - break; - case 5: -/* #line 62 "./ragel/tmedia_imageattr.rl" */ - { - if(*sets_count < TMEDIA_imageattr_ARRAY_MAX_SIZE) (*sets_count)++; - } - break; - case 6: -/* #line 65 "./ragel/tmedia_imageattr.rl" */ - { - if(xyrange) xyrange->is_range = 0; - } - break; - case 7: -/* #line 68 "./ragel/tmedia_imageattr.rl" */ - { - if(xyrange) xyrange->is_range = 1; - } - break; - case 8: -/* #line 71 "./ragel/tmedia_imageattr.rl" */ - { - if(xyrange)xyrange->range.start = atoi(tag_start); - } - break; - case 9: -/* #line 74 "./ragel/tmedia_imageattr.rl" */ - { - if(xyrange)xyrange->range.step = atoi(tag_start); - } - break; - case 10: -/* #line 77 "./ragel/tmedia_imageattr.rl" */ - { - if(xyrange)xyrange->range.end = atoi(tag_start); - } - break; - case 11: -/* #line 80 "./ragel/tmedia_imageattr.rl" */ - { - if(xyrange && xyrange->array.count < TMEDIA_imageattr_ARRAY_MAX_SIZE){ - xyrange->array.values[xyrange->array.count++] = atoi(tag_start); - } - } - break; - case 12: -/* #line 85 "./ragel/tmedia_imageattr.rl" */ - { - if(*sets_count < TMEDIA_imageattr_ARRAY_MAX_SIZE){ - sets[*sets_count].qvalue = atof(tag_start); - } - } - break; - case 13: -/* #line 91 "./ragel/tmedia_imageattr.rl" */ - { - if(srange) srange->is_range = 0; - } - break; - case 14: -/* #line 94 "./ragel/tmedia_imageattr.rl" */ - { - if(srange) srange->is_range = 1; - } - break; - case 15: -/* #line 97 "./ragel/tmedia_imageattr.rl" */ - { - srange = (*sets_count < TMEDIA_imageattr_ARRAY_MAX_SIZE) ? &sets[*sets_count].srange : tsk_null; - } - break; - case 16: -/* #line 100 "./ragel/tmedia_imageattr.rl" */ - { - if(srange && srange->array.count < TMEDIA_imageattr_ARRAY_MAX_SIZE){ - srange->array.values[srange->array.count++] = atof(tag_start); - } - } - break; - case 17: -/* #line 105 "./ragel/tmedia_imageattr.rl" */ - { - if(srange) srange->range.start = atof(tag_start); - } - break; - case 18: -/* #line 108 "./ragel/tmedia_imageattr.rl" */ - { - if(srange) srange->range.end = atof(tag_start); - } - break; - case 19: -/* #line 112 "./ragel/tmedia_imageattr.rl" */ - { - if(*sets_count < TMEDIA_imageattr_ARRAY_MAX_SIZE) sets[*sets_count].prange.start = atof(tag_start); - } - break; - case 20: -/* #line 115 "./ragel/tmedia_imageattr.rl" */ - { - if(*sets_count < TMEDIA_imageattr_ARRAY_MAX_SIZE) sets[*sets_count].prange.end = atof(tag_start), sets[*sets_count].prange.is_present = 1; - } - break; -/* #line 912 "./src/tmedia_imageattr.c" */ - } - } + cs = _tmedia_machine_imageattr_trans_targs[_trans]; + + if ( _tmedia_machine_imageattr_trans_actions[_trans] == 0 ) { + goto _again; + } + + _acts = _tmedia_machine_imageattr_actions + _tmedia_machine_imageattr_trans_actions[_trans]; + _nacts = (unsigned int) *_acts++; + while ( _nacts-- > 0 ) { + switch ( *_acts++ ) { + case 0: + /* #line 40 "./ragel/tmedia_imageattr.rl" */ + { + tag_start = p; + } + break; + case 1: + /* #line 44 "./ragel/tmedia_imageattr.rl" */ + { + sets = &self->send.sets[0]; + sets_count = &self->send.count; + *sets_count = 0; + } + break; + case 2: + /* #line 50 "./ragel/tmedia_imageattr.rl" */ + { + sets = &self->recv.sets[0]; + sets_count = &self->recv.count; + *sets_count = 0; + } + break; + case 3: + /* #line 56 "./ragel/tmedia_imageattr.rl" */ + { + xyrange = (*sets_count < TMEDIA_imageattr_ARRAY_MAX_SIZE) ? &sets[*sets_count].xrange : tsk_null; + } + break; + case 4: + /* #line 59 "./ragel/tmedia_imageattr.rl" */ + { + xyrange = (*sets_count < TMEDIA_imageattr_ARRAY_MAX_SIZE) ? &sets[*sets_count].yrange : tsk_null; + } + break; + case 5: + /* #line 62 "./ragel/tmedia_imageattr.rl" */ + { + if(*sets_count < TMEDIA_imageattr_ARRAY_MAX_SIZE) { + (*sets_count)++; + } + } + break; + case 6: + /* #line 65 "./ragel/tmedia_imageattr.rl" */ + { + if(xyrange) { + xyrange->is_range = 0; + } + } + break; + case 7: + /* #line 68 "./ragel/tmedia_imageattr.rl" */ + { + if(xyrange) { + xyrange->is_range = 1; + } + } + break; + case 8: + /* #line 71 "./ragel/tmedia_imageattr.rl" */ + { + if(xyrange) { + xyrange->range.start = atoi(tag_start); + } + } + break; + case 9: + /* #line 74 "./ragel/tmedia_imageattr.rl" */ + { + if(xyrange) { + xyrange->range.step = atoi(tag_start); + } + } + break; + case 10: + /* #line 77 "./ragel/tmedia_imageattr.rl" */ + { + if(xyrange) { + xyrange->range.end = atoi(tag_start); + } + } + break; + case 11: + /* #line 80 "./ragel/tmedia_imageattr.rl" */ + { + if(xyrange && xyrange->array.count < TMEDIA_imageattr_ARRAY_MAX_SIZE) { + xyrange->array.values[xyrange->array.count++] = atoi(tag_start); + } + } + break; + case 12: + /* #line 85 "./ragel/tmedia_imageattr.rl" */ + { + if(*sets_count < TMEDIA_imageattr_ARRAY_MAX_SIZE) { + sets[*sets_count].qvalue = atof(tag_start); + } + } + break; + case 13: + /* #line 91 "./ragel/tmedia_imageattr.rl" */ + { + if(srange) { + srange->is_range = 0; + } + } + break; + case 14: + /* #line 94 "./ragel/tmedia_imageattr.rl" */ + { + if(srange) { + srange->is_range = 1; + } + } + break; + case 15: + /* #line 97 "./ragel/tmedia_imageattr.rl" */ + { + srange = (*sets_count < TMEDIA_imageattr_ARRAY_MAX_SIZE) ? &sets[*sets_count].srange : tsk_null; + } + break; + case 16: + /* #line 100 "./ragel/tmedia_imageattr.rl" */ + { + if(srange && srange->array.count < TMEDIA_imageattr_ARRAY_MAX_SIZE) { + srange->array.values[srange->array.count++] = atof(tag_start); + } + } + break; + case 17: + /* #line 105 "./ragel/tmedia_imageattr.rl" */ + { + if(srange) { + srange->range.start = atof(tag_start); + } + } + break; + case 18: + /* #line 108 "./ragel/tmedia_imageattr.rl" */ + { + if(srange) { + srange->range.end = atof(tag_start); + } + } + break; + case 19: + /* #line 112 "./ragel/tmedia_imageattr.rl" */ + { + if(*sets_count < TMEDIA_imageattr_ARRAY_MAX_SIZE) { + sets[*sets_count].prange.start = atof(tag_start); + } + } + break; + case 20: + /* #line 115 "./ragel/tmedia_imageattr.rl" */ + { + if(*sets_count < TMEDIA_imageattr_ARRAY_MAX_SIZE) { + sets[*sets_count].prange.end = atof(tag_start), sets[*sets_count].prange.is_present = 1; + } + } + break; + /* #line 912 "./src/tmedia_imageattr.c" */ + } + } _again: - if ( cs == 0 ) - goto _out; - if ( ++p != pe ) - goto _resume; - _test_eof: {} - if ( p == eof ) - { - const char *__acts = _tmedia_machine_imageattr_actions + _tmedia_machine_imageattr_eof_actions[cs]; - unsigned int __nacts = (unsigned int) *__acts++; - while ( __nacts-- > 0 ) { - switch ( *__acts++ ) { - case 5: -/* #line 62 "./ragel/tmedia_imageattr.rl" */ - { - if(*sets_count < TMEDIA_imageattr_ARRAY_MAX_SIZE) (*sets_count)++; - } - break; -/* #line 934 "./src/tmedia_imageattr.c" */ - } - } - } - - _out: {} - } - -/* #line 175 "./ragel/tmedia_imageattr.rl" */ - TSK_RAGEL_DISABLE_WARNINGS_END() - - if( cs < -/* #line 946 "./src/tmedia_imageattr.c" */ -325 -/* #line 177 "./ragel/tmedia_imageattr.rl" */ - ){ - TSK_DEBUG_ERROR("Parsing failed to parse image-attr=%s", (char*)in_data); - return -1; - } - - return 0; + if ( cs == 0 ) { + goto _out; + } + if ( ++p != pe ) { + goto _resume; + } +_test_eof: { + } + if ( p == eof ) { + const char *__acts = _tmedia_machine_imageattr_actions + _tmedia_machine_imageattr_eof_actions[cs]; + unsigned int __nacts = (unsigned int) *__acts++; + while ( __nacts-- > 0 ) { + switch ( *__acts++ ) { + case 5: + /* #line 62 "./ragel/tmedia_imageattr.rl" */ + { + if(*sets_count < TMEDIA_imageattr_ARRAY_MAX_SIZE) { + (*sets_count)++; + } + } + break; + /* #line 934 "./src/tmedia_imageattr.c" */ + } + } + } + +_out: { + } + } + + /* #line 175 "./ragel/tmedia_imageattr.rl" */ + TSK_RAGEL_DISABLE_WARNINGS_END() + + if( cs < + /* #line 946 "./src/tmedia_imageattr.c" */ + 325 + /* #line 177 "./ragel/tmedia_imageattr.rl" */ + ) { + TSK_DEBUG_ERROR("Parsing failed to parse image-attr=%s", (char*)in_data); + return -1; + } + + return 0; }
\ No newline at end of file diff --git a/tinyMEDIA/src/tmedia_jitterbuffer.c b/tinyMEDIA/src/tmedia_jitterbuffer.c index 108eee1..bf43586 100755 --- a/tinyMEDIA/src/tmedia_jitterbuffer.c +++ b/tinyMEDIA/src/tmedia_jitterbuffer.c @@ -2,19 +2,19 @@ * Copyright (C) 2011 Mamadou Diop. * * Contact: Mamadou Diop <diopmamadou(at)doubango[dot]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. * @@ -34,183 +34,183 @@ static const tmedia_jitterbuffer_plugin_def_t* __tmedia_jitterbuffer_plugins[TME int tmedia_jitterbuffer_init(tmedia_jitterbuffer_t* self) { - if(!self){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - return 0; + if(!self) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + return 0; } int tmedia_jitterbuffer_set(tmedia_jitterbuffer_t *self, const tmedia_param_t* param) { - if(!self || !self->plugin || !param){ - TSK_DEBUG_ERROR("Invalid parameter"); - return 0; - } - return self->plugin->set ? self->plugin->set(self, param) : 0; + if(!self || !self->plugin || !param) { + TSK_DEBUG_ERROR("Invalid parameter"); + return 0; + } + return self->plugin->set ? self->plugin->set(self, param) : 0; } int tmedia_jitterbuffer_open(tmedia_jitterbuffer_t* self, uint32_t frame_duration, uint32_t rate, uint32_t channels) { - int ret; - - if(!self || !self->plugin || !self->plugin->open){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - if(self->opened){ - TSK_DEBUG_WARN("JitterBuffer already opened"); - return 0; - } - - if((ret = self->plugin->open(self, frame_duration, rate, channels))){ - TSK_DEBUG_ERROR("Failed to open [%s] jitterbufferr", self->plugin->desc); - return ret; - } - else{ - self->opened = tsk_true; - return 0; - } + int ret; + + if(!self || !self->plugin || !self->plugin->open) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + if(self->opened) { + TSK_DEBUG_WARN("JitterBuffer already opened"); + return 0; + } + + if((ret = self->plugin->open(self, frame_duration, rate, channels))) { + TSK_DEBUG_ERROR("Failed to open [%s] jitterbufferr", self->plugin->desc); + return ret; + } + else { + self->opened = tsk_true; + return 0; + } } int tmedia_jitterbuffer_tick(tmedia_jitterbuffer_t* self) { - if(!self || !self->plugin || !self->plugin->tick){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } + if(!self || !self->plugin || !self->plugin->tick) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } - if(!self->opened){ - TSK_DEBUG_ERROR("JitterBuffer not opened"); - return -1; - } + if(!self->opened) { + TSK_DEBUG_ERROR("JitterBuffer not opened"); + return -1; + } - return self->plugin->tick(self); + return self->plugin->tick(self); } int tmedia_jitterbuffer_put(tmedia_jitterbuffer_t* self, void* data, tsk_size_t data_size, const tsk_object_t* proto_hdr) { - if(!self || !self->plugin || !self->plugin->put){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } + if(!self || !self->plugin || !self->plugin->put) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } - if(!self->opened){ - TSK_DEBUG_ERROR("JitterBuffer not opened"); - return -1; - } + if(!self->opened) { + TSK_DEBUG_ERROR("JitterBuffer not opened"); + return -1; + } - return self->plugin->put(self, data, data_size, proto_hdr); + return self->plugin->put(self, data, data_size, proto_hdr); } tsk_size_t tmedia_jitterbuffer_get(tmedia_jitterbuffer_t* self, void* out_data, tsk_size_t out_size) { - if(!self || !self->plugin || !self->plugin->get){ - TSK_DEBUG_ERROR("Invalid parameter"); - return 0; - } + if(!self || !self->plugin || !self->plugin->get) { + TSK_DEBUG_ERROR("Invalid parameter"); + return 0; + } - if(!self->opened){ - TSK_DEBUG_ERROR("JitterBuffer not opened"); - return 0; - } + if(!self->opened) { + TSK_DEBUG_ERROR("JitterBuffer not opened"); + return 0; + } - return self->plugin->get(self, out_data, out_size); + return self->plugin->get(self, out_data, out_size); } int tmedia_jitterbuffer_reset(tmedia_jitterbuffer_t* self) { - if(!self || !self->plugin){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - if(self->opened && self->plugin->reset){ - return self->plugin->reset(self); - } - - return 0; + if(!self || !self->plugin) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + if(self->opened && self->plugin->reset) { + return self->plugin->reset(self); + } + + return 0; } int tmedia_jitterbuffer_close(tmedia_jitterbuffer_t* self) { - if(!self || !self->plugin){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - if(!self->opened){ - TSK_DEBUG_WARN("JitterBuffer not opened"); - return 0; - } - - if(self->plugin->close){ - int ret; - - if((ret = self->plugin->close(self))){ - TSK_DEBUG_ERROR("Failed to close [%s] jitterbufferr", self->plugin->desc); - return ret; - } - else{ - self->opened = tsk_false; - return 0; - } - } - else{ - self->opened = tsk_false; - return 0; - } + if(!self || !self->plugin) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + if(!self->opened) { + TSK_DEBUG_WARN("JitterBuffer not opened"); + return 0; + } + + if(self->plugin->close) { + int ret; + + if((ret = self->plugin->close(self))) { + TSK_DEBUG_ERROR("Failed to close [%s] jitterbufferr", self->plugin->desc); + return ret; + } + else { + self->opened = tsk_false; + return 0; + } + } + else { + self->opened = tsk_false; + return 0; + } } int tmedia_jitterbuffer_deinit(tmedia_jitterbuffer_t* self) { - if(!self){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } + if(!self) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } - if(self->opened){ - tmedia_jitterbuffer_close(self); - } + if(self->opened) { + tmedia_jitterbuffer_close(self); + } - return 0; + return 0; } tmedia_jitterbuffer_t* tmedia_jitterbuffer_create(tmedia_type_t type) { - tmedia_jitterbuffer_t* jitter_buffer = tsk_null; - const tmedia_jitterbuffer_plugin_def_t* plugin; - tsk_size_t i = 0; - - while((i < TMED_JITTER_BUFFER_MAX_PLUGINS) && (plugin = __tmedia_jitterbuffer_plugins[i++])){ - if(plugin->objdef && plugin->type == type){ - if((jitter_buffer = tsk_object_new(plugin->objdef))){ - /* initialize the newly created jitter_buffer */ - jitter_buffer->plugin = plugin; - break; - } - } - } - - return jitter_buffer; + tmedia_jitterbuffer_t* jitter_buffer = tsk_null; + const tmedia_jitterbuffer_plugin_def_t* plugin; + tsk_size_t i = 0; + + while((i < TMED_JITTER_BUFFER_MAX_PLUGINS) && (plugin = __tmedia_jitterbuffer_plugins[i++])) { + if(plugin->objdef && plugin->type == type) { + if((jitter_buffer = tsk_object_new(plugin->objdef))) { + /* initialize the newly created jitter_buffer */ + jitter_buffer->plugin = plugin; + break; + } + } + } + + return jitter_buffer; } int tmedia_jitterbuffer_plugin_register(const tmedia_jitterbuffer_plugin_def_t* plugin) { - tsk_size_t i; - if(!plugin){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - - /* add or replace the plugin */ - for(i = 0; i<TMED_JITTER_BUFFER_MAX_PLUGINS; i++){ - if(!__tmedia_jitterbuffer_plugins[i] || (__tmedia_jitterbuffer_plugins[i] == plugin)){ - __tmedia_jitterbuffer_plugins[i] = plugin; - return 0; - } - } - - TSK_DEBUG_ERROR("There are already %d plugins.", TMED_JITTER_BUFFER_MAX_PLUGINS); - return -2; + tsk_size_t i; + if(!plugin) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + + /* add or replace the plugin */ + for(i = 0; i<TMED_JITTER_BUFFER_MAX_PLUGINS; i++) { + if(!__tmedia_jitterbuffer_plugins[i] || (__tmedia_jitterbuffer_plugins[i] == plugin)) { + __tmedia_jitterbuffer_plugins[i] = plugin; + return 0; + } + } + + TSK_DEBUG_ERROR("There are already %d plugins.", TMED_JITTER_BUFFER_MAX_PLUGINS); + return -2; } /**@ingroup tmedia_jitterbuffer_group @@ -220,62 +220,62 @@ int tmedia_jitterbuffer_plugin_register(const tmedia_jitterbuffer_plugin_def_t* */ int tmedia_jitterbuffer_plugin_unregister(const tmedia_jitterbuffer_plugin_def_t* plugin) { - tsk_size_t i; - tsk_bool_t found = tsk_false; - if(!plugin){ - TSK_DEBUG_ERROR("Invalid Parameter"); - return -1; - } - - /* find the plugin to unregister */ - for(i = 0; i<TMED_JITTER_BUFFER_MAX_PLUGINS && __tmedia_jitterbuffer_plugins[i]; i++){ - if(__tmedia_jitterbuffer_plugins[i] == plugin){ - __tmedia_jitterbuffer_plugins[i] = tsk_null; - found = tsk_true; - break; - } - } - - /* compact */ - if(found){ - for(; i<(TMED_JITTER_BUFFER_MAX_PLUGINS - 1); i++){ - if(__tmedia_jitterbuffer_plugins[i+1]){ - __tmedia_jitterbuffer_plugins[i] = __tmedia_jitterbuffer_plugins[i+1]; - } - else{ - break; - } - } - __tmedia_jitterbuffer_plugins[i] = tsk_null; - } - return (found ? 0 : -2); + tsk_size_t i; + tsk_bool_t found = tsk_false; + if(!plugin) { + TSK_DEBUG_ERROR("Invalid Parameter"); + return -1; + } + + /* find the plugin to unregister */ + for(i = 0; i<TMED_JITTER_BUFFER_MAX_PLUGINS && __tmedia_jitterbuffer_plugins[i]; i++) { + if(__tmedia_jitterbuffer_plugins[i] == plugin) { + __tmedia_jitterbuffer_plugins[i] = tsk_null; + found = tsk_true; + break; + } + } + + /* compact */ + if(found) { + for(; i<(TMED_JITTER_BUFFER_MAX_PLUGINS - 1); i++) { + if(__tmedia_jitterbuffer_plugins[i+1]) { + __tmedia_jitterbuffer_plugins[i] = __tmedia_jitterbuffer_plugins[i+1]; + } + else { + break; + } + } + __tmedia_jitterbuffer_plugins[i] = tsk_null; + } + return (found ? 0 : -2); } int tmedia_jitterbuffer_plugin_unregister_by_type(tmedia_type_t type) { - tsk_size_t i; - tsk_bool_t found = tsk_false; - - /* find the plugin to unregister */ - for(i = 0; i<TMED_JITTER_BUFFER_MAX_PLUGINS && __tmedia_jitterbuffer_plugins[i]; i++){ - if((__tmedia_jitterbuffer_plugins[i]->type & type) == __tmedia_jitterbuffer_plugins[i]->type){ - __tmedia_jitterbuffer_plugins[i] = tsk_null; - found = tsk_true; - break; - } - } - - /* compact */ - if(found){ - for(; i<(TMED_JITTER_BUFFER_MAX_PLUGINS - 1); i++){ - if(__tmedia_jitterbuffer_plugins[i+1]){ - __tmedia_jitterbuffer_plugins[i] = __tmedia_jitterbuffer_plugins[i+1]; - } - else{ - break; - } - } - __tmedia_jitterbuffer_plugins[i] = tsk_null; - } - return (found ? 0 : -2); + tsk_size_t i; + tsk_bool_t found = tsk_false; + + /* find the plugin to unregister */ + for(i = 0; i<TMED_JITTER_BUFFER_MAX_PLUGINS && __tmedia_jitterbuffer_plugins[i]; i++) { + if((__tmedia_jitterbuffer_plugins[i]->type & type) == __tmedia_jitterbuffer_plugins[i]->type) { + __tmedia_jitterbuffer_plugins[i] = tsk_null; + found = tsk_true; + break; + } + } + + /* compact */ + if(found) { + for(; i<(TMED_JITTER_BUFFER_MAX_PLUGINS - 1); i++) { + if(__tmedia_jitterbuffer_plugins[i+1]) { + __tmedia_jitterbuffer_plugins[i] = __tmedia_jitterbuffer_plugins[i+1]; + } + else { + break; + } + } + __tmedia_jitterbuffer_plugins[i] = tsk_null; + } + return (found ? 0 : -2); } diff --git a/tinyMEDIA/src/tmedia_params.c b/tinyMEDIA/src/tmedia_params.c index 85e9df3..1586a7d 100755 --- a/tinyMEDIA/src/tmedia_params.c +++ b/tinyMEDIA/src/tmedia_params.c @@ -2,19 +2,19 @@ * Copyright (C) 2010-2011 Mamadou Diop. * * Contact: Mamadou Diop <diopmamadou(at)doubango[dot]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. * @@ -35,118 +35,118 @@ #include "tsk_debug.h" #include "tsk_memory.h" -tmedia_param_t* tmedia_param_create(tmedia_param_access_type_t access_type, - tmedia_type_t media_type, - tmedia_param_plugin_type_t plugin_type, - tmedia_param_value_type_t value_type, - const char* key, - void* value) +tmedia_param_t* tmedia_param_create(tmedia_param_access_type_t access_type, + tmedia_type_t media_type, + tmedia_param_plugin_type_t plugin_type, + tmedia_param_value_type_t value_type, + const char* key, + void* value) { - tmedia_param_t* param; - - if(!key || (!value && (value_type != tmedia_pvt_pobject && value_type != tmedia_pvt_pchar))){ - TSK_DEBUG_ERROR("Invalid parameter"); - return tsk_null; - } - - if((param = tsk_object_new(tmedia_param_def_t))){ - param->access_type = access_type; - param->media_type = media_type; - param->plugin_type = plugin_type; - param->value_type = value_type; - param->key = tsk_strdup(key); - if(access_type == tmedia_pat_get){ - param->value = (value); - } - else if(access_type == tmedia_pat_set){ - switch(value_type){ - case tmedia_pvt_int32: - if((param->value = tsk_calloc(1, sizeof(int32_t)))){ - memcpy(param->value, value, sizeof(int32_t)); - } - break; - case tmedia_pvt_pobject: - param->value = tsk_object_ref(value); - break; - case tmedia_pvt_pchar: - param->value = tsk_strdup(value); - break; - case tmedia_pvt_int64: - if((param->value = tsk_calloc(1, sizeof(int64_t)))){ - memcpy(param->value, value, sizeof(int64_t)); - } - break; - } - } - } - else{ - TSK_DEBUG_ERROR("Failed to create media parameter"); - } - return param; + tmedia_param_t* param; + + if(!key || (!value && (value_type != tmedia_pvt_pobject && value_type != tmedia_pvt_pchar))) { + TSK_DEBUG_ERROR("Invalid parameter"); + return tsk_null; + } + + if((param = tsk_object_new(tmedia_param_def_t))) { + param->access_type = access_type; + param->media_type = media_type; + param->plugin_type = plugin_type; + param->value_type = value_type; + param->key = tsk_strdup(key); + if(access_type == tmedia_pat_get) { + param->value = (value); + } + else if(access_type == tmedia_pat_set) { + switch(value_type) { + case tmedia_pvt_int32: + if((param->value = tsk_calloc(1, sizeof(int32_t)))) { + memcpy(param->value, value, sizeof(int32_t)); + } + break; + case tmedia_pvt_pobject: + param->value = tsk_object_ref(value); + break; + case tmedia_pvt_pchar: + param->value = tsk_strdup(value); + break; + case tmedia_pvt_int64: + if((param->value = tsk_calloc(1, sizeof(int64_t)))) { + memcpy(param->value, value, sizeof(int64_t)); + } + break; + } + } + } + else { + TSK_DEBUG_ERROR("Failed to create media parameter"); + } + return param; } tmedia_params_L_t* tmedia_params_create_2(va_list *app) { - tmedia_session_param_type_t curr; - tmedia_params_L_t* params; - - if(!app){ - TSK_DEBUG_ERROR("Invalid parameter"); - return tsk_null; - } - - params = tmedia_params_create(); - - while((curr = va_arg(*app, tmedia_session_param_type_t)) != tmedia_sptype_null){ - switch(curr){ - case tmedia_sptype_set: - case tmedia_sptype_get: - { /* (tmedia_type_t)MEDIA_TYPE_ENUM, (tmedia_param_plugin_type_t)PLUGIN_TYPE_ENUM, (tmedia_param_value_type_t)VALUE_TYPE_ENUM \ - (const char*)KEY_STR, (void*)&VALUE */ - /* IMPORTANT: do not pass va_arg() directly into the function */ - tmedia_type_t media_type = va_arg(*app, tmedia_type_t); - tmedia_param_plugin_type_t plugin_type = va_arg(*app, tmedia_param_plugin_type_t); - tmedia_param_value_type_t value_type = va_arg(*app, tmedia_param_value_type_t); - const char* key = va_arg(*app, const char*); - void* value = va_arg(*app, void*); - tmedia_params_add_param(¶ms, (curr == tmedia_sptype_set) ? tmedia_pat_set : tmedia_pat_get, - media_type, plugin_type, value_type, key, value); - break; - } - default: - { /* va_list will be unsafe => exit */ - TSK_DEBUG_ERROR("%d NOT a valid pname", curr); - break; - } - }/* switch */ - }/* while */ - - return params; + tmedia_session_param_type_t curr; + tmedia_params_L_t* params; + + if(!app) { + TSK_DEBUG_ERROR("Invalid parameter"); + return tsk_null; + } + + params = tmedia_params_create(); + + while((curr = va_arg(*app, tmedia_session_param_type_t)) != tmedia_sptype_null) { + switch(curr) { + case tmedia_sptype_set: + case tmedia_sptype_get: { + /* (tmedia_type_t)MEDIA_TYPE_ENUM, (tmedia_param_plugin_type_t)PLUGIN_TYPE_ENUM, (tmedia_param_value_type_t)VALUE_TYPE_ENUM \ + (const char*)KEY_STR, (void*)&VALUE */ + /* IMPORTANT: do not pass va_arg() directly into the function */ + tmedia_type_t media_type = va_arg(*app, tmedia_type_t); + tmedia_param_plugin_type_t plugin_type = va_arg(*app, tmedia_param_plugin_type_t); + tmedia_param_value_type_t value_type = va_arg(*app, tmedia_param_value_type_t); + const char* key = va_arg(*app, const char*); + void* value = va_arg(*app, void*); + tmedia_params_add_param(¶ms, (curr == tmedia_sptype_set) ? tmedia_pat_set : tmedia_pat_get, + media_type, plugin_type, value_type, key, value); + break; + } + default: { + /* va_list will be unsafe => exit */ + TSK_DEBUG_ERROR("%d NOT a valid pname", curr); + break; + } + }/* switch */ + }/* while */ + + return params; } -int tmedia_params_add_param(tmedia_params_L_t **self, - tmedia_param_access_type_t access_type, - tmedia_type_t media_type, - tmedia_param_plugin_type_t plugin_type, - tmedia_param_value_type_t value_type, - const char* key, - void* value) +int tmedia_params_add_param(tmedia_params_L_t **self, + tmedia_param_access_type_t access_type, + tmedia_type_t media_type, + tmedia_param_plugin_type_t plugin_type, + tmedia_param_value_type_t value_type, + const char* key, + void* value) { - tmedia_param_t *param; + tmedia_param_t *param; - if(!self) { - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } + if(!self) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } - if(!*self){ - *self = tmedia_params_create(); - } + if(!*self) { + *self = tmedia_params_create(); + } - if((param = tmedia_param_create(access_type, media_type, plugin_type, value_type, key, value))){ - tsk_list_push_back_data(*self, (void**)¶m); - } - return 0; + if((param = tmedia_param_create(access_type, media_type, plugin_type, value_type, key, value))) { + tsk_list_push_back_data(*self, (void**)¶m); + } + return 0; } @@ -157,41 +157,40 @@ int tmedia_params_add_param(tmedia_params_L_t **self, // static tsk_object_t* tmedia_param_ctor(tsk_object_t* self, va_list * app) { - tmedia_param_t *param = self; - if(param){ - } + tmedia_param_t *param = self; + if(param) { + } - return self; + return self; } static tsk_object_t* tmedia_param_dtor(tsk_object_t* self) -{ - tmedia_param_t *param = self; - if(param){ - TSK_FREE(param->key); - if(param->access_type == tmedia_pat_set){ - switch(param->value_type){ - case tmedia_pvt_pobject: - TSK_OBJECT_SAFE_FREE(param->value); - break; - case tmedia_pvt_pchar: - case tmedia_pvt_int64: - case tmedia_pvt_int32: - TSK_FREE(param->value); - break; - } - } - } - - return self; +{ + tmedia_param_t *param = self; + if(param) { + TSK_FREE(param->key); + if(param->access_type == tmedia_pat_set) { + switch(param->value_type) { + case tmedia_pvt_pobject: + TSK_OBJECT_SAFE_FREE(param->value); + break; + case tmedia_pvt_pchar: + case tmedia_pvt_int64: + case tmedia_pvt_int32: + TSK_FREE(param->value); + break; + } + } + } + + return self; } -static const tsk_object_def_t tmedia_param_def_s = -{ - sizeof(tmedia_param_t), - tmedia_param_ctor, - tmedia_param_dtor, - tsk_null, +static const tsk_object_def_t tmedia_param_def_s = { + sizeof(tmedia_param_t), + tmedia_param_ctor, + tmedia_param_dtor, + tsk_null, }; const tsk_object_def_t *tmedia_param_def_t = &tmedia_param_def_s; diff --git a/tinyMEDIA/src/tmedia_producer.c b/tinyMEDIA/src/tmedia_producer.c index 4b7c252..7f71013 100755 --- a/tinyMEDIA/src/tmedia_producer.c +++ b/tinyMEDIA/src/tmedia_producer.c @@ -1,18 +1,18 @@ /* * Copyright (C) 2010-2014 Mamadou DIOP -* +* * 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. * @@ -41,18 +41,18 @@ const tmedia_producer_plugin_def_t* __tmedia_producer_plugins[TMED_PRODUCER_MAX_ */ int tmedia_producer_init(tmedia_producer_t* self) { - if(!self){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - - self->video.chroma = TMEDIA_PRODUCER_CHROMA_DEFAULT; - self->audio.bits_per_sample = TMEDIA_PRODUCER_BITS_PER_SAMPLE_DEFAULT; - self->audio.channels = TMEDIA_PRODUCER_CHANNELS_DEFAULT; - self->audio.rate = TMEDIA_PRODUCER_RATE_DEFAULT; - self->audio.volume = tmedia_defaults_get_volume(); - - return 0; + if(!self) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + + self->video.chroma = TMEDIA_PRODUCER_CHROMA_DEFAULT; + self->audio.bits_per_sample = TMEDIA_PRODUCER_BITS_PER_SAMPLE_DEFAULT; + self->audio.channels = TMEDIA_PRODUCER_CHANNELS_DEFAULT; + self->audio.rate = TMEDIA_PRODUCER_RATE_DEFAULT; + self->audio.volume = tmedia_defaults_get_volume(); + + return 0; } /**@ingroup tmedia_producer_group @@ -60,15 +60,15 @@ int tmedia_producer_init(tmedia_producer_t* self) */ int tmedia_producer_set_enc_callback(tmedia_producer_t *self, tmedia_producer_enc_cb_f callback, const void* callback_data) { - if(!self){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } + if(!self) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } - self->enc_cb.callback = callback; - self->enc_cb.callback_data = callback_data; + self->enc_cb.callback = callback; + self->enc_cb.callback_data = callback_data; - return 0; + return 0; } /**@ingroup tmedia_producer_group @@ -76,15 +76,15 @@ int tmedia_producer_set_enc_callback(tmedia_producer_t *self, tmedia_producer_en */ int tmedia_producer_set_raw_callback(tmedia_producer_t *self, tmedia_producer_raw_cb_f callback, const void* callback_data) { - if(!self){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } + if(!self) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } - self->raw_cb.callback = callback; - self->raw_cb.chunck_curr.usr_data = callback_data; + self->raw_cb.callback = callback; + self->raw_cb.chunck_curr.usr_data = callback_data; - return 0; + return 0; } /**@ingroup tmedia_producer_group @@ -92,11 +92,11 @@ int tmedia_producer_set_raw_callback(tmedia_producer_t *self, tmedia_producer_ra */ int tmedia_producer_set(tmedia_producer_t* self, const tmedia_param_t* param) { - if(!self || !self->plugin || !self->plugin->set || !param){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - return self->plugin->set(self, param); + if(!self || !self->plugin || !self->plugin->set || !param) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + return self->plugin->set(self, param); } /**@ingroup tmedia_producer_group @@ -107,15 +107,15 @@ int tmedia_producer_set(tmedia_producer_t* self, const tmedia_param_t* param) */ int tmedia_producer_prepare(tmedia_producer_t *self, const tmedia_codec_t* codec) { - int ret; - if (!self || !self->plugin || !self->plugin->prepare || !codec) { - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - if ((ret = self->plugin->prepare(self, codec)) == 0) { - self->is_prepared = tsk_true; - } - return ret; + int ret; + if (!self || !self->plugin || !self->plugin->prepare || !codec) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + if ((ret = self->plugin->prepare(self, codec)) == 0) { + self->is_prepared = tsk_true; + } + return ret; } /**@ingroup tmedia_producer_group @@ -125,15 +125,15 @@ int tmedia_producer_prepare(tmedia_producer_t *self, const tmedia_codec_t* codec */ int tmedia_producer_start(tmedia_producer_t *self) { - int ret; - if (!self || !self->plugin || !self->plugin->start) { - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - if ((ret = self->plugin->start(self)) == 0) { - self->is_started = tsk_true; - } - return ret; + int ret; + if (!self || !self->plugin || !self->plugin->start) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + if ((ret = self->plugin->start(self)) == 0) { + self->is_started = tsk_true; + } + return ret; } @@ -144,11 +144,11 @@ int tmedia_producer_start(tmedia_producer_t *self) */ int tmedia_producer_pause(tmedia_producer_t *self) { - if (!self || !self->plugin || !self->plugin->pause) { - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - return self->plugin->pause(self); + if (!self || !self->plugin || !self->plugin->pause) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + return self->plugin->pause(self); } @@ -159,15 +159,15 @@ int tmedia_producer_pause(tmedia_producer_t *self) */ int tmedia_producer_stop(tmedia_producer_t *self) { - int ret; - if (!self || !self->plugin || !self->plugin->stop) { - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - if ((ret = self->plugin->stop(self)) == 0) { - self->is_started = tsk_false; - } - return ret; + int ret; + if (!self || !self->plugin || !self->plugin->stop) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + if ((ret = self->plugin->stop(self)) == 0) { + self->is_started = tsk_false; + } + return ret; } @@ -180,11 +180,11 @@ int tmedia_producer_stop(tmedia_producer_t *self) */ int tmedia_producer_deinit(tmedia_producer_t* self) { - if(!self){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - return 0; + if(!self) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + return 0; } /**@ingroup tmedia_producer_group @@ -195,22 +195,22 @@ int tmedia_producer_deinit(tmedia_producer_t* self) */ tmedia_producer_t* tmedia_producer_create(tmedia_type_t type, uint64_t session_id) { - tmedia_producer_t* producer = tsk_null; - const tmedia_producer_plugin_def_t* plugin; - tsk_size_t i = 0; - - while((i < TMED_PRODUCER_MAX_PLUGINS) && (plugin = __tmedia_producer_plugins[i++])){ - if(plugin->objdef && plugin->type == type){ - if((producer = tsk_object_new(plugin->objdef))){ - /* initialize the newly created producer */ - producer->plugin = plugin; - producer->session_id = session_id; - break; - } - } - } - - return producer; + tmedia_producer_t* producer = tsk_null; + const tmedia_producer_plugin_def_t* plugin; + tsk_size_t i = 0; + + while((i < TMED_PRODUCER_MAX_PLUGINS) && (plugin = __tmedia_producer_plugins[i++])) { + if(plugin->objdef && plugin->type == type) { + if((producer = tsk_object_new(plugin->objdef))) { + /* initialize the newly created producer */ + producer->plugin = plugin; + producer->session_id = session_id; + break; + } + } + } + + return producer; } /**@ingroup tmedia_producer_group @@ -221,22 +221,22 @@ tmedia_producer_t* tmedia_producer_create(tmedia_type_t type, uint64_t session_i */ int tmedia_producer_plugin_register(const tmedia_producer_plugin_def_t* plugin) { - tsk_size_t i; - if(!plugin){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - - /* add or replace the plugin */ - for(i = 0; i<TMED_PRODUCER_MAX_PLUGINS; i++){ - if(!__tmedia_producer_plugins[i] || (__tmedia_producer_plugins[i] == plugin)){ - __tmedia_producer_plugins[i] = plugin; - return 0; - } - } - - TSK_DEBUG_ERROR("There are already %d plugins.", TMED_PRODUCER_MAX_PLUGINS); - return -2; + tsk_size_t i; + if(!plugin) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + + /* add or replace the plugin */ + for(i = 0; i<TMED_PRODUCER_MAX_PLUGINS; i++) { + if(!__tmedia_producer_plugins[i] || (__tmedia_producer_plugins[i] == plugin)) { + __tmedia_producer_plugins[i] = plugin; + return 0; + } + } + + TSK_DEBUG_ERROR("There are already %d plugins.", TMED_PRODUCER_MAX_PLUGINS); + return -2; } /**@ingroup tmedia_producer_group @@ -246,35 +246,35 @@ int tmedia_producer_plugin_register(const tmedia_producer_plugin_def_t* plugin) */ int tmedia_producer_plugin_unregister(const tmedia_producer_plugin_def_t* plugin) { - tsk_size_t i; - tsk_bool_t found = tsk_false; - if(!plugin){ - TSK_DEBUG_ERROR("Invalid Parameter"); - return -1; - } - - /* find the plugin to unregister */ - for(i = 0; i<TMED_PRODUCER_MAX_PLUGINS && __tmedia_producer_plugins[i]; i++){ - if(__tmedia_producer_plugins[i] == plugin){ - __tmedia_producer_plugins[i] = tsk_null; - found = tsk_true; - break; - } - } - - /* compact */ - if(found){ - for(; i<(TMED_PRODUCER_MAX_PLUGINS - 1); i++){ - if(__tmedia_producer_plugins[i+1]){ - __tmedia_producer_plugins[i] = __tmedia_producer_plugins[i+1]; - } - else{ - break; - } - } - __tmedia_producer_plugins[i] = tsk_null; - } - return (found ? 0 : -2); + tsk_size_t i; + tsk_bool_t found = tsk_false; + if(!plugin) { + TSK_DEBUG_ERROR("Invalid Parameter"); + return -1; + } + + /* find the plugin to unregister */ + for(i = 0; i<TMED_PRODUCER_MAX_PLUGINS && __tmedia_producer_plugins[i]; i++) { + if(__tmedia_producer_plugins[i] == plugin) { + __tmedia_producer_plugins[i] = tsk_null; + found = tsk_true; + break; + } + } + + /* compact */ + if(found) { + for(; i<(TMED_PRODUCER_MAX_PLUGINS - 1); i++) { + if(__tmedia_producer_plugins[i+1]) { + __tmedia_producer_plugins[i] = __tmedia_producer_plugins[i+1]; + } + else { + break; + } + } + __tmedia_producer_plugins[i] = tsk_null; + } + return (found ? 0 : -2); } /**@ingroup tmedia_producer_group @@ -284,21 +284,21 @@ int tmedia_producer_plugin_unregister(const tmedia_producer_plugin_def_t* plugin */ int tmedia_producer_plugin_unregister_by_type(tmedia_type_t type) { - int i, j; - - /* find the plugin to unregister */ - for (i = 0; i < TMED_PRODUCER_MAX_PLUGINS && __tmedia_producer_plugins[i]; ) { - if ((__tmedia_producer_plugins[i]->type & type) == __tmedia_producer_plugins[i]->type) { - __tmedia_producer_plugins[i] = tsk_null; - /* compact */ - for (j = i; j < (TMED_PRODUCER_MAX_PLUGINS - 1) && __tmedia_producer_plugins[j + 1]; ++j) { - __tmedia_producer_plugins[j] = __tmedia_producer_plugins[j + 1]; - } - __tmedia_producer_plugins[j] = tsk_null; - } - else { - ++i; - } - } - return 0; + int i, j; + + /* find the plugin to unregister */ + for (i = 0; i < TMED_PRODUCER_MAX_PLUGINS && __tmedia_producer_plugins[i]; ) { + if ((__tmedia_producer_plugins[i]->type & type) == __tmedia_producer_plugins[i]->type) { + __tmedia_producer_plugins[i] = tsk_null; + /* compact */ + for (j = i; j < (TMED_PRODUCER_MAX_PLUGINS - 1) && __tmedia_producer_plugins[j + 1]; ++j) { + __tmedia_producer_plugins[j] = __tmedia_producer_plugins[j + 1]; + } + __tmedia_producer_plugins[j] = tsk_null; + } + else { + ++i; + } + } + return 0; } diff --git a/tinyMEDIA/src/tmedia_qos.c b/tinyMEDIA/src/tmedia_qos.c index c5c9d3d..1a4b0af 100755 --- a/tinyMEDIA/src/tmedia_qos.c +++ b/tinyMEDIA/src/tmedia_qos.c @@ -2,19 +2,19 @@ * Copyright (C) 2010-2011 Mamadou Diop. * * Contact: Mamadou Diop <diopmamadou(at)doubango[dot]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. * @@ -36,401 +36,402 @@ static const char* tmedia_qos_strength_tostring(tmedia_qos_strength_t strength) { - switch(strength){ - case tmedia_qos_strength_none: - return "none"; - case tmedia_qos_strength_mandatory: - return "mandatory"; - case tmedia_qos_strength_optional: - return "optional"; - case tmedia_qos_strength_failure: - return "failure"; - case tmedia_qos_strength_unknown: - default: - return "unknown"; - } + switch(strength) { + case tmedia_qos_strength_none: + return "none"; + case tmedia_qos_strength_mandatory: + return "mandatory"; + case tmedia_qos_strength_optional: + return "optional"; + case tmedia_qos_strength_failure: + return "failure"; + case tmedia_qos_strength_unknown: + default: + return "unknown"; + } } static tmedia_qos_strength_t tmedia_qos_strength_fromstring(const char* strength) { - if(tsk_strequals(strength, "none")){ - return tmedia_qos_strength_none; - } - else if(tsk_strequals(strength, "mandatory")){ - return tmedia_qos_strength_mandatory; - } - else if(tsk_strequals(strength, "optional")){ - return tmedia_qos_strength_optional; - } - else if(tsk_strequals(strength, "failure")){ - return tmedia_qos_strength_failure; - } - else{ - return tmedia_qos_strength_unknown; - } + if(tsk_strequals(strength, "none")) { + return tmedia_qos_strength_none; + } + else if(tsk_strequals(strength, "mandatory")) { + return tmedia_qos_strength_mandatory; + } + else if(tsk_strequals(strength, "optional")) { + return tmedia_qos_strength_optional; + } + else if(tsk_strequals(strength, "failure")) { + return tmedia_qos_strength_failure; + } + else { + return tmedia_qos_strength_unknown; + } } static tmedia_qos_direction_t tmedia_qos_direction_fromstring(const char* direction) { - if(tsk_strequals(direction, "send")){ - return tmedia_qos_direction_send; - } - else if(tsk_strequals(direction, "recv")){ - return tmedia_qos_direction_recv; - } - else if(tsk_strequals(direction, "sendrecv")){ - return tmedia_qos_direction_sendrecv; - } - else{ - return tmedia_qos_direction_none; - } + if(tsk_strequals(direction, "send")) { + return tmedia_qos_direction_send; + } + else if(tsk_strequals(direction, "recv")) { + return tmedia_qos_direction_recv; + } + else if(tsk_strequals(direction, "sendrecv")) { + return tmedia_qos_direction_sendrecv; + } + else { + return tmedia_qos_direction_none; + } } /* ========================= Common ==================================*/ tmedia_qos_tline_t* tmedia_qos_tline_create(tmedia_qos_stype_t type, tmedia_qos_strength_t strength) { - switch(type){ - case tmedia_qos_stype_e2e: - return (tmedia_qos_tline_t*)tmedia_qos_tline_e2e_create(strength); - case tmedia_qos_stype_segmented: - return (tmedia_qos_tline_t*)tmedia_qos_tline_segmented_create(strength); - default: break; - } - return tsk_null; + switch(type) { + case tmedia_qos_stype_e2e: + return (tmedia_qos_tline_t*)tmedia_qos_tline_e2e_create(strength); + case tmedia_qos_stype_segmented: + return (tmedia_qos_tline_t*)tmedia_qos_tline_segmented_create(strength); + default: + break; + } + return tsk_null; } tmedia_qos_stype_t tmedia_qos_get_type(const tsdp_header_M_t* m) { - const tsdp_header_A_t* A; - char s0[10]; - - if(!m){ - TSK_DEBUG_ERROR("Invalid parameter"); - return tmedia_qos_stype_none; - } - - if((A = tsdp_header_M_findA(m, "curr"))){ - if(sscanf(A->value, "qos %s %*s", s0) != EOF){ - return tsk_strequals(s0, "e2e") ? tmedia_qos_stype_e2e : tmedia_qos_stype_segmented; - } - else{ - TSK_DEBUG_ERROR("Failed to parse a=%s:%s", A->field, A->value); - } - } - - return tmedia_qos_stype_none; + const tsdp_header_A_t* A; + char s0[10]; + + if(!m) { + TSK_DEBUG_ERROR("Invalid parameter"); + return tmedia_qos_stype_none; + } + + if((A = tsdp_header_M_findA(m, "curr"))) { + if(sscanf(A->value, "qos %s %*s", s0) != EOF) { + return tsk_strequals(s0, "e2e") ? tmedia_qos_stype_e2e : tmedia_qos_stype_segmented; + } + else { + TSK_DEBUG_ERROR("Failed to parse a=%s:%s", A->field, A->value); + } + } + + return tmedia_qos_stype_none; } tmedia_qos_tline_t* tmedia_qos_tline_from_sdp(const tsdp_header_M_t* m) { - if(!m){ - TSK_DEBUG_ERROR("Invalid parameter"); - return tsk_null; - } - - switch(tmedia_qos_get_type(m)){ - case tmedia_qos_stype_e2e: - return (tmedia_qos_tline_t*)tmedia_qos_tline_e2e_from_sdp(m); - case tmedia_qos_stype_segmented: - return (tmedia_qos_tline_t*)tmedia_qos_tline_segmented_from_sdp(m); - default: - return tsk_null; - } + if(!m) { + TSK_DEBUG_ERROR("Invalid parameter"); + return tsk_null; + } + + switch(tmedia_qos_get_type(m)) { + case tmedia_qos_stype_e2e: + return (tmedia_qos_tline_t*)tmedia_qos_tline_e2e_from_sdp(m); + case tmedia_qos_stype_segmented: + return (tmedia_qos_tline_t*)tmedia_qos_tline_segmented_from_sdp(m); + default: + return tsk_null; + } } int tmedia_qos_tline_to_sdp(const tmedia_qos_tline_t* self, tsdp_header_M_t* m) { - if(!self || !m){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - - switch(self->type){ - case tmedia_qos_stype_e2e: - return tmedia_qos_tline_e2e_to_sdp((tmedia_qos_tline_e2e_t*)self, m); - case tmedia_qos_stype_segmented: - return tmedia_qos_tline_segmented_to_sdp((tmedia_qos_tline_segmented_t*)self, m); - default: - TSK_DEBUG_ERROR("Invalid type"); - return -2; - } + if(!self || !m) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + + switch(self->type) { + case tmedia_qos_stype_e2e: + return tmedia_qos_tline_e2e_to_sdp((tmedia_qos_tline_e2e_t*)self, m); + case tmedia_qos_stype_segmented: + return tmedia_qos_tline_segmented_to_sdp((tmedia_qos_tline_segmented_t*)self, m); + default: + TSK_DEBUG_ERROR("Invalid type"); + return -2; + } } int tmedia_qos_tline_set_ro(tmedia_qos_tline_t* self, const tmedia_qos_tline_t* ro) { - if(!self || !ro){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - - switch(self->type){ - case tmedia_qos_stype_e2e: - return tmedia_qos_tline_e2e_set_ro((tmedia_qos_tline_e2e_t*)self, (const tmedia_qos_tline_e2e_t*)ro); - case tmedia_qos_stype_segmented: - return tmedia_qos_tline_segmented_set_ro((tmedia_qos_tline_segmented_t*)self, (const tmedia_qos_tline_segmented_t*)ro); - default: - TSK_DEBUG_ERROR("Invalid type"); - return -2; - } + if(!self || !ro) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + + switch(self->type) { + case tmedia_qos_stype_e2e: + return tmedia_qos_tline_e2e_set_ro((tmedia_qos_tline_e2e_t*)self, (const tmedia_qos_tline_e2e_t*)ro); + case tmedia_qos_stype_segmented: + return tmedia_qos_tline_segmented_set_ro((tmedia_qos_tline_segmented_t*)self, (const tmedia_qos_tline_segmented_t*)ro); + default: + TSK_DEBUG_ERROR("Invalid type"); + return -2; + } } tsk_bool_t tmedia_qos_tline_canresume(const tmedia_qos_tline_t* self) { - if(!self){ - TSK_DEBUG_ERROR("Invalid parameter"); - return tsk_true; - } - switch(self->type){ - case tmedia_qos_stype_segmented: - return tmedia_qos_tline_segmented_canresume((const tmedia_qos_tline_segmented_t*)self); - case tmedia_qos_stype_e2e: - return tmedia_qos_tline_e2e_canresume((const tmedia_qos_tline_e2e_t*)self); - default: - return tsk_true; - } + if(!self) { + TSK_DEBUG_ERROR("Invalid parameter"); + return tsk_true; + } + switch(self->type) { + case tmedia_qos_stype_segmented: + return tmedia_qos_tline_segmented_canresume((const tmedia_qos_tline_segmented_t*)self); + case tmedia_qos_stype_e2e: + return tmedia_qos_tline_e2e_canresume((const tmedia_qos_tline_e2e_t*)self); + default: + return tsk_true; + } } /* ========================= E2E ==================================*/ tmedia_qos_tline_e2e_t* tmedia_qos_tline_e2e_create(tmedia_qos_strength_t strength) { - return tsk_object_new(tmedia_qos_tline_e2e_def_t, strength); + return tsk_object_new(tmedia_qos_tline_e2e_def_t, strength); } tmedia_qos_tline_e2e_t* tmedia_qos_tline_e2e_from_sdp(const tsdp_header_M_t* m) { - tmedia_qos_tline_e2e_t* e2e = tsk_null; - const tsdp_header_A_t* A; - tsk_size_t i; - - char s0[10], s1[10]; - - if(!m){ - TSK_DEBUG_ERROR("invalid parameter"); - return tsk_null; - } - - /* Example - a=curr:qos e2e none - a=des:qos mandatory e2e sendrecv - a=conf:qos e2e recv - */ - - e2e = tmedia_qos_tline_e2e_create(tmedia_qos_strength_unknown); - - /* curr */ - for(i = 0; (A = tsdp_header_M_findA_at(m, "curr", i)); i++){ - if(sscanf(A->value, "qos e2e %10s", s0) != EOF){ - tmedia_qos_direction_t dir = tmedia_qos_direction_fromstring(s0); - switch(dir){ - case tmedia_qos_direction_send: - e2e->send.current = tsk_true; - break; - case tmedia_qos_direction_recv: - e2e->recv.current = tsk_true; - break; - case tmedia_qos_direction_sendrecv: - e2e->send.current = tsk_true; - e2e->recv.current = tsk_true; - break; - case tmedia_qos_direction_none: - e2e->send.current = tsk_false; - e2e->recv.current = tsk_false; - break; - default: - break; - } - } - else{ - TSK_DEBUG_ERROR("Failed to parse a=%s:%s", A->field, A->value); - } - } - - /* des */ - for(i = 0; (A = tsdp_header_M_findA_at(m, "des", i)); i++){ - if(sscanf(A->value, "qos %10s e2e %10s", s0, s1) != EOF){ - tmedia_qos_strength_t strength = tmedia_qos_strength_fromstring(s0); - tmedia_qos_direction_t dir = tmedia_qos_direction_fromstring(s1); - switch(dir){ - case tmedia_qos_direction_send: - e2e->send.strength = strength; - break; - case tmedia_qos_direction_recv: - e2e->recv.strength = strength; - break; - case tmedia_qos_direction_sendrecv: - e2e->send.strength = strength; - e2e->recv.strength = strength; - break; - default: - break; - } - } - else{ - TSK_DEBUG_ERROR("Failed to parse a=%s:%s", A->field, A->value); - } - } - - /* conf */ - for(i = 0; (A = tsdp_header_M_findA_at(m, "conf", i)); i++){ - if(sscanf(A->value, "qos e2e %10s", s0) != EOF){ - tmedia_qos_direction_t dir = tmedia_qos_direction_fromstring(s0); - switch(dir){ - case tmedia_qos_direction_send: - e2e->send.confirm = tsk_true; - break; - case tmedia_qos_direction_recv: - e2e->recv.confirm = tsk_true; - break; - case tmedia_qos_direction_sendrecv: - e2e->send.confirm = tsk_true; - e2e->recv.confirm = tsk_true; - break; - default: - break; - } - } - else{ - TSK_DEBUG_ERROR("Failed to parse a=%s:%s", A->field, A->value); - } - } - - return e2e; + tmedia_qos_tline_e2e_t* e2e = tsk_null; + const tsdp_header_A_t* A; + tsk_size_t i; + + char s0[10], s1[10]; + + if(!m) { + TSK_DEBUG_ERROR("invalid parameter"); + return tsk_null; + } + + /* Example + a=curr:qos e2e none + a=des:qos mandatory e2e sendrecv + a=conf:qos e2e recv + */ + + e2e = tmedia_qos_tline_e2e_create(tmedia_qos_strength_unknown); + + /* curr */ + for(i = 0; (A = tsdp_header_M_findA_at(m, "curr", i)); i++) { + if(sscanf(A->value, "qos e2e %10s", s0) != EOF) { + tmedia_qos_direction_t dir = tmedia_qos_direction_fromstring(s0); + switch(dir) { + case tmedia_qos_direction_send: + e2e->send.current = tsk_true; + break; + case tmedia_qos_direction_recv: + e2e->recv.current = tsk_true; + break; + case tmedia_qos_direction_sendrecv: + e2e->send.current = tsk_true; + e2e->recv.current = tsk_true; + break; + case tmedia_qos_direction_none: + e2e->send.current = tsk_false; + e2e->recv.current = tsk_false; + break; + default: + break; + } + } + else { + TSK_DEBUG_ERROR("Failed to parse a=%s:%s", A->field, A->value); + } + } + + /* des */ + for(i = 0; (A = tsdp_header_M_findA_at(m, "des", i)); i++) { + if(sscanf(A->value, "qos %10s e2e %10s", s0, s1) != EOF) { + tmedia_qos_strength_t strength = tmedia_qos_strength_fromstring(s0); + tmedia_qos_direction_t dir = tmedia_qos_direction_fromstring(s1); + switch(dir) { + case tmedia_qos_direction_send: + e2e->send.strength = strength; + break; + case tmedia_qos_direction_recv: + e2e->recv.strength = strength; + break; + case tmedia_qos_direction_sendrecv: + e2e->send.strength = strength; + e2e->recv.strength = strength; + break; + default: + break; + } + } + else { + TSK_DEBUG_ERROR("Failed to parse a=%s:%s", A->field, A->value); + } + } + + /* conf */ + for(i = 0; (A = tsdp_header_M_findA_at(m, "conf", i)); i++) { + if(sscanf(A->value, "qos e2e %10s", s0) != EOF) { + tmedia_qos_direction_t dir = tmedia_qos_direction_fromstring(s0); + switch(dir) { + case tmedia_qos_direction_send: + e2e->send.confirm = tsk_true; + break; + case tmedia_qos_direction_recv: + e2e->recv.confirm = tsk_true; + break; + case tmedia_qos_direction_sendrecv: + e2e->send.confirm = tsk_true; + e2e->recv.confirm = tsk_true; + break; + default: + break; + } + } + else { + TSK_DEBUG_ERROR("Failed to parse a=%s:%s", A->field, A->value); + } + } + + return e2e; } int tmedia_qos_tline_e2e_to_sdp(const tmedia_qos_tline_e2e_t* self, tsdp_header_M_t* m) { - /* RFC 3312 - 5.1.1 SDP encoding - - For the end-to-end status type, the user agent MUST generate one - current status line with the tag "e2e" for the media stream. If the - strength-tags for both directions are equal (e.g., both "mandatory") - in the transaction status table, the user agent MUST add one desired - status line with the tag "sendrecv". If both tags are different, the - user agent MUST include two desired status lines, one with the tag - "send" and the other with the tag "recv". - */ - char* temp = tsk_null; - - if(!self || !m){ - TSK_DEBUG_ERROR("invalid parameter"); - return -1; - } - /* Example - a=curr:qos e2e none - a=des:qos mandatory e2e sendrecv - */ - - - /* curr */ - tsk_sprintf(&temp, "qos e2e %s", (self->recv.current && self->send.current) ? "sendrecv" : (self->recv.current ? "recv" : (self->send.current ? "send" : "none"))); - tsdp_header_M_add_headers(m, - TSDP_HEADER_A_VA_ARGS("curr", temp), - tsk_null); - TSK_FREE(temp); - - /* des */ - if(self->recv.strength == self->send.strength){ - /* sendrecv */ - tsk_sprintf(&temp, "qos %s e2e sendrecv", tmedia_qos_strength_tostring(self->recv.strength)); - tsdp_header_M_add_headers(m, - TSDP_HEADER_A_VA_ARGS("des", temp), - tsk_null); - TSK_FREE(temp); - } - else{ - /* send */ - tsk_sprintf(&temp, "qos %s e2e send", tmedia_qos_strength_tostring(self->send.strength)); - tsdp_header_M_add_headers(m, - TSDP_HEADER_A_VA_ARGS("des", temp), - tsk_null); - TSK_FREE(temp); - - /* recv */ - tsk_sprintf(&temp, "qos %s e2e recv", tmedia_qos_strength_tostring(self->recv.strength)); - tsdp_header_M_add_headers(m, - TSDP_HEADER_A_VA_ARGS("des", temp), - tsk_null); - TSK_FREE(temp); - } - - /* conf (should not request confirm on "send" direction)*/ - if(self->recv.confirm){ - tsdp_header_M_add_headers(m, - TSDP_HEADER_A_VA_ARGS("conf", "qos e2e recv"), - tsk_null); - } - return 0; + /* RFC 3312 - 5.1.1 SDP encoding + + For the end-to-end status type, the user agent MUST generate one + current status line with the tag "e2e" for the media stream. If the + strength-tags for both directions are equal (e.g., both "mandatory") + in the transaction status table, the user agent MUST add one desired + status line with the tag "sendrecv". If both tags are different, the + user agent MUST include two desired status lines, one with the tag + "send" and the other with the tag "recv". + */ + char* temp = tsk_null; + + if(!self || !m) { + TSK_DEBUG_ERROR("invalid parameter"); + return -1; + } + /* Example + a=curr:qos e2e none + a=des:qos mandatory e2e sendrecv + */ + + + /* curr */ + tsk_sprintf(&temp, "qos e2e %s", (self->recv.current && self->send.current) ? "sendrecv" : (self->recv.current ? "recv" : (self->send.current ? "send" : "none"))); + tsdp_header_M_add_headers(m, + TSDP_HEADER_A_VA_ARGS("curr", temp), + tsk_null); + TSK_FREE(temp); + + /* des */ + if(self->recv.strength == self->send.strength) { + /* sendrecv */ + tsk_sprintf(&temp, "qos %s e2e sendrecv", tmedia_qos_strength_tostring(self->recv.strength)); + tsdp_header_M_add_headers(m, + TSDP_HEADER_A_VA_ARGS("des", temp), + tsk_null); + TSK_FREE(temp); + } + else { + /* send */ + tsk_sprintf(&temp, "qos %s e2e send", tmedia_qos_strength_tostring(self->send.strength)); + tsdp_header_M_add_headers(m, + TSDP_HEADER_A_VA_ARGS("des", temp), + tsk_null); + TSK_FREE(temp); + + /* recv */ + tsk_sprintf(&temp, "qos %s e2e recv", tmedia_qos_strength_tostring(self->recv.strength)); + tsdp_header_M_add_headers(m, + TSDP_HEADER_A_VA_ARGS("des", temp), + tsk_null); + TSK_FREE(temp); + } + + /* conf (should not request confirm on "send" direction)*/ + if(self->recv.confirm) { + tsdp_header_M_add_headers(m, + TSDP_HEADER_A_VA_ARGS("conf", "qos e2e recv"), + tsk_null); + } + return 0; } int tmedia_qos_tline_e2e_set_ro(tmedia_qos_tline_e2e_t* self, const tmedia_qos_tline_e2e_t* ro) { - if(!self || !ro){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - - /* We were the offerer - * Remote asked for confirmation in its "recv" direction? - * "recv" direction for remote is our "send" direction - * As we don't support RSVP (under the way), confirm immediatly. - * "send" direction should not requested for confirmation - */ - if(ro->recv.confirm){ - self->send.current = tsk_true; - goto bail; - } - if(ro->send.current){ - self->recv.confirm = tsk_false; /* remote confirmed */ - self->recv.current = tsk_true; /* because ro confirmed */ - self->send.current = tsk_true; /* beacuse we don't support RSVP */ - goto bail; - } - - /* We are the answerer - * As we don't support RSVP (under the way): - * ==> request confirmation for "recv" direction if equal to "none" (not reserved) - * => - */ - if(!self->recv.current){ - self->recv.confirm = tsk_true; - goto bail; - } + if(!self || !ro) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + + /* We were the offerer + * Remote asked for confirmation in its "recv" direction? + * "recv" direction for remote is our "send" direction + * As we don't support RSVP (under the way), confirm immediatly. + * "send" direction should not requested for confirmation + */ + if(ro->recv.confirm) { + self->send.current = tsk_true; + goto bail; + } + if(ro->send.current) { + self->recv.confirm = tsk_false; /* remote confirmed */ + self->recv.current = tsk_true; /* because ro confirmed */ + self->send.current = tsk_true; /* beacuse we don't support RSVP */ + goto bail; + } + + /* We are the answerer + * As we don't support RSVP (under the way): + * ==> request confirmation for "recv" direction if equal to "none" (not reserved) + * => + */ + if(!self->recv.current) { + self->recv.confirm = tsk_true; + goto bail; + } bail: - /* all other cases: success */ - return 0; + /* all other cases: success */ + return 0; } tsk_bool_t tmedia_qos_tline_e2e_canresume(const tmedia_qos_tline_e2e_t* self) { - if(!self){ - TSK_DEBUG_ERROR("Invalid parameter"); - return tsk_true; - } - - /* Example - a=curr:qos e2e none - a=des:qos mandatory e2e sendrecv - - Or - - a=curr:qos e2e send - a=des:qos mandatory e2e recv - a=des:qos optional e2e send - */ - - /* only "mandatory" strength should force the application to continue nego. */ - if(self->recv.strength == tmedia_qos_strength_mandatory && !self->recv.current){ - return tsk_false; - } - /*else */if(self->send.strength == tmedia_qos_strength_mandatory && !self->send.current){ - return tsk_false; - } - - /* "optinal" and "none" strengths */ - return tsk_true; + if(!self) { + TSK_DEBUG_ERROR("Invalid parameter"); + return tsk_true; + } + + /* Example + a=curr:qos e2e none + a=des:qos mandatory e2e sendrecv + + Or + + a=curr:qos e2e send + a=des:qos mandatory e2e recv + a=des:qos optional e2e send + */ + + /* only "mandatory" strength should force the application to continue nego. */ + if(self->recv.strength == tmedia_qos_strength_mandatory && !self->recv.current) { + return tsk_false; + } + /*else */if(self->send.strength == tmedia_qos_strength_mandatory && !self->send.current) { + return tsk_false; + } + + /* "optinal" and "none" strengths */ + return tsk_true; } // @@ -438,29 +439,28 @@ tsk_bool_t tmedia_qos_tline_e2e_canresume(const tmedia_qos_tline_e2e_t* self) // static tsk_object_t* tmedia_qos_tline_e2e_ctor(tsk_object_t * self, va_list * app) { - tmedia_qos_tline_e2e_t *e2e = self; - if(e2e){ - e2e->recv.strength = e2e->send.strength = va_arg(*app, tmedia_qos_strength_t); - TMEDIA_QOS_TLINE(e2e)->type = tmedia_qos_stype_e2e; - } - return self; + tmedia_qos_tline_e2e_t *e2e = self; + if(e2e) { + e2e->recv.strength = e2e->send.strength = va_arg(*app, tmedia_qos_strength_t); + TMEDIA_QOS_TLINE(e2e)->type = tmedia_qos_stype_e2e; + } + return self; } static tsk_object_t* tmedia_qos_tline_e2e_dtor(tsk_object_t * self) -{ - tmedia_qos_tline_e2e_t *e2e = self; - if(e2e){ - } +{ + tmedia_qos_tline_e2e_t *e2e = self; + if(e2e) { + } - return self; + return self; } -static const tsk_object_def_t tmedia_qos_tline_e2e_def_s = -{ - sizeof(tmedia_qos_tline_e2e_t), - tmedia_qos_tline_e2e_ctor, - tmedia_qos_tline_e2e_dtor, - tsk_null, +static const tsk_object_def_t tmedia_qos_tline_e2e_def_s = { + sizeof(tmedia_qos_tline_e2e_t), + tmedia_qos_tline_e2e_ctor, + tmedia_qos_tline_e2e_dtor, + tsk_null, }; const tsk_object_def_t *tmedia_qos_tline_e2e_def_t = &tmedia_qos_tline_e2e_def_s; @@ -477,356 +477,356 @@ const tsk_object_def_t *tmedia_qos_tline_e2e_def_t = &tmedia_qos_tline_e2e_def_s tmedia_qos_tline_segmented_t* tmedia_qos_tline_segmented_create(tmedia_qos_strength_t strength) { - return tsk_object_new(tmedia_qos_tline_segmented_def_t, strength); + return tsk_object_new(tmedia_qos_tline_segmented_def_t, strength); } tmedia_qos_tline_segmented_t* tmedia_qos_tline_segmented_from_sdp(const tsdp_header_M_t* m) { - tmedia_qos_tline_segmented_t* segmented = tsk_null; - const tsdp_header_A_t* A; - tsk_size_t i; - - char s0[10], s1[10], s2[10]; - - if(!m){ - TSK_DEBUG_ERROR("invalid parameter"); - return tsk_null; - } - - /* Example - a=curr:qos local none - a=curr:qos remote none - a=des:qos optional remote send - a=des:qos none remote recv - a=des:qos none local sendrecv - a=conf:qos local recv - */ - segmented = tmedia_qos_tline_segmented_create(tmedia_qos_strength_unknown); - - /* curr */ - for(i = 0; (A = tsdp_header_M_findA_at(m, "curr", i)); i++){ - if(sscanf(A->value, "qos %10s %10s", s0, s1) != EOF){ - /* For segmented, s0 should be equal to "local" or "remote" */ - tmedia_qos_direction_t dir = tmedia_qos_direction_fromstring(s1); - if(tsk_strequals(s0, "local")){ - /* local */ - switch(dir){ - case tmedia_qos_direction_send: - segmented->local_send.current = tsk_true; - break; - case tmedia_qos_direction_recv: - segmented->local_recv.current = tsk_true; - break; - case tmedia_qos_direction_sendrecv: - segmented->local_send.current = tsk_true; - segmented->local_recv.current = tsk_true; - break; - case tmedia_qos_direction_none: - segmented->local_send.current = tsk_false; - segmented->local_recv.current = tsk_false; - break; - default: - break; - } - } - else{ - /* remote */ - switch(dir){ - case tmedia_qos_direction_send: - segmented->remote_send.current = tsk_true; - break; - case tmedia_qos_direction_recv: - segmented->remote_recv.current = tsk_true; - break; - case tmedia_qos_direction_sendrecv: - segmented->remote_send.current = tsk_true; - segmented->remote_recv.current = tsk_true; - break; - case tmedia_qos_direction_none: - segmented->remote_send.current = tsk_false; - segmented->remote_recv.current = tsk_false; - break; - default: - break; - } - } - } - else{ - TSK_DEBUG_ERROR("Failed to parse a=%s:%s", A->field, A->value); - } - } - - /* des */ - for(i = 0; (A = tsdp_header_M_findA_at(m, "des", i)); i++){ - if(sscanf(A->value, "qos %10s %10s %10s", s0, s1, s2) != EOF){ - /* For segmented, s1 should be equal to "local" or "remote" */ - tmedia_qos_strength_t strength = tmedia_qos_strength_fromstring(s0); - tmedia_qos_direction_t dir = tmedia_qos_direction_fromstring(s2); - if(tsk_strequals(s1, "local")){ - /* local */ - switch(dir){ - case tmedia_qos_direction_send: - segmented->local_send.strength = strength; - break; - case tmedia_qos_direction_recv: - segmented->local_recv.strength = strength; - break; - case tmedia_qos_direction_sendrecv: - segmented->local_send.strength = strength; - segmented->local_recv.strength = strength; - break; - default: - break; - } - } - else{ - /* remote */ - switch(dir){ - case tmedia_qos_direction_send: - segmented->remote_send.strength = strength; - break; - case tmedia_qos_direction_recv: - segmented->remote_recv.strength = strength; - break; - case tmedia_qos_direction_sendrecv: - segmented->remote_send.strength = strength; - segmented->remote_recv.strength = strength; - break; - default: - break; - } - } - } - else{ - TSK_DEBUG_ERROR("Failed to parse a=%s:%s", A->field, A->value); - } - } - - /* conf */ - for(i = 0; (A = tsdp_header_M_findA_at(m, "conf", i)); i++){ - if(sscanf(A->value, "qos %10s %10s", s0, s1) != EOF){ - /* For segmented, s0 should be equal to "local" or "remote" */ - tmedia_qos_direction_t dir = tmedia_qos_direction_fromstring(s1); - if(tsk_strequals(s0, "local")){ - /* local */ - switch(dir){ - case tmedia_qos_direction_send: - segmented->local_send.confirm = tsk_true; - break; - case tmedia_qos_direction_recv: - segmented->local_recv.confirm = tsk_true; - break; - case tmedia_qos_direction_sendrecv: - segmented->local_send.confirm = tsk_true; - segmented->local_recv.confirm = tsk_true; - break; - default: - break; - } - } - else{ - /* remote */ - switch(dir){ - case tmedia_qos_direction_send: - segmented->remote_send.confirm = tsk_true; - break; - case tmedia_qos_direction_recv: - segmented->remote_recv.confirm = tsk_true; - break; - case tmedia_qos_direction_sendrecv: - segmented->remote_send.confirm = tsk_true; - segmented->remote_recv.confirm = tsk_true; - break; - default: - break; - } - } - } - else{ - TSK_DEBUG_ERROR("Failed to parse a=%s:%s", A->field, A->value); - } - } - - return segmented; + tmedia_qos_tline_segmented_t* segmented = tsk_null; + const tsdp_header_A_t* A; + tsk_size_t i; + + char s0[10], s1[10], s2[10]; + + if(!m) { + TSK_DEBUG_ERROR("invalid parameter"); + return tsk_null; + } + + /* Example + a=curr:qos local none + a=curr:qos remote none + a=des:qos optional remote send + a=des:qos none remote recv + a=des:qos none local sendrecv + a=conf:qos local recv + */ + segmented = tmedia_qos_tline_segmented_create(tmedia_qos_strength_unknown); + + /* curr */ + for(i = 0; (A = tsdp_header_M_findA_at(m, "curr", i)); i++) { + if(sscanf(A->value, "qos %10s %10s", s0, s1) != EOF) { + /* For segmented, s0 should be equal to "local" or "remote" */ + tmedia_qos_direction_t dir = tmedia_qos_direction_fromstring(s1); + if(tsk_strequals(s0, "local")) { + /* local */ + switch(dir) { + case tmedia_qos_direction_send: + segmented->local_send.current = tsk_true; + break; + case tmedia_qos_direction_recv: + segmented->local_recv.current = tsk_true; + break; + case tmedia_qos_direction_sendrecv: + segmented->local_send.current = tsk_true; + segmented->local_recv.current = tsk_true; + break; + case tmedia_qos_direction_none: + segmented->local_send.current = tsk_false; + segmented->local_recv.current = tsk_false; + break; + default: + break; + } + } + else { + /* remote */ + switch(dir) { + case tmedia_qos_direction_send: + segmented->remote_send.current = tsk_true; + break; + case tmedia_qos_direction_recv: + segmented->remote_recv.current = tsk_true; + break; + case tmedia_qos_direction_sendrecv: + segmented->remote_send.current = tsk_true; + segmented->remote_recv.current = tsk_true; + break; + case tmedia_qos_direction_none: + segmented->remote_send.current = tsk_false; + segmented->remote_recv.current = tsk_false; + break; + default: + break; + } + } + } + else { + TSK_DEBUG_ERROR("Failed to parse a=%s:%s", A->field, A->value); + } + } + + /* des */ + for(i = 0; (A = tsdp_header_M_findA_at(m, "des", i)); i++) { + if(sscanf(A->value, "qos %10s %10s %10s", s0, s1, s2) != EOF) { + /* For segmented, s1 should be equal to "local" or "remote" */ + tmedia_qos_strength_t strength = tmedia_qos_strength_fromstring(s0); + tmedia_qos_direction_t dir = tmedia_qos_direction_fromstring(s2); + if(tsk_strequals(s1, "local")) { + /* local */ + switch(dir) { + case tmedia_qos_direction_send: + segmented->local_send.strength = strength; + break; + case tmedia_qos_direction_recv: + segmented->local_recv.strength = strength; + break; + case tmedia_qos_direction_sendrecv: + segmented->local_send.strength = strength; + segmented->local_recv.strength = strength; + break; + default: + break; + } + } + else { + /* remote */ + switch(dir) { + case tmedia_qos_direction_send: + segmented->remote_send.strength = strength; + break; + case tmedia_qos_direction_recv: + segmented->remote_recv.strength = strength; + break; + case tmedia_qos_direction_sendrecv: + segmented->remote_send.strength = strength; + segmented->remote_recv.strength = strength; + break; + default: + break; + } + } + } + else { + TSK_DEBUG_ERROR("Failed to parse a=%s:%s", A->field, A->value); + } + } + + /* conf */ + for(i = 0; (A = tsdp_header_M_findA_at(m, "conf", i)); i++) { + if(sscanf(A->value, "qos %10s %10s", s0, s1) != EOF) { + /* For segmented, s0 should be equal to "local" or "remote" */ + tmedia_qos_direction_t dir = tmedia_qos_direction_fromstring(s1); + if(tsk_strequals(s0, "local")) { + /* local */ + switch(dir) { + case tmedia_qos_direction_send: + segmented->local_send.confirm = tsk_true; + break; + case tmedia_qos_direction_recv: + segmented->local_recv.confirm = tsk_true; + break; + case tmedia_qos_direction_sendrecv: + segmented->local_send.confirm = tsk_true; + segmented->local_recv.confirm = tsk_true; + break; + default: + break; + } + } + else { + /* remote */ + switch(dir) { + case tmedia_qos_direction_send: + segmented->remote_send.confirm = tsk_true; + break; + case tmedia_qos_direction_recv: + segmented->remote_recv.confirm = tsk_true; + break; + case tmedia_qos_direction_sendrecv: + segmented->remote_send.confirm = tsk_true; + segmented->remote_recv.confirm = tsk_true; + break; + default: + break; + } + } + } + else { + TSK_DEBUG_ERROR("Failed to parse a=%s:%s", A->field, A->value); + } + } + + return segmented; } int tmedia_qos_tline_segmented_to_sdp(const tmedia_qos_tline_segmented_t* self, tsdp_header_M_t* m) { - /* RFC 3312 - 5.1.1 SDP encoding - - For the segmented status type, the user agent MUST generate two - current status lines: one with the tag "local" and the other with the - tag "remote". The user agent MUST add one or two desired status - lines per segment (i.e., local and remote). If, for a particular - segment (local or remote), the tags for both directions in the - transaction status table are equal (e.g., both "mandatory"), the user - agent MUST add one desired status line with the tag "sendrecv". If - both tags are different, the user agent MUST include two desired - status lines, one with the tag "send" and the other with the tag "recv". - */ - char* temp = tsk_null; - - if(!self || !m){ - TSK_DEBUG_ERROR("invalid parameter"); - return -1; - } - - /* Example - a=curr:qos local none - a=curr:qos remote none - a=des:qos optional remote send - a=des:qos none remote recv - a=des:qos none local sendrecv - */ - - /* curr:local */ - tsk_sprintf(&temp, "qos local %s", (self->local_recv.current && self->local_send.current) ? "sendrecv" : (self->local_recv.current ? "recv" : (self->local_send.current ? "send" : "none"))); - tsdp_header_M_add_headers(m, - TSDP_HEADER_A_VA_ARGS("curr", temp), - tsk_null); - TSK_FREE(temp); - - /* curr:remote */ - tsk_sprintf(&temp, "qos remote %s", (self->remote_recv.current && self->remote_send.current) ? "sendrecv" : (self->remote_recv.current ? "recv" : (self->remote_send.current ? "send" : "none"))); - tsdp_header_M_add_headers(m, - TSDP_HEADER_A_VA_ARGS("curr", temp), - tsk_null); - TSK_FREE(temp); - - - /* des:local */ - if(self->local_recv.strength == self->local_send.strength){ - /* sendrecv */ - tsk_sprintf(&temp, "qos %s local sendrecv", tmedia_qos_strength_tostring(self->local_send.strength)); - tsdp_header_M_add_headers(m, - TSDP_HEADER_A_VA_ARGS("des", temp), - tsk_null); - TSK_FREE(temp); - } - else{ - /* send */ - tsk_sprintf(&temp, "qos %s local send", tmedia_qos_strength_tostring(self->local_send.strength)); - tsdp_header_M_add_headers(m, - TSDP_HEADER_A_VA_ARGS("des", temp), - tsk_null); - TSK_FREE(temp); - - /* recv */ - tsk_sprintf(&temp, "qos %s local recv", tmedia_qos_strength_tostring(self->local_recv.strength)); - tsdp_header_M_add_headers(m, - TSDP_HEADER_A_VA_ARGS("des", temp), - tsk_null); - TSK_FREE(temp); - } - - - /* des:remote */ - if(self->remote_recv.strength == self->remote_send.strength){ - /* sendrecv */ - tsk_sprintf(&temp, "qos %s remote sendrecv", tmedia_qos_strength_tostring(self->remote_send.strength)); - tsdp_header_M_add_headers(m, - TSDP_HEADER_A_VA_ARGS("des", temp), - tsk_null); - TSK_FREE(temp); - } - else{ - /* send */ - tsk_sprintf(&temp, "qos %s remote send", tmedia_qos_strength_tostring(self->remote_send.strength)); - tsdp_header_M_add_headers(m, - TSDP_HEADER_A_VA_ARGS("des", temp), - tsk_null); - TSK_FREE(temp); - - /* recv */ - tsk_sprintf(&temp, "qos %s remote recv", tmedia_qos_strength_tostring(self->remote_recv.strength)); - tsdp_header_M_add_headers(m, - TSDP_HEADER_A_VA_ARGS("des", temp), - tsk_null); - TSK_FREE(temp); - } - - /* conf */ - if(self->remote_recv.confirm || self->remote_send.confirm){ - tsk_sprintf(&temp, "qos remote %s", (self->remote_recv.confirm && self->remote_send.confirm) ? "sendrecv" : (self->remote_recv.confirm ? "recv" : (self->remote_send.confirm ? "send" : "none"))); - tsdp_header_M_add_headers(m, - TSDP_HEADER_A_VA_ARGS("conf", temp), - tsk_null); - TSK_FREE(temp); - } - - return 0; + /* RFC 3312 - 5.1.1 SDP encoding + + For the segmented status type, the user agent MUST generate two + current status lines: one with the tag "local" and the other with the + tag "remote". The user agent MUST add one or two desired status + lines per segment (i.e., local and remote). If, for a particular + segment (local or remote), the tags for both directions in the + transaction status table are equal (e.g., both "mandatory"), the user + agent MUST add one desired status line with the tag "sendrecv". If + both tags are different, the user agent MUST include two desired + status lines, one with the tag "send" and the other with the tag "recv". + */ + char* temp = tsk_null; + + if(!self || !m) { + TSK_DEBUG_ERROR("invalid parameter"); + return -1; + } + + /* Example + a=curr:qos local none + a=curr:qos remote none + a=des:qos optional remote send + a=des:qos none remote recv + a=des:qos none local sendrecv + */ + + /* curr:local */ + tsk_sprintf(&temp, "qos local %s", (self->local_recv.current && self->local_send.current) ? "sendrecv" : (self->local_recv.current ? "recv" : (self->local_send.current ? "send" : "none"))); + tsdp_header_M_add_headers(m, + TSDP_HEADER_A_VA_ARGS("curr", temp), + tsk_null); + TSK_FREE(temp); + + /* curr:remote */ + tsk_sprintf(&temp, "qos remote %s", (self->remote_recv.current && self->remote_send.current) ? "sendrecv" : (self->remote_recv.current ? "recv" : (self->remote_send.current ? "send" : "none"))); + tsdp_header_M_add_headers(m, + TSDP_HEADER_A_VA_ARGS("curr", temp), + tsk_null); + TSK_FREE(temp); + + + /* des:local */ + if(self->local_recv.strength == self->local_send.strength) { + /* sendrecv */ + tsk_sprintf(&temp, "qos %s local sendrecv", tmedia_qos_strength_tostring(self->local_send.strength)); + tsdp_header_M_add_headers(m, + TSDP_HEADER_A_VA_ARGS("des", temp), + tsk_null); + TSK_FREE(temp); + } + else { + /* send */ + tsk_sprintf(&temp, "qos %s local send", tmedia_qos_strength_tostring(self->local_send.strength)); + tsdp_header_M_add_headers(m, + TSDP_HEADER_A_VA_ARGS("des", temp), + tsk_null); + TSK_FREE(temp); + + /* recv */ + tsk_sprintf(&temp, "qos %s local recv", tmedia_qos_strength_tostring(self->local_recv.strength)); + tsdp_header_M_add_headers(m, + TSDP_HEADER_A_VA_ARGS("des", temp), + tsk_null); + TSK_FREE(temp); + } + + + /* des:remote */ + if(self->remote_recv.strength == self->remote_send.strength) { + /* sendrecv */ + tsk_sprintf(&temp, "qos %s remote sendrecv", tmedia_qos_strength_tostring(self->remote_send.strength)); + tsdp_header_M_add_headers(m, + TSDP_HEADER_A_VA_ARGS("des", temp), + tsk_null); + TSK_FREE(temp); + } + else { + /* send */ + tsk_sprintf(&temp, "qos %s remote send", tmedia_qos_strength_tostring(self->remote_send.strength)); + tsdp_header_M_add_headers(m, + TSDP_HEADER_A_VA_ARGS("des", temp), + tsk_null); + TSK_FREE(temp); + + /* recv */ + tsk_sprintf(&temp, "qos %s remote recv", tmedia_qos_strength_tostring(self->remote_recv.strength)); + tsdp_header_M_add_headers(m, + TSDP_HEADER_A_VA_ARGS("des", temp), + tsk_null); + TSK_FREE(temp); + } + + /* conf */ + if(self->remote_recv.confirm || self->remote_send.confirm) { + tsk_sprintf(&temp, "qos remote %s", (self->remote_recv.confirm && self->remote_send.confirm) ? "sendrecv" : (self->remote_recv.confirm ? "recv" : (self->remote_send.confirm ? "send" : "none"))); + tsdp_header_M_add_headers(m, + TSDP_HEADER_A_VA_ARGS("conf", temp), + tsk_null); + TSK_FREE(temp); + } + + return 0; } int tmedia_qos_tline_segmented_set_ro(tmedia_qos_tline_segmented_t* self, const tmedia_qos_tline_segmented_t* ro) { - if(!self || !ro){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - - ////////////// - if(!ro->local_recv.current && !ro->remote_recv.confirm){ - /* request confirmation */ - self->remote_recv.confirm = tsk_true; - } - else{ - self->remote_recv.confirm = tsk_false; - self->local_recv.current = tsk_true; - } - if(!ro->local_send.current && !ro->remote_send.confirm){ - /* request confirmation */ - self->remote_send.confirm = tsk_true; - } - else{ - self->remote_send.confirm = tsk_false; - self->local_send.current = tsk_true; - } - - ////////////// - if(ro->remote_recv.confirm){ - self->local_recv.current = tsk_true; - } - if(ro->remote_send.confirm){ - self->local_send.current = tsk_true; - } - - ////////////// - if(ro->local_recv.current){ - self->remote_recv.current = tsk_true; - } - if(ro->local_send.current){ - self->remote_send.current = tsk_true; - } - - return 0; + if(!self || !ro) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + + ////////////// + if(!ro->local_recv.current && !ro->remote_recv.confirm) { + /* request confirmation */ + self->remote_recv.confirm = tsk_true; + } + else { + self->remote_recv.confirm = tsk_false; + self->local_recv.current = tsk_true; + } + if(!ro->local_send.current && !ro->remote_send.confirm) { + /* request confirmation */ + self->remote_send.confirm = tsk_true; + } + else { + self->remote_send.confirm = tsk_false; + self->local_send.current = tsk_true; + } + + ////////////// + if(ro->remote_recv.confirm) { + self->local_recv.current = tsk_true; + } + if(ro->remote_send.confirm) { + self->local_send.current = tsk_true; + } + + ////////////// + if(ro->local_recv.current) { + self->remote_recv.current = tsk_true; + } + if(ro->local_send.current) { + self->remote_send.current = tsk_true; + } + + return 0; } tsk_bool_t tmedia_qos_tline_segmented_canresume(const tmedia_qos_tline_segmented_t* self) { - if(!self){ - TSK_DEBUG_ERROR("Invalid parameter"); - return tsk_true; - } - - /* == Strength is mandatory == */ - if(self->local_recv.strength == tmedia_qos_strength_mandatory && !self->local_recv.current){ - return tsk_false; - } - - if(self->local_send.strength == tmedia_qos_strength_mandatory && !self->local_send.current){ - return tsk_false; - } - - if(self->remote_recv.strength == tmedia_qos_strength_mandatory && !self->remote_recv.current){ - return tsk_false; - } - - if(self->remote_send.strength == tmedia_qos_strength_mandatory && !self->remote_send.current){ - return tsk_false; - } - - /* "optinal" and "none" strengths */ - return tsk_true; + if(!self) { + TSK_DEBUG_ERROR("Invalid parameter"); + return tsk_true; + } + + /* == Strength is mandatory == */ + if(self->local_recv.strength == tmedia_qos_strength_mandatory && !self->local_recv.current) { + return tsk_false; + } + + if(self->local_send.strength == tmedia_qos_strength_mandatory && !self->local_send.current) { + return tsk_false; + } + + if(self->remote_recv.strength == tmedia_qos_strength_mandatory && !self->remote_recv.current) { + return tsk_false; + } + + if(self->remote_send.strength == tmedia_qos_strength_mandatory && !self->remote_send.current) { + return tsk_false; + } + + /* "optinal" and "none" strengths */ + return tsk_true; } // @@ -834,29 +834,28 @@ tsk_bool_t tmedia_qos_tline_segmented_canresume(const tmedia_qos_tline_segmented // static tsk_object_t* tmedia_qos_tline_segmented_ctor(tsk_object_t * self, va_list * app) { - tmedia_qos_tline_segmented_t *segmented = self; - if(segmented){ - segmented->local_recv.strength = segmented->local_send.strength - = segmented->remote_recv.strength = segmented->remote_send.strength = va_arg(*app, tmedia_qos_strength_t); - TMEDIA_QOS_TLINE(segmented)->type = tmedia_qos_stype_segmented; - } - return self; + tmedia_qos_tline_segmented_t *segmented = self; + if(segmented) { + segmented->local_recv.strength = segmented->local_send.strength + = segmented->remote_recv.strength = segmented->remote_send.strength = va_arg(*app, tmedia_qos_strength_t); + TMEDIA_QOS_TLINE(segmented)->type = tmedia_qos_stype_segmented; + } + return self; } static tsk_object_t* tmedia_qos_tline_segmented_dtor(tsk_object_t * self) -{ - tmedia_qos_tline_segmented_t *segmented = self; - if(segmented){ - } +{ + tmedia_qos_tline_segmented_t *segmented = self; + if(segmented) { + } - return self; + return self; } -static const tsk_object_def_t tmedia_qos_tline_segmented_def_s = -{ - sizeof(tmedia_qos_tline_segmented_t), - tmedia_qos_tline_segmented_ctor, - tmedia_qos_tline_segmented_dtor, - tsk_null, +static const tsk_object_def_t tmedia_qos_tline_segmented_def_s = { + sizeof(tmedia_qos_tline_segmented_t), + tmedia_qos_tline_segmented_ctor, + tmedia_qos_tline_segmented_dtor, + tsk_null, }; const tsk_object_def_t *tmedia_qos_tline_segmented_def_t = &tmedia_qos_tline_segmented_def_s;
\ No newline at end of file diff --git a/tinyMEDIA/src/tmedia_resampler.c b/tinyMEDIA/src/tmedia_resampler.c index 0d547cf..d4113de 100755 --- a/tinyMEDIA/src/tmedia_resampler.c +++ b/tinyMEDIA/src/tmedia_resampler.c @@ -2,19 +2,19 @@ * Copyright (C) 2011 Mamadou Diop. * * Contact: Mamadou Diop <diopmamadou(at)doubango[dot]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. * @@ -33,120 +33,120 @@ static const tmedia_resampler_plugin_def_t* __tmedia_resampler_plugin = tsk_null int tmedia_resampler_init(tmedia_resampler_t* self) { - if(!self){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - return 0; + if(!self) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + return 0; } int tmedia_resampler_open(tmedia_resampler_t* self, uint32_t in_freq, uint32_t out_freq, uint32_t frame_duration, uint32_t in_channels, uint32_t out_channels, uint32_t quality, uint32_t bits_per_sample) { - int ret; - - if (!self || !self->plugin || !self->plugin->open) { - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - if (self->opened) { - TSK_DEBUG_WARN("Resampler already opened"); - return 0; - } - - if ((ret = self->plugin->open(self, in_freq, out_freq, frame_duration, in_channels, out_channels, quality, bits_per_sample))) { - TSK_DEBUG_ERROR("Failed to open [%s] resamplerr", self->plugin->desc); - return ret; - } - else{ - self->opened = tsk_true; - return 0; - } + int ret; + + if (!self || !self->plugin || !self->plugin->open) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + if (self->opened) { + TSK_DEBUG_WARN("Resampler already opened"); + return 0; + } + + if ((ret = self->plugin->open(self, in_freq, out_freq, frame_duration, in_channels, out_channels, quality, bits_per_sample))) { + TSK_DEBUG_ERROR("Failed to open [%s] resamplerr", self->plugin->desc); + return ret; + } + else { + self->opened = tsk_true; + return 0; + } } tsk_size_t tmedia_resampler_process(tmedia_resampler_t* self, const void* in_data, tsk_size_t in_size_in_sample, void* out_data, tsk_size_t out_size_in_sample) { - if (!self || !in_data || !in_size_in_sample || !out_size_in_sample || !self->plugin || !self->plugin->process) { - TSK_DEBUG_ERROR("Invalid parameter"); - return 0; - } - if (!self->opened) { - TSK_DEBUG_ERROR("Resampler not opened"); - return 0; - } - return self->plugin->process(self, in_data, in_size_in_sample, out_data, out_size_in_sample); + if (!self || !in_data || !in_size_in_sample || !out_size_in_sample || !self->plugin || !self->plugin->process) { + TSK_DEBUG_ERROR("Invalid parameter"); + return 0; + } + if (!self->opened) { + TSK_DEBUG_ERROR("Resampler not opened"); + return 0; + } + return self->plugin->process(self, in_data, in_size_in_sample, out_data, out_size_in_sample); } int tmedia_resampler_close(tmedia_resampler_t* self) { - if (!self || !self->plugin) { - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - if (!self->opened) { - TSK_DEBUG_WARN("Resampler not opened"); - return 0; - } - - if (self->plugin->close) { - int ret; - - if ((ret = self->plugin->close(self))) { - TSK_DEBUG_ERROR("Failed to close [%s] resamplerr", self->plugin->desc); - return ret; - } - else { - self->opened = tsk_false; - return 0; - } - } - else { - self->opened = tsk_false; - return 0; - } + if (!self || !self->plugin) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + if (!self->opened) { + TSK_DEBUG_WARN("Resampler not opened"); + return 0; + } + + if (self->plugin->close) { + int ret; + + if ((ret = self->plugin->close(self))) { + TSK_DEBUG_ERROR("Failed to close [%s] resamplerr", self->plugin->desc); + return ret; + } + else { + self->opened = tsk_false; + return 0; + } + } + else { + self->opened = tsk_false; + return 0; + } } int tmedia_resampler_deinit(tmedia_resampler_t* self) { - if(!self){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } + if(!self) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } - if(self->opened){ - tmedia_resampler_close(self); - } + if(self->opened) { + tmedia_resampler_close(self); + } - return 0; + return 0; } int tmedia_resampler_plugin_register(const tmedia_resampler_plugin_def_t* plugin) { - if(!plugin){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - if(!__tmedia_resampler_plugin) { - TSK_DEBUG_INFO("Register resampler: %s", plugin->desc); - __tmedia_resampler_plugin = plugin; - } - return 0; + if(!plugin) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + if(!__tmedia_resampler_plugin) { + TSK_DEBUG_INFO("Register resampler: %s", plugin->desc); + __tmedia_resampler_plugin = plugin; + } + return 0; } int tmedia_resampler_plugin_unregister(const tmedia_resampler_plugin_def_t* plugin) { - (void)(plugin); - __tmedia_resampler_plugin = tsk_null; - return 0; + (void)(plugin); + __tmedia_resampler_plugin = tsk_null; + return 0; } tmedia_resampler_t* tmedia_resampler_create() { - tmedia_resampler_t* resampler = tsk_null; - - if(__tmedia_resampler_plugin){ - if((resampler = (tmedia_resampler_t*)tsk_object_new(__tmedia_resampler_plugin->objdef))){ - resampler->plugin = __tmedia_resampler_plugin; - } - } - return resampler; + tmedia_resampler_t* resampler = tsk_null; + + if(__tmedia_resampler_plugin) { + if((resampler = (tmedia_resampler_t*)tsk_object_new(__tmedia_resampler_plugin->objdef))) { + resampler->plugin = __tmedia_resampler_plugin; + } + } + return resampler; } diff --git a/tinyMEDIA/src/tmedia_session.c b/tinyMEDIA/src/tmedia_session.c index 08348d3..72c924a 100755 --- a/tinyMEDIA/src/tmedia_session.c +++ b/tinyMEDIA/src/tmedia_session.c @@ -82,52 +82,56 @@ int tmedia_session_set_ro(tmedia_session_t* self, const tsdp_header_M_t* m); /*== Predicate function to find session object by media */ static 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((const tmedia_session_t *)item->data), (const char*)media); - } - return -1; + if (item && item->data) { + return tsk_stricmp(tmedia_session_get_media((const tmedia_session_t *)item->data), (const char*)media); + } + return -1; } /*== Predicate function to find session object by type */ static int __pred_find_session_by_type(const tsk_list_item_t *item, const void *type) { - if (item && item->data){ - return ((const tmedia_session_t *)item->data)->type - *((tmedia_type_t*)type); - } - return -1; + if (item && item->data) { + return ((const tmedia_session_t *)item->data)->type - *((tmedia_type_t*)type); + } + return -1; } /*== Predicate function to find codec object by format */ static int __pred_find_codec_by_format(const tsk_list_item_t *item, const void *codec) { - if (item && item->data && codec){ - return tsk_stricmp(((const tmedia_codec_t*)item->data)->format, ((const tmedia_codec_t*)codec)->format); - } - return -1; + if (item && item->data && codec) { + return tsk_stricmp(((const tmedia_codec_t*)item->data)->format, ((const tmedia_codec_t*)codec)->format); + } + return -1; } /*== Predicate function to find codec object by id */ static int __pred_find_codec_by_id(const tsk_list_item_t *item, const void *id) { - if (item && item->data && id){ - if (((const tmedia_codec_t*)item->data)->id == *((const tmedia_codec_id_t*)id)){ - return 0; - } - } - return -1; + if (item && item->data && id) { + if (((const tmedia_codec_t*)item->data)->id == *((const tmedia_codec_id_t*)id)) { + return 0; + } + } + return -1; } -static tsk_size_t __flags_sum(const tsk_bool_t *flags, tsk_size_t count) { - tsk_size_t sum = 0, i; - for (i = 0; i < count; ++i) { - if (flags[i] == tsk_true) ++sum; - } - return sum; +static tsk_size_t __flags_sum(const tsk_bool_t *flags, tsk_size_t count) +{ + tsk_size_t sum = 0, i; + for (i = 0; i < count; ++i) { + if (flags[i] == tsk_true) { + ++sum; + } + } + return sum; } -uint64_t tmedia_session_get_unique_id(){ - static uint64_t __UniqueId = 1; // MUST not be equal to zero - return __UniqueId++; +uint64_t tmedia_session_get_unique_id() +{ + static uint64_t __UniqueId = 1; // MUST not be equal to zero + return __UniqueId++; } /**@ingroup tmedia_session_group @@ -138,135 +142,152 @@ uint64_t tmedia_session_get_unique_id(){ */ int tmedia_session_init(tmedia_session_t* self, tmedia_type_t type) { - int ret = 0; - - if (!self){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - - if (!self->initialized){ - /* set values */ - if (!self->id){ - self->id = tmedia_session_get_unique_id(); - } - self->type = type; - self->initialized = tsk_true; - self->bl = tmedia_defaults_get_bl(); - self->codecs_allowed = tmedia_codec_id_all; - self->bypass_encoding = tmedia_defaults_get_bypass_encoding(); - self->bypass_decoding = tmedia_defaults_get_bypass_decoding(); - /* SSL certificates */{ - const char* priv_path = tsk_null, *pub_path = tsk_null, *ca_path = tsk_null; - tsk_bool_t verify = tsk_false; - if ((ret = tmedia_defaults_get_ssl_certs(&priv_path, &pub_path, &ca_path, &verify))) { - return ret; - } - self->dtls.file_pvk = tsk_strdup(priv_path); - self->dtls.file_pbk = tsk_strdup(pub_path); - self->dtls.file_ca = tsk_strdup(ca_path); - self->dtls.verify = verify; - } - /* load associated codecs */ - ret = _tmedia_session_load_codecs(self); - } - - return 0; + int ret = 0; + + if (!self) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + + if (!self->initialized) { + /* set values */ + if (!self->id) { + self->id = tmedia_session_get_unique_id(); + } + self->type = type; + self->initialized = tsk_true; + self->bl = tmedia_defaults_get_bl(); + self->codecs_allowed = tmedia_codec_id_all; + self->bypass_encoding = tmedia_defaults_get_bypass_encoding(); + self->bypass_decoding = tmedia_defaults_get_bypass_decoding(); + /* SSL certificates */{ + const char* priv_path = tsk_null, *pub_path = tsk_null, *ca_path = tsk_null; + tsk_bool_t verify = tsk_false; + if ((ret = tmedia_defaults_get_ssl_certs(&priv_path, &pub_path, &ca_path, &verify))) { + return ret; + } + self->dtls.file_pvk = tsk_strdup(priv_path); + self->dtls.file_pbk = tsk_strdup(pub_path); + self->dtls.file_ca = tsk_strdup(ca_path); + self->dtls.verify = verify; + } + /* QoS metrics */ + self->qos_metrics.q1 = 0.f; + self->qos_metrics.q2 = 0.f; + self->qos_metrics.q3 = 0.f; + self->qos_metrics.q4 = 0.f; + self->qos_metrics.qvag = 1.f; + self->qos_metrics.last_update_time = 0; + self->qos_metrics.bw_up_est_kbps = 0; + self->qos_metrics.bw_down_est_kbps = 0; + self->qos_metrics.video_out_width = 0; + self->qos_metrics.video_out_height = 0; + self->qos_metrics.video_in_width = 0; + self->qos_metrics.video_in_height = 0; + self->qos_metrics.video_in_avg_fps = 0; + self->qos_metrics.video_dec_avg_time = 0; + self->qos_metrics.video_enc_avg_time = 0; + + /* load associated codecs */ + ret = _tmedia_session_load_codecs(self); + } + + return 0; } int tmedia_session_set(tmedia_session_t* self, ...) { - va_list ap; - tmedia_params_L_t* params; - - if (!self || !self->plugin || !self->plugin->set){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - - va_start(ap, self); - if ((params = tmedia_params_create_2(&ap))){ - const tsk_list_item_t *item; - const tmedia_param_t* param; - tsk_list_foreach(item, params){ - if (!(param = item->data)){ - continue; - } - if ((self->type & param->media_type)){ - self->plugin->set(self, param); - } - } - TSK_OBJECT_SAFE_FREE(params); - } - va_end(ap); - return 0; + va_list ap; + tmedia_params_L_t* params; + + if (!self || !self->plugin || !self->plugin->set) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + + va_start(ap, self); + if ((params = tmedia_params_create_2(&ap))) { + const tsk_list_item_t *item; + const tmedia_param_t* param; + tsk_list_foreach(item, params) { + if (!(param = item->data)) { + continue; + } + if ((self->type & param->media_type)) { + self->plugin->set(self, param); + } + } + TSK_OBJECT_SAFE_FREE(params); + } + va_end(ap); + return 0; } tsk_bool_t tmedia_session_set_2(tmedia_session_t* self, const tmedia_param_t* param) { - if (!self || !param){ - TSK_DEBUG_ERROR("Invalid parameter"); - return tsk_false; - } - - if (param->plugin_type == tmedia_ppt_session){ - if (param->value_type == tmedia_pvt_int32){ - if (tsk_striequals(param->key, "codecs-supported")){ - //if(self->M.lo){ - // TSK_DEBUG_WARN("Cannot change codec values at this stage"); - //} - //else{ - int32_t codecs_allowed = *((int32_t*)param->value); - if (self->codecs_allowed != codecs_allowed){ - self->codecs_allowed = codecs_allowed; - return (_tmedia_session_load_codecs(self) == 0); - } - return 0; - //} - return tsk_true; - } - else if (tsk_striequals(param->key, "bypass-encoding")){ - self->bypass_encoding = *((int32_t*)param->value); - return tsk_true; - } - else if (tsk_striequals(param->key, "bypass-decoding")){ - self->bypass_decoding = *((int32_t*)param->value); - return tsk_true; - } - else if (tsk_striequals(param->key, "dtls-cert-verify")){ - self->dtls.verify = *((int32_t*)param->value) ? tsk_true : tsk_false; - return tsk_true; - } - } - else if (param->value_type == tmedia_pvt_pchar){ - if (tsk_striequals(param->key, "dtls-file-ca")){ - tsk_strupdate(&self->dtls.file_ca, param->value); - return tsk_true; - } - else if (tsk_striequals(param->key, "dtls-file-pbk")){ - tsk_strupdate(&self->dtls.file_pbk, param->value); - return tsk_true; - } - else if (tsk_striequals(param->key, "dtls-file-pvk")){ - tsk_strupdate(&self->dtls.file_pvk, param->value); - return tsk_true; - } - } - } - - return tsk_false; + if (!self || !param) { + TSK_DEBUG_ERROR("Invalid parameter"); + return tsk_false; + } + + if (param->plugin_type == tmedia_ppt_session) { + if (param->value_type == tmedia_pvt_int32) { + if (tsk_striequals(param->key, "codecs-supported")) { + //if(self->M.lo){ + // TSK_DEBUG_WARN("Cannot change codec values at this stage"); + //} + //else{ + int32_t codecs_allowed = *((int32_t*)param->value); + if (self->codecs_allowed != codecs_allowed) { + self->codecs_allowed = codecs_allowed; + return (_tmedia_session_load_codecs(self) == 0); + } + return 0; + //} + return tsk_true; + } + else if (tsk_striequals(param->key, "bypass-encoding")) { + self->bypass_encoding = *((int32_t*)param->value); + return tsk_true; + } + else if (tsk_striequals(param->key, "bypass-decoding")) { + self->bypass_decoding = *((int32_t*)param->value); + return tsk_true; + } + else if (tsk_striequals(param->key, "dtls-cert-verify")) { + self->dtls.verify = *((int32_t*)param->value) ? tsk_true : tsk_false; + return tsk_true; + } + } + else if (param->value_type == tmedia_pvt_pchar) { + if (tsk_striequals(param->key, "dtls-file-ca")) { + tsk_strupdate(&self->dtls.file_ca, param->value); + return tsk_true; + } + else if (tsk_striequals(param->key, "dtls-file-pbk")) { + tsk_strupdate(&self->dtls.file_pbk, param->value); + return tsk_true; + } + else if (tsk_striequals(param->key, "dtls-file-pvk")) { + tsk_strupdate(&self->dtls.file_pvk, param->value); + return tsk_true; + } + } + } + + return tsk_false; } int tmedia_session_get(tmedia_session_t* self, tmedia_param_t* param) { - if (!self || !param) { - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - if (self->plugin && self->plugin->get) { - return self->plugin->get(self, param); - } - return -2; + if (!self || !param) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + if (self->plugin && self->plugin->get) { + return self->plugin->get(self, param); + } + return -2; } /**@ingroup tmedia_session_group @@ -280,9 +301,9 @@ int tmedia_session_get(tmedia_session_t* self, tmedia_param_t* param) */ int tmedia_session_cmp(const tsk_object_t* sess1, const tsk_object_t* sess2) { - int ret; - tsk_subsat_int32_ptr(sess1, sess2, &ret); - return ret; + int ret; + tsk_subsat_int32_ptr(sess1, sess2, &ret); + return ret; } /**@ingroup tmedia_session_group @@ -293,22 +314,22 @@ int tmedia_session_cmp(const tsk_object_t* sess1, const tsk_object_t* sess2) */ int tmedia_session_plugin_register(const tmedia_session_plugin_def_t* plugin) { - tsk_size_t i; - if (!plugin){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } + tsk_size_t i; + if (!plugin) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } - /* add or replace the plugin */ - for (i = 0; i < TMED_SESSION_MAX_PLUGINS; i++){ - if (!__tmedia_session_plugins[i] || (__tmedia_session_plugins[i] == plugin)){ - __tmedia_session_plugins[i] = plugin; - return 0; - } - } + /* add or replace the plugin */ + for (i = 0; i < TMED_SESSION_MAX_PLUGINS; i++) { + if (!__tmedia_session_plugins[i] || (__tmedia_session_plugins[i] == plugin)) { + __tmedia_session_plugins[i] = plugin; + return 0; + } + } - TSK_DEBUG_ERROR("There are already %d plugins.", TMED_SESSION_MAX_PLUGINS); - return -2; + TSK_DEBUG_ERROR("There are already %d plugins.", TMED_SESSION_MAX_PLUGINS); + return -2; } /**@ingroup tmedia_session_group @@ -316,20 +337,20 @@ int tmedia_session_plugin_register(const tmedia_session_plugin_def_t* plugin) */ 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; - } + 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; + /* 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 @@ -339,35 +360,35 @@ const tmedia_session_plugin_def_t* tmedia_session_plugin_find_by_media(const cha */ int tmedia_session_plugin_unregister(const tmedia_session_plugin_def_t* plugin) { - tsk_size_t i; - tsk_bool_t found = tsk_false; - if (!plugin){ - TSK_DEBUG_ERROR("Invalid Parameter"); - return -1; - } - - /* find the plugin to unregister */ - for (i = 0; i < TMED_SESSION_MAX_PLUGINS && __tmedia_session_plugins[i]; i++){ - if (__tmedia_session_plugins[i] == plugin){ - __tmedia_session_plugins[i] = tsk_null; - found = tsk_true; - break; - } - } - - /* compact */ - if (found){ - for (; i < (TMED_SESSION_MAX_PLUGINS - 1); i++){ - if (__tmedia_session_plugins[i + 1]){ - __tmedia_session_plugins[i] = __tmedia_session_plugins[i + 1]; - } - else{ - break; - } - } - __tmedia_session_plugins[i] = tsk_null; - } - return (found ? 0 : -2); + tsk_size_t i; + tsk_bool_t found = tsk_false; + if (!plugin) { + TSK_DEBUG_ERROR("Invalid Parameter"); + return -1; + } + + /* find the plugin to unregister */ + for (i = 0; i < TMED_SESSION_MAX_PLUGINS && __tmedia_session_plugins[i]; i++) { + if (__tmedia_session_plugins[i] == plugin) { + __tmedia_session_plugins[i] = tsk_null; + found = tsk_true; + break; + } + } + + /* compact */ + if (found) { + for (; i < (TMED_SESSION_MAX_PLUGINS - 1); i++) { + if (__tmedia_session_plugins[i + 1]) { + __tmedia_session_plugins[i] = __tmedia_session_plugins[i + 1]; + } + else { + break; + } + } + __tmedia_session_plugins[i] = tsk_null; + } + return (found ? 0 : -2); } /**@ingroup tmedia_session_group @@ -377,252 +398,268 @@ int tmedia_session_plugin_unregister(const tmedia_session_plugin_def_t* plugin) */ tmedia_session_t* tmedia_session_create(tmedia_type_t type) { - tmedia_session_t* session = tsk_null; - const tmedia_session_plugin_def_t* plugin; - tsk_size_t i = 0; + tmedia_session_t* session = tsk_null; + const tmedia_session_plugin_def_t* plugin; + tsk_size_t i = 0; - while ((i < TMED_SESSION_MAX_PLUGINS) && (plugin = __tmedia_session_plugins[i++])){ - if (plugin->objdef && (plugin->type == type)){ - if ((session = tsk_object_new(plugin->objdef))){ - if (!session->initialized){ - tmedia_session_init(session, type); - } - session->plugin = plugin; - } - break; - } - } - return session; + while ((i < TMED_SESSION_MAX_PLUGINS) && (plugin = __tmedia_session_plugins[i++])) { + if (plugin->objdef && (plugin->type == type)) { + if ((session = tsk_object_new(plugin->objdef))) { + if (!session->initialized) { + tmedia_session_init(session, type); + } + session->plugin = plugin; + } + break; + } + } + return session; } /* internal funtion: prepare lo */ static int _tmedia_session_prepare(tmedia_session_t* self) { - int ret; - if (!self || !self->plugin || !self->plugin->prepare){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - if (self->prepared){ - TSK_DEBUG_WARN("Session already prepared"); - return 0; - } - if ((ret = self->plugin->prepare(self))){ - TSK_DEBUG_ERROR("Failed to prepare the session"); - } - else{ - self->prepared = tsk_true; - } - return ret; + int ret; + if (!self || !self->plugin || !self->plugin->prepare) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + if (self->prepared) { + TSK_DEBUG_WARN("Session already prepared"); + return 0; + } + if ((ret = self->plugin->prepare(self))) { + TSK_DEBUG_ERROR("Failed to prepare the session"); + } + else { + self->prepared = tsk_true; + } + return ret; } /* internal function used to set remote offer */ int _tmedia_session_set_ro(tmedia_session_t* self, const tsdp_header_M_t* m) { - int ret; - if (!self || !self->plugin || !self->plugin->set_remote_offer){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - if (!(ret = self->plugin->set_remote_offer(self, m))){ - self->ro_changed = tsk_true; - self->ro_held = tsdp_header_M_is_held(m, tsk_false); - } - return ret; + int ret; + if (!self || !self->plugin || !self->plugin->set_remote_offer) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + if (!(ret = self->plugin->set_remote_offer(self, m))) { + self->ro_changed = tsk_true; + self->ro_held = tsdp_header_M_is_held(m, tsk_false); + } + return ret; } /* 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; - } + 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; - } + /* 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) { - const tsdp_header_M_t* m; + const tsdp_header_M_t* m; - if (!self || !self->plugin || !self->plugin->get_local_offer){ - TSK_DEBUG_ERROR("Invalid parameter"); - return tsk_null; - } + if (!self || !self->plugin || !self->plugin->get_local_offer) { + TSK_DEBUG_ERROR("Invalid parameter"); + return tsk_null; + } - if ((m = self->plugin->get_local_offer(self))){ - self->ro_changed = tsk_false; /* we should have a fresh local offer (based on the latest ro) */ - } - return m; + if ((m = self->plugin->get_local_offer(self))) { + self->ro_changed = tsk_false; /* we should have a fresh local offer (based on the latest ro) */ + } + return m; } /* Match a codec */ tmedia_codecs_L_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, *image_attr = tsk_null, *name = tsk_null; - const tsdp_fmt_t* fmt; - const tsk_list_item_t *it1, *it2; - tsk_bool_t found = tsk_false; - tmedia_codecs_L_t* matchingCodecs = tsk_null; - - 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){ - /* 'tmedia_codec_id_none' is used for fake codecs (e.g. dtmf or msrp) and should not be filtered beacuse of backward compatibility*/ - if (!(codec = it2->data) || !codec->plugin || !(codec->id == tmedia_codec_id_none || (codec->id & self->codecs_allowed))){ - continue; - } - - // Guard to avoid matching a codec more than once - // For example, H.264 codecs without profiles (Jitsi, Tiscali PC client) to distinguish them could match more than once - if (matchingCodecs && tsk_list_find_object_by_pred(matchingCodecs, __pred_find_codec_by_format, codec)){ - continue; - } - - // Dyn. payload type - if (codec->dyn && (rtpmap = tsdp_header_M_get_rtpmap(M, fmt->value))){ - int32_t rate, channels; - /* parse rtpmap */ - if (tmedia_parse_rtpmap(rtpmap, &name, &rate, &channels)){ - goto next; - } - - /* compare name and rate... what about channels? */ - if (tsk_striequals(name, codec->name) && (!rate || !codec->plugin->rate || (codec->plugin->rate == rate))){ - goto compare_fmtp; - } - } - // Fixed payload type - else{ - if (tsk_striequals(fmt->value, codec->format)){ - goto compare_fmtp; - } - } - - /* rtpmap do not match: free strings and try next codec */ - goto next; - - compare_fmtp: - if ((fmtp = tsdp_header_M_get_fmtp(M, fmt->value))){ /* remote have fmtp? */ - if (tmedia_codec_sdp_att_match(codec, "fmtp", fmtp)){ /* fmtp matches? */ - if (codec->type & tmedia_video) goto compare_imageattr; - else found = tsk_true; - } - else goto next; - } - else{ /* no fmtp -> always match */ - if (codec->type & tmedia_video) goto compare_imageattr; - else found = tsk_true; - } - - compare_imageattr: - if (codec->type & tmedia_video){ - if ((image_attr = tsdp_header_M_get_imageattr(M, fmt->value))){ - if (tmedia_codec_sdp_att_match(codec, "imageattr", image_attr)) found = tsk_true; - } - else found = tsk_true; - } - - // update neg. format - if (found) tsk_strupdate((char**)&codec->neg_format, fmt->value); - - next: - TSK_FREE(name); - TSK_FREE(fmtp); - TSK_FREE(rtpmap); - TSK_FREE(image_attr); - if (found){ - tmedia_codec_t * copy; - if (!matchingCodecs){ - matchingCodecs = tsk_list_create(); - } - copy = tsk_object_ref((void*)codec); - tsk_list_push_back_data(matchingCodecs, (void**)©); - - found = tsk_false; - break; - } - } - } - - - return matchingCodecs; + const tmedia_codec_t *codec; + char *rtpmap = tsk_null, *fmtp = tsk_null, *image_attr = tsk_null, *name = tsk_null; + const tsdp_fmt_t* fmt; + const tsk_list_item_t *it1, *it2; + tsk_bool_t found = tsk_false; + tmedia_codecs_L_t* matchingCodecs = tsk_null; + + 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) { + /* 'tmedia_codec_id_none' is used for fake codecs (e.g. dtmf or msrp) and should not be filtered beacuse of backward compatibility*/ + if (!(codec = it2->data) || !codec->plugin || !(codec->id == tmedia_codec_id_none || (codec->id & self->codecs_allowed))) { + continue; + } + + // Guard to avoid matching a codec more than once + // For example, H.264 codecs without profiles (Jitsi, Tiscali PC client) to distinguish them could match more than once + if (matchingCodecs && tsk_list_find_object_by_pred(matchingCodecs, __pred_find_codec_by_format, codec)) { + continue; + } + + // Dyn. payload type + if (codec->dyn && (rtpmap = tsdp_header_M_get_rtpmap(M, fmt->value))) { + int32_t rate, channels; + /* parse rtpmap */ + if (tmedia_parse_rtpmap(rtpmap, &name, &rate, &channels)) { + goto next; + } + + /* compare name and rate... what about channels? */ + if (tsk_striequals(name, codec->name) && (!rate || !codec->plugin->rate || (codec->plugin->rate == rate))) { + goto compare_fmtp; + } + } + // Fixed payload type + else { + if (tsk_striequals(fmt->value, codec->format)) { + goto compare_fmtp; + } + } + + /* rtpmap do not match: free strings and try next codec */ + goto next; + +compare_fmtp: + if ((fmtp = tsdp_header_M_get_fmtp(M, fmt->value))) { /* remote have fmtp? */ + if (tmedia_codec_sdp_att_match(codec, "fmtp", fmtp)) { /* fmtp matches? */ + if (codec->type & tmedia_video) { + goto compare_imageattr; + } + else { + found = tsk_true; + } + } + else { + goto next; + } + } + else { /* no fmtp -> always match */ + if (codec->type & tmedia_video) { + goto compare_imageattr; + } + else { + found = tsk_true; + } + } + +compare_imageattr: + if (codec->type & tmedia_video) { + if ((image_attr = tsdp_header_M_get_imageattr(M, fmt->value))) { + if (tmedia_codec_sdp_att_match(codec, "imageattr", image_attr)) { + found = tsk_true; + } + } + else { + found = tsk_true; + } + } + + // update neg. format + if (found) { + tsk_strupdate((char**)&codec->neg_format, fmt->value); + } + +next: + TSK_FREE(name); + TSK_FREE(fmtp); + TSK_FREE(rtpmap); + TSK_FREE(image_attr); + if (found) { + tmedia_codec_t * copy; + if (!matchingCodecs) { + matchingCodecs = tsk_list_create(); + } + copy = tsk_object_ref((void*)codec); + tsk_list_push_back_data(matchingCodecs, (void**)©); + + found = tsk_false; + break; + } + } + } + + + return matchingCodecs; } int tmedia_session_set_onrtcp_cbfn(tmedia_session_t* self, const void* context, tmedia_session_rtcp_onevent_cb_f func) { - if (self && self->plugin && self->plugin->rtcp.set_onevent_cbfn){ - return self->plugin->rtcp.set_onevent_cbfn(self, context, func); - } - return -1; + if (self && self->plugin && self->plugin->rtcp.set_onevent_cbfn) { + return self->plugin->rtcp.set_onevent_cbfn(self, context, func); + } + return -1; } int tmedia_session_send_rtcp_event(tmedia_session_t* self, tmedia_rtcp_event_type_t event_type, uint32_t ssrc_media) { - if (self && self->plugin && self->plugin->rtcp.send_event){ - return self->plugin->rtcp.send_event(self, event_type, ssrc_media); - } - TSK_DEBUG_INFO("Not sending RTCP event with SSRC = %u because no callback function found", ssrc_media); - return -1; + if (self && self->plugin && self->plugin->rtcp.send_event) { + return self->plugin->rtcp.send_event(self, event_type, ssrc_media); + } + TSK_DEBUG_INFO("Not sending RTCP event with SSRC = %u because no callback function found", ssrc_media); + return -1; } int tmedia_session_recv_rtcp_event(tmedia_session_t* self, tmedia_rtcp_event_type_t event_type, uint32_t ssrc_media) { - if (self && self->plugin && self->plugin->rtcp.recv_event){ - return self->plugin->rtcp.recv_event(self, event_type, ssrc_media); - } - TSK_DEBUG_INFO("Not receiving RTCP event with SSRC = %u because no callback function found", ssrc_media); - return -1; + if (self && self->plugin && self->plugin->rtcp.recv_event) { + return self->plugin->rtcp.recv_event(self, event_type, ssrc_media); + } + TSK_DEBUG_INFO("Not receiving RTCP event with SSRC = %u because no callback function found", ssrc_media); + return -1; } int tmedia_session_set_onerror_cbfn(tmedia_session_t* self, const void* usrdata, tmedia_session_onerror_cb_f fun) { - if (!self){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - self->onerror_cb.fun = fun; - self->onerror_cb.usrdata = usrdata; - return 0; + if (!self) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + self->onerror_cb.fun = fun; + self->onerror_cb.usrdata = usrdata; + return 0; } int tmedia_session_set_rfc5168_cbfn(tmedia_session_t* self, const void* usrdata, tmedia_session_rfc5168_cb_f fun) { - if (!self) { - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - self->rfc5168_cb.fun = fun; - self->rfc5168_cb.usrdata = usrdata; - return 0; + if (!self) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + self->rfc5168_cb.fun = fun; + self->rfc5168_cb.usrdata = usrdata; + return 0; } int tmedia_session_set_bfcp_cbfn(tmedia_session_t* self, const void* usrdata, tmedia_session_bfcp_cb_f fun) { - if (!self) { - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - self->bfcp_cb.fun = fun; - self->bfcp_cb.usrdata = usrdata; - return 0; + if (!self) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + self->bfcp_cb.fun = fun; + self->bfcp_cb.usrdata = usrdata; + return 0; } /**@ingroup tmedia_session_group @@ -632,28 +669,28 @@ int tmedia_session_set_bfcp_cbfn(tmedia_session_t* self, const void* usrdata, tm */ int tmedia_session_deinit(tmedia_session_t* self) { - if (!self){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } + if (!self) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } - /* free codecs */ - TSK_OBJECT_SAFE_FREE(self->codecs); - TSK_OBJECT_SAFE_FREE(self->neg_codecs); + /* free codecs */ + TSK_OBJECT_SAFE_FREE(self->codecs); + TSK_OBJECT_SAFE_FREE(self->neg_codecs); - /* free lo, no and ro */ - TSK_OBJECT_SAFE_FREE(self->M.lo); - TSK_OBJECT_SAFE_FREE(self->M.ro); + /* free lo, no and ro */ + TSK_OBJECT_SAFE_FREE(self->M.lo); + TSK_OBJECT_SAFE_FREE(self->M.ro); - /* QoS */ - TSK_OBJECT_SAFE_FREE(self->qos); + /* QoS */ + TSK_OBJECT_SAFE_FREE(self->qos); - /* DTLS */ - TSK_FREE(self->dtls.file_ca); - TSK_FREE(self->dtls.file_pbk); - TSK_FREE(self->dtls.file_pvk); + /* DTLS */ + TSK_FREE(self->dtls.file_ca); + TSK_FREE(self->dtls.file_pbk); + TSK_FREE(self->dtls.file_pvk); - return 0; + return 0; } /**@ingroup tmedia_session_group @@ -664,109 +701,109 @@ int tmedia_session_deinit(tmedia_session_t* self) */ int tmedia_session_audio_send_dtmf(tmedia_session_audio_t* self, uint8_t event) { - if (!self || !TMEDIA_SESSION(self)->plugin || !TMEDIA_SESSION(self)->plugin->audio.send_dtmf){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - return TMEDIA_SESSION(self)->plugin->audio.send_dtmf(TMEDIA_SESSION(self), event); + if (!self || !TMEDIA_SESSION(self)->plugin || !TMEDIA_SESSION(self)->plugin->audio.send_dtmf) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + return TMEDIA_SESSION(self)->plugin->audio.send_dtmf(TMEDIA_SESSION(self), event); } int tmedia_session_t140_set_ondata_cbfn(tmedia_session_t* self, const void* context, tmedia_session_t140_ondata_cb_f func) { - if (self && self->plugin && self->plugin->t140.set_ondata_cbfn){ - return self->plugin->t140.set_ondata_cbfn(self, context, func); - } - return -1; + if (self && self->plugin && self->plugin->t140.set_ondata_cbfn) { + return self->plugin->t140.set_ondata_cbfn(self, context, func); + } + return -1; } int tmedia_session_t140_send_data(tmedia_session_t* self, enum tmedia_t140_data_type_e data_type, const void* data_ptr, unsigned data_size) { - if (self && self->plugin && self->plugin->t140.send_data){ - return self->plugin->t140.send_data(self, data_type, data_ptr, data_size); - } - return -1; + if (self && self->plugin && self->plugin->t140.send_data) { + return self->plugin->t140.send_data(self, data_type, data_ptr, data_size); + } + return -1; } /* internal function used to prepare a session */ int _tmedia_session_load_codecs(tmedia_session_t* self) { - tsk_size_t i = 0; - tmedia_codec_t* codec; - const tmedia_codec_plugin_def_t* plugin; - const tsk_list_item_t* item; - tmedia_type_t type; - - if (!self){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - - if (!self->codecs && !(self->codecs = tsk_list_create())){ - TSK_DEBUG_ERROR("Failed to create new list"); - return -1; - } - - tsk_list_lock(self->codecs); - - /* remove old codecs */ - tsk_list_clear_items(self->codecs); - - type = self->type; - if ((type & tmedia_bfcp_video) == tmedia_bfcp_video) { - type |= tmedia_video; - } - if ((type & tmedia_bfcp_audio) == tmedia_bfcp_audio) { - type |= tmedia_audio; - } - - /* for each registered plugin create a session instance */ - while ((i < TMED_CODEC_MAX_PLUGINS) && (plugin = __tmedia_codec_plugins[i++])){ - /* 'tmedia_codec_id_none' is used for fake codecs (e.g. dtmf, bfcp or msrp) and should not be filtered beacuse of backward compatibility*/ - if ((plugin->type & type) && (plugin->codec_id == tmedia_codec_id_none || (plugin->codec_id & self->codecs_allowed))){ - // do not load bfcp codec for "audiobfcp" and "videobfcp" session - if ((plugin->type == tmedia_bfcp) && (type != tmedia_bfcp)) { - continue; - } - if ((codec = tmedia_codec_create(plugin->format))){ - if (!self->codecs){ - self->codecs = tsk_list_create(); - } - tsk_list_push_back_data(self->codecs, (void**)(&codec)); - } - } - } - - // filter negotiated codecs with the newly loaded codecs - if (1){ // code valid for all use-cases but for now it's not fully tested and not needed for the clients - filter_neg_codecs: - tsk_list_foreach(item, self->neg_codecs){ - if (!(codec = (item->data))){ - continue; - } - if (!(tsk_list_find_item_by_pred(self->codecs, __pred_find_codec_by_id, &codec->id))){ - const char* codec_name = codec->plugin ? codec->plugin->name : "unknown"; - const char* neg_format = codec->neg_format ? codec->neg_format : codec->format; - TSK_DEBUG_INFO("Codec '%s' with format '%s' was negotiated but [supported codecs] updated without it -> removing", codec_name, neg_format); - // update sdp and remove the codec from the list - if (self->M.lo && !TSK_LIST_IS_EMPTY(self->M.lo->FMTs)){ - if (self->M.lo->FMTs->head->next == tsk_null && tsdp_header_M_have_fmt(self->M.lo, neg_format)){ // single item? - // rejecting a media with port equal to zero requires at least one format - TSK_DEBUG_INFO("[supported codecs] updated but do not remove codec with name='%s' and format='%s' because it's the last one", codec_name, neg_format); - self->M.lo->port = 0; - } - else{ - tsdp_header_M_remove_fmt(self->M.lo, neg_format); - } - } - tsk_list_remove_item_by_data(self->neg_codecs, codec); - goto filter_neg_codecs; - } - } - } - - tsk_list_unlock(self->codecs); - - return 0; + tsk_size_t i = 0; + tmedia_codec_t* codec; + const tmedia_codec_plugin_def_t* plugin; + const tsk_list_item_t* item; + tmedia_type_t type; + + if (!self) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + + if (!self->codecs && !(self->codecs = tsk_list_create())) { + TSK_DEBUG_ERROR("Failed to create new list"); + return -1; + } + + tsk_list_lock(self->codecs); + + /* remove old codecs */ + tsk_list_clear_items(self->codecs); + + type = self->type; + if ((type & tmedia_bfcp_video) == tmedia_bfcp_video) { + type |= tmedia_video; + } + if ((type & tmedia_bfcp_audio) == tmedia_bfcp_audio) { + type |= tmedia_audio; + } + + /* for each registered plugin create a session instance */ + while ((i < TMED_CODEC_MAX_PLUGINS) && (plugin = __tmedia_codec_plugins[i++])) { + /* 'tmedia_codec_id_none' is used for fake codecs (e.g. dtmf, bfcp or msrp) and should not be filtered beacuse of backward compatibility*/ + if ((plugin->type & type) && (plugin->codec_id == tmedia_codec_id_none || (plugin->codec_id & self->codecs_allowed))) { + // do not load bfcp codec for "audiobfcp" and "videobfcp" session + if ((plugin->type == tmedia_bfcp) && (type != tmedia_bfcp)) { + continue; + } + if ((codec = tmedia_codec_create(plugin->format))) { + if (!self->codecs) { + self->codecs = tsk_list_create(); + } + tsk_list_push_back_data(self->codecs, (void**)(&codec)); + } + } + } + + // filter negotiated codecs with the newly loaded codecs + if (1) { // code valid for all use-cases but for now it's not fully tested and not needed for the clients +filter_neg_codecs: + tsk_list_foreach(item, self->neg_codecs) { + if (!(codec = (item->data))) { + continue; + } + if (!(tsk_list_find_item_by_pred(self->codecs, __pred_find_codec_by_id, &codec->id))) { + const char* codec_name = codec->plugin ? codec->plugin->name : "unknown"; + const char* neg_format = codec->neg_format ? codec->neg_format : codec->format; + TSK_DEBUG_INFO("Codec '%s' with format '%s' was negotiated but [supported codecs] updated without it -> removing", codec_name, neg_format); + // update sdp and remove the codec from the list + if (self->M.lo && !TSK_LIST_IS_EMPTY(self->M.lo->FMTs)) { + if (self->M.lo->FMTs->head->next == tsk_null && tsdp_header_M_have_fmt(self->M.lo, neg_format)) { // single item? + // rejecting a media with port equal to zero requires at least one format + TSK_DEBUG_INFO("[supported codecs] updated but do not remove codec with name='%s' and format='%s' because it's the last one", codec_name, neg_format); + self->M.lo->port = 0; + } + else { + tsdp_header_M_remove_fmt(self->M.lo, neg_format); + } + } + tsk_list_remove_item_by_data(self->neg_codecs, codec); + goto filter_neg_codecs; + } + } + } + + tsk_list_unlock(self->codecs); + + return 0; } @@ -781,155 +818,169 @@ int _tmedia_session_load_codecs(tmedia_session_t* self) */ tmedia_session_mgr_t* tmedia_session_mgr_create(tmedia_type_t type, const char* addr, tsk_bool_t ipv6, tsk_bool_t offerer) { - tmedia_session_mgr_t* mgr; + tmedia_session_mgr_t* mgr; - if (!(mgr = tsk_object_new(tmedia_session_mgr_def_t))){ - TSK_DEBUG_ERROR("Failed to create Media Session manager"); - return tsk_null; - } + if (!(mgr = tsk_object_new(tmedia_session_mgr_def_t))) { + TSK_DEBUG_ERROR("Failed to create Media Session manager"); + return tsk_null; + } - /* init */ - mgr->type = type; - mgr->addr = tsk_strdup(addr); - mgr->ipv6 = ipv6; + /* init */ + mgr->type = type; + mgr->addr = tsk_strdup(addr); + mgr->ipv6 = ipv6; - /* load sessions (will allow us to generate lo) */ - if (offerer){ - mgr->offerer = tsk_true; - //if(_tmedia_session_mgr_load_sessions(mgr)){ - /* Do nothing */ - // TSK_DEBUG_ERROR("Failed to load sessions"); - //} - } + /* load sessions (will allow us to generate lo) */ + if (offerer) { + mgr->offerer = tsk_true; + //if(_tmedia_session_mgr_load_sessions(mgr)){ + /* Do nothing */ + // TSK_DEBUG_ERROR("Failed to load sessions"); + //} + } - return mgr; + return mgr; } /**@ingroup tmedia_session_group */ int tmedia_session_mgr_set_media_type(tmedia_session_mgr_t* self, tmedia_type_t type) { - static tsk_bool_t __force_set = tsk_false; - return tmedia_session_mgr_set_media_type_2(self, type, __force_set); + static tsk_bool_t __force_set = tsk_false; + return tmedia_session_mgr_set_media_type_2(self, type, __force_set); } /**@ingroup tmedia_session_group */ int tmedia_session_mgr_set_media_type_2(tmedia_session_mgr_t* self, tmedia_type_t type, tsk_bool_t force) { - if (!self) { - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - if (force || self->type != type) { - self->mediaType_changed = tsk_true; - self->type = type; - } - return 0; + if (!self) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + if (force || self->type != type) { + self->mediaType_changed = tsk_true; + self->type = type; + } + return 0; } // special set() case int tmedia_session_mgr_set_codecs_supported(tmedia_session_mgr_t* self, tmedia_codec_id_t codecs_supported) { - int ret = 0; - if (!self){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - - // calling set() could create zombies (media sessions with port equal to zero) - ret = tmedia_session_mgr_set(self, - TMEDIA_SESSION_SET_INT32(self->type, "codecs-supported", codecs_supported), - tsk_null); - if (ret == 0 && self->sdp.lo){ - // update type (will discard zombies) - tmedia_type_t new_type = tmedia_type_from_sdp(self->sdp.lo); - if (new_type != self->type){ - TSK_DEBUG_INFO("codecs-supported updated and media type changed from %d to %d", self->type, new_type); - self->type = new_type; - } - } - return ret; + int ret = 0; + if (!self) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + + // calling set() could create zombies (media sessions with port equal to zero) + ret = tmedia_session_mgr_set(self, + TMEDIA_SESSION_SET_INT32(self->type, "codecs-supported", codecs_supported), + tsk_null); + if (ret == 0 && self->sdp.lo) { + // update type (will discard zombies) + tmedia_type_t new_type = tmedia_type_from_sdp(self->sdp.lo); + if (new_type != self->type) { + TSK_DEBUG_INFO("codecs-supported updated and media type changed from %d to %d", self->type, new_type); + self->type = new_type; + } + } + return ret; } /**@ingroup tmedia_session_group */ tmedia_session_t* tmedia_session_mgr_find(tmedia_session_mgr_t* self, tmedia_type_t type) { - tmedia_session_t* session; + tmedia_session_t* session; - tsk_list_lock(self->sessions); - session = (tmedia_session_t*)tsk_list_find_object_by_pred(self->sessions, __pred_find_session_by_type, &type); - tsk_list_unlock(self->sessions); + tsk_list_lock(self->sessions); + session = (tmedia_session_t*)tsk_list_find_object_by_pred(self->sessions, __pred_find_session_by_type, &type); + tsk_list_unlock(self->sessions); - return tsk_object_ref(session); + return tsk_object_ref(session); } /**@ingroup tmedia_session_group */ int tmedia_session_mgr_set_natt_ctx(tmedia_session_mgr_t* self, struct tnet_nat_ctx_s* natt_ctx, const char* public_addr) { - if (!self || !natt_ctx){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - TSK_OBJECT_SAFE_FREE(self->natt_ctx); - self->natt_ctx = tsk_object_ref(natt_ctx); - tsk_strupdate(&self->public_addr, public_addr); + if (!self || !natt_ctx) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + TSK_OBJECT_SAFE_FREE(self->natt_ctx); + self->natt_ctx = tsk_object_ref(natt_ctx); + tsk_strupdate(&self->public_addr, public_addr); - tmedia_session_mgr_set(self, - TMEDIA_SESSION_SET_POBJECT(self->type, "natt-ctx", self->natt_ctx), - TMEDIA_SESSION_SET_NULL()); - return 0; + tmedia_session_mgr_set(self, + TMEDIA_SESSION_SET_POBJECT(self->type, "natt-ctx", self->natt_ctx), + TMEDIA_SESSION_SET_NULL()); + return 0; } // @deprecated int tmedia_session_mgr_set_ice_ctx(tmedia_session_mgr_t* self, struct tnet_ice_ctx_s* ctx_audio, struct tnet_ice_ctx_s* ctx_video) { - if (!self){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - TSK_OBJECT_SAFE_FREE(self->ice.ctx_audio); // backward compatibility - TSK_OBJECT_SAFE_FREE(self->ice.ctx_video); // backward compatibility - if (self->type & tmedia_audio) { - tmedia_session_mgr_set_ice_ctx_2(self, tmedia_audio, ctx_audio); - } - if (self->type & tmedia_video) { - tmedia_session_mgr_set_ice_ctx_2(self, tmedia_video, ctx_video); - } - return 0; + if (!self) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + TSK_OBJECT_SAFE_FREE(self->ice.ctx_audio); // backward compatibility + TSK_OBJECT_SAFE_FREE(self->ice.ctx_video); // backward compatibility + if (self->type & tmedia_audio) { + tmedia_session_mgr_set_ice_ctx_2(self, tmedia_audio, ctx_audio); + } + if (self->type & tmedia_video) { + tmedia_session_mgr_set_ice_ctx_2(self, tmedia_video, ctx_video); + } + return 0; } int tmedia_session_mgr_set_ice_ctx_2(tmedia_session_mgr_t* self, tmedia_type_t type, struct tnet_ice_ctx_s* ctx) { - if (!self){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - if ((self->type & type) == type) { - struct tnet_ice_ctx_s **_ctx = tsk_null; - switch (type) { - case tmedia_audio: _ctx = &self->ice.ctx_audio; break; - case tmedia_video: _ctx = &self->ice.ctx_video; break; - case tmedia_bfcp_video: _ctx = &self->ice.ctx_bfcpvid; break; - default: TSK_DEBUG_ERROR("Media type(%d) not supported by this session manager", type); return -2; - } - TSK_OBJECT_SAFE_FREE((*_ctx)); - *_ctx = tsk_object_ref(ctx); - return tmedia_session_mgr_set(self, - TMEDIA_SESSION_SET_POBJECT(type, "ice-ctx", ctx), - TMEDIA_SESSION_SET_NULL()); - } - else if (!ctx) { //cleanup - switch (type) { - case tmedia_audio: TSK_OBJECT_SAFE_FREE(self->ice.ctx_audio); return 0; - case tmedia_video: TSK_OBJECT_SAFE_FREE(self->ice.ctx_video); return 0; - case tmedia_bfcp_video: TSK_OBJECT_SAFE_FREE(self->ice.ctx_bfcpvid); return 0; - } - } - TSK_DEBUG_ERROR("Ignoring ICE context definition for media type %d", type); - return -2; + if (!self) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + if ((self->type & type) == type) { + struct tnet_ice_ctx_s **_ctx = tsk_null; + switch (type) { + case tmedia_audio: + _ctx = &self->ice.ctx_audio; + break; + case tmedia_video: + _ctx = &self->ice.ctx_video; + break; + case tmedia_bfcp_video: + _ctx = &self->ice.ctx_bfcpvid; + break; + default: + TSK_DEBUG_ERROR("Media type(%d) not supported by this session manager", type); + return -2; + } + TSK_OBJECT_SAFE_FREE((*_ctx)); + *_ctx = tsk_object_ref(ctx); + return tmedia_session_mgr_set(self, + TMEDIA_SESSION_SET_POBJECT(type, "ice-ctx", ctx), + TMEDIA_SESSION_SET_NULL()); + } + else if (!ctx) { //cleanup + switch (type) { + case tmedia_audio: + TSK_OBJECT_SAFE_FREE(self->ice.ctx_audio); + return 0; + case tmedia_video: + TSK_OBJECT_SAFE_FREE(self->ice.ctx_video); + return 0; + case tmedia_bfcp_video: + TSK_OBJECT_SAFE_FREE(self->ice.ctx_bfcpvid); + return 0; + } + } + TSK_DEBUG_ERROR("Ignoring ICE context definition for media type %d", type); + return -2; } /**@ingroup tmedia_session_group @@ -942,7 +993,7 @@ int tmedia_session_mgr_set_ice_ctx_2(tmedia_session_mgr_t* self, tmedia_type_t t */ int tmedia_session_mgr_start(tmedia_session_mgr_t* self) { - return _tmedia_session_mgr_start(self, kSessionIndexAll); + return _tmedia_session_mgr_start(self, kSessionIndexAll); } /**@ingroup tmedia_session_group @@ -953,19 +1004,19 @@ int tmedia_session_mgr_start(tmedia_session_mgr_t* self) */ int tmedia_session_mgr_set(tmedia_session_mgr_t* self, ...) { - va_list ap; - int ret; + va_list ap; + int ret; - if (!self){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } + if (!self) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } - va_start(ap, self); - ret = tmedia_session_mgr_set_2(self, &ap); - va_end(ap); + va_start(ap, self); + ret = tmedia_session_mgr_set_2(self, &ap); + va_end(ap); - return ret; + return ret; } /**@ingroup tmedia_session_group @@ -976,29 +1027,29 @@ int tmedia_session_mgr_set(tmedia_session_mgr_t* self, ...) */ int tmedia_session_mgr_set_2(tmedia_session_mgr_t* self, va_list *app) { - tmedia_params_L_t* params; + tmedia_params_L_t* params; - if (!self || !app){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } + if (!self || !app) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } - if ((params = tmedia_params_create_2(app))){ - if (!self->params){ - self->params = tsk_object_ref(params); - } - else{ - tsk_list_pushback_list(self->params, params); - } - TSK_OBJECT_SAFE_FREE(params); - } + if ((params = tmedia_params_create_2(app))) { + if (!self->params) { + self->params = tsk_object_ref(params); + } + else { + tsk_list_pushback_list(self->params, params); + } + TSK_OBJECT_SAFE_FREE(params); + } - /* load params if we already have sessions */ - if (!TSK_LIST_IS_EMPTY(self->sessions)){ - _tmedia_session_mgr_apply_params(self); - } + /* load params if we already have sessions */ + if (!TSK_LIST_IS_EMPTY(self->sessions)) { + _tmedia_session_mgr_apply_params(self); + } - return 0; + return 0; } /**@ingroup tmedia_session_group @@ -1009,59 +1060,59 @@ int tmedia_session_mgr_set_2(tmedia_session_mgr_t* self, va_list *app) */ int tmedia_session_mgr_set_3(tmedia_session_mgr_t* self, const tmedia_params_L_t* params) { - if (!self || !params){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } + if (!self || !params) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } - if (!self->params){ - self->params = tsk_list_create(); - } - tsk_list_pushback_list(self->params, params); + if (!self->params) { + self->params = tsk_list_create(); + } + tsk_list_pushback_list(self->params, params); - /* load params if we already have sessions */ - if (!TSK_LIST_IS_EMPTY(self->sessions)){ - _tmedia_session_mgr_apply_params(self); - } + /* load params if we already have sessions */ + if (!TSK_LIST_IS_EMPTY(self->sessions)) { + _tmedia_session_mgr_apply_params(self); + } - return 0; + return 0; } int tmedia_session_mgr_get(tmedia_session_mgr_t* self, ...) { - va_list ap; - int ret = 0; - tmedia_params_L_t* params; - const tsk_list_item_t *item1, *item2; - - if (!self){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - - va_start(ap, self); - - if ((params = tmedia_params_create_2(&ap))){ - tmedia_session_t* session; - tmedia_param_t* param; - tsk_list_foreach(item2, params){ - if ((param = item2->data)){ - tsk_list_foreach(item1, self->sessions){ - if (!(session = (tmedia_session_t*)item1->data) || !session->plugin){ - continue; - } - if ((session->type & param->media_type) == session->type && session->plugin->set){ - ret = session->plugin->get(session, param); - } - } - } - } - TSK_OBJECT_SAFE_FREE(params); - } - - va_end(ap); - - return ret; + va_list ap; + int ret = 0; + tmedia_params_L_t* params; + const tsk_list_item_t *item1, *item2; + + if (!self) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + + va_start(ap, self); + + if ((params = tmedia_params_create_2(&ap))) { + tmedia_session_t* session; + tmedia_param_t* param; + tsk_list_foreach(item2, params) { + if ((param = item2->data)) { + tsk_list_foreach(item1, self->sessions) { + if (!(session = (tmedia_session_t*)item1->data) || !session->plugin) { + continue; + } + if ((session->type & param->media_type) == session->type && session->plugin->set) { + ret = session->plugin->get(session, param); + } + } + } + } + TSK_OBJECT_SAFE_FREE(params); + } + + va_end(ap); + + return ret; } /**@ingroup tmedia_session_group @@ -1073,7 +1124,7 @@ int tmedia_session_mgr_get(tmedia_session_mgr_t* self, ...) */ int tmedia_session_mgr_stop(tmedia_session_mgr_t* self) { - return _tmedia_session_mgr_stop(self, kSessionIndexAll); + return _tmedia_session_mgr_stop(self, kSessionIndexAll); } /**@ingroup tmedia_session_group @@ -1081,7 +1132,7 @@ int tmedia_session_mgr_stop(tmedia_session_mgr_t* self) */ const tsdp_message_t* tmedia_session_mgr_get_lo(tmedia_session_mgr_t* self) { - return _tmedia_session_mgr_get_lo(self, kSkipSessionLoadFalse, kForceUpdateLOFalse); + return _tmedia_session_mgr_get_lo(self, kSkipSessionLoadFalse, kForceUpdateLOFalse); } @@ -1090,486 +1141,503 @@ const tsdp_message_t* tmedia_session_mgr_get_lo(tmedia_session_mgr_t* self) */ int tmedia_session_mgr_set_ro(tmedia_session_mgr_t* self, const tsdp_message_t* sdp, tmedia_ro_type_t ro_type) { - const tmedia_session_t* ms; - const tsdp_header_M_t* M; - const tsdp_header_C_t* C; /* global "c=" line */ - const tsdp_header_O_t* O; - tsk_size_t index = 0; - tsk_size_t active_sessions_count = 0, m_lines_count = 0; - int ret = 0; - tsk_bool_t found; - tsk_bool_t stopped_to_reconf[TMEDIA_SESSION_MAX_LINES] = { tsk_false }; - tsk_bool_t is_ro_codecs_changed[TMEDIA_SESSION_MAX_LINES] = { tsk_false }; - tsk_bool_t is_local_encoder_still_ok[TMEDIA_SESSION_MAX_LINES] = { tsk_false }; // decoder is dynamically mapped for each incoming rtp frame -> no need to check it - tsk_bool_t is_ro_network_info_changed[TMEDIA_SESSION_MAX_LINES] = { tsk_false }; - tsk_bool_t is_ro_hold_resume_changed[TMEDIA_SESSION_MAX_LINES] = { tsk_false }; - tsk_bool_t is_ro_loopback_address[TMEDIA_SESSION_MAX_LINES] = { tsk_false }; - tsk_bool_t is_ice_enabled[TMEDIA_SESSION_MAX_LINES] = { tsk_false }; - tsk_bool_t is_ice_restart[TMEDIA_SESSION_MAX_LINES] = { tsk_false }; - tsk_bool_t is_dtls_fingerprint_changed[TMEDIA_SESSION_MAX_LINES] = { tsk_false }; + const tmedia_session_t* ms; + const tsdp_header_M_t* M; + const tsdp_header_C_t* C; /* global "c=" line */ + const tsdp_header_O_t* O; + tsk_size_t index = 0; + tsk_size_t active_sessions_count = 0, m_lines_count = 0; + int ret = 0; + tsk_bool_t found; + tsk_bool_t stopped_to_reconf[TMEDIA_SESSION_MAX_LINES] = { tsk_false }; + tsk_bool_t is_ro_codecs_changed[TMEDIA_SESSION_MAX_LINES] = { tsk_false }; + tsk_bool_t is_local_encoder_still_ok[TMEDIA_SESSION_MAX_LINES] = { tsk_false }; // decoder is dynamically mapped for each incoming rtp frame -> no need to check it + tsk_bool_t is_ro_network_info_changed[TMEDIA_SESSION_MAX_LINES] = { tsk_false }; + tsk_bool_t is_ro_hold_resume_changed[TMEDIA_SESSION_MAX_LINES] = { tsk_false }; + tsk_bool_t is_ro_loopback_address[TMEDIA_SESSION_MAX_LINES] = { tsk_false }; + tsk_bool_t is_ice_enabled[TMEDIA_SESSION_MAX_LINES] = { tsk_false }; + tsk_bool_t is_ice_restart[TMEDIA_SESSION_MAX_LINES] = { tsk_false }; + tsk_bool_t is_dtls_fingerprint_changed[TMEDIA_SESSION_MAX_LINES] = { tsk_false }; tsk_bool_t is_sdes_crypto_changed[TMEDIA_SESSION_MAX_LINES] = { tsk_false }; - tmedia_type_t media_types[TMEDIA_SESSION_MAX_LINES] = { tmedia_none }; - tsk_bool_t is_media_type_changed = tsk_false; - tsk_bool_t is_ro_media_lines_changed = tsk_false; - tsk_bool_t had_ro_sdp, had_lo_sdp, had_ro_provisional, is_ro_provisional_final_matching = tsk_false; - tsk_bool_t is_new_mediatype_striped = tsk_false; - tmedia_qos_stype_t qos_type = tmedia_qos_stype_none; - tmedia_type_t new_mediatype = tmedia_none; - tmedia_sessions_L_t *list_tmp_sessions; - - if (!self || !sdp) { - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - if (!(list_tmp_sessions = tsk_list_create())) { - TSK_DEBUG_ERROR("Failed to create tmp list"); - return -2; - } - - tsk_safeobj_lock(self); - tsk_list_lock(self->sessions); - - new_mediatype = tmedia_type_from_sdp(sdp); - had_ro_sdp = (self->sdp.ro != tsk_null); - had_lo_sdp = (self->sdp.lo != tsk_null); - had_ro_provisional = (had_ro_sdp && self->ro_provisional); - - // Remove BFCP offer if not locally enabled. Only the client can init BFCP session. - if ((ro_type & tmedia_ro_type_offer)) { - if (!(self->type & tmedia_bfcp_video)) { - is_new_mediatype_striped |= (new_mediatype & tmedia_bfcp_video); - new_mediatype &= ~tmedia_bfcp_video; - } - if (!(self->type & tmedia_bfcp_audio)) { - is_new_mediatype_striped |= (new_mediatype & tmedia_bfcp_video); - new_mediatype &= ~tmedia_bfcp_audio; - } - if (!(self->type & tmedia_bfcp)) { - is_new_mediatype_striped |= (new_mediatype & tmedia_bfcp_video); - new_mediatype &= ~tmedia_bfcp; - } - } - - /* RFC 3264 subcaluse 8 - When issuing an offer that modifies the session, the "o=" line of the new SDP MUST be identical to that in the previous SDP, - except that the version in the origin field MUST increment by one from the previous SDP. If the version in the origin line - does not increment, the SDP MUST be identical to the SDP with that version number. The answerer MUST be prepared to receive - an offer that contains SDP with a version that has not changed; this is effectively a no-op. - */ - if ((O = (const tsdp_header_O_t*)tsdp_message_get_header(sdp, tsdp_htype_O))){ - tsk_bool_t is_ro_provisional; - if (self->sdp.ro_ver == (int32_t)O->sess_version){ - TSK_DEBUG_INFO("Remote offer has not changed"); - ret = 0; - goto bail; - } - // Last provisional and new final sdp messages match only if: - // - session version diff is == 1 - // - previous sdp was provisional and new one is final - // - the new final sdp is inside an answer - is_ro_provisional = ((ro_type & tmedia_ro_type_provisional) == tmedia_ro_type_provisional); - is_ro_provisional_final_matching = ((had_ro_provisional && !is_ro_provisional) && ((self->sdp.ro_ver + 1) == O->sess_version) && ((ro_type & tmedia_ro_type_answer) == tmedia_ro_type_answer)); - self->sdp.ro_ver = (int32_t)O->sess_version; - } - else{ - TSK_DEBUG_ERROR("o= line is missing"); - ret = -2; - goto bail; - } - - /* SDP comparison */ - if ((sdp && self->sdp.ro)){ - const tsdp_header_M_t *M0, *M1; - const tsdp_header_C_t *C0, *C1; - const tsdp_header_A_t *A0, *A1; - const tsdp_header_A_t *A0_sess_fp, *A1_sess_fp; // session-level fingerprints - tsdp_header_M_diff_t med_level_diff; // media-level diff - index = 0; - A0_sess_fp = tsdp_message_get_headerA(self->sdp.ro, "fingerprint"); - A1_sess_fp = tsdp_message_get_headerA(sdp, "fingerprint"); - while ((M0 = (const tsdp_header_M_t*)tsdp_message_get_headerAt(self->sdp.ro, tsdp_htype_M, index))){ - ++m_lines_count; - if (m_lines_count >= TMEDIA_SESSION_MAX_LINES) { - TSK_DEBUG_ERROR("Too many m-lines %u>%u", (unsigned)m_lines_count, (unsigned)TMEDIA_SESSION_MAX_LINES); - ret = -2; - goto bail; - } - M1 = (const tsdp_header_M_t*)tsdp_message_get_headerAt(sdp, tsdp_htype_M, index); - // media-level diffs - - if ((ret = tsdp_header_M_diff(M0, M1, &med_level_diff)) != 0) { - goto bail; - } - if (med_level_diff & tsdp_header_M_diff_hold_resume) is_ro_hold_resume_changed[index] = tsk_true; - if (med_level_diff & tsdp_header_M_diff_index) is_ro_media_lines_changed = tsk_true; - if (med_level_diff & tsdp_header_M_diff_codecs) is_ro_codecs_changed[index] = tsk_true; - if (med_level_diff & tsdp_header_M_diff_network_info) is_ro_network_info_changed[index] = tsk_true; - if (tmedia_defaults_get_ice_enabled() && (med_level_diff & tsdp_header_M_diff_ice_enabled)) is_ice_enabled[index] = tsk_true; - if (tmedia_defaults_get_ice_enabled() && (med_level_diff & tsdp_header_M_diff_ice_restart)) is_ice_restart[index] = tsk_true; - if (med_level_diff & tsdp_header_M_diff_dtls_fingerprint) is_dtls_fingerprint_changed[index] = tsk_true; - if (med_level_diff & tsdp_header_M_diff_sdes_crypto) is_sdes_crypto_changed[index] = tsk_true; - if (med_level_diff & tsdp_header_M_diff_media_type); // cannot happen as media must keep same index - - // dtls fingerprint (session-level) - if (!is_dtls_fingerprint_changed[index]) { - A0 = tsdp_header_M_findA_at(M0, "fingerprint", 0); - A1 = M1 ? tsdp_header_M_findA_at(M1, "fingerprint", 0) : tsk_null; - is_dtls_fingerprint_changed[index] = (A0 && A1 && !tsk_striequals(A0->value, A1->value)); - } - // network info (session-level) - if (!is_ro_network_info_changed[index]) { - C0 = (const tsdp_header_C_t*)tsdp_message_get_headerAt(self->sdp.ro, tsdp_htype_C, index); - C1 = (const tsdp_header_C_t*)tsdp_message_get_headerAt(sdp, tsdp_htype_C, index); - // Connection informations must be both "null" or "not-null" - if (!(is_ro_network_info_changed[index] = !((C0 && C1) || (!C0 && !C1)))){ - if (C0) { - is_ro_network_info_changed[index] = (!tsk_strequals(C1->addr, C0->addr) || !tsk_strequals(C1->nettype, C0->nettype) || !tsk_strequals(C1->addrtype, C0->addrtype)); - } - } - } + tmedia_type_t media_types[TMEDIA_SESSION_MAX_LINES] = { tmedia_none }; + tsk_bool_t is_media_type_changed = tsk_false; + tsk_bool_t is_ro_media_lines_changed = tsk_false; + tsk_bool_t had_ro_sdp, had_lo_sdp, had_ro_provisional, is_ro_provisional_final_matching = tsk_false; + tsk_bool_t is_new_mediatype_striped = tsk_false; + tmedia_qos_stype_t qos_type = tmedia_qos_stype_none; + tmedia_type_t new_mediatype = tmedia_none; + tmedia_sessions_L_t *list_tmp_sessions; + + if (!self || !sdp) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + if (!(list_tmp_sessions = tsk_list_create())) { + TSK_DEBUG_ERROR("Failed to create tmp list"); + return -2; + } + + tsk_safeobj_lock(self); + tsk_list_lock(self->sessions); + + new_mediatype = tmedia_type_from_sdp(sdp); + had_ro_sdp = (self->sdp.ro != tsk_null); + had_lo_sdp = (self->sdp.lo != tsk_null); + had_ro_provisional = (had_ro_sdp && self->ro_provisional); + + // Remove BFCP offer if not locally enabled. Only the client can init BFCP session. + if ((ro_type & tmedia_ro_type_offer)) { + if (!(self->type & tmedia_bfcp_video)) { + is_new_mediatype_striped |= (new_mediatype & tmedia_bfcp_video); + new_mediatype &= ~tmedia_bfcp_video; + } + if (!(self->type & tmedia_bfcp_audio)) { + is_new_mediatype_striped |= (new_mediatype & tmedia_bfcp_video); + new_mediatype &= ~tmedia_bfcp_audio; + } + if (!(self->type & tmedia_bfcp)) { + is_new_mediatype_striped |= (new_mediatype & tmedia_bfcp_video); + new_mediatype &= ~tmedia_bfcp; + } + } + + /* RFC 3264 subcaluse 8 + When issuing an offer that modifies the session, the "o=" line of the new SDP MUST be identical to that in the previous SDP, + except that the version in the origin field MUST increment by one from the previous SDP. If the version in the origin line + does not increment, the SDP MUST be identical to the SDP with that version number. The answerer MUST be prepared to receive + an offer that contains SDP with a version that has not changed; this is effectively a no-op. + */ + if ((O = (const tsdp_header_O_t*)tsdp_message_get_header(sdp, tsdp_htype_O))) { + tsk_bool_t is_ro_provisional; + if (self->sdp.ro_ver == (int32_t)O->sess_version) { + TSK_DEBUG_INFO("Remote offer has not changed"); + ret = 0; + goto bail; + } + // Last provisional and new final sdp messages match only if: + // - session version diff is == 1 + // - previous sdp was provisional and new one is final + // - the new final sdp is inside an answer + is_ro_provisional = ((ro_type & tmedia_ro_type_provisional) == tmedia_ro_type_provisional); + is_ro_provisional_final_matching = ((had_ro_provisional && !is_ro_provisional) && ((self->sdp.ro_ver + 1) == O->sess_version) && ((ro_type & tmedia_ro_type_answer) == tmedia_ro_type_answer)); + self->sdp.ro_ver = (int32_t)O->sess_version; + } + else { + TSK_DEBUG_ERROR("o= line is missing"); + ret = -2; + goto bail; + } + + /* SDP comparison */ + if ((sdp && self->sdp.ro)) { + const tsdp_header_M_t *M0, *M1; + const tsdp_header_C_t *C0, *C1; + const tsdp_header_A_t *A0, *A1; + const tsdp_header_A_t *A0_sess_fp, *A1_sess_fp; // session-level fingerprints + tsdp_header_M_diff_t med_level_diff; // media-level diff + index = 0; + A0_sess_fp = tsdp_message_get_headerA(self->sdp.ro, "fingerprint"); + A1_sess_fp = tsdp_message_get_headerA(sdp, "fingerprint"); + while ((M0 = (const tsdp_header_M_t*)tsdp_message_get_headerAt(self->sdp.ro, tsdp_htype_M, index))) { + ++m_lines_count; + if (m_lines_count >= TMEDIA_SESSION_MAX_LINES) { + TSK_DEBUG_ERROR("Too many m-lines %u>%u", (unsigned)m_lines_count, (unsigned)TMEDIA_SESSION_MAX_LINES); + ret = -2; + goto bail; + } + M1 = (const tsdp_header_M_t*)tsdp_message_get_headerAt(sdp, tsdp_htype_M, index); + // media-level diffs + + if ((ret = tsdp_header_M_diff(M0, M1, &med_level_diff)) != 0) { + goto bail; + } + if (med_level_diff & tsdp_header_M_diff_hold_resume) { + is_ro_hold_resume_changed[index] = tsk_true; + } + if (med_level_diff & tsdp_header_M_diff_index) { + is_ro_media_lines_changed = tsk_true; + } + if (med_level_diff & tsdp_header_M_diff_codecs) { + is_ro_codecs_changed[index] = tsk_true; + } + if (med_level_diff & tsdp_header_M_diff_network_info) { + is_ro_network_info_changed[index] = tsk_true; + } + if (tmedia_defaults_get_ice_enabled() && (med_level_diff & tsdp_header_M_diff_ice_enabled)) { + is_ice_enabled[index] = tsk_true; + } + if (tmedia_defaults_get_ice_enabled() && (med_level_diff & tsdp_header_M_diff_ice_restart)) { + is_ice_restart[index] = tsk_true; + } + if (med_level_diff & tsdp_header_M_diff_dtls_fingerprint) { + is_dtls_fingerprint_changed[index] = tsk_true; + } + if (med_level_diff & tsdp_header_M_diff_sdes_crypto) { + is_sdes_crypto_changed[index] = tsk_true; + } + if (med_level_diff & tsdp_header_M_diff_media_type); // cannot happen as media must keep same index + + // dtls fingerprint (session-level) + if (!is_dtls_fingerprint_changed[index]) { + A0 = tsdp_header_M_findA_at(M0, "fingerprint", 0); + A1 = M1 ? tsdp_header_M_findA_at(M1, "fingerprint", 0) : tsk_null; + is_dtls_fingerprint_changed[index] = (A0 && A1 && !tsk_striequals(A0->value, A1->value)); + } + // network info (session-level) + if (!is_ro_network_info_changed[index]) { + C0 = (const tsdp_header_C_t*)tsdp_message_get_headerAt(self->sdp.ro, tsdp_htype_C, index); + C1 = (const tsdp_header_C_t*)tsdp_message_get_headerAt(sdp, tsdp_htype_C, index); + // Connection informations must be both "null" or "not-null" + if (!(is_ro_network_info_changed[index] = !((C0 && C1) || (!C0 && !C1)))) { + if (C0) { + is_ro_network_info_changed[index] = (!tsk_strequals(C1->addr, C0->addr) || !tsk_strequals(C1->nettype, C0->nettype) || !tsk_strequals(C1->addrtype, C0->addrtype)); + } + } + } // TODO: sdes crypo lines (session-level) - // media type - media_types[index] = tmedia_type_from_sdp_headerM(M1); - - // ice (session-level) - if (tmedia_defaults_get_ice_enabled()) { - is_ice_enabled[index] |= tsdp_message_is_ice_enabled(sdp, index); - is_ice_restart[index] |= tsdp_message_is_ice_restart(sdp, index); - } - - // ro_codecs - if (had_lo_sdp && is_ro_codecs_changed[index]) { - // we already have a local sdp (means codecs already negotiated) and the remote is changing the codecs - tmedia_session_t* ms = (tmedia_session_t*)tsk_object_ref(TSK_OBJECT(_tmedia_session_mgr_find_session_at_index(self->sessions, index))); - if (ms && ms->prepared) { - tmedia_codec_t* encoder = tsk_null; - tmedia_param_t* param_get_codec = tmedia_param_create_get_session(media_types[index], tmedia_pvt_pobject, "codec-encoder", &encoder); - if (param_get_codec) { - if (tmedia_session_get(ms, param_get_codec) == 0) { - if (encoder) { - const char* codec_name = encoder->plugin ? encoder->plugin->name : "unknown"; - const char* neg_format = encoder->neg_format ? encoder->neg_format : encoder->format; - if (tsdp_header_M_have_fmt(M1, neg_format) == tsk_true) { // new ro has the old encoder? - // same rtpmap would produce same encoder -> change nothing - char* old_rtpmap = tsdp_header_M_get_rtpmap(M0, neg_format); - char* new_rtpmap = tsdp_header_M_get_rtpmap(M1, neg_format); - is_local_encoder_still_ok[index] = tsk_striequals(old_rtpmap, new_rtpmap); - TSK_FREE(old_rtpmap); TSK_FREE(new_rtpmap); - if (is_local_encoder_still_ok[index]) { - // TODO: add more checks - } - } - TSK_OBJECT_SAFE_FREE(encoder); // destroying "param_get_codec" won't release "encoder" - } - } - TSK_OBJECT_SAFE_FREE(param_get_codec); - } - } - TSK_OBJECT_SAFE_FREE(ms); - } - - ++index; - } - // the index was used against current ro which means at this step there is no longer any media at "index" - // to be sure that new and old sdp have same number of media lines, we just check that there is no media in the new sdp at "index" - is_ro_media_lines_changed |= (tsdp_message_get_headerAt(sdp, tsdp_htype_M, index) != tsk_null); - } - - /* - * Make sure that the provisional response is an preview of the final as explained rfc6337 section 3.1.1. We only check the most important part (IP addr and ports). - * It's useless to check codecs or any other caps (SRTP, ICE, DTLS...) as our offer haven't changed - * If the preview is different than the final response than this is a bug on the remote party: - * As per rfc6337 section 3.1.1.: - * - [RFC3261] requires all SDP in the responses to the INVITE request to be identical. - * - After the UAS has sent the answer in a reliable provisional - response to the INVITE, the UAS should not include any SDPs in - subsequent responses to the INVITE. - * If the remote party is buggy, then the newly generated local SDP will be sent in the ACK request - */ - is_ro_provisional_final_matching &= !(is_ro_media_lines_changed || __flags_sum((const tsk_bool_t*)&is_ro_network_info_changed, m_lines_count)); - - /* This is to hack fake forking from ZTE => ignore SDP with loopback address in order to not start/stop the camera several - * times which leads to more than ten seconds for session connection. - * Gets the global connection line: "c=" - * Loopback address is only invalid on - */ - if ((C = (const tsdp_header_C_t*)tsdp_message_get_header(sdp, tsdp_htype_C)) && C->addr){ - tsk_bool_t _is_ro_loopback_address = (tsk_striequals("IP4", C->addrtype) && tsk_striequals("127.0.0.1", C->addr)) - || (tsk_striequals("IP6", C->addrtype) && tsk_striequals("::1", C->addr)); - for (index = 0; index < m_lines_count; ++index) { - is_ro_loopback_address[index] = _is_ro_loopback_address; - } - } - - /* Check if media type has changed or not - * For initial offer we don't need to check anything - */ - if (self->sdp.lo) { - if ((is_media_type_changed = (new_mediatype != self->type)) || is_new_mediatype_striped) { - tsk_bool_t force = !!is_new_mediatype_striped; - tmedia_session_mgr_set_media_type_2(self, new_mediatype, force); - TSK_DEBUG_INFO("media type has changed"); - } - } - - TSK_DEBUG_INFO( - "m_lines_count=%u,\n" - "is_dtls_fingerprint_changed=%u,\n" + // media type + media_types[index] = tmedia_type_from_sdp_headerM(M1); + + // ice (session-level) + if (tmedia_defaults_get_ice_enabled()) { + is_ice_enabled[index] |= tsdp_message_is_ice_enabled(sdp, index); + is_ice_restart[index] |= tsdp_message_is_ice_restart(sdp, index); + } + + // ro_codecs + if (had_lo_sdp && is_ro_codecs_changed[index]) { + // we already have a local sdp (means codecs already negotiated) and the remote is changing the codecs + tmedia_session_t* ms = (tmedia_session_t*)tsk_object_ref(TSK_OBJECT(_tmedia_session_mgr_find_session_at_index(self->sessions, index))); + if (ms && ms->prepared) { + tmedia_codec_t* encoder = tsk_null; + tmedia_param_t* param_get_codec = tmedia_param_create_get_session(media_types[index], tmedia_pvt_pobject, "codec-encoder", &encoder); + if (param_get_codec) { + if (tmedia_session_get(ms, param_get_codec) == 0) { + if (encoder) { + const char* codec_name = encoder->plugin ? encoder->plugin->name : "unknown"; + const char* neg_format = encoder->neg_format ? encoder->neg_format : encoder->format; + if (tsdp_header_M_have_fmt(M1, neg_format) == tsk_true) { // new ro has the old encoder? + // same rtpmap would produce same encoder -> change nothing + char* old_rtpmap = tsdp_header_M_get_rtpmap(M0, neg_format); + char* new_rtpmap = tsdp_header_M_get_rtpmap(M1, neg_format); + is_local_encoder_still_ok[index] = tsk_striequals(old_rtpmap, new_rtpmap); + TSK_FREE(old_rtpmap); + TSK_FREE(new_rtpmap); + if (is_local_encoder_still_ok[index]) { + // TODO: add more checks + } + } + TSK_OBJECT_SAFE_FREE(encoder); // destroying "param_get_codec" won't release "encoder" + } + } + TSK_OBJECT_SAFE_FREE(param_get_codec); + } + } + TSK_OBJECT_SAFE_FREE(ms); + } + + ++index; + } + // the index was used against current ro which means at this step there is no longer any media at "index" + // to be sure that new and old sdp have same number of media lines, we just check that there is no media in the new sdp at "index" + is_ro_media_lines_changed |= (tsdp_message_get_headerAt(sdp, tsdp_htype_M, index) != tsk_null); + } + + /* + * Make sure that the provisional response is an preview of the final as explained rfc6337 section 3.1.1. We only check the most important part (IP addr and ports). + * It's useless to check codecs or any other caps (SRTP, ICE, DTLS...) as our offer haven't changed + * If the preview is different than the final response than this is a bug on the remote party: + * As per rfc6337 section 3.1.1.: + * - [RFC3261] requires all SDP in the responses to the INVITE request to be identical. + * - After the UAS has sent the answer in a reliable provisional + response to the INVITE, the UAS should not include any SDPs in + subsequent responses to the INVITE. + * If the remote party is buggy, then the newly generated local SDP will be sent in the ACK request + */ + is_ro_provisional_final_matching &= !(is_ro_media_lines_changed || __flags_sum((const tsk_bool_t*)&is_ro_network_info_changed, m_lines_count)); + + /* This is to hack fake forking from ZTE => ignore SDP with loopback address in order to not start/stop the camera several + * times which leads to more than ten seconds for session connection. + * Gets the global connection line: "c=" + * Loopback address is only invalid on + */ + if ((C = (const tsdp_header_C_t*)tsdp_message_get_header(sdp, tsdp_htype_C)) && C->addr) { + tsk_bool_t _is_ro_loopback_address = (tsk_striequals("IP4", C->addrtype) && tsk_striequals("127.0.0.1", C->addr)) + || (tsk_striequals("IP6", C->addrtype) && tsk_striequals("::1", C->addr)); + for (index = 0; index < m_lines_count; ++index) { + is_ro_loopback_address[index] = _is_ro_loopback_address; + } + } + + /* Check if media type has changed or not + * For initial offer we don't need to check anything + */ + if (self->sdp.lo) { + if ((is_media_type_changed = (new_mediatype != self->type)) || is_new_mediatype_striped) { + tsk_bool_t force = !!is_new_mediatype_striped; + tmedia_session_mgr_set_media_type_2(self, new_mediatype, force); + TSK_DEBUG_INFO("media type has changed"); + } + } + + TSK_DEBUG_INFO( + "m_lines_count=%u,\n" + "is_dtls_fingerprint_changed=%u,\n" "is_sdes_crypto_changed=%u,\n" - "is_ice_enabled=%u,\n" - "is_ice_restart=%u,\n" - "is_ro_hold_resume_changed=%u,\n" - "is_ro_provisional_final_matching=%d,\n" - "is_ro_media_lines_changed=%d,\n" - "is_ro_network_info_changed=%u,\n" - "is_ro_loopback_address=%u,\n" - "is_media_type_changed=%d,\n" - "is_ro_codecs_changed=%u\n" - "is_local_encoder_still_ok=%u\n", - (unsigned)m_lines_count, - (unsigned)__flags_sum((const tsk_bool_t*)&is_dtls_fingerprint_changed, m_lines_count), + "is_ice_enabled=%u,\n" + "is_ice_restart=%u,\n" + "is_ro_hold_resume_changed=%u,\n" + "is_ro_provisional_final_matching=%d,\n" + "is_ro_media_lines_changed=%d,\n" + "is_ro_network_info_changed=%u,\n" + "is_ro_loopback_address=%u,\n" + "is_media_type_changed=%d,\n" + "is_ro_codecs_changed=%u\n" + "is_local_encoder_still_ok=%u\n", + (unsigned)m_lines_count, + (unsigned)__flags_sum((const tsk_bool_t*)&is_dtls_fingerprint_changed, m_lines_count), (unsigned)__flags_sum((const tsk_bool_t*)&is_sdes_crypto_changed, m_lines_count), - (unsigned)__flags_sum((const tsk_bool_t*)&is_ice_enabled, m_lines_count), - (unsigned)__flags_sum((const tsk_bool_t*)&is_ice_restart, m_lines_count), - (unsigned)__flags_sum((const tsk_bool_t*)&is_ro_hold_resume_changed, m_lines_count), - is_ro_provisional_final_matching, - is_ro_media_lines_changed, - (unsigned)__flags_sum((const tsk_bool_t*)&is_ro_network_info_changed, m_lines_count), - (unsigned)__flags_sum((const tsk_bool_t*)&is_ro_loopback_address, m_lines_count), - is_media_type_changed, - (unsigned)__flags_sum((const tsk_bool_t*)&is_ro_codecs_changed, m_lines_count), - (unsigned)__flags_sum((const tsk_bool_t*)&is_local_encoder_still_ok, m_lines_count) - ); - - /* - * It's almost impossible to update the codecs, the connection information etc etc while the sessions are running - * For example, if the video producer is already started then, you probably cannot update its configuration - * without stoping it and restarting it again with the right config. Same for RTP Network config (ip addresses, NAT, ports, IP version, ...) - * - * "is_loopback_address" is used as a guard to avoid reconf for loopback address used for example by ZTE for fake forking. In all case - * loopback address won't work on embedded devices such as iOS and Android. - * - */ - if (self->started) { - for (index = 0; index < m_lines_count; ++index) { - if (/* && (!is_ro_loopback_address[index]) && */ ((is_ro_codecs_changed[index] && !is_local_encoder_still_ok[index]) || is_ro_network_info_changed[index] || is_dtls_fingerprint_changed[index] || is_sdes_crypto_changed[index])) { - TSK_DEBUG_INFO("Stop media index %d to reconf", (int)index); - stopped_to_reconf[index] = tsk_true; - tmedia_session_mgr_set(self, - TMEDIA_SESSION_SET_INT32(media_types[index], "stop-to-reconf", stopped_to_reconf[index]), - TMEDIA_SESSION_SET_NULL()); - if ((ret = _tmedia_session_mgr_stop(self, (int)index))){ - TSK_DEBUG_ERROR("Failed to stop session manager"); - goto bail; - } - } - } - } - - /* update remote offer */ - TSK_OBJECT_SAFE_FREE(self->sdp.ro); - self->sdp.ro = tsk_object_ref((void*)sdp); - - /* - if the session is running this means no session update is required unless some important changes - - this check must be done after the "ro" update - - "is_ro_hold_resume_changed" do not restart the session but updates the SDP - */ - if (self->started && !(__flags_sum((const tsk_bool_t*)&is_ro_hold_resume_changed, m_lines_count) || __flags_sum((const tsk_bool_t*)&stopped_to_reconf, m_lines_count) || is_ro_media_lines_changed)) { - goto end_of_sessions_update; - } - - /* prepare the session manager if not already done (create all sessions with their codecs) - * if network-initiated: think about tmedia_type_from_sdp() before creating the manager */ - if (_tmedia_session_mgr_load_sessions(self)){ - TSK_DEBUG_ERROR("Failed to prepare the session manager"); - ret = -3; - goto bail; - } - // update media line counts - index = m_lines_count; // save old "m_lines_count" before loading sessions - m_lines_count = tsk_list_count_all(self->sessions); // "m_lines_count" after loading sessions - TSK_DEBUG_INFO("new m_lines_count = %u -> %u", (unsigned)index, (unsigned)m_lines_count); - if (index != m_lines_count) { // start new sessions - for (; index < m_lines_count; ++index) { // for(session in new_sessions) - stopped_to_reconf[index] = self->started; // start new session if mgr started - if (tmedia_defaults_get_ice_enabled()) { - is_ice_enabled[index] |= tsdp_message_is_ice_enabled(sdp, index); - is_ice_restart[index] |= tsdp_message_is_ice_restart(sdp, index); - } - } - } - - /* get global connection line (common to all sessions) - * Each session should override this info if it has a different one in its "m=" line - * /!\ "remote-ip" is deprecated by "remote-sdp-message" and pending before complete remove - */ - if (C && C->addr){ - tmedia_session_mgr_set(self, - TMEDIA_SESSION_SET_STR(self->type, "remote-ip", C->addr), - TMEDIA_SESSION_SET_NULL()); - } - - /* pass complete remote sdp to the sessions to allow them to use session-level attributes - */ - tmedia_session_mgr_set(self, - TMEDIA_SESSION_SET_POBJECT(self->type, "remote-sdp-message", self->sdp.ro), - TMEDIA_SESSION_SET_NULL()); - - /* foreach "m=" line in the remote offer create/prepare a session (requires the session to be stopped)*/ - index = 0; - tsk_list_pushback_list(list_tmp_sessions, self->sessions); - tsk_list_clear_items(self->sessions); - while ((M = (const tsdp_header_M_t*)tsdp_message_get_headerAt(sdp, tsdp_htype_M, index++))) { - found = tsk_false; + (unsigned)__flags_sum((const tsk_bool_t*)&is_ice_enabled, m_lines_count), + (unsigned)__flags_sum((const tsk_bool_t*)&is_ice_restart, m_lines_count), + (unsigned)__flags_sum((const tsk_bool_t*)&is_ro_hold_resume_changed, m_lines_count), + is_ro_provisional_final_matching, + is_ro_media_lines_changed, + (unsigned)__flags_sum((const tsk_bool_t*)&is_ro_network_info_changed, m_lines_count), + (unsigned)__flags_sum((const tsk_bool_t*)&is_ro_loopback_address, m_lines_count), + is_media_type_changed, + (unsigned)__flags_sum((const tsk_bool_t*)&is_ro_codecs_changed, m_lines_count), + (unsigned)__flags_sum((const tsk_bool_t*)&is_local_encoder_still_ok, m_lines_count) + ); + + /* + * It's almost impossible to update the codecs, the connection information etc etc while the sessions are running + * For example, if the video producer is already started then, you probably cannot update its configuration + * without stoping it and restarting it again with the right config. Same for RTP Network config (ip addresses, NAT, ports, IP version, ...) + * + * "is_loopback_address" is used as a guard to avoid reconf for loopback address used for example by ZTE for fake forking. In all case + * loopback address won't work on embedded devices such as iOS and Android. + * + */ + if (self->started) { + for (index = 0; index < m_lines_count; ++index) { + if (/* && (!is_ro_loopback_address[index]) && */ ((is_ro_codecs_changed[index] && !is_local_encoder_still_ok[index]) || is_ro_network_info_changed[index] || is_dtls_fingerprint_changed[index] || is_sdes_crypto_changed[index])) { + TSK_DEBUG_INFO("Stop media index %d to reconf", (int)index); + stopped_to_reconf[index] = tsk_true; + tmedia_session_mgr_set(self, + TMEDIA_SESSION_SET_INT32(media_types[index], "stop-to-reconf", stopped_to_reconf[index]), + TMEDIA_SESSION_SET_NULL()); + if ((ret = _tmedia_session_mgr_stop(self, (int)index))) { + TSK_DEBUG_ERROR("Failed to stop session manager"); + goto bail; + } + } + } + } + + /* update remote offer */ + TSK_OBJECT_SAFE_FREE(self->sdp.ro); + self->sdp.ro = tsk_object_ref((void*)sdp); + + /* - if the session is running this means no session update is required unless some important changes + - this check must be done after the "ro" update + - "is_ro_hold_resume_changed" do not restart the session but updates the SDP + */ + if (self->started && !(__flags_sum((const tsk_bool_t*)&is_ro_hold_resume_changed, m_lines_count) || __flags_sum((const tsk_bool_t*)&stopped_to_reconf, m_lines_count) || is_ro_media_lines_changed)) { + goto end_of_sessions_update; + } + + /* prepare the session manager if not already done (create all sessions with their codecs) + * if network-initiated: think about tmedia_type_from_sdp() before creating the manager */ + if (_tmedia_session_mgr_load_sessions(self)) { + TSK_DEBUG_ERROR("Failed to prepare the session manager"); + ret = -3; + goto bail; + } + // update media line counts + index = m_lines_count; // save old "m_lines_count" before loading sessions + m_lines_count = tsk_list_count_all(self->sessions); // "m_lines_count" after loading sessions + TSK_DEBUG_INFO("new m_lines_count = %u -> %u", (unsigned)index, (unsigned)m_lines_count); + if (index != m_lines_count) { // start new sessions + for (; index < m_lines_count; ++index) { // for(session in new_sessions) + stopped_to_reconf[index] = self->started; // start new session if mgr started + if (tmedia_defaults_get_ice_enabled()) { + is_ice_enabled[index] |= tsdp_message_is_ice_enabled(sdp, index); + is_ice_restart[index] |= tsdp_message_is_ice_restart(sdp, index); + } + } + } + + /* get global connection line (common to all sessions) + * Each session should override this info if it has a different one in its "m=" line + * /!\ "remote-ip" is deprecated by "remote-sdp-message" and pending before complete remove + */ + if (C && C->addr) { + tmedia_session_mgr_set(self, + TMEDIA_SESSION_SET_STR(self->type, "remote-ip", C->addr), + TMEDIA_SESSION_SET_NULL()); + } + + /* pass complete remote sdp to the sessions to allow them to use session-level attributes + */ + tmedia_session_mgr_set(self, + TMEDIA_SESSION_SET_POBJECT(self->type, "remote-sdp-message", self->sdp.ro), + TMEDIA_SESSION_SET_NULL()); + + /* foreach "m=" line in the remote offer create/prepare a session (requires the session to be stopped)*/ + index = 0; + tsk_list_pushback_list(list_tmp_sessions, self->sessions); + tsk_list_clear_items(self->sessions); + while ((M = (const tsdp_header_M_t*)tsdp_message_get_headerAt(sdp, tsdp_htype_M, index++))) { + found = tsk_false; #if 1 - // rfc3264 - 8 Modifying the Session - // if the previous SDP had N "m=" lines, the new SDP MUST have at least N "m=" lines - // Deleted media streams from a previous SDP MUST NOT be removed in a new SDP - if (had_lo_sdp) { - ms = _tmedia_session_mgr_find_session_at_index(list_tmp_sessions, (index - 1 - active_sessions_count)); - } - else { - // Initial Offer - tmedia_type_t M_media_type = tmedia_type_from_sdp_headerM(M); - ms = tsk_list_find_object_by_pred(list_tmp_sessions, __pred_find_session_by_type, &M_media_type); - } + // rfc3264 - 8 Modifying the Session + // if the previous SDP had N "m=" lines, the new SDP MUST have at least N "m=" lines + // Deleted media streams from a previous SDP MUST NOT be removed in a new SDP + if (had_lo_sdp) { + ms = _tmedia_session_mgr_find_session_at_index(list_tmp_sessions, (index - 1 - active_sessions_count)); + } + else { + // Initial Offer + tmedia_type_t M_media_type = tmedia_type_from_sdp_headerM(M); + ms = tsk_list_find_object_by_pred(list_tmp_sessions, __pred_find_session_by_type, &M_media_type); + } #else - if (ro_type & tmedia_ro_type_answer) { - // Answer -> match by index - ms = _tmedia_session_mgr_find_session_at_index(list_tmp_sessions, (index - 1 - active_sessions_count)); - } - else { - // Request -> match by type - tmedia_type_t M_media_type = tmedia_type_from_sdp_headerM(M); - ms = tsk_list_find_object_by_pred(list_tmp_sessions, __pred_find_session_by_type, &M_media_type); - } + if (ro_type & tmedia_ro_type_answer) { + // Answer -> match by index + ms = _tmedia_session_mgr_find_session_at_index(list_tmp_sessions, (index - 1 - active_sessions_count)); + } + else { + // Request -> match by type + tmedia_type_t M_media_type = tmedia_type_from_sdp_headerM(M); + ms = tsk_list_find_object_by_pred(list_tmp_sessions, __pred_find_session_by_type, &M_media_type); + } #endif - if (ms && (tsk_striequals(tmedia_session_get_media(ms), M->media))) { - /* prepare the media session */ - if (!ms->prepared && M->port && (_tmedia_session_prepare(TMEDIA_SESSION(ms)))){ - TSK_DEBUG_ERROR("Failed to prepare session"); /* should never happen */ - goto bail; - } - /* set remote ro at session-level unless media is disabled (port=0) */ - if (M->port == 0 || (ret = _tmedia_session_set_ro(TMEDIA_SESSION(ms), M)) == 0) { - tmedia_session_t* _ms = tsk_object_ref(TSK_OBJECT(ms)); - found = tsk_true; - ++active_sessions_count; - tsk_list_push_back_data(self->sessions, (void**)&_ms); // add at the same index - tsk_list_remove_item_by_data(list_tmp_sessions, ms); // make sure not to use the session more than once - } - else { - TSK_DEBUG_WARN("_tmedia_session_set_ro() failed"); - ret = 0; // add ghost for this session. Do not goto bail because set_ro() is allowed to fail (e.g. codec mismatch). - } - /* set QoS type (only if we are not the offerer) */ - if (/*!self->offerer ==> we suppose that the remote party respected our demand &&*/ qos_type == tmedia_qos_stype_none) { - tmedia_qos_tline_t* tline = tmedia_qos_tline_from_sdp(M); - if (tline) { - qos_type = tline->type; - TSK_OBJECT_SAFE_FREE(tline); - } - } - } - - if (!found /*&& (self->sdp.lo == tsk_null)*/){ - /* Session not supported and we are not the initial offerer ==> add ghost session */ - /* - An offered stream MAY be rejected in the answer, for any reason. If - a stream is rejected, the offerer and answerer MUST NOT generate - media (or RTCP packets) for that stream. To reject an offered - stream, the port number in the corresponding stream in the answer - MUST be set to zero. Any media formats listed are ignored. AT LEAST - ONE MUST BE PRESENT, AS SPECIFIED BY SDP. - */ - 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_strupdate(&ghost->proto, M->proto); /* copy proto */ - if (!TSK_LIST_IS_EMPTY(M->FMTs)){ - tsk_strupdate(&ghost->first_format, ((const tsdp_fmt_t*)TSK_LIST_FIRST_DATA(M->FMTs))->value); /* copy format */ - } - tsk_list_push_back_data(self->sessions, (void**)&ghost); - } - else { - TSK_DEBUG_ERROR("Failed to create ghost session"); - continue; - } - } - } + if (ms && (tsk_striequals(tmedia_session_get_media(ms), M->media))) { + /* prepare the media session */ + if (!ms->prepared && M->port && (_tmedia_session_prepare(TMEDIA_SESSION(ms)))) { + TSK_DEBUG_ERROR("Failed to prepare session"); /* should never happen */ + goto bail; + } + /* set remote ro at session-level unless media is disabled (port=0) */ + if (M->port == 0 || (ret = _tmedia_session_set_ro(TMEDIA_SESSION(ms), M)) == 0) { + tmedia_session_t* _ms = tsk_object_ref(TSK_OBJECT(ms)); + found = tsk_true; + ++active_sessions_count; + tsk_list_push_back_data(self->sessions, (void**)&_ms); // add at the same index + tsk_list_remove_item_by_data(list_tmp_sessions, ms); // make sure not to use the session more than once + } + else { + TSK_DEBUG_WARN("_tmedia_session_set_ro() failed"); + ret = 0; // add ghost for this session. Do not goto bail because set_ro() is allowed to fail (e.g. codec mismatch). + } + /* set QoS type (only if we are not the offerer) */ + if (/*!self->offerer ==> we suppose that the remote party respected our demand &&*/ qos_type == tmedia_qos_stype_none) { + tmedia_qos_tline_t* tline = tmedia_qos_tline_from_sdp(M); + if (tline) { + qos_type = tline->type; + TSK_OBJECT_SAFE_FREE(tline); + } + } + } + + if (!found /*&& (self->sdp.lo == tsk_null)*/) { + /* Session not supported and we are not the initial offerer ==> add ghost session */ + /* + An offered stream MAY be rejected in the answer, for any reason. If + a stream is rejected, the offerer and answerer MUST NOT generate + media (or RTCP packets) for that stream. To reject an offered + stream, the port number in the corresponding stream in the answer + MUST be set to zero. Any media formats listed are ignored. AT LEAST + ONE MUST BE PRESENT, AS SPECIFIED BY SDP. + */ + 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_strupdate(&ghost->proto, M->proto); /* copy proto */ + if (!TSK_LIST_IS_EMPTY(M->FMTs)) { + tsk_strupdate(&ghost->first_format, ((const tsdp_fmt_t*)TSK_LIST_FIRST_DATA(M->FMTs))->value); /* copy format */ + } + tsk_list_push_back_data(self->sessions, (void**)&ghost); + } + else { + TSK_DEBUG_ERROR("Failed to create ghost session"); + continue; + } + } + } end_of_sessions_update: - /* update QoS type */ - if (!self->offerer && (qos_type != tmedia_qos_stype_none)){ - self->qos.type = qos_type; - } - - /* signal that ro has changed (will be used to update lo) unless there was no ro_sdp */ - self->ro_changed = (had_ro_sdp && (__flags_sum((const tsk_bool_t*)&is_ro_hold_resume_changed, m_lines_count) || __flags_sum((const tsk_bool_t*)&is_ro_network_info_changed, m_lines_count) || is_ro_media_lines_changed || __flags_sum((const tsk_bool_t*)&is_ro_codecs_changed, m_lines_count) /*|| is_media_type_changed || is_new_mediatype_striped*/)); - - /* update "provisional" info */ - self->ro_provisional = ((ro_type & tmedia_ro_type_provisional) == tmedia_ro_type_provisional); - - if (self->ro_changed) { - /* update local offer before restarting the session manager otherwise neg_codecs won't match if new codecs - have been added or removed. No need to load sessions again. */ - (_tmedia_session_mgr_get_lo(self, kSkipSessionLoadTrue, kForceUpdateLOFalse)); - } - /* manager was started and we stopped it in order to reconfigure it (codecs, network, ....) - * When ICE is active ("is_ice_active" = yes), the media session will be explicitly restarted when conncheck succeed or fail. - */ - for (index = 0; index < m_lines_count; ++index) { - if (stopped_to_reconf[index] && !is_ice_enabled[index]) { - if ((ret = _tmedia_session_mgr_start(self, (int)index))) { - TSK_DEBUG_ERROR("Failed to re-start session at index = %d", (int)index); - goto bail; - } - } - } - - // will send [488 Not Acceptable] / [BYE] if no active session - ret = (self->ro_changed && active_sessions_count <= 0) ? -0xFF : 0; + /* update QoS type */ + if (!self->offerer && (qos_type != tmedia_qos_stype_none)) { + self->qos.type = qos_type; + } + + /* signal that ro has changed (will be used to update lo) unless there was no ro_sdp */ + self->ro_changed = (had_ro_sdp && (__flags_sum((const tsk_bool_t*)&is_ro_hold_resume_changed, m_lines_count) || __flags_sum((const tsk_bool_t*)&is_ro_network_info_changed, m_lines_count) || is_ro_media_lines_changed || __flags_sum((const tsk_bool_t*)&is_ro_codecs_changed, m_lines_count) /*|| is_media_type_changed || is_new_mediatype_striped*/)); + + /* update "provisional" info */ + self->ro_provisional = ((ro_type & tmedia_ro_type_provisional) == tmedia_ro_type_provisional); + + if (self->ro_changed) { + /* update local offer before restarting the session manager otherwise neg_codecs won't match if new codecs + have been added or removed. No need to load sessions again. */ + (_tmedia_session_mgr_get_lo(self, kSkipSessionLoadTrue, kForceUpdateLOFalse)); + } + /* manager was started and we stopped it in order to reconfigure it (codecs, network, ....) + * When ICE is active ("is_ice_active" = yes), the media session will be explicitly restarted when conncheck succeed or fail. + */ + for (index = 0; index < m_lines_count; ++index) { + if (stopped_to_reconf[index] && !is_ice_enabled[index]) { + if ((ret = _tmedia_session_mgr_start(self, (int)index))) { + TSK_DEBUG_ERROR("Failed to re-start session at index = %d", (int)index); + goto bail; + } + } + } + + // will send [488 Not Acceptable] / [BYE] if no active session + ret = (self->ro_changed && active_sessions_count <= 0) ? -0xFF : 0; bail: - TSK_OBJECT_SAFE_FREE(list_tmp_sessions); + TSK_OBJECT_SAFE_FREE(list_tmp_sessions); - tsk_safeobj_unlock(self); - tsk_list_unlock(self->sessions); - return ret; + tsk_safeobj_unlock(self); + tsk_list_unlock(self->sessions); + return ret; } const tsdp_message_t* tmedia_session_mgr_get_ro(tmedia_session_mgr_t* self) { - if (!self){ - TSK_DEBUG_ERROR("Invalid parameter"); - return tsk_null; - } - return self->sdp.ro; + if (!self) { + TSK_DEBUG_ERROR("Invalid parameter"); + return tsk_null; + } + return self->sdp.ro; } tsk_bool_t tmedia_session_mgr_is_new_ro(tmedia_session_mgr_t* self, const tsdp_message_t* sdp) { - tsk_bool_t is_new = tsk_true; - const tsdp_header_O_t* O; + tsk_bool_t is_new = tsk_true; + const tsdp_header_O_t* O; - if (!self || !sdp){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } + if (!self || !sdp) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } - tsk_safeobj_lock(self); + tsk_safeobj_lock(self); - if ((O = (const tsdp_header_O_t*)tsdp_message_get_header(sdp, tsdp_htype_O))) { - is_new = (self->sdp.ro_ver != (int32_t)O->sess_version); - } - else { - TSK_DEBUG_ERROR("o= line is missing"); - } + if ((O = (const tsdp_header_O_t*)tsdp_message_get_header(sdp, tsdp_htype_O))) { + is_new = (self->sdp.ro_ver != (int32_t)O->sess_version); + } + else { + TSK_DEBUG_ERROR("o= line is missing"); + } - tsk_safeobj_unlock(self); - return is_new; + tsk_safeobj_unlock(self); + return is_new; } /**@ingroup tmedia_session_group @@ -1581,23 +1649,23 @@ tsk_bool_t tmedia_session_mgr_is_new_ro(tmedia_session_mgr_t* self, const tsdp_m */ int tmedia_session_mgr_hold(tmedia_session_mgr_t* self, tmedia_type_t type) { - const tsk_list_item_t* item; + const tsk_list_item_t* item; - if (!self){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } + if (!self) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } - tsk_list_foreach(item, self->sessions){ - tmedia_session_t* session = TMEDIA_SESSION(item->data); - if (((session->type & type) == session->type) && session->M.lo){ - if (tsdp_header_M_hold(session->M.lo, tsk_true) == 0){ - self->state_changed = tsk_true; - session->lo_held = tsk_true; - } - } - } - return 0; + tsk_list_foreach(item, self->sessions) { + tmedia_session_t* session = TMEDIA_SESSION(item->data); + if (((session->type & type) == session->type) && session->M.lo) { + if (tsdp_header_M_hold(session->M.lo, tsk_true) == 0) { + self->state_changed = tsk_true; + session->lo_held = tsk_true; + } + } + } + return 0; } /**@ingroup tmedia_session_group @@ -1608,33 +1676,33 @@ int tmedia_session_mgr_hold(tmedia_session_mgr_t* self, tmedia_type_t type) */ tsk_bool_t tmedia_session_mgr_is_held(tmedia_session_mgr_t* self, tmedia_type_t type, tsk_bool_t local) { - const tsk_list_item_t* item; - tsk_bool_t have_these_sessions = tsk_false; - - if (!self){ - TSK_DEBUG_ERROR("Invalid parameter"); - return tsk_false; - } - - tsk_list_foreach(item, self->sessions){ - tmedia_session_t* session = TMEDIA_SESSION(item->data); - if ((session->type & type) == session->type){ - if (local && session->M.lo){ - have_these_sessions = tsk_true; - if (!tsdp_header_M_is_held(session->M.lo, tsk_true)){ - return tsk_false; - } - } - else if (!local && session->M.ro){ - have_these_sessions = tsk_true; - if (!tsdp_header_M_is_held(session->M.ro, tsk_false)){ - return tsk_false; - } - } - } - } - /* none is held */ - return have_these_sessions ? tsk_true : tsk_false; + const tsk_list_item_t* item; + tsk_bool_t have_these_sessions = tsk_false; + + if (!self) { + TSK_DEBUG_ERROR("Invalid parameter"); + return tsk_false; + } + + tsk_list_foreach(item, self->sessions) { + tmedia_session_t* session = TMEDIA_SESSION(item->data); + if ((session->type & type) == session->type) { + if (local && session->M.lo) { + have_these_sessions = tsk_true; + if (!tsdp_header_M_is_held(session->M.lo, tsk_true)) { + return tsk_false; + } + } + else if (!local && session->M.ro) { + have_these_sessions = tsk_true; + if (!tsdp_header_M_is_held(session->M.ro, tsk_false)) { + return tsk_false; + } + } + } + } + /* none is held */ + return have_these_sessions ? tsk_true : tsk_false; } /**@ingroup tmedia_session_group @@ -1647,28 +1715,28 @@ tsk_bool_t tmedia_session_mgr_is_held(tmedia_session_mgr_t* self, tmedia_type_t */ int tmedia_session_mgr_resume(tmedia_session_mgr_t* self, tmedia_type_t type, tsk_bool_t local) { - const tsk_list_item_t* item; - int ret = 0; - if (!self){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - - tsk_list_foreach(item, self->sessions){ - tmedia_session_t* session = TMEDIA_SESSION(item->data); - if (((session->type & type) == session->type) && session->M.lo){ - if ((ret = tsdp_header_M_resume(session->M.lo, local)) == 0){ - self->state_changed = tsk_true; - if (local){ - session->lo_held = tsk_false; - } - else{ - session->ro_held = tsk_false; - } - } - } - } - return ret; + const tsk_list_item_t* item; + int ret = 0; + if (!self) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + + tsk_list_foreach(item, self->sessions) { + tmedia_session_t* session = TMEDIA_SESSION(item->data); + if (((session->type & type) == session->type) && session->M.lo) { + if ((ret = tsdp_header_M_resume(session->M.lo, local)) == 0) { + self->state_changed = tsk_true; + if (local) { + session->lo_held = tsk_false; + } + else { + session->ro_held = tsk_false; + } + } + } + } + return ret; } /**@ingroup tmedia_session_group @@ -1680,47 +1748,47 @@ int tmedia_session_mgr_resume(tmedia_session_mgr_t* self, tmedia_type_t type, ts */ int tmedia_session_mgr_add_media(tmedia_session_mgr_t* self, tmedia_type_t type) { - tsk_size_t i = 0; - tmedia_session_t* session; - const tmedia_session_plugin_def_t* plugin; - - if (!self){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - - /* for each registered plugin match with the supplied type */ - while ((i < TMED_SESSION_MAX_PLUGINS) && (plugin = __tmedia_session_plugins[i++])){ - if ((plugin->type & type) == plugin->type){ - /* check whether we already support this media */ - if ((session = (tmedia_session_t*)tsk_list_find_object_by_pred(self->sessions, __pred_find_session_by_type, &plugin->type)) && session->plugin){ - if (session->prepared){ - TSK_DEBUG_WARN("[%s] already active", plugin->media); - } - else{ - /* exist but unprepared(port=0) */ - _tmedia_session_prepare(session); - if (self->started && session->plugin->start){ - session->plugin->start(session); - } - self->state_changed = tsk_true; - } - } - else{ - /* session not supported */ - self->state_changed = tsk_true; - if ((session = tmedia_session_create(plugin->type))){ - if (self->started && session->plugin->start){ - session->plugin->start(session); - } - tsk_list_push_back_data(self->sessions, (void**)(&session)); - self->state_changed = tsk_true; - } - } - } - } - - return self->state_changed ? 0 : -2; + tsk_size_t i = 0; + tmedia_session_t* session; + const tmedia_session_plugin_def_t* plugin; + + if (!self) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + + /* for each registered plugin match with the supplied type */ + while ((i < TMED_SESSION_MAX_PLUGINS) && (plugin = __tmedia_session_plugins[i++])) { + if ((plugin->type & type) == plugin->type) { + /* check whether we already support this media */ + if ((session = (tmedia_session_t*)tsk_list_find_object_by_pred(self->sessions, __pred_find_session_by_type, &plugin->type)) && session->plugin) { + if (session->prepared) { + TSK_DEBUG_WARN("[%s] already active", plugin->media); + } + else { + /* exist but unprepared(port=0) */ + _tmedia_session_prepare(session); + if (self->started && session->plugin->start) { + session->plugin->start(session); + } + self->state_changed = tsk_true; + } + } + else { + /* session not supported */ + self->state_changed = tsk_true; + if ((session = tmedia_session_create(plugin->type))) { + if (self->started && session->plugin->start) { + session->plugin->start(session); + } + tsk_list_push_back_data(self->sessions, (void**)(&session)); + self->state_changed = tsk_true; + } + } + } + } + + return self->state_changed ? 0 : -2; } /**@ingroup tmedia_session_group @@ -1731,22 +1799,22 @@ int tmedia_session_mgr_add_media(tmedia_session_mgr_t* self, tmedia_type_t type) */ int tmedia_session_mgr_remove_media(tmedia_session_mgr_t* self, tmedia_type_t type) { - const tsk_list_item_t* item; + const tsk_list_item_t* item; - if (!self){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } + if (!self) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } - tsk_list_foreach(item, self->sessions){ - tmedia_session_t* session = TMEDIA_SESSION(item->data); - if (((session->type & type) == session->type) && session->plugin->stop){ - if (!session->plugin->stop(session)){ - self->state_changed = tsk_true; - } - } - } - return 0; + tsk_list_foreach(item, self->sessions) { + tmedia_session_t* session = TMEDIA_SESSION(item->data); + if (((session->type & type) == session->type) && session->plugin->stop) { + if (!session->plugin->stop(session)) { + self->state_changed = tsk_true; + } + } + } + return 0; } /**@ingroup tmedia_session_group @@ -1758,14 +1826,14 @@ int tmedia_session_mgr_remove_media(tmedia_session_mgr_t* self, tmedia_type_t ty */ int tmedia_session_mgr_set_qos(tmedia_session_mgr_t* self, tmedia_qos_stype_t qos_type, tmedia_qos_strength_t qos_strength) { - if (!self){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } + if (!self) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } - self->qos.type = qos_type; - self->qos.strength = qos_strength; - return 0; + self->qos.type = qos_type; + self->qos.strength = qos_strength; + return 0; } /**@ingroup tmedia_session_group @@ -1775,20 +1843,20 @@ int tmedia_session_mgr_set_qos(tmedia_session_mgr_t* self, tmedia_qos_stype_t qo */ tsk_bool_t tmedia_session_mgr_canresume(tmedia_session_mgr_t* self) { - const tsk_list_item_t* item; + const tsk_list_item_t* item; - if (!self){ - TSK_DEBUG_ERROR("Invalid parameter"); - return tsk_true; - } + if (!self) { + TSK_DEBUG_ERROR("Invalid parameter"); + return tsk_true; + } - tsk_list_foreach(item, self->sessions){ - tmedia_session_t* session = TMEDIA_SESSION(item->data); - if (session && session->qos && !tmedia_qos_tline_canresume(session->qos)){ - return tsk_false; - } - } - return tsk_true; + tsk_list_foreach(item, self->sessions) { + tmedia_session_t* session = TMEDIA_SESSION(item->data); + if (session && session->qos && !tmedia_qos_tline_canresume(session->qos)) { + return tsk_false; + } + } + return tsk_true; } @@ -1797,673 +1865,673 @@ tsk_bool_t tmedia_session_mgr_canresume(tmedia_session_mgr_t* self) */ tsk_bool_t tmedia_session_mgr_has_active_session(tmedia_session_mgr_t* self) { - const tsk_list_item_t* item; + const tsk_list_item_t* item; - if (!self){ - TSK_DEBUG_ERROR("Invalid parameter"); - return tsk_false; - } + if (!self) { + TSK_DEBUG_ERROR("Invalid parameter"); + return tsk_false; + } - tsk_list_foreach(item, self->sessions){ - tmedia_session_t* session = TMEDIA_SESSION(item->data); - if (session && session->M.lo && session->M.lo->port){ - return tsk_true; - } - } - return tsk_false; + tsk_list_foreach(item, self->sessions) { + tmedia_session_t* session = TMEDIA_SESSION(item->data); + if (session && session->M.lo && session->M.lo->port) { + return tsk_true; + } + } + return tsk_false; } int tmedia_session_mgr_send_dtmf(tmedia_session_mgr_t* self, uint8_t event) { - tmedia_session_audio_t* session; - static const tmedia_type_t audio_type = tmedia_audio; - int ret = -3; + tmedia_session_audio_t* session; + static const tmedia_type_t audio_type = tmedia_audio; + int ret = -3; - if (!self){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } + if (!self) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } - session = (tmedia_session_audio_t*)tsk_list_find_object_by_pred(self->sessions, __pred_find_session_by_type, &audio_type); - if (session){ - session = tsk_object_ref(session); - ret = tmedia_session_audio_send_dtmf(TMEDIA_SESSION_AUDIO(session), event); - TSK_OBJECT_SAFE_FREE(session); - } - else{ - TSK_DEBUG_ERROR("No audio session associated to this manager"); - } + session = (tmedia_session_audio_t*)tsk_list_find_object_by_pred(self->sessions, __pred_find_session_by_type, &audio_type); + if (session) { + session = tsk_object_ref(session); + ret = tmedia_session_audio_send_dtmf(TMEDIA_SESSION_AUDIO(session), event); + TSK_OBJECT_SAFE_FREE(session); + } + else { + TSK_DEBUG_ERROR("No audio session associated to this manager"); + } - return ret; + return ret; } int tmedia_session_mgr_set_t140_ondata_cbfn(tmedia_session_mgr_t* self, const void* context, tmedia_session_t140_ondata_cb_f func) { - tmedia_session_t* session; - int ret = -1; - if ((session = tmedia_session_mgr_find(self, tmedia_t140))){ - ret = tmedia_session_t140_set_ondata_cbfn(session, context, func); - TSK_OBJECT_SAFE_FREE(session); - } - return ret; + tmedia_session_t* session; + int ret = -1; + if ((session = tmedia_session_mgr_find(self, tmedia_t140))) { + ret = tmedia_session_t140_set_ondata_cbfn(session, context, func); + TSK_OBJECT_SAFE_FREE(session); + } + return ret; } int tmedia_session_mgr_send_t140_data(tmedia_session_mgr_t* self, enum tmedia_t140_data_type_e data_type, const void* data_ptr, unsigned data_size) { - tmedia_session_t* session; - int ret = -1; - if ((session = tmedia_session_mgr_find(self, tmedia_t140))){ - ret = tmedia_session_t140_send_data(session, data_type, data_ptr, data_size); - TSK_OBJECT_SAFE_FREE(session); - } - return ret; + tmedia_session_t* session; + int ret = -1; + if ((session = tmedia_session_mgr_find(self, tmedia_t140))) { + ret = tmedia_session_t140_send_data(session, data_type, data_ptr, data_size); + TSK_OBJECT_SAFE_FREE(session); + } + return ret; } int tmedia_session_mgr_set_onrtcp_cbfn(tmedia_session_mgr_t* self, tmedia_type_t media_type, const void* context, tmedia_session_rtcp_onevent_cb_f fun) { - tmedia_session_t* session; - tsk_list_item_t *item; + tmedia_session_t* session; + tsk_list_item_t *item; - if (!self){ - TSK_DEBUG_ERROR("Invlid parameter"); - return -1; - } + if (!self) { + TSK_DEBUG_ERROR("Invlid parameter"); + return -1; + } - tsk_list_lock(self->sessions); - tsk_list_foreach(item, self->sessions){ - if (!(session = item->data) || !(session->type & media_type)){ - continue; - } - tmedia_session_set_onrtcp_cbfn(session, context, fun); - } - tsk_list_unlock(self->sessions); + tsk_list_lock(self->sessions); + tsk_list_foreach(item, self->sessions) { + if (!(session = item->data) || !(session->type & media_type)) { + continue; + } + tmedia_session_set_onrtcp_cbfn(session, context, fun); + } + tsk_list_unlock(self->sessions); - return 0; + return 0; } int tmedia_session_mgr_send_rtcp_event(tmedia_session_mgr_t* self, tmedia_type_t media_type, tmedia_rtcp_event_type_t event_type, uint32_t ssrc_media) { - tmedia_session_t* session; - tsk_list_item_t *item; + tmedia_session_t* session; + tsk_list_item_t *item; - if (!self){ - TSK_DEBUG_ERROR("Invlid parameter"); - return -1; - } + if (!self) { + TSK_DEBUG_ERROR("Invlid parameter"); + return -1; + } - tsk_list_lock(self->sessions); - tsk_list_foreach(item, self->sessions){ - if (!(session = item->data) || !(session->type & media_type)){ - continue; - } - tmedia_session_send_rtcp_event(session, event_type, ssrc_media); - } - tsk_list_unlock(self->sessions); + tsk_list_lock(self->sessions); + tsk_list_foreach(item, self->sessions) { + if (!(session = item->data) || !(session->type & media_type)) { + continue; + } + tmedia_session_send_rtcp_event(session, event_type, ssrc_media); + } + tsk_list_unlock(self->sessions); - return 0; + return 0; } int tmedia_session_mgr_recv_rtcp_event(tmedia_session_mgr_t* self, tmedia_type_t media_type, tmedia_rtcp_event_type_t event_type, uint32_t ssrc_media) { - static const uint64_t __fake_session_id = 0; - return _tmedia_session_mgr_recv_rtcp_event(self, media_type, event_type, ssrc_media, __fake_session_id); + static const uint64_t __fake_session_id = 0; + return _tmedia_session_mgr_recv_rtcp_event(self, media_type, event_type, ssrc_media, __fake_session_id); } int tmedia_session_mgr_recv_rtcp_event_2(tmedia_session_mgr_t* self, tmedia_rtcp_event_type_t event_type, uint64_t session_id) { - static const uint32_t __fake_ssrc_media = 0; - static const tmedia_type_t __fake_media_type = tmedia_none; - return _tmedia_session_mgr_recv_rtcp_event(self, __fake_media_type, event_type, __fake_ssrc_media, session_id); + static const uint32_t __fake_ssrc_media = 0; + static const tmedia_type_t __fake_media_type = tmedia_none; + return _tmedia_session_mgr_recv_rtcp_event(self, __fake_media_type, event_type, __fake_ssrc_media, session_id); } int tmedia_session_mgr_send_file(tmedia_session_mgr_t* self, const char* path, ...) { - tmedia_session_msrp_t* session; - tmedia_type_t msrp_type = tmedia_msrp; - int ret = -3; + tmedia_session_msrp_t* session; + tmedia_type_t msrp_type = tmedia_msrp; + int ret = -3; - if (!self || !path){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } + if (!self || !path) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } - session = (tmedia_session_msrp_t*)tsk_list_find_object_by_pred(self->sessions, __pred_find_session_by_type, &msrp_type); - if (session && session->send_file){ - va_list ap; - va_start(ap, path); - session = tsk_object_ref(session); - ret = session->send_file(TMEDIA_SESSION_MSRP(session), path, &ap); - TSK_OBJECT_SAFE_FREE(session); - va_end(ap); - } - else{ - TSK_DEBUG_ERROR("No MSRP session associated to this manager or session does not support file transfer"); - } + session = (tmedia_session_msrp_t*)tsk_list_find_object_by_pred(self->sessions, __pred_find_session_by_type, &msrp_type); + if (session && session->send_file) { + va_list ap; + va_start(ap, path); + session = tsk_object_ref(session); + ret = session->send_file(TMEDIA_SESSION_MSRP(session), path, &ap); + TSK_OBJECT_SAFE_FREE(session); + va_end(ap); + } + else { + TSK_DEBUG_ERROR("No MSRP session associated to this manager or session does not support file transfer"); + } - return ret; + return ret; } int tmedia_session_mgr_send_message(tmedia_session_mgr_t* self, const void* data, tsk_size_t size, const tmedia_params_L_t *params) { - tmedia_session_msrp_t* session; - tmedia_type_t msrp_type = tmedia_msrp; - int ret = -3; + tmedia_session_msrp_t* session; + tmedia_type_t msrp_type = tmedia_msrp; + int ret = -3; - if (!self || !size || !data){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } + if (!self || !size || !data) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } - session = (tmedia_session_msrp_t*)tsk_list_find_object_by_pred(self->sessions, __pred_find_session_by_type, &msrp_type); - if (session && session->send_message){ - session = tsk_object_ref(session); - ret = session->send_message(TMEDIA_SESSION_MSRP(session), data, size, params); - TSK_OBJECT_SAFE_FREE(session); - } - else{ - TSK_DEBUG_ERROR("No MSRP session associated to this manager or session does not support file transfer"); - } + session = (tmedia_session_msrp_t*)tsk_list_find_object_by_pred(self->sessions, __pred_find_session_by_type, &msrp_type); + if (session && session->send_message) { + session = tsk_object_ref(session); + ret = session->send_message(TMEDIA_SESSION_MSRP(session), data, size, params); + TSK_OBJECT_SAFE_FREE(session); + } + else { + TSK_DEBUG_ERROR("No MSRP session associated to this manager or session does not support file transfer"); + } - return ret; + return ret; } int tmedia_session_mgr_set_msrp_cb(tmedia_session_mgr_t* self, const void* callback_data, tmedia_session_msrp_cb_f func) { - tmedia_session_msrp_t* session; - tmedia_type_t msrp_type = tmedia_msrp; + tmedia_session_msrp_t* session; + tmedia_type_t msrp_type = tmedia_msrp; - if (!self){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } + if (!self) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } - if ((session = (tmedia_session_msrp_t*)tsk_list_find_object_by_pred(self->sessions, __pred_find_session_by_type, &msrp_type))){ - session->callback.data = callback_data; - session->callback.func = func; - return 0; - } - else{ - TSK_DEBUG_ERROR("No MSRP session associated to this manager or session does not support file transfer"); - return -2; - } + if ((session = (tmedia_session_msrp_t*)tsk_list_find_object_by_pred(self->sessions, __pred_find_session_by_type, &msrp_type))) { + session->callback.data = callback_data; + session->callback.func = func; + return 0; + } + else { + TSK_DEBUG_ERROR("No MSRP session associated to this manager or session does not support file transfer"); + return -2; + } } int tmedia_session_mgr_set_onerror_cbfn(tmedia_session_mgr_t* self, const void* usrdata, tmedia_session_onerror_cb_f fun) { - tmedia_session_t* session; - tsk_list_item_t *item; + tmedia_session_t* session; + tsk_list_item_t *item; - if (!self){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } + if (!self) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } // save for sessions created later - self->onerror_cb.fun = fun; - self->onerror_cb.usrdata = usrdata; + self->onerror_cb.fun = fun; + self->onerror_cb.usrdata = usrdata; - tsk_list_lock(self->sessions); - tsk_list_foreach(item, self->sessions){ - if (!(session = item->data)){ - continue; - } - tmedia_session_set_onerror_cbfn(session, usrdata, fun); - } - tsk_list_unlock(self->sessions); + tsk_list_lock(self->sessions); + tsk_list_foreach(item, self->sessions) { + if (!(session = item->data)) { + continue; + } + tmedia_session_set_onerror_cbfn(session, usrdata, fun); + } + tsk_list_unlock(self->sessions); - return 0; + return 0; } int tmedia_session_mgr_set_rfc5168_cbfn(tmedia_session_mgr_t* self, const void* usrdata, tmedia_session_rfc5168_cb_f fun) { - tmedia_session_t* session; - tsk_list_item_t *item; + tmedia_session_t* session; + tsk_list_item_t *item; - if (!self){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } + if (!self) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } // save for functions created later - self->rfc5168_cb.fun = fun; - self->rfc5168_cb.usrdata = usrdata; + self->rfc5168_cb.fun = fun; + self->rfc5168_cb.usrdata = usrdata; - tsk_list_lock(self->sessions); - tsk_list_foreach(item, self->sessions){ - if (!(session = item->data)){ - continue; - } - tmedia_session_set_rfc5168_cbfn(session, usrdata, fun); - } - tsk_list_unlock(self->sessions); + tsk_list_lock(self->sessions); + tsk_list_foreach(item, self->sessions) { + if (!(session = item->data)) { + continue; + } + tmedia_session_set_rfc5168_cbfn(session, usrdata, fun); + } + tsk_list_unlock(self->sessions); - return 0; + return 0; } int tmedia_session_mgr_set_bfcp_cbfn(tmedia_session_mgr_t* self, const void* usrdata, tmedia_session_bfcp_cb_f fun) { - tmedia_session_t* session; - tsk_list_item_t *item; + tmedia_session_t* session; + tsk_list_item_t *item; - if (!self) { - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } + if (!self) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } - tsk_list_lock(self->sessions); - tsk_list_foreach(item, self->sessions) { - if (!(session = item->data)) { - continue; - } - tmedia_session_set_bfcp_cbfn(session, usrdata, fun); - } - tsk_list_unlock(self->sessions); + tsk_list_lock(self->sessions); + tsk_list_foreach(item, self->sessions) { + if (!(session = item->data)) { + continue; + } + tmedia_session_set_bfcp_cbfn(session, usrdata, fun); + } + tsk_list_unlock(self->sessions); - return 0; + return 0; } int tmedia_session_mgr_lo_apply_changes(tmedia_session_mgr_t* self) { - if (!self) { - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - _tmedia_session_mgr_get_lo(self, kSkipSessionLoadTrue, kForceUpdateLOTrue); - return 0; + if (!self) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + _tmedia_session_mgr_get_lo(self, kSkipSessionLoadTrue, kForceUpdateLOTrue); + return 0; } static int _tmedia_session_mgr_recv_rtcp_event(tmedia_session_mgr_t* self, tmedia_type_t media_type, tmedia_rtcp_event_type_t event_type, uint32_t ssrc_media, uint64_t session_id) { - tmedia_session_t* session; - tsk_list_item_t *item; + tmedia_session_t* session; + tsk_list_item_t *item; - if (!self){ - TSK_DEBUG_ERROR("Invlid parameter"); - return -1; - } + if (!self) { + TSK_DEBUG_ERROR("Invlid parameter"); + return -1; + } - tsk_list_lock(self->sessions); - tsk_list_foreach(item, self->sessions) { - if (!(session = item->data) || !((session->type & media_type) || (session->id == session_id))) { - continue; - } - tmedia_session_recv_rtcp_event(session, event_type, ssrc_media); - } - tsk_list_unlock(self->sessions); + tsk_list_lock(self->sessions); + tsk_list_foreach(item, self->sessions) { + if (!(session = item->data) || !((session->type & media_type) || (session->id == session_id))) { + continue; + } + tmedia_session_recv_rtcp_event(session, event_type, ssrc_media); + } + tsk_list_unlock(self->sessions); - return 0; + return 0; } /** internal function used to load sessions */ static int _tmedia_session_mgr_load_sessions(tmedia_session_mgr_t* self) { - tsk_size_t i = 0; - tmedia_session_t* session; - const tmedia_session_plugin_def_t* plugin; + tsk_size_t i = 0; + tmedia_session_t* session; + const tmedia_session_plugin_def_t* plugin; - tsk_list_lock(self->sessions); + tsk_list_lock(self->sessions); #define has_media(media_type) (tsk_list_find_object_by_pred(self->sessions, __pred_find_session_by_type, &(media_type))) - if (TSK_LIST_IS_EMPTY(self->sessions) || self->mediaType_changed) { - //static tmedia_type_t __ghost_media_type = tmedia_ghost; - //static tmedia_type_t __none_media_type = tmedia_none; - // Remove ghost sessions. Up to the - //while (tsk_list_remove_item_by_pred(self->sessions, __pred_find_session_by_type, &__ghost_media_type)) ; - //while (tsk_list_remove_item_by_pred(self->sessions, __pred_find_session_by_type, &__none_media_type)) ; - /* 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) { /* media_type *IS* enabled */ - if (has_media(plugin->type)) { - // we already have a matching media session -> enable it if not already done - _tmedia_session_mgr_enable_session_with_type(self, plugin->type); - } - else { - // we don't have a matching media session yet - if ((session = tmedia_session_create(plugin->type))) { - /* do not call "tmedia_session_mgr_set()" here to avoid applying parms before the creation of all session */ - - /* set other default values */ - - /* push session */ - tsk_list_push_back_data(self->sessions, (void**)(&session)); - } - } - } - else { /* media_type *IS NOT* enabled */ - if (has_media(plugin->type)) { - // do not remove to make sure media indexes match -> see rfc 3264 section 8 - // tsk_list_remove_item_by_pred(self->sessions, __pred_find_session_by_type, &(plugin->type)); - _tmedia_session_mgr_disable_session_with_type(self, plugin->type); - } - } - } - /* set default values and apply params*/ - tmedia_session_mgr_set(self, - TMEDIA_SESSION_SET_POBJECT(tmedia_audio, "ice-ctx", self->ice.ctx_audio), - TMEDIA_SESSION_SET_POBJECT(tmedia_video, "ice-ctx", self->ice.ctx_video), - TMEDIA_SESSION_SET_POBJECT(tmedia_bfcp_video, "ice-ctx", self->ice.ctx_bfcpvid), - - TMEDIA_SESSION_SET_STR(self->type, "local-ip", self->addr), - TMEDIA_SESSION_SET_STR(self->type, "local-ipver", self->ipv6 ? "ipv6" : "ipv4"), - TMEDIA_SESSION_SET_INT32(self->type, "bandwidth-level", self->bl), - TMEDIA_SESSION_SET_NULL()); + if (TSK_LIST_IS_EMPTY(self->sessions) || self->mediaType_changed) { + //static tmedia_type_t __ghost_media_type = tmedia_ghost; + //static tmedia_type_t __none_media_type = tmedia_none; + // Remove ghost sessions. Up to the + //while (tsk_list_remove_item_by_pred(self->sessions, __pred_find_session_by_type, &__ghost_media_type)) ; + //while (tsk_list_remove_item_by_pred(self->sessions, __pred_find_session_by_type, &__none_media_type)) ; + /* 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) { /* media_type *IS* enabled */ + if (has_media(plugin->type)) { + // we already have a matching media session -> enable it if not already done + _tmedia_session_mgr_enable_session_with_type(self, plugin->type); + } + else { + // we don't have a matching media session yet + if ((session = tmedia_session_create(plugin->type))) { + /* do not call "tmedia_session_mgr_set()" here to avoid applying parms before the creation of all session */ + + /* set other default values */ + + /* push session */ + tsk_list_push_back_data(self->sessions, (void**)(&session)); + } + } + } + else { /* media_type *IS NOT* enabled */ + if (has_media(plugin->type)) { + // do not remove to make sure media indexes match -> see rfc 3264 section 8 + // tsk_list_remove_item_by_pred(self->sessions, __pred_find_session_by_type, &(plugin->type)); + _tmedia_session_mgr_disable_session_with_type(self, plugin->type); + } + } + } + /* set default values and apply params*/ + tmedia_session_mgr_set(self, + TMEDIA_SESSION_SET_POBJECT(tmedia_audio, "ice-ctx", self->ice.ctx_audio), + TMEDIA_SESSION_SET_POBJECT(tmedia_video, "ice-ctx", self->ice.ctx_video), + TMEDIA_SESSION_SET_POBJECT(tmedia_bfcp_video, "ice-ctx", self->ice.ctx_bfcpvid), + + TMEDIA_SESSION_SET_STR(self->type, "local-ip", self->addr), + TMEDIA_SESSION_SET_STR(self->type, "local-ipver", self->ipv6 ? "ipv6" : "ipv4"), + TMEDIA_SESSION_SET_INT32(self->type, "bandwidth-level", self->bl), + TMEDIA_SESSION_SET_NULL()); // set callback functions tmedia_session_mgr_set_onerror_cbfn(self, self->onerror_cb.usrdata, self->onerror_cb.fun); tmedia_session_mgr_set_rfc5168_cbfn(self, self->rfc5168_cb.usrdata, self->rfc5168_cb.fun); - } + } #undef has_media - tsk_list_unlock(self->sessions); - return 0; + tsk_list_unlock(self->sessions); + return 0; } //!\ not thread-safe static const tmedia_session_t* _tmedia_session_mgr_find_session_at_index(const tmedia_sessions_L_t* list, tsk_size_t index) { - const tsk_list_item_t *item; - tsk_size_t u = 0; - tsk_list_foreach(item, list) { - if (u++ == index) { - return (const tmedia_session_t*)item->data; - } - } - return tsk_null; + const tsk_list_item_t *item; + tsk_size_t u = 0; + tsk_list_foreach(item, list) { + if (u++ == index) { + return (const tmedia_session_t*)item->data; + } + } + return tsk_null; } /* internal function */ static int _tmedia_session_mgr_disable_or_enable_session_with_type(tmedia_session_mgr_t* self, tmedia_type_t media_type, tsk_bool_t enable) { - tsk_list_item_t *item; - tmedia_session_t *session; - tsk_list_lock(self->sessions); - - tsk_list_foreach(item, self->sessions) { - if ((session = (tmedia_session_t*)item->data) && session->plugin && session->plugin->type == media_type) { - if (enable) { - if (session->M.lo && !session->M.lo->port) { - TSK_OBJECT_SAFE_FREE(session->M.ro); - TSK_OBJECT_SAFE_FREE(session->M.lo); - session->prepared = tsk_false; - } - } - else { - if (session->plugin->stop) { - session->plugin->stop(session); - } - if (session->M.lo) { - session->M.lo->port = 0; - } - session->prepared = tsk_false; - } - } - } - - tsk_list_unlock(self->sessions); - return 0; + tsk_list_item_t *item; + tmedia_session_t *session; + tsk_list_lock(self->sessions); + + tsk_list_foreach(item, self->sessions) { + if ((session = (tmedia_session_t*)item->data) && session->plugin && session->plugin->type == media_type) { + if (enable) { + if (session->M.lo && !session->M.lo->port) { + TSK_OBJECT_SAFE_FREE(session->M.ro); + TSK_OBJECT_SAFE_FREE(session->M.lo); + session->prepared = tsk_false; + } + } + else { + if (session->plugin->stop) { + session->plugin->stop(session); + } + if (session->M.lo) { + session->M.lo->port = 0; + } + session->prepared = tsk_false; + } + } + } + + tsk_list_unlock(self->sessions); + return 0; } /* internal function */ static int _tmedia_session_mgr_clear_sessions(tmedia_session_mgr_t* self) { - if (self && self->sessions){ - tsk_list_clear_items(self->sessions); - } - return 0; + if (self && self->sessions) { + tsk_list_clear_items(self->sessions); + } + return 0; } /* internal function */ // force_update_lo: means use same sdp version number but update fields static const tsdp_message_t* _tmedia_session_mgr_get_lo(tmedia_session_mgr_t* self, tsk_bool_t skip_session_load, tsk_bool_t force_update_lo) { - const tsk_list_item_t* item; - const tmedia_session_t* ms; - const tsdp_header_M_t* m; - const tsdp_message_t* ret = tsk_null; - uint32_t new_ver_num; - tsk_bool_t inc_ver = tsk_false; - - if (!self){ - TSK_DEBUG_ERROR("Invalid parameter"); - return tsk_null; - } - - tsk_safeobj_lock(self); - - /* prepare the session manager if not already done (create all sessions) */ - if (TSK_LIST_IS_EMPTY(self->sessions)){ - if (_tmedia_session_mgr_load_sessions(self)){ - TSK_DEBUG_ERROR("Failed to prepare the session manager"); - goto bail; - } - } - - /* creates local sdp if not already done or update it's value (because of set_ro())*/ - if ((self->ro_changed || self->state_changed || self->mediaType_changed) && self->sdp.lo) { - // delete current lo - TSK_OBJECT_SAFE_FREE(self->sdp.lo); - if (self->mediaType_changed && !skip_session_load) { - // reload session with new medias and keep the old one - _tmedia_session_mgr_load_sessions(self); - } - self->ro_changed = tsk_false; - self->ro_provisional = tsk_false; - self->state_changed = tsk_false; - self->mediaType_changed = tsk_false; - } - if (force_update_lo && self->sdp.lo) { - const tsdp_header_O_t* O; - - if ((O = (const tsdp_header_O_t*)tsdp_message_get_header(self->sdp.lo, tsdp_htype_O))) { - tsk_list_item_t *item; - tmedia_session_t *session; - - new_ver_num = O->sess_version; - tsk_list_lock(self->sessions); - tsk_list_foreach(item, self->sessions) { - if ((session = (tmedia_session_t*)item->data)) { - TSK_OBJECT_SAFE_FREE(session->M.lo); - } - } - tsk_list_unlock(self->sessions); - TSK_OBJECT_SAFE_FREE(self->sdp.lo); - } - else { - new_ver_num = (self->sdp.lo_ver + 1); - inc_ver = tsk_true; - } - } - else { - new_ver_num = (self->sdp.lo_ver + 1); - inc_ver = tsk_true; - } - - if (self->sdp.lo) { - ret = self->sdp.lo; - goto bail; - } - else { - if ((self->sdp.lo = tsdp_message_create_empty(self->public_addr ? self->public_addr : self->addr, self->ipv6, new_ver_num))) { - /* Set connection "c=" */ - tsdp_message_add_headers(self->sdp.lo, - TSDP_HEADER_C_VA_ARGS("IN", self->ipv6 ? "IP6" : "IP4", self->public_addr ? self->public_addr : self->addr), - tsk_null); - if (inc_ver) { - ++self->sdp.lo_ver; - } - } - else { - TSK_DEBUG_ERROR("Failed to create empty SDP message"); - goto bail; - } - } - - /* pass complete local sdp to the sessions to allow them to use session-level attributes */ - tmedia_session_mgr_set(self, - TMEDIA_SESSION_SET_POBJECT(self->type, "local-sdp-message", self->sdp.lo), - TMEDIA_SESSION_SET_NULL()); - - /* gets each "m=" line from the sessions and add them to the local sdp */ - tsk_list_foreach(item, self->sessions){ - if (!(ms = item->data) || !ms->plugin){ - TSK_DEBUG_ERROR("Invalid session"); - continue; - } - if ((self->type & ms->plugin->type) || ms->plugin->type == tmedia_ghost) { - /* prepare the media session */ - if (!ms->prepared && (_tmedia_session_prepare(TMEDIA_SESSION(ms)))){ - TSK_DEBUG_ERROR("Failed to prepare session"); /* should never happen */ - continue; - } - - /* Add QoS lines to our local media */ - if ((self->qos.type != tmedia_qos_stype_none) && !TMEDIA_SESSION(ms)->qos){ - TMEDIA_SESSION(ms)->qos = tmedia_qos_tline_create(self->qos.type, self->qos.strength); - } - - /* add "m=" line from the session to the local sdp */ - if ((m = tmedia_session_get_lo(TMEDIA_SESSION(ms)))) { - tsdp_message_add_header(self->sdp.lo, TSDP_HEADER(m)); - } - else { - TSK_DEBUG_ERROR("Failed to get m= line for [%s] media", ms->plugin->media); - } - } - else if (ms->M.lo) { - // media not enabled -> add sdp with port zero - tsdp_message_add_header(self->sdp.lo, TSDP_HEADER(ms->M.lo)); - } - } - - self->type = self->sdp.lo ? tmedia_type_from_sdp(self->sdp.lo) : tmedia_none; - ret = self->sdp.lo; + const tsk_list_item_t* item; + const tmedia_session_t* ms; + const tsdp_header_M_t* m; + const tsdp_message_t* ret = tsk_null; + uint32_t new_ver_num; + tsk_bool_t inc_ver = tsk_false; + + if (!self) { + TSK_DEBUG_ERROR("Invalid parameter"); + return tsk_null; + } + + tsk_safeobj_lock(self); + + /* prepare the session manager if not already done (create all sessions) */ + if (TSK_LIST_IS_EMPTY(self->sessions)) { + if (_tmedia_session_mgr_load_sessions(self)) { + TSK_DEBUG_ERROR("Failed to prepare the session manager"); + goto bail; + } + } + + /* creates local sdp if not already done or update it's value (because of set_ro())*/ + if ((self->ro_changed || self->state_changed || self->mediaType_changed) && self->sdp.lo) { + // delete current lo + TSK_OBJECT_SAFE_FREE(self->sdp.lo); + if (self->mediaType_changed && !skip_session_load) { + // reload session with new medias and keep the old one + _tmedia_session_mgr_load_sessions(self); + } + self->ro_changed = tsk_false; + self->ro_provisional = tsk_false; + self->state_changed = tsk_false; + self->mediaType_changed = tsk_false; + } + if (force_update_lo && self->sdp.lo) { + const tsdp_header_O_t* O; + + if ((O = (const tsdp_header_O_t*)tsdp_message_get_header(self->sdp.lo, tsdp_htype_O))) { + tsk_list_item_t *item; + tmedia_session_t *session; + + new_ver_num = O->sess_version; + tsk_list_lock(self->sessions); + tsk_list_foreach(item, self->sessions) { + if ((session = (tmedia_session_t*)item->data)) { + TSK_OBJECT_SAFE_FREE(session->M.lo); + } + } + tsk_list_unlock(self->sessions); + TSK_OBJECT_SAFE_FREE(self->sdp.lo); + } + else { + new_ver_num = (self->sdp.lo_ver + 1); + inc_ver = tsk_true; + } + } + else { + new_ver_num = (self->sdp.lo_ver + 1); + inc_ver = tsk_true; + } + + if (self->sdp.lo) { + ret = self->sdp.lo; + goto bail; + } + else { + if ((self->sdp.lo = tsdp_message_create_empty(self->public_addr ? self->public_addr : self->addr, self->ipv6, new_ver_num))) { + /* Set connection "c=" */ + tsdp_message_add_headers(self->sdp.lo, + TSDP_HEADER_C_VA_ARGS("IN", self->ipv6 ? "IP6" : "IP4", self->public_addr ? self->public_addr : self->addr), + tsk_null); + if (inc_ver) { + ++self->sdp.lo_ver; + } + } + else { + TSK_DEBUG_ERROR("Failed to create empty SDP message"); + goto bail; + } + } + + /* pass complete local sdp to the sessions to allow them to use session-level attributes */ + tmedia_session_mgr_set(self, + TMEDIA_SESSION_SET_POBJECT(self->type, "local-sdp-message", self->sdp.lo), + TMEDIA_SESSION_SET_NULL()); + + /* gets each "m=" line from the sessions and add them to the local sdp */ + tsk_list_foreach(item, self->sessions) { + if (!(ms = item->data) || !ms->plugin) { + TSK_DEBUG_ERROR("Invalid session"); + continue; + } + if ((self->type & ms->plugin->type) || ms->plugin->type == tmedia_ghost) { + /* prepare the media session */ + if (!ms->prepared && (_tmedia_session_prepare(TMEDIA_SESSION(ms)))) { + TSK_DEBUG_ERROR("Failed to prepare session"); /* should never happen */ + continue; + } + + /* Add QoS lines to our local media */ + if ((self->qos.type != tmedia_qos_stype_none) && !TMEDIA_SESSION(ms)->qos) { + TMEDIA_SESSION(ms)->qos = tmedia_qos_tline_create(self->qos.type, self->qos.strength); + } + + /* add "m=" line from the session to the local sdp */ + if ((m = tmedia_session_get_lo(TMEDIA_SESSION(ms)))) { + tsdp_message_add_header(self->sdp.lo, TSDP_HEADER(m)); + } + else { + TSK_DEBUG_ERROR("Failed to get m= line for [%s] media", ms->plugin->media); + } + } + else if (ms->M.lo) { + // media not enabled -> add sdp with port zero + tsdp_message_add_header(self->sdp.lo, TSDP_HEADER(ms->M.lo)); + } + } + + self->type = self->sdp.lo ? tmedia_type_from_sdp(self->sdp.lo) : tmedia_none; + ret = self->sdp.lo; bail: - tsk_safeobj_unlock(self); + tsk_safeobj_unlock(self); - return ret; + return ret; } static int _tmedia_session_mgr_start(tmedia_session_mgr_t* self, int session_index) { - int ret = 0, index = 0; - tsk_list_item_t* item; - tmedia_session_t* session; - - if (!self) { - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - - tsk_safeobj_lock(self); - - tsk_list_foreach(item, self->sessions) { - if (session_index == kSessionIndexAll || index++ == session_index) { - if (!(session = item->data) || !session->plugin || !session->plugin->start) { - TSK_DEBUG_ERROR("Invalid session"); - ret = -2; - goto bail; - } - if (!session->M.lo || !session->M.lo->port) { - continue; - } - if ((ret = session->plugin->start(session))) { - TSK_DEBUG_ERROR("Failed to start %s session", session->plugin->media); - continue; - } - } - } - if (session_index == kSessionIndexAll) { - self->started = tsk_true; - } + int ret = 0, index = 0; + tsk_list_item_t* item; + tmedia_session_t* session; + + if (!self) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + + tsk_safeobj_lock(self); + + tsk_list_foreach(item, self->sessions) { + if (session_index == kSessionIndexAll || index++ == session_index) { + if (!(session = item->data) || !session->plugin || !session->plugin->start) { + TSK_DEBUG_ERROR("Invalid session"); + ret = -2; + goto bail; + } + if (!session->M.lo || !session->M.lo->port) { + continue; + } + if ((ret = session->plugin->start(session))) { + TSK_DEBUG_ERROR("Failed to start %s session", session->plugin->media); + continue; + } + } + } + if (session_index == kSessionIndexAll) { + self->started = tsk_true; + } bail: - tsk_safeobj_unlock(self); - return ret; + tsk_safeobj_unlock(self); + return ret; } static int _tmedia_session_mgr_stop(tmedia_session_mgr_t* self, int session_index) { - int ret = 0, index = 0; - tsk_list_item_t* item; - tmedia_session_t* session; - - TSK_DEBUG_INFO("tmedia_session_mgr_stop()"); - - if (!self) { - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - tsk_safeobj_lock(self); - - tsk_list_foreach(item, self->sessions) { - if (session_index == kSessionIndexAll || index++ == session_index) { - if (!(session = item->data) || !session->plugin || !session->plugin->stop) { - TSK_DEBUG_ERROR("Invalid session"); - ret = -2; - goto bail; - } - if ((ret = session->plugin->stop(session))) { - TSK_DEBUG_ERROR("Failed to stop session"); - continue; - } - session->prepared = tsk_false; - } - } - if (session_index == kSessionIndexAll) { - self->started = tsk_false; - } + int ret = 0, index = 0; + tsk_list_item_t* item; + tmedia_session_t* session; + + TSK_DEBUG_INFO("tmedia_session_mgr_stop()"); + + if (!self) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + tsk_safeobj_lock(self); + + tsk_list_foreach(item, self->sessions) { + if (session_index == kSessionIndexAll || index++ == session_index) { + if (!(session = item->data) || !session->plugin || !session->plugin->stop) { + TSK_DEBUG_ERROR("Invalid session"); + ret = -2; + goto bail; + } + if ((ret = session->plugin->stop(session))) { + TSK_DEBUG_ERROR("Failed to stop session"); + continue; + } + session->prepared = tsk_false; + } + } + if (session_index == kSessionIndexAll) { + self->started = tsk_false; + } bail: - tsk_safeobj_unlock(self); - return ret; + tsk_safeobj_unlock(self); + return ret; } /* internal function */ static int _tmedia_session_mgr_apply_params(tmedia_session_mgr_t* self) { - tsk_list_item_t *it1, *it2; - tmedia_param_t* param; - tmedia_session_t* session; + tsk_list_item_t *it1, *it2; + tmedia_param_t* param; + tmedia_session_t* session; - if (!self){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } + if (!self) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } - /* If no parameters ==> do nothing (not error) */ - if (TSK_LIST_IS_EMPTY(self->params)){ - return 0; - } + /* If no parameters ==> do nothing (not error) */ + if (TSK_LIST_IS_EMPTY(self->params)) { + return 0; + } - tsk_list_lock(self->params); + tsk_list_lock(self->params); - tsk_list_foreach(it1, self->params){ - if (!(param = it1->data)){ - continue; - } + tsk_list_foreach(it1, self->params) { + if (!(param = it1->data)) { + continue; + } - /* For us */ - if (param->plugin_type == tmedia_ppt_manager){ - continue; - } + /* For us */ + if (param->plugin_type == tmedia_ppt_manager) { + continue; + } - /* For the session (or consumer or producer or codec) */ - tsk_list_foreach(it2, self->sessions){ - if (!(session = it2->data) || !session->plugin){ - continue; - } - if (session->plugin->set && (session->type & param->media_type) == session->type){ - session->plugin->set(session, param); - } - } - } + /* For the session (or consumer or producer or codec) */ + tsk_list_foreach(it2, self->sessions) { + if (!(session = it2->data) || !session->plugin) { + continue; + } + if (session->plugin->set && (session->type & param->media_type) == session->type) { + session->plugin->set(session, param); + } + } + } - /* Clean up params */ - tsk_list_clear_items(self->params); + /* Clean up params */ + tsk_list_clear_items(self->params); - tsk_list_unlock(self->params); + tsk_list_unlock(self->params); - return 0; + return 0; } //================================================================================================= @@ -2471,54 +2539,53 @@ static int _tmedia_session_mgr_apply_params(tmedia_session_mgr_t* self) // static tsk_object_t* tmedia_session_mgr_ctor(tsk_object_t * self, va_list * app) { - tmedia_session_mgr_t *mgr = self; - if (mgr){ - mgr->sessions = tsk_list_create(); + tmedia_session_mgr_t *mgr = self; + if (mgr) { + mgr->sessions = tsk_list_create(); - mgr->sdp.lo_ver = TSDP_HEADER_O_SESS_VERSION_DEFAULT; - mgr->sdp.ro_ver = -1; + mgr->sdp.lo_ver = TSDP_HEADER_O_SESS_VERSION_DEFAULT; + mgr->sdp.ro_ver = -1; - mgr->qos.type = tmedia_qos_stype_none; - mgr->qos.strength = tmedia_qos_strength_optional; - mgr->bl = tmedia_defaults_get_bl(); + mgr->qos.type = tmedia_qos_stype_none; + mgr->qos.strength = tmedia_qos_strength_optional; + mgr->bl = tmedia_defaults_get_bl(); - tsk_safeobj_init(mgr); - } - return self; + tsk_safeobj_init(mgr); + } + return self; } static tsk_object_t* tmedia_session_mgr_dtor(tsk_object_t * self) { - tmedia_session_mgr_t *mgr = self; - if (mgr){ - TSK_OBJECT_SAFE_FREE(mgr->sessions); + tmedia_session_mgr_t *mgr = self; + if (mgr) { + TSK_OBJECT_SAFE_FREE(mgr->sessions); - TSK_OBJECT_SAFE_FREE(mgr->sdp.lo); - TSK_OBJECT_SAFE_FREE(mgr->sdp.ro); + TSK_OBJECT_SAFE_FREE(mgr->sdp.lo); + TSK_OBJECT_SAFE_FREE(mgr->sdp.ro); - TSK_OBJECT_SAFE_FREE(mgr->params); + TSK_OBJECT_SAFE_FREE(mgr->params); - TSK_OBJECT_SAFE_FREE(mgr->natt_ctx); - TSK_FREE(mgr->public_addr); + TSK_OBJECT_SAFE_FREE(mgr->natt_ctx); + TSK_FREE(mgr->public_addr); - TSK_OBJECT_SAFE_FREE(mgr->ice.ctx_audio); - TSK_OBJECT_SAFE_FREE(mgr->ice.ctx_video); - TSK_OBJECT_SAFE_FREE(mgr->ice.ctx_bfcpvid); + TSK_OBJECT_SAFE_FREE(mgr->ice.ctx_audio); + TSK_OBJECT_SAFE_FREE(mgr->ice.ctx_video); + TSK_OBJECT_SAFE_FREE(mgr->ice.ctx_bfcpvid); - TSK_FREE(mgr->addr); + TSK_FREE(mgr->addr); - tsk_safeobj_deinit(mgr); - } + tsk_safeobj_deinit(mgr); + } - return self; + return self; } -static const tsk_object_def_t tmedia_session_mgr_def_s = -{ - sizeof(tmedia_session_mgr_t), - tmedia_session_mgr_ctor, - tmedia_session_mgr_dtor, - tsk_null, +static const tsk_object_def_t tmedia_session_mgr_def_s = { + sizeof(tmedia_session_mgr_t), + tmedia_session_mgr_ctor, + tmedia_session_mgr_dtor, + tsk_null, }; const tsk_object_def_t *tmedia_session_mgr_def_t = &tmedia_session_mgr_def_s; diff --git a/tinyMEDIA/src/tmedia_session_dummy.c b/tinyMEDIA/src/tmedia_session_dummy.c index dfd141e..c65e512 100755 --- a/tinyMEDIA/src/tmedia_session_dummy.c +++ b/tinyMEDIA/src/tmedia_session_dummy.c @@ -2,19 +2,19 @@ * Copyright (C) 2010-2011 Mamadou Diop. * * Contact: Mamadou Diop <diopmamadou(at)doubango[dot]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. * @@ -36,286 +36,286 @@ int tmedia_session_daudio_set(tmedia_session_t* self, const tmedia_param_t* param) { - tmedia_session_daudio_t* daudio; + tmedia_session_daudio_t* daudio; - daudio = (tmedia_session_daudio_t*)self; + daudio = (tmedia_session_daudio_t*)self; - return 0; + return 0; } int tmedia_session_daudio_get(tmedia_session_t* self, tmedia_param_t* param) { - return 0; + return 0; } int tmedia_session_daudio_prepare(tmedia_session_t* self) { - tmedia_session_daudio_t* daudio; + tmedia_session_daudio_t* daudio; - daudio = (tmedia_session_daudio_t*)self; + daudio = (tmedia_session_daudio_t*)self; - /* set local port */ - daudio->local_port = rand() ^ rand(); + /* set local port */ + daudio->local_port = rand() ^ rand(); - return 0; + return 0; } int tmedia_session_daudio_start(tmedia_session_t* self) { - return 0; + return 0; } int tmedia_session_daudio_stop(tmedia_session_t* self) { - tmedia_session_daudio_t* daudio; + tmedia_session_daudio_t* daudio; - daudio = (tmedia_session_daudio_t*)self; + daudio = (tmedia_session_daudio_t*)self; - /* very important */ - daudio->local_port = 0; + /* very important */ + daudio->local_port = 0; - return 0; + return 0; } int tmedia_session_daudio_send_dtmf(tmedia_session_t* self, uint8_t event) { - return 0; + return 0; } int tmedia_session_daudio_pause(tmedia_session_t* self) { - return 0; + return 0; } const tsdp_header_M_t* tmedia_session_daudio_get_lo(tmedia_session_t* self) { - tmedia_session_daudio_t* daudio; - tsk_bool_t changed = tsk_false; - - if(!self || !self->plugin){ - TSK_DEBUG_ERROR("Invalid parameter"); - return tsk_null; - } - - daudio = (tmedia_session_daudio_t*)self; - - if(self->ro_changed && self->M.lo){ - /* Codecs */ - tsdp_header_A_removeAll_by_field(self->M.lo->Attributes, "fmtp"); - tsdp_header_A_removeAll_by_field(self->M.lo->Attributes, "rtpmap"); - tsk_list_clear_items(self->M.lo->FMTs); - - /* QoS */ - tsdp_header_A_removeAll_by_field(self->M.lo->Attributes, "curr"); - tsdp_header_A_removeAll_by_field(self->M.lo->Attributes, "des"); - tsdp_header_A_removeAll_by_field(self->M.lo->Attributes, "conf"); - } - - changed = (self->ro_changed || !self->M.lo); - - if(!self->M.lo && !(self->M.lo = tsdp_header_M_create(self->plugin->media, daudio->local_port, "RTP/AVP"))){ - TSK_DEBUG_ERROR("Failed to create lo"); - return tsk_null; - } - - if(changed){ - /* from codecs to sdp */ - tmedia_codec_to_sdp(self->neg_codecs ? self->neg_codecs : self->codecs, self->M.lo); - /* QoS */ - if(self->qos){ - tmedia_qos_tline_t* ro_tline; - if(self->M.ro && (ro_tline = tmedia_qos_tline_from_sdp(self->M.ro))){ - tmedia_qos_tline_set_ro(self->qos, ro_tline); - TSK_OBJECT_SAFE_FREE(ro_tline); - } - tmedia_qos_tline_to_sdp(self->qos, self->M.lo); - } - } - - - return self->M.lo; + tmedia_session_daudio_t* daudio; + tsk_bool_t changed = tsk_false; + + if(!self || !self->plugin) { + TSK_DEBUG_ERROR("Invalid parameter"); + return tsk_null; + } + + daudio = (tmedia_session_daudio_t*)self; + + if(self->ro_changed && self->M.lo) { + /* Codecs */ + tsdp_header_A_removeAll_by_field(self->M.lo->Attributes, "fmtp"); + tsdp_header_A_removeAll_by_field(self->M.lo->Attributes, "rtpmap"); + tsk_list_clear_items(self->M.lo->FMTs); + + /* QoS */ + tsdp_header_A_removeAll_by_field(self->M.lo->Attributes, "curr"); + tsdp_header_A_removeAll_by_field(self->M.lo->Attributes, "des"); + tsdp_header_A_removeAll_by_field(self->M.lo->Attributes, "conf"); + } + + changed = (self->ro_changed || !self->M.lo); + + if(!self->M.lo && !(self->M.lo = tsdp_header_M_create(self->plugin->media, daudio->local_port, "RTP/AVP"))) { + TSK_DEBUG_ERROR("Failed to create lo"); + return tsk_null; + } + + if(changed) { + /* from codecs to sdp */ + tmedia_codec_to_sdp(self->neg_codecs ? self->neg_codecs : self->codecs, self->M.lo); + /* QoS */ + if(self->qos) { + tmedia_qos_tline_t* ro_tline; + if(self->M.ro && (ro_tline = tmedia_qos_tline_from_sdp(self->M.ro))) { + tmedia_qos_tline_set_ro(self->qos, ro_tline); + TSK_OBJECT_SAFE_FREE(ro_tline); + } + tmedia_qos_tline_to_sdp(self->qos, self->M.lo); + } + } + + + return self->M.lo; } int tmedia_session_daudio_set_ro(tmedia_session_t* self, const tsdp_header_M_t* m) { - tmedia_codecs_L_t* neg_codecs; - - if((neg_codecs = tmedia_session_match_codec(self, m))){ - /* update negociated codecs */ - TSK_OBJECT_SAFE_FREE(self->neg_codecs); - self->neg_codecs = neg_codecs; - /* update remote offer */ - TSK_OBJECT_SAFE_FREE(self->M.ro); - self->M.ro = tsk_object_ref((void*)m); - - return 0; - } - return -1; + tmedia_codecs_L_t* neg_codecs; + + if((neg_codecs = tmedia_session_match_codec(self, m))) { + /* update negociated codecs */ + TSK_OBJECT_SAFE_FREE(self->neg_codecs); + self->neg_codecs = neg_codecs; + /* update remote offer */ + TSK_OBJECT_SAFE_FREE(self->M.ro); + self->M.ro = tsk_object_ref((void*)m); + + return 0; + } + return -1; } /* ============ Video Session ================= */ int tmedia_session_dvideo_set(tmedia_session_t* self, const tmedia_param_t* param) { - tmedia_session_dvideo_t* dvideo; + tmedia_session_dvideo_t* dvideo; - dvideo = (tmedia_session_dvideo_t*)self; + dvideo = (tmedia_session_dvideo_t*)self; - return 0; + return 0; } int tmedia_session_dvideo_get(tmedia_session_t* self, tmedia_param_t* param) { - return 0; + return 0; } int tmedia_session_dvideo_prepare(tmedia_session_t* self) { - tmedia_session_dvideo_t* dvideo; + tmedia_session_dvideo_t* dvideo; - dvideo = (tmedia_session_dvideo_t*)self; + dvideo = (tmedia_session_dvideo_t*)self; - /* set local port */ - dvideo->local_port = rand() ^ rand(); + /* set local port */ + dvideo->local_port = rand() ^ rand(); - return 0; + return 0; } int tmedia_session_dvideo_start(tmedia_session_t* self) { - return -1; + return -1; } int tmedia_session_dvideo_stop(tmedia_session_t* self) { - tmedia_session_dvideo_t* dvideo; + tmedia_session_dvideo_t* dvideo; - dvideo = (tmedia_session_dvideo_t*)self; + dvideo = (tmedia_session_dvideo_t*)self; - /* very important */ - dvideo->local_port = 0; + /* very important */ + dvideo->local_port = 0; - return 0; + return 0; } int tmedia_session_dvideo_pause(tmedia_session_t* self) { - return -1; + return -1; } const tsdp_header_M_t* tmedia_session_dvideo_get_lo(tmedia_session_t* self) { - tmedia_session_dvideo_t* dvideo; - tsk_bool_t changed = tsk_false; - - if(!self || !self->plugin){ - TSK_DEBUG_ERROR("Invalid parameter"); - return tsk_null; - } - - dvideo = (tmedia_session_dvideo_t*)self; - - if(self->ro_changed && self->M.lo){ - /* Codecs */ - tsdp_header_A_removeAll_by_field(self->M.lo->Attributes, "fmtp"); - tsdp_header_A_removeAll_by_field(self->M.lo->Attributes, "rtpmap"); - tsk_list_clear_items(self->M.lo->FMTs); - - /* QoS */ - tsdp_header_A_removeAll_by_field(self->M.lo->Attributes, "curr"); - tsdp_header_A_removeAll_by_field(self->M.lo->Attributes, "des"); - tsdp_header_A_removeAll_by_field(self->M.lo->Attributes, "conf"); - } - - changed = (self->ro_changed || !self->M.lo); - - if(!self->M.lo && !(self->M.lo = tsdp_header_M_create(self->plugin->media, dvideo->local_port, "RTP/AVP"))){ - TSK_DEBUG_ERROR("Failed to create lo"); - return tsk_null; - } - - if(changed){ - /* from codecs to sdp */ - tmedia_codec_to_sdp(self->neg_codecs ? self->neg_codecs : self->codecs, self->M.lo); - /* QoS */ - if(self->qos){ - tmedia_qos_tline_t* ro_tline; - if(self->M.ro && (ro_tline = tmedia_qos_tline_from_sdp(self->M.ro))){ - tmedia_qos_tline_set_ro(self->qos, ro_tline); - TSK_OBJECT_SAFE_FREE(ro_tline); - } - tmedia_qos_tline_to_sdp(self->qos, self->M.lo); - } - } - - return self->M.lo; + tmedia_session_dvideo_t* dvideo; + tsk_bool_t changed = tsk_false; + + if(!self || !self->plugin) { + TSK_DEBUG_ERROR("Invalid parameter"); + return tsk_null; + } + + dvideo = (tmedia_session_dvideo_t*)self; + + if(self->ro_changed && self->M.lo) { + /* Codecs */ + tsdp_header_A_removeAll_by_field(self->M.lo->Attributes, "fmtp"); + tsdp_header_A_removeAll_by_field(self->M.lo->Attributes, "rtpmap"); + tsk_list_clear_items(self->M.lo->FMTs); + + /* QoS */ + tsdp_header_A_removeAll_by_field(self->M.lo->Attributes, "curr"); + tsdp_header_A_removeAll_by_field(self->M.lo->Attributes, "des"); + tsdp_header_A_removeAll_by_field(self->M.lo->Attributes, "conf"); + } + + changed = (self->ro_changed || !self->M.lo); + + if(!self->M.lo && !(self->M.lo = tsdp_header_M_create(self->plugin->media, dvideo->local_port, "RTP/AVP"))) { + TSK_DEBUG_ERROR("Failed to create lo"); + return tsk_null; + } + + if(changed) { + /* from codecs to sdp */ + tmedia_codec_to_sdp(self->neg_codecs ? self->neg_codecs : self->codecs, self->M.lo); + /* QoS */ + if(self->qos) { + tmedia_qos_tline_t* ro_tline; + if(self->M.ro && (ro_tline = tmedia_qos_tline_from_sdp(self->M.ro))) { + tmedia_qos_tline_set_ro(self->qos, ro_tline); + TSK_OBJECT_SAFE_FREE(ro_tline); + } + tmedia_qos_tline_to_sdp(self->qos, self->M.lo); + } + } + + return self->M.lo; } int tmedia_session_dvideo_set_ro(tmedia_session_t* self, const tsdp_header_M_t* m) { - tmedia_codecs_L_t* neg_codecs; - - if((neg_codecs = tmedia_session_match_codec(self, m))){ - /* update negociated codecs */ - TSK_OBJECT_SAFE_FREE(self->neg_codecs); - self->neg_codecs = neg_codecs; - /* update remote offer */ - TSK_OBJECT_SAFE_FREE(self->M.ro); - self->M.ro = tsk_object_ref((void*)m); - - return 0; - } - return -1; + tmedia_codecs_L_t* neg_codecs; + + if((neg_codecs = tmedia_session_match_codec(self, m))) { + /* update negociated codecs */ + TSK_OBJECT_SAFE_FREE(self->neg_codecs); + self->neg_codecs = neg_codecs; + /* update remote offer */ + TSK_OBJECT_SAFE_FREE(self->M.ro); + self->M.ro = tsk_object_ref((void*)m); + + return 0; + } + return -1; } /* ============ Msrp Session ================= */ int tmedia_session_dmsrp_set(tmedia_session_t* self, const tmedia_param_t* param) { - tmedia_session_dmsrp_t* dmsrp; + tmedia_session_dmsrp_t* dmsrp; - dmsrp = (tmedia_session_dmsrp_t*)self; + dmsrp = (tmedia_session_dmsrp_t*)self; - return 0; + return 0; } int tmedia_session_dmsrp_get(tmedia_session_t* self, tmedia_param_t* param) { - return 0; + return 0; } int tmedia_session_dmsrp_prepare(tmedia_session_t* self) { - return 0; + return 0; } int tmedia_session_dmsrp_start(tmedia_session_t* self) { - return 0; + return 0; } int tmedia_session_dmsrp_stop(tmedia_session_t* self) { - return 0; + return 0; } int tmedia_session_dmsrp_pause(tmedia_session_t* self) { - return 0; + return 0; } const tsdp_header_M_t* tmedia_session_dmsrp_get_lo(tmedia_session_t* self) { - if(self->ro_changed){ - TSK_OBJECT_SAFE_FREE(self->M.lo); - } + if(self->ro_changed) { + TSK_OBJECT_SAFE_FREE(self->M.lo); + } - return tsk_null; + return tsk_null; } int tmedia_session_dmsrp_set_ro(tmedia_session_t* self, const tsdp_header_M_t* m) { - return -1; + return -1; } //================================================================================================= @@ -324,53 +324,51 @@ int tmedia_session_dmsrp_set_ro(tmedia_session_t* self, const tsdp_header_M_t* m /* constructor */ static tsk_object_t* tmedia_session_daudio_ctor(tsk_object_t * self, va_list * app) { - tmedia_session_daudio_t *session = self; - if(session){ - /* init base: called by tmedia_session_create() */ - /* init self */ - } - return self; + tmedia_session_daudio_t *session = self; + if(session) { + /* init base: called by tmedia_session_create() */ + /* init self */ + } + return self; } /* destructor */ 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 */ - } - - return self; +{ + tmedia_session_daudio_t *session = self; + if(session) { + /* deinit base */ + tmedia_session_deinit(self); + /* deinit self */ + } + + return self; } /* object definition */ -static const tsk_object_def_t tmedia_session_daudio_def_s = -{ - sizeof(tmedia_session_daudio_t), - tmedia_session_daudio_ctor, - tmedia_session_daudio_dtor, - tmedia_session_cmp, +static const tsk_object_def_t tmedia_session_daudio_def_s = { + sizeof(tmedia_session_daudio_t), + tmedia_session_daudio_ctor, + tmedia_session_daudio_dtor, + tmedia_session_cmp, }; /* plugin definition*/ -static const tmedia_session_plugin_def_t tmedia_session_daudio_plugin_def_s = -{ - &tmedia_session_daudio_def_s, - - tmedia_audio, - "audio", - - tmedia_session_daudio_set, - tmedia_session_daudio_get, - tmedia_session_daudio_prepare, - tmedia_session_daudio_start, - tmedia_session_daudio_pause, - tmedia_session_daudio_stop, - - /* Audio part */ - { tsk_null }, - - tmedia_session_daudio_get_lo, - tmedia_session_daudio_set_ro +static const tmedia_session_plugin_def_t tmedia_session_daudio_plugin_def_s = { + &tmedia_session_daudio_def_s, + + tmedia_audio, + "audio", + + tmedia_session_daudio_set, + tmedia_session_daudio_get, + tmedia_session_daudio_prepare, + tmedia_session_daudio_start, + tmedia_session_daudio_pause, + tmedia_session_daudio_stop, + + /* Audio part */ + { tsk_null }, + + tmedia_session_daudio_get_lo, + tmedia_session_daudio_set_ro }; const tmedia_session_plugin_def_t *tmedia_session_daudio_plugin_def_t = &tmedia_session_daudio_plugin_def_s; @@ -381,53 +379,51 @@ const tmedia_session_plugin_def_t *tmedia_session_daudio_plugin_def_t = &tmedia_ /* constructor */ static tsk_object_t* tmedia_session_dvideo_ctor(tsk_object_t * self, va_list * app) { - tmedia_session_dvideo_t *session = self; - if(session){ - /* init base: called by tmedia_session_create() */ - /* init self */ - } - return self; + tmedia_session_dvideo_t *session = self; + if(session) { + /* init base: called by tmedia_session_create() */ + /* init self */ + } + return self; } /* destructor */ 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 */ - } - - return self; +{ + tmedia_session_dvideo_t *session = self; + if(session) { + /* deinit base */ + tmedia_session_deinit(self); + /* deinit self */ + } + + return self; } /* object definition */ -static const tsk_object_def_t tmedia_session_dvideo_def_s = -{ - sizeof(tmedia_session_dvideo_t), - tmedia_session_dvideo_ctor, - tmedia_session_dvideo_dtor, - tmedia_session_cmp, +static const tsk_object_def_t tmedia_session_dvideo_def_s = { + sizeof(tmedia_session_dvideo_t), + tmedia_session_dvideo_ctor, + tmedia_session_dvideo_dtor, + tmedia_session_cmp, }; /* plugin definition*/ -static const tmedia_session_plugin_def_t tmedia_session_dvideo_plugin_def_s = -{ - &tmedia_session_dvideo_def_s, - - tmedia_video, - "video", - - tmedia_session_dvideo_set, - tmedia_session_dvideo_get, - tmedia_session_dvideo_prepare, - tmedia_session_dvideo_start, - tmedia_session_dvideo_pause, - tmedia_session_dvideo_stop, - - /* Audio part */ - { tsk_null }, - - tmedia_session_dvideo_get_lo, - tmedia_session_dvideo_set_ro +static const tmedia_session_plugin_def_t tmedia_session_dvideo_plugin_def_s = { + &tmedia_session_dvideo_def_s, + + tmedia_video, + "video", + + tmedia_session_dvideo_set, + tmedia_session_dvideo_get, + tmedia_session_dvideo_prepare, + tmedia_session_dvideo_start, + tmedia_session_dvideo_pause, + tmedia_session_dvideo_stop, + + /* Audio part */ + { tsk_null }, + + tmedia_session_dvideo_get_lo, + tmedia_session_dvideo_set_ro }; const tmedia_session_plugin_def_t *tmedia_session_dvideo_plugin_def_t = &tmedia_session_dvideo_plugin_def_s; @@ -438,53 +434,51 @@ const tmedia_session_plugin_def_t *tmedia_session_dvideo_plugin_def_t = &tmedia_ /* constructor */ static tsk_object_t* tmedia_session_dmsrp_ctor(tsk_object_t * self, va_list * app) { - tmedia_session_dmsrp_t *session = self; - if(session){ - /* init base: called by tmedia_session_create() */ - /* init self */ - } - return self; + tmedia_session_dmsrp_t *session = self; + if(session) { + /* init base: called by tmedia_session_create() */ + /* init self */ + } + return self; } /* destructor */ 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 */ +{ + tmedia_session_dmsrp_t *session = self; + if(session) { + /* deinit base */ + tmedia_session_deinit(self); + /* deinit self */ - } + } - return self; + return self; } /* object definition */ -static const tsk_object_def_t tmedia_session_dmsrp_def_s = -{ - sizeof(tmedia_session_dmsrp_t), - tmedia_session_dmsrp_ctor, - tmedia_session_dmsrp_dtor, - tmedia_session_cmp, +static const tsk_object_def_t tmedia_session_dmsrp_def_s = { + sizeof(tmedia_session_dmsrp_t), + tmedia_session_dmsrp_ctor, + tmedia_session_dmsrp_dtor, + tmedia_session_cmp, }; /* plugin definition*/ -static const tmedia_session_plugin_def_t tmedia_session_dmsrp_plugin_def_s = -{ - &tmedia_session_dmsrp_def_s, - - tmedia_msrp, - "message", - - tmedia_session_dmsrp_set, - tmedia_session_dmsrp_get, - tmedia_session_dmsrp_prepare, - tmedia_session_dmsrp_start, - tmedia_session_dmsrp_pause, - tmedia_session_dmsrp_stop, - - /* Audio part */ - { tsk_null }, - - tmedia_session_dmsrp_get_lo, - tmedia_session_dmsrp_set_ro +static const tmedia_session_plugin_def_t tmedia_session_dmsrp_plugin_def_s = { + &tmedia_session_dmsrp_def_s, + + tmedia_msrp, + "message", + + tmedia_session_dmsrp_set, + tmedia_session_dmsrp_get, + tmedia_session_dmsrp_prepare, + tmedia_session_dmsrp_start, + tmedia_session_dmsrp_pause, + tmedia_session_dmsrp_stop, + + /* Audio part */ + { tsk_null }, + + tmedia_session_dmsrp_get_lo, + tmedia_session_dmsrp_set_ro }; const tmedia_session_plugin_def_t *tmedia_session_dmsrp_plugin_def_t = &tmedia_session_dmsrp_plugin_def_s; diff --git a/tinyMEDIA/src/tmedia_session_ghost.c b/tinyMEDIA/src/tmedia_session_ghost.c index 7045e69..b6fb6cd 100755 --- a/tinyMEDIA/src/tmedia_session_ghost.c +++ b/tinyMEDIA/src/tmedia_session_ghost.c @@ -2,19 +2,19 @@ * Copyright (C) 2010-2011 Mamadou Diop. * * Contact: Mamadou Diop <diopmamadou(at)doubango[dot]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. * @@ -36,55 +36,55 @@ static int tmedia_session_ghost_prepare(tmedia_session_t* self) { - return 0; + return 0; } static int tmedia_session_ghost_start(tmedia_session_t* self) { - return 0; + return 0; } static int tmedia_session_ghost_stop(tmedia_session_t* self) { - TSK_DEBUG_INFO("tmedia_session_ghost_stop"); - return 0; + TSK_DEBUG_INFO("tmedia_session_ghost_stop"); + return 0; } static int tmedia_session_ghost_pause(tmedia_session_t* self) { - return 0; + return 0; } static const tsdp_header_M_t* tmedia_session_ghost_get_lo(tmedia_session_t* self) { - tmedia_session_ghost_t* ghost; - - ghost = (tmedia_session_ghost_t*)self; - - if(self->M.lo){ - return self->M.lo; - } - else if(!(self->M.lo = tsdp_header_M_create(ghost->media, 0, ghost->proto ? ghost->proto: "RTP/AVP"))){ - TSK_DEBUG_ERROR("Failed to create lo"); - return tsk_null; - } - - // add format - if(!tsk_strnullORempty(ghost->first_format)){ - tsk_string_t* fmt = tsk_string_create(ghost->first_format); - if(!self->M.lo->FMTs){ - self->M.lo->FMTs = tsk_list_create(); - } - tsk_list_push_back_data(self->M.lo->FMTs, (void**)&fmt); - TSK_OBJECT_SAFE_FREE(fmt); - } - - return self->M.lo; + tmedia_session_ghost_t* ghost; + + ghost = (tmedia_session_ghost_t*)self; + + if(self->M.lo) { + return self->M.lo; + } + else if(!(self->M.lo = tsdp_header_M_create(ghost->media, 0, ghost->proto ? ghost->proto: "RTP/AVP"))) { + TSK_DEBUG_ERROR("Failed to create lo"); + return tsk_null; + } + + // add format + if(!tsk_strnullORempty(ghost->first_format)) { + tsk_string_t* fmt = tsk_string_create(ghost->first_format); + if(!self->M.lo->FMTs) { + self->M.lo->FMTs = tsk_list_create(); + } + tsk_list_push_back_data(self->M.lo->FMTs, (void**)&fmt); + TSK_OBJECT_SAFE_FREE(fmt); + } + + return self->M.lo; } static int tmedia_session_ghost_set_ro(tmedia_session_t* self, const tsdp_header_M_t* m) { - return 0; + return 0; } @@ -99,56 +99,54 @@ static int tmedia_session_ghost_set_ro(tmedia_session_t* self, const tsdp_header /* 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; + 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); - TSK_FREE(session->proto); - TSK_FREE(session->first_format); - } - - return self; +{ + tmedia_session_ghost_t *session = self; + if(session) { + /* deinit base */ + tmedia_session_deinit(TMEDIA_SESSION(session)); + /* deinit self */ + TSK_FREE(session->media); + TSK_FREE(session->proto); + TSK_FREE(session->first_format); + } + + 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_session_cmp, +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_session_cmp, }; /* plugin definition*/ -static const tmedia_session_plugin_def_t tmedia_session_ghost_plugin_def_s = -{ - &tmedia_session_ghost_def_s, - - tmedia_ghost, - "ghost", - - tsk_null, /* set() */ - tsk_null, /* get() */ - tmedia_session_ghost_prepare, - tmedia_session_ghost_start, - tmedia_session_ghost_stop, - tmedia_session_ghost_pause, - - /* Audio part */ - { tsk_null }, - - tmedia_session_ghost_get_lo, - tmedia_session_ghost_set_ro +static const tmedia_session_plugin_def_t tmedia_session_ghost_plugin_def_s = { + &tmedia_session_ghost_def_s, + + tmedia_ghost, + "ghost", + + tsk_null, /* set() */ + tsk_null, /* get() */ + tmedia_session_ghost_prepare, + tmedia_session_ghost_start, + tmedia_session_ghost_stop, + tmedia_session_ghost_pause, + + /* Audio part */ + { tsk_null }, + + tmedia_session_ghost_get_lo, + tmedia_session_ghost_set_ro }; const tmedia_session_plugin_def_t *tmedia_session_ghost_plugin_def_t = &tmedia_session_ghost_plugin_def_s; diff --git a/tinyMEDIA/test/dummy.c b/tinyMEDIA/test/dummy.c index 5874de5..e7ca8cd 100755 --- a/tinyMEDIA/test/dummy.c +++ b/tinyMEDIA/test/dummy.c @@ -2,19 +2,19 @@ * Copyright (C) 2009 Mamadou Diop. * * Contact: Mamadou Diop <diopmamadou(at)yahoo.fr> -* +* * 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. * @@ -27,73 +27,72 @@ int dummy_start(tmedia_t* self) { - dummy_t *dummy = DUMMY(self); - TSK_DEBUG_INFO("dummy_start"); + dummy_t *dummy = DUMMY(self); + TSK_DEBUG_INFO("dummy_start"); - return 0; + return 0; } int dummy_pause(tmedia_t* self) { - dummy_t *dummy = DUMMY(self); - TSK_DEBUG_INFO("dummy_pause"); + dummy_t *dummy = DUMMY(self); + TSK_DEBUG_INFO("dummy_pause"); - return 0; + return 0; } int dummy_stop(tmedia_t* self) { - dummy_t *dummy = DUMMY(self); - TSK_DEBUG_INFO("dummy_stop"); - - return 0; + dummy_t *dummy = DUMMY(self); + TSK_DEBUG_INFO("dummy_stop"); + + return 0; } const tsdp_header_M_t* dummy_get_local_offer(tmedia_t* self, va_list *app) { - dummy_t *dummy = DUMMY(self); - const tsk_object_def_t* objdef; - tsdp_header_t* header; + dummy_t *dummy = DUMMY(self); + const tsk_object_def_t* objdef; + tsdp_header_t* header; - TSK_DEBUG_INFO("dummy_get_local_offer"); - while((objdef = va_arg(*app, const tsk_object_def_t*))){ - header = tsk_object_new_2(objdef, app); + TSK_DEBUG_INFO("dummy_get_local_offer"); + while((objdef = va_arg(*app, const tsk_object_def_t*))) { + header = tsk_object_new_2(objdef, app); - TSK_OBJECT_SAFE_FREE(header); - } + TSK_OBJECT_SAFE_FREE(header); + } - return tsk_null; + return tsk_null; } const tsdp_header_M_t* dummy_get_negotiated_offer(tmedia_t* self) { - dummy_t *dummy = DUMMY(self); - TSK_DEBUG_INFO("dummy_get_negotiated_offer"); + dummy_t *dummy = DUMMY(self); + TSK_DEBUG_INFO("dummy_get_negotiated_offer"); - return tsk_null; + return tsk_null; } int dummy_set_remote_offer(tmedia_t* self, const tsdp_message_t* offer) { - dummy_t *dummy = DUMMY(self); - TSK_DEBUG_INFO("dummy_set_remote_offer"); + dummy_t *dummy = DUMMY(self); + TSK_DEBUG_INFO("dummy_set_remote_offer"); - return 0; + return 0; } int dummy_perform(tmedia_t* self, tmedia_action_t action, const tsk_params_L_t* params) { - dummy_t *dummy = DUMMY(self); - - switch(action){ - case tma_dummy_say_hello: - { - TSK_DEBUG_INFO("dummy_perform (hello to \"%s\")", tsk_params_get_param_value(params, "to")); - break; - } - } - - return 0; + dummy_t *dummy = DUMMY(self); + + switch(action) { + case tma_dummy_say_hello: { + TSK_DEBUG_INFO("dummy_perform (hello to \"%s\")", tsk_params_get_param_value(params, "to")); + break; + } + } + + return 0; } @@ -102,50 +101,48 @@ int dummy_perform(tmedia_t* self, tmedia_action_t action, const tsk_params_L_t* // static void* dummy_create(tsk_object_t *self, va_list * app) { - dummy_t *dummy = self; - if(dummy) - { - // Parameters MUST appear in this order - const char* name = va_arg(*app, const char*); - const char* host = va_arg(*app, const char*); - tnet_socket_type_t socket_type = va_arg(*app, tnet_socket_type_t); - - tmedia_init(TMEDIA(dummy), name); - - TMEDIA(dummy)->protocol = tsk_strdup("TCP/DUMMY"); - } - else{ - TSK_DEBUG_ERROR("Failed to create new dummy media."); - } - return self; + dummy_t *dummy = self; + if(dummy) { + // Parameters MUST appear in this order + const char* name = va_arg(*app, const char*); + const char* host = va_arg(*app, const char*); + tnet_socket_type_t socket_type = va_arg(*app, tnet_socket_type_t); + + tmedia_init(TMEDIA(dummy), name); + + TMEDIA(dummy)->protocol = tsk_strdup("TCP/DUMMY"); + } + else { + TSK_DEBUG_ERROR("Failed to create new dummy media."); + } + return self; } static void* dummy_destroy(tsk_object_t *self) { - dummy_t *dummy = self; - if(dummy){ - tmedia_deinit(TMEDIA(dummy)); - TSK_FREE(dummy->local_sdp); - TSK_FREE(dummy->remote_sdp); - TSK_FREE(dummy->negotiated_sdp); - } - else{ - TSK_DEBUG_ERROR("Null dummy media."); - } - - return self; + dummy_t *dummy = self; + if(dummy) { + tmedia_deinit(TMEDIA(dummy)); + TSK_FREE(dummy->local_sdp); + TSK_FREE(dummy->remote_sdp); + TSK_FREE(dummy->negotiated_sdp); + } + else { + TSK_DEBUG_ERROR("Null dummy media."); + } + + return self; } static int dummy_cmp(const tsk_object_t *obj1, const tsk_object_t *obj2) { - return -1; + return -1; } -static const tsk_object_def_t dummy_def_s = -{ - sizeof(dummy_t), - dummy_create, - dummy_destroy, - dummy_cmp +static const tsk_object_def_t dummy_def_s = { + sizeof(dummy_t), + dummy_create, + dummy_destroy, + dummy_cmp }; const tsk_object_def_t *dummy_def_t = &dummy_def_s; @@ -153,21 +150,20 @@ const tsk_object_def_t *dummy_def_t = &dummy_def_s; //======================================================== // Dummy media plugin definition // -static const tmedia_plugin_def_t dummy_plugin_def_s = -{ - &dummy_def_s, - "dummy plugin", - "audio", +static const tmedia_plugin_def_t dummy_plugin_def_s = { + &dummy_def_s, + "dummy plugin", + "audio", - dummy_start, - dummy_pause, - dummy_stop, + dummy_start, + dummy_pause, + dummy_stop, - dummy_get_local_offer, - dummy_get_negotiated_offer, - dummy_set_remote_offer, + dummy_get_local_offer, + dummy_get_negotiated_offer, + dummy_set_remote_offer, - dummy_perform + dummy_perform }; const tmedia_plugin_def_t *dummy_plugin_def_t = &dummy_plugin_def_s; diff --git a/tinyMEDIA/test/dummy.h b/tinyMEDIA/test/dummy.h index a916ea6..cb0d82e 100755 --- a/tinyMEDIA/test/dummy.h +++ b/tinyMEDIA/test/dummy.h @@ -2,19 +2,19 @@ * Copyright (C) 2009 Mamadou Diop. * * Contact: Mamadou Diop <diopmamadou(at)yahoo.fr> -* +* * 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. * @@ -26,13 +26,12 @@ #define DUMMY(self) ((dummy_t*)(self)) -typedef struct dummy_s -{ - TMED_DECLARE_MEDIA; - - char* local_sdp; - char* remote_sdp; - char* negotiated_sdp; +typedef struct dummy_s { + TMED_DECLARE_MEDIA; + + char* local_sdp; + char* remote_sdp; + char* negotiated_sdp; } dummy_t; diff --git a/tinyMEDIA/test/test.c b/tinyMEDIA/test/test.c index 759a96b..c11f2a0 100755 --- a/tinyMEDIA/test/test.c +++ b/tinyMEDIA/test/test.c @@ -2,19 +2,19 @@ * Copyright (C) 2009 Mamadou Diop. * * Contact: Mamadou Diop <diopmamadou(at)yahoo.fr> -* +* * 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. * @@ -50,78 +50,78 @@ int _tmain(int argc, _TCHAR* argv[]) int main() #endif { - /* Register dummy plugins */ - test_register_dummy_plugins(); - /* Register content plugins */ - test_register_contents_plugins(); + /* Register dummy plugins */ + test_register_dummy_plugins(); + /* Register content plugins */ + test_register_contents_plugins(); - do { + do { #if RUN_TEST_ALL || RUN_TEST_CODECS - test_codecs(); + test_codecs(); #endif #if RUN_TEST_ALL || RUN_TEST_SESSIONS - test_sessions(); + test_sessions(); #endif #if RUN_TEST_ALL || RUN_TEST_QOS - test_qos(); + test_qos(); #endif #if RUN_TEST_ALL || RUN_TEST_IMAGEATTR - test_qos_imageattr(); + test_qos_imageattr(); #endif #if RUN_TEST_ALL || RUN_TEST_CONTENTS - test_contents(); + test_contents(); #endif - - } - while(RUN_TEST_LOOP); - - return 0; + + } + while(RUN_TEST_LOOP); + + return 0; } void test_register_contents_plugins() { - tmedia_content_plugin_register("text/html", tmedia_content_dummy_plugin_def_t); - tmedia_content_plugin_register("text/plain", tmedia_content_dummy_plugin_def_t); - tmedia_content_plugin_register("message/CPIM", tmedia_content_cpim_plugin_def_t); + tmedia_content_plugin_register("text/html", tmedia_content_dummy_plugin_def_t); + tmedia_content_plugin_register("text/plain", tmedia_content_dummy_plugin_def_t); + tmedia_content_plugin_register("message/CPIM", tmedia_content_cpim_plugin_def_t); } void test_register_dummy_plugins() { - int ret; - - /* === Sessions === */ - if((ret = tmedia_session_plugin_register(tmedia_session_daudio_plugin_def_t))){ - TSK_DEBUG_ERROR("Failed to register audio plugin"); - } - if((ret = tmedia_session_plugin_register(tmedia_session_dvideo_plugin_def_t))){ - TSK_DEBUG_ERROR("Failed to register video plugin"); - } - 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))){ - TSK_DEBUG_ERROR("Failed to register G.711a plugin"); - } - if((ret = tmedia_codec_plugin_register(tmedia_codec_dpcmu_plugin_def_t))){ - TSK_DEBUG_ERROR("Failed to register G.711u plugin"); - } - if((ret = tmedia_codec_plugin_register(tmedia_codec_dh263_plugin_def_t))){ - TSK_DEBUG_ERROR("Failed to register H.263-1996 plugin"); - } - if((ret = tmedia_codec_plugin_register(tmedia_codec_dh264_plugin_def_t))){ - TSK_DEBUG_ERROR("Failed to register H.264 (Base profile 10) plugin"); - } + int ret; + + /* === Sessions === */ + if((ret = tmedia_session_plugin_register(tmedia_session_daudio_plugin_def_t))) { + TSK_DEBUG_ERROR("Failed to register audio plugin"); + } + if((ret = tmedia_session_plugin_register(tmedia_session_dvideo_plugin_def_t))) { + TSK_DEBUG_ERROR("Failed to register video plugin"); + } + 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))) { + TSK_DEBUG_ERROR("Failed to register G.711a plugin"); + } + if((ret = tmedia_codec_plugin_register(tmedia_codec_dpcmu_plugin_def_t))) { + TSK_DEBUG_ERROR("Failed to register G.711u plugin"); + } + if((ret = tmedia_codec_plugin_register(tmedia_codec_dh263_plugin_def_t))) { + TSK_DEBUG_ERROR("Failed to register H.263-1996 plugin"); + } + if((ret = tmedia_codec_plugin_register(tmedia_codec_dh264_plugin_def_t))) { + TSK_DEBUG_ERROR("Failed to register H.264 (Base profile 10) plugin"); + } } //#ifdef _WIN32_WCE @@ -133,23 +133,23 @@ void test_register_dummy_plugins() // while(1) // { // tmedia_t* dummy = tsk_null; -// +// // // Register dummy media // tmedia_plugin_register(dummy_plugin_def_t); // // ...if you have another one to register // // ...and another // // ...again and again -// +// // // Create dummy media // if((dummy = tmedia_factory_create("dummy plugin", "127.0.0.1", tnet_socket_type_udp_ipv4))){ // // tmedia_get_local_offer(dummy, // TSDP_HEADER_A_VA_ARGS("file-disposition", "attachment"), -// +// // tsk_null // ); // tmedia_get_negotiated_offer(dummy); -// tmedia_set_remote_offer(dummy, tsk_null); +// tmedia_set_remote_offer(dummy, tsk_null); // // tmedia_start(dummy); // tmedia_pause(dummy); @@ -160,11 +160,11 @@ void test_register_dummy_plugins() // tsk_null); // // tmedia_stop(dummy); -// +// // TSK_OBJECT_SAFE_FREE(dummy); // } // } -// +// // return 0; //} diff --git a/tinyMEDIA/test/test_codecs.h b/tinyMEDIA/test/test_codecs.h index 865953c..8fdb809 100755 --- a/tinyMEDIA/test/test_codecs.h +++ b/tinyMEDIA/test/test_codecs.h @@ -2,19 +2,19 @@ * Copyright (C) 2009 Mamadou Diop. * * Contact: Mamadou Diop <diopmamadou(at)yahoo.fr> -* +* * 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. * @@ -24,14 +24,14 @@ void test_codecs() { - tmedia_codec_t* pcmu, *pcma; + tmedia_codec_t* pcmu, *pcma; - /* creates codecs */ - pcmu = tmedia_codec_create(TMEDIA_CODEC_FORMAT_G711u); - pcma = tmedia_codec_create(TMEDIA_CODEC_FORMAT_G711a); + /* creates codecs */ + pcmu = tmedia_codec_create(TMEDIA_CODEC_FORMAT_G711u); + pcma = tmedia_codec_create(TMEDIA_CODEC_FORMAT_G711a); - TSK_OBJECT_SAFE_FREE(pcmu); - TSK_OBJECT_SAFE_FREE(pcma); + TSK_OBJECT_SAFE_FREE(pcmu); + TSK_OBJECT_SAFE_FREE(pcma); } #endif /* _TEST_CODECS_H_ */ diff --git a/tinyMEDIA/test/test_contents.h b/tinyMEDIA/test/test_contents.h index fe33797..abce61e 100755 --- a/tinyMEDIA/test/test_contents.h +++ b/tinyMEDIA/test/test_contents.h @@ -2,19 +2,19 @@ * Copyright (C) 2009 Mamadou Diop. * * Contact: Mamadou Diop <diopmamadou(at)yahoo.fr> -* +* * 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. * @@ -28,9 +28,9 @@ static void test_content_cpim(); static void test_contents() { - test_content_dummy(); - test_content_text_plain(); - test_content_cpim(); + test_content_dummy(); + test_content_text_plain(); + test_content_cpim(); } @@ -38,28 +38,28 @@ static void test_content_dummy() { #define CONTENT_DUMMY_DATA "salut" #define CONTENT_DUMMY_TYPE "cool/ok" - tmedia_content_t* content = tmedia_content_parse(CONTENT_DUMMY_DATA, tsk_strlen(CONTENT_DUMMY_DATA), CONTENT_DUMMY_TYPE); - if(content){ - tsk_buffer_t* data = tmedia_content_get_data(content); - TSK_DEBUG_INFO("content-type=%s\n\ncontent=%s", TMEDIA_CONTENT(content)->type, TSK_BUFFER_DATA(data)); - tsk_object_unref(data); - } + tmedia_content_t* content = tmedia_content_parse(CONTENT_DUMMY_DATA, tsk_strlen(CONTENT_DUMMY_DATA), CONTENT_DUMMY_TYPE); + if(content) { + tsk_buffer_t* data = tmedia_content_get_data(content); + TSK_DEBUG_INFO("content-type=%s\n\ncontent=%s", TMEDIA_CONTENT(content)->type, TSK_BUFFER_DATA(data)); + tsk_object_unref(data); + } - TSK_OBJECT_SAFE_FREE(content); + TSK_OBJECT_SAFE_FREE(content); } static void test_content_text_plain() { #define CONTENT_TEXT_PLAIN_DATA "salut comment tu vas?" #define CONTENT_TEXT_PLAIN_TYPE "text/plain" - tmedia_content_t* content = tmedia_content_parse(CONTENT_TEXT_PLAIN_DATA, tsk_strlen(CONTENT_TEXT_PLAIN_DATA), CONTENT_TEXT_PLAIN_TYPE); - if(content){ - tsk_buffer_t* data = tmedia_content_get_data(content); - TSK_DEBUG_INFO("content-type=%s\n\ncontent=%s", TMEDIA_CONTENT(content)->type, TSK_BUFFER_DATA(data)); - tsk_object_unref(data); - } + tmedia_content_t* content = tmedia_content_parse(CONTENT_TEXT_PLAIN_DATA, tsk_strlen(CONTENT_TEXT_PLAIN_DATA), CONTENT_TEXT_PLAIN_TYPE); + if(content) { + tsk_buffer_t* data = tmedia_content_get_data(content); + TSK_DEBUG_INFO("content-type=%s\n\ncontent=%s", TMEDIA_CONTENT(content)->type, TSK_BUFFER_DATA(data)); + tsk_object_unref(data); + } - TSK_OBJECT_SAFE_FREE(content); + TSK_OBJECT_SAFE_FREE(content); } static void test_content_cpim() @@ -75,14 +75,14 @@ static void test_content_cpim() "salut comment tu vas?\r\n" #define CONTENT_CPIM_TYPE "message/CPIM" - tmedia_content_t* content = tmedia_content_parse(CONTENT_CPIM_DATA, tsk_strlen(CONTENT_CPIM_DATA), CONTENT_CPIM_TYPE); - if(content){ - tsk_buffer_t* data = tmedia_content_get_data(content); - TSK_DEBUG_INFO("content-type=%s\n\ncontent=%s", TMEDIA_CONTENT(content)->type, TSK_BUFFER_DATA(data)); - tsk_object_unref(data); - } + tmedia_content_t* content = tmedia_content_parse(CONTENT_CPIM_DATA, tsk_strlen(CONTENT_CPIM_DATA), CONTENT_CPIM_TYPE); + if(content) { + tsk_buffer_t* data = tmedia_content_get_data(content); + TSK_DEBUG_INFO("content-type=%s\n\ncontent=%s", TMEDIA_CONTENT(content)->type, TSK_BUFFER_DATA(data)); + tsk_object_unref(data); + } - TSK_OBJECT_SAFE_FREE(content); + TSK_OBJECT_SAFE_FREE(content); } #endif /* _TEST_CONTENTS_H_ */ diff --git a/tinyMEDIA/test/test_image_attr.h b/tinyMEDIA/test/test_image_attr.h index e91d25f..51dfe35 100755 --- a/tinyMEDIA/test/test_image_attr.h +++ b/tinyMEDIA/test/test_image_attr.h @@ -2,19 +2,19 @@ * Copyright (C) 20012 Doubango Telecom <http://www.doubango.org> * * Contact: Mamadou Diop <diopmamadou(at)yahoo[dot]fr> -* +* * 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. * @@ -22,31 +22,30 @@ #ifndef _TEST_IMG_ATTR_H_ #define _TEST_IMG_ATTR_H_ -static const char* __test_imageattrs[] = -{ - "send [x=800,y=640,sar=1.1,q=0.6] [x=480,y=320] recv [x=330,y=250]", - "recv [x=800,y=640,sar=1.1] send [x=330,y=250]", - "recv [x=800,y=640,sar=1.1] send [x=[320:16:640],y=[240:16:480],par=[1.2-1.3]]", - "send [x=[480:16:800],y=[320:16:640],par=[1.2-1.3],q=0.6] [x=[176:8:208],y=[144:8:176],par=[1.2-1.3]] recv *", - "send [x=176,y=144] [x=224,y=176] [x=272,y=224] [x=320,y=240] recv [x=176,y=144] [x=224,y=176] [x=272,y=224,q=0.6] [x=320,y=240]", - "send [x=320,y=240]", - "recv [x=320,y=240]", - "send [x=[400:16:800],y=[320:16:640],sar=[1.0-1.3],par=[1.2-1.3]] recv [x=800,y=600,sar=1.1]", - "recv [x=464,y=384,sar=1.15] send [x=800,y=600,sar=1.1]" +static const char* __test_imageattrs[] = { + "send [x=800,y=640,sar=1.1,q=0.6] [x=480,y=320] recv [x=330,y=250]", + "recv [x=800,y=640,sar=1.1] send [x=330,y=250]", + "recv [x=800,y=640,sar=1.1] send [x=[320:16:640],y=[240:16:480],par=[1.2-1.3]]", + "send [x=[480:16:800],y=[320:16:640],par=[1.2-1.3],q=0.6] [x=[176:8:208],y=[144:8:176],par=[1.2-1.3]] recv *", + "send [x=176,y=144] [x=224,y=176] [x=272,y=224] [x=320,y=240] recv [x=176,y=144] [x=224,y=176] [x=272,y=224,q=0.6] [x=320,y=240]", + "send [x=320,y=240]", + "recv [x=320,y=240]", + "send [x=[400:16:800],y=[320:16:640],sar=[1.0-1.3],par=[1.2-1.3]] recv [x=800,y=600,sar=1.1]", + "recv [x=464,y=384,sar=1.15] send [x=800,y=600,sar=1.1]" }; void test_qos_imageattr() { - tsk_size_t i; - tmedia_imageattr_xt imageattr; - for(i = 0; i < sizeof(__test_imageattrs)/sizeof(__test_imageattrs[0]); ++i){ - if(tmedia_imageattr_parse(&imageattr, __test_imageattrs[i], tsk_strlen(__test_imageattrs[i])) == 0){ - TSK_DEBUG_INFO("image-attr parsed (OK): %s", __test_imageattrs[i]); - } - else{ - TSK_DEBUG_ERROR("image-attr parsed (NOK): %s", __test_imageattrs[i]); - } - } + tsk_size_t i; + tmedia_imageattr_xt imageattr; + for(i = 0; i < sizeof(__test_imageattrs)/sizeof(__test_imageattrs[0]); ++i) { + if(tmedia_imageattr_parse(&imageattr, __test_imageattrs[i], tsk_strlen(__test_imageattrs[i])) == 0) { + TSK_DEBUG_INFO("image-attr parsed (OK): %s", __test_imageattrs[i]); + } + else { + TSK_DEBUG_ERROR("image-attr parsed (NOK): %s", __test_imageattrs[i]); + } + } } diff --git a/tinyMEDIA/test/test_qos.h b/tinyMEDIA/test/test_qos.h index 3565cc2..b1c21ac 100755 --- a/tinyMEDIA/test/test_qos.h +++ b/tinyMEDIA/test/test_qos.h @@ -2,19 +2,19 @@ * Copyright (C) 2009 Mamadou Diop. * * Contact: Mamadou Diop <diopmamadou(at)yahoo.fr> -* +* * 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. * @@ -24,244 +24,244 @@ char* test_qos_tostring(const tmedia_qos_tline_t* tline) { - char* ret = tsk_null; - tsdp_header_M_t* M; - - if(!tline){ - TSK_DEBUG_ERROR("Invalid parameter"); - return tsk_null; - } - - M = tsdp_header_M_create("audio", 20000, "RTP/AVP"); - tmedia_qos_tline_to_sdp(tline, M); - - ret = tsdp_header_tostring(TSDP_HEADER(M)); - TSK_OBJECT_SAFE_FREE(M); - - return ret; + char* ret = tsk_null; + tsdp_header_M_t* M; + + if(!tline) { + TSK_DEBUG_ERROR("Invalid parameter"); + return tsk_null; + } + + M = tsdp_header_M_create("audio", 20000, "RTP/AVP"); + tmedia_qos_tline_to_sdp(tline, M); + + ret = tsdp_header_tostring(TSDP_HEADER(M)); + TSK_OBJECT_SAFE_FREE(M); + + return ret; } void test_qos_parser() { - tsdp_header_M_t* M; - tmedia_qos_tline_e2e_t* e2e; - tmedia_qos_tline_segmented_t* segmented; - char* temp = tsk_null; - tmedia_qos_stype_t type; - tsk_bool_t canresume; - - /* test E2E */ - M = tsdp_header_M_create("audio", 20000, "RTP/AVP"); - e2e = tmedia_qos_tline_e2e_create(tmedia_qos_strength_mandatory); - // to_sdp - tmedia_qos_tline_e2e_to_sdp(e2e, M); - if((type = tmedia_qos_get_type(M)) != tmedia_qos_stype_e2e){ - TSK_DEBUG_ERROR("Invalid type"); - } - if((temp = tsdp_header_tostring(TSDP_HEADER(M)))){ - TSK_DEBUG_INFO("E2E to_sdp: %s", temp); - TSK_FREE(temp); - } - // from_sdp - TSK_OBJECT_SAFE_FREE(e2e); - e2e = tmedia_qos_tline_e2e_from_sdp(M); - canresume = tmedia_qos_tline_e2e_canresume(e2e); - tmedia_qos_tline_e2e_to_sdp(e2e, M); - if((temp = tsdp_header_tostring(TSDP_HEADER(M)))){ - TSK_DEBUG_INFO("e2e from_sdp: %s", temp); - TSK_FREE(temp); - } - - - TSK_OBJECT_SAFE_FREE(e2e); - TSK_OBJECT_SAFE_FREE(M); - - /* test Segmented */ - M = tsdp_header_M_create("video", 20002, "RTP/AVP"); - segmented = tmedia_qos_tline_segmented_create(tmedia_qos_strength_none); - segmented->remote_send.strength = tmedia_qos_strength_optional; - // to_sdp - tmedia_qos_tline_segmented_to_sdp(segmented, M); - if((type = tmedia_qos_get_type(M)) != tmedia_qos_stype_segmented){ - TSK_DEBUG_ERROR("Invalid type"); - } - if((temp = tsdp_header_tostring(TSDP_HEADER(M)))){ - TSK_DEBUG_INFO("Segmented to_sdp: %s", temp); - TSK_FREE(temp); - } - // from_sdp - TSK_OBJECT_SAFE_FREE(segmented); - segmented = tmedia_qos_tline_segmented_from_sdp(M); - canresume = tmedia_qos_tline_segmented_canresume(segmented); - tmedia_qos_tline_segmented_to_sdp(segmented, M); - if((temp = tsdp_header_tostring(TSDP_HEADER(M)))){ - TSK_DEBUG_INFO("Segmented from_sdp: %s", temp); - TSK_FREE(temp); - } - - - - TSK_OBJECT_SAFE_FREE(segmented); - TSK_OBJECT_SAFE_FREE(M); + tsdp_header_M_t* M; + tmedia_qos_tline_e2e_t* e2e; + tmedia_qos_tline_segmented_t* segmented; + char* temp = tsk_null; + tmedia_qos_stype_t type; + tsk_bool_t canresume; + + /* test E2E */ + M = tsdp_header_M_create("audio", 20000, "RTP/AVP"); + e2e = tmedia_qos_tline_e2e_create(tmedia_qos_strength_mandatory); + // to_sdp + tmedia_qos_tline_e2e_to_sdp(e2e, M); + if((type = tmedia_qos_get_type(M)) != tmedia_qos_stype_e2e) { + TSK_DEBUG_ERROR("Invalid type"); + } + if((temp = tsdp_header_tostring(TSDP_HEADER(M)))) { + TSK_DEBUG_INFO("E2E to_sdp: %s", temp); + TSK_FREE(temp); + } + // from_sdp + TSK_OBJECT_SAFE_FREE(e2e); + e2e = tmedia_qos_tline_e2e_from_sdp(M); + canresume = tmedia_qos_tline_e2e_canresume(e2e); + tmedia_qos_tline_e2e_to_sdp(e2e, M); + if((temp = tsdp_header_tostring(TSDP_HEADER(M)))) { + TSK_DEBUG_INFO("e2e from_sdp: %s", temp); + TSK_FREE(temp); + } + + + TSK_OBJECT_SAFE_FREE(e2e); + TSK_OBJECT_SAFE_FREE(M); + + /* test Segmented */ + M = tsdp_header_M_create("video", 20002, "RTP/AVP"); + segmented = tmedia_qos_tline_segmented_create(tmedia_qos_strength_none); + segmented->remote_send.strength = tmedia_qos_strength_optional; + // to_sdp + tmedia_qos_tline_segmented_to_sdp(segmented, M); + if((type = tmedia_qos_get_type(M)) != tmedia_qos_stype_segmented) { + TSK_DEBUG_ERROR("Invalid type"); + } + if((temp = tsdp_header_tostring(TSDP_HEADER(M)))) { + TSK_DEBUG_INFO("Segmented to_sdp: %s", temp); + TSK_FREE(temp); + } + // from_sdp + TSK_OBJECT_SAFE_FREE(segmented); + segmented = tmedia_qos_tline_segmented_from_sdp(M); + canresume = tmedia_qos_tline_segmented_canresume(segmented); + tmedia_qos_tline_segmented_to_sdp(segmented, M); + if((temp = tsdp_header_tostring(TSDP_HEADER(M)))) { + TSK_DEBUG_INFO("Segmented from_sdp: %s", temp); + TSK_FREE(temp); + } + + + + TSK_OBJECT_SAFE_FREE(segmented); + TSK_OBJECT_SAFE_FREE(M); } void test_qos_e2e_neg() { - tmedia_qos_tline_e2e_t *e2eA = tsk_null, *e2eB = tsk_null; - char* temp = tsk_null; + tmedia_qos_tline_e2e_t *e2eA = tsk_null, *e2eB = tsk_null; + char* temp = tsk_null; - /* SDP1: A includes end-to-end quality of service preconditions in the - initial offer. + /* SDP1: A includes end-to-end quality of service preconditions in the + initial offer. - m=audio 20000 RTP/AVP 0 + m=audio 20000 RTP/AVP 0 c=IN IP4 192.0.2.1 a=curr:qos e2e none a=des:qos mandatory e2e sendrecv - */ - e2eA = tmedia_qos_tline_e2e_create(tmedia_qos_strength_mandatory); - if((temp = test_qos_tostring((const tmedia_qos_tline_t*)e2eA))){ - TSK_DEBUG_INFO("SDP1=\n%s", temp); - TSK_FREE(temp); - } - - /* SDP2: Since B uses RSVP, it can know when resources in its "send" - direction are available, because it will receive RESV messages from - the network. However, it does not know the status of the - reservations in the other direction. B requests confirmation for - resource reservations in its "recv" direction to the peer user agent - A in its answer. - - m=audio 30000 RTP/AVP 0 + */ + e2eA = tmedia_qos_tline_e2e_create(tmedia_qos_strength_mandatory); + if((temp = test_qos_tostring((const tmedia_qos_tline_t*)e2eA))) { + TSK_DEBUG_INFO("SDP1=\n%s", temp); + TSK_FREE(temp); + } + + /* SDP2: Since B uses RSVP, it can know when resources in its "send" + direction are available, because it will receive RESV messages from + the network. However, it does not know the status of the + reservations in the other direction. B requests confirmation for + resource reservations in its "recv" direction to the peer user agent + A in its answer. + + m=audio 30000 RTP/AVP 0 c=IN IP4 192.0.2.4 a=curr:qos e2e none a=des:qos mandatory e2e sendrecv a=conf:qos e2e recv - */ - e2eB = tmedia_qos_tline_e2e_create(tmedia_qos_strength_mandatory); - tmedia_qos_tline_e2e_set_ro(e2eB, e2eA); - if((temp = test_qos_tostring((const tmedia_qos_tline_t*)e2eB))){ - TSK_DEBUG_INFO("SDP2=\n%s", temp); - TSK_FREE(temp); - } - - /* SDP3: When A receives RESV messages, it sends an updated offer (5) to B: - - m=audio 20000 RTP/AVP 0 - c=IN IP4 192.0.2.1 - a=curr:qos e2e send - a=des:qos mandatory e2e sendrecv - */ - tmedia_qos_tline_e2e_set_ro(e2eA, e2eB); - if((temp = test_qos_tostring((const tmedia_qos_tline_t*)e2eA))){ - TSK_DEBUG_INFO("SDP3=\n%s", temp); - TSK_FREE(temp); - } - - /* SDP4: B responds with an answer (6) which contains the current status - of the resource reservation (i.e., sendrecv): - - m=audio 30000 RTP/AVP 0 - c=IN IP4 192.0.2.4 - a=curr:qos e2e sendrecv - a=des:qos mandatory e2e sendrecv - */ - tmedia_qos_tline_e2e_set_ro(e2eB, e2eA); - if((temp = test_qos_tostring((const tmedia_qos_tline_t*)e2eB))){ - TSK_DEBUG_INFO("SDP4=\n%s", temp); - TSK_FREE(temp); - } - - /* A receive B's response */ - tmedia_qos_tline_e2e_set_ro(e2eA, e2eB); - if((temp = test_qos_tostring((const tmedia_qos_tline_t*)e2eA))){ - TSK_DEBUG_INFO("SDP5=\n%s", temp); - TSK_FREE(temp); - } - - if(tmedia_qos_tline_e2e_canresume(e2eA)){ - TSK_DEBUG_INFO("A can resume"); - } - else{ - TSK_DEBUG_ERROR("A can't resume"); - } - - if(tmedia_qos_tline_e2e_canresume(e2eB)){ - TSK_DEBUG_INFO("B can resume"); - } - else{ - TSK_DEBUG_ERROR("B can't resume"); - } - - TSK_OBJECT_SAFE_FREE(e2eB); - TSK_OBJECT_SAFE_FREE(e2eA); + */ + e2eB = tmedia_qos_tline_e2e_create(tmedia_qos_strength_mandatory); + tmedia_qos_tline_e2e_set_ro(e2eB, e2eA); + if((temp = test_qos_tostring((const tmedia_qos_tline_t*)e2eB))) { + TSK_DEBUG_INFO("SDP2=\n%s", temp); + TSK_FREE(temp); + } + + /* SDP3: When A receives RESV messages, it sends an updated offer (5) to B: + + m=audio 20000 RTP/AVP 0 + c=IN IP4 192.0.2.1 + a=curr:qos e2e send + a=des:qos mandatory e2e sendrecv + */ + tmedia_qos_tline_e2e_set_ro(e2eA, e2eB); + if((temp = test_qos_tostring((const tmedia_qos_tline_t*)e2eA))) { + TSK_DEBUG_INFO("SDP3=\n%s", temp); + TSK_FREE(temp); + } + + /* SDP4: B responds with an answer (6) which contains the current status + of the resource reservation (i.e., sendrecv): + + m=audio 30000 RTP/AVP 0 + c=IN IP4 192.0.2.4 + a=curr:qos e2e sendrecv + a=des:qos mandatory e2e sendrecv + */ + tmedia_qos_tline_e2e_set_ro(e2eB, e2eA); + if((temp = test_qos_tostring((const tmedia_qos_tline_t*)e2eB))) { + TSK_DEBUG_INFO("SDP4=\n%s", temp); + TSK_FREE(temp); + } + + /* A receive B's response */ + tmedia_qos_tline_e2e_set_ro(e2eA, e2eB); + if((temp = test_qos_tostring((const tmedia_qos_tline_t*)e2eA))) { + TSK_DEBUG_INFO("SDP5=\n%s", temp); + TSK_FREE(temp); + } + + if(tmedia_qos_tline_e2e_canresume(e2eA)) { + TSK_DEBUG_INFO("A can resume"); + } + else { + TSK_DEBUG_ERROR("A can't resume"); + } + + if(tmedia_qos_tline_e2e_canresume(e2eB)) { + TSK_DEBUG_INFO("B can resume"); + } + else { + TSK_DEBUG_ERROR("B can't resume"); + } + + TSK_OBJECT_SAFE_FREE(e2eB); + TSK_OBJECT_SAFE_FREE(e2eA); } void test_qos_segmented_neg() { - tmedia_qos_tline_segmented_t *segA = tsk_null, *segB = tsk_null; - char* temp = tsk_null; - - /* INVITE - a=curr:qos local none - a=curr:qos remote none - a=des:qos mandatory local sendrecv - a=des:qos mandatory remote sendrecv - */ - segA = tmedia_qos_tline_segmented_create(tmedia_qos_strength_mandatory); - if((temp = test_qos_tostring((const tmedia_qos_tline_t*)segA))){ - TSK_DEBUG_INFO("INVITE=\n%s", temp); - TSK_FREE(temp); - } - - /* 183 Sesson progress - a=curr:qos local none - a=curr:qos remote none - a=des:qos mandatory local sendrecv - a=des:qos mandatory remote sendrecv - a=conf:qos remote sendrecv - */ - segB = tmedia_qos_tline_segmented_create(tmedia_qos_strength_mandatory); - tmedia_qos_tline_segmented_set_ro(segB, segA); - if((temp = test_qos_tostring((const tmedia_qos_tline_t*)segB))){ - TSK_DEBUG_INFO("183=\n%s", temp); - TSK_FREE(temp); - } - - /* UPDATE - a=curr:qos local sendrecv - a=curr:qos remote none - a=des:qos mandatory local sendrecv - a=des:qos mandatory remote sendrecv - */ - tmedia_qos_tline_segmented_set_ro(segA, segB); - if((temp = test_qos_tostring((const tmedia_qos_tline_t*)segA))){ - TSK_DEBUG_INFO("UPDATE=\n%s", temp); - TSK_FREE(temp); - } - - /* 200 OK - a=curr:qos local sendrecv - a=curr:qos remote sendrecv - a=des:qos mandatory local sendrecv - a=des:qos mandatory remote sendrecv - */ - tmedia_qos_tline_segmented_set_ro(segB, segA); - if((temp = test_qos_tostring((const tmedia_qos_tline_t*)segB))){ - TSK_DEBUG_INFO("200OK=\n%s", temp); - TSK_FREE(temp); - } - - TSK_OBJECT_SAFE_FREE(segA); - TSK_OBJECT_SAFE_FREE(segB); + tmedia_qos_tline_segmented_t *segA = tsk_null, *segB = tsk_null; + char* temp = tsk_null; + + /* INVITE + a=curr:qos local none + a=curr:qos remote none + a=des:qos mandatory local sendrecv + a=des:qos mandatory remote sendrecv + */ + segA = tmedia_qos_tline_segmented_create(tmedia_qos_strength_mandatory); + if((temp = test_qos_tostring((const tmedia_qos_tline_t*)segA))) { + TSK_DEBUG_INFO("INVITE=\n%s", temp); + TSK_FREE(temp); + } + + /* 183 Sesson progress + a=curr:qos local none + a=curr:qos remote none + a=des:qos mandatory local sendrecv + a=des:qos mandatory remote sendrecv + a=conf:qos remote sendrecv + */ + segB = tmedia_qos_tline_segmented_create(tmedia_qos_strength_mandatory); + tmedia_qos_tline_segmented_set_ro(segB, segA); + if((temp = test_qos_tostring((const tmedia_qos_tline_t*)segB))) { + TSK_DEBUG_INFO("183=\n%s", temp); + TSK_FREE(temp); + } + + /* UPDATE + a=curr:qos local sendrecv + a=curr:qos remote none + a=des:qos mandatory local sendrecv + a=des:qos mandatory remote sendrecv + */ + tmedia_qos_tline_segmented_set_ro(segA, segB); + if((temp = test_qos_tostring((const tmedia_qos_tline_t*)segA))) { + TSK_DEBUG_INFO("UPDATE=\n%s", temp); + TSK_FREE(temp); + } + + /* 200 OK + a=curr:qos local sendrecv + a=curr:qos remote sendrecv + a=des:qos mandatory local sendrecv + a=des:qos mandatory remote sendrecv + */ + tmedia_qos_tline_segmented_set_ro(segB, segA); + if((temp = test_qos_tostring((const tmedia_qos_tline_t*)segB))) { + TSK_DEBUG_INFO("200OK=\n%s", temp); + TSK_FREE(temp); + } + + TSK_OBJECT_SAFE_FREE(segA); + TSK_OBJECT_SAFE_FREE(segB); } void test_qos() { - //test_qos_parser(); - //test_qos_e2e_neg(); - test_qos_segmented_neg(); + //test_qos_parser(); + //test_qos_e2e_neg(); + test_qos_segmented_neg(); } #endif /* _TEST_QOS_H_ */ diff --git a/tinyMEDIA/test/test_sessions.h b/tinyMEDIA/test/test_sessions.h index 97f5d56..bb39fd7 100755 --- a/tinyMEDIA/test/test_sessions.h +++ b/tinyMEDIA/test/test_sessions.h @@ -2,19 +2,19 @@ * Copyright (C) 2009 Mamadou Diop. * * Contact: Mamadou Diop <diopmamadou(at)yahoo.fr> -* +* * 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. * @@ -71,176 +71,176 @@ void test_sessions_client() { - tmedia_session_mgr_t* mgr; - const tsdp_message_t* sdp_lo; - tsdp_message_t* sdp_ro; - char* temp; - tsk_bool_t canresume; - tmedia_type_t media_type = (tmedia_audio | tmedia_video | tmedia_msrp | tmedia_t38); - - int32_t width = 176; - int64_t height = 144LL; - - - /* create manager */ - mgr = tmedia_session_mgr_create((tmedia_audio | tmedia_video | tmedia_msrp | tmedia_t38), - "0.0.0.0", tsk_false, tsk_true); - tmedia_session_mgr_set_qos(mgr, tmedia_qos_stype_segmented, tmedia_qos_strength_mandatory); - - tmedia_session_mgr_set(mgr, - TMEDIA_SESSION_VIDEO_SET_INT32("width", width), - TMEDIA_SESSION_VIDEO_SET_INT64("height", height), - TMEDIA_SESSION_VIDEO_SET_STR("description", "This is my session"), - TMEDIA_SESSION_AUDIO_SET_INT32("rate", "8000"), - TMEDIA_SESSION_SET_STR(tmedia_audio | tmedia_video, "hello", "world"), - TMEDIA_SESSION_SET_NULL()); - - /* 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); - } - - /* 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); - } - - tmedia_session_mgr_start(mgr); - - canresume = tmedia_session_mgr_canresume(mgr); - - TSK_OBJECT_SAFE_FREE(mgr); + tmedia_session_mgr_t* mgr; + const tsdp_message_t* sdp_lo; + tsdp_message_t* sdp_ro; + char* temp; + tsk_bool_t canresume; + tmedia_type_t media_type = (tmedia_audio | tmedia_video | tmedia_msrp | tmedia_t38); + + int32_t width = 176; + int64_t height = 144LL; + + + /* create manager */ + mgr = tmedia_session_mgr_create((tmedia_audio | tmedia_video | tmedia_msrp | tmedia_t38), + "0.0.0.0", tsk_false, tsk_true); + tmedia_session_mgr_set_qos(mgr, tmedia_qos_stype_segmented, tmedia_qos_strength_mandatory); + + tmedia_session_mgr_set(mgr, + TMEDIA_SESSION_VIDEO_SET_INT32("width", width), + TMEDIA_SESSION_VIDEO_SET_INT64("height", height), + TMEDIA_SESSION_VIDEO_SET_STR("description", "This is my session"), + TMEDIA_SESSION_AUDIO_SET_INT32("rate", "8000"), + TMEDIA_SESSION_SET_STR(tmedia_audio | tmedia_video, "hello", "world"), + TMEDIA_SESSION_SET_NULL()); + + /* 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); + } + + /* 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); + } + + tmedia_session_mgr_start(mgr); + + canresume = tmedia_session_mgr_canresume(mgr); + + TSK_OBJECT_SAFE_FREE(mgr); } void test_sessions_server() { - tmedia_session_mgr_t* mgr = tsk_null; - const tsdp_message_t* sdp_lo; - tsdp_message_t* sdp_ro = tsk_null; - char* temp; - tmedia_type_t type; - - /* parse ro */ - if(!(sdp_ro = tsdp_message_parse(SDP_RO, tsk_strlen(SDP_RO)))){ - TSK_DEBUG_ERROR("Failed to parse ro"); - return; - } - else{ - /* get ro media type */ - type = tmedia_type_from_sdp(sdp_ro); - } - - /* create manager */ - mgr = tmedia_session_mgr_create(type, "192.168.16.82", tsk_false, tsk_false); - - /* set ro */ - tmedia_session_mgr_set_ro(mgr, sdp_ro); - - /* 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); - } - - TSK_OBJECT_SAFE_FREE(sdp_ro); - TSK_OBJECT_SAFE_FREE(mgr); + tmedia_session_mgr_t* mgr = tsk_null; + const tsdp_message_t* sdp_lo; + tsdp_message_t* sdp_ro = tsk_null; + char* temp; + tmedia_type_t type; + + /* parse ro */ + if(!(sdp_ro = tsdp_message_parse(SDP_RO, tsk_strlen(SDP_RO)))) { + TSK_DEBUG_ERROR("Failed to parse ro"); + return; + } + else { + /* get ro media type */ + type = tmedia_type_from_sdp(sdp_ro); + } + + /* create manager */ + mgr = tmedia_session_mgr_create(type, "192.168.16.82", tsk_false, tsk_false); + + /* set ro */ + tmedia_session_mgr_set_ro(mgr, sdp_ro); + + /* 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); + } + + TSK_OBJECT_SAFE_FREE(sdp_ro); + TSK_OBJECT_SAFE_FREE(mgr); } void test_sessions_hold_resume() { - tmedia_session_mgr_t* mgr; - const tsdp_message_t* sdp_lo; - char* temp; - tmedia_type_t type = tmedia_audio | tmedia_video | tmedia_msrp | tmedia_t38; - - /* create manager */ - mgr = tmedia_session_mgr_create(type, "192.168.16.82", tsk_false, tsk_true); - - /* 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); - } - - /* hold */ - tmedia_session_mgr_hold(mgr, type); - sdp_lo = tmedia_session_mgr_get_lo(mgr); - if((temp = tsdp_message_tostring(sdp_lo))){ - TSK_DEBUG_INFO("sdp_lo(hold)=%s", temp); - TSK_FREE(temp); - } - TSK_DEBUG_INFO("Hold local=%s and remote=%s", - tmedia_session_mgr_is_held(mgr, type, tsk_true) ? "yes" : "no", - tmedia_session_mgr_is_held(mgr, type, tsk_false) ? "yes" : "no" - ); - - /* resume */ - tmedia_session_mgr_resume(mgr, type, tsk_true); - sdp_lo = tmedia_session_mgr_get_lo(mgr); - if((temp = tsdp_message_tostring(sdp_lo))){ - TSK_DEBUG_INFO("sdp_lo(resume)=%s", temp); - TSK_FREE(temp); - } - TSK_DEBUG_INFO("Hold local=%s and remote=%s", - tmedia_session_mgr_is_held(mgr, type, tsk_true) ? "yes" : "no", - tmedia_session_mgr_is_held(mgr, type, tsk_false) ? "yes" : "no" - ); - - TSK_OBJECT_SAFE_FREE(mgr); + tmedia_session_mgr_t* mgr; + const tsdp_message_t* sdp_lo; + char* temp; + tmedia_type_t type = tmedia_audio | tmedia_video | tmedia_msrp | tmedia_t38; + + /* create manager */ + mgr = tmedia_session_mgr_create(type, "192.168.16.82", tsk_false, tsk_true); + + /* 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); + } + + /* hold */ + tmedia_session_mgr_hold(mgr, type); + sdp_lo = tmedia_session_mgr_get_lo(mgr); + if((temp = tsdp_message_tostring(sdp_lo))) { + TSK_DEBUG_INFO("sdp_lo(hold)=%s", temp); + TSK_FREE(temp); + } + TSK_DEBUG_INFO("Hold local=%s and remote=%s", + tmedia_session_mgr_is_held(mgr, type, tsk_true) ? "yes" : "no", + tmedia_session_mgr_is_held(mgr, type, tsk_false) ? "yes" : "no" + ); + + /* resume */ + tmedia_session_mgr_resume(mgr, type, tsk_true); + sdp_lo = tmedia_session_mgr_get_lo(mgr); + if((temp = tsdp_message_tostring(sdp_lo))) { + TSK_DEBUG_INFO("sdp_lo(resume)=%s", temp); + TSK_FREE(temp); + } + TSK_DEBUG_INFO("Hold local=%s and remote=%s", + tmedia_session_mgr_is_held(mgr, type, tsk_true) ? "yes" : "no", + tmedia_session_mgr_is_held(mgr, type, tsk_false) ? "yes" : "no" + ); + + TSK_OBJECT_SAFE_FREE(mgr); } void test_sessions_add_remove() { - tmedia_session_mgr_t* mgr = tsk_null; - const tsdp_message_t* sdp_lo; - tsdp_message_t* sdp_ro = tsk_null; - char* temp; - tmedia_type_t type; - - /* parse ro */ - if(!(sdp_ro = tsdp_message_parse(SDP_RO, tsk_strlen(SDP_RO)))){ - TSK_DEBUG_ERROR("Failed to parse ro"); - return; - } - else{ - /* get ro media type */ - type = tmedia_type_from_sdp(sdp_ro); - } - - /* create manager */ - mgr = tmedia_session_mgr_create(type, "192.168.16.82", tsk_false, tsk_false); - - /* set ro */ - tmedia_session_mgr_set_ro(mgr, sdp_ro); - - /* 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); - } - - TSK_OBJECT_SAFE_FREE(sdp_ro); - TSK_OBJECT_SAFE_FREE(mgr); + tmedia_session_mgr_t* mgr = tsk_null; + const tsdp_message_t* sdp_lo; + tsdp_message_t* sdp_ro = tsk_null; + char* temp; + tmedia_type_t type; + + /* parse ro */ + if(!(sdp_ro = tsdp_message_parse(SDP_RO, tsk_strlen(SDP_RO)))) { + TSK_DEBUG_ERROR("Failed to parse ro"); + return; + } + else { + /* get ro media type */ + type = tmedia_type_from_sdp(sdp_ro); + } + + /* create manager */ + mgr = tmedia_session_mgr_create(type, "192.168.16.82", tsk_false, tsk_false); + + /* set ro */ + tmedia_session_mgr_set_ro(mgr, sdp_ro); + + /* 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); + } + + TSK_OBJECT_SAFE_FREE(sdp_ro); + TSK_OBJECT_SAFE_FREE(mgr); } void test_sessions() { - test_sessions_client(); - //test_sessions_server(); - //test_sessions_hold_resume(); + test_sessions_client(); + //test_sessions_server(); + //test_sessions_hold_resume(); } #endif /* _TEST_SESSIONS_H_ */ |