[mod_loopback] Add video support to null endpoint
* [mod_loopback] add video support to null channel * [core test] add video session support * [core] add video channel test case
This commit is contained in:
parent
60c4b62254
commit
90db5a9032
|
@ -484,9 +484,10 @@ static switch_status_t fst_init_core_and_modload(const char *confdir, const char
|
|||
*
|
||||
* @param name the name of this test
|
||||
* @param rate the rate of the channel
|
||||
* @param video_codec the rate of the channel
|
||||
*/
|
||||
|
||||
#define FST_SESSION_BEGIN_RATE(name, rate) \
|
||||
#define FST_SESSION_BEGIN_RATE_VIDEO(name, rate, video_codec) \
|
||||
FCT_TEST_BGN(name) \
|
||||
{ \
|
||||
if (fst_core) { \
|
||||
|
@ -513,7 +514,7 @@ static switch_status_t fst_init_core_and_modload(const char *confdir, const char
|
|||
fst_requires(switch_event_create_plain(&fst_originate_vars, SWITCH_EVENT_CHANNEL_DATA) == SWITCH_STATUS_SUCCESS); \
|
||||
switch_event_add_header_string(fst_originate_vars, SWITCH_STACK_BOTTOM, "origination_caller_id_number", "+15551112222"); \
|
||||
switch_event_add_header(fst_originate_vars, SWITCH_STACK_BOTTOM, "rate", "%d", rate); \
|
||||
if (switch_ivr_originate(NULL, &fst_session, &fst_cause, "null/+15553334444", 2, NULL, NULL, NULL, NULL, fst_originate_vars, SOF_NONE, NULL, NULL) == SWITCH_STATUS_SUCCESS && fst_session) { \
|
||||
if (switch_ivr_originate(NULL, &fst_session, &fst_cause, "{null_video_codec=" video_codec "}null/+15553334444", 2, NULL, NULL, NULL, NULL, fst_originate_vars, SOF_NONE, NULL, NULL) == SWITCH_STATUS_SUCCESS && fst_session) { \
|
||||
switch_memory_pool_t *fst_session_pool = switch_core_session_get_pool(fst_session); \
|
||||
switch_channel_t *fst_channel = switch_core_session_get_channel(fst_session); \
|
||||
switch_channel_set_state(fst_channel, CS_SOFT_EXECUTE); \
|
||||
|
@ -525,10 +526,11 @@ static switch_status_t fst_init_core_and_modload(const char *confdir, const char
|
|||
|
||||
/**
|
||||
* Define a session test in a test suite. This can be used to test IVR functions.
|
||||
* See FST_SESSION_BEGIN_RATE
|
||||
* See FST_SESSION_BEGIN_RATE_VIDEO
|
||||
*/
|
||||
|
||||
#define FST_SESSION_BEGIN(name) FST_SESSION_BEGIN_RATE(name, 8000)
|
||||
#define FST_SESSION_BEGIN_RATE(name, rate) FST_SESSION_BEGIN_RATE_VIDEO(name, rate, "")
|
||||
|
||||
/* BODY OF TEST CASE HERE */
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
*
|
||||
* Anthony Minessale II <anthm@freeswitch.org>
|
||||
* Emmanuel Schmidbauer <e.schmidbauer@gmail.com>
|
||||
* Seven Du <dujinfang@gmail.com>
|
||||
*
|
||||
*
|
||||
* mod_loopback.c -- Loopback Endpoint Module
|
||||
|
@ -1302,6 +1303,9 @@ struct null_private_object {
|
|||
switch_codec_t read_codec;
|
||||
switch_codec_t write_codec;
|
||||
switch_timer_t timer;
|
||||
switch_codec_t video_read_codec;
|
||||
switch_codec_t video_write_codec;
|
||||
switch_timer_t video_timer;
|
||||
switch_caller_profile_t *caller_profile;
|
||||
switch_frame_t read_frame;
|
||||
int16_t *null_buf;
|
||||
|
@ -1312,6 +1316,12 @@ struct null_private_object {
|
|||
int enable_auto_answer;
|
||||
/* auto_answer_delay (0 ms by default) */
|
||||
int auto_answer_delay;
|
||||
char *video_codec_name;
|
||||
switch_frame_t video_read_frame;
|
||||
uint8_t video_data[SWITCH_RECOMMENDED_BUFFER_SIZE];
|
||||
switch_image_t *img;
|
||||
switch_media_handle_t *media_handle;
|
||||
switch_core_media_params_t mparams;
|
||||
};
|
||||
|
||||
typedef struct null_private_object null_private_t;
|
||||
|
@ -1324,9 +1334,31 @@ static switch_call_cause_t null_channel_outgoing_channel(switch_core_session_t *
|
|||
switch_call_cause_t *cancel_cause);
|
||||
static switch_status_t null_channel_read_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id);
|
||||
static switch_status_t null_channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id);
|
||||
static switch_status_t null_channel_read_video_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id);
|
||||
static switch_status_t null_channel_write_video_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id);
|
||||
static switch_status_t null_channel_kill_channel(switch_core_session_t *session, int sig);
|
||||
|
||||
static void set_mparams(null_private_t *tech_pvt)
|
||||
{
|
||||
switch_core_media_params_t *mparams = &tech_pvt->mparams;
|
||||
|
||||
mparams->inbound_codec_string = "L16";
|
||||
mparams->outbound_codec_string = "L16";
|
||||
mparams->timer_name = "soft";
|
||||
mparams->extsipip = "10.0.0.1";
|
||||
mparams->extrtpip = "10.0.0.2";
|
||||
mparams->local_network = "127.0.0.1";
|
||||
mparams->sipip = "127.0.0.1";
|
||||
mparams->rtpip = "127.0.0.1";
|
||||
mparams->jb_msec = "60";
|
||||
mparams->rtcp_audio_interval_msec = "5000";
|
||||
mparams->rtcp_video_interval_msec = "5000";
|
||||
mparams->sdp_username = "FreeSWITCH";
|
||||
mparams->cng_pt = 13;
|
||||
mparams->rtp_timeout_sec = 300;
|
||||
mparams->rtp_hold_timeout_sec = 3600;
|
||||
mparams->external_video_source = 1;
|
||||
}
|
||||
|
||||
static switch_status_t null_tech_init(null_private_t *tech_pvt, switch_core_session_t *session)
|
||||
{
|
||||
|
@ -1364,6 +1396,43 @@ static switch_status_t null_tech_init(null_private_t *tech_pvt, switch_core_sess
|
|||
switch_core_session_set_read_codec(session, &tech_pvt->read_codec);
|
||||
switch_core_session_set_write_codec(session, &tech_pvt->write_codec);
|
||||
|
||||
if (!zstr(tech_pvt->video_codec_name)) {
|
||||
status = switch_core_codec_init(&tech_pvt->video_read_codec,
|
||||
tech_pvt->video_codec_name,
|
||||
NULL,
|
||||
NULL,
|
||||
90000, 0, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, switch_core_session_get_pool(session));
|
||||
|
||||
if (status != SWITCH_STATUS_SUCCESS || !tech_pvt->video_read_codec.implementation || !switch_core_codec_ready(&tech_pvt->video_read_codec)) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
status = switch_core_codec_init(&tech_pvt->video_write_codec,
|
||||
tech_pvt->video_codec_name,
|
||||
NULL,
|
||||
NULL,
|
||||
90000, 0, 0, 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->video_read_codec);
|
||||
goto end;
|
||||
}
|
||||
|
||||
switch_channel_set_flag(switch_core_session_get_channel(session), CF_VIDEO);
|
||||
switch_core_session_set_video_read_codec(session, &tech_pvt->read_codec);
|
||||
switch_core_session_set_video_write_codec(session, &tech_pvt->write_codec);
|
||||
switch_core_timer_init(&tech_pvt->video_timer, "soft", 100, 900, switch_core_session_get_pool(session));
|
||||
set_mparams(tech_pvt);
|
||||
switch_media_handle_create(&tech_pvt->media_handle, session, &tech_pvt->mparams);
|
||||
// switch_core_media_prepare_codecs(session, SWITCH_TRUE);
|
||||
// switch_core_media_check_video_codecs(session);
|
||||
// switch_core_media_choose_port(session, SWITCH_MEDIA_TYPE_AUDIO, 0);
|
||||
// switch_core_media_choose_port(session, SWITCH_MEDIA_TYPE_VIDEO, 0);
|
||||
// switch_core_media_gen_local_sdp(session, SDP_TYPE_REQUEST, "127.0.0.1", 2000, NULL, 0);
|
||||
// switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s\n", mparams.local_sdp_str);
|
||||
}
|
||||
|
||||
read_impl = tech_pvt->read_codec.implementation;
|
||||
|
||||
switch_core_timer_init(&tech_pvt->timer, "soft",
|
||||
|
@ -1419,8 +1488,20 @@ static switch_status_t null_channel_on_destroy(switch_core_session_t *session)
|
|||
if (switch_core_codec_ready(&tech_pvt->write_codec)) {
|
||||
switch_core_codec_destroy(&tech_pvt->write_codec);
|
||||
}
|
||||
|
||||
if (switch_core_codec_ready(&tech_pvt->video_read_codec)) {
|
||||
switch_core_codec_destroy(&tech_pvt->video_read_codec);
|
||||
}
|
||||
|
||||
if (switch_core_codec_ready(&tech_pvt->video_write_codec)) {
|
||||
switch_core_codec_destroy(&tech_pvt->video_write_codec);
|
||||
}
|
||||
|
||||
switch_img_free(&tech_pvt->img);
|
||||
}
|
||||
|
||||
switch_media_handle_destroy(session);
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -1558,6 +1639,50 @@ static switch_status_t null_channel_write_frame(switch_core_session_t *session,
|
|||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static switch_status_t null_channel_read_video_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id)
|
||||
{
|
||||
switch_channel_t *channel = NULL;
|
||||
null_private_t *tech_pvt = NULL;
|
||||
switch_status_t status = SWITCH_STATUS_FALSE;
|
||||
|
||||
channel = switch_core_session_get_channel(session);
|
||||
switch_assert(channel != NULL);
|
||||
|
||||
tech_pvt = switch_core_session_get_private(session);
|
||||
switch_assert(tech_pvt != NULL);
|
||||
|
||||
*frame = NULL;
|
||||
|
||||
if (!switch_channel_ready(channel)) {
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
switch_core_timer_next(&tech_pvt->video_timer);
|
||||
|
||||
tech_pvt->video_read_frame.codec = &tech_pvt->video_read_codec;
|
||||
tech_pvt->video_read_frame.datalen = 0;
|
||||
tech_pvt->video_read_frame.buflen = SWITCH_RECOMMENDED_BUFFER_SIZE;
|
||||
tech_pvt->video_read_frame.samples = 0;
|
||||
tech_pvt->video_read_frame.data = tech_pvt->video_data;
|
||||
if (!tech_pvt->img) {
|
||||
tech_pvt->img = switch_img_alloc(NULL, SWITCH_IMG_FMT_I420, 1280, 720, 0);
|
||||
}
|
||||
tech_pvt->video_read_frame.img = tech_pvt->img;
|
||||
*frame = &tech_pvt->video_read_frame;
|
||||
|
||||
if (*frame) {
|
||||
status = SWITCH_STATUS_SUCCESS;
|
||||
} else {
|
||||
status = SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
static switch_status_t null_channel_write_video_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id)
|
||||
{
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static switch_status_t null_channel_receive_message(switch_core_session_t *session, switch_core_session_message_t *msg)
|
||||
{
|
||||
switch_channel_t *channel;
|
||||
|
@ -1638,6 +1763,7 @@ static switch_call_cause_t null_channel_outgoing_channel(switch_core_session_t *
|
|||
|
||||
if ((tech_pvt = (null_private_t *) switch_core_session_alloc(*new_session, sizeof(null_private_t))) != 0) {
|
||||
const char *rate_ = switch_event_get_header(var_event, "rate");
|
||||
const char *video_codec = switch_event_get_header(var_event, "null_video_codec");
|
||||
int rate = 0;
|
||||
|
||||
if (rate_) {
|
||||
|
@ -1649,9 +1775,12 @@ static switch_call_cause_t null_channel_outgoing_channel(switch_core_session_t *
|
|||
}
|
||||
|
||||
tech_pvt->rate = rate;
|
||||
|
||||
tech_pvt->pre_answer = switch_true(pre_answer);
|
||||
|
||||
if (video_codec) {
|
||||
tech_pvt->video_codec_name = switch_core_session_strdup(*new_session, video_codec);
|
||||
}
|
||||
|
||||
if (!enable_auto_answer) {
|
||||
/* if not set - enabled by default */
|
||||
tech_pvt->enable_auto_answer = SWITCH_TRUE;
|
||||
|
@ -1733,7 +1862,15 @@ static switch_io_routines_t null_channel_io_routines = {
|
|||
/*.write_frame */ null_channel_write_frame,
|
||||
/*.kill_channel */ null_channel_kill_channel,
|
||||
/*.send_dtmf */ null_channel_send_dtmf,
|
||||
/*.receive_message */ null_channel_receive_message
|
||||
/*.receive_message */ null_channel_receive_message,
|
||||
/*.receive_event */ NULL,
|
||||
/*.state_change */ NULL,
|
||||
/*.read_video_frame */ null_channel_read_video_frame,
|
||||
/*.write_video_frame */ null_channel_write_video_frame,
|
||||
/*.read_text_frame */ NULL,
|
||||
/*.write_text_frame */ NULL,
|
||||
/*.state_run*/ NULL,
|
||||
/*.get_jb*/ NULL
|
||||
};
|
||||
|
||||
switch_status_t load_loopback_configuration(switch_bool_t reload)
|
||||
|
|
|
@ -763,6 +763,28 @@ FST_CORE_BEGIN("./conf")
|
|||
}
|
||||
FST_TEST_END()
|
||||
|
||||
FST_TEST_BEGIN(originate_test_video)
|
||||
{
|
||||
switch_core_session_t *session = NULL;
|
||||
switch_channel_t *channel = NULL;
|
||||
switch_status_t status;
|
||||
switch_call_cause_t cause;
|
||||
|
||||
status = switch_ivr_originate(NULL, &session, &cause, "{null_video_codec=VP8}null/+15553334444", 2, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL, NULL);
|
||||
fst_requires(session);
|
||||
fst_check(status == SWITCH_STATUS_SUCCESS);
|
||||
|
||||
channel = switch_core_session_get_channel(session);
|
||||
fst_requires(channel);
|
||||
fst_check(switch_channel_test_flag(channel, CF_VIDEO));
|
||||
switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
|
||||
fst_check(!switch_channel_ready(channel));
|
||||
|
||||
switch_core_session_rwunlock(session);
|
||||
switch_sleep(1000000);
|
||||
}
|
||||
FST_TEST_END()
|
||||
|
||||
FST_TEST_BEGIN(enterprise_originate_test_group_confirm_two_handles)
|
||||
{
|
||||
switch_core_session_t *session = NULL;
|
||||
|
|
Loading…
Reference in New Issue