diff --git a/src/include/private/switch_core_pvt.h b/src/include/private/switch_core_pvt.h index 9acc2a2741..f1d7dfed12 100644 --- a/src/include/private/switch_core_pvt.h +++ b/src/include/private/switch_core_pvt.h @@ -103,6 +103,7 @@ typedef enum { SSF_MEDIA_BUG_TAP_ONLY = (1 << 10) } switch_session_flag_t; +typedef switch_status_t (switch_core_video_thread_callback_func_t) (switch_core_session_t *session, switch_frame_t *frame, void *user_data); struct switch_core_session { switch_memory_pool_t *pool; @@ -189,6 +190,8 @@ struct switch_core_session { switch_media_handle_t *media_handle; uint32_t decoder_errors; + switch_core_video_thread_callback_func_t *_video_thread_callback; + void *_video_thread_user_data; }; struct switch_media_bug { diff --git a/src/include/switch_core.h b/src/include/switch_core.h index b123284670..0ace87d288 100644 --- a/src/include/switch_core.h +++ b/src/include/switch_core.h @@ -2303,6 +2303,35 @@ SWITCH_DECLARE(uint8_t) switch_core_session_compare(switch_core_session_t *a, sw \return TRUE or FALSE */ SWITCH_DECLARE(uint8_t) switch_core_session_check_interface(switch_core_session_t *session, const switch_endpoint_interface_t *endpoint_interface); + +/*! + \brief Set a callback to let the core video thread call us + \param session the session + \param func to callback + \param private user data + \return SWITCH_STATUS_CONTINUE | SWITCH_STATUS_SUCCESS | SWITCH_STATUS_BREAK | SWITCH_STATUS_* + + If returns SWITCH_STATUS_CONTINUE, it will continues to run furthur code (read/write) in the core video thread, + that is to say, if the callback func to nothing and just returns SWITCH_STATUS_CONTINUE, it remains the default behaviour, + Return SWITCH_STATUS_SUCCESS to skip the default behaviour + Return SWITCH_STATUS_BREAK will break the loop and end the video thread +*/ + +SWITCH_DECLARE(switch_status_t) switch_core_session_set_video_thread_callback(switch_core_session_t *session, void *func, void *user_data); + +/*! + \brief Set a callback to let the core video thread call us + \param session the session + \param the current video frame + \param private user data + \return SWITCH_STATUS_CONTINUE or SWITCH_STATUS_SUCCESS + + If returns SWITCH_STATUS_CONTINUE, it will continues to run furthur code (read/write) in the core video thread, + that is to say, if the callback func to nothing and just returns SWITCH_STATUS_CONTINUE, it remains the default behaviour, + Return SWITCH_STATUS_SUCCESS to skip the default behaviour +*/ +SWITCH_DECLARE(switch_status_t) switch_core_session_video_thread_callback(switch_core_session_t *session, switch_frame_t *frame); + SWITCH_DECLARE(switch_hash_index_t *) switch_core_mime_index(void); SWITCH_DECLARE(const char *) switch_core_mime_ext2type(const char *ext); SWITCH_DECLARE(const char *) switch_core_mime_type2ext(const char *type); diff --git a/src/include/switch_types.h b/src/include/switch_types.h index 65d25d1188..dd6a979a62 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -1477,7 +1477,7 @@ SFF_PLC = (1 << 3) - Frame has generated PLC data SFF_RFC2833 = (1 << 4) - Frame has rfc2833 dtmf data SFF_DYNAMIC = (1 << 5) - Frame is dynamic and should be freed SFF_MARKER = (1 << 11) - Frame flag has Marker set, only set by encoder -SFF_WAIT_KEY_FRAME = (1 << 12) - Need a key from before could decode +SFF_WAIT_KEY_FRAME = (1 << 12) - Need a key from before could decode, or force generate a key frame on encode */ typedef enum { diff --git a/src/switch_core_media.c b/src/switch_core_media.c index b8ceaffc01..9dcedfbd9b 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -4518,6 +4518,14 @@ static void *SWITCH_THREAD_FUNC video_helper_thread(switch_thread_t *thread, voi continue; } + status = switch_core_session_video_thread_callback(session, read_frame); + + if (status != SWITCH_STATUS_CONTINUE) { + if (status == SWITCH_STATUS_SUCCESS) continue; + + break; + } + if (switch_channel_test_flag(channel, CF_VIDEO_ECHO)) { switch_core_session_write_video_frame(session, read_frame, SWITCH_IO_FLAG_NONE, 0); } diff --git a/src/switch_core_session.c b/src/switch_core_session.c index 8d77bd4433..8bf3c710b6 100644 --- a/src/switch_core_session.c +++ b/src/switch_core_session.c @@ -3063,6 +3063,31 @@ SWITCH_DECLARE(void) switch_core_session_debug_pool(switch_stream_handle_t *stre session_manager.running, session_manager.busy, session_manager.popping); } +SWITCH_DECLARE(switch_status_t) switch_core_session_set_video_thread_callback(switch_core_session_t *session, void *func, void *user_data) +{ + if (!func) { + session->_video_thread_callback = NULL; + session->_video_thread_user_data = NULL; + return SWITCH_STATUS_SUCCESS; + } else if (session->_video_thread_callback) { + return SWITCH_STATUS_FALSE; + } else { + session->_video_thread_callback = func; + session->_video_thread_user_data = user_data; + return SWITCH_STATUS_SUCCESS; + } +} + +SWITCH_DECLARE(switch_status_t) switch_core_session_video_thread_callback(switch_core_session_t *session, switch_frame_t *frame) +{ + if (session->_video_thread_callback) { + return session->_video_thread_callback(session, frame, session->_video_thread_user_data); + } + + return SWITCH_STATUS_CONTINUE; +} + + /* For Emacs: * Local Variables: * mode:c