mirror of
https://github.com/signalwire/freeswitch.git
synced 2025-04-20 10:26:51 +00:00
FS-10126: [freeswitch-core] General Video Improvements #resolve
Conflicts: src/include/switch_core.h src/include/switch_types.h src/mod/applications/mod_conference/conference_file.c src/mod/applications/mod_conference/conference_video.c src/mod/languages/mod_managed/managed/swig.cs src/switch_core_media.c src/switch_ivr_bridge.c src/switch_rtp.c
This commit is contained in:
parent
3da6bd0108
commit
35b3e9a6a0
@ -1274,6 +1274,9 @@ SWITCH_DECLARE(uint32_t) switch_core_session_private_event_count(_In_ switch_cor
|
||||
SWITCH_DECLARE(switch_status_t) switch_core_session_dequeue_private_event(_In_ switch_core_session_t *session, _Out_ switch_event_t **event);
|
||||
|
||||
|
||||
SWITCH_DECLARE(switch_bool_t) switch_core_session_transcoding(switch_core_session_t *session_a, switch_core_session_t *session_b, switch_media_type_t type);
|
||||
SWITCH_DECLARE(void) switch_core_session_passthru(switch_core_session_t *session, switch_media_type_t type, switch_bool_t on);
|
||||
|
||||
/*!
|
||||
\brief Flush the private event queue of a session
|
||||
\param session the session to flush
|
||||
|
@ -207,6 +207,7 @@ struct switch_timer {
|
||||
unsigned int samples;
|
||||
/*! current sample count based on samples parameter */
|
||||
uint32_t samplecount;
|
||||
uint32_t last_samplecount;
|
||||
/*! the timer interface provided from a loadable module */
|
||||
switch_timer_interface_t *timer_interface;
|
||||
/*! the timer's memory pool */
|
||||
|
@ -770,8 +770,6 @@ typedef enum {
|
||||
SWITCH_RTP_FLAG_MUTE,
|
||||
SWITCH_RTP_FLAG_NACK,
|
||||
SWITCH_RTP_FLAG_TMMBR,
|
||||
SWITCH_RTP_FLAG_GEN_TS_DELTA,
|
||||
SWITCH_RTP_FLAG_GEN_TS_MANUAL,
|
||||
SWITCH_RTP_FLAG_DETECT_SSRC,
|
||||
SWITCH_RTP_FLAG_OLD_FIR,
|
||||
SWITCH_RTP_FLAG_PASSTHRU,
|
||||
@ -905,7 +903,6 @@ typedef enum {
|
||||
|
||||
*/
|
||||
|
||||
|
||||
} switch_rtp_bug_flag_t;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
@ -1530,6 +1527,8 @@ typedef struct switch_vid_params_s {
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
uint32_t fps;
|
||||
uint32_t d_width;
|
||||
uint32_t d_height;
|
||||
} switch_vid_params_t;
|
||||
|
||||
|
||||
|
@ -41,42 +41,25 @@
|
||||
*/
|
||||
#include <mod_conference.h>
|
||||
|
||||
static struct conference_fps FPS_VALS[] = {
|
||||
{1.0f, 1000, 90},
|
||||
{5.0f, 200, 450},
|
||||
{10.0f, 100, 900},
|
||||
{15.0f, 66, 1364},
|
||||
{16.60f, 60, 1500},
|
||||
{20.0f, 50, 4500},
|
||||
{25.0f, 40, 2250},
|
||||
{30.0f, 33, 2700},
|
||||
{33.0f, 30, 2790},
|
||||
{66.60f, 15, 6000},
|
||||
{100.0f, 10, 9000},
|
||||
{0,0,0}
|
||||
};
|
||||
|
||||
|
||||
int conference_video_set_fps(conference_obj_t *conference, float fps)
|
||||
{
|
||||
uint32_t i = 0, j = 0;
|
||||
uint32_t j = 0;
|
||||
|
||||
for (i = 0; FPS_VALS[i].ms; i++) {
|
||||
if (FPS_VALS[i].fps == fps) {
|
||||
if (fps > 100) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
conference->video_fps = FPS_VALS[i];
|
||||
conference->video_fps.fps = fps;
|
||||
conference->video_fps.ms = (int) 1000 / fps;
|
||||
conference->video_fps.samples = (int) 90000 / conference->video_fps.ms;
|
||||
|
||||
for (j = 0; j <= conference->canvas_count; j++) {
|
||||
if (conference->canvases[j]) {
|
||||
conference->canvases[j]->video_timer_reset = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
for (j = 0; j <= conference->canvas_count; j++) {
|
||||
if (conference->canvases[j]) {
|
||||
conference->canvases[j]->video_timer_reset = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@ -1312,7 +1295,7 @@ void conference_video_write_canvas_image_to_codec_group(conference_obj_t *confer
|
||||
}
|
||||
|
||||
if (frame->timestamp) {
|
||||
switch_set_flag(frame, SFF_RAW_RTP_PARSE_FRAME);
|
||||
switch_set_flag(frame, SFF_RAW_RTP_PARSE_FRAME|SFF_USE_VIDEO_TIMESTAMP);
|
||||
}
|
||||
|
||||
frame->packetlen = frame->datalen + 12;
|
||||
@ -1342,7 +1325,9 @@ void conference_video_write_canvas_image_to_codec_group(conference_obj_t *confer
|
||||
switch_core_session_request_video_refresh(imember->session);
|
||||
}
|
||||
|
||||
if (switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_RECVONLY || switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_INACTIVE) {
|
||||
if (switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_RECVONLY ||
|
||||
switch_channel_test_flag(imember->channel, CF_VIDEO_WRITING) ||
|
||||
switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_INACTIVE) {
|
||||
switch_core_session_rwunlock(imember->session);
|
||||
continue;
|
||||
}
|
||||
@ -2996,6 +2981,7 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr
|
||||
|
||||
if (!imember->rec &&
|
||||
(!imember->session || !switch_channel_test_flag(imember->channel, CF_VIDEO_READY) || !imember->canvas ||
|
||||
switch_channel_test_flag(imember->channel, CF_VIDEO_WRITING) ||
|
||||
switch_core_session_read_lock(imember->session) != SWITCH_STATUS_SUCCESS)) {
|
||||
continue;
|
||||
}
|
||||
@ -3196,7 +3182,9 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr
|
||||
switch_core_session_request_video_refresh(imember->session);
|
||||
}
|
||||
|
||||
if (switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_RECVONLY || switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_INACTIVE) {
|
||||
if (switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_RECVONLY ||
|
||||
switch_channel_test_flag(imember->channel, CF_VIDEO_WRITING) ||
|
||||
switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_INACTIVE) {
|
||||
switch_core_session_rwunlock(imember->session);
|
||||
continue;
|
||||
}
|
||||
@ -3206,13 +3194,14 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr
|
||||
switch_core_media_gen_key_frame(imember->session);
|
||||
}
|
||||
|
||||
switch_set_flag(&write_frame, SFF_RAW_RTP);
|
||||
switch_set_flag(&write_frame, SFF_RAW_RTP|SFF_USE_VIDEO_TIMESTAMP|SFF_RAW_RTP_PARSE_FRAME);
|
||||
write_frame.img = write_img;
|
||||
write_frame.packet = packet;
|
||||
write_frame.data = ((uint8_t *)packet) + 12;
|
||||
write_frame.datalen = 0;
|
||||
write_frame.buflen = SWITCH_RTP_MAX_BUF_LEN - 12;
|
||||
write_frame.packetlen = 0;
|
||||
write_frame.timestamp = timestamp;
|
||||
|
||||
//switch_core_session_write_video_frame(imember->session, &write_frame, SWITCH_IO_FLAG_NONE, 0);
|
||||
|
||||
@ -3545,7 +3534,9 @@ void *SWITCH_THREAD_FUNC conference_video_super_muxing_thread_run(switch_thread_
|
||||
switch_core_session_request_video_refresh(imember->session);
|
||||
}
|
||||
|
||||
if (switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_RECVONLY || switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_INACTIVE) {
|
||||
if (switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_RECVONLY ||
|
||||
switch_channel_test_flag(imember->channel, CF_VIDEO_WRITING) ||
|
||||
switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_INACTIVE) {
|
||||
switch_core_session_rwunlock(imember->session);
|
||||
continue;
|
||||
}
|
||||
|
@ -53,7 +53,8 @@ static void gen_ice(switch_core_session_t *session, switch_media_type_t type, co
|
||||
typedef enum {
|
||||
SMF_INIT = (1 << 0),
|
||||
SMF_READY = (1 << 1),
|
||||
SMF_JB_PAUSED = (1 << 2)
|
||||
SMF_JB_PAUSED = (1 << 2),
|
||||
SMF_VB_PAUSED = (1 << 3)
|
||||
} smh_flag_t;
|
||||
|
||||
|
||||
@ -173,6 +174,7 @@ typedef struct switch_rtp_engine_s {
|
||||
switch_media_flow_t rmode;
|
||||
switch_media_flow_t smode;
|
||||
switch_thread_id_t thread_id;
|
||||
switch_thread_id_t thread_write_lock;
|
||||
uint8_t new_ice;
|
||||
uint8_t new_dtls;
|
||||
uint32_t sdp_bw;
|
||||
@ -2651,6 +2653,11 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_write_frame(switch_core_sessio
|
||||
|
||||
engine = &smh->engines[type];
|
||||
|
||||
if (type == SWITCH_MEDIA_TYPE_VIDEO) {
|
||||
if (engine->thread_write_lock && engine->thread_write_lock != switch_thread_self()) {
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
if (switch_channel_test_flag(session->channel, CF_VIDEO_ONLY) && type == SWITCH_MEDIA_TYPE_AUDIO) {
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
@ -5390,7 +5397,7 @@ SWITCH_DECLARE(switch_file_handle_t *) switch_core_media_get_video_file(switch_c
|
||||
return fh;
|
||||
}
|
||||
|
||||
static void switch_core_session_write_blank_video(switch_core_session_t *session, uint32_t ms)
|
||||
SWITCH_DECLARE(void) switch_core_session_write_blank_video(switch_core_session_t *session, uint32_t ms)
|
||||
{
|
||||
switch_frame_t fr = { 0 };
|
||||
int i = 0;
|
||||
@ -5446,6 +5453,20 @@ static void switch_core_session_write_blank_video(switch_core_session_t *session
|
||||
|
||||
}
|
||||
|
||||
typedef struct core_fps_s {
|
||||
float fps;
|
||||
int ms;
|
||||
int samples;
|
||||
} core_fps_t;
|
||||
|
||||
static int video_get_fps(core_fps_t *fpsP, float fps)
|
||||
{
|
||||
fpsP->fps = fps;
|
||||
fpsP->ms = (int) 1000 / fps;
|
||||
fpsP->samples = (int) 90000 / fpsP->ms;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void *SWITCH_THREAD_FUNC video_write_thread(switch_thread_t *thread, void *obj)
|
||||
{
|
||||
@ -5457,9 +5478,11 @@ static void *SWITCH_THREAD_FUNC video_write_thread(switch_thread_t *thread, void
|
||||
int buflen = SWITCH_RTP_MAX_BUF_LEN;
|
||||
switch_timer_t timer = { 0 };
|
||||
int fps;
|
||||
switch_video_read_flag_t read_flags = SVR_FLUSH|SVR_BLOCK;
|
||||
switch_video_read_flag_t read_flags = SVR_FLUSH;
|
||||
switch_core_session_t *b_session = NULL;
|
||||
|
||||
core_fps_t fps_data = { 0 };
|
||||
switch_image_t *last_frame = NULL;
|
||||
|
||||
if (switch_core_session_read_lock(session) != SWITCH_STATUS_SUCCESS) {
|
||||
return NULL;
|
||||
}
|
||||
@ -5478,7 +5501,10 @@ static void *SWITCH_THREAD_FUNC video_write_thread(switch_thread_t *thread, void
|
||||
|
||||
v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO];
|
||||
|
||||
switch_mutex_lock(smh->write_mutex[SWITCH_MEDIA_TYPE_VIDEO]);
|
||||
v_engine->thread_write_lock = switch_thread_self();
|
||||
|
||||
|
||||
buf = switch_core_session_alloc(session, buflen);
|
||||
fr.packet = buf;
|
||||
fr.packetlen = buflen;
|
||||
@ -5498,7 +5524,8 @@ static void *SWITCH_THREAD_FUNC video_write_thread(switch_thread_t *thread, void
|
||||
}
|
||||
|
||||
|
||||
switch_core_timer_init(&timer, "soft", (int)(1000 / fps) , 1, switch_core_session_get_pool(session));
|
||||
video_get_fps(&fps_data, fps);
|
||||
switch_core_timer_init(&timer, "soft", (int)(1000 / fps) , fps_data.samples, switch_core_session_get_pool(session));
|
||||
|
||||
while (smh->video_write_thread_running > 0 &&
|
||||
switch_channel_up_nosig(session->channel) && smh->video_write_fh && switch_test_flag(smh->video_write_fh, SWITCH_FILE_OPEN)) {
|
||||
@ -5509,15 +5536,27 @@ static void *SWITCH_THREAD_FUNC video_write_thread(switch_thread_t *thread, void
|
||||
|
||||
if (smh->video_write_fh && smh->video_write_fh->mm.source_fps && smh->video_write_fh->mm.source_fps != fps) {
|
||||
switch_core_timer_destroy(&timer);
|
||||
switch_core_timer_init(&timer, "soft", (int)(1000 / fps) , 1, switch_core_session_get_pool(session));
|
||||
video_get_fps(&fps_data, fps);
|
||||
switch_core_timer_init(&timer, "soft", (int)(1000 / fps) , fps_data.samples, switch_core_session_get_pool(session));
|
||||
}
|
||||
|
||||
if (smh->video_write_fh && !switch_test_flag(smh->video_write_fh, SWITCH_FILE_FLAG_VIDEO_EOF)) {
|
||||
wstatus = switch_core_file_read_video(smh->video_write_fh, &fr, read_flags);
|
||||
|
||||
if (wstatus == SWITCH_STATUS_SUCCESS) {
|
||||
switch_core_session_write_video_frame(session, &fr, SWITCH_IO_FLAG_FORCE, SVR_FLUSH);
|
||||
switch_img_free(&fr.img);
|
||||
fr.timestamp = timer.samplecount;
|
||||
fr.flags = SFF_USE_VIDEO_TIMESTAMP|SFF_RAW_RTP|SFF_RAW_RTP_PARSE_FRAME;
|
||||
|
||||
if (smh->vid_params.d_width && smh->vid_params.d_height) {
|
||||
switch_img_fit(&fr.img, smh->vid_params.d_width, smh->vid_params.d_height, SWITCH_FIT_SIZE);
|
||||
}
|
||||
|
||||
switch_core_session_write_video_frame(session, &fr, SWITCH_IO_FLAG_FORCE, 0);
|
||||
|
||||
switch_img_free(&last_frame);
|
||||
last_frame = fr.img;
|
||||
fr.img = NULL;
|
||||
|
||||
} else if (wstatus != SWITCH_STATUS_BREAK && wstatus != SWITCH_STATUS_IGNORE) {
|
||||
switch_set_flag_locked(smh->video_write_fh, SWITCH_FILE_FLAG_VIDEO_EOF);
|
||||
}
|
||||
@ -5525,6 +5564,25 @@ static void *SWITCH_THREAD_FUNC video_write_thread(switch_thread_t *thread, void
|
||||
switch_mutex_unlock(v_engine->mh.file_write_mutex);
|
||||
}
|
||||
|
||||
if (last_frame) {
|
||||
int x = 0;
|
||||
switch_rgb_color_t bgcolor;
|
||||
switch_color_set_rgb(&bgcolor, "#000000");
|
||||
switch_img_fill(last_frame, 0, 0, last_frame->d_w, last_frame->d_h, &bgcolor);
|
||||
fr.img = last_frame;
|
||||
|
||||
for (x = 0; x < fps / 2; x++) {
|
||||
switch_core_timer_next(&timer);
|
||||
fr.timestamp = timer.samplecount;
|
||||
fr.flags = SFF_USE_VIDEO_TIMESTAMP|SFF_RAW_RTP|SFF_RAW_RTP_PARSE_FRAME;
|
||||
switch_core_session_write_video_frame(session, &fr, SWITCH_IO_FLAG_FORCE, 0);
|
||||
}
|
||||
switch_core_media_gen_key_frame(session);
|
||||
switch_core_session_request_video_refresh(session);
|
||||
switch_img_free(&last_frame);
|
||||
}
|
||||
|
||||
|
||||
switch_core_timer_destroy(&timer);
|
||||
|
||||
switch_core_session_rwunlock(session);
|
||||
@ -5534,6 +5592,10 @@ static void *SWITCH_THREAD_FUNC video_write_thread(switch_thread_t *thread, void
|
||||
switch_core_session_rwunlock(b_session);
|
||||
}
|
||||
|
||||
|
||||
v_engine->thread_write_lock = 0;
|
||||
switch_mutex_unlock(smh->write_mutex[SWITCH_MEDIA_TYPE_VIDEO]);
|
||||
|
||||
switch_channel_clear_flag(session->channel, CF_VIDEO_WRITING);
|
||||
smh->video_write_thread_running = 0;
|
||||
|
||||
@ -5675,7 +5737,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_set_video_file(switch_core_ses
|
||||
|
||||
if (fh) {
|
||||
switch_threadattr_t *thd_attr = NULL;
|
||||
switch_core_session_write_blank_video(session, 500);
|
||||
//switch_core_session_write_blank_video(session, 500);
|
||||
switch_threadattr_create(&thd_attr, switch_core_session_get_pool(session));
|
||||
switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
|
||||
smh->video_write_thread_running = 1;
|
||||
@ -5692,7 +5754,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_set_video_file(switch_core_ses
|
||||
switch_thread_join(&st, smh->video_write_thread);
|
||||
switch_mutex_lock(v_engine->mh.file_write_mutex);
|
||||
smh->video_write_thread = NULL;
|
||||
switch_core_session_write_blank_video(session, 500);
|
||||
//switch_core_session_write_blank_video(session, 500);
|
||||
}
|
||||
|
||||
smh->video_write_fh = fh;
|
||||
@ -6887,11 +6949,6 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi
|
||||
}
|
||||
|
||||
|
||||
if ((val = switch_channel_get_variable(session->channel, "rtp_gen_ts_delta_audio")) && switch_true(val)) {
|
||||
flags[SWITCH_RTP_FLAG_GEN_TS_MANUAL] = 1;
|
||||
flags[SWITCH_RTP_FLAG_GEN_TS_DELTA] = 1;
|
||||
}
|
||||
|
||||
if (switch_channel_up(session->channel)) {
|
||||
switch_channel_set_variable(session->channel, "rtp_use_timer_name", timer_name);
|
||||
|
||||
@ -7292,11 +7349,6 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi
|
||||
flags[SWITCH_RTP_FLAG_AUTOADJ]++;
|
||||
}
|
||||
|
||||
if ((val = switch_channel_get_variable(session->channel, "rtp_gen_ts_delta_video")) && switch_true(val)) {
|
||||
flags[SWITCH_RTP_FLAG_GEN_TS_MANUAL] = 1;
|
||||
flags[SWITCH_RTP_FLAG_GEN_TS_DELTA] = 1;
|
||||
}
|
||||
|
||||
if (switch_channel_test_flag(session->channel, CF_PROXY_MEDIA)) {
|
||||
flags[SWITCH_RTP_FLAG_PROXY_MEDIA]++;
|
||||
}
|
||||
@ -10034,8 +10086,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_receive_message(switch_core_se
|
||||
const char *val;
|
||||
int ok = 0;
|
||||
|
||||
if (!switch_channel_test_flag(session->channel, CF_VIDEO) &&
|
||||
(!(val = switch_channel_get_variable(session->channel, "rtp_jitter_buffer_during_bridge")) || switch_false(val))) {
|
||||
if ((!(val = switch_channel_get_variable(session->channel, "rtp_jitter_buffer_during_bridge")) || switch_false(val))) {
|
||||
if (switch_channel_test_flag(session->channel, CF_JITTERBUFFER) && switch_channel_test_cap_partner(session->channel, CC_FS_RTP)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
|
||||
"%s PAUSE Jitterbuffer\n", switch_channel_get_name(session->channel));
|
||||
@ -10089,6 +10140,20 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_receive_message(switch_core_se
|
||||
}
|
||||
goto end;
|
||||
case SWITCH_MESSAGE_INDICATE_UNBRIDGE:
|
||||
|
||||
#if 0
|
||||
if (switch_rtp_ready(v_engine->rtp_session)) {
|
||||
|
||||
if (switch_test_flag(smh, SMF_VB_PAUSED)) {
|
||||
switch_clear_flag(smh, SMF_VB_PAUSED);
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
|
||||
"%s RESUME Video Jitterbuffer\n", switch_channel_get_name(session->channel));
|
||||
switch_rtp_pause_jitter_buffer(v_engine->rtp_session, SWITCH_FALSE);
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (switch_rtp_ready(a_engine->rtp_session)) {
|
||||
|
||||
if (switch_test_flag(smh, SMF_JB_PAUSED)) {
|
||||
@ -11694,8 +11759,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_video_frame(switch_cor
|
||||
switch_image_t *dup_img = NULL, *img = frame->img;
|
||||
switch_status_t encode_status;
|
||||
switch_frame_t write_frame = {0};
|
||||
switch_rtp_engine_t *v_engine;
|
||||
|
||||
switch_rtp_engine_t *v_engine = NULL;
|
||||
switch_assert(session);
|
||||
|
||||
if (!(smh = session->media_handle)) {
|
||||
@ -11711,9 +11775,6 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_video_frame(switch_cor
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
if (switch_channel_test_flag(session->channel, CF_VIDEO_WRITING) && !(flags & SWITCH_IO_FLAG_FORCE)) {
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
if (switch_core_session_media_flow(session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_RECVONLY || switch_core_session_media_flow(session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_INACTIVE) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG3, "Writing video to RECVONLY/INACTIVE session\n");
|
||||
@ -11736,6 +11797,11 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_video_frame(switch_cor
|
||||
return SWITCH_STATUS_INUSE;
|
||||
}
|
||||
|
||||
v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO];
|
||||
if (v_engine->thread_write_lock && v_engine->thread_write_lock != switch_thread_self()) {
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
if (!smh->video_init && smh->mparams->video_key_first && (now - smh->video_last_key_time) > smh->mparams->video_key_first) {
|
||||
switch_core_media_gen_key_frame(session);
|
||||
|
||||
@ -11753,17 +11819,9 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_video_frame(switch_cor
|
||||
|
||||
if (!img) {
|
||||
switch_status_t vstatus;
|
||||
|
||||
if (!switch_rtp_test_flag(v_engine->rtp_session, SWITCH_RTP_FLAG_GEN_TS_MANUAL)) {
|
||||
switch_rtp_set_flag(v_engine->rtp_session, SWITCH_RTP_FLAG_GEN_TS_DELTA);
|
||||
}
|
||||
|
||||
vstatus = switch_core_session_write_encoded_video_frame(session, frame, flags, stream_id);
|
||||
switch_goto_status(vstatus, done);
|
||||
} else {
|
||||
if (!switch_rtp_test_flag(v_engine->rtp_session, SWITCH_RTP_FLAG_GEN_TS_MANUAL)) {
|
||||
switch_rtp_clear_flag(v_engine->rtp_session, SWITCH_RTP_FLAG_GEN_TS_DELTA);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -11776,6 +11834,11 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_video_frame(switch_cor
|
||||
|
||||
img = dup_img;
|
||||
}
|
||||
|
||||
if (!switch_channel_test_flag(session->channel, CF_VIDEO_WRITING)) {
|
||||
smh->vid_params.d_width = img->d_w;
|
||||
smh->vid_params.d_height = img->d_h;
|
||||
}
|
||||
|
||||
if (session->bugs) {
|
||||
switch_media_bug_t *bp;
|
||||
@ -11949,6 +12012,53 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_wait_for_video_input_params(
|
||||
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(switch_bool_t) switch_core_session_transcoding(switch_core_session_t *session_a, switch_core_session_t *session_b, switch_media_type_t type)
|
||||
{
|
||||
switch_bool_t transcoding = SWITCH_FALSE;
|
||||
|
||||
switch(type) {
|
||||
case SWITCH_MEDIA_TYPE_AUDIO:
|
||||
transcoding = (session_a->read_codec->implementation->impl_id != session_b->read_codec->implementation->impl_id || session_a->read_impl.decoded_bytes_per_packet != session_b->read_impl.decoded_bytes_per_packet);
|
||||
break;
|
||||
case SWITCH_MEDIA_TYPE_VIDEO:
|
||||
transcoding = (switch_channel_test_flag(session_a->channel, CF_VIDEO_DECODED_READ) ||
|
||||
switch_channel_test_flag(session_b->channel, CF_VIDEO_DECODED_READ));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return transcoding;
|
||||
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(void) switch_core_session_passthru(switch_core_session_t *session, switch_media_type_t type, switch_bool_t on)
|
||||
{
|
||||
switch_rtp_engine_t *engine;
|
||||
|
||||
if (!session->media_handle) return;
|
||||
|
||||
engine = &session->media_handle->engines[type];
|
||||
|
||||
|
||||
if (switch_rtp_ready(engine->rtp_session)) {
|
||||
if (on) {
|
||||
switch_rtp_set_flag(engine->rtp_session, SWITCH_RTP_FLAG_PASSTHRU);
|
||||
} else {
|
||||
switch_rtp_clear_flag(engine->rtp_session, SWITCH_RTP_FLAG_PASSTHRU);
|
||||
}
|
||||
|
||||
if (type == SWITCH_MEDIA_TYPE_VIDEO) {
|
||||
switch_core_session_request_video_refresh(session);
|
||||
if (!on) {
|
||||
switch_core_media_gen_key_frame(session);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_core_session_read_video_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags,
|
||||
int stream_id)
|
||||
{
|
||||
|
@ -55,6 +55,7 @@ static void video_bridge_thread(switch_core_session_t *session, void *obj)
|
||||
switch_frame_t *read_frame = 0;
|
||||
int set_decoded_read = 0, refresh_timer = 0;
|
||||
int refresh_cnt = 300;
|
||||
int pass_val = 0, last_pass_val = 0;
|
||||
|
||||
vh->up = 1;
|
||||
|
||||
@ -78,8 +79,18 @@ static void video_bridge_thread(switch_core_session_t *session, void *obj)
|
||||
if (switch_channel_media_up(channel)) {
|
||||
switch_codec_t *a_codec = switch_core_session_get_video_read_codec(vh->session_a);
|
||||
switch_codec_t *b_codec = switch_core_session_get_video_write_codec(vh->session_b);
|
||||
|
||||
if (switch_core_session_transcoding(vh->session_a, vh->session_b, SWITCH_MEDIA_TYPE_VIDEO)) {
|
||||
pass_val = 1;
|
||||
} else {
|
||||
pass_val = 2;
|
||||
}
|
||||
|
||||
|
||||
if (pass_val != last_pass_val) {
|
||||
switch_core_session_passthru(session, SWITCH_MEDIA_TYPE_VIDEO, pass_val == 2 ? SWITCH_TRUE : SWITCH_FALSE);
|
||||
last_pass_val = pass_val;
|
||||
}
|
||||
|
||||
if (switch_channel_test_flag(channel, CF_VIDEO_REFRESH_REQ)) {
|
||||
switch_channel_clear_flag(channel, CF_VIDEO_REFRESH_REQ);
|
||||
refresh_timer = refresh_cnt;
|
||||
@ -146,6 +157,8 @@ static void video_bridge_thread(switch_core_session_t *session, void *obj)
|
||||
switch_core_session_request_video_refresh(vh->session_a);
|
||||
switch_core_session_request_video_refresh(vh->session_b);
|
||||
|
||||
switch_core_session_passthru(vh->session_a, SWITCH_MEDIA_TYPE_VIDEO, SWITCH_FALSE);
|
||||
|
||||
switch_core_session_rwunlock(vh->session_a);
|
||||
switch_core_session_rwunlock(vh->session_b);
|
||||
|
||||
@ -268,6 +281,7 @@ static void *audio_bridge_thread(switch_thread_t *thread, void *obj)
|
||||
switch_codec_implementation_t read_impl = { 0 };
|
||||
const char *banner_file = NULL;
|
||||
int played_banner = 0, banner_counter = 0;
|
||||
int pass_val = 0, last_pass_val = 0;
|
||||
|
||||
#ifdef SWITCH_VIDEO_IN_THREADS
|
||||
struct vid_helper vh = { 0 };
|
||||
@ -398,6 +412,17 @@ static void *audio_bridge_thread(switch_thread_t *thread, void *obj)
|
||||
switch_status_t status;
|
||||
switch_event_t *event;
|
||||
|
||||
if (switch_core_session_transcoding(session_a, session_b, SWITCH_MEDIA_TYPE_AUDIO)) {
|
||||
pass_val = 1;
|
||||
} else {
|
||||
pass_val = 2;
|
||||
}
|
||||
|
||||
if (pass_val != last_pass_val) {
|
||||
switch_core_session_passthru(session_a, SWITCH_MEDIA_TYPE_AUDIO, pass_val == 2 ? SWITCH_TRUE : SWITCH_FALSE);
|
||||
last_pass_val = pass_val;
|
||||
}
|
||||
|
||||
if (switch_channel_test_flag(chan_a, CF_TRANSFER)) {
|
||||
data->clean_exit = 1;
|
||||
}
|
||||
@ -702,6 +727,8 @@ static void *audio_bridge_thread(switch_thread_t *thread, void *obj)
|
||||
}
|
||||
#endif
|
||||
|
||||
switch_core_session_passthru(session_a, SWITCH_MEDIA_TYPE_AUDIO, SWITCH_FALSE);
|
||||
|
||||
|
||||
if (silence_val) {
|
||||
switch_core_codec_destroy(&silence_codec);
|
||||
|
@ -386,6 +386,14 @@ static switch_status_t timer_generic_sync(switch_timer_t *timer)
|
||||
timer->tick = (elapsed / timer->interval) / 1000;
|
||||
timer->samplecount = (uint32_t)(timer->tick * timer->samples);
|
||||
|
||||
if (timer->interval == 1 && timer->samplecount == timer->last_samplecount) {
|
||||
timer->samplecount++;
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "Timer sync too often\n");
|
||||
}
|
||||
timer->last_samplecount = timer->samplecount;
|
||||
|
||||
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user