int tdav_producer_audio_set(tdav_producer_audio_t* self, const tmedia_param_t* param)
{
	if(!self){
		TSK_DEBUG_ERROR("Invalid parameter");
		return -1;
	}

	if(param->plugin_type == tmedia_ppt_producer){
		if(param->value_type == tmedia_pvt_int32){
			if(tsk_striequals(param->key, "gain")){
				uint32_t gain = TSK_TO_UINT32((uint8_t*)param->value);
				if(gain<TDAV_AUDIO_GAIN_MAX && gain>=0){
					TMEDIA_PRODUCER(self)->audio.gain = (uint8_t)gain;
					TSK_DEBUG_INFO("audio producer gain=%u", gain);
				}
				else{
					TSK_DEBUG_ERROR("%u is invalid as gain value", gain);
					return -2;
				}
			}
			else if(tsk_striequals(param->key, "volume")){
				TMEDIA_PRODUCER(self)->audio.volume = TSK_TO_INT32((uint8_t*)param->value);
				TMEDIA_PRODUCER(self)->audio.volume = TSK_CLAMP(0, TMEDIA_PRODUCER(self)->audio.volume, 100);
			}
		}
	}

	return 0;
}
int tdav_session_msrp_set(tmedia_session_t* self, const tmedia_param_t* param)
{
	int ret = 0;
	tdav_session_msrp_t* msrp;

	if(!self){
		TSK_DEBUG_ERROR("Invalid parameter");
		return -1;
	}

	TSK_DEBUG_INFO("tdav_session_msrp_set");

	msrp = (tdav_session_msrp_t*)self;

	if(param->value_type == tmedia_pvt_pchar){
		if(tsk_striequals(param->key, "remote-ip")){
			// only if no ip associated to the "m=" line
			if(param->value && !msrp->remote_ip){
				msrp->remote_ip = tsk_strdup(param->value);
			}
		}
		else if(tsk_striequals(param->key, "local-ip")){
			tsk_strupdate(&msrp->local_ip, param->value);
		}
		else if(tsk_striequals(param->key, "local-ipver")){
			msrp->useIPv6 = tsk_striequals(param->value, "ipv6");
		}
		else if(tsk_striequals(param->key, "accept-types")){
			tsk_strupdate(&msrp->accept_types, param->value);
		}
		else if(tsk_striequals(param->key, "accept-wrapped-types")){
			tsk_strupdate(&msrp->accept_w_types, param->value);
		}

		/* Configuration */
		else if(tsk_striequals(param->key, "Failure-Report")){
			msrp->config->Failure_Report = tsk_striequals(param->value, "yes");
		}
		else if(tsk_striequals(param->key, "Success-Report")){
			msrp->config->Success_Report = tsk_striequals(param->value, "yes");
		}

		/* File Transfer */
		else if(tsk_striequals(param->key, "file-path") && !tsk_strnullORempty((const char*)param->value)){
			tsk_strupdate(&msrp->file.path, param->value);
		}
		else if(tsk_striequals(param->key, "file-selector")){
			tsk_strupdate(&msrp->file.selector, param->value);
		}
		else if(tsk_striequals(param->key, "file-disposition")){
			tsk_strupdate(&msrp->file.disposition, param->value);
		}
		else if(tsk_striequals(param->key, "file-date")){
			tsk_strupdate(&msrp->file.date, param->value);
		}
		else if(tsk_striequals(param->key, "file-icon")){
			tsk_strupdate(&msrp->file.icon, param->value);
		}
		else if(tsk_striequals(param->key, "file-transfer-id")){
			tsk_strupdate(&msrp->file.transfer_id, param->value);
		}
	}
	else if(param->value_type == tmedia_pvt_pobject){
		if(tsk_striequals(param->key, "natt-ctx")){
			TSK_OBJECT_SAFE_FREE(msrp->natt_ctx);
			msrp->natt_ctx = tsk_object_ref(param->value);
		}
	}
	else if(param->value_type == tmedia_pvt_int64 || param->value_type == tmedia_pvt_int32){
		if(tsk_striequals(param->key, "chunck-duration")){
			msrp->chunck_duration = TSK_TO_UINT32((uint8_t*)param->value);
			if(msrp->sender){
				msrp->sender->chunck_duration = msrp->chunck_duration;
			}
		}
	}

	return ret;
}