SWITCH_DECLARE(void) switch_core_session_stop_media(switch_core_session_t *session);
SWITCH_DECLARE(switch_media_flow_t) switch_core_session_media_flow(switch_core_session_t *session, switch_media_type_t type);
SWITCH_DECLARE(switch_status_t) switch_core_media_get_vid_params(switch_core_session_t *session, switch_vid_params_t *vid_params);
-SWITCH_DECLARE(switch_status_t) switch_core_media_set_video_file(switch_core_session_t *session, switch_file_handle_t *fh);
+SWITCH_DECLARE(switch_status_t) switch_core_media_set_video_file(switch_core_session_t *session, switch_file_handle_t *fh, switch_rw_t rw);
SWITCH_END_EXTERN_C
#endif
#define SWITCH_ACCEPTABLE_INTERVAL(_i) (_i && _i <= SWITCH_MAX_INTERVAL && (_i % 10) == 0)
+typedef enum {
+ SWITCH_RW_READ,
+ SWITCH_RW_WRITE
+} switch_rw_t;
+
typedef enum {
SWITCH_CPF_NONE = 0,
SWITCH_CPF_SCREEN = (1 << 0),
switch_frame_t write_frame = { 0 };
uint8_t *packet = NULL;
layout_group_t *lg = NULL;
- switch_image_t *write_img = NULL, *free_img = NULL;
+ switch_image_t *write_img = NULL, *file_img = NULL;
#ifdef TRACK_FPS
uint64_t frames = 0;
switch_core_timer_init(&conference->canvas->timer, "soft", conference->video_fps.ms, conference->video_fps.samples, NULL);
need_reset = SWITCH_TRUE;
}
-
- switch_core_timer_next(&conference->canvas->timer);
+
+ if (!conference->record_fh) {
+ switch_core_timer_next(&conference->canvas->timer);
+ }
now = switch_micro_time_now();
continue;
}
- if (switch_test_flag(imember, MFLAG_NO_MINIMIZE_ENCODING)) {
+ if (!switch_test_flag(imember, MFLAG_NO_MINIMIZE_ENCODING)) {
min_members++;
}
if (conference->fnode) {
if (switch_core_file_read_video(&conference->fnode->fh, &write_frame) == SWITCH_STATUS_SUCCESS) {
- write_img = free_img = write_frame.img;
+ switch_img_free(&file_img);
+ write_img = file_img = write_frame.img;
}
+ } else if (file_img) {
+ switch_img_free(&file_img);
}
if (conference->record_fh) {
switch_core_session_rwunlock(imember->session);
}
}
+
switch_mutex_unlock(conference->member_mutex);
-
- switch_img_free(&free_img);
}
for (i = 0; i < MCU_MAX_LAYERS; i++) {
{
vlc_video_context_t *context = (vlc_video_context_t *) data;
+ if (context->img) {
+ if (context->img->d_w != context->width || context->img->d_h != context->height) {
+ switch_img_free(&context->img);
+ }
+ }
+
if (!context->img) context->img = switch_img_alloc(NULL, SWITCH_IMG_FMT_I420, context->width, context->height, 0);
switch_assert(context->img);
vlc_video_context_t *context = (vlc_video_context_t *) data;
if (context->channel && !switch_channel_test_flag(context->channel, CF_VIDEO)) return;
+ if (!context->img) return;
if (context->video_queue) {
- switch_queue_push(context->video_queue, context->img);
- context->img = NULL;
+ switch_image_t *img_copy = NULL;
+ switch_img_copy(context->img, &img_copy);
+ switch_queue_push(context->video_queue, img_copy);
+
} else {
context->vid_frame->img = context->img;
context->vid_frame->packet = context->video_packet;
{
vlc_file_context_t *context;
libvlc_event_manager_t *mp_event_manager, *m_event_manager;
-
+ char *ext = NULL;
+
context = switch_core_alloc(handle->memory_pool, sizeof(*context));
context->pool = handle->memory_pool;
- context->path = switch_core_strdup(context->pool, path);
context->vlc_handle = libvlc_new(sizeof(vlc_args)/sizeof(char *), vlc_args);
+
+ if (switch_test_flag(handle, SWITCH_FILE_FLAG_VIDEO) && switch_test_flag(handle, SWITCH_FILE_FLAG_WRITE) &&
+ (ext = strrchr(path, '.')) && !strcasecmp(ext, ".mp4")) {
+ path = switch_core_sprintf(context->pool, "#transcode{vcodec=h264,acodec=mp3}:std{access=file,mux=mp4,dst=%s}", path);
+ }
+
+ context->path = switch_core_strdup(context->pool, path);
+
+
if (!switch_test_flag(handle, SWITCH_FILE_FLAG_VIDEO)) {
switch_buffer_create_dynamic(&(context->audio_buffer), VLC_BUFFER_SIZE, VLC_BUFFER_SIZE * 8, 0);
switch_mutex_init(&context->audio_mutex, SWITCH_MUTEX_NESTED, context->pool);
/* connect my internal structure to the blank pointer passed to me */
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
-
+
vlc_file_supported_formats[0] = "vlc";
+ vlc_file_supported_formats[1] = "mp4"; /* maybe add config for this mod to enable or disable */
file_interface = switch_loadable_module_create_interface(*module_interface, SWITCH_FILE_INTERFACE);
file_interface->interface_name = modname;
void *video_user_data;
int8_t video_function_running;
switch_vid_params_t vid_params;
- switch_file_handle_t *video_fh;
+ switch_file_handle_t *video_read_fh;
+ switch_file_handle_t *video_write_fh;
};
return changed;
}
-SWITCH_DECLARE(switch_status_t) switch_core_media_set_video_file(switch_core_session_t *session, switch_file_handle_t *fh)
+SWITCH_DECLARE(switch_status_t) switch_core_media_set_video_file(switch_core_session_t *session, switch_file_handle_t *fh, switch_rw_t rw)
{
switch_media_handle_t *smh;
switch_rtp_engine_t *v_engine;
return SWITCH_STATUS_FALSE;
}
- smh->video_fh = fh;
+ if (rw == SWITCH_RW_READ) {
+ smh->video_read_fh = fh;
+ if (fh) {
+ switch_channel_set_flag_recursive(session->channel, CF_VIDEO_DECODED_READ);
+ } else {
+ switch_channel_clear_flag_recursive(session->channel, CF_VIDEO_DECODED_READ);
+ switch_core_session_video_reset(session);
+ }
+ } else {
+ smh->video_write_fh = fh;
+ }
return SWITCH_STATUS_SUCCESS;
}
uint32_t loops = 0, xloops = 0;
switch_frame_t fr = { 0 };
unsigned char *buf = NULL;
+ //switch_rtp_engine_t *v_engine = NULL;
if (!(smh = session->media_handle)) {
return NULL;
}
+ //v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO];
+
switch_core_session_read_lock(session);
mh->up = 1;
switch_mutex_unlock(smh->control_mutex);
}
}
-
- status = switch_core_session_read_video_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
-
- if (!SWITCH_READ_ACCEPTABLE(status)) {
- switch_cond_next();
- continue;
- }
-
- if (switch_test_flag(read_frame, SFF_CNG)) {
- continue;
- }
-
+ if (!smh->video_write_fh || !switch_channel_test_flag(channel, CF_VIDEO_READY)) {
+ status = switch_core_session_read_video_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
+
+ if (!SWITCH_READ_ACCEPTABLE(status)) {
+ switch_cond_next();
+ continue;
+ }
- if (read_frame->img) {
- switch_channel_set_flag(channel, CF_VIDEO_READY);
- smh->vid_params.width = read_frame->img->d_w;
- smh->vid_params.height = read_frame->img->d_h;
+ if (switch_test_flag(read_frame, SFF_CNG)) {
+ continue;
+ }
+
+ if (read_frame->img) {
+ switch_channel_set_flag(channel, CF_VIDEO_READY);
+ smh->vid_params.width = read_frame->img->d_w;
+ smh->vid_params.height = read_frame->img->d_h;
+ } else if (read_frame->datalen > 2 && !switch_channel_test_flag(channel, CF_VIDEO_DECODED_READ)) {
+ switch_channel_set_flag(channel, CF_VIDEO_READY);
+ }
}
- if (smh->video_fh) {
+ if (smh->video_write_fh) {
if (!buf) {
- int buflen = SWITCH_RECOMMENDED_BUFFER_SIZE * 2;
+ int buflen = SWITCH_RECOMMENDED_BUFFER_SIZE * 4;
buf = switch_core_session_alloc(session, buflen);
fr.packet = buf;
fr.packetlen = buflen;
fr.data = buf + 12;
fr.buflen = buflen - 12;
}
- if (switch_core_file_read_video(smh->video_fh, &fr) == SWITCH_STATUS_SUCCESS) {
+
+ if (switch_core_file_read_video(smh->video_write_fh, &fr) == SWITCH_STATUS_SUCCESS) {
switch_core_session_write_video_frame(session, &fr, SWITCH_IO_FLAG_NONE, 0);
switch_img_free(&fr.img);
}
-
- } else if (switch_channel_test_flag(channel, CF_VIDEO_ECHO)) {
+
+ } else if (smh->video_read_fh && read_frame->img) {
+ switch_core_file_write_video(smh->video_read_fh, read_frame);
+ }
+
+ if (read_frame && switch_channel_test_flag(channel, CF_VIDEO_ECHO)) {
switch_core_session_write_video_frame(session, read_frame, SWITCH_IO_FLAG_NONE, 0);
}
-
}
-
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s Video thread ended\n", switch_channel_get_name(session->channel));
switch_mutex_unlock(mh->cond_mutex);
int file_flags = SWITCH_FILE_FLAG_WRITE | SWITCH_FILE_DATA_SHORT;
int restart_limit_on_dtmf = 0;
const char *prefix, *var;
-
+
if (switch_channel_pre_answer(channel) != SWITCH_STATUS_SUCCESS) {
return SWITCH_STATUS_FALSE;
fh->prefix = prefix;
}
+ if (switch_channel_test_flag(channel, CF_VIDEO)) {
+ file_flags |= SWITCH_FILE_FLAG_VIDEO;
+ }
+
if (switch_core_file_open(fh, file, fh->channels, read_impl.actual_samples_per_second, file_flags, NULL) != SWITCH_STATUS_SUCCESS) {
switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE);
arg_recursion_check_stop(args);
return SWITCH_STATUS_GENERR;
}
+
+ if (switch_core_file_has_video(fh)) {
+ switch_channel_set_flag(channel, CF_VIDEO_ECHO);
+ switch_core_media_set_video_file(session, fh, SWITCH_RW_READ);
+ }
if (sample_start > 0) {
uint32_t pos = 0;
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR,
"Raw Codec Activation Failed %s@%uhz %u channels %dms\n", codec_name, fh->samplerate,
fh->channels, read_impl.microseconds_per_packet / 1000);
+ if (switch_core_file_has_video(fh)) {
+ switch_channel_set_flag(channel, CF_VIDEO_ECHO);
+ switch_core_media_set_video_file(session, NULL, SWITCH_RW_READ);
+ }
switch_core_file_close(fh);
+
switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE);
arg_recursion_check_stop(args);
return SWITCH_STATUS_GENERR;
break;
}
}
-
}
if (fill_cng || waste_resources) {
switch_core_codec_destroy(&write_codec);
}
+ if (switch_core_file_has_video(fh)) {
+ switch_channel_set_flag(channel, CF_VIDEO_ECHO);
+ switch_core_media_set_video_file(session, NULL, SWITCH_RW_READ);
+ }
switch_core_file_close(fh);
switch_core_session_io_rwunlock(session);
if (switch_core_file_has_video(fh)) {
- switch_core_media_set_video_file(session, fh);
+ switch_core_media_set_video_file(session, fh, SWITCH_RW_WRITE);
}
if (!abuf) {
switch_core_session_io_rwunlock(session);
if (switch_core_file_has_video(fh)) {
- switch_core_media_set_video_file(session, NULL);
+ switch_core_media_set_video_file(session, NULL, SWITCH_RW_WRITE);
}
+
switch_core_file_close(fh);
switch_core_session_reset(session, SWITCH_TRUE, SWITCH_FALSE);
switch_core_session_io_rwunlock(session);
if (switch_core_file_has_video(fh)) {
- switch_core_media_set_video_file(session, NULL);
+ switch_core_media_set_video_file(session, NULL, SWITCH_RW_WRITE);
}
switch_core_file_close(fh);
switch_channel_set_private(channel, "__fh", NULL);
switch_core_session_io_rwunlock(session);
if (switch_core_file_has_video(fh)) {
- switch_core_media_set_video_file(session, NULL);
+ switch_core_media_set_video_file(session, NULL, SWITCH_RW_WRITE);
}
switch_core_file_close(fh);
switch_core_session_reset(session, SWITCH_TRUE, SWITCH_FALSE);
switch_core_session_io_rwunlock(session);
if (switch_core_file_has_video(fh)) {
- switch_core_media_set_video_file(session, NULL);
+ switch_core_media_set_video_file(session, NULL, SWITCH_RW_WRITE);
}
switch_core_file_close(fh);