RTS API Documentation  1.10.11
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)
 
void switch_core_media_bug_set_media_params (switch_media_bug_t *bug, switch_mm_t *mm)
 
void switch_core_media_bug_get_media_params (switch_media_bug_t *bug, switch_mm_t *mm)
 
switch_core_session_tswitch_core_media_bug_get_session (switch_media_bug_t *bug)
 
const char * switch_core_media_bug_get_text (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 int flush_video_queue (switch_queue_t *q, int min)
 
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_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_bool_t destroy)
 
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

◆ MAX_BUG_BUFFER

#define MAX_BUG_BUFFER   1024 * 512

Definition at line 793 of file switch_core_media_bug.c.

Referenced by switch_core_media_bug_add().

Function Documentation

◆ flush_video_queue()

static int flush_video_queue ( switch_queue_t q,
int  min 
)
static

Definition at line 573 of file switch_core_media_bug.c.

References switch_img_free(), switch_queue_size(), switch_queue_trypop(), and SWITCH_STATUS_SUCCESS.

Referenced by video_bug_thread().

574 {
575  void *pop;
576 
577  if (switch_queue_size(q) > min) {
578  while (switch_queue_trypop(q, &pop) == SWITCH_STATUS_SUCCESS) {
579  switch_image_t *img = (switch_image_t *) pop;
580  switch_img_free(&img);
581  if (min && switch_queue_size(q) <= min) {
582  break;
583  }
584  }
585  }
586 
587  return switch_queue_size(q);
588 }
unsigned int switch_queue_size(switch_queue_t *queue)
Definition: switch_apr.c:1238
Image Descriptor.
Definition: switch_image.h:88
void switch_img_free(switch_image_t **img)
Close an image descriptor.
switch_status_t switch_queue_trypop(switch_queue_t *queue, void **data)
Definition: switch_apr.c:1264

◆ switch_core_media_bug_add()

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 794 of file switch_core_media_bug.c.

References switch_core_session::bug_rwlock, switch_core_session::bugs, switch_media_bug::callback, CF_VIDEO_DECODED_READ, CF_VIDEO_READ_TAPPED, CF_VIDEO_WRITE_TAPPED, switch_core_session::channel, switch_codec_implementation::decoded_bytes_per_packet, switch_media_bug::flags, switch_media_bug::function, MAX_BUG_BUFFER, switch_media_bug::next, pool, switch_core_session::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_FIRST, SMBF_ONE_ONLY, SMBF_READ_PING, SMBF_READ_REPLACE, SMBF_READ_STREAM, SMBF_READ_TEXT_STREAM, SMBF_READ_VIDEO_PATCH, 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_CODEC_FLAG_VIDEO_PATCHING, 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_zmalloc, switch_media_bug::target, switch_media_bug::text_buffer, switch_media_bug::text_framedata, switch_media_bug::text_framesize, switch_media_bug::thread_id, switch_media_bug::user_data, switch_media_bug::video_bug_thread, video_bug_thread(), switch_core_session::video_read_codec, 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().

