Example #1
0
static switch_status_t channel_on_destroy(switch_core_session_t *session)
{
    ctdm_private_t *tech_pvt = switch_core_session_get_private(session);
    
 	if ((tech_pvt = switch_core_session_get_private(session))) {
	
		if (FTDM_SUCCESS != ftdm_channel_command(tech_pvt->ftdm_channel, FTDM_COMMAND_ENABLE_ECHOCANCEL, NULL)) {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Failed to enable echo cancellation.\n");
		}
        
		if (tech_pvt->read_codec.implementation) {
			switch_core_codec_destroy(&tech_pvt->read_codec);
		}
		
		if (tech_pvt->write_codec.implementation) {
			switch_core_codec_destroy(&tech_pvt->write_codec);
		}

		switch_core_session_unset_read_codec(session);
		switch_core_session_unset_write_codec(session);
        
        ftdm_channel_close(&tech_pvt->ftdm_channel);
	}

    return SWITCH_STATUS_SUCCESS;
}
Example #2
0
static switch_status_t channel_on_destroy(switch_core_session_t *session)
{
	switch_channel_t *channel = NULL;
	private_t *tech_pvt = NULL;
	void *pop;

	channel = switch_core_session_get_channel(session);
	switch_assert(channel != NULL);

	tech_pvt = switch_core_session_get_private(session);

	if (tech_pvt) {
		switch_core_timer_destroy(&tech_pvt->timer);

		if (switch_core_codec_ready(&tech_pvt->read_codec)) {
			switch_core_codec_destroy(&tech_pvt->read_codec);
		}

		if (switch_core_codec_ready(&tech_pvt->write_codec)) {
			switch_core_codec_destroy(&tech_pvt->write_codec);
		}

		if (tech_pvt->write_frame) {
			switch_frame_free(&tech_pvt->write_frame);
		}

		while (switch_queue_trypop(tech_pvt->frame_queue, &pop) == SWITCH_STATUS_SUCCESS && pop) {
			switch_frame_t *frame = (switch_frame_t *) pop;
			switch_frame_free(&frame);
		}
	}


	return SWITCH_STATUS_SUCCESS;
}
SWITCH_DECLARE(switch_status_t) switch_core_media_bug_remove(switch_core_session_t *session, switch_media_bug_t **bug)
{
	switch_media_bug_t *bp = NULL, *last = NULL;
	switch_status_t status = SWITCH_STATUS_FALSE;

	switch_thread_rwlock_wrlock(session->bug_rwlock);
	if (session->bugs) {
		for (bp = session->bugs; bp; bp = bp->next) {
			if ((!bp->thread_id || bp->thread_id == switch_thread_self()) && bp->ready && bp == *bug) {
				if (last) {
					last->next = bp->next;
				} else {
					session->bugs = bp->next;
				}
				break;
			}

			last = bp;
		}
	}

	if (!session->bugs && switch_core_codec_ready(&session->bug_codec)) {
		switch_core_codec_destroy(&session->bug_codec);
	}

	switch_thread_rwlock_unlock(session->bug_rwlock);

	if (bp) {
		status = switch_core_media_bug_close(&bp);
	}
	
	return status;
}
SWITCH_DECLARE(switch_status_t) switch_core_media_bug_remove_all_function(switch_core_session_t *session, const char *function)
{
	switch_media_bug_t *bp;
	switch_status_t status = SWITCH_STATUS_FALSE;

	if (session->bugs) {
		switch_thread_rwlock_wrlock(session->bug_rwlock);
		for (bp = session->bugs; bp; bp = bp->next) {
			if ((bp->thread_id && bp->thread_id != switch_thread_self()) || switch_test_flag(bp, SMBF_LOCK)) {
				switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "BUG is thread locked skipping.\n");
				continue;
			}
			
			if (!zstr(function) && strcmp(bp->function, function)) {
				continue;
			}


			if (bp->callback) {
				bp->callback(bp, bp->user_data, SWITCH_ABC_TYPE_CLOSE);
			}
			switch_core_media_bug_destroy(bp);
			switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Removing BUG from %s\n", switch_channel_get_name(session->channel));
		}
		session->bugs = NULL;
		switch_thread_rwlock_unlock(session->bug_rwlock);
		status = SWITCH_STATUS_SUCCESS;
	}

	if (switch_core_codec_ready(&session->bug_codec)) {
		switch_core_codec_destroy(&session->bug_codec);
	}

	return status;
}
switch_status_t spandsp_tdd_send_session(switch_core_session_t *session, const char *text)
{
	v18_state_t *tdd_state;
	switch_frame_t *read_frame, write_frame = { 0 };
	uint8_t write_buf[SWITCH_RECOMMENDED_BUFFER_SIZE];
	switch_codec_implementation_t read_impl = { 0 };
	switch_codec_t write_codec = { 0 };
	switch_channel_t *channel = switch_core_session_get_channel(session);
	switch_status_t status;

	switch_core_session_get_read_impl(session, &read_impl);

	if (switch_core_codec_init(&write_codec,
				"L16",
				NULL,
				read_impl.actual_samples_per_second,
				read_impl.microseconds_per_packet / 1000,
				read_impl.number_of_channels,
				SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL,
				switch_core_session_get_pool(session)) == SWITCH_STATUS_SUCCESS) {
				write_frame.data = write_buf;
				write_frame.buflen = sizeof(write_buf);
				write_frame.datalen = read_impl.decoded_bytes_per_packet;
				write_frame.samples = write_frame.datalen / 2;
				write_frame.codec = &write_codec;
		switch_core_session_set_read_codec(session, &write_codec);
	} else {
		return SWITCH_STATUS_FALSE;
	}

	tdd_state = v18_init(NULL, TRUE, get_v18_mode(session), put_text_msg, NULL);


	v18_put(tdd_state, text, -1);

	while(switch_channel_ready(channel)) {
		status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);

		if (!SWITCH_READ_ACCEPTABLE(status)) {
			break;
		}


		if (!v18_tx(tdd_state, (void *)write_buf, write_frame.samples)) {
			break;
		}

		if (switch_core_session_write_frame(session, &write_frame, SWITCH_IO_FLAG_NONE, 0) != SWITCH_STATUS_SUCCESS) {
			break;
		}

	}

	switch_core_codec_destroy(&write_codec);
	switch_core_session_set_read_codec(session, NULL);

	v18_free(tdd_state);

	return SWITCH_STATUS_SUCCESS;
}
void WSClientParser::DestroyChannel(WSChannel* wsChannel) {
	switch_log_printf(
			SWITCH_CHANNEL_UUID_LOG(this->GetUUID()),
			SWITCH_LOG_INFO,
			"WSClientParser::DestroyChannel( "
			"this : %p, "
			"wsChannel : %p "
			") \n",
			this,
			mpChannel
			);

	if( wsChannel ) {
		// Audio
		if (switch_core_codec_ready(&wsChannel->read_codec)) {
			switch_core_codec_destroy(&wsChannel->read_codec);
		}

		if (switch_core_codec_ready(&wsChannel->write_codec)) {
			switch_core_codec_destroy(&wsChannel->write_codec);
		}

		// Video
		if (switch_core_codec_ready(&wsChannel->video_read_codec)) {
			switch_core_codec_destroy(&wsChannel->video_read_codec);
		}

		if (switch_core_codec_ready(&wsChannel->video_write_codec)) {
			switch_core_codec_destroy(&wsChannel->video_write_codec);
		}

		if( wsChannel->video_readbuf_mutex ) {
			switch_mutex_destroy(wsChannel->video_readbuf_mutex);
			wsChannel->video_readbuf_mutex = NULL;
		}

		if( wsChannel->session ) {
			switch_media_handle_destroy(wsChannel->session);
			wsChannel->session = NULL;
		}

		if( wsChannel->video_readbuf ) {
			switch_buffer_destroy(&wsChannel->video_readbuf);
			wsChannel->video_readbuf = NULL;
		}
	}
}
Example #7
0
static switch_status_t channel_on_destroy(switch_core_session_t *session)
{
    crtp_private_t *tech_pvt = NULL;
    
 	if ((tech_pvt = switch_core_session_get_private(session))) {
        
		if (tech_pvt->read_codec.implementation) {
			switch_core_codec_destroy(&tech_pvt->read_codec);
		}
		
		if (tech_pvt->write_codec.implementation) {
			switch_core_codec_destroy(&tech_pvt->write_codec);
		}
	}
    
    return SWITCH_STATUS_SUCCESS;
}
static switch_status_t tech_init(private_t *tech_pvt, switch_core_session_t *session)
{
	const char *iananame = "L16";
	int rate = 8000;
	int interval = 20;
	switch_status_t status = SWITCH_STATUS_SUCCESS;
	switch_channel_t *channel = switch_core_session_get_channel(session);
	const switch_codec_implementation_t *read_impl;


	switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s setup codec %s/%d/%d\n", switch_channel_get_name(channel), iananame, rate,
					  interval);

	status = switch_core_codec_init(&tech_pvt->read_codec,
									iananame,
									NULL,
									rate, interval, 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, switch_core_session_get_pool(session));

	if (status != SWITCH_STATUS_SUCCESS || !tech_pvt->read_codec.implementation || !switch_core_codec_ready(&tech_pvt->read_codec)) {
		goto end;
	}

	status = switch_core_codec_init(&tech_pvt->write_codec,
									iananame,
									NULL,
									rate, interval, 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, switch_core_session_get_pool(session));


	if (status != SWITCH_STATUS_SUCCESS) {
		switch_core_codec_destroy(&tech_pvt->read_codec);
		goto end;
	}

	tech_pvt->read_frame.data = tech_pvt->databuf;
	tech_pvt->read_frame.buflen = sizeof(tech_pvt->databuf);
	tech_pvt->read_frame.codec = &tech_pvt->read_codec;
	tech_pvt->read_frame.flags = SFF_NONE;

	switch_core_session_set_read_codec(session, &tech_pvt->read_codec);
	switch_core_session_set_write_codec(session, &tech_pvt->write_codec);

	read_impl = tech_pvt->read_codec.implementation;

	switch_core_timer_init(&tech_pvt->timer, "soft",
						   read_impl->microseconds_per_packet / 1000, read_impl->samples_per_packet, switch_core_session_get_pool(session));


	switch_mutex_init(&tech_pvt->mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session));
	switch_core_session_set_private(session, tech_pvt);
	tech_pvt->session = session;
	tech_pvt->channel = switch_core_session_get_channel(session);

  end:

	return status;
}
Example #9
0
static switch_status_t webm_file_close(switch_file_handle_t *handle)
{
	webm_file_context_t *context = (webm_file_context_t *)handle->private_info;

	context->segment->Finalize();
	delete context->segment;
	delete context->writer;

	if (switch_core_codec_ready(&context->audio_codec)) switch_core_codec_destroy(&context->audio_codec);
	if (switch_core_codec_ready(&context->video_codec)) switch_core_codec_destroy(&context->video_codec);

	if (context->timer.interval) {
		switch_core_timer_destroy(&context->timer);
	}

	switch_buffer_destroy(&context->buf);
	switch_buffer_destroy(&context->audio_buffer);

	return SWITCH_STATUS_SUCCESS;
}
Example #10
0
static switch_status_t mp4_file_close(switch_file_handle_t *handle)
{
	mp4_file_context_t *context = handle->private_info;

	if (context->fd) {
		MP4Close(context->fd, 0);
		context->fd = NULL;
	}

	if (switch_core_codec_ready(&context->audio_codec)) switch_core_codec_destroy(&context->audio_codec);
	if (switch_core_codec_ready(&context->video_codec)) switch_core_codec_destroy(&context->video_codec);

	if (context->timer.interval) {
		switch_core_timer_destroy(&context->timer);
	}

	switch_img_free(&context->last_img);
	switch_buffer_destroy(&context->buf);

	return SWITCH_STATUS_SUCCESS;
}
SWITCH_DECLARE(switch_status_t) switch_core_media_bug_remove(switch_core_session_t *session, switch_media_bug_t **bug)
{
	switch_media_bug_t *bp = NULL, *bp2 = NULL, *last = NULL;
	switch_status_t status = SWITCH_STATUS_FALSE;
	int tap_only = 0;

	if (switch_core_media_bug_test_flag(*bug, SMBF_LOCK)) {
		return status;
	}

	switch_thread_rwlock_wrlock(session->bug_rwlock);
	if (session->bugs) {
		for (bp = session->bugs; bp; bp = bp->next) {
			if ((!bp->thread_id || bp->thread_id == switch_thread_self()) && bp->ready && bp == *bug) {
				if (last) {
					last->next = bp->next;
				} else {
					session->bugs = bp->next;
				}
				break;
			}

			last = bp;
		}
	}

	if (!session->bugs && switch_core_codec_ready(&session->bug_codec)) {
		switch_core_codec_destroy(&session->bug_codec);
	}

	if (session->bugs) {
		for(bp2 = session->bugs; bp2; bp2 = bp2->next) {
			if (bp2->ready && !switch_test_flag(bp2, SMBF_TAP_NATIVE_READ) && !switch_test_flag(bp2, SMBF_TAP_NATIVE_WRITE)) {
				tap_only = 0;
			}	
		}
	}
	
	if (tap_only) {
		switch_set_flag(session, SSF_MEDIA_BUG_TAP_ONLY);
	} else {
		switch_clear_flag(session, SSF_MEDIA_BUG_TAP_ONLY);
	}

	switch_thread_rwlock_unlock(session->bug_rwlock);

	if (bp) {
		status = switch_core_media_bug_close(&bp);
	}
	
	return status;
}
Example #12
0
static switch_status_t channel_on_destroy(switch_core_session_t *session)
{
    switch_channel_t *channel = NULL;
    private_t *tech_pvt = NULL;

    channel = switch_core_session_get_channel(session);
    assert(channel != NULL);

    tech_pvt = switch_core_session_get_private(session);

    if (tech_pvt) {
        if (switch_core_codec_ready(&tech_pvt->read_codec)) {
            switch_core_codec_destroy(&tech_pvt->read_codec);
        }

        if (switch_core_codec_ready(&tech_pvt->write_codec)) {
            switch_core_codec_destroy(&tech_pvt->write_codec);
        }
    }

    return SWITCH_STATUS_SUCCESS;
}
Example #13
0
static switch_status_t channel_on_destroy(switch_core_session_t *session)
{
	switch_channel_t *channel = NULL;
	loopback_private_t *tech_pvt = NULL;
	switch_event_t *vars;

	channel = switch_core_session_get_channel(session);
	switch_assert(channel != NULL);

	tech_pvt = switch_core_session_get_private(session);

	if ((vars = (switch_event_t *) switch_channel_get_private(channel, "__loopback_vars__"))) {
		switch_channel_set_private(channel, "__loopback_vars__", NULL);
		switch_event_destroy(&vars);
	}
	
	if (tech_pvt) {
		switch_core_timer_destroy(&tech_pvt->timer);

		if (switch_core_codec_ready(&tech_pvt->read_codec)) {
			switch_core_codec_destroy(&tech_pvt->read_codec);
		}

		if (switch_core_codec_ready(&tech_pvt->write_codec)) {
			switch_core_codec_destroy(&tech_pvt->write_codec);
		}

		if (tech_pvt->write_frame) {
			switch_frame_free(&tech_pvt->write_frame);
		}

		clear_queue(tech_pvt);
	}


	return SWITCH_STATUS_SUCCESS;
}
static void teletone_destroy(JSContext * cx, JSObject * obj)
{
	struct teletone_obj *tto = JS_GetPrivate(cx, obj);
	switch_memory_pool_t *pool;
	if (tto) {
		if (tto->timer) {
			switch_core_timer_destroy(tto->timer);
		}
		teletone_destroy_session(&tto->ts);
		switch_buffer_destroy(&tto->audio_buffer);
		switch_core_codec_destroy(&tto->codec);
		pool = tto->pool;
		tto->pool = NULL;
		if (pool) {
			switch_core_destroy_memory_pool(&pool);
		}
	}
}
SWITCH_DECLARE(switch_status_t) switch_core_media_bug_transfer_callback(switch_core_session_t *orig_session, switch_core_session_t *new_session, 
																		switch_media_bug_callback_t callback, void * (*user_data_dup_func) (switch_core_session_t *, void *))
{
	switch_media_bug_t *new_bug = NULL, *cur = NULL, *bp = NULL, *last = NULL;
	int total = 0;

	switch_thread_rwlock_wrlock(orig_session->bug_rwlock);
	bp = orig_session->bugs;
	while (bp) {
		cur = bp;
		bp = bp->next;
		
		if (cur->callback == callback) {
			if (last) {
				last->next = cur->next;
			} else {
				orig_session->bugs = cur->next;
			}

			switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(orig_session), SWITCH_LOG_DEBUG, "Transfering %s from %s to %s\n", cur->target,
							  switch_core_session_get_name(orig_session), switch_core_session_get_name(new_session));

			switch_core_media_bug_add(new_session, cur->function, cur->target, cur->callback,
									  user_data_dup_func(new_session, cur->user_data),
									  cur->stop_time, cur->flags, &new_bug);
			switch_core_media_bug_destroy(cur);
			total++;
		} else {
			last = cur;
		}
	}

	if (!orig_session->bugs && switch_core_codec_ready(&orig_session->bug_codec)) {
		switch_core_codec_destroy(&orig_session->bug_codec);
	}

	switch_thread_rwlock_unlock(orig_session->bug_rwlock);


	return total ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE;
}
SWITCH_DECLARE(uint32_t) switch_core_media_bug_prune(switch_core_session_t *session)
{
	switch_media_bug_t *bp = NULL, *last = NULL;
	int ttl = 0;


  top:

	switch_thread_rwlock_wrlock(session->bug_rwlock);
	if (session->bugs) {
		for (bp = session->bugs; bp; bp = bp->next) {
			if (switch_core_media_bug_test_flag(bp, SMBF_PRUNE)) {
				if (last) {
					last->next = bp->next;
				} else {
					session->bugs = bp->next;
				}
				break;
			}

			last = bp;
		}
	}

	if (!session->bugs && switch_core_codec_ready(&session->bug_codec)) {
		switch_core_codec_destroy(&session->bug_codec);
	}

	switch_thread_rwlock_unlock(session->bug_rwlock);

	if (bp) {
		switch_clear_flag(bp, SMBF_LOCK);
		bp->thread_id = 0;
		switch_core_media_bug_close(&bp);
		ttl++;
		goto top;
	}
	
	return ttl;
}
SWITCH_DECLARE(switch_status_t) switch_core_media_bug_remove_callback(switch_core_session_t *session, switch_media_bug_callback_t callback)
{
	switch_media_bug_t *cur = NULL, *bp = NULL, *last = NULL;
	int total = 0;

	switch_thread_rwlock_wrlock(session->bug_rwlock);
	if (session->bugs) {
		bp = session->bugs;
		while (bp) {
			cur = bp;
			bp = bp->next;

			if ((!cur->thread_id || cur->thread_id == switch_thread_self()) && cur->ready && cur->callback == callback) {
				if (last) {
					last->next = cur->next;
				} else {
					session->bugs = cur->next;
				}
				if (switch_core_media_bug_close(&cur) == SWITCH_STATUS_SUCCESS) {
					total++;
				}
			} else {
				last = cur;
			}
		}
	}

	if (!session->bugs && switch_core_codec_ready(&session->bug_codec)) {
		switch_core_codec_destroy(&session->bug_codec);
	}

	switch_thread_rwlock_unlock(session->bug_rwlock);


	return total ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE;
}
Example #18
0
static switch_status_t tech_init(private_t *tech_pvt, switch_core_session_t *session, switch_codec_t *codec)
{
	const char *iananame = "L16";
	int rate = 8000;
	int interval = 20;
	switch_status_t status = SWITCH_STATUS_SUCCESS;
	switch_channel_t *channel = switch_core_session_get_channel(session);
	const switch_codec_implementation_t *read_impl;

	if (codec) {
		iananame = codec->implementation->iananame;
		rate = codec->implementation->samples_per_second;
		interval = codec->implementation->microseconds_per_packet / 1000;
	}

	if (switch_core_codec_ready(&tech_pvt->read_codec)) {
		switch_core_codec_destroy(&tech_pvt->read_codec);
	}

	if (switch_core_codec_ready(&tech_pvt->write_codec)) {
		switch_core_codec_destroy(&tech_pvt->write_codec);
	}

	switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s setup codec %s/%d/%d\n", switch_channel_get_name(channel), iananame, rate,
					  interval);

	status = switch_core_codec_init(&tech_pvt->read_codec,
									iananame,
									NULL,
									rate, interval, 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, switch_core_session_get_pool(session));

	if (status != SWITCH_STATUS_SUCCESS || !tech_pvt->read_codec.implementation || !switch_core_codec_ready(&tech_pvt->read_codec)) {
		goto end;
	}

	status = switch_core_codec_init(&tech_pvt->write_codec,
									iananame,
									NULL,
									rate, interval, 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, switch_core_session_get_pool(session));


	if (status != SWITCH_STATUS_SUCCESS) {
		switch_core_codec_destroy(&tech_pvt->read_codec);
		goto end;
	}

	tech_pvt->read_frame.data = tech_pvt->databuf;
	tech_pvt->read_frame.buflen = sizeof(tech_pvt->databuf);
	tech_pvt->read_frame.codec = &tech_pvt->read_codec;


	tech_pvt->cng_frame.data = tech_pvt->cng_databuf;
	tech_pvt->cng_frame.buflen = sizeof(tech_pvt->cng_databuf);
	//switch_set_flag((&tech_pvt->cng_frame), SFF_CNG);
	tech_pvt->cng_frame.datalen = 2;

	tech_pvt->bowout_frame_count = (tech_pvt->read_codec.implementation->actual_samples_per_second /
									tech_pvt->read_codec.implementation->samples_per_packet) * 3;

	switch_core_session_set_read_codec(session, &tech_pvt->read_codec);
	switch_core_session_set_write_codec(session, &tech_pvt->write_codec);

	if (tech_pvt->flag_mutex) {
		switch_core_timer_destroy(&tech_pvt->timer);
	}

	read_impl = tech_pvt->read_codec.implementation;

	switch_core_timer_init(&tech_pvt->timer, "soft",
						   read_impl->microseconds_per_packet / 1000, read_impl->samples_per_packet * 4, switch_core_session_get_pool(session));


	if (!tech_pvt->flag_mutex) {
		switch_mutex_init(&tech_pvt->flag_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session));
		switch_mutex_init(&tech_pvt->mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session));
		switch_core_session_set_private(session, tech_pvt);
		switch_queue_create(&tech_pvt->frame_queue, FRAME_QUEUE_LEN, switch_core_session_get_pool(session));
		tech_pvt->session = session;
		tech_pvt->channel = switch_core_session_get_channel(session);
	}

  end:

	return status;
}
Example #19
0
static switch_status_t channel_receive_event(switch_core_session_t *session, switch_event_t *event)
{
    const char *command = switch_event_get_header(event, "command");
    switch_channel_t *channel = switch_core_session_get_channel(session);
    crtp_private_t *tech_pvt = switch_core_session_get_private(session);
    char *codec  = switch_event_get_header_nil(event, kCODEC);
    char *szptime  = switch_event_get_header_nil(event, kPTIME);
    char *szrate = switch_event_get_header_nil(event, kRATE);
    char *szpt = switch_event_get_header_nil(event, kPT);

    int ptime  = !zstr(szptime) ? atoi(szptime) : 0,
		rate = !zstr(szrate) ? atoi(szrate) : 8000,
		pt = !zstr(szpt) ? atoi(szpt) : 0;


    if (!zstr(command) && !strcasecmp(command, "media_modify")) {
        /* Compare parameters */
        if (compare_var(event, channel, kREMOTEADDR) ||
            compare_var(event, channel, kREMOTEPORT)) {
		char *remote_addr = switch_event_get_header(event, kREMOTEADDR);
		char *szremote_port = switch_event_get_header(event, kREMOTEPORT);
		switch_port_t remote_port = !zstr(szremote_port) ? atoi(szremote_port) : 0;
		const char *err;


            switch_channel_set_variable(channel, kREMOTEADDR, remote_addr);
            switch_channel_set_variable(channel, kREMOTEPORT, szremote_port);
            
            if (switch_rtp_set_remote_address(tech_pvt->rtp_session, remote_addr, remote_port, 0, SWITCH_TRUE, &err) != SWITCH_STATUS_SUCCESS) {
                switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Error setting RTP remote address: %s\n", err);
            } else {
                switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Set RTP remote: %s:%d\n", remote_addr, (int)remote_port);
                tech_pvt->mode = RTP_SENDRECV;
            }
        }
        
        if (compare_var(event, channel, kCODEC) ||
            compare_var(event, channel, kPTIME) ||
            compare_var(event, channel, kPT) ||
	    compare_var(event, channel, kRATE)) {
		/* Reset codec */
		switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Switching codec updating \n");

		if (switch_core_codec_init(&tech_pvt->read_codec,
					codec,
					NULL,
					rate,
					ptime,
					1,
					/*SWITCH_CODEC_FLAG_ENCODE |*/ SWITCH_CODEC_FLAG_DECODE,
					NULL, switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't load codec?\n");
			goto fail;
		} else {
			if (switch_core_codec_init(&tech_pvt->write_codec,
						codec,
						NULL,
						rate,
						ptime,
						1,
						SWITCH_CODEC_FLAG_ENCODE /*| SWITCH_CODEC_FLAG_DECODE*/, 
						NULL, switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't load codec?\n");
				goto fail;
			}
		}

		if (switch_core_session_set_read_codec(session, &tech_pvt->read_codec) != SWITCH_STATUS_SUCCESS) {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't set read codec?\n");
			goto fail;
		}

		if (switch_core_session_set_write_codec(session, &tech_pvt->write_codec) != SWITCH_STATUS_SUCCESS) {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't set write codec?\n");
			goto fail;
		}

		switch_rtp_set_default_payload(tech_pvt->rtp_session, pt);
		//switch_rtp_set_recv_pt(tech_pvt->rtp_session, pt);
	}
        
        if (compare_var(event, channel, kRFC2833PT)) {
            const char *szpt = switch_channel_get_variable(channel, kRFC2833PT);
            int pt = !zstr(szpt) ? atoi(szpt) : 0;
            
            switch_channel_set_variable(channel, kRFC2833PT, szpt);
            switch_rtp_set_telephony_event(tech_pvt->rtp_session, pt);
        }
    
    } else {
        switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Received unknown command [%s] in event.\n", !command ? "null" : command);
    }

    return SWITCH_STATUS_SUCCESS;
fail:
     if (tech_pvt) {
        if (tech_pvt->read_codec.implementation) {
			switch_core_codec_destroy(&tech_pvt->read_codec);
		}
		
		if (tech_pvt->write_codec.implementation) {
			switch_core_codec_destroy(&tech_pvt->write_codec);
		}
    }
    
    if (session) {
        switch_core_session_destroy(&session);
    }
    return SWITCH_STATUS_FALSE;

}
Example #20
0
static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session, switch_event_t *var_event,
													switch_caller_profile_t *outbound_profile,
													switch_core_session_t **new_session, 
													switch_memory_pool_t **pool,
													switch_originate_flag_t flags, switch_call_cause_t *cancel_cause)
{
    const char  *szchanid = switch_event_get_header(var_event, kCHAN_ID),
                *span_name = switch_event_get_header(var_event, kSPAN_NAME),
                *szprebuffer_len = switch_event_get_header(var_event, kPREBUFFER_LEN);
    int chan_id;
    int span_id;
    switch_caller_profile_t *caller_profile;
    ftdm_span_t *span;
    ftdm_channel_t *chan;
    switch_channel_t *channel;
    char name[128];
    const char *dname;
    ftdm_codec_t codec;
    uint32_t interval;
    ctdm_private_t *tech_pvt = NULL;

    if (zstr(szchanid) || zstr(span_name)) {
        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Both ["kSPAN_ID"] and ["kCHAN_ID"] have to be set.\n");
        goto fail;
    }
    
    chan_id = atoi(szchanid);
    
    if (ftdm_span_find_by_name(span_name, &span) == FTDM_SUCCESS) {
         span_id = ftdm_span_get_id(span);   
    } else {
        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot find span [%s]\n", span_name);
        goto fail;
    }

    if (!(*new_session = switch_core_session_request(ctdm.endpoint_interface, SWITCH_CALL_DIRECTION_OUTBOUND, 0, pool))) {
        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't request session.\n");
        goto fail;
    }
    
    channel = switch_core_session_get_channel(*new_session);
    
    if (ftdm_channel_open_ph(span_id, chan_id, &chan) != FTDM_SUCCESS) {
        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't open span or channel.\n"); 
        goto fail;
    }
    
    span = ftdm_channel_get_span(chan);
    
    tech_pvt = switch_core_session_alloc(*new_session, sizeof *tech_pvt);
    tech_pvt->chan_id = chan_id;
    tech_pvt->span_id = span_id;
    tech_pvt->ftdm_channel = chan;
    tech_pvt->session = *new_session;
    tech_pvt->read_frame.buflen = sizeof(tech_pvt->databuf);
    tech_pvt->read_frame.data = tech_pvt->databuf;
    tech_pvt->prebuffer_len = zstr(szprebuffer_len) ? 0 : atoi(szprebuffer_len);
    switch_core_session_set_private(*new_session, tech_pvt);
    
    
    caller_profile = switch_caller_profile_clone(*new_session, outbound_profile);
    switch_channel_set_caller_profile(channel, caller_profile);
    
    snprintf(name, sizeof(name), "tdm/%d:%d", span_id, chan_id);
	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Connect outbound channel %s\n", name);
	switch_channel_set_name(channel, name);
    
    switch_channel_set_state(channel, CS_INIT);
    
	if (FTDM_SUCCESS != ftdm_channel_command(chan, FTDM_COMMAND_GET_CODEC, &codec)) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to retrieve channel codec.\n");
		return SWITCH_STATUS_GENERR;
	}
    
    if (FTDM_SUCCESS != ftdm_channel_command(chan, FTDM_COMMAND_GET_INTERVAL, &interval)) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to retrieve channel interval.\n");
		return SWITCH_STATUS_GENERR;
	}
    
    if (FTDM_SUCCESS != ftdm_channel_command(chan, FTDM_COMMAND_SET_PRE_BUFFER_SIZE, &tech_pvt->prebuffer_len)) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to set channel pre buffer size.\n");
		return SWITCH_STATUS_GENERR;        
    }

    if (FTDM_SUCCESS != ftdm_channel_command(tech_pvt->ftdm_channel, FTDM_COMMAND_ENABLE_ECHOCANCEL, NULL)) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Failed to set enable echo cancellation.\n");
	}
    
	switch(codec) {
        case FTDM_CODEC_ULAW:
		{
			dname = "PCMU";
		}
            break;
        case FTDM_CODEC_ALAW:
		{
			dname = "PCMA";
		}
            break;
        case FTDM_CODEC_SLIN:
		{
			dname = "L16";
		}
            break;
        default:
		{
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid codec value retrieved from channel, codec value: %d\n", codec);
			goto fail;
		}
	}

    
	if (switch_core_codec_init(&tech_pvt->read_codec,
							   dname,
							   NULL,
							   8000,
							   interval,
							   1,
							   SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
							   NULL, switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't load codec?\n");
        goto fail;
	} else {
		if (switch_core_codec_init(&tech_pvt->write_codec,
								   dname,
								   NULL,
								   8000,
								   interval,
								   1,
								   SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
								   NULL, switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't load codec?\n");
			switch_core_codec_destroy(&tech_pvt->read_codec);
            goto fail;
		}
	}
    
    if (switch_core_session_set_read_codec(*new_session, &tech_pvt->read_codec) != SWITCH_STATUS_SUCCESS) {
        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't set read codec?\n");
        goto fail;
    }
    
    if (switch_core_session_set_write_codec(*new_session, &tech_pvt->write_codec) != SWITCH_STATUS_SUCCESS) {
        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't set write codec?\n");        
    }
    
    if (switch_core_session_thread_launch(*new_session) != SWITCH_STATUS_SUCCESS) {
        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't start session thread.\n"); 
        goto fail;
    }
    
    switch_channel_mark_answered(channel);
    
    return SWITCH_CAUSE_SUCCESS;

fail:
    
    if (tech_pvt) {
        if (tech_pvt->ftdm_channel) {
            ftdm_channel_close(&tech_pvt->ftdm_channel);
        }
        
        if (tech_pvt->read_codec.implementation) {
			switch_core_codec_destroy(&tech_pvt->read_codec);
		}
		
		if (tech_pvt->write_codec.implementation) {
			switch_core_codec_destroy(&tech_pvt->write_codec);
		}
    }
    
    if (*new_session) {
        switch_core_session_destroy(new_session);
    }
    return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
}
Example #21
0
static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session, switch_event_t *var_event,
													switch_caller_profile_t *outbound_profile,
													switch_core_session_t **new_session, 
													switch_memory_pool_t **pool,
													switch_originate_flag_t flags, switch_call_cause_t *cancel_cause)
{
    switch_channel_t *channel;
    char name[128];
    crtp_private_t *tech_pvt = NULL;    
    switch_caller_profile_t *caller_profile;
    switch_rtp_flag_t rtp_flags[SWITCH_RTP_FLAG_INVALID] = {0};
    
    const char *err;

    
    const char  *local_addr = switch_event_get_header_nil(var_event, kLOCALADDR),
                *szlocal_port = switch_event_get_header_nil(var_event, kLOCALPORT),
                *remote_addr = switch_event_get_header_nil(var_event, kREMOTEADDR),
                *szremote_port = switch_event_get_header_nil(var_event, kREMOTEPORT),
                *codec  = switch_event_get_header_nil(var_event, kCODEC),
                *szptime  = switch_event_get_header_nil(var_event, kPTIME),
                //*mode  = switch_event_get_header_nil(var_event, kMODE),
                //*szrfc2833_pt = switch_event_get_header_nil(var_event, kRFC2833PT),
                *szrate = switch_event_get_header_nil(var_event, kRATE),
                *szpt = switch_event_get_header_nil(var_event, kPT);
    
    
    switch_port_t local_port = !zstr(szlocal_port) ? atoi(szlocal_port) : 0,
                 remote_port = !zstr(szremote_port) ? atoi(szremote_port) : 0;
    
    int ptime  = !zstr(szptime) ? atoi(szptime) : 0,
        //rfc2833_pt = !zstr(szrfc2833_pt) ? atoi(szrfc2833_pt) : 0,
        rate = !zstr(szrate) ? atoi(szrate) : 8000,
        pt = !zstr(szpt) ? atoi(szpt) : 0;
    
        if (
            ((zstr(remote_addr) || remote_port == 0) && (zstr(local_addr) || local_port == 0)) ||
            zstr(codec) ||
            zstr(szpt)) {
        
        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing required arguments\n");
        goto fail;
    }
    
    
    if (!(*new_session = switch_core_session_request(crtp.endpoint_interface, SWITCH_CALL_DIRECTION_OUTBOUND, 0, pool))) {
        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't request session.\n");
        goto fail;
    }
    
    channel = switch_core_session_get_channel(*new_session);
    
    tech_pvt = switch_core_session_alloc(*new_session, sizeof *tech_pvt);
    tech_pvt->session = *new_session;
    tech_pvt->channel = channel;
    tech_pvt->local_address = switch_core_session_strdup(*new_session, local_addr);
    tech_pvt->local_port = local_port;
    tech_pvt->remote_address = switch_core_session_strdup(*new_session, remote_addr);
    tech_pvt->remote_port = remote_port;
    tech_pvt->ptime = ptime;
    tech_pvt->agreed_pt = pt;
    tech_pvt->dtmf_type = DTMF_2833; /* XXX */
    
    if (zstr(local_addr) || local_port == 0) {
        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "The local address and port must be set\n");
        goto fail;
    } else if (zstr(remote_addr) || remote_port == 0) {
        tech_pvt->mode = RTP_RECVONLY;
    } else {
        tech_pvt->mode = RTP_SENDRECV;
    }
    
    switch_core_session_set_private(*new_session, tech_pvt);
    
    caller_profile = switch_caller_profile_clone(*new_session, outbound_profile);
    switch_channel_set_caller_profile(channel, caller_profile);
    
    
    snprintf(name, sizeof(name), "rtp/%s", outbound_profile->destination_number);
	switch_channel_set_name(channel, name);
    
    switch_channel_set_state(channel, CS_INIT);

	if (switch_core_codec_init(&tech_pvt->read_codec,
							   codec,
							   NULL,
							   rate,
							   ptime,
							   1,
							   /*SWITCH_CODEC_FLAG_ENCODE |*/ SWITCH_CODEC_FLAG_DECODE,
							   NULL, switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't load codec?\n");
        goto fail;
	} else {
		if (switch_core_codec_init(&tech_pvt->write_codec,
								   codec,
								   NULL,
								   rate,
								   ptime,
								   1,
								   SWITCH_CODEC_FLAG_ENCODE /*| SWITCH_CODEC_FLAG_DECODE*/, 
								   NULL, switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't load codec?\n");
            goto fail;
		}
	}
    
    if (switch_core_session_set_read_codec(*new_session, &tech_pvt->read_codec) != SWITCH_STATUS_SUCCESS) {
        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't set read codec?\n");
        goto fail;
    }
    
    if (switch_core_session_set_write_codec(*new_session, &tech_pvt->write_codec) != SWITCH_STATUS_SUCCESS) {
        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't set write codec?\n");
        goto fail;
    }
    
    if (!(tech_pvt->rtp_session = switch_rtp_new(local_addr, local_port, remote_addr, remote_port, tech_pvt->agreed_pt,
												 tech_pvt->read_codec.implementation->samples_per_packet, ptime * 1000,
												 rtp_flags, "soft", &err, switch_core_session_get_pool(*new_session)))) {
        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't setup RTP session: [%s]\n", err);
        goto fail;
    }
    
    if (switch_core_session_thread_launch(*new_session) != SWITCH_STATUS_SUCCESS) {
        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't start session thread.\n"); 
        goto fail;
    }
    
    switch_channel_mark_answered(channel);
    
    return SWITCH_CAUSE_SUCCESS;
    
fail:
     if (tech_pvt) {
        if (tech_pvt->read_codec.implementation) {
			switch_core_codec_destroy(&tech_pvt->read_codec);
		}
		
		if (tech_pvt->write_codec.implementation) {
			switch_core_codec_destroy(&tech_pvt->write_codec);
		}
    }
    
    if (*new_session) {
        switch_core_session_destroy(new_session);
    }
    return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
}
static switch_status_t engage_device(portaudio_stream_source_t *source, int restart)
{
	PaStreamParameters inputParameters, outputParameters;
	PaError err;
	int sample_rate = source->rate;
	int codec_ms = source->interval;

	switch_mutex_init(&source->device_lock, SWITCH_MUTEX_NESTED, module_pool);

	if (source->timer.timer_interface) {
		switch_core_timer_sync(&source->timer);
	}

	if (source->audio_stream) {
		return SWITCH_STATUS_SUCCESS;
	}

	if (!switch_core_codec_ready(&source->read_codec)) {
		if (switch_core_codec_init(&source->read_codec,
								   "L16",
								   NULL, sample_rate, codec_ms, 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL,
								   NULL) != SWITCH_STATUS_SUCCESS) {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't load codec?\n");
			return SWITCH_STATUS_FALSE;
		}
	}

	switch_assert(source->read_codec.implementation);

	if (!switch_core_codec_ready(&source->write_codec)) {
		if (switch_core_codec_init(&source->write_codec,
								   "L16",
								   NULL,
								   sample_rate, codec_ms, 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, NULL) != SWITCH_STATUS_SUCCESS) {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't load codec?\n");
			switch_core_codec_destroy(&source->read_codec);
			return SWITCH_STATUS_FALSE;
		}
	}


	if (!source->timer.timer_interface) {
		if (switch_core_timer_init(&source->timer,
								   source->timer_name, codec_ms, source->read_codec.implementation->samples_per_packet,
								   module_pool) != SWITCH_STATUS_SUCCESS) {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "setup timer failed!\n");
			switch_core_codec_destroy(&source->read_codec);
			switch_core_codec_destroy(&source->write_codec);
			return SWITCH_STATUS_FALSE;
		}
	}

	source->read_frame.rate = sample_rate;
	source->read_frame.codec = &source->read_codec;

	switch_mutex_lock(source->device_lock);
	/* LOCKED ************************************************************************************************** */
	inputParameters.device = source->sourcedev;
	inputParameters.channelCount = 1;
	inputParameters.sampleFormat = SAMPLE_TYPE;
	inputParameters.suggestedLatency = Pa_GetDeviceInfo(inputParameters.device)->defaultLowInputLatency;
	inputParameters.hostApiSpecificStreamInfo = NULL;
	outputParameters.device = source->sourcedev;
	outputParameters.channelCount = 1;
	outputParameters.sampleFormat = SAMPLE_TYPE;
	outputParameters.suggestedLatency = Pa_GetDeviceInfo(outputParameters.device)->defaultLowOutputLatency;
	outputParameters.hostApiSpecificStreamInfo = NULL;


	err = OpenAudioStream(&source->audio_stream, &inputParameters, NULL, sample_rate, paClipOff, source->read_codec.implementation->samples_per_packet, 0);
	/* UNLOCKED ************************************************************************************************* */
	if (err != paNoError) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error opening audio device retrying\n");
		switch_yield(1000000);
		err = OpenAudioStream(&source->audio_stream, &inputParameters, &outputParameters, sample_rate, paClipOff,
							  source->read_codec.implementation->samples_per_packet, 0);
	}

	switch_mutex_unlock(source->device_lock);
	if (err != paNoError) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't open audio device\n");
		switch_core_codec_destroy(&source->read_codec);
		switch_core_timer_destroy(&source->timer);
		return SWITCH_STATUS_FALSE;
	}


	return SWITCH_STATUS_SUCCESS;
}
static void *SWITCH_THREAD_FUNC read_stream_thread(switch_thread_t *thread, void *obj)
{
	portaudio_stream_source_t *source = obj;
	portaudio_stream_context_t *cp;
	int samples = 0;
	int bused, bytesToWrite;


	switch_mutex_lock(globals.mutex);
	globals.threads++;
	switch_mutex_unlock(globals.mutex);

	if (!source->prebuf) {
		source->prebuf = DEFAULT_PREBUFFER_SIZE;
	}



	switch_mutex_lock(globals.mutex);
	switch_core_hash_insert(globals.source_hash, source->sourcename, source);
	switch_mutex_unlock(globals.mutex);


	switch_thread_rwlock_create(&source->rwlock, source->pool);

	if (engage_device(source, 0) != SWITCH_STATUS_SUCCESS) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, " Dev %d cant be engaged !\n", (int) source->sourcedev);
	} else {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, " Dev %d engaged at %d rate!\n", (int) source->sourcedev, (int) source->rate);
		if (globals.running && !source->stopped) {
			source->ready = 1;

			if (!source->audio_stream) {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No Audio Stream wops!\n");
				source->stopped = 0;
				source->ready = 0;
			} else {
				while (globals.running && !source->stopped) {
					samples = 0;
					switch_mutex_lock(source->device_lock);
					samples = ReadAudioStream(source->audio_stream, source->databuf,
								  source->read_codec.implementation->samples_per_packet, 0, &source->timer);
					switch_mutex_unlock(source->device_lock);


					if (samples) {
						bytesToWrite = source->samples;
						if (samples < bytesToWrite) {
							bytesToWrite = samples;
						}
						bytesToWrite *= source->audio_stream->bytesPerFrame;

						if (source->total) {

							switch_mutex_lock(source->mutex);
							for (cp = source->context_list; cp; cp = cp->next) {

								switch_mutex_lock(cp->audio_mutex);

								bused = switch_buffer_inuse(cp->audio_buffer);
								if (bused > source->samples * 768) {
									switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Leaking stream handle! [%s() %s:%d] %d used %d max\n",
													  cp->func, cp->file, cp->line, (int) bused, (int) (source->samples * 768));
									switch_buffer_zero(cp->audio_buffer);
								} else {
									switch_buffer_write(cp->audio_buffer, source->databuf, bytesToWrite);
								}

								switch_mutex_unlock(cp->audio_mutex);
							}
							switch_mutex_unlock(source->mutex);
						}

					}

				}
			}

		}
	}


	source->ready = 0;

	switch_mutex_lock(globals.mutex);
	switch_core_hash_delete(globals.source_hash, source->sourcename);
	switch_mutex_unlock(globals.mutex);

	switch_thread_rwlock_wrlock(source->rwlock);
	switch_thread_rwlock_unlock(source->rwlock);


	switch_mutex_lock(source->device_lock);
	CloseAudioStream(source->audio_stream);
	if (switch_core_codec_ready(&source->read_codec)) {
		switch_core_codec_destroy(&source->read_codec);
		switch_core_codec_destroy(&source->write_codec);
	}
	if (switch_core_codec_ready(&source->write_codec)) {
		switch_core_codec_destroy(&source->write_codec);
	}
	switch_mutex_unlock(source->device_lock);


	switch_core_destroy_memory_pool(&source->pool);

	switch_mutex_lock(globals.mutex);
	globals.threads--;
	switch_mutex_unlock(globals.mutex);

	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, " thread ending succesfully !\n");
	switch_thread_exit(thread, SWITCH_STATUS_SUCCESS);

	return NULL;
}
Example #24
0
SWITCH_DECLARE(switch_status_t) switch_core_session_set_real_read_codec(switch_core_session_t *session, switch_codec_t *codec)
{
	switch_event_t *event;
	switch_channel_t *channel = switch_core_session_get_channel(session);
	char tmp[30];
	switch_status_t status = SWITCH_STATUS_SUCCESS;
	int changed_read_codec = 0;

	switch_mutex_lock(session->codec_read_mutex);

	if (codec && (!codec->implementation || !switch_core_codec_ready(codec))) {
		codec = NULL;
	}

	if (codec) {
		/* set real_read_codec and read_codec */
		if (!session->real_read_codec) {
			switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Original read codec set to %s:%d\n",
							  switch_channel_get_name(session->channel), codec->implementation->iananame, codec->implementation->ianacode);
			session->read_codec = session->real_read_codec = codec;
			changed_read_codec = 1;
			if (codec->implementation) {
				session->read_impl = *codec->implementation;
				session->real_read_impl = *codec->implementation;
			} else {
				memset(&session->read_impl, 0, sizeof(session->read_impl));
			}
		} else { /* replace real_read_codec */
			switch_codec_t *cur_codec;
			switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Original read codec replaced with %s:%d\n",
							  switch_channel_get_name(session->channel), codec->implementation->iananame, codec->implementation->ianacode);
			/* Set real_read_codec to front of the list of read_codecs */
			cur_codec = session->read_codec;
			while (cur_codec != NULL) {
				if (cur_codec->next == session->real_read_codec) {
					cur_codec->next = codec;
					break;
				}
				cur_codec = cur_codec->next;
			}
			session->real_read_codec = codec;
			/* set read_codec with real_read_codec if it no longer is ready */
			if (!switch_core_codec_ready(session->read_codec)) {
				session->read_codec = codec;
				changed_read_codec = 1;
				if (codec->implementation) {
					session->read_impl = *codec->implementation;
					session->real_read_impl = *codec->implementation;
				} else {
					memset(&session->read_impl, 0, sizeof(session->read_impl));
				}
			}
		}

		/* force media bugs to copy the read codec from the next frame */
		switch_thread_rwlock_wrlock(session->bug_rwlock);
		if (switch_core_codec_ready(&session->bug_codec)) {
			switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Destroying BUG Codec %s:%d\n",
				session->bug_codec.implementation->iananame, session->bug_codec.implementation->ianacode);
			switch_core_codec_destroy(&session->bug_codec);
		}
		switch_thread_rwlock_unlock(session->bug_rwlock);
	} else {
		status = SWITCH_STATUS_FALSE;
		goto end;
	}

	if (changed_read_codec && session->read_codec && session->read_impl.decoded_bytes_per_packet) {
		if (switch_event_create(&event, SWITCH_EVENT_CODEC) == SWITCH_STATUS_SUCCESS) {
			switch_channel_event_set_data(session->channel, event);
			switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "channel-read-codec-name", session->read_impl.iananame);
			switch_event_add_header(event, SWITCH_STACK_BOTTOM, "channel-read-codec-rate", "%d", session->read_impl.actual_samples_per_second);
			switch_event_add_header(event, SWITCH_STACK_BOTTOM, "channel-read-codec-bit-rate", "%d", session->read_impl.bits_per_second);
			if (session->read_impl.actual_samples_per_second != session->read_impl.samples_per_second) {
				switch_event_add_header(event, SWITCH_STACK_BOTTOM, "channel-reported-read-codec-rate", "%d", session->read_impl.samples_per_second);
			}
			switch_event_fire(&event);
		}

		switch_channel_set_variable(channel, "read_codec", session->read_impl.iananame);
		switch_snprintf(tmp, sizeof(tmp), "%d", session->read_impl.actual_samples_per_second);
		switch_channel_set_variable(channel, "read_rate", tmp);

		session->raw_read_frame.codec = session->read_codec;
		session->raw_write_frame.codec = session->read_codec;
		session->enc_read_frame.codec = session->read_codec;
		session->enc_write_frame.codec = session->read_codec;
	}

  end:

	if (session->read_codec) {
		switch_channel_set_flag(channel, CF_MEDIA_SET);
	}

	switch_mutex_unlock(session->codec_read_mutex);
	return status;
}
Example #25
0
int main(int argc, char *argv[]) 
{
	int r = 1;
	switch_bool_t verbose = SWITCH_FALSE;
	const char *err = NULL;
	int i;
	char *extra_modules[100] = { 0 };
	int extra_modules_count = 0;
	int cmd_fail = 0;
	const char *fmtp = "";
	int ptime = 20;
	const char *input, *output, *format = NULL;
	int channels = 1;
	int rate = 8000;
	switch_file_handle_t fh_input = { 0 }, fh_output = { 0 };
	switch_codec_t codec = { 0 };
	switch_codec_t raw_codec = { 0 };
	char buf[2048];
	switch_size_t len = sizeof(buf)/2;
	switch_memory_pool_t *pool = NULL;
	int bitrate = 0;
	int blocksize;
	int in_asis = 0;
	int out_asis = 0;
	int out_flags = SWITCH_FILE_FLAG_WRITE;

	for (i = 1; i < argc; i++) {
		if (argv[i][0] == '-') {
			switch(argv[i][1]) {
				case 'c':
					i++;
					if((SWITCH_GLOBAL_dirs.conf_dir = (char *) malloc(strlen(argv[i]) + 1)) == NULL) {
						return 255;
					}
					strcpy(SWITCH_GLOBAL_dirs.conf_dir, argv[i]);
					break;
				case 'k':
					i++;
					if((SWITCH_GLOBAL_dirs.log_dir = (char *) malloc(strlen(argv[i]) + 1)) == NULL) {
						return 255;
					}
					strcpy(SWITCH_GLOBAL_dirs.log_dir, argv[i]);
					break;
				case 'm':
					i++;
					if((SWITCH_GLOBAL_dirs.mod_dir = (char *) malloc(strlen(argv[i]) + 1)) == NULL) {
						return 255;
					}
					strcpy(SWITCH_GLOBAL_dirs.mod_dir, argv[i]);
					break;
				case 'l':
					i++;
					/* Load extra modules */
					if (strchr(argv[i], ','))  {
						extra_modules_count = switch_split(argv[i], ',', extra_modules);	
					} else {
						extra_modules_count = 1;
						extra_modules[0] = argv[i];
					}
					break;
				case 'f':
					fmtp = argv[++i];
					break;
				case 'p':
					ptime = atoi(argv[++i]);
					break;
				case 'r':
					rate = atoi(argv[++i]);
					break;
				case 'b':
					bitrate = atoi(argv[++i]);
					break;
				case 'v':
					verbose = SWITCH_TRUE;
					break;
				default:
					printf("Command line option not recognized: %s\n", argv[i]);
					cmd_fail = 1;
			}
		} else {
			break;
		}
	}
	
	if (argc - i < 2 || cmd_fail) {
		goto usage;
	}
	
	input = argv[i++];
	output = argv[i++];
	if (zstr(input) || zstr(output) || !(format = strchr(output, '.'))) {
		goto usage;
	}
	
	format++;
	
	if (switch_core_init(SCF_MINIMAL, verbose, &err) != SWITCH_STATUS_SUCCESS) {
		fprintf(stderr, "Cannot init core [%s]\n", err);
		goto end;
	}
	
	switch_loadable_module_init(SWITCH_FALSE);
	switch_loadable_module_load_module("", "CORE_PCM_MODULE", SWITCH_TRUE, &err);
	switch_loadable_module_load_module("", "CORE_SPEEX_MODULE", SWITCH_TRUE, &err);
	switch_loadable_module_load_module("", "CORE_SOFTTIMER_MODULE", SWITCH_TRUE, &err);

	for (i = 0; i < extra_modules_count; i++) {
		if (switch_loadable_module_load_module((char *) SWITCH_GLOBAL_dirs.mod_dir, (char *) extra_modules[i], SWITCH_TRUE, &err) != SWITCH_STATUS_SUCCESS) {
			fprintf(stderr, "Cannot init %s [%s]\n", extra_modules[i], err);
			goto end;
		}
	}
	
	if (switch_loadable_module_load_module((char *) SWITCH_GLOBAL_dirs.mod_dir, (char *) "mod_spandsp", SWITCH_TRUE, &err) != SWITCH_STATUS_SUCCESS) {
		fprintf(stderr, "Cannot init mod_spandsp [%s]\n", err);
		goto end;
	}
	
	if (switch_loadable_module_load_module((char *) SWITCH_GLOBAL_dirs.mod_dir, (char *) "mod_sndfile", SWITCH_TRUE, &err) != SWITCH_STATUS_SUCCESS) {
		fprintf(stderr, "Cannot init mod_sndfile [%s]\n", err);
		goto end;
	}
	
	if (switch_loadable_module_load_module((char *) SWITCH_GLOBAL_dirs.mod_dir, (char *) "mod_native_file", SWITCH_TRUE, &err) != SWITCH_STATUS_SUCCESS) {
		fprintf(stderr, "Cannot init mod_native_file [%s]\n", err);
		goto end;
	}

	switch_core_new_memory_pool(&pool);
	if (verbose) {
		fprintf(stderr, "Opening file %s\n", input);
	}
	if (switch_core_file_open(&fh_input, input, channels, rate, SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) != SWITCH_STATUS_SUCCESS) {
		fprintf(stderr, "Couldn't open %s\n", input);
		goto end;
	}
	

	if (verbose) {
		fprintf(stderr, "Opening file %s\n", output);
	}

	if (switch_stristr(".wav", output)) {
		out_asis = 0;
		out_flags |= SWITCH_FILE_DATA_SHORT;
	} else {
		out_asis = 1;
		out_flags |= SWITCH_FILE_NATIVE;
	}


	if (out_asis) {
		if (switch_core_codec_init_with_bitrate(&codec, format, NULL, fmtp, rate, ptime, channels, bitrate, SWITCH_CODEC_FLAG_ENCODE, NULL, pool) != SWITCH_STATUS_SUCCESS) {
			fprintf(stderr, "Couldn't initialize codec for %s@%dh@%di\n", format, rate, ptime);
			goto end;
		}
	} else {
		char *p;

		if ((p = strchr(input, '.'))) {
			p++;
		}
		if (!p || switch_core_codec_init_with_bitrate(&codec, p, NULL, fmtp, rate, ptime, channels, bitrate, SWITCH_CODEC_FLAG_ENCODE|SWITCH_CODEC_FLAG_DECODE, NULL, pool) != SWITCH_STATUS_SUCCESS) {
			fprintf(stderr, "Couldn't initialize codec for %s@%dh@%di\n", p, rate, ptime);
			goto end;
		}
		
		if (switch_core_codec_init_with_bitrate(&raw_codec, "L16", NULL, fmtp, rate, ptime, channels, bitrate, SWITCH_CODEC_FLAG_ENCODE|SWITCH_CODEC_FLAG_DECODE, NULL, pool) != SWITCH_STATUS_SUCCESS) {
		fprintf(stderr, "Couldn't initialize codec for %s@%dh@%di\n", "L16", rate, ptime);
		goto end;
		}
	}




	if (switch_core_file_open(&fh_output, output, channels, codec.implementation->actual_samples_per_second, out_flags, NULL) != SWITCH_STATUS_SUCCESS) {
		fprintf(stderr, "Couldn't open %s\n", output);
		goto end;	
	}
	
	if (switch_test_flag(&fh_input, SWITCH_FILE_NATIVE)) {
		in_asis = 1;
	}



	if (in_asis) {
		blocksize = len = codec.implementation->encoded_bytes_per_packet;
	} else {
		blocksize = len = (rate*ptime)/1000;
	}

	switch_assert(sizeof(buf) >= len * 2);

	if (verbose) {
		fprintf(stderr, "Frame size is %d\n", blocksize);	
	}
	
	while (switch_core_file_read(&fh_input, buf, &len) == SWITCH_STATUS_SUCCESS) {
		char encode_buf[2048];
		uint32_t encoded_len = sizeof(buf);
		uint32_t encoded_rate = rate;
		unsigned int flags = 0;

		if (out_asis) {
			if (switch_core_codec_encode(&codec, NULL, buf, len*2, rate, encode_buf, &encoded_len, &encoded_rate, &flags) != SWITCH_STATUS_SUCCESS) {
				fprintf(stderr, "Codec encoder error\n");
				goto end;
			}
			
			len = encoded_len;
		} else {
			if (!in_asis) {
				encoded_len = len;
			} else if (in_asis) {
				
				switch_core_codec_decode(&codec,
										 &raw_codec,
										 buf,
										 len,
										 rate,
										 encode_buf,
										 &encoded_len,
										 &encoded_rate,
										 &flags);
				encoded_len /= 2;
				len = encoded_len;
			}
		}


		if (switch_core_file_write(&fh_output, encode_buf, &len) != SWITCH_STATUS_SUCCESS) {
			fprintf(stderr, "Write error\n");
			goto end;
		}
		
		if (len != encoded_len) {
			printf("Short write: wrote %"SWITCH_SIZE_T_FMT"/%d bytes\n", len, encoded_len);
		}
		
		len = blocksize;
	}
	
	r = 0;

end:


	switch_core_codec_destroy(&codec);
	switch_core_codec_destroy(&raw_codec);


	if (fh_input.file_interface) {
		switch_core_file_close(&fh_input);		
	}

	if (fh_output.file_interface) {
		switch_core_file_close(&fh_output);		
	}

	if (pool) {
		switch_core_destroy_memory_pool(&pool);
	}
	
	fs_encode_cleanup();

	//switch_core_destroy();

	return r;
usage:
	printf("Usage: %s [options] input output\n\n", argv[0]);
	printf("The output must end in the format, e.g., myfile.SPEEX\n");
	printf("\t\t -c path\t\t Path to the FS configurations.\n");
	printf("\t\t -k path\t\t Path to the FS log directory\n");
	printf("\t\t -l module[,module]\t Load additional modules (comma-separated)\n");
	printf("\t\t -m path\t\t Path to the modules.\n");
	printf("\t\t -f format\t\t fmtp to pass to the codec\n");
	printf("\t\t -p ptime\t\t ptime to use while encoding\n");
	printf("\t\t -r rate\t\t sampling rate\n");
	printf("\t\t -b bitrate\t\t codec bitrate (if supported)\n");
	printf("\t\t -v\t\t\t verbose\n");
	fs_encode_cleanup();
	return 1;
}