]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
FS-7505: train video a little in beginning and make play file wait for it to train
authorAnthony Minessale <anthm@freeswitch.org>
Tue, 3 Mar 2015 00:05:59 +0000 (18:05 -0600)
committerMichael Jerris <mike@jerris.com>
Thu, 28 May 2015 17:47:07 +0000 (12:47 -0500)
src/mod/formats/mod_vlc/mod_vlc.c
src/switch_core_file.c
src/switch_core_media.c
src/switch_ivr_play_say.c

index 3a3894b8fefef1eb1a14bf99f3944a948ad1181b..26b7d4065fba4b40567f95eaca501360b8e0954a 100644 (file)
@@ -930,10 +930,6 @@ static switch_status_t vlc_file_av_read(switch_file_handle_t *handle, void *data
                }
                switch_mutex_unlock(vcontext->cond_mutex); 
        }
-
-       while(!switch_buffer_inuse(vcontext->audio_buffer) && !vcontext->err && vcontext->playing) {
-               switch_cond_next();
-       }
        
        switch_mutex_lock(vcontext->audio_mutex);
        read = switch_buffer_read(vcontext->audio_buffer, data, bytes);
@@ -944,7 +940,7 @@ static switch_status_t vlc_file_av_read(switch_file_handle_t *handle, void *data
        if (!read && (status == libvlc_Stopped || status == libvlc_Ended || status == libvlc_Error)) {
                return SWITCH_STATUS_FALSE;
        } else if (!read) {
-               read = 2;
+               read = bytes;
                memset(data, 0, read);
        }
 
@@ -1030,6 +1026,11 @@ static switch_status_t vlc_file_read_video(switch_file_handle_t *handle, switch_
        }
        
        if (switch_queue_pop(vcontext->video_queue, &pop) == SWITCH_STATUS_SUCCESS) {
+               if (!pop) {
+                       vcontext->err = 1;
+                       return SWITCH_STATUS_FALSE;
+               }
+
                if (!vcontext->vid_ready) {
                        vcontext->vid_ready = 1;
                        
@@ -1039,10 +1040,7 @@ static switch_status_t vlc_file_read_video(switch_file_handle_t *handle, switch_
                        }
                }
 
-               if (!pop) {
-                       vcontext->err = 1;
-                       return SWITCH_STATUS_FALSE;
-               }
+
                frame->img = (switch_image_t *) pop;
                return SWITCH_STATUS_SUCCESS;
        }
@@ -1378,6 +1376,9 @@ SWITCH_STANDARD_APP(play_video_function)
        libvlc_video_set_format_callbacks(context->mp, video_format_setup_callback, video_format_clean_callback);
        libvlc_video_set_callbacks(context->mp, vlc_video_lock_callback, vlc_video_unlock_callback, vlc_video_display_callback, context);
 
+       switch_channel_set_flag(channel, CF_VIDEO_DECODED_READ);
+       switch_channel_wait_for_flag(channel, CF_VIDEO_READY, SWITCH_TRUE, 10000, NULL);
+
        // start play
        if (-1 == libvlc_media_player_play(context->mp)) {
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "VLC error playing %s\n", path);
index ab07c10dae4058d20b54c3ae288ff8fc1e1c1ad3..2f180bc7bbb05a3d4632b71a7c9337af1c2bc5fa 100644 (file)
@@ -222,7 +222,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_perform_file_open(const char *file,
                }
        }
 
