mirror of
https://github.com/signalwire/freeswitch.git
synced 2025-06-27 19:53:55 +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_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
|
\brief Flush the private event queue of a session
|
||||||
\param session the session to flush
|
\param session the session to flush
|
||||||
|
@ -207,6 +207,7 @@ struct switch_timer {
|
|||||||
unsigned int samples;
|
unsigned int samples;
|
||||||
/*! current sample count based on samples parameter */
|
/*! current sample count based on samples parameter */
|
||||||
uint32_t samplecount;
|
uint32_t samplecount;
|
||||||
|
uint32_t last_samplecount;
|
||||||
/*! the timer interface provided from a loadable module */
|
/*! the timer interface provided from a loadable module */
|
||||||
switch_timer_interface_t *timer_interface;
|
switch_timer_interface_t *timer_interface;
|
||||||
/*! the timer's memory pool */
|
/*! the timer's memory pool */
|
||||||
|
@ -770,8 +770,6 @@ typedef enum {
|
|||||||
SWITCH_RTP_FLAG_MUTE,
|
SWITCH_RTP_FLAG_MUTE,
|
||||||
SWITCH_RTP_FLAG_NACK,
|
SWITCH_RTP_FLAG_NACK,
|
||||||
SWITCH_RTP_FLAG_TMMBR,
|
SWITCH_RTP_FLAG_TMMBR,
|
||||||
SWITCH_RTP_FLAG_GEN_TS_DELTA,
|
|
||||||
SWITCH_RTP_FLAG_GEN_TS_MANUAL,
|
|
||||||
SWITCH_RTP_FLAG_DETECT_SSRC,
|
SWITCH_RTP_FLAG_DETECT_SSRC,
|
||||||
SWITCH_RTP_FLAG_OLD_FIR,
|
SWITCH_RTP_FLAG_OLD_FIR,
|
||||||
SWITCH_RTP_FLAG_PASSTHRU,
|
SWITCH_RTP_FLAG_PASSTHRU,
|
||||||
@ -905,7 +903,6 @@ typedef enum {
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
} switch_rtp_bug_flag_t;
|
} switch_rtp_bug_flag_t;
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
@ -1530,6 +1527,8 @@ typedef struct switch_vid_params_s {
|
|||||||
uint32_t width;
|
uint32_t width;
|
||||||
uint32_t height;
|
uint32_t height;
|
||||||
uint32_t fps;
|
uint32_t fps;
|
||||||
|
uint32_t d_width;
|
||||||
|
uint32_t d_height;
|
||||||
} switch_vid_params_t;
|
} switch_vid_params_t;
|
||||||
|
|
||||||
|
|
||||||
|
@ -41,42 +41,25 @@
|
|||||||
*/
|
*/
|
||||||
#include <mod_conference.h>
|
#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)
|
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 > 100) {
|
||||||
if (FPS_VALS[i].fps == fps) {
|
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++) {
|
for (j = 0; j <= conference->canvas_count; j++) {
|
||||||
if (conference->canvases[j]) {
|
if (conference->canvases[j]) {
|
||||||
conference->canvases[j]->video_timer_reset = 1;
|
conference->canvases[j]->video_timer_reset = 1;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 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) {
|
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;
|
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);
|
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);
|
switch_core_session_rwunlock(imember->session);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -2996,6 +2981,7 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr
|
|||||||
|
|
||||||
if (!imember->rec &&
|
if (!imember->rec &&
|
||||||
(!imember->session || !switch_channel_test_flag(imember->channel, CF_VIDEO_READY) || !imember->canvas ||
|
(!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)) {
|
switch_core_session_read_lock(imember->session) != SWITCH_STATUS_SUCCESS)) {
|
||||||
continue;
|
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);
|
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);
|
switch_core_session_rwunlock(imember->session);
|
||||||
continue;
|
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_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.img = write_img;
|
||||||
write_frame.packet = packet;
|
write_frame.packet = packet;
|
||||||
write_frame.data = ((uint8_t *)packet) + 12;
|
write_frame.data = ((uint8_t *)packet) + 12;
|
||||||
write_frame.datalen = 0;
|
write_frame.datalen = 0;
|
||||||
write_frame.buflen = SWITCH_RTP_MAX_BUF_LEN - 12;
|
write_frame.buflen = SWITCH_RTP_MAX_BUF_LEN - 12;
|
||||||
write_frame.packetlen = 0;
|
write_frame.packetlen = 0;
|
||||||
|
write_frame.timestamp = timestamp;
|
||||||
|
|
||||||
//switch_core_session_write_video_frame(imember->session, &write_frame, SWITCH_IO_FLAG_NONE, 0);
|
//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);
|
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);
|
switch_core_session_rwunlock(imember->session);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -53,7 +53,8 @@ static void gen_ice(switch_core_session_t *session, switch_media_type_t type, co
|
|||||||
typedef enum {
|
typedef enum {
|
||||||
SMF_INIT = (1 << 0),
|
SMF_INIT = (1 << 0),
|
||||||
SMF_READY = (1 << 1),
|
SMF_READY = (1 << 1),
|
||||||
SMF_JB_PAUSED = (1 << 2)
|
SMF_JB_PAUSED = (1 << 2),
|
||||||
|
SMF_VB_PAUSED = (1 << 3)
|
||||||
} smh_flag_t;
|
} smh_flag_t;
|
||||||
|
|
||||||
|
|
||||||
@ -173,6 +174,7 @@ typedef struct switch_rtp_engine_s {
|
|||||||
switch_media_flow_t rmode;
|
switch_media_flow_t rmode;
|
||||||
switch_media_flow_t smode;
|
switch_media_flow_t smode;
|
||||||
switch_thread_id_t thread_id;
|
switch_thread_id_t thread_id;
|
||||||
|
switch_thread_id_t thread_write_lock;
|
||||||
uint8_t new_ice;
|
uint8_t new_ice;
|
||||||
uint8_t new_dtls;
|
uint8_t new_dtls;
|
||||||
uint32_t sdp_bw;
|
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];
|
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) {
|
if (switch_channel_test_flag(session->channel, CF_VIDEO_ONLY) && type == SWITCH_MEDIA_TYPE_AUDIO) {
|
||||||
return SWITCH_STATUS_SUCCESS;
|
return SWITCH_STATUS_SUCCESS;
|
||||||
@ -5390,7 +5397,7 @@ SWITCH_DECLARE(switch_file_handle_t *) switch_core_media_get_video_file(switch_c
|
|||||||
return fh;
|
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 };
|
switch_frame_t fr = { 0 };
|
||||||
int i = 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)
|
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;
|
int buflen = SWITCH_RTP_MAX_BUF_LEN;
|
||||||
switch_timer_t timer = { 0 };
|
switch_timer_t timer = { 0 };
|
||||||
int fps;
|
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;
|
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) {
|
if (switch_core_session_read_lock(session) != SWITCH_STATUS_SUCCESS) {
|
||||||
return NULL;
|
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];
|
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);
|
buf = switch_core_session_alloc(session, buflen);
|
||||||
fr.packet = buf;
|
fr.packet = buf;
|
||||||
fr.packetlen = buflen;
|
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 &&
|
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)) {
|
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) {
|
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_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)) {
|
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);
|
wstatus = switch_core_file_read_video(smh->video_write_fh, &fr, read_flags);
|
||||||
|
|
||||||
if (wstatus == SWITCH_STATUS_SUCCESS) {
|
if (wstatus == SWITCH_STATUS_SUCCESS) {
|
||||||
switch_core_session_write_video_frame(session, &fr, SWITCH_IO_FLAG_FORCE, SVR_FLUSH);
|
fr.timestamp = timer.samplecount;
|
||||||
switch_img_free(&fr.img);
|
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) {
|
} else if (wstatus != SWITCH_STATUS_BREAK && wstatus != SWITCH_STATUS_IGNORE) {
|
||||||
switch_set_flag_locked(smh->video_write_fh, SWITCH_FILE_FLAG_VIDEO_EOF);
|
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);
|
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_timer_destroy(&timer);
|
||||||
|
|
||||||
switch_core_session_rwunlock(session);
|
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);
|
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);
|
switch_channel_clear_flag(session->channel, CF_VIDEO_WRITING);
|
||||||
smh->video_write_thread_running = 0;
|
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) {
|
if (fh) {
|
||||||
switch_threadattr_t *thd_attr = NULL;
|
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_create(&thd_attr, switch_core_session_get_pool(session));
|
||||||
switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
|
switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
|
||||||
smh->video_write_thread_running = 1;
|
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_thread_join(&st, smh->video_write_thread);
|
||||||
switch_mutex_lock(v_engine->mh.file_write_mutex);
|
switch_mutex_lock(v_engine->mh.file_write_mutex);
|
||||||
smh->video_write_thread = NULL;
|
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;
|
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)) {
|
if (switch_channel_up(session->channel)) {
|
||||||
switch_channel_set_variable(session->channel, "rtp_use_timer_name", timer_name);
|
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]++;
|
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)) {
|
if (switch_channel_test_flag(session->channel, CF_PROXY_MEDIA)) {
|
||||||
flags[SWITCH_RTP_FLAG_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;
|
const char *val;
|
||||||
int ok = 0;
|
int ok = 0;
|
||||||
|
|
||||||
if (!switch_channel_test_flag(session->channel, CF_VIDEO) &&
|
if ((!(val = switch_channel_get_variable(session->channel, "rtp_jitter_buffer_during_bridge")) || switch_false(val))) {
|
||||||
(!(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)) {
|
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,
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
|
||||||
"%s PAUSE Jitterbuffer\n", switch_channel_get_name(session->channel));
|
"%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;
|
goto end;
|
||||||
case SWITCH_MESSAGE_INDICATE_UNBRIDGE:
|
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_rtp_ready(a_engine->rtp_session)) {
|
||||||
|
|
||||||
if (switch_test_flag(smh, SMF_JB_PAUSED)) {
|
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_image_t *dup_img = NULL, *img = frame->img;
|
||||||
switch_status_t encode_status;
|
switch_status_t encode_status;
|
||||||
switch_frame_t write_frame = {0};
|
switch_frame_t write_frame = {0};
|
||||||
switch_rtp_engine_t *v_engine;
|
switch_rtp_engine_t *v_engine = NULL;
|
||||||
|
|
||||||
switch_assert(session);
|
switch_assert(session);
|
||||||
|
|
||||||
if (!(smh = session->media_handle)) {
|
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;
|
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) {
|
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");
|
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;
|
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) {
|
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);
|
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) {
|
if (!img) {
|
||||||
switch_status_t vstatus;
|
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);
|
vstatus = switch_core_session_write_encoded_video_frame(session, frame, flags, stream_id);
|
||||||
switch_goto_status(vstatus, done);
|
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;
|
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) {
|
if (session->bugs) {
|
||||||
switch_media_bug_t *bp;
|
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,
|
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)
|
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;
|
switch_frame_t *read_frame = 0;
|
||||||
int set_decoded_read = 0, refresh_timer = 0;
|
int set_decoded_read = 0, refresh_timer = 0;
|
||||||
int refresh_cnt = 300;
|
int refresh_cnt = 300;
|
||||||
|
int pass_val = 0, last_pass_val = 0;
|
||||||
|
|
||||||
vh->up = 1;
|
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)) {
|
if (switch_channel_media_up(channel)) {
|
||||||
switch_codec_t *a_codec = switch_core_session_get_video_read_codec(vh->session_a);
|
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);
|
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)) {
|
if (switch_channel_test_flag(channel, CF_VIDEO_REFRESH_REQ)) {
|
||||||
switch_channel_clear_flag(channel, CF_VIDEO_REFRESH_REQ);
|
switch_channel_clear_flag(channel, CF_VIDEO_REFRESH_REQ);
|
||||||
refresh_timer = refresh_cnt;
|
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_a);
|
||||||
switch_core_session_request_video_refresh(vh->session_b);
|
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_a);
|
||||||
switch_core_session_rwunlock(vh->session_b);
|
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 };
|
switch_codec_implementation_t read_impl = { 0 };
|
||||||
const char *banner_file = NULL;
|
const char *banner_file = NULL;
|
||||||
int played_banner = 0, banner_counter = 0;
|
int played_banner = 0, banner_counter = 0;
|
||||||
|
int pass_val = 0, last_pass_val = 0;
|
||||||
|
|
||||||
#ifdef SWITCH_VIDEO_IN_THREADS
|
#ifdef SWITCH_VIDEO_IN_THREADS
|
||||||
struct vid_helper vh = { 0 };
|
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_status_t status;
|
||||||
switch_event_t *event;
|
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)) {
|
if (switch_channel_test_flag(chan_a, CF_TRANSFER)) {
|
||||||
data->clean_exit = 1;
|
data->clean_exit = 1;
|
||||||
}
|
}
|
||||||
@ -702,6 +727,8 @@ static void *audio_bridge_thread(switch_thread_t *thread, void *obj)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
switch_core_session_passthru(session_a, SWITCH_MEDIA_TYPE_AUDIO, SWITCH_FALSE);
|
||||||
|
|
||||||
|
|
||||||
if (silence_val) {
|
if (silence_val) {
|
||||||
switch_core_codec_destroy(&silence_codec);
|
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->tick = (elapsed / timer->interval) / 1000;
|
||||||
timer->samplecount = (uint32_t)(timer->tick * timer->samples);
|
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;
|
return SWITCH_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user