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
This commit is contained in:
Seven Du 2014-08-23 16:54:50 +08:00 committed by Michael Jerris
parent 422a1f0419
commit 35ff4b5cda
5 changed files with 66 additions and 1 deletions

View File

@ -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 {

View File

@ -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);

View File

@ -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
</pre>
*/
typedef enum {

View File

@ -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);
}

View File

@ -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