-       if (switch_test_flag(fh, SWITCH_FILE_FLAG_VIDEO) && (flags & SWITCH_FILE_FLAG_WRITE)) {
+       if (switch_test_flag(fh, SWITCH_FILE_FLAG_VIDEO)) {
                fh->pre_buffer_datalen = 0;
        }
 
index 422ee3e080b0b15826ca733a058ebaf2b588fd24..392619fa7fedbb36100054801799593a8b590b11 100644 (file)
@@ -72,6 +72,7 @@ struct media_helper {
        switch_core_session_t *session;
        switch_thread_cond_t *cond;
        switch_mutex_t *cond_mutex;
+       switch_mutex_t *file_mutex;
        int up;
 };
 
@@ -4604,6 +4605,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_set_video_file(switch_core_ses
                return SWITCH_STATUS_FALSE;
        }
 
+       switch_mutex_lock(v_engine->mh.file_mutex);
+
        if (rw == SWITCH_RW_READ) {
                smh->video_read_fh = fh;
                if (fh) {
@@ -4616,6 +4619,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_set_video_file(switch_core_ses
                smh->video_write_fh = fh;
        }
 
+       switch_mutex_unlock(v_engine->mh.file_mutex);
+
        return SWITCH_STATUS_SUCCESS;
 }
 
@@ -4627,15 +4632,22 @@ static void *SWITCH_THREAD_FUNC video_helper_thread(switch_thread_t *thread, voi
        switch_status_t status;
        switch_frame_t *read_frame;
        switch_media_handle_t *smh;
-       uint32_t loops = 0, xloops = 0;
+       uint32_t loops = 0, xloops = 0, vloops = 0;
        switch_frame_t fr = { 0 };
        unsigned char *buf = NULL;
-       //switch_rtp_engine_t *v_engine = NULL;
+       switch_image_t *blank_img = NULL;
+       switch_rgb_color_t bgcolor;
 
+       switch_color_set_rgb(&bgcolor, "#000000");
+       blank_img = switch_img_alloc(NULL, SWITCH_IMG_FMT_I420, 640, 480, 1);
+       switch_img_fill(blank_img, 0, 0, blank_img->d_w, blank_img->d_h, &bgcolor);
+       
+       //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);
@@ -4713,38 +4725,58 @@ static void *SWITCH_THREAD_FUNC video_helper_thread(switch_thread_t *thread, voi
                        }
                
                        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)) {
+                               if (++vloops > 5) {
+                                       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 {
+                                       switch_img_free(&blank_img);
+                                       blank_img = switch_img_alloc(NULL, SWITCH_IMG_FMT_I420, read_frame->img->d_w, read_frame->img->d_h, 1);
+                                       switch_img_fill(blank_img, 0, 0, blank_img->d_w, blank_img->d_h, &bgcolor);
+                               }
+                       } else if (read_frame->datalen > 2 && !switch_channel_test_flag(channel, CF_VIDEO_DECODED_READ) && ++vloops > 20) {
                                switch_channel_set_flag(channel, CF_VIDEO_READY);
                        }
                }
 
-               if (smh->video_write_fh) {
-                       if (!buf) {
-                               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_write_fh, &fr) == SWITCH_STATUS_SUCCESS) {
-                               switch_core_session_write_video_frame(session, &fr, SWITCH_IO_FLAG_NONE, 0);
-                               switch_img_free(&fr.img);
-                       }
+               if (!buf) {
+                       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;
+                       switch_core_media_gen_key_frame(session);
+               }
 
-               } else if (smh->video_read_fh && read_frame->img) {
-                       switch_core_file_write_video(smh->video_read_fh, read_frame);
-               } 
+               if (switch_channel_test_flag(channel, CF_VIDEO_READY)) {
+                       switch_mutex_lock(mh->file_mutex);
+                       if (smh->video_write_fh) {
+                               switch_core_media_gen_key_frame(session);
+                               while (smh->video_write_fh && 
+                                          switch_channel_ready(session->channel) && 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);
+                                       switch_mutex_unlock(mh->file_mutex);
+                                       switch_mutex_lock(mh->file_mutex);
+                               }
+                               
+                       } else if (smh->video_read_fh && read_frame->img) {
+                               switch_core_file_write_video(smh->video_read_fh, read_frame);
+                       } 
+                       switch_mutex_unlock(mh->file_mutex);
+               } else if (switch_channel_test_flag(channel, CF_VIDEO_DECODED_READ)) {
+                       fr.img = blank_img;
+                       switch_core_session_write_video_frame(session, &fr, SWITCH_IO_FLAG_NONE, 0);
+               }
 
-               if (read_frame && switch_channel_test_flag(channel, CF_VIDEO_ECHO)) {
+               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_img_free(&blank_img);
+
        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);