801 {
802  switch_media_bug_t *bug, *bp;
803  switch_size_t bytes;
804  switch_event_t *event;
805  int tap_only = 1, punt = 0, added = 0;
806 
807  const char *p;
808 
809  if (!zstr(function)) {
810  if ((flags & SMBF_ONE_ONLY)) {
812  for (bp = session->bugs; bp; bp = bp->next) {
813  if (!zstr(bp->function) && !strcasecmp(function, bp->function)) {
814  punt = 1;
815  break;
816  }
817  }
819  }
820  }
821 
822  if (punt) {
823  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Only one bug of this type allowed!\n");
824  return SWITCH_STATUS_GENERR;
825  }
826 
827 
828  if (!switch_channel_media_ready(session->channel)) {
830  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cannot establish media. Media bug add failed.\n");
831  return SWITCH_STATUS_FALSE;
832  }
833  }
834 
835 
836 
837  *new_bug = NULL;
838 
839 
840  if ((p = switch_channel_get_variable(session->channel, "media_bug_answer_req")) && switch_true(p)) {
841  flags |= SMBF_ANSWER_REQ;
842  }
843 #if 0
844  if (flags & SMBF_WRITE_REPLACE) {
846  for (bp = session->bugs; bp; bp = bp->next) {
847  if (switch_test_flag(bp, SMBF_WRITE_REPLACE)) {
848  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Only one bug of this type allowed!\n");
850  return SWITCH_STATUS_GENERR;
851  }
852  }
854  }
855 
856  if (flags & SMBF_READ_REPLACE) {
858  for (bp = session->bugs; bp; bp = bp->next) {
859  if (switch_test_flag(bp, SMBF_READ_REPLACE)) {
860  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Only one bug of this type allowed!\n");
862  return SWITCH_STATUS_GENERR;
863  }
864  }
866  }
867 #endif
868 
869  if (!(bug = switch_core_session_alloc(session, sizeof(*bug)))) {
870  return SWITCH_STATUS_MEMERR;
871  }
872 
873  bug->callback = callback;
874  bug->user_data = user_data;
875  bug->session = session;
876  bug->flags = flags;
877  bug->function = "N/A";
878  bug->target = "N/A";
879 
882 
883  if (function) {
884  bug->function = switch_core_session_strdup(session, function);
885  }
886 
887  if (target) {
888  bug->target = switch_core_session_strdup(session, target);
889  }
890 
891  bug->stop_time = stop_time;
892 
893  if (!(bytes = bug->read_impl.decoded_bytes_per_packet)) {
894  bytes = 320;
895  }
896 
897  if (!bug->flags) {
899  }
900 
904  }
905 
907 
911  }
912 
913  if ((bug->flags & SMBF_THREAD_LOCK)) {
914  bug->thread_id = switch_thread_self();
915  }
916 
919 
922  }
923 
926  }
927  }
928 
932  }
933 
935 
936  switch_buffer_create_dynamic(&bug->text_buffer, 512, 1024, 0);
937  switch_zmalloc(bug->text_framedata, 1024);
938  bug->text_framesize = 1024;
939 
940  }
941 
944 
947  }
948 
951  }
952  }
953 
954 
955  if (bug->callback) {
956  switch_bool_t result = bug->callback(bug, bug->user_data, SWITCH_ABC_TYPE_INIT);
957  if (result == SWITCH_FALSE) {
959  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Error attaching BUG to %s\n",
960  switch_channel_get_name(session->channel));
961  return SWITCH_STATUS_GENERR;
962  }
963  }
964 
965  bug->ready = 1;
966 
968  switch_threadattr_t *thd_attr = NULL;
970  switch_threadattr_create(&thd_attr, pool);
972  switch_thread_create(&bug->video_bug_thread, thd_attr, video_bug_thread, bug, pool);
973 
974  }
975 
978 
979  if (!session->bugs) {
980  session->bugs = bug;
981  added = 1;
982  }
983 
984  if (!added && switch_test_flag(bug, SMBF_FIRST)) {
985  bug->next = session->bugs;
986  session->bugs = bug;
987  added = 1;
988  }
989 
990  for(bp = session->bugs; bp; bp = bp->next) {
992  tap_only = 0;
993  }
994 
995  if (!added && !bp->next) {
996  bp->next = bug;
997  break;
998  }
999  }
1000 
1002  *new_bug = bug;
1003 
1004  if (tap_only) {
1006  } else {
1008  }
1009 
1012  }
1013 
1015  switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Media-Bug-Function", "%s", bug->function);
1016  switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Media-Bug-Target", "%s", bug->target);
1017  switch_channel_event_set_data(session->channel, event);
1018  switch_event_fire(&event);
1019  }
1020 
1022 
1023  return SWITCH_STATUS_SUCCESS;
1024 }
#define switch_event_fire(event)
Fire an event filling in most of the arguements with obvious values.
Definition: switch_event.h:413
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:286
#define SWITCH_BUFFER_START_FRAMES
static switch_bool_t switch_true(const char *expr)
Evaluate the truthfullness of a string expression.
Definition: switch_utils.h:519
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:700
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:437
static void switch_core_media_bug_destroy(switch_media_bug_t **bug)
switch_codec_t * video_read_codec
switch_status_t switch_threadattr_stacksize_set(switch_threadattr_t *attr, switch_size_t stacksize)
Definition: switch_apr.c:683
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)
switch_buffer_t * text_buffer
switch_media_bug_callback_t callback
#define zstr(x)
Definition: switch_utils.h:314
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:724
#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:260
#define MAX_BUG_BUFFER
switch_channel_t * channel
#define SWITCH_CORE_QUEUE_LEN
Definition: switch_types.h:593
#define switch_channel_get_variable(_c, _v)
#define SWITCH_THREAD_STACKSIZE
Definition: switch_types.h:584
switch_thread_t * video_bug_thread
switch_queue_t * spy_video_queue[2]
#define switch_zmalloc(ptr, len)
switch_status_t switch_mutex_init(switch_mutex_t **lock, unsigned int flags, switch_memory_pool_t *pool)
Definition: switch_apr.c:293
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
const cJSON *const target
#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:384
#define switch_core_session_alloc(_session, _memory)
Allocate memory from a session&#39;s pool.
Definition: switch_core.h:696
#define switch_test_flag(obj, flag)
Test for the existance of a flag on an arbitary object.
Definition: switch_utils.h:693
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:665
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:698
struct fspr_pool_t switch_memory_pool_t
switch_status_t switch_queue_create(switch_queue_t **queue, unsigned int queue_capacity, switch_memory_pool_t *pool)
Definition: switch_apr.c:1233
#define switch_core_session_strdup(_session, _todup)
Copy a string using memory allocation from a session&#39;s pool.
Definition: switch_core.h:719
switch_thread_id_t switch_thread_self(void)
Definition: switch_apr.c:102
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.

◆ switch_core_media_bug_clear_flag()

uint32_t switch_core_media_bug_clear_flag ( switch_media_bug_t bug,
uint32_t  flag 
)

Definition at line 115 of file switch_core_media_bug.c.

References switch_clear_flag.

116 {
117  return switch_clear_flag(bug, flag);
118 }
#define switch_clear_flag(obj, flag)
Clear a flag on an arbitrary object while locked.
Definition: switch_utils.h:724

◆ switch_core_media_bug_close()

switch_status_t switch_core_media_bug_close ( switch_media_bug_t **  bug,
switch_bool_t  destroy 
)

Definition at line 1290 of file switch_core_media_bug.c.

References switch_media_bug::callback, CF_VIDEO_DECODED_READ, CF_VIDEO_READ_TAPPED, CF_VIDEO_WRITE_TAPPED, 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_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_LOG_DEBUG, switch_log_printf(), switch_queue_push(), SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, switch_test_flag, switch_thread_self(), switch_media_bug::thread_id, switch_media_bug::user_data, and switch_media_bug::write_video_queue.

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

