]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
[mod_video_filter] fix some keyframe stuff and add read:sound and write:sound options
authorAnthony Minessale <anthm@freeswitch.org>
Fri, 19 Jul 2019 23:28:48 +0000 (23:28 +0000)
committerAndrey Volk <andywolk@gmail.com>
Sat, 23 Oct 2021 19:00:30 +0000 (22:00 +0300)
src/mod/applications/mod_video_filter/mod_video_filter.c
src/switch_ivr_async.c

index 613f8d91958e279ffb791a7a12581c3a643222e1..2f4d5d5bf79c838d85b3184a6b6233e9463935e5 100644 (file)
@@ -74,6 +74,7 @@ typedef struct video_replace_context_s {
        switch_image_t *rp_img;
        switch_file_handle_t vfh;
        switch_core_session_t *session;
+       int sound;
 } video_replace_context_t;
 
 
@@ -227,7 +228,6 @@ static void parse_params(chromakey_context_t *context, int start, int argc, char
        if (n > 2 && argv[i]) {
 
                if (context->child_bug) {
-                       printf("WTF CLOSE IT\n");
                        switch_core_media_bug_close(&context->child_bug, SWITCH_TRUE);
                        context->child_uuid = NULL;
                }
@@ -575,6 +575,7 @@ static switch_status_t video_thread_callback(switch_core_session_t *session, swi
 
                        if (context->vfh.params) {
                                const char *loopstr = switch_event_get_header(context->vfh.params, "loop");
+
                                if (switch_true(loopstr)) {
                                        uint32_t pos = 0;
                                        switch_core_file_seek(&context->vfh, &pos, 0, SEEK_SET);
@@ -612,7 +613,6 @@ static switch_status_t video_thread_callback(switch_core_session_t *session, swi
 
                status = switch_core_file_read_video(&context->fg_vfh, &file_frame, SVR_FLUSH);
                switch_core_file_command(&context->fg_vfh, SCFC_FLUSH_AUDIO);
-               
 
                if (status != SWITCH_STATUS_SUCCESS && status != SWITCH_STATUS_BREAK) {
                        int close = 1;
@@ -840,41 +840,51 @@ static switch_status_t video_replace_thread_callback(switch_core_session_t *sess
        if (switch_test_flag(&context->vfh, SWITCH_FILE_OPEN)) {
                switch_status_t status = SWITCH_STATUS_FALSE;
 
-               if (type == SWITCH_ABC_TYPE_READ_VIDEO_PING || (context->vfh.params && switch_true(switch_event_get_header(context->vfh.params, "scale")))) {
-                       context->vfh.mm.scale_w = frame->img->d_w;
-                       context->vfh.mm.scale_h = frame->img->d_h;
-               }
+               //if (type == SWITCH_ABC_TYPE_READ_VIDEO_PING || (context->vfh.params && switch_true(switch_event_get_header(context->vfh.params, "scale")))) {
+                       //context->vfh.mm.scale_w = frame->img->d_w;
+                       //context->vfh.mm.scale_h = frame->img->d_h;
+               //}
 
                status = switch_core_file_read_video(&context->vfh, &file_frame, SVR_FLUSH);
-               switch_core_file_command(&context->vfh, SCFC_FLUSH_AUDIO);
-
+               if (!context->sound) { 
+                       switch_core_file_command(&context->vfh, SCFC_FLUSH_AUDIO);
+               }
+               
                if (status != SWITCH_STATUS_SUCCESS && status != SWITCH_STATUS_BREAK) {
                        int close = 1;
-
+                       
                        if (context->vfh.params) {
                                const char *loopstr = switch_event_get_header(context->vfh.params, "loop");
                                if (switch_true(loopstr)) {
                                        uint32_t pos = 0;
 
-                                       if (switch_core_file_seek(&context->vfh, &pos, 0, SEEK_SET) == SWITCH_STATUS_SUCCESS) close = 0;
+                                       switch_core_file_seek(&context->vfh, &pos, 0, SEEK_SET);
+                                       close = 0;
                                }
                        }
 
                        if (close) {
                                switch_core_file_close(&context->vfh);
+                               switch_core_session_request_video_refresh(session);
                        }
                }
 
                if (file_frame.img) {
                        switch_img_free(&(context->rp_img));
-                       context->rp_img = file_frame.img;
+
+                       if (frame->img && (frame->img->d_w != file_frame.img->d_w || frame->img->d_h != file_frame.img->d_h)) {
+                               switch_img_letterbox(file_frame.img, &context->rp_img, frame->img->d_w, frame->img->d_h, "#0000000");
+                               switch_img_free(&file_frame.img);
+                       } else {
+                               context->rp_img = file_frame.img;
+                       }
                }
 
                if (context->rp_img) {
                        if (context->rp_img->d_w != frame->img->d_w || context->rp_img->d_h != frame->img->d_h ) {
                                frame->img = NULL;
                        }
-
+                       
                        switch_img_copy(context->rp_img, &frame->img);
                }
        }
@@ -891,10 +901,17 @@ static switch_bool_t video_replace_bug_callback(switch_media_bug_t *bug, void *u
        switch (type) {
        case SWITCH_ABC_TYPE_INIT:
                {
+                       switch_core_session_request_video_refresh(session);
+                       switch_channel_set_flag(channel, CF_VIDEO_REFRESH_REQ);
+                       switch_core_media_gen_key_frame(session);
                }
                break;
        case SWITCH_ABC_TYPE_CLOSE:
                {
+                       switch_core_session_request_video_refresh(session);
+                       switch_channel_set_flag(channel, CF_VIDEO_REFRESH_REQ);
+                       switch_core_media_gen_key_frame(session);
+                       
                        switch_thread_rwlock_unlock(MODULE_INTERFACE->rwlock);
                        switch_img_free(&context->rp_img);
 
@@ -904,6 +921,33 @@ static switch_bool_t video_replace_bug_callback(switch_media_bug_t *bug, void *u
                        }
                }
                break;
+       case SWITCH_ABC_TYPE_WRITE_REPLACE:
+       case SWITCH_ABC_TYPE_READ_REPLACE:
+               {
+                       switch_frame_t *rframe = NULL;
+                       switch_size_t len;
+
+                       if (type == SWITCH_ABC_TYPE_WRITE_REPLACE) {
+                               rframe = switch_core_media_bug_get_write_replace_frame(bug);
+                       } else {
+                               rframe = switch_core_media_bug_get_read_replace_frame(bug);
+                       }
+                       
+                       if (rframe) {
+                               len = rframe->samples;
+
+                               if (switch_test_flag(&context->vfh, SWITCH_FILE_OPEN)) {
+                                       switch_core_file_read(&context->vfh, rframe->data, &len);
+
+                                       if (len < rframe->samples) {
+                                               memset((char *)rframe->data + (len * 2 * context->vfh.channels), 0, (rframe->samples - len) * 2 * context->vfh.channels);
+                                       }
+
+                                       rframe->datalen = rframe->samples * 2 * context->vfh.channels;
+                               }
+                       }
+               }
+               break;
        case SWITCH_ABC_TYPE_READ_VIDEO_PING:
        case SWITCH_ABC_TYPE_WRITE_VIDEO_PING:
                {
@@ -936,7 +980,8 @@ SWITCH_STANDARD_APP(video_replace_start_function)
        char *argv[2] = { 0 };
        char *direction = NULL;
        char *file = NULL;
-
+       switch_codec_implementation_t read_impl = { 0 };
+       
        if ((bug = (switch_media_bug_t *) switch_channel_get_private(channel, "_video_replace_bug_"))) {
                if (!zstr(data) && !strcasecmp(data, "stop")) {
                        switch_channel_set_private(channel, "_video_replace_bug_", NULL);
@@ -979,7 +1024,9 @@ SWITCH_STANDARD_APP(video_replace_start_function)
 
        switch_thread_rwlock_rdlock(MODULE_INTERFACE->rwlock);
 
-       if (switch_core_file_open(&context->vfh, file, 1, 8000,
+       switch_core_session_get_read_impl(session, &read_impl);
+       
+       if (switch_core_file_open(&context->vfh, file, read_impl.number_of_channels, read_impl.actual_samples_per_second,
                                                                  SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT | SWITCH_FILE_FLAG_VIDEO, 
                                                                  switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error opening video file\n");
@@ -1014,7 +1061,9 @@ SWITCH_STANDARD_API(video_replace_api_function)
        char *direction = NULL;
        switch_media_bug_flag_t flags = 0;
        const char *function = "video_replace";
-
+       switch_codec_implementation_t read_impl = { 0 };
+       int sound = 0;
+       
        if (zstr(cmd)) {
                goto usage;
        }
@@ -1060,10 +1109,18 @@ SWITCH_STANDARD_API(video_replace_api_function)
 
                if (zstr(direction) || zstr(file)) goto usage;
 
-               if (!strcasecmp(direction, "read")) {
+               if (!strncasecmp(direction, "read", 4)) {
                        flags = SMBF_READ_VIDEO_PING;
-               } else if (!strcasecmp(direction, "write")) {
+                       if (switch_stristr(":sound", direction)) {
+                               flags |= SMBF_READ_REPLACE;
+                               sound = 1;
+                       }
+               } else if (!strncasecmp(direction, "write", 5)) {
                        flags = SMBF_WRITE_VIDEO_PING;
+                       if (switch_stristr(":sound", direction)) {
+                               flags |= SMBF_WRITE_REPLACE;
+                               sound = 1;
+                       }
                } else {
                        goto usage;
                }
@@ -1079,10 +1136,13 @@ SWITCH_STANDARD_API(video_replace_api_function)
        context = (video_replace_context_t *) switch_core_session_alloc(rsession, sizeof(*context));
        switch_assert(context != NULL);
        context->session = rsession;
-
+       context->sound = sound;
        switch_thread_rwlock_rdlock(MODULE_INTERFACE->rwlock);
 
-       if (switch_core_file_open(&context->vfh, file, 1, 8000,
+       
+       switch_core_session_get_read_impl(rsession, &read_impl);
+       
+       if (switch_core_file_open(&context->vfh, file, read_impl.number_of_channels, read_impl.actual_samples_per_second,
                                                                  SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT | SWITCH_FILE_FLAG_VIDEO, 
                                                                  switch_core_session_get_pool(rsession)) != SWITCH_STATUS_SUCCESS) {
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error opening video file\n");
index 357ea3f07a4af809c4e8bd253a05185aaef6ed7b..726073c7a38deb075d38f91ccfe0fdffdf17a43a 100644 (file)
@@ -1447,6 +1447,7 @@ static switch_bool_t record_callback(switch_media_bug_t *bug, void *user_data, s
                                rh->fh->native_rate = rh->read_impl.actual_samples_per_second;
                                if (switch_core_file_has_video(rh->fh, SWITCH_TRUE)) {
                                        switch_core_media_bug_set_media_params(bug, &rh->fh->mm);
+                                       switch_core_session_request_video_refresh(session);
                                }
                        }
                }