FreeSWITCH API Documentation  1.7.0
Macros | Functions
switch_core_media_bug.c File Reference
#include "switch.h"
#include "private/switch_core_pvt.h"
+ Include dependency graph for switch_core_media_bug.c:

Go to the source code of this file.

Macros

#define MAX_BUG_BUFFER   1024 * 512
 

Functions

static void switch_core_media_bug_destroy (switch_media_bug_t *bug)
 
void switch_core_media_bug_pause (switch_core_session_t *session)
 Pause a media bug on the session. More...
 
void switch_core_media_bug_resume (switch_core_session_t *session)
 Resume a media bug on the session. More...
 
uint32_t switch_core_media_bug_test_flag (switch_media_bug_t *bug, uint32_t flag)
 
uint32_t switch_core_media_bug_set_flag (switch_media_bug_t *bug, uint32_t flag)
 
uint32_t switch_core_media_bug_clear_flag (switch_media_bug_t *bug, uint32_t flag)
 
switch_core_session_tswitch_core_media_bug_get_session (switch_media_bug_t *bug)
 
switch_frame_tswitch_core_media_bug_get_video_ping_frame (switch_media_bug_t *bug)
 
switch_frame_tswitch_core_media_bug_get_write_replace_frame (switch_media_bug_t *bug)
 
void switch_core_media_bug_set_write_replace_frame (switch_media_bug_t *bug, switch_frame_t *frame)
 
switch_frame_tswitch_core_media_bug_get_read_replace_frame (switch_media_bug_t *bug)
 
switch_frame_tswitch_core_media_bug_get_native_read_frame (switch_media_bug_t *bug)
 
switch_frame_tswitch_core_media_bug_get_native_write_frame (switch_media_bug_t *bug)
 
void switch_core_media_bug_set_read_replace_frame (switch_media_bug_t *bug, switch_frame_t *frame)
 
void switch_core_media_bug_set_read_demux_frame (switch_media_bug_t *bug, switch_frame_t *frame)
 
void * switch_core_media_bug_get_user_data (switch_media_bug_t *bug)
 
void switch_core_media_bug_flush (switch_media_bug_t *bug)
 
void switch_core_media_bug_inuse (switch_media_bug_t *bug, switch_size_t *readp, switch_size_t *writep)
 
switch_status_t switch_core_media_bug_set_pre_buffer_framecount (switch_media_bug_t *bug, uint32_t framecount)
 
switch_status_t switch_core_media_bug_read (switch_media_bug_t *bug, switch_frame_t *frame, switch_bool_t fill)
 
switch_vid_spy_fmt_t switch_media_bug_parse_spy_fmt (const char *name)
 
void switch_media_bug_set_spy_fmt (switch_media_bug_t *bug, switch_vid_spy_fmt_t spy_fmt)
 
switch_status_t switch_core_media_bug_patch_spy_frame (switch_media_bug_t *bug, switch_image_t *img, switch_rw_t rw)
 
static void *SWITCH_THREAD_FUNC video_bug_thread (switch_thread_t *thread, void *obj)
 
switch_status_t switch_core_media_bug_push_spy_frame (switch_media_bug_t *bug, switch_frame_t *frame, switch_rw_t rw)
 
switch_status_t switch_core_media_bug_add (switch_core_session_t *session, const char *function, const char *target, switch_media_bug_callback_t callback, void *user_data, time_t stop_time, switch_media_bug_flag_t flags, switch_media_bug_t **new_bug)
 
switch_status_t switch_core_media_bug_flush_all (switch_core_session_t *session)
 
switch_status_t switch_core_media_bug_transfer_recordings (switch_core_session_t *orig_session, switch_core_session_t *new_session)
 
switch_status_t switch_core_media_bug_transfer_callback (switch_core_session_t *orig_session, switch_core_session_t *new_session, switch_media_bug_callback_t callback, void *(*user_data_dup_func)(switch_core_session_t *, void *))
 
switch_status_t switch_core_media_bug_pop (switch_core_session_t *orig_session, const char *function, switch_media_bug_t **pop)
 
uint32_t switch_core_media_bug_count (switch_core_session_t *orig_session, const char *function)
 
uint32_t switch_core_media_bug_patch_video (switch_core_session_t *orig_session, switch_frame_t *frame)
 
switch_status_t switch_core_media_bug_exec_all (switch_core_session_t *orig_session, const char *function, switch_media_bug_exec_cb_t cb, void *user_data)
 
switch_status_t switch_core_media_bug_enumerate (switch_core_session_t *session, switch_stream_handle_t *stream)
 
switch_status_t switch_core_media_bug_remove_all_function (switch_core_session_t *session, const char *function)
 
switch_status_t switch_core_media_bug_close (switch_media_bug_t **bug)
 
switch_status_t switch_core_media_bug_remove (switch_core_session_t *session, switch_media_bug_t **bug)
 
uint32_t switch_core_media_bug_prune (switch_core_session_t *session)
 
switch_status_t switch_core_media_bug_remove_callback (switch_core_session_t *session, switch_media_bug_callback_t callback)
 Remove media bug callback. More...
 

Macro Definition Documentation

#define MAX_BUG_BUFFER   1024 * 512

Definition at line 665 of file switch_core_media_bug.c.

Referenced by switch_core_media_bug_add().

Function Documentation

switch_status_t switch_core_media_bug_add ( switch_core_session_t session,
const char *  function,
const char *  target,
switch_media_bug_callback_t  callback,
void *  user_data,
time_t  stop_time,
switch_media_bug_flag_t  flags,
switch_media_bug_t **  new_bug 
)

Definition at line 666 of file switch_core_media_bug.c.