@@ -4783,6 +4815,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_start_video_thread(switch_co
        
        switch_thread_cond_create(&v_engine->mh.cond, pool);
        switch_mutex_init(&v_engine->mh.cond_mutex, SWITCH_MUTEX_NESTED, pool);
+       switch_mutex_init(&v_engine->mh.file_mutex, SWITCH_MUTEX_NESTED, pool);
        switch_mutex_init(&v_engine->read_mutex[SWITCH_MEDIA_TYPE_VIDEO], SWITCH_MUTEX_NESTED, pool);
        switch_thread_create(&v_engine->media_thread, thd_attr, video_helper_thread, &v_engine->mh, switch_core_session_get_pool(session));
 
index f2a3204a2b530b75c4fb693042444d2496048a4c..bd37589b6815b29cf6db66778bc230b1aa942030 100644 (file)
@@ -525,6 +525,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_file(switch_core_session_t *se
 
        if (switch_channel_test_flag(channel, CF_VIDEO)) {
                file_flags |= SWITCH_FILE_FLAG_VIDEO;
+               switch_channel_set_flag_recursive(channel, CF_VIDEO_DECODED_READ);
+               switch_channel_wait_for_flag(channel, CF_VIDEO_READY, SWITCH_TRUE, 10000, NULL);
        }
 
        if (switch_core_file_open(fh, file, fh->channels, read_impl.actual_samples_per_second, file_flags, NULL) != SWITCH_STATUS_SUCCESS) {
@@ -606,7 +608,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_file(switch_core_session_t *se
                                                          "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_channel_clear_flag(channel, CF_VIDEO_ECHO);
+                               switch_channel_clear_flag_recursive(channel, CF_VIDEO_DECODED_READ);
                                switch_core_media_set_video_file(session, NULL, SWITCH_RW_READ);
                        }
                        switch_core_file_close(fh);
@@ -782,7 +785,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_file(switch_core_session_t *se
        }
 
        if (switch_core_file_has_video(fh)) {
-               switch_channel_set_flag(channel, CF_VIDEO_ECHO);
+               switch_channel_clear_flag(channel, CF_VIDEO_ECHO);
+               switch_channel_clear_flag_recursive(channel, CF_VIDEO_DECODED_READ);
                switch_core_media_set_video_file(session, NULL, SWITCH_RW_READ);
        }
        switch_core_file_close(fh);
@@ -1259,6 +1263,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess
 
                if (switch_channel_test_flag(channel, CF_VIDEO)) {
                        flags |= SWITCH_FILE_FLAG_VIDEO;
+                       switch_channel_set_flag_recursive(channel, CF_VIDEO_DECODED_READ);
+                       switch_channel_wait_for_flag(channel, CF_VIDEO_READY, SWITCH_TRUE, 10000, NULL);
                }
 
                if (switch_core_file_open(fh,
@@ -1352,6 +1358,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess
                                switch_core_session_io_rwunlock(session);
 
                                if (switch_core_file_has_video(fh)) {
+                                       switch_channel_clear_flag_recursive(channel, CF_VIDEO_DECODED_READ);
                                        switch_core_media_set_video_file(session, NULL, SWITCH_RW_WRITE);
                                }
 
@@ -1377,6 +1384,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess
                                switch_core_session_io_rwunlock(session);
 
                                if (switch_core_file_has_video(fh)) {
+                                       switch_channel_clear_flag_recursive(channel, CF_VIDEO_DECODED_READ);
                                        switch_core_media_set_video_file(session, NULL, SWITCH_RW_WRITE);
                                }
                                switch_core_file_close(fh);
@@ -1405,6 +1413,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess
                                switch_channel_set_private(channel, "__fh", NULL);
                                switch_core_session_io_rwunlock(session);
                                if (switch_core_file_has_video(fh)) {
+                                       switch_channel_clear_flag_recursive(channel, CF_VIDEO_DECODED_READ);
                                        switch_core_media_set_video_file(session, NULL, SWITCH_RW_WRITE);
                                }
                                switch_core_file_close(fh);
@@ -1565,7 +1574,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess
                                        olen /= 2;
                                }
                                switch_set_flag(fh, SWITCH_FILE_BREAK_ON_CHANGE);
-                               
+
                                if ((rstatus = switch_core_file_read(fh, abuf, &olen)) == SWITCH_STATUS_BREAK) {
                                        continue;
                                }
@@ -1815,6 +1824,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess
                switch_core_session_io_rwunlock(session);
 
                if (switch_core_file_has_video(fh)) {
+                       switch_channel_clear_flag_recursive(channel, CF_VIDEO_DECODED_READ);
                        switch_core_media_set_video_file(session, NULL, SWITCH_RW_WRITE);
                }
                switch_core_file_close(fh);