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;
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 {
\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);
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 {
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);
}
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