References switch_media_bug::callback, CF_VIDEO_DECODED_READ, switch_codec_implementation::decoded_bytes_per_packet, switch_media_bug::flags, switch_media_bug::function, MAX_BUG_BUFFER, switch_media_bug::next, pool, switch_media_bug::raw_read_buffer, switch_media_bug::raw_write_buffer, switch_media_bug::read_impl, switch_media_bug::read_mutex, switch_media_bug::read_video_queue, switch_media_bug::ready, switch_media_bug::session, SMBF_ANSWER_REQ, SMBF_ONE_ONLY, SMBF_READ_PING, SMBF_READ_REPLACE, SMBF_READ_STREAM, SMBF_READ_VIDEO_PING, SMBF_READ_VIDEO_STREAM, SMBF_SPY_VIDEO_STREAM, SMBF_SPY_VIDEO_STREAM_BLEG, SMBF_TAP_NATIVE_READ, SMBF_TAP_NATIVE_WRITE, SMBF_THREAD_LOCK, SMBF_WRITE_REPLACE, SMBF_WRITE_STREAM, SMBF_WRITE_VIDEO_PING, SMBF_WRITE_VIDEO_STREAM, switch_media_bug::spy_video_queue, SSF_MEDIA_BUG_TAP_ONLY, switch_media_bug::stop_time, SWITCH_ABC_TYPE_INIT, SWITCH_BUFFER_BLOCK_FRAMES, switch_buffer_create_dynamic(), SWITCH_BUFFER_START_FRAMES, switch_channel_event_set_data(), switch_channel_get_name(), switch_channel_get_variable, switch_channel_media_ready, switch_channel_pre_answer, SWITCH_CHANNEL_SESSION_LOG, switch_channel_set_flag_recursive(), switch_clear_flag, switch_core_media_bug_destroy(), switch_core_media_bug_test_flag(), switch_core_media_hard_mute(), SWITCH_CORE_QUEUE_LEN, switch_core_session_alloc, switch_core_session_get_pool(), switch_core_session_get_read_impl(), switch_core_session_get_write_impl(), switch_core_session_strdup, switch_event_add_header(), switch_event_create, switch_event_fire, SWITCH_EVENT_MEDIA_BUG_START, SWITCH_FALSE, SWITCH_LOG_DEBUG, SWITCH_LOG_ERROR, switch_log_printf(), switch_mutex_init(), SWITCH_MUTEX_NESTED, switch_queue_create(), switch_set_flag, SWITCH_STACK_BOTTOM, SWITCH_STATUS_FALSE, SWITCH_STATUS_GENERR, SWITCH_STATUS_MEMERR, SWITCH_STATUS_SUCCESS, switch_test_flag, switch_thread_create(), switch_thread_rwlock_unlock(), switch_thread_rwlock_wrlock(), switch_thread_self(), SWITCH_THREAD_STACKSIZE, switch_threadattr_create(), switch_threadattr_stacksize_set(), switch_true(), switch_media_bug::target, switch_media_bug::thread_id, switch_media_bug::user_data, switch_media_bug::video_bug_thread, video_bug_thread(), switch_media_bug::write_impl, switch_media_bug::write_mutex, switch_media_bug::write_video_queue, and zstr.

Referenced by switch_core_media_bug_transfer_callback().