1291 {
1292  switch_media_bug_t *bp = *bug;
1293 
1294  if (bp) {
1295  if ((bp->thread_id && bp->thread_id != switch_thread_self()) || switch_test_flag(bp, SMBF_LOCK)) {
1297  return SWITCH_STATUS_FALSE;
1298  }
1299 
1300  if (bp->callback) {
1302  }
1303 
1306 
1309  }
1310 
1313  }
1314  }
1315 
1316  bp->ready = 0;
1317 
1318  if (bp->read_video_queue) {
1320  }
1321 
1322  if (bp->write_video_queue) {
1324  }
1325 
1328 
1329  if (destroy) {
1331  }
1332 
1333  return SWITCH_STATUS_SUCCESS;
1334  }
1335 
1336  return SWITCH_STATUS_FALSE;
1337 }
#define SWITCH_CHANNEL_SESSION_LOG(x)
switch_thread_id_t thread_id
static void switch_core_media_bug_destroy(switch_media_bug_t **bug)
switch_queue_t * read_video_queue
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_channel_t * channel
switch_status_t switch_queue_push(switch_queue_t *queue, void *data)
Definition: switch_apr.c:1253
#define switch_test_flag(obj, flag)
Test for the existance of a flag on an arbitary object.
Definition: switch_utils.h:693
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:102
char * switch_channel_get_name(switch_channel_t *channel)
Retrieve the name of a given channel.

◆ switch_core_media_bug_destroy()

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, SMBF_READ_VIDEO_PATCH, switch_media_bug::spy_img, switch_media_bug::spy_video_queue, switch_buffer_destroy(), switch_channel_event_set_data(), switch_clear_flag, SWITCH_CODEC_FLAG_VIDEO_PATCHING, switch_event_add_header(), switch_event_create, switch_event_fire, SWITCH_EVENT_MEDIA_BUG_STOP, switch_img_free(), switch_queue_trypop(), switch_safe_free, SWITCH_STACK_BOTTOM, SWITCH_STATUS_SUCCESS, switch_test_flag, switch_thread_join(), switch_media_bug::target, switch_media_bug::text_buffer, switch_media_bug::text_framedata, switch_media_bug::video_bug_thread, and switch_core_session::video_read_codec.

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

39 {
40  switch_event_t *event = NULL;
41  switch_media_bug_t *bp = *bug;
42 
43  *bug = NULL;
44 
45  if (bp->text_buffer) {
48  }
49 
50  switch_img_free(&bp->spy_img[0]);
51  switch_img_free(&bp->spy_img[1]);
52 
53  if (bp->video_bug_thread) {
54  switch_status_t st;
55  int i;
56 
57  for (i = 0; i < 2; i++) {
58  void *pop;
59  switch_image_t *img;
60 
61  if (bp->spy_video_queue[i]) {
62  while (switch_queue_trypop(bp->spy_video_queue[i], &pop) == SWITCH_STATUS_SUCCESS && pop) {
63  img = (switch_image_t *) pop;
64  switch_img_free(&img);
65  }
66  }
67  }
68 
70  }
71 
74  }
75 
76  if (bp->raw_read_buffer) {
78  }
79 
80  if (bp->raw_write_buffer) {
82  }
83 
85  switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Media-Bug-Function", "%s", bp->function);
86  switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Media-Bug-Target", "%s", bp->target);
88  switch_event_fire(&event);
89  }
90 }
#define switch_event_fire(event)
Fire an event filling in most of the arguements with obvious values.
Definition: switch_event.h:413
Image Descriptor.
Definition: switch_image.h:88
void switch_img_free(switch_image_t **img)
Close an image descriptor.
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_codec_t * video_read_codec
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_status_t switch_queue_trypop(switch_queue_t *queue, void **data)
Definition: switch_apr.c:1264
switch_core_session_t * session
switch_buffer_t * raw_write_buffer
switch_buffer_t * text_buffer
#define switch_clear_flag(obj, flag)
Clear a flag on an arbitrary object while locked.
Definition: switch_utils.h:724
switch_channel_t * channel
switch_thread_t * video_bug_thread
switch_queue_t * spy_video_queue[2]
#define switch_safe_free(it)
Free a pointer and set it to NULL unless it already is NULL.
Definition: switch_utils.h:885
switch_image_t * spy_img[2]
switch_status_t switch_thread_join(switch_status_t *retval, switch_thread_t *thd)
Definition: switch_apr.c:1379
switch_status_t
Common return values.
#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:384
#define switch_test_flag(obj, flag)
Test for the existance of a flag on an arbitary object.
Definition: switch_utils.h:693
switch_buffer_t * raw_read_buffer
void switch_buffer_destroy(switch_buffer_t **buffer)
Destroy the buffer.

◆ switch_core_media_bug_flush()

void switch_core_media_bug_flush ( switch_media_bug_t bug)

Definition at line 185 of file switch_core_media_bug.c.

References switch_media_bug::raw_read_buffer, switch_media_bug::raw_write_buffer, switch_media_bug::read_mutex, switch_media_bug::record_frame_size, switch_media_bug::record_pre_buffer_count, switch_buffer_zero(), switch_mutex_lock(), switch_mutex_unlock(), and switch_media_bug::write_mutex.

Referenced by switch_core_media_bug_flush_all(), and switch_core_media_bug_read().

186 {
187 
188  bug->record_pre_buffer_count = 0;
189 
190  if (bug->raw_read_buffer) {
194  }
195 
196  if (bug->raw_write_buffer) {
200  }
201 
202  bug->record_frame_size = 0;
203  bug->record_pre_buffer_count = 0;
204 }
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:313
switch_status_t switch_mutex_lock(switch_mutex_t *lock)
Definition: switch_apr.c:308
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_core_media_bug_flush_all()

switch_status_t switch_core_media_bug_flush_all ( switch_core_session_t session)

Definition at line 1027 of file switch_core_media_bug.c.

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

