From 35ff4b5cdaf2f25c3c73be8a841e7f1d3baf6c15 Mon Sep 17 00:00:00 2001 From: Seven Du Date: Sat, 23 Aug 2014 16:54:50 +0800 Subject: [PATCH] FS-7500: add ability to insert a custom callback to the core video thread the callback will be called on each loop on read video frame, or the callback function call run it's own loop to take over the core loop so it can read video from session by itself. the callback function can - return SWITCH_STATUS_SUCCESS to wait another loop return SWITCH_STATUS_CONTINUE to continue use the default behaviour return anything else will break the core video loop and end the core thread --- src/include/private/switch_core_pvt.h | 3 +++ src/include/switch_core.h | 29 +++++++++++++++++++++++++++ src/include/switch_types.h | 2 +- src/switch_core_media.c | 8 ++++++++ src/switch_core_session.c | 25 +++++++++++++++++++++++ 5 files changed, 66 insertions(+), 1 deletion(-) 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