673 {
674  switch_media_bug_t *bug, *bp;
675  switch_size_t bytes;
676  switch_event_t *event;
677  int tap_only = 1, punt = 0;
678 
679  const char *p;
680 
681  if (!zstr(function)) {
682  if ((flags & SMBF_ONE_ONLY)) {
684  for (bp = session->bugs; bp; bp = bp->next) {
685  if (!zstr(bp->function) && !strcasecmp(function, bp->function)) {
686  punt = 1;
687  break;
688  }
689  }
691  }
692  }
693 
694  if (punt) {
695  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Only one bug of this type allowed!\n");
696  return SWITCH_STATUS_GENERR;
697  }
698 
699 
700  if (!switch_channel_media_ready(session->channel)) {
702  return SWITCH_STATUS_FALSE;
703  }
704  }
705 
706 
707 
708  *new_bug = NULL;
709 
710 
711  if ((p = switch_channel_get_variable(session->channel, "media_bug_answer_req")) && switch_true(p)) {
712  flags |= SMBF_ANSWER_REQ;
713  }
714 #if 0
715  if (flags & SMBF_WRITE_REPLACE) {
717  for (bp = session->bugs; bp; bp = bp->next) {
718  if (switch_test_flag(bp, SMBF_WRITE_REPLACE)) {
719  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Only one bug of this type allowed!\n");
721  return SWITCH_STATUS_GENERR;
722  }
723  }
725  }
726 
727  if (flags & SMBF_READ_REPLACE) {
729  for (bp = session->bugs; bp; bp = bp->next) {
730  if (switch_test_flag(bp, SMBF_READ_REPLACE)) {
731  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Only one bug of this type allowed!\n");
733  return SWITCH_STATUS_GENERR;
734  }
735  }
737  }
738 #endif
739 
740  if (!(bug = switch_core_session_alloc(session, sizeof(*bug)))) {
741  return SWITCH_STATUS_MEMERR;
742  }
743 
744  bug->callback = callback;
745  bug->user_data = user_data;
746  bug->session = session;
747  bug->flags = flags;
748  bug->function = "N/A";
749  bug->target = "N/A";
750 
753 
754  if (function) {
755  bug->function = switch_core_session_strdup(session, function);
756  }
757 
758  if (target) {
759  bug->target = switch_core_session_strdup(session, target);
760  }
761 
762  bug->stop_time = stop_time;
763  bytes = bug->read_impl.decoded_bytes_per_packet;
764 
765  if (!bug->flags) {
767  }
768 
772  }
773 
775 
779  }
780 
781  if ((bug->flags & SMBF_THREAD_LOCK)) {
782  bug->thread_id = switch_thread_self();
783  }
784 
787  }
788 
792  }
793 
796 
799  }
800 
803  }
804  }
805 
806 
807  if (bug->callback) {
808  switch_bool_t result = bug->callback(bug, bug->user_data, SWITCH_ABC_TYPE_INIT);
809  if (result == SWITCH_FALSE) {
811  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Error attaching BUG to %s\n",
812  switch_channel_get_name(session->channel));
813  return SWITCH_STATUS_GENERR;
814  }
815  }
816 
817  bug->ready = 1;
818 
820  switch_threadattr_t *thd_attr = NULL;
822  switch_threadattr_create(&thd_attr, pool);
824  switch_thread_create(&bug->video_bug_thread, thd_attr, video_bug_thread, bug, pool);
825 
826  }
827 
830  bug->next = session->bugs;
831  session->bugs = bug;
832 
833  for(bp = session->bugs; bp; bp = bp->next) {
835  tap_only = 0;
836  }
837  }
838 
840  *new_bug = bug;
841 
842  if (tap_only) {
844  } else {
846  }
847 
849  switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Media-Bug-Function", "%s", bug->function);
850  switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Media-Bug-Target", "%s", bug->target);
851  switch_channel_event_set_data(session->channel, event);
852  switch_event_fire(&event);
853  }
854 
856 
857  return SWITCH_STATUS_SUCCESS;
858 }
static void switch_core_media_bug_destroy(switch_media_bug_t *bug)
#define switch_event_fire(event)
Fire an event filling in most of the arguements with obvious values.
Definition: switch_event.h:412
void switch_channel_set_flag_recursive(switch_channel_t *channel, switch_channel_flag_t flag)
switch_status_t switch_thread_rwlock_unlock(switch_thread_rwlock_t *rwlock)
Definition: switch_apr.c:263
#define SWITCH_BUFFER_START_FRAMES
switch_codec_implementation_t read_impl
#define SWITCH_CHANNEL_SESSION_LOG(x)
switch_thread_rwlock_t * bug_rwlock
#define switch_set_flag(obj, flag)
Set a flag on an arbitrary object.
Definition: switch_utils.h:631
switch_thread_id_t thread_id
switch_status_t switch_buffer_create_dynamic(_Out_ switch_buffer_t **buffer, _In_ switch_size_t blocksize, _In_ switch_size_t start_len, _In_ switch_size_t max_len)
Allocate a new dynamic switch_buffer.
void switch_channel_event_set_data(_In_ switch_channel_t *channel, _In_ switch_event_t *event)
Add information about a given channel to an event object.
switch_bool_t
Definition: switch_types.h:405
switch_status_t switch_threadattr_stacksize_set(switch_threadattr_t *attr, switch_size_t stacksize)
Definition: switch_apr.c:660
switch_memory_pool_t * pool
switch_status_t switch_event_add_header(switch_event_t *event, switch_stack_t stack, const char *header_name, const char *fmt,...) PRINTF_FUNCTION(4
Add a header to an event.
Representation of an event.
Definition: switch_event.h:80
switch_queue_t * read_video_queue
switch_core_session_t * session
#define switch_channel_media_ready(_channel)
switch_buffer_t * raw_write_buffer
static void *SWITCH_THREAD_FUNC video_bug_thread(switch_thread_t *thread, void *obj)
static int switch_true(const char *expr)
Evaluate the truthfullness of a string expression.
Definition: switch_utils.h:450
switch_media_bug_callback_t callback
#define zstr(x)
Definition: switch_utils.h:281
switch_queue_t * write_video_queue
switch_mutex_t * read_mutex
switch_status_t switch_core_session_get_read_impl(switch_core_session_t *session, switch_codec_implementation_t *impp)
#define switch_clear_flag(obj, flag)
Clear a flag on an arbitrary object while locked.
Definition: switch_utils.h:655
#define SWITCH_MUTEX_NESTED
Definition: switch_apr.h:318
switch_status_t switch_thread_rwlock_wrlock(switch_thread_rwlock_t *rwlock)
Definition: switch_apr.c:237
#define MAX_BUG_BUFFER
switch_channel_t * channel
#define SWITCH_CORE_QUEUE_LEN
Definition: switch_types.h:560
#define switch_channel_get_variable(_c, _v)
#define SWITCH_THREAD_STACKSIZE
Definition: switch_types.h:551
switch_thread_t * video_bug_thread
switch_queue_t * spy_video_queue[2]
switch_status_t switch_mutex_init(switch_mutex_t **lock, unsigned int flags, switch_memory_pool_t *pool)
Definition: switch_apr.c:270
switch_media_bug_t * bugs
uintptr_t switch_size_t
struct switch_media_bug * next
void switch_core_media_hard_mute(switch_core_session_t *session, switch_bool_t on)
switch_status_t switch_core_session_get_write_impl(switch_core_session_t *session, switch_codec_implementation_t *impp)
uint32_t switch_core_media_bug_test_flag(switch_media_bug_t *bug, uint32_t flag)
switch_codec_implementation_t write_impl
switch_memory_pool_t * pool
#define switch_event_create(event, id)
Create a new event assuming it will not be custom event and therefore hiding the unused parameters...
Definition: switch_event.h:383
#define switch_core_session_alloc(_session, _memory)
Allocate memory from a session's pool.
Definition: switch_core.h:694
struct apr_pool_t switch_memory_pool_t
#define switch_test_flag(obj, flag)
Test for the existance of a flag on an arbitary object.
Definition: switch_utils.h:624
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
switch_status_t switch_threadattr_create(switch_threadattr_t **new_attr, switch_memory_pool_t *pool)
Definition: switch_apr.c:642
switch_status_t switch_thread_create(switch_thread_t **new_thread, switch_threadattr_t *attr, switch_thread_start_t func, void *data, switch_memory_pool_t *cont)
Definition: switch_apr.c:675
switch_status_t switch_queue_create(switch_queue_t **queue, unsigned int queue_capacity, switch_memory_pool_t *pool)
Definition: switch_apr.c:1109
#define switch_core_session_strdup(_session, _todup)
Copy a string using memory allocation from a session's pool.
Definition: switch_core.h:717
switch_thread_id_t switch_thread_self(void)
Definition: switch_apr.c:79
switch_buffer_t * raw_read_buffer
switch_mutex_t * write_mutex
#define switch_channel_pre_answer(channel)
Indicate progress on a channel to attempt early media.
#define SWITCH_BUFFER_BLOCK_FRAMES
char * switch_channel_get_name(switch_channel_t *channel)
Retrieve the name of a given channel.
switch_memory_pool_t * switch_core_session_get_pool(_In_ switch_core_session_t *session)
Retrieve the memory pool from a session.
uint32_t switch_core_media_bug_clear_flag ( switch_media_bug_t bug,
uint32_t  flag 
)

Definition at line 81 of file switch_core_media_bug.c.

References switch_clear_flag.

82 {
83  return switch_clear_flag(bug, flag);
84 }
#define switch_clear_flag(obj, flag)
Clear a flag on an arbitrary object while locked.
Definition: switch_utils.h:655
switch_status_t switch_core_media_bug_close ( switch_media_bug_t **  bug)

Definition at line 1139 of file switch_core_media_bug.c.

References switch_media_bug::callback, CF_VIDEO_DECODED_READ, switch_core_session::channel, switch_media_bug::read_video_queue, switch_media_bug::ready, switch_media_bug::session, SMBF_LOCK, SMBF_READ_VIDEO_PING, SMBF_READ_VIDEO_STREAM, SMBF_WRITE_VIDEO_PING, SMBF_WRITE_VIDEO_STREAM, switch_media_bug::spy_img, switch_media_bug::spy_video_queue, SWITCH_ABC_TYPE_CLOSE, switch_channel_clear_flag_recursive(), switch_channel_get_name(), SWITCH_CHANNEL_SESSION_LOG, switch_core_media_bug_destroy(), switch_core_media_bug_get_session(), switch_img_free(), SWITCH_LOG_DEBUG, switch_log_printf(), switch_queue_push(), switch_queue_trypop(), SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, switch_test_flag, switch_thread_join(), switch_thread_self(), switch_media_bug::thread_id, switch_media_bug::user_data, switch_media_bug::video_bug_thread, and switch_media_bug::write_video_queue.

Referenced by switch_core_media_bug_prune(), switch_core_media_bug_remove(), and switch_core_media_bug_remove_callback().

1140 {
1141  switch_media_bug_t *bp = *bug;
1142 
1143  if (bp) {
1144  if ((bp->thread_id && bp->thread_id != switch_thread_self()) || switch_test_flag(bp, SMBF_LOCK)) {
1146  return SWITCH_STATUS_FALSE;
1147  }
1148 
1149  if (bp->callback) {
1151  }
1152 
1155  }
1156 
1157  bp->ready = 0;
1158 
1159  switch_img_free(&bp->spy_img[0]);
1160  switch_img_free(&bp->spy_img[1]);
1161 
1162  if (bp->video_bug_thread) {
1163  switch_status_t st;
1164  int i;
1165 
1166  for (i = 0; i < 2; i++) {
1167  void *pop;
1168  switch_image_t *img;
1169 
1170  if (bp->spy_video_queue[i]) {
1171  while (switch_queue_trypop(bp->spy_video_queue[i], &pop) == SWITCH_STATUS_SUCCESS && pop) {
1172  img = (switch_image_t *) pop;
1173  switch_img_free(&img);
1174  }
1175  }
1176  }
1177 
1178  if (bp->read_video_queue) {
1180  }
1181 
1182  if (bp->write_video_queue) {
1184  }
1185 
1187  }
1188 
1192  *bug = NULL;
1193  return SWITCH_STATUS_SUCCESS;
1194  }
1195 
1196  return SWITCH_STATUS_FALSE;
1197 }
static void switch_core_media_bug_destroy(switch_media_bug_t *bug)
#define SWITCH_CHANNEL_SESSION_LOG(x)
Image Descriptor.
Definition: switch_image.h:88
switch_thread_id_t thread_id
void switch_img_free(switch_image_t **img)
Close an image descriptor.
switch_queue_t * read_video_queue
switch_status_t switch_queue_trypop(switch_queue_t *queue, void **data)
Definition: switch_apr.c:1140
switch_core_session_t * session
switch_media_bug_callback_t callback
switch_core_session_t * switch_core_media_bug_get_session(switch_media_bug_t *bug)
switch_queue_t * write_video_queue
switch_status_t switch_thread_join(switch_status_t *retval, switch_thread_t *thd)
Definition: switch_apr.c:1255
switch_channel_t * channel
switch_thread_t * video_bug_thread
switch_queue_t * spy_video_queue[2]
switch_image_t * spy_img[2]
switch_status_t
Common return values.
switch_status_t switch_queue_push(switch_queue_t *queue, void *data)
Definition: switch_apr.c:1129
#define switch_test_flag(obj, flag)
Test for the existance of a flag on an arbitary object.
Definition: switch_utils.h:624
void switch_channel_clear_flag_recursive(switch_channel_t *channel, switch_channel_flag_t flag)
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
switch_thread_id_t switch_thread_self(void)
Definition: switch_apr.c:79
char * switch_channel_get_name(switch_channel_t *channel)
Retrieve the name of a given channel.
static void switch_core_media_bug_destroy ( switch_media_bug_t bug)
static

Definition at line 38 of file switch_core_media_bug.c.

References switch_core_session::channel, switch_media_bug::function, switch_media_bug::raw_read_buffer, switch_media_bug::raw_write_buffer, switch_media_bug::session, switch_buffer_destroy(), switch_channel_event_set_data(), switch_event_add_header(), switch_event_create, switch_event_fire, SWITCH_EVENT_MEDIA_BUG_STOP, SWITCH_STACK_BOTTOM, SWITCH_STATUS_SUCCESS, and switch_media_bug::target.

Referenced by switch_core_media_bug_add(), switch_core_media_bug_close(), switch_core_media_bug_remove_all_function(), and switch_core_media_bug_transfer_callback().

39 {
40  switch_event_t *event = NULL;
41 
42  if (bug->raw_read_buffer) {
44  }
45 
46  if (bug->raw_write_buffer) {
48  }
49 
51  switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Media-Bug-Function", "%s", bug->function);
52  switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Media-Bug-Target", "%s", bug->target);
53  if (bug->session) switch_channel_event_set_data(bug->session->channel, event);
54  switch_event_fire(&event);
55  }
56 }
#define switch_event_fire(event)
Fire an event filling in most of the arguements with obvious values.
Definition: switch_event.h:412
void switch_channel_event_set_data(_In_ switch_channel_t *channel, _In_ switch_event_t *event)
Add information about a given channel to an event object.
switch_status_t switch_event_add_header(switch_event_t *event, switch_stack_t stack, const char *header_name, const char *fmt,...) PRINTF_FUNCTION(4
Add a header to an event.
Representation of an event.
Definition: switch_event.h:80
switch_core_session_t * session
switch_buffer_t * raw_write_buffer
switch_channel_t * channel
#define switch_event_create(event, id)
Create a new event assuming it will not be custom event and therefore hiding the unused parameters...
Definition: switch_event.h:383
switch_buffer_t * raw_read_buffer
void switch_buffer_destroy(switch_buffer_t **buffer)
Destroy the buffer.
void switch_core_media_bug_flush ( switch_media_bug_t bug)

Definition at line 136 of file switch_core_media_bug.c.

References switch_buffer_zero(), switch_mutex_lock(), and switch_mutex_unlock().

Referenced by switch_core_media_bug_flush_all(), and switch_core_media_bug_read().

137 {
138 
139  bug->record_pre_buffer_count = 0;
140 
141  if (bug->raw_read_buffer) {
145  }
146 
147  if (bug->raw_write_buffer) {
151  }
152 
153  bug->record_frame_size = 0;
154  bug->record_pre_buffer_count = 0;
155 }
uint32_t record_pre_buffer_count
switch_buffer_t * raw_write_buffer
switch_mutex_t * read_mutex
switch_status_t switch_mutex_unlock(switch_mutex_t *lock)
Definition: switch_apr.c:290
switch_status_t switch_mutex_lock(switch_mutex_t *lock)
Definition: switch_apr.c:285
void switch_buffer_zero(_In_ switch_buffer_t *buffer)
Remove all data from the buffer.
uint32_t record_frame_size
switch_buffer_t * raw_read_buffer
switch_mutex_t * write_mutex
switch_status_t switch_core_media_bug_flush_all ( switch_core_session_t session)

Definition at line 861 of file switch_core_media_bug.c.

References switch_media_bug::next, switch_core_media_bug_flush(), SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, switch_thread_rwlock_unlock(), and switch_thread_rwlock_wrlock().

862 {
863  switch_media_bug_t *bp;
864 
865  if (session->bugs) {
867  for (bp = session->bugs; bp; bp = bp->next) {
869  }
871  return SWITCH_STATUS_SUCCESS;
872  }
873 
874  return SWITCH_STATUS_FALSE;
875 }
switch_status_t switch_thread_rwlock_unlock(switch_thread_rwlock_t *rwlock)
Definition: switch_apr.c:263
switch_thread_rwlock_t * bug_rwlock
switch_status_t switch_thread_rwlock_wrlock(switch_thread_rwlock_t *rwlock)
Definition: switch_apr.c:237
switch_media_bug_t * bugs
struct switch_media_bug * next
void switch_core_media_bug_flush(switch_media_bug_t *bug)
switch_frame_t* switch_core_media_bug_get_read_replace_frame ( switch_media_bug_t bug)

Definition at line 106 of file switch_core_media_bug.c.

107 {
108  return bug->read_replace_frame_in;
109 }
switch_frame_t * read_replace_frame_in
switch_core_session_t* switch_core_media_bug_get_session ( switch_media_bug_t bug)

Definition at line 86 of file switch_core_media_bug.c.

Referenced by switch_core_media_bug_close(), and switch_core_media_bug_read().

87 {
88  return bug->session;
89 }
switch_core_session_t * session
void* switch_core_media_bug_get_user_data ( switch_media_bug_t bug)

Definition at line 131 of file switch_core_media_bug.c.

132 {
133  return bug->user_data;
134 }
switch_frame_t* switch_core_media_bug_get_write_replace_frame ( switch_media_bug_t bug)

Definition at line 96 of file switch_core_media_bug.c.

97 {
98  return bug->write_replace_frame_in;
99 }
switch_frame_t * write_replace_frame_in
switch_status_t switch_core_media_bug_read ( switch_media_bug_t bug,
switch_frame_t frame,
switch_bool_t  fill 
)

Definition at line 183 of file switch_core_media_bug.c.

References switch_codec_implementation::actual_samples_per_second, switch_codec_implementation::decoded_bytes_per_packet, memset(), switch_codec_implementation::number_of_channels, SMBF_READ_STREAM, SMBF_STEREO, SMBF_STEREO_SWAP, SMBF_WRITE_STREAM, switch_assert, switch_buffer_inuse(), switch_buffer_read(), switch_buffer_toss(), switch_channel_get_name(), SWITCH_CHANNEL_SESSION_LOG, switch_core_media_bug_flush(), switch_core_media_bug_get_session(), switch_core_session_get_read_impl(), SWITCH_LOG_ERROR, switch_log_printf(), switch_mutex_lock(), switch_mutex_unlock(), switch_normalize_to_16bit, SWITCH_RECOMMENDED_BUFFER_SIZE, SWITCH_SMAX, SWITCH_SMIN, SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, and switch_test_flag.

184 {
185  switch_size_t bytes = 0, datalen = 0;
186  int16_t *dp, *fp;
187  uint32_t x;
188  size_t rlen = 0;
189  size_t wlen = 0;
190  uint32_t blen;
191  switch_codec_implementation_t read_impl = { 0 };
192  int16_t *tp;
193  switch_size_t do_read = 0, do_write = 0, has_read = 0, has_write = 0, fill_read = 0, fill_write = 0;
194 
195  switch_core_session_get_read_impl(bug->session, &read_impl);
196 
197  bytes = read_impl.decoded_bytes_per_packet;
198 
199  if (frame->buflen < bytes) {
202  return SWITCH_STATUS_FALSE;
203  }
204 
205  if ((!bug->raw_read_buffer && (!bug->raw_write_buffer || !switch_test_flag(bug, SMBF_WRITE_STREAM)))) {
207  "%s Buffer Error (raw_read_buffer=%p, raw_write_buffer=%p, read=%s, write=%s)\n",
209  (void *)bug->raw_read_buffer, (void *)bug->raw_write_buffer,
210  switch_test_flag(bug, SMBF_READ_STREAM) ? "yes" : "no",
211  switch_test_flag(bug, SMBF_WRITE_STREAM) ? "yes" : "no");
212  return SWITCH_STATUS_FALSE;
213  }
214 
215  frame->flags = 0;
216  frame->datalen = 0;
217 
219  has_read = 1;
221  do_read = switch_buffer_inuse(bug->raw_read_buffer);
223  }
224 
226  has_write = 1;
228  do_write = switch_buffer_inuse(bug->raw_write_buffer);
230  }
231 
232 
233  if (bug->record_frame_size && bug->record_pre_buffer_max && (do_read || do_write) && bug->record_pre_buffer_count < bug->record_pre_buffer_max) {
235  return SWITCH_STATUS_FALSE;
236  } else {
237  uint32_t frame_size;
238  switch_codec_implementation_t read_impl = { 0 };
239 
240  switch_core_session_get_read_impl(bug->session, &read_impl);
241  frame_size = read_impl.decoded_bytes_per_packet;
242  bug->record_frame_size = frame_size;
243  }
244 
245  if (bug->record_frame_size && do_write > do_read && do_write > (bug->record_frame_size * 2)) {
248  do_write = switch_buffer_inuse(bug->raw_write_buffer);
250  }
251 
252 
253 
254  if ((has_read && !do_read)) {
255  fill_read = 1;
256  }
257 
258  if ((has_write && !do_write)) {
259  fill_write = 1;
260  }
261 
262 
263  if (bug->record_frame_size) {
264  if ((do_read && do_read < bug->record_frame_size) || (do_write && do_write < bug->record_frame_size)) {
265  return SWITCH_STATUS_FALSE;
266  }
267 
268  if (do_read && do_read > bug->record_frame_size) {
269  do_read = bug->record_frame_size;
270  }
271 
272  if (do_write && do_write > bug->record_frame_size) {
273  do_write = bug->record_frame_size;
274  }
275  }
276 
277  if ((fill_read && fill_write) || (fill && (fill_read || fill_write))) {
278  return SWITCH_STATUS_FALSE;
279  }
280 
281  if (do_read && do_read > SWITCH_RECOMMENDED_BUFFER_SIZE) {
282  do_read = 1280;
283  }
284 
285  if (do_write && do_write > SWITCH_RECOMMENDED_BUFFER_SIZE) {
286  do_write = 1280;
287  }
288 
289  if (do_read) {
291  frame->datalen = (uint32_t) switch_buffer_read(bug->raw_read_buffer, frame->data, do_read);
292  if (frame->datalen != do_read) {
296  return SWITCH_STATUS_FALSE;
297  }
299  } else if (fill_read) {
300  frame->datalen = (uint32_t)bytes;
301  memset(frame->data, 255, frame->datalen);
302  }
303 
304  if (do_write) {
307  datalen = (uint32_t) switch_buffer_read(bug->raw_write_buffer, bug->data, do_write);
308  if (datalen != do_write) {
312  return SWITCH_STATUS_FALSE;
313  }
315  } else if (fill_write) {
316  datalen = bytes;
317  memset(bug->data, 255, datalen);
318  }
319 
320  tp = bug->tmp;
321  dp = (int16_t *) bug->data;
322  fp = (int16_t *) frame->data;
323  rlen = frame->datalen / 2;
324  wlen = datalen / 2;
325  blen = (uint32_t)(bytes / 2);
326 
327  if (switch_test_flag(bug, SMBF_STEREO)) {
328  int16_t *left, *right;
329  size_t left_len, right_len;
331  left = dp; /* write stream */
332  left_len = wlen;
333  right = fp; /* read stream */
334  right_len = rlen;
335  } else {
336  left = fp; /* read stream */
337  left_len = rlen;
338  right = dp; /* write stream */
339  right_len = wlen;
340  }
341  for (x = 0; x < blen; x++) {
342  if (x < left_len) {
343  *(tp++) = *(left + x);
344  } else {
345  *(tp++) = 0;
346  }
347  if (x < right_len) {
348  *(tp++) = *(right + x);
349  } else {
350  *(tp++) = 0;
351  }
352  }
353  memcpy(frame->data, bug->tmp, bytes * 2);
354  } else {
355  for (x = 0; x < blen; x++) {
356  int32_t w = 0, r = 0, z = 0;
357 
358  if (x < rlen) {
359  r = (int32_t) * (fp + x);
360  }
361 
362  if (x < wlen) {
363  w = (int32_t) * (dp + x);
364  }
365 
366  z = w + r;
367 
368  if (z > SWITCH_SMAX || z < SWITCH_SMIN) {
369  if (r) z += (r/2);
370  if (w) z += (w/2);
371  }
372 
374 
375  *(fp + x) = (int16_t) z;
376  }
377  }
378 
379  frame->datalen = (uint32_t)bytes;
380  frame->samples = (uint32_t)(bytes / sizeof(int16_t) / read_impl.number_of_channels);
381  frame->rate = read_impl.actual_samples_per_second;
382  frame->codec = NULL;
383 
384  if (switch_test_flag(bug, SMBF_STEREO)) {
385  frame->datalen *= 2;
386  frame->channels = 2;
387  } else {
388  frame->channels = read_impl.number_of_channels;
389  }
390 
391  return SWITCH_STATUS_SUCCESS;
392 }
#define SWITCH_CHANNEL_SESSION_LOG(x)
switch_size_t switch_buffer_read(_In_ switch_buffer_t *buffer, _In_ void *data, _In_ switch_size_t datalen)
Read data from a switch_buffer_t up to the ammount of datalen if it is available. Remove read data fr...
#define SWITCH_RECOMMENDED_BUFFER_SIZE
Definition: switch_types.h:557
uint32_t record_pre_buffer_count
switch_core_session_t * session
switch_buffer_t * raw_write_buffer
switch_codec_t * codec
Definition: switch_frame.h:45
switch_core_session_t * switch_core_media_bug_get_session(switch_media_bug_t *bug)
switch_mutex_t * read_mutex
switch_status_t switch_mutex_unlock(switch_mutex_t *lock)
Definition: switch_apr.c:290
switch_status_t switch_core_session_get_read_impl(switch_core_session_t *session, switch_codec_implementation_t *impp)
switch_size_t switch_buffer_toss(_In_ switch_buffer_t *buffer, _In_ switch_size_t datalen)
Remove data from the buffer.
uint32_t buflen
Definition: switch_frame.h:59
switch_channel_t * channel
uint32_t datalen
Definition: switch_frame.h:57
switch_frame_flag_t flags
Definition: switch_frame.h:74
switch_status_t switch_mutex_lock(switch_mutex_t *lock)
Definition: switch_apr.c:285
uint32_t rate
Definition: switch_frame.h:63
uintptr_t switch_size_t
#define SWITCH_SMAX
Definition: switch_utils.h:259
#define SWITCH_SMIN
Definition: switch_utils.h:260
void switch_core_media_bug_flush(switch_media_bug_t *bug)
uint32_t record_frame_size
uint32_t samples
Definition: switch_frame.h:61
uint32_t channels
Definition: switch_frame.h:65
int16_t tmp[SWITCH_RECOMMENDED_BUFFER_SIZE]
#define switch_test_flag(obj, flag)
Test for the existance of a flag on an arbitary object.
Definition: switch_utils.h:624
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
A table of settings and callbacks that define a paticular implementation of a codec.
#define switch_normalize_to_16bit(n)
Definition: switch_utils.h:261
uint8_t data[SWITCH_RECOMMENDED_BUFFER_SIZE]
switch_buffer_t * raw_read_buffer
#define switch_assert(expr)
switch_mutex_t * write_mutex
switch_size_t switch_buffer_inuse(_In_ switch_buffer_t *buffer)
Get the in use amount of a switch_buffer_t.
char * switch_channel_get_name(switch_channel_t *channel)
Retrieve the name of a given channel.
memset(buf, 0, buflen)
uint32_t record_pre_buffer_max
switch_status_t switch_core_media_bug_remove ( switch_core_session_t session,
switch_media_bug_t **  bug 
)

Definition at line 1199 of file switch_core_media_bug.c.

References switch_media_bug::next, switch_media_bug::ready, SMBF_LOCK, SMBF_TAP_NATIVE_READ, SMBF_TAP_NATIVE_WRITE, SSF_MEDIA_BUG_TAP_ONLY, switch_clear_flag, switch_core_codec_destroy(), switch_core_codec_ready(), switch_core_media_bug_close(), switch_core_media_bug_test_flag(), switch_set_flag, SWITCH_STATUS_FALSE, switch_test_flag, switch_thread_rwlock_unlock(), switch_thread_rwlock_wrlock(), switch_thread_self(), and switch_media_bug::thread_id.

1200 {
1201  switch_media_bug_t *bp = NULL, *bp2 = NULL, *last = NULL;
1203  int tap_only = 0;
1204 
1206  return status;
1207  }
1208 
1210  if (session->bugs) {
1211  for (bp = session->bugs; bp; bp = bp->next) {
1212  if ((!bp->thread_id || bp->thread_id == switch_thread_self()) && bp->ready && bp == *bug) {
1213  if (last) {
1214  last->next = bp->next;
1215  } else {
1216  session->bugs = bp->next;
1217  }
1218  break;
1219  }
1220 
1221  last = bp;
1222  }
1223  }
1224 
1225  if (!session->bugs && switch_core_codec_ready(&session->bug_codec)) {
1227  }
1228 
1229  if (session->bugs) {
1230  for(bp2 = session->bugs; bp2; bp2 = bp2->next) {
1231  if (bp2->ready && !switch_test_flag(bp2, SMBF_TAP_NATIVE_READ) && !switch_test_flag(bp2, SMBF_TAP_NATIVE_WRITE)) {
1232  tap_only = 0;
1233  }
1234  }
1235  }
1236 
1237  if (tap_only) {
1239  } else {
1241  }
1242 
1244 
1245  if (bp) {
1246  status = switch_core_media_bug_close(&bp);
1247  }
1248 
1249  return status;
1250 }
switch_status_t switch_thread_rwlock_unlock(switch_thread_rwlock_t *rwlock)
Definition: switch_apr.c:263
switch_thread_rwlock_t * bug_rwlock
#define switch_set_flag(obj, flag)
Set a flag on an arbitrary object.
Definition: switch_utils.h:631
switch_thread_id_t thread_id
switch_status_t switch_core_codec_destroy(switch_codec_t *codec)
Destroy an initalized codec handle.
#define switch_clear_flag(obj, flag)
Clear a flag on an arbitrary object while locked.
Definition: switch_utils.h:655
switch_status_t switch_thread_rwlock_wrlock(switch_thread_rwlock_t *rwlock)
Definition: switch_apr.c:237
switch_status_t switch_core_media_bug_close(switch_media_bug_t **bug)
switch_media_bug_t * bugs
struct switch_media_bug * next
uint32_t switch_core_media_bug_test_flag(switch_media_bug_t *bug, uint32_t flag)
switch_codec_t bug_codec
switch_status_t
Common return values.
#define switch_test_flag(obj, flag)
Test for the existance of a flag on an arbitary object.
Definition: switch_utils.h:624
static switch_bool_t switch_core_codec_ready(switch_codec_t *codec)
switch_thread_id_t switch_thread_self(void)
Definition: switch_apr.c:79
switch_status_t switch_core_media_bug_remove_all_function ( switch_core_session_t session,
const char *  function 
)

Definition at line 1096 of file switch_core_media_bug.c.

References switch_media_bug::callback, switch_media_bug::function, switch_media_bug::next, SMBF_LOCK, SSF_DESTROYABLE, SWITCH_ABC_TYPE_CLOSE, switch_channel_get_name(), SWITCH_CHANNEL_SESSION_LOG, switch_core_codec_destroy(), switch_core_codec_ready(), switch_core_media_bug_destroy(), SWITCH_LOG_DEBUG, switch_log_printf(), SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, switch_test_flag, switch_thread_rwlock_unlock(), switch_thread_rwlock_wrlock(), switch_thread_self(), switch_media_bug::thread_id, switch_media_bug::user_data, and zstr.

1097 {
1098  switch_media_bug_t *bp, *last = NULL;
1100 
1101  if (session->bugs) {
1103  for (bp = session->bugs; bp; bp = bp->next) {
1104  if (!switch_test_flag(session, SSF_DESTROYABLE) &&
1105  ((bp->thread_id && bp->thread_id != switch_thread_self()) || switch_test_flag(bp, SMBF_LOCK))) {
1106  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "BUG is thread locked skipping.\n");
1107  last = bp;
1108  continue;
1109  }
1110 
1111  if (!zstr(function) && strcmp(bp->function, function)) {
1112  last = bp;
1113  continue;
1114  }
1115 
1116  if (bp->callback) {
1118  }
1120  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Removing BUG from %s\n", switch_channel_get_name(session->channel));
1121 
1122  if (last) {
1123  last->next = bp->next;
1124  } else {
1125  session->bugs = bp->next;
1126  }
1127  }
1129  status = SWITCH_STATUS_SUCCESS;
1130  }
1131 
1132  if (switch_core_codec_ready(&session->bug_codec)) {
1134  }
1135 
1136  return status;
1137 }
static void switch_core_media_bug_destroy(switch_media_bug_t *bug)
switch_status_t switch_thread_rwlock_unlock(switch_thread_rwlock_t *rwlock)
Definition: switch_apr.c:263
#define SWITCH_CHANNEL_SESSION_LOG(x)
switch_thread_rwlock_t * bug_rwlock
switch_thread_id_t thread_id
switch_status_t switch_core_codec_destroy(switch_codec_t *codec)
Destroy an initalized codec handle.
switch_media_bug_callback_t callback
#define zstr(x)
Definition: switch_utils.h:281
switch_status_t switch_thread_rwlock_wrlock(switch_thread_rwlock_t *rwlock)
Definition: switch_apr.c:237
switch_channel_t * channel
switch_media_bug_t * bugs
struct switch_media_bug * next
switch_codec_t bug_codec
switch_status_t
Common return values.
#define switch_test_flag(obj, flag)
Test for the existance of a flag on an arbitary object.
Definition: switch_utils.h:624
static switch_bool_t switch_core_codec_ready(switch_codec_t *codec)
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
switch_thread_id_t switch_thread_self(void)
Definition: switch_apr.c:79
char * switch_channel_get_name(switch_channel_t *channel)
Retrieve the name of a given channel.
uint32_t switch_core_media_bug_set_flag ( switch_media_bug_t bug,
uint32_t  flag 
)

Definition at line 73 of file switch_core_media_bug.c.

References SMBF_LOCK, SMBF_PRUNE, switch_clear_flag, and switch_set_flag.

74 {
75  if ((flag & SMBF_PRUNE)) {
77  }
78  return switch_set_flag(bug, flag);
79 }
#define switch_set_flag(obj, flag)
Set a flag on an arbitrary object.
Definition: switch_utils.h:631
#define switch_clear_flag(obj, flag)
Clear a flag on an arbitrary object while locked.
Definition: switch_utils.h:655
void switch_core_media_bug_set_read_demux_frame ( switch_media_bug_t bug,
switch_frame_t frame 
)

Definition at line 126 of file switch_core_media_bug.c.

127 {
128  bug->read_demux_frame = frame;
129 }
switch_frame_t * read_demux_frame
void switch_core_media_bug_set_read_replace_frame ( switch_media_bug_t bug,
switch_frame_t frame 
)

Definition at line 121 of file switch_core_media_bug.c.

122 {
123  bug->read_replace_frame_out = frame;
124 }
switch_frame_t * read_replace_frame_out
void switch_core_media_bug_set_write_replace_frame ( switch_media_bug_t bug,
switch_frame_t frame 
)

Definition at line 101 of file switch_core_media_bug.c.

102 {
103  bug->write_replace_frame_out = frame;
104 }
switch_frame_t * write_replace_frame_out
uint32_t switch_core_media_bug_test_flag ( switch_media_bug_t bug,
uint32_t  flag 
)

Definition at line 68 of file switch_core_media_bug.c.

References switch_test_flag.

Referenced by switch_core_media_bug_add(), switch_core_media_bug_prune(), and switch_core_media_bug_remove().

69 {
70  return switch_test_flag(bug, flag);
71 }
#define switch_test_flag(obj, flag)
Test for the existance of a flag on an arbitary object.
Definition: switch_utils.h:624
static void* SWITCH_THREAD_FUNC video_bug_thread ( switch_thread_t thread,
void *  obj 
)
static

Definition at line 525 of file switch_core_media_bug.c.

References buf, switch_frame::buflen, buflen, switch_core_session::bug_rwlock, switch_media_bug::callback, vpx_image::d_h, vpx_image::d_w, switch_frame::data, switch_frame::flags, switch_frame::img, switch_frame::packet, switch_frame::packetlen, switch_media_bug::read_video_queue, switch_media_bug::ready, switch_media_bug::session, SFF_RAW_RTP, SMBF_PRUNE, SMBF_READ_VIDEO_STREAM, SMBF_WRITE_VIDEO_STREAM, switch_media_bug::stop_time, SWITCH_ABC_TYPE_STREAM_VIDEO_PING, switch_core_session_alloc, switch_epoch_time_now(), SWITCH_FALSE, switch_img_alloc(), SWITCH_IMG_FMT_I420, switch_img_free(), switch_img_patch(), switch_img_scale(), switch_queue_pop(), switch_queue_size(), switch_queue_trypop(), SWITCH_RTP_MAX_BUF_LEN, switch_set_flag, SWITCH_STATUS_SUCCESS, switch_test_flag, switch_thread_rwlock_rdlock(), switch_thread_rwlock_unlock(), switch_media_bug::user_data, switch_media_bug::video_ping_frame, and switch_media_bug::write_video_queue.

Referenced by switch_core_media_bug_add().

526 {
527  switch_media_bug_t *bug = (switch_media_bug_t *) obj;
528  switch_queue_t *main_q = NULL, *other_q = NULL;
529  switch_image_t *IMG = NULL, *img = NULL, *other_img = NULL;
530  void *pop;
531  uint8_t *buf;
533  switch_frame_t frame = { 0 };
534 
535  buf = switch_core_session_alloc(bug->session, buflen);
536  frame.packet = buf;
537  frame.data = buf + 12;
538  frame.packetlen = buflen;
539  frame.buflen = buflen - 12;
540  frame.flags = SFF_RAW_RTP;
541 
543  main_q = bug->read_video_queue;
544 
546  other_q = bug->write_video_queue;
547  }
548  } else if (switch_test_flag(bug, SMBF_WRITE_VIDEO_STREAM)) {
549  main_q = bug->write_video_queue;
550  } else {
551  return NULL;
552  }
553 
554  while (bug->ready) {
555  switch_status_t status;
556  int w = 0, h = 0, ok = 1;
557 
558 
559  if ((status = switch_queue_pop(main_q, &pop)) == SWITCH_STATUS_SUCCESS) {
560  switch_img_free(&img);
561 
562  if (!pop) {
563  goto end;
564  }
565 
566  img = (switch_image_t *) pop;
567 
568  w = img->d_w;
569  h = img->d_h;
570 
571  if (other_q) {
572  while(switch_queue_size(other_q) > 0) {
573  if ((status = switch_queue_trypop(other_q, &pop)) == SWITCH_STATUS_SUCCESS) {
574  switch_img_free(&other_img);
575  if (!(other_img = (switch_image_t *) pop)) {
576  goto end;
577  }
578  }
579  }
580 
581  if (other_img) {
582  if (other_img->d_w != w || other_img->d_h != h) {
583  switch_image_t *tmp_img = NULL;
584 
585  switch_img_scale(other_img, &tmp_img, w, h);
586  switch_img_free(&other_img);
587  other_img = tmp_img;
588  }
589  }
590 
591  w *= 2;
592 
593  if (!IMG || IMG->d_h != h || IMG->d_w != w) {
594  switch_img_free(&IMG);
595  IMG = switch_img_alloc(NULL, SWITCH_IMG_FMT_I420, w, h, 1);
596  }
597 
598  switch_img_patch(IMG, img, 0, 0);
599 
600  if (other_img) {
601  switch_img_patch(IMG, other_img, w / 2, 0);
602  }
603  }
604 
606  frame.img = other_q ? IMG : img;
607  bug->video_ping_frame = &frame;
608  if (bug->callback) {
610  || (bug->stop_time && bug->stop_time <= switch_epoch_time_now(NULL))) {
611  ok = SWITCH_FALSE;
612  }
613  }
614  bug->video_ping_frame = NULL;
616 
617  if (!ok) {
619  goto end;
620  }
621  }
622  }
623 
624  end:
625 
626  switch_img_free(&IMG);
627  switch_img_free(&img);
628  switch_img_free(&other_img);
629 
630  while (switch_queue_trypop(main_q, &pop) == SWITCH_STATUS_SUCCESS && pop) {
631  img = (switch_image_t *) pop;
632  switch_img_free(&img);
633  }
634 
635  if (other_q) {
636  while (switch_queue_trypop(other_q, &pop) == SWITCH_STATUS_SUCCESS && pop) {
637  img = (switch_image_t *) pop;
638  switch_img_free(&img);
639  }
640  }
641 
642  return NULL;
643 }
struct apr_queue_t switch_queue_t
Definition: switch_apr.h:590
unsigned int switch_queue_size(switch_queue_t *queue)
Definition: switch_apr.c:1114
switch_status_t switch_thread_rwlock_unlock(switch_thread_rwlock_t *rwlock)
Definition: switch_apr.c:263
Image Descriptor.
Definition: switch_image.h:88
void switch_img_patch(switch_image_t *IMG, switch_image_t *img, int x, int y)
patch a small img to a big IMG at position x,y
switch_thread_rwlock_t * bug_rwlock
#define switch_set_flag(obj, flag)
Set a flag on an arbitrary object.
Definition: switch_utils.h:631
void switch_img_free(switch_image_t **img)
Close an image descriptor.
switch_queue_t * read_video_queue
#define SWITCH_RTP_MAX_BUF_LEN
Definition: switch_rtp.h:44
switch_status_t switch_queue_trypop(switch_queue_t *queue, void **data)
Definition: switch_apr.c:1140
switch_core_session_t * session
switch_status_t switch_queue_pop(switch_queue_t *queue, void **data)
Definition: switch_apr.c:1119
switch_media_bug_callback_t callback
switch_image_t * switch_img_alloc(switch_image_t *img, switch_img_fmt_t fmt, unsigned int d_w, unsigned int d_h, unsigned int align)
Open a descriptor, allocating storage for the underlying image.
unsigned int d_w
Definition: switch_image.h:99
switch_queue_t * write_video_queue
switch_status_t switch_thread_rwlock_rdlock(switch_thread_rwlock_t *rwlock)
Definition: switch_apr.c:227
uint32_t buflen
Definition: switch_frame.h:59
switch_byte_t switch_byte_t * buf
uint32_t packetlen
Definition: switch_frame.h:51
switch_frame_flag_t flags
Definition: switch_frame.h:74
An abstraction of a data frame.
Definition: switch_frame.h:43
uintptr_t switch_size_t
switch_frame_t * video_ping_frame
switch_byte_t switch_byte_t uint32_t buflen
switch_status_t switch_img_scale(switch_image_t *src, switch_image_t **destP, int width, int height)
void * packet
Definition: switch_frame.h:49
switch_image_t * img
Definition: switch_frame.h:77
switch_status_t
Common return values.
#define SWITCH_IMG_FMT_I420
Definition: switch_vpx.h:77
time_t switch_epoch_time_now(time_t *t)
Get the current epoch time.
Definition: switch_time.c:321
#define switch_core_session_alloc(_session, _memory)
Allocate memory from a session's pool.
Definition: switch_core.h:694
#define switch_test_flag(obj, flag)
Test for the existance of a flag on an arbitary object.
Definition: switch_utils.h:624
unsigned int d_h
Definition: switch_image.h:100