mirror of
https://github.com/signalwire/freeswitch.git
synced 2026-11-14 05:18:31 +00:00
commit dbea6143d6b63765f2d0eba26728c3903d3d2606
Author: achaloyan <achaloyan@f001bc3a-424a-0410-80a0-a715b8f413a8>
Date: Wed Jul 8 17:37:24 2009 +0000
Added yet another buffer of media frames mpf_frame_buffer.
There are a number of similar buffers (mpf_jitter_buffer, mpf_buffer, mpf_frame_buffer). All of them produce mpf_frames as output, but input is somewhat dif
ferent. Input is RTP payload in case of mpf_jitter_buffer, synthesized chunks of voice in case of mpf_buffer, and mpf_frame in case of mpf_frame_buffer
git-svn-id: https://unimrcp.googlecode.com/svn/trunk@1043 f001bc3a-424a-0410-80a0-a715b8f413a8
commit 1bf7a66012180649bd1f01fd72e483a9e5de3495
Author: achaloyan <achaloyan@f001bc3a-424a-0410-80a0-a715b8f413a8>
Date: Wed Jul 8 16:33:36 2009 +0000
Fixed termination of client and server stacks (Issue-28)
Network client/server stacks generated double TERMINATE_COMPLETE event, while mpf engine generated no TERMINATE_COMPLETE event.
git-svn-id: https://unimrcp.googlecode.com/svn/trunk@1042 f001bc3a-424a-0410-80a0-a715b8f413a8
commit 0327cf17779430b51290d22cc7d51130f997f2f2
Author: achaloyan <achaloyan@f001bc3a-424a-0410-80a0-a715b8f413a8>
Date: Sun Jul 5 19:22:31 2009 +0000
Enhanced flite plugin to
- support more than one SPEAK requests in a session (SPEAK -> STOP -> SPEAK or SPEAK-> SPEAK-COMPLETE->SPEAK), task is created upon channel creation and is
waiting for consecutive SPEAK requests to process
- properly handle race between STOP request and SPEAK-COMPLETE event
- respond with IN-PROGRESS, when all the required parameters are checked to be valid and synthesizing is due to start
git-svn-id: https://unimrcp.googlecode.com/svn/trunk@1037 f001bc3a-424a-0410-80a0-a715b8f413a8
commit e2f73f9279e54ef3a40cb637a38ab1ff485ea5d3
Author: achaloyan <achaloyan@f001bc3a-424a-0410-80a0-a715b8f413a8>
Date: Sun Jul 5 03:46:13 2009 +0000
Separated flite voices (unified voice register/unregister routine, select voice by name)
git-svn-id: https://unimrcp.googlecode.com/svn/trunk@1036 f001bc3a-424a-0410-80a0-a715b8f413a8
commit 694783a527cb795ca45982c2388895da06dd6009
Author: achaloyan <achaloyan@f001bc3a-424a-0410-80a0-a715b8f413a8>
Date: Sat Jul 4 05:06:17 2009 +0000
Checked content-type to be "text/plain" as flite doesn't support SSML yet.
git-svn-id: https://unimrcp.googlecode.com/svn/trunk@1035 f001bc3a-424a-0410-80a0-a715b8f413a8
commit aafdc6e30e77c40e5470cce844f48ec28a254786
Author: achaloyan <achaloyan@f001bc3a-424a-0410-80a0-a715b8f413a8>
Date: Fri Jul 3 14:55:10 2009 +0000
Enhanced float value generation to use the precision (digits after decimal sign) user provides by removing optional trailing 0s (if any)
Issue-35
git-svn-id: https://unimrcp.googlecode.com/svn/trunk@1034 f001bc3a-424a-0410-80a0-a715b8f413a8
commit bcc2f137956f5c532c0256b064c8a3d1015a46d0
Author: achaloyan <achaloyan@f001bc3a-424a-0410-80a0-a715b8f413a8>
Date: Fri Jul 3 07:04:07 2009 +0000
Enhanced RTP port management (Issue-34, Thanks cpsoares)
git-svn-id: https://unimrcp.googlecode.com/svn/trunk@1033 f001bc3a-424a-0410-80a0-a715b8f413a8
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@14166 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
1 parent
72b4dfd6c1
commit
915fa372d8
16 files changed
+664
-294
No files matched your search
@@ -22,8 +22,6 @@
|
||||
* @brief Text Stream Parse/Generate Routine
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "apt_string.h"
|
||||
#include "apt_pair.h"
|
||||
|
||||
@@ -95,40 +93,17 @@ APT_DECLARE(apt_bool_t) apt_boolean_value_parse(const apt_str_t *str, apt_bool_t
|
||||
/** Generate boolean-value */
|
||||
APT_DECLARE(apt_bool_t) apt_boolean_value_generate(apt_bool_t value, apt_text_stream_t *str);
|
||||
|
||||
|
||||
/** Parse size_t value */
|
||||
static APR_INLINE apr_size_t apt_size_value_parse(const apt_str_t *str)
|
||||
{
|
||||
return str->buf ? atol(str->buf) : 0;
|
||||
}
|
||||
APT_DECLARE(apr_size_t) apt_size_value_parse(const apt_str_t *str);
|
||||
|
||||
/** Generate apr_size_t value */
|
||||
static APR_INLINE apt_bool_t apt_size_value_generate(apr_size_t value, apt_text_stream_t *stream)
|
||||
{
|
||||
int length = sprintf(stream->pos, "%"APR_SIZE_T_FMT, value);
|
||||
if(length <= 0) {
|
||||
return FALSE;
|
||||
}
|
||||
stream->pos += length;
|
||||
return TRUE;
|
||||
}
|
||||
APT_DECLARE(apt_bool_t) apt_size_value_generate(apr_size_t value, apt_text_stream_t *stream);
|
||||
|
||||
/** Parse float value */
|
||||
static APR_INLINE float apt_float_value_parse(const apt_str_t *str)
|
||||
{
|
||||
return str->buf ? (float)atof(str->buf) : 0;
|
||||
}
|
||||
APT_DECLARE(float) apt_float_value_parse(const apt_str_t *str);
|
||||
|
||||
/** Generate float value */
|
||||
static APR_INLINE apt_bool_t apt_float_value_generate(float value, apt_text_stream_t *stream)
|
||||
{
|
||||
int length = sprintf(stream->pos,"%.2f",value);
|
||||
if(length <= 0) {
|
||||
return FALSE;
|
||||
}
|
||||
stream->pos += length;
|
||||
return TRUE;
|
||||
}
|
||||
APT_DECLARE(apt_bool_t) apt_float_value_generate(float value, apt_text_stream_t *stream);
|
||||
|
||||
/** Generate string value */
|
||||
static APR_INLINE apt_bool_t apt_string_value_generate(const apt_str_t *str, apt_text_stream_t *stream)
|
||||
|
||||
@@ -300,8 +300,6 @@ static apt_bool_t apt_net_client_task_run(apt_task_t *base)
|
||||
}
|
||||
|
||||
apt_net_client_task_pollset_destroy(task);
|
||||
|
||||
apt_task_child_terminate(task->base);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
@@ -350,8 +350,6 @@ static apt_bool_t apt_net_server_task_run(apt_task_t *base)
|
||||
}
|
||||
|
||||
apt_net_server_task_pollset_destroy(task);
|
||||
|
||||
apt_task_child_terminate(task->base);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <apr_uuid.h>
|
||||
#include "apt_text_stream.h"
|
||||
|
||||
@@ -307,6 +309,45 @@ APT_DECLARE(apt_bool_t) apt_boolean_value_generate(apt_bool_t value, apt_text_st
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/** Parse size_t value */
|
||||
APT_DECLARE(apr_size_t) apt_size_value_parse(const apt_str_t *str)
|
||||
{
|
||||
return str->buf ? atol(str->buf) : 0;
|
||||
}
|
||||
|
||||
/** Generate apr_size_t value */
|
||||
APT_DECLARE(apt_bool_t) apt_size_value_generate(apr_size_t value, apt_text_stream_t *stream)
|
||||
{
|
||||
int length = sprintf(stream->pos, "%"APR_SIZE_T_FMT, value);
|
||||
if(length <= 0) {
|
||||
return FALSE;
|
||||
}
|
||||
stream->pos += length;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/** Parse float value */
|
||||
APT_DECLARE(float) apt_float_value_parse(const apt_str_t *str)
|
||||
{
|
||||
return str->buf ? (float)atof(str->buf) : 0;
|
||||
}
|
||||
|
||||
/** Generate float value */
|
||||
APT_DECLARE(apt_bool_t) apt_float_value_generate(float value, apt_text_stream_t *stream)
|
||||
{
|
||||
char *end;
|
||||
int length = sprintf(stream->pos,"%f",value);
|
||||
if(length <= 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* remove trailing 0s (if any) */
|
||||
end = stream->pos + length -1;
|
||||
while(*end == 0x30 && end != stream->pos) end--;
|
||||
|
||||
stream->pos = end + 1;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/** Generate value plus the length (number of digits) of the value itself. */
|
||||
APT_DECLARE(apt_bool_t) apt_var_length_value_generate(apr_size_t *value, apr_size_t max_count, apt_str_t *str)
|
||||
|
||||
@@ -20,6 +20,7 @@ include_HEADERS = codecs/g711/g711.h \
|
||||
include/mpf_context.h \
|
||||
include/mpf_engine.h \
|
||||
include/mpf_frame.h \
|
||||
include/mpf_frame_buffer.h \
|
||||
include/mpf_message.h \
|
||||
include/mpf_object.h \
|
||||
include/mpf_stream.h \
|
||||
@@ -55,6 +56,7 @@ libmpf_la_SOURCES = codecs/g711/g711.c \
|
||||
src/mpf_termination.c \
|
||||
src/mpf_rtp_termination_factory.c \
|
||||
src/mpf_file_termination_factory.c \
|
||||
src/mpf_frame_buffer.c \
|
||||
src/mpf_timer.c \
|
||||
src/mpf_encoder.c \
|
||||
src/mpf_decoder.c \
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright 2008 Arsen Chaloyan
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __MPF_FRAME_BUFFER_H__
|
||||
#define __MPF_FRAME_BUFFER_H__
|
||||
|
||||
/**
|
||||
* @file mpf_frame_buffer.h
|
||||
* @brief Buffer of Media Frames
|
||||
*/
|
||||
|
||||
#include "mpf_frame.h"
|
||||
|
||||
APT_BEGIN_EXTERN_C
|
||||
|
||||
/** Opaque frame buffer declaration */
|
||||
typedef struct mpf_frame_buffer_t mpf_frame_buffer_t;
|
||||
|
||||
|
||||
/** Create frame buffer */
|
||||
mpf_frame_buffer_t* mpf_frame_buffer_create(apr_size_t frame_size, apr_size_t frame_count, apr_pool_t *pool);
|
||||
|
||||
/** Destroy frame buffer */
|
||||
void mpf_frame_buffer_destroy(mpf_frame_buffer_t *buffer);
|
||||
|
||||
/** Restart frame buffer */
|
||||
apt_bool_t mpf_frame_buffer_restart(mpf_frame_buffer_t *buffer);
|
||||
|
||||
/** Write frame to buffer */
|
||||
apt_bool_t mpf_frame_buffer_write(mpf_frame_buffer_t *buffer, const mpf_frame_t *frame);
|
||||
|
||||
/** Read frame from buffer */
|
||||
apt_bool_t mpf_frame_buffer_read(mpf_frame_buffer_t *buffer, mpf_frame_t *frame);
|
||||
|
||||
APT_END_EXTERN_C
|
||||
|
||||
#endif /*__MPF_FRAME_BUFFER_H__*/
|
||||
@@ -207,6 +207,10 @@
|
||||
RelativePath=".\include\mpf_frame.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\include\mpf_frame_buffer.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\include\mpf_jitter_buffer.h"
|
||||
>
|
||||
@@ -332,6 +336,10 @@
|
||||
RelativePath=".\src\mpf_file_termination_factory.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\mpf_frame_buffer.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\mpf_jitter_buffer.c"
|
||||
>
|
||||
|
||||
@@ -128,6 +128,7 @@ static apt_bool_t mpf_engine_terminate(apt_task_t *task)
|
||||
|
||||
mpf_timer_stop(engine->timer);
|
||||
mpf_engine_contexts_destroy(engine);
|
||||
apt_task_child_terminate(task);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Copyright 2009 Arsen Chaloyan
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "mpf_frame_buffer.h"
|
||||
|
||||
struct mpf_frame_buffer_t {
|
||||
apr_byte_t *raw_data;
|
||||
mpf_frame_t *frames;
|
||||
apr_size_t frame_count;
|
||||
apr_size_t frame_size;
|
||||
|
||||
apr_size_t write_pos;
|
||||
apr_size_t read_pos;
|
||||
|
||||
apr_thread_mutex_t *guard;
|
||||
apr_pool_t *pool;
|
||||
};
|
||||
|
||||
|
||||
mpf_frame_buffer_t* mpf_frame_buffer_create(apr_size_t frame_size, apr_size_t frame_count, apr_pool_t *pool)
|
||||
{
|
||||
apr_size_t i;
|
||||
mpf_frame_buffer_t *buffer = apr_palloc(pool,sizeof(mpf_frame_buffer_t));
|
||||
|
||||
buffer->frame_size = frame_size;
|
||||
buffer->frame_count = frame_count;
|
||||
buffer->raw_data = apr_palloc(pool,buffer->frame_size*buffer->frame_count);
|
||||
buffer->frames = apr_palloc(pool,sizeof(mpf_frame_t)*buffer->frame_count);
|
||||
for(i=0; i<buffer->frame_count; i++) {
|
||||
buffer->frames[i].type = MEDIA_FRAME_TYPE_NONE;
|
||||
buffer->frames[i].codec_frame.buffer = buffer->raw_data + i*buffer->frame_size;
|
||||
}
|
||||
|
||||
buffer->write_pos = buffer->read_pos = 0;
|
||||
apr_thread_mutex_create(&buffer->guard,APR_THREAD_MUTEX_UNNESTED,pool);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
void mpf_frame_buffer_destroy(mpf_frame_buffer_t *buffer)
|
||||
{
|
||||
if(buffer->guard) {
|
||||
apr_thread_mutex_destroy(buffer->guard);
|
||||
buffer->guard = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
apt_bool_t mpf_frame_buffer_restart(mpf_frame_buffer_t *buffer)
|
||||
{
|
||||
buffer->write_pos = buffer->read_pos;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static APR_INLINE mpf_frame_t* mpf_frame_buffer_frame_get(mpf_frame_buffer_t *buffer, apr_size_t pos)
|
||||
{
|
||||
apr_size_t index = pos % buffer->frame_count;
|
||||
return &buffer->frames[index];
|
||||
}
|
||||
|
||||
apt_bool_t mpf_frame_buffer_write(mpf_frame_buffer_t *buffer, const mpf_frame_t *frame)
|
||||
{
|
||||
mpf_frame_t *write_frame;
|
||||
void *data = frame->codec_frame.buffer;
|
||||
apr_size_t size = frame->codec_frame.size;
|
||||
|
||||
apr_thread_mutex_lock(buffer->guard);
|
||||
while(buffer->write_pos - buffer->read_pos < buffer->frame_count && size >= buffer->frame_size) {
|
||||
write_frame = mpf_frame_buffer_frame_get(buffer,buffer->write_pos);
|
||||
write_frame->type = frame->type;
|
||||
write_frame->codec_frame.size = buffer->frame_size;
|
||||
memcpy(
|
||||
write_frame->codec_frame.buffer,
|
||||
data,
|
||||
write_frame->codec_frame.size);
|
||||
|
||||
data = (char*)data + buffer->frame_size;
|
||||
size -= buffer->frame_size;
|
||||
buffer->write_pos ++;
|
||||
}
|
||||
|
||||
apr_thread_mutex_unlock(buffer->guard);
|
||||
/* if size != 0 => non frame alligned or buffer is full */
|
||||
return size == 0 ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
apt_bool_t mpf_frame_buffer_read(mpf_frame_buffer_t *buffer, mpf_frame_t *media_frame)
|
||||
{
|
||||
apr_thread_mutex_lock(buffer->guard);
|
||||
if(buffer->write_pos > buffer->read_pos) {
|
||||
/* normal read */
|
||||
mpf_frame_t *src_media_frame = mpf_frame_buffer_frame_get(buffer,buffer->read_pos);
|
||||
media_frame->type = src_media_frame->type;
|
||||
if(media_frame->type & MEDIA_FRAME_TYPE_AUDIO) {
|
||||
media_frame->codec_frame.size = src_media_frame->codec_frame.size;
|
||||
memcpy(
|
||||
media_frame->codec_frame.buffer,
|
||||
src_media_frame->codec_frame.buffer,
|
||||
media_frame->codec_frame.size);
|
||||
}
|
||||
if(media_frame->type & MEDIA_FRAME_TYPE_EVENT) {
|
||||
media_frame->event_frame = src_media_frame->event_frame;
|
||||
}
|
||||
src_media_frame->type = MEDIA_FRAME_TYPE_NONE;
|
||||
buffer->read_pos ++;
|
||||
}
|
||||
else {
|
||||
/* underflow */
|
||||
media_frame->type = MEDIA_FRAME_TYPE_NONE;
|
||||
}
|
||||
apr_thread_mutex_unlock(buffer->guard);
|
||||
return TRUE;
|
||||
}
|
||||
@@ -83,21 +83,6 @@ MPF_DECLARE(mpf_audio_stream_t*) mpf_rtp_stream_create(mpf_termination_t *termin
|
||||
return rtp_stream->base;
|
||||
}
|
||||
|
||||
static void mpf_rtp_stream_ip_port_set(mpf_rtp_media_descriptor_t *media, mpf_rtp_config_t *config)
|
||||
{
|
||||
if(media->base.ip.length == 0) {
|
||||
media->base.ip = config->ip;
|
||||
media->base.ext_ip = config->ext_ip;
|
||||
}
|
||||
if(media->base.port == 0) {
|
||||
media->base.port = config->rtp_port_cur;
|
||||
config->rtp_port_cur += 2;
|
||||
if(config->rtp_port_cur == config->rtp_port_max) {
|
||||
config->rtp_port_cur = config->rtp_port_min;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static apt_bool_t mpf_rtp_stream_local_media_create(mpf_rtp_stream_t *rtp_stream, mpf_rtp_media_descriptor_t *local_media, mpf_rtp_media_descriptor_t *remote_media)
|
||||
{
|
||||
apt_bool_t status = TRUE;
|
||||
@@ -111,9 +96,31 @@ static apt_bool_t mpf_rtp_stream_local_media_create(mpf_rtp_stream_t *rtp_stream
|
||||
if(remote_media) {
|
||||
local_media->base.id = remote_media->base.id;
|
||||
}
|
||||
if(local_media->base.ip.length == 0) {
|
||||
local_media->base.ip = rtp_stream->config->ip;
|
||||
local_media->base.ext_ip = rtp_stream->config->ext_ip;
|
||||
}
|
||||
if(local_media->base.port == 0) {
|
||||
/* RTP port management */
|
||||
apr_port_t first_port_in_search = rtp_stream->config->rtp_port_cur;
|
||||
apt_bool_t is_port_ok = FALSE;
|
||||
|
||||
mpf_rtp_stream_ip_port_set(local_media,rtp_stream->config);
|
||||
if(mpf_rtp_socket_create(rtp_stream,local_media) == FALSE) {
|
||||
do {
|
||||
local_media->base.port = rtp_stream->config->rtp_port_cur;
|
||||
rtp_stream->config->rtp_port_cur += 2;
|
||||
if(rtp_stream->config->rtp_port_cur == rtp_stream->config->rtp_port_max) {
|
||||
rtp_stream->config->rtp_port_cur = rtp_stream->config->rtp_port_min;
|
||||
}
|
||||
if(mpf_rtp_socket_create(rtp_stream,local_media) == TRUE) {
|
||||
is_port_ok = TRUE;
|
||||
}
|
||||
} while((is_port_ok == FALSE) && (first_port_in_search != rtp_stream->config->rtp_port_cur));
|
||||
if(is_port_ok == FALSE) {
|
||||
local_media->base.state = MPF_MEDIA_DISABLED;
|
||||
status = FALSE;
|
||||
}
|
||||
}
|
||||
else if(mpf_rtp_socket_create(rtp_stream,local_media) == FALSE) {
|
||||
local_media->base.state = MPF_MEDIA_DISABLED;
|
||||
status = FALSE;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user