1028 {
1029  switch_media_bug_t *bp;
1030 
1031  if (session->bugs) {
1033  for (bp = session->bugs; bp; bp = bp->next) {
1035  }
1037  return SWITCH_STATUS_SUCCESS;
1038  }
1039 
1040  return SWITCH_STATUS_FALSE;
1041 }
switch_status_t switch_thread_rwlock_unlock(switch_thread_rwlock_t *rwlock)
Definition: switch_apr.c:286
switch_thread_rwlock_t * bug_rwlock
switch_status_t switch_thread_rwlock_wrlock(switch_thread_rwlock_t *rwlock)
Definition: switch_apr.c:260
switch_media_bug_t * bugs
struct switch_media_bug * next
void switch_core_media_bug_flush(switch_media_bug_t *bug)

◆ switch_core_media_bug_get_read_replace_frame()

switch_frame_t* switch_core_media_bug_get_read_replace_frame ( switch_media_bug_t bug)

Definition at line 155 of file switch_core_media_bug.c.

References switch_media_bug::read_replace_frame_in.

156 {
157  return bug->read_replace_frame_in;
158 }
switch_frame_t * read_replace_frame_in

◆ switch_core_media_bug_get_session()

switch_core_session_t* switch_core_media_bug_get_session ( switch_media_bug_t bug)

Definition at line 130 of file switch_core_media_bug.c.

References switch_media_bug::session.

Referenced by switch_core_media_bug_close(), and switch_core_media_bug_read().

131 {
132  return bug->session;
133 }
switch_core_session_t * session

◆ switch_core_media_bug_get_user_data()

void* switch_core_media_bug_get_user_data ( switch_media_bug_t bug)

Definition at line 180 of file switch_core_media_bug.c.

References switch_media_bug::user_data.

181 {
182  return bug->user_data;
183 }

◆ switch_core_media_bug_get_write_replace_frame()

switch_frame_t* switch_core_media_bug_get_write_replace_frame ( switch_media_bug_t bug)

Definition at line 145 of file switch_core_media_bug.c.

References switch_media_bug::write_replace_frame_in.

146 {
147  return bug->write_replace_frame_in;
148 }
switch_frame_t * write_replace_frame_in

◆ switch_core_media_bug_read()

switch_status_t switch_core_media_bug_read ( switch_media_bug_t bug,
switch_frame_t frame,
switch_bool_t  fill 
)

Definition at line 232 of file switch_core_media_bug.c.

References switch_codec_implementation::actual_samples_per_second, switch_frame::buflen, switch_core_session::channel, switch_frame::channels, switch_frame::codec, switch_frame::data, switch_media_bug::data, switch_frame::datalen, switch_codec_implementation::decoded_bytes_per_packet, switch_frame::flags, memset(), switch_codec_implementation::number_of_channels, switch_frame::rate, switch_media_bug::raw_read_buffer, switch_media_bug::raw_write_buffer, switch_rtp_engine_s::read_impl, switch_media_bug::read_mutex, switch_media_bug::record_frame_size, switch_media_bug::record_pre_buffer_count, switch_media_bug::record_pre_buffer_max, switch_frame::samples, switch_media_bug::session, 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, switch_test_flag, switch_media_bug::tmp, and switch_media_bug::write_mutex.

233 {
234  switch_size_t bytes = 0, datalen = 0;
235  int16_t *dp, *fp;
236  uint32_t x;
237  size_t rlen = 0;
238  size_t wlen = 0;
239  uint32_t blen;
240  switch_codec_implementation_t read_impl = { 0 };
241  int16_t *tp;
242  switch_size_t do_read = 0, do_write = 0, has_read = 0, has_write = 0, fill_read = 0, fill_write = 0;
243 
244  switch_core_session_get_read_impl(bug->session, &read_impl);
245 
246  bytes = read_impl.decoded_bytes_per_packet;
247 
248  if (frame->buflen < bytes) {
251  return SWITCH_STATUS_FALSE;
252  }
253 
254  if ((!bug->raw_read_buffer && (!bug->raw_write_buffer || !switch_test_flag(bug, SMBF_WRITE_STREAM)))) {
256  "%s Buffer Error (raw_read_buffer=%p, raw_write_buffer=%p, read=%s, write=%s)\n",
258  (void *)bug->raw_read_buffer, (void *)bug->raw_write_buffer,
259  switch_test_flag(bug, SMBF_READ_STREAM) ? "yes" : "no",
260  switch_test_flag(bug, SMBF_WRITE_STREAM) ? "yes" : "no");
261  return SWITCH_STATUS_FALSE;
262  }
263 
264  frame->flags = 0;
265  frame->datalen = 0;
266 
268  has_read = 1;
270  do_read = switch_buffer_inuse(bug->raw_read_buffer);
272  }
273 
275  has_write = 1;
277  do_write = switch_buffer_inuse(bug->raw_write_buffer);
279  }
280 
281 
282  if (bug->record_frame_size && bug->record_pre_buffer_max && (do_read || do_write) && bug->record_pre_buffer_count < bug->record_pre_buffer_max) {
284  return SWITCH_STATUS_FALSE;
285  } else {
286  uint32_t frame_size;
287  switch_codec_implementation_t read_impl = { 0 };
288 
289  switch_core_session_get_read_impl(bug->session, &read_impl);
290  frame_size = read_impl.decoded_bytes_per_packet;
291  bug->record_frame_size = frame_size;
292  }
293 
294  if (bug->record_frame_size && do_write > do_read && do_write > (bug->record_frame_size * 2)) {
297  do_write = switch_buffer_inuse(bug->raw_write_buffer);
299  }
300 
301 
302 
303  if ((has_read && !do_read)) {
304  fill_read = 1;
305  }
306 
307  if ((has_write && !do_write)) {
308  fill_write = 1;
309  }
310 
311 
312  if (bug->record_frame_size) {
313  if ((do_read && do_read < bug->record_frame_size) || (do_write && do_write < bug->record_frame_size)) {
314  return SWITCH_STATUS_FALSE;
315  }
316 
317  if (do_read && do_read > bug->record_frame_size) {
318  do_read = bug->record_frame_size;
319  }
320 
321  if (do_write && do_write > bug->record_frame_size) {
322  do_write = bug->record_frame_size;
323  }
324  }
325 
326  if ((fill_read && fill_write) || (fill && (fill_read || fill_write))) {
327  return SWITCH_STATUS_FALSE;
328  }
329 
330  if (do_read && do_read > SWITCH_RECOMMENDED_BUFFER_SIZE) {
331  do_read = 1280;
332  }
333 
334  if (do_write && do_write > SWITCH_RECOMMENDED_BUFFER_SIZE) {
335  do_write = 1280;
336  }
337 
338  if (do_read) {
340  frame->datalen = (uint32_t) switch_buffer_read(bug->raw_read_buffer, frame->data, do_read);
341  if (frame->datalen != do_read) {
345  return SWITCH_STATUS_FALSE;
346  }
348  } else if (fill_read) {
349  frame->datalen = (uint32_t)bytes;
350  memset(frame->data, 255, frame->datalen);
351  }
352 
353  if (do_write) {
356  datalen = (uint32_t) switch_buffer_read(bug->raw_write_buffer, bug->data, do_write);
357  if (datalen != do_write) {
361  return SWITCH_STATUS_FALSE;
362  }
364  } else if (fill_write) {
365  datalen = bytes;
366  memset(bug->data, 255, datalen);
367  }
368 
369  tp = bug->tmp;
370  dp = (int16_t *) bug->data;
371  fp = (int16_t *) frame->data;
372  rlen = frame->datalen / 2;
373  wlen = datalen / 2;
374  blen = (uint32_t)(bytes / 2);
375 
376  if (switch_test_flag(bug, SMBF_STEREO)) {
377  int16_t *left, *right;
378  size_t left_len, right_len;
380  left = dp; /* write stream */
381  left_len = wlen;
382  right = fp; /* read stream */
383  right_len = rlen;
384  } else {
385  left = fp; /* read stream */
386  left_len = rlen;
387  right = dp; /* write stream */
388  right_len = wlen;
389  }
390  for (x = 0; x < blen; x++) {
391  if (x < left_len) {
392  *(tp++) = *(left + x);
393  } else {
394  *(tp++) = 0;
395  }
396  if (x < right_len) {
397  *(tp++) = *(right + x);
398  } else {
399  *(tp++) = 0;
400  }
401  }
402  memcpy(frame->data, bug->tmp, bytes * 2);
403  } else {
404  for (x = 0; x < blen; x++) {
405  int32_t w = 0, r = 0, z = 0;
406 
407  if (x < rlen) {
408  r = (int32_t) * (fp + x);
409  }
410 
411  if (x < wlen) {
412  w = (int32_t) * (dp + x);
413  }
414 
415  z = w + r;
416 
417  if (z > SWITCH_SMAX || z < SWITCH_SMIN) {
418  if (r) z += (r/2);
419  if (w) z += (w/2);
420  }
421 
423 
424  *(fp + x) = (int16_t) z;
425  }
426  }
427 
428  frame->datalen = (uint32_t)bytes;
429  frame->samples = (uint32_t)(bytes / sizeof(int16_t) / read_impl.number_of_channels);
430  frame->rate = read_impl.actual_samples_per_second;
431  frame->codec = NULL;
432 
433  if (switch_test_flag(bug, SMBF_STEREO)) {
434  frame->datalen *= 2;
435  frame->channels = 2;
436  } else {
437  frame->channels = read_impl.number_of_channels;
438  }
439 
440  return SWITCH_STATUS_SUCCESS;
441 }
#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:590
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:56
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:313
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:70
switch_channel_t * channel
uint32_t datalen
Definition: switch_frame.h:68
switch_frame_flag_t flags
Definition: switch_frame.h:85
switch_status_t switch_mutex_lock(switch_mutex_t *lock)
Definition: switch_apr.c:308
uint32_t rate
Definition: switch_frame.h:74
uintptr_t switch_size_t
#define SWITCH_SMAX
Definition: switch_utils.h:290
#define SWITCH_SMIN
Definition: switch_utils.h:291
void switch_core_media_bug_flush(switch_media_bug_t *bug)
uint32_t record_frame_size
uint32_t samples
Definition: switch_frame.h:72
uint32_t channels
Definition: switch_frame.h:76
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:693
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:292
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_core_media_bug_remove()

switch_status_t switch_core_media_bug_remove ( switch_core_session_t session,
switch_media_bug_t **  bug 
)

Definition at line 1339 of file switch_core_media_bug.c.

References switch_core_session::bug_codec, switch_core_session::bug_rwlock, switch_core_session::bugs, 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(), SWITCH_TRUE, and switch_media_bug::thread_id.

1340 {
1341  switch_media_bug_t *bp = NULL, *bp2 = NULL, *last = NULL;
1343  int tap_only = 0;
1344 
1346  return status;
1347  }
1348 
1350  if (session->bugs) {
1351  for (bp = session->bugs; bp; bp = bp->next) {
1352  if ((!bp->thread_id || bp->thread_id == switch_thread_self()) && bp->ready && bp == *bug) {
1353  if (last) {
1354  last->next = bp->next;
1355  } else {
1356  session->bugs = bp->next;
1357  }
1358  break;
1359  }
1360 
1361  last = bp;
1362  }
1363  }
1364 
1365  if (!session->bugs && switch_core_codec_ready(&session->bug_codec)) {
1367  }
1368 
1369  if (session->bugs) {
1370  for(bp2 = session->bugs; bp2; bp2 = bp2->next) {
1371  if (bp2->ready && !switch_test_flag(bp2, SMBF_TAP_NATIVE_READ) && !switch_test_flag(bp2, SMBF_TAP_NATIVE_WRITE)) {
1372  tap_only = 0;
1373  }
1374  }
1375  }
1376 
1377  if (tap_only) {
1379  } else {
1381  }
1382 
1384 
1385  if (bp) {
1387  }
1388 
1389  return status;
1390 }
switch_status_t switch_thread_rwlock_unlock(switch_thread_rwlock_t *rwlock)
Definition: switch_apr.c:286
switch_thread_rwlock_t * bug_rwlock
#define switch_set_flag(obj, flag)
Set a flag on an arbitrary object.
Definition: switch_utils.h:700
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:724
switch_status_t switch_thread_rwlock_wrlock(switch_thread_rwlock_t *rwlock)
Definition: switch_apr.c:260
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:693
static switch_bool_t switch_core_codec_ready(switch_codec_t *codec)
switch_thread_id_t switch_thread_self(void)
Definition: switch_apr.c:102
switch_status_t switch_core_media_bug_close(switch_media_bug_t **bug, switch_bool_t destroy)

◆ switch_core_media_bug_remove_all_function()

switch_status_t switch_core_media_bug_remove_all_function ( switch_core_session_t session,
const char *  function 
)

Definition at line 1237 of file switch_core_media_bug.c.

References switch_core_session::bug_codec, switch_core_session::bug_rwlock, switch_core_session::bugs, switch_media_bug::function, switch_media_bug::next, SMBF_LOCK, SSF_DESTROYABLE, SWITCH_CHANNEL_SESSION_LOG, switch_core_codec_destroy(), switch_core_codec_ready(), switch_core_media_bug_close(), switch_core_media_bug_destroy(), SWITCH_FALSE, 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, and zstr.

1238 {
1239  switch_media_bug_t *bp, *last = NULL, *next = NULL;
1241  switch_media_bug_t *closed = NULL;
1242 
1244  if (session->bugs) {
1245  for (bp = session->bugs; bp; bp = next) {
1246  next = bp->next;
1247 
1248  if (!switch_test_flag(session, SSF_DESTROYABLE) &&
1249  ((bp->thread_id && bp->thread_id != switch_thread_self()) || switch_test_flag(bp, SMBF_LOCK))) {
1250  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "BUG is thread locked skipping.\n");
1251  last = bp;
1252  continue;
1253  }
1254 
1255  if (!zstr(function) && strcmp(bp->function, function)) {
1256  last = bp;
1257  continue;
1258  }
1259 
1260  if (last) {
1261  last->next = bp->next;
1262  } else {
1263  session->bugs = bp->next;
1264  }
1265 
1266  bp->next = closed;
1267  closed = bp;
1268 
1270  }
1271  status = SWITCH_STATUS_SUCCESS;
1272  }
1274 
1275 
1276  if (closed) {
1277  for (bp = closed; bp; bp = next) {
1278  next = bp->next;
1280  }
1281  }
1282 
1283  if (switch_core_codec_ready(&session->bug_codec)) {
1285  }
1286 
1287  return status;
1288 }
switch_status_t switch_thread_rwlock_unlock(switch_thread_rwlock_t *rwlock)
Definition: switch_apr.c:286
#define SWITCH_CHANNEL_SESSION_LOG(x)
switch_thread_rwlock_t * bug_rwlock
switch_thread_id_t thread_id
static void switch_core_media_bug_destroy(switch_media_bug_t **bug)
switch_status_t switch_core_codec_destroy(switch_codec_t *codec)
Destroy an initalized codec handle.
#define zstr(x)
Definition: switch_utils.h:314
switch_status_t switch_thread_rwlock_wrlock(switch_thread_rwlock_t *rwlock)
Definition: switch_apr.c:260
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:693
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:102
switch_status_t switch_core_media_bug_close(switch_media_bug_t **bug, switch_bool_t destroy)

◆ switch_core_media_bug_set_flag()

uint32_t switch_core_media_bug_set_flag ( switch_media_bug_t bug,
uint32_t  flag 
)

Definition at line 107 of file switch_core_media_bug.c.

References SMBF_LOCK, SMBF_PRUNE, switch_clear_flag, and switch_set_flag.

108 {
109  if ((flag & SMBF_PRUNE)) {
111  }
112  return switch_set_flag(bug, flag);
113 }
#define switch_set_flag(obj, flag)
Set a flag on an arbitrary object.
Definition: switch_utils.h:700
#define switch_clear_flag(obj, flag)
Clear a flag on an arbitrary object while locked.
Definition: switch_utils.h:724

◆ switch_core_media_bug_set_read_demux_frame()

void switch_core_media_bug_set_read_demux_frame ( switch_media_bug_t bug,
switch_frame_t frame 
)

Definition at line 175 of file switch_core_media_bug.c.

References switch_media_bug::read_demux_frame.

176 {
177  bug->read_demux_frame = frame;
178 }
switch_frame_t * read_demux_frame

◆ switch_core_media_bug_set_read_replace_frame()

void switch_core_media_bug_set_read_replace_frame ( switch_media_bug_t bug,
switch_frame_t frame 
)

Definition at line 170 of file switch_core_media_bug.c.

References switch_media_bug::read_replace_frame_out.

171 {
172  bug->read_replace_frame_out = frame;
173 }
switch_frame_t * read_replace_frame_out

◆ switch_core_media_bug_set_write_replace_frame()

void switch_core_media_bug_set_write_replace_frame ( switch_media_bug_t bug,
switch_frame_t frame 
)

Definition at line 150 of file switch_core_media_bug.c.

References switch_media_bug::write_replace_frame_out.

151 {
152  bug->write_replace_frame_out = frame;
153 }
switch_frame_t * write_replace_frame_out

◆ switch_core_media_bug_test_flag()

uint32_t switch_core_media_bug_test_flag ( switch_media_bug_t bug,
uint32_t  flag 
)

Definition at line 102 of file switch_core_media_bug.c.

References switch_test_flag.

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

103 {
104  return switch_test_flag(bug, flag);
105 }
#define switch_test_flag(obj, flag)
Test for the existance of a flag on an arbitary object.
Definition: switch_utils.h:693

◆ video_bug_thread()

static void* SWITCH_THREAD_FUNC video_bug_thread ( switch_thread_t thread,
void *  obj 
)
static

Definition at line 590 of file switch_core_media_bug.c.

References buf, switch_frame::buflen, buflen, switch_core_session::bug_rwlock, switch_media_bug::callback, CF_ANSWERED, switch_core_session::channel, vpx_image::d_h, vpx_image::d_w, switch_frame::data, switch_frame::flags, flush_video_queue(), switch_mm_s::fps, switch_frame::img, switch_fps_s::ms, switch_frame::packet, switch_frame::packetlen, POS_CENTER_MID, switch_media_bug::read_video_queue, switch_media_bug::ready, switch_fps_s::samples, switch_media_bug::session, SFF_RAW_RTP, SMBF_ANSWER_REQ, SMBF_PRUNE, SMBF_READ_VIDEO_STREAM, SMBF_WRITE_VIDEO_STREAM, switch_media_bug::stop_time, SWITCH_ABC_TYPE_STREAM_VIDEO_PING, switch_calc_video_fps, switch_channel_test_flag(), switch_color_set_rgb(), switch_core_media_bug_get_media_params(), switch_core_media_bug_test_flag(), switch_core_session_alloc, switch_core_timer_destroy(), switch_core_timer_init(), switch_core_timer_next(), switch_epoch_time_now(), SWITCH_FALSE, SWITCH_FIT_SIZE, switch_img_alloc(), switch_img_fill(), switch_img_find_position(), switch_img_fit(), SWITCH_IMG_FMT_I420, switch_img_free(), switch_img_patch(), 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_mm_s::vh, switch_media_bug::video_ping_frame, switch_mm_s::vw, and switch_media_bug::write_video_queue.

Referenced by switch_core_media_bug_add().

591 {
592  switch_media_bug_t *bug = (switch_media_bug_t *) obj;
593  switch_queue_t *main_q = NULL, *other_q = NULL;
594  switch_image_t *IMG = NULL, *img = NULL, *other_img = NULL;
595  void *pop, *other_pop;
596  uint8_t *buf;
598  switch_frame_t frame = { 0 };
599  switch_timer_t timer = { 0 };
600  switch_mm_t mm = { 0 };
601  int vw = 1280;
602  int vh = 720;
603  int last_w = 0, last_h = 0, other_last_w = 0, other_last_h = 0;
604  switch_fps_t fps_data = { 0 };
605  float fps;
606  switch_rgb_color_t color = { 0 };
607  switch_color_set_rgb(&color, "#000000");
608 
609  buf = switch_core_session_alloc(bug->session, buflen);
610  frame.packet = buf;
611  frame.data = buf + 12;
612  frame.packetlen = buflen;
613  frame.buflen = buflen - 12;
614  frame.flags = SFF_RAW_RTP;
615 
617  main_q = bug->read_video_queue;
618 
620  other_q = bug->write_video_queue;
621  }
622  } else if (switch_test_flag(bug, SMBF_WRITE_VIDEO_STREAM)) {
623  main_q = bug->write_video_queue;
624  } else {
625  return NULL;
626  }
627 
629 
630  if (mm.vw) vw = mm.vw;
631  if (mm.vh) vh = mm.vh;
632 
633  if (mm.fps) {
634  fps = mm.fps;
635  } else {
636  fps = 15;
637  }
638  switch_calc_video_fps(&fps_data, fps);
639 
640  switch_core_timer_init(&timer, "soft", fps_data.ms, fps_data.samples, NULL);
641 
642  while (bug->ready) {
643  int w = 0, h = 0, ok = 1, new_main = 0, new_other = 0, new_canvas = 0;
644 
645  switch_core_timer_next(&timer);
646 
648  flush_video_queue(main_q, 0);
649  if (other_q) flush_video_queue(other_q, 0);
650  continue;
651  }
652 
653  flush_video_queue(main_q, 1);
654 
655  w = vw / 2;
656  h = vh;
657 
658  if (switch_queue_trypop(main_q, &pop) == SWITCH_STATUS_SUCCESS) {
659  switch_img_free(&img);
660 
661  if (!pop) {
662  goto end;
663  }
664 
665  img = (switch_image_t *) pop;
666  new_main = 1;
667 
668  if (IMG && !(last_w == img->d_w && last_h == img->d_h)) {
669  switch_img_fill(IMG, 0, 0, w, h, &color);
670  }
671 
672  last_w = img->d_w;
673  last_h = img->d_h;
674  }
675 
676  if (other_q) {
677  flush_video_queue(other_q, 1);
678 
679  if (switch_queue_trypop(other_q, &other_pop) == SWITCH_STATUS_SUCCESS) {
680  switch_img_free(&other_img);
681  other_img = (switch_image_t *) other_pop;
682 
683  if (IMG && !(other_last_w == other_img->d_w && other_last_h == other_img->d_h)) {
684  switch_img_fill(IMG, w, 0, w, h, &color);
685  }
686 
687  other_last_w = other_img->d_w;
688  other_last_h = other_img->d_h;
689  new_other = 1;
690  }
691 
692 
693  if (img && new_main) {
694  switch_img_fit(&img, w, h, SWITCH_FIT_SIZE);
695  }
696 
697  if (other_img && new_other) {
698  switch_img_fit(&other_img, w, h, SWITCH_FIT_SIZE);
699  }
700 
701  if (!IMG) {
702  IMG = switch_img_alloc(NULL, SWITCH_IMG_FMT_I420, vw, vh, 1);
703  new_canvas = 1;
704  switch_img_fill(IMG, 0, 0, IMG->d_w, IMG->d_h, &color);
705  }
706  }
707 
708 
709  if (IMG) {
710 
711 
712  if (img && (new_canvas || new_main)) {
713  int x = 0, y = 0;
714  switch_img_find_position(POS_CENTER_MID, w, h, img->d_w, img->d_h, &x, &y);
715 
716  switch_img_patch(IMG, img, x, y);
717  }
718 
719  if (other_img && (new_canvas || new_other)) {
720  int x = 0, y = 0;
721  switch_img_find_position(POS_CENTER_MID, w, h, other_img->d_w, other_img->d_h, &x, &y);
722 
723  switch_img_patch(IMG, other_img, w + x, y);
724  }
725  }
726 
727  if (IMG || img) {
729  frame.img = other_q ? IMG : img;
730 
731  bug->video_ping_frame = &frame;
732 
733  if (bug->callback) {
735  || (bug->stop_time && bug->stop_time <= switch_epoch_time_now(NULL))) {
736  ok = SWITCH_FALSE;
737  }
738  }
739 
740  bug->video_ping_frame = NULL;
742 
743  if (!ok) {
745  goto end;
746  }
747  }
748  }
749 
750  end:
751 
753 
754  switch_img_free(&IMG);
755  switch_img_free(&img);
756  switch_img_free(&other_img);
757 
758  while (switch_queue_trypop(main_q, &pop) == SWITCH_STATUS_SUCCESS && pop) {
759  img = (switch_image_t *) pop;
760  switch_img_free(&img);
761  }
762 
763  if (other_q) {
764  while (switch_queue_trypop(other_q, &pop) == SWITCH_STATUS_SUCCESS && pop) {
765  img = (switch_image_t *) pop;
766  switch_img_free(&img);
767  }
768  }
769 
770  return NULL;
771 }
switch_status_t switch_thread_rwlock_unlock(switch_thread_rwlock_t *rwlock)
Definition: switch_apr.c:286
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:700
switch_status_t switch_core_timer_init(switch_timer_t *timer, const char *timer_name, int interval, int samples, switch_memory_pool_t *pool)
Request a timer handle using given time module.
void switch_img_free(switch_image_t **img)
Close an image descriptor.
static int flush_video_queue(switch_queue_t *q, int min)
switch_queue_t * read_video_queue
#define SWITCH_RTP_MAX_BUF_LEN
Definition: switch_rtp.h:45
switch_status_t switch_queue_trypop(switch_queue_t *queue, void **data)
Definition: switch_apr.c:1264
switch_core_session_t * session
#define switch_calc_video_fps(fpsP, fps)
Abstract handler to a timer module.
uint32_t switch_channel_test_flag(switch_channel_t *channel, switch_channel_flag_t flag)
Test for presence of given flag on a given channel.
void switch_img_find_position(switch_img_position_t pos, int sw, int sh, int iw, int ih, int *xP, int *yP)
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:250
uint32_t buflen
Definition: switch_frame.h:70
switch_byte_t switch_byte_t * buf
switch_channel_t * channel
uint32_t packetlen
Definition: switch_frame.h:62
switch_frame_flag_t flags
Definition: switch_frame.h:85
switch_status_t switch_img_fit(switch_image_t **srcP, int width, int height, switch_img_fit_t fit)
An abstraction of a data frame.
Definition: switch_frame.h:54
uintptr_t switch_size_t
switch_frame_t * video_ping_frame
switch_byte_t switch_byte_t uint32_t buflen
void switch_color_set_rgb(switch_rgb_color_t *color, const char *color_str)
Set RGB color with a string.
switch_status_t switch_core_timer_destroy(switch_timer_t *timer)
Destroy an allocated timer.
uint32_t switch_core_media_bug_test_flag(switch_media_bug_t *bug, uint32_t flag)
void switch_core_media_bug_get_media_params(switch_media_bug_t *bug, switch_mm_t *mm)
switch_status_t switch_core_timer_next(switch_timer_t *timer)
Wait for one cycle on an existing timer.
void * packet
Definition: switch_frame.h:60
switch_image_t * img
Definition: switch_frame.h:88
void switch_img_fill(switch_image_t *img, int x, int y, int w, int h, switch_rgb_color_t *color)
Fill image with color.
#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:322
#define switch_core_session_alloc(_session, _memory)
Allocate memory from a session&#39;s pool.
Definition: switch_core.h:696
#define switch_test_flag(obj, flag)
Test for the existance of a flag on an arbitary object.
Definition: switch_utils.h:693
unsigned int d_h
Definition: switch_image.h:100