summaryrefslogtreecommitdiffstats
path: root/tinyMEDIA/src/tmedia_codec.c
diff options
context:
space:
mode:
Diffstat (limited to 'tinyMEDIA/src/tmedia_codec.c')
-rwxr-xr-xtinyMEDIA/src/tmedia_codec.c1180
1 files changed, 623 insertions, 557 deletions
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
OpenPOWER on IntegriCloud