]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
FS-10126: [freeswitch-core] General Video Improvements #resolve
authorAnthony Minessale <anthm@freeswitch.org>
Sat, 11 Mar 2017 03:14:17 +0000 (21:14 -0600)
committerMike Jerris <mike@jerris.com>
Fri, 7 Apr 2017 22:32:05 +0000 (17:32 -0500)
Conflicts:
src/include/switch_core.h
src/include/switch_types.h
src/mod/applications/mod_conference/conference_file.c
src/mod/applications/mod_conference/conference_video.c
src/mod/languages/mod_managed/managed/swig.cs
src/switch_core_media.c
src/switch_ivr_bridge.c
src/switch_rtp.c

src/include/switch_core.h
src/include/switch_module_interfaces.h
src/include/switch_types.h
src/mod/applications/mod_conference/conference_video.c
src/switch_core_media.c
src/switch_ivr_bridge.c
src/switch_time.c

index c0af4c00dcebed88d5ba064e0e21fc30f9d4b89d..52b643e5ebd144f518530a4d76271aaa553f874b 100644 (file)
@@ -1274,6 +1274,9 @@ SWITCH_DECLARE(uint32_t) switch_core_session_private_event_count(_In_ switch_cor
 SWITCH_DECLARE(switch_status_t) switch_core_session_dequeue_private_event(_In_ switch_core_session_t *session, _Out_ switch_event_t **event);
 
 
+SWITCH_DECLARE(switch_bool_t) switch_core_session_transcoding(switch_core_session_t *session_a, switch_core_session_t *session_b, switch_media_type_t type);
+SWITCH_DECLARE(void) switch_core_session_passthru(switch_core_session_t *session, switch_media_type_t type, switch_bool_t on);
+
 /*!
   \brief Flush the private event queue of a session
   \param session the session to flush
index 1802f872e3fc2ceda8baf7d42a7e720d3565c12e..e0a5c2019e3d38032fa787df738a6f5830d8a9c2 100644 (file)
@@ -207,6 +207,7 @@ struct switch_timer {
        unsigned int samples;
        /*! current sample count based on samples parameter */
        uint32_t samplecount;
+       uint32_t last_samplecount;
        /*! the timer interface provided from a loadable module */
        switch_timer_interface_t *timer_interface;
        /*! the timer's memory pool */
index 03e141d53650be5470cc5e115bbb3097415609f2..47ea86b2529826ca7516123565df34f3288915fd 100644 (file)
@@ -770,8 +770,6 @@ typedef enum {
        SWITCH_RTP_FLAG_MUTE,
        SWITCH_RTP_FLAG_NACK,
        SWITCH_RTP_FLAG_TMMBR,
-       SWITCH_RTP_FLAG_GEN_TS_DELTA,
-       SWITCH_RTP_FLAG_GEN_TS_MANUAL,
        SWITCH_RTP_FLAG_DETECT_SSRC,
        SWITCH_RTP_FLAG_OLD_FIR,
        SWITCH_RTP_FLAG_PASSTHRU,
@@ -905,7 +903,6 @@ typedef enum {
 
         */
 
-
 } switch_rtp_bug_flag_t;
 
 #ifdef _MSC_VER
@@ -1530,6 +1527,8 @@ typedef struct switch_vid_params_s {
        uint32_t width;
        uint32_t height;
        uint32_t fps;
+       uint32_t d_width;
+       uint32_t d_height;
 } switch_vid_params_t;
 
 
index e9bee8b523c1328a8d626bf0d64796372bf60a62..acedda36d47d312d397a70b17d3b4a66e4a3129d 100644 (file)
  */
 #include <mod_conference.h>
 
-static struct conference_fps FPS_VALS[] = {
-       {1.0f, 1000, 90},
-       {5.0f, 200, 450},
-       {10.0f, 100, 900},
-       {15.0f, 66, 1364},
-       {16.60f, 60, 1500},
-       {20.0f, 50, 4500},
-       {25.0f, 40, 2250},
-       {30.0f, 33, 2700},
-       {33.0f, 30, 2790},
-       {66.60f, 15, 6000},
-       {100.0f, 10, 9000},
-       {0,0,0}
-};
-
-
 int conference_video_set_fps(conference_obj_t *conference, float fps)
 {
-       uint32_t i = 0, j = 0;
-
-       for (i = 0; FPS_VALS[i].ms; i++) {
-               if (FPS_VALS[i].fps == fps) {
+       uint32_t j = 0;
 
-                       conference->video_fps = FPS_VALS[i];
+       if (fps > 100) {
+               return 0;
+       }
 
-                       for (j = 0; j <= conference->canvas_count; j++) {
-                               if (conference->canvases[j]) {
-                                       conference->canvases[j]->video_timer_reset = 1;
-                               }
-                       }
+       conference->video_fps.fps = fps;
+       conference->video_fps.ms = (int) 1000 / fps;
+       conference->video_fps.samples = (int) 90000 / conference->video_fps.ms;
 
-                       return 1;
+       for (j = 0; j <= conference->canvas_count; j++) {
+               if (conference->canvases[j]) {
+                       conference->canvases[j]->video_timer_reset = 1;
                }
        }
 
-       return 0;
+       return 1;
 }
 
 
@@ -1312,7 +1295,7 @@ void conference_video_write_canvas_image_to_codec_group(conference_obj_t *confer
                        }
 
                        if (frame->timestamp) {
-                               switch_set_flag(frame, SFF_RAW_RTP_PARSE_FRAME);
+                               switch_set_flag(frame, SFF_RAW_RTP_PARSE_FRAME|SFF_USE_VIDEO_TIMESTAMP);
                        }
 
                        frame->packetlen = frame->datalen + 12;
@@ -1342,7 +1325,9 @@ void conference_video_write_canvas_image_to_codec_group(conference_obj_t *confer
                                        switch_core_session_request_video_refresh(imember->session);
                                }
 
-                               if (switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_RECVONLY || switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_INACTIVE) {
+                               if (switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_RECVONLY || 
+                                       switch_channel_test_flag(imember->channel, CF_VIDEO_WRITING) ||
+                                       switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_INACTIVE) {
                                        switch_core_session_rwunlock(imember->session);
                                        continue;
                                }
@@ -2996,6 +2981,7 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr
 
                                if (!imember->rec && 
                                        (!imember->session || !switch_channel_test_flag(imember->channel, CF_VIDEO_READY) || !imember->canvas ||
+                                        switch_channel_test_flag(imember->channel, CF_VIDEO_WRITING) ||
                                         switch_core_session_read_lock(imember->session) != SWITCH_STATUS_SUCCESS)) {
                                        continue;
                                }
@@ -3196,7 +3182,9 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr
                                        switch_core_session_request_video_refresh(imember->session);
                                }
 
-                               if (switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_RECVONLY || switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_INACTIVE) {
+                               if (switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_RECVONLY || 
+                                       switch_channel_test_flag(imember->channel, CF_VIDEO_WRITING) ||
+                                       switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_INACTIVE) {
                                        switch_core_session_rwunlock(imember->session);
                                        continue;
                                }
@@ -3206,13 +3194,14 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr
                                        switch_core_media_gen_key_frame(imember->session);
                                }
 
-                               switch_set_flag(&write_frame, SFF_RAW_RTP);
+                               switch_set_flag(&write_frame, SFF_RAW_RTP|SFF_USE_VIDEO_TIMESTAMP|SFF_RAW_RTP_PARSE_FRAME);
                                write_frame.img = write_img;
                                write_frame.packet = packet;
                                write_frame.data = ((uint8_t *)packet) + 12;
                                write_frame.datalen = 0;
                                write_frame.buflen = SWITCH_RTP_MAX_BUF_LEN - 12;
                                write_frame.packetlen = 0;
+                               write_frame.timestamp = timestamp;
 
                                //switch_core_session_write_video_frame(imember->session, &write_frame, SWITCH_IO_FLAG_NONE, 0);
 
@@ -3545,7 +3534,9 @@ void *SWITCH_THREAD_FUNC conference_video_super_muxing_thread_run(switch_thread_
                                switch_core_session_request_video_refresh(imember->session);
                        }
 
-                       if (switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_RECVONLY || switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_INACTIVE) {
+                       if (switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_RECVONLY || 
+                               switch_channel_test_flag(imember->channel, CF_VIDEO_WRITING) ||
+                               switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_INACTIVE) {
                                switch_core_session_rwunlock(imember->session);
                                continue;
                        }
index 727005b00bbf47c7b006297ecd252e7481e41479..397b71e2deb09cbeb2f92ed67cf168e1d7f1ed2c 100644 (file)
@@ -53,7 +53,8 @@ static void gen_ice(switch_core_session_t *session, switch_media_type_t type, co
 typedef enum {
        SMF_INIT = (1 << 0),
        SMF_READY = (1 << 1),
-       SMF_JB_PAUSED = (1 << 2)
+       SMF_JB_PAUSED = (1 << 2),
+       SMF_VB_PAUSED = (1 << 3)
 } smh_flag_t;
 
 
@@ -173,6 +174,7 @@ typedef struct switch_rtp_engine_s {
        switch_media_flow_t rmode;
        switch_media_flow_t smode;
        switch_thread_id_t thread_id;
+       switch_thread_id_t thread_write_lock;
        uint8_t new_ice;
        uint8_t new_dtls;
        uint32_t sdp_bw;
@@ -2651,6 +2653,11 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_write_frame(switch_core_sessio
 
        engine = &smh->engines[type];
 
+       if (type == SWITCH_MEDIA_TYPE_VIDEO) {
+               if (engine->thread_write_lock && engine->thread_write_lock != switch_thread_self()) {
+                       return SWITCH_STATUS_SUCCESS;
+               }
+       }
 
        if (switch_channel_test_flag(session->channel, CF_VIDEO_ONLY) && type == SWITCH_MEDIA_TYPE_AUDIO) {
                return SWITCH_STATUS_SUCCESS;
@@ -5390,7 +5397,7 @@ SWITCH_DECLARE(switch_file_handle_t *) switch_core_media_get_video_file(switch_c
        return fh;
 }
 
-static void switch_core_session_write_blank_video(switch_core_session_t *session, uint32_t ms)
+SWITCH_DECLARE(void) switch_core_session_write_blank_video(switch_core_session_t *session, uint32_t ms)
 {
        switch_frame_t fr = { 0 };
        int i = 0;
@@ -5446,6 +5453,20 @@ static void switch_core_session_write_blank_video(switch_core_session_t *session
 
 }
 
+typedef struct core_fps_s {
+       float fps;
+       int ms;
+       int samples;
+} core_fps_t;
+
+static int video_get_fps(core_fps_t *fpsP, float fps)
+{
+       fpsP->fps = fps;
+       fpsP->ms = (int) 1000 / fps;
+       fpsP->samples = (int) 90000 / fpsP->ms;
+
+       return 0;
+}
 
 static void *SWITCH_THREAD_FUNC video_write_thread(switch_thread_t *thread, void *obj)
 {
@@ -5457,9 +5478,11 @@ static void *SWITCH_THREAD_FUNC video_write_thread(switch_thread_t *thread, void
        int buflen = SWITCH_RTP_MAX_BUF_LEN;
        switch_timer_t timer = { 0 };
        int fps;
-       switch_video_read_flag_t read_flags = SVR_FLUSH|SVR_BLOCK;
+       switch_video_read_flag_t read_flags = SVR_FLUSH;
        switch_core_session_t *b_session = NULL;
-
+       core_fps_t fps_data = { 0 };
+       switch_image_t *last_frame = NULL;
+       
        if (switch_core_session_read_lock(session) != SWITCH_STATUS_SUCCESS) {
                return NULL;
        }
@@ -5478,7 +5501,10 @@ static void *SWITCH_THREAD_FUNC video_write_thread(switch_thread_t *thread, void
 
        v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO];      
 
+       switch_mutex_lock(smh->write_mutex[SWITCH_MEDIA_TYPE_VIDEO]);
+       v_engine->thread_write_lock = switch_thread_self();
 
+       
        buf = switch_core_session_alloc(session, buflen);
        fr.packet = buf;
        fr.packetlen = buflen;
@@ -5498,7 +5524,8 @@ static void *SWITCH_THREAD_FUNC video_write_thread(switch_thread_t *thread, void
        }
 
 
-       switch_core_timer_init(&timer, "soft", (int)(1000 / fps) , 1, switch_core_session_get_pool(session));
+       video_get_fps(&fps_data, fps);
+       switch_core_timer_init(&timer, "soft", (int)(1000 / fps) , fps_data.samples, switch_core_session_get_pool(session));
 
        while (smh->video_write_thread_running > 0 &&
                   switch_channel_up_nosig(session->channel) && smh->video_write_fh && switch_test_flag(smh->video_write_fh, SWITCH_FILE_OPEN)) {
@@ -5509,15 +5536,27 @@ static void *SWITCH_THREAD_FUNC video_write_thread(switch_thread_t *thread, void
 
                if (smh->video_write_fh && smh->video_write_fh->mm.source_fps && smh->video_write_fh->mm.source_fps != fps) {
                        switch_core_timer_destroy(&timer);
-                       switch_core_timer_init(&timer, "soft", (int)(1000 / fps) , 1, switch_core_session_get_pool(session));
+                       video_get_fps(&fps_data, fps);
+                       switch_core_timer_init(&timer, "soft", (int)(1000 / fps) , fps_data.samples, switch_core_session_get_pool(session));
                }
 
                if (smh->video_write_fh && !switch_test_flag(smh->video_write_fh, SWITCH_FILE_FLAG_VIDEO_EOF)) {
                        wstatus = switch_core_file_read_video(smh->video_write_fh, &fr, read_flags);
 
                        if (wstatus == SWITCH_STATUS_SUCCESS) {
-                               switch_core_session_write_video_frame(session, &fr, SWITCH_IO_FLAG_FORCE, SVR_FLUSH);
-                               switch_img_free(&fr.img);
+                               fr.timestamp = timer.samplecount;
+                               fr.flags = SFF_USE_VIDEO_TIMESTAMP|SFF_RAW_RTP|SFF_RAW_RTP_PARSE_FRAME;
+                               
+                               if (smh->vid_params.d_width && smh->vid_params.d_height) {
+                                       switch_img_fit(&fr.img, smh->vid_params.d_width, smh->vid_params.d_height, SWITCH_FIT_SIZE);
+                               }
+                               
+                               switch_core_session_write_video_frame(session, &fr, SWITCH_IO_FLAG_FORCE, 0);
+
+                               switch_img_free(&last_frame);
+                               last_frame = fr.img;
+                               fr.img = NULL;
+                               
                        } else if (wstatus != SWITCH_STATUS_BREAK && wstatus != SWITCH_STATUS_IGNORE) {
                                switch_set_flag_locked(smh->video_write_fh, SWITCH_FILE_FLAG_VIDEO_EOF);
                        }
@@ -5525,6 +5564,25 @@ static void *SWITCH_THREAD_FUNC video_write_thread(switch_thread_t *thread, void
                switch_mutex_unlock(v_engine->mh.file_write_mutex);
        }
 
+       if (last_frame) {
+               int x = 0;
+               switch_rgb_color_t bgcolor;
+               switch_color_set_rgb(&bgcolor, "#000000");
+               switch_img_fill(last_frame, 0, 0, last_frame->d_w, last_frame->d_h, &bgcolor);
+               fr.img = last_frame;
+
+               for (x = 0; x < fps / 2; x++) {
+                       switch_core_timer_next(&timer);
+                       fr.timestamp = timer.samplecount;
+                       fr.flags = SFF_USE_VIDEO_TIMESTAMP|SFF_RAW_RTP|SFF_RAW_RTP_PARSE_FRAME;
+                       switch_core_session_write_video_frame(session, &fr, SWITCH_IO_FLAG_FORCE, 0);
+               }
+               switch_core_media_gen_key_frame(session);
+               switch_core_session_request_video_refresh(session);
+               switch_img_free(&last_frame);
+       }
+
+
        switch_core_timer_destroy(&timer);
 
        switch_core_session_rwunlock(session);
@@ -5534,6 +5592,10 @@ static void *SWITCH_THREAD_FUNC video_write_thread(switch_thread_t *thread, void
                switch_core_session_rwunlock(b_session);
        }
 
+       
+       v_engine->thread_write_lock = 0;
+       switch_mutex_unlock(smh->write_mutex[SWITCH_MEDIA_TYPE_VIDEO]);
+
        switch_channel_clear_flag(session->channel, CF_VIDEO_WRITING);
        smh->video_write_thread_running = 0;
 
@@ -5675,7 +5737,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_set_video_file(switch_core_ses
 
                if (fh) {
                        switch_threadattr_t *thd_attr = NULL;
-                       switch_core_session_write_blank_video(session, 500);
+                       //switch_core_session_write_blank_video(session, 500);
                        switch_threadattr_create(&thd_attr, switch_core_session_get_pool(session));
                        switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
                        smh->video_write_thread_running = 1;
@@ -5692,7 +5754,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_set_video_file(switch_core_ses
                        switch_thread_join(&st, smh->video_write_thread);
                        switch_mutex_lock(v_engine->mh.file_write_mutex);
                        smh->video_write_thread = NULL;
-                       switch_core_session_write_blank_video(session, 500);
+                       //switch_core_session_write_blank_video(session, 500);
                }
                
                smh->video_write_fh = fh;
@@ -6887,11 +6949,6 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi
        }
 
 
-       if ((val = switch_channel_get_variable(session->channel, "rtp_gen_ts_delta_audio")) && switch_true(val)) {
-               flags[SWITCH_RTP_FLAG_GEN_TS_MANUAL] = 1;
-               flags[SWITCH_RTP_FLAG_GEN_TS_DELTA] = 1;
-       }
-
        if (switch_channel_up(session->channel)) {
                switch_channel_set_variable(session->channel, "rtp_use_timer_name", timer_name);
                
@@ -7292,11 +7349,6 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi
                                flags[SWITCH_RTP_FLAG_AUTOADJ]++;                               
                        }
 
-                       if ((val = switch_channel_get_variable(session->channel, "rtp_gen_ts_delta_video")) && switch_true(val)) {
-                               flags[SWITCH_RTP_FLAG_GEN_TS_MANUAL] = 1;
-                               flags[SWITCH_RTP_FLAG_GEN_TS_DELTA] = 1;
-                       }
-
                        if (switch_channel_test_flag(session->channel, CF_PROXY_MEDIA)) {
                                flags[SWITCH_RTP_FLAG_PROXY_MEDIA]++;
                        }
@@ -10034,8 +10086,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_receive_message(switch_core_se
                                const char *val;
                                int ok = 0;
                                
-                               if (!switch_channel_test_flag(session->channel, CF_VIDEO) &&
-                                       (!(val = switch_channel_get_variable(session->channel, "rtp_jitter_buffer_during_bridge")) || switch_false(val))) {
+                               if ((!(val = switch_channel_get_variable(session->channel, "rtp_jitter_buffer_during_bridge")) || switch_false(val))) {
                                        if (switch_channel_test_flag(session->channel, CF_JITTERBUFFER) && switch_channel_test_cap_partner(session->channel, CC_FS_RTP)) {
                                                switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
                                                                                  "%s PAUSE Jitterbuffer\n", switch_channel_get_name(session->channel));                                        
@@ -10089,6 +10140,20 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_receive_message(switch_core_se
                }
                goto end;
        case SWITCH_MESSAGE_INDICATE_UNBRIDGE:
+
+#if 0
+               if (switch_rtp_ready(v_engine->rtp_session)) {
+
+                       if (switch_test_flag(smh, SMF_VB_PAUSED)) {
+                               switch_clear_flag(smh, SMF_VB_PAUSED);
+                               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
+                                                                 "%s RESUME Video Jitterbuffer\n", switch_channel_get_name(session->channel));
+                               switch_rtp_pause_jitter_buffer(v_engine->rtp_session, SWITCH_FALSE);
+                               
+                       }
+               }
+#endif
+
                if (switch_rtp_ready(a_engine->rtp_session)) {
                        
                        if (switch_test_flag(smh, SMF_JB_PAUSED)) {
@@ -11694,8 +11759,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_video_frame(switch_cor
        switch_image_t *dup_img = NULL, *img = frame->img;
        switch_status_t encode_status;
        switch_frame_t write_frame = {0};
-       switch_rtp_engine_t *v_engine;
-
+       switch_rtp_engine_t *v_engine = NULL;
        switch_assert(session);
 
        if (!(smh = session->media_handle)) {
@@ -11711,9 +11775,6 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_video_frame(switch_cor
                return SWITCH_STATUS_FALSE;
        }
 
-       if (switch_channel_test_flag(session->channel, CF_VIDEO_WRITING) && !(flags & SWITCH_IO_FLAG_FORCE)) {
-               return SWITCH_STATUS_SUCCESS;
-       }
 
        if (switch_core_session_media_flow(session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_RECVONLY || switch_core_session_media_flow(session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_INACTIVE) {
                switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG3, "Writing video to RECVONLY/INACTIVE session\n");
@@ -11736,6 +11797,11 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_video_frame(switch_cor
                return SWITCH_STATUS_INUSE;
        }
 
+       v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO];
+       if (v_engine->thread_write_lock && v_engine->thread_write_lock != switch_thread_self()) {
+               return SWITCH_STATUS_SUCCESS;
+       }
+
        if (!smh->video_init && smh->mparams->video_key_first && (now - smh->video_last_key_time) > smh->mparams->video_key_first) {
                switch_core_media_gen_key_frame(session);
 
@@ -11753,17 +11819,9 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_video_frame(switch_cor
 
        if (!img) {
                switch_status_t vstatus;
-
-               if (!switch_rtp_test_flag(v_engine->rtp_session, SWITCH_RTP_FLAG_GEN_TS_MANUAL)) {
-                       switch_rtp_set_flag(v_engine->rtp_session, SWITCH_RTP_FLAG_GEN_TS_DELTA);
-               }
                
                vstatus = switch_core_session_write_encoded_video_frame(session, frame, flags, stream_id);
                switch_goto_status(vstatus, done);
-       } else {
-               if (!switch_rtp_test_flag(v_engine->rtp_session, SWITCH_RTP_FLAG_GEN_TS_MANUAL)) {
-                       switch_rtp_clear_flag(v_engine->rtp_session, SWITCH_RTP_FLAG_GEN_TS_DELTA);
-               }
        }
 
 
@@ -11776,6 +11834,11 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_video_frame(switch_cor
 
                img = dup_img;
        }
+
+       if (!switch_channel_test_flag(session->channel, CF_VIDEO_WRITING)) {
+               smh->vid_params.d_width = img->d_w;
+               smh->vid_params.d_height = img->d_h;
+       }
        
        if (session->bugs) {
                switch_media_bug_t *bp;
@@ -11949,6 +12012,53 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_wait_for_video_input_params(
        
 }
 
+SWITCH_DECLARE(switch_bool_t) switch_core_session_transcoding(switch_core_session_t *session_a, switch_core_session_t *session_b, switch_media_type_t type)
+{
+       switch_bool_t transcoding = SWITCH_FALSE;
+       
+       switch(type) {
+       case SWITCH_MEDIA_TYPE_AUDIO:
+               transcoding = (session_a->read_codec->implementation->impl_id != session_b->read_codec->implementation->impl_id || session_a->read_impl.decoded_bytes_per_packet != session_b->read_impl.decoded_bytes_per_packet);
+               break;
+       case SWITCH_MEDIA_TYPE_VIDEO:
+               transcoding = (switch_channel_test_flag(session_a->channel, CF_VIDEO_DECODED_READ) || 
+                                          switch_channel_test_flag(session_b->channel, CF_VIDEO_DECODED_READ));
+               break;
+       default:
+               break;
+       }
+
+       return transcoding;
+
+}
+
+SWITCH_DECLARE(void) switch_core_session_passthru(switch_core_session_t *session, switch_media_type_t type, switch_bool_t on)
+{
+       switch_rtp_engine_t *engine;
+
+       if (!session->media_handle) return;
+
+       engine = &session->media_handle->engines[type];
+
+
+       if (switch_rtp_ready(engine->rtp_session)) {
+               if (on) {
+                       switch_rtp_set_flag(engine->rtp_session, SWITCH_RTP_FLAG_PASSTHRU);
+               } else {
+                       switch_rtp_clear_flag(engine->rtp_session, SWITCH_RTP_FLAG_PASSTHRU);
+               }
+
+               if (type == SWITCH_MEDIA_TYPE_VIDEO) {
+                       switch_core_session_request_video_refresh(session);
+                       if (!on) {
+                               switch_core_media_gen_key_frame(session);
+                       }
+               }
+
+       }
+
+}
+
 SWITCH_DECLARE(switch_status_t) switch_core_session_read_video_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags,
                                                                                                                                         int stream_id)
 {
index 654aa492ac2195a8e9dd03c95b49fd6484ebc5a8..8c0c1e7becc544b8e4d2203de93af7a5d3c0f25f 100644 (file)
@@ -55,6 +55,7 @@ static void video_bridge_thread(switch_core_session_t *session, void *obj)
        switch_frame_t *read_frame = 0;
        int set_decoded_read = 0, refresh_timer = 0;
        int refresh_cnt = 300;
+       int pass_val = 0, last_pass_val = 0;
 
        vh->up = 1;
 
@@ -78,8 +79,18 @@ static void video_bridge_thread(switch_core_session_t *session, void *obj)
                if (switch_channel_media_up(channel)) {
                        switch_codec_t *a_codec = switch_core_session_get_video_read_codec(vh->session_a);
                        switch_codec_t *b_codec = switch_core_session_get_video_write_codec(vh->session_b);
+                       
+                       if (switch_core_session_transcoding(vh->session_a, vh->session_b, SWITCH_MEDIA_TYPE_VIDEO)) {
+                               pass_val = 1;
+                       } else {
+                               pass_val = 2;
+                       }
 
-
+                       if (pass_val != last_pass_val) {
+                               switch_core_session_passthru(session, SWITCH_MEDIA_TYPE_VIDEO, pass_val == 2 ? SWITCH_TRUE : SWITCH_FALSE);
+                               last_pass_val = pass_val;
+                       }
+                       
                        if (switch_channel_test_flag(channel, CF_VIDEO_REFRESH_REQ)) {
                                switch_channel_clear_flag(channel, CF_VIDEO_REFRESH_REQ);
                                refresh_timer = refresh_cnt;
@@ -146,6 +157,8 @@ static void video_bridge_thread(switch_core_session_t *session, void *obj)
        switch_core_session_request_video_refresh(vh->session_a);
        switch_core_session_request_video_refresh(vh->session_b);
 
+       switch_core_session_passthru(vh->session_a, SWITCH_MEDIA_TYPE_VIDEO, SWITCH_FALSE);
+
        switch_core_session_rwunlock(vh->session_a);
        switch_core_session_rwunlock(vh->session_b);
 
@@ -268,6 +281,7 @@ static void *audio_bridge_thread(switch_thread_t *thread, void *obj)
        switch_codec_implementation_t read_impl = { 0 };
        const char *banner_file = NULL;
        int played_banner = 0, banner_counter = 0;
+       int pass_val = 0, last_pass_val = 0;
 
 #ifdef SWITCH_VIDEO_IN_THREADS
        struct vid_helper vh = { 0 };
@@ -398,6 +412,17 @@ static void *audio_bridge_thread(switch_thread_t *thread, void *obj)
                switch_status_t status;
                switch_event_t *event;
 
+               if (switch_core_session_transcoding(session_a, session_b, SWITCH_MEDIA_TYPE_AUDIO)) {
+                       pass_val = 1;
+               } else {
+                       pass_val = 2;
+               }
+               
+               if (pass_val != last_pass_val) {
+                       switch_core_session_passthru(session_a, SWITCH_MEDIA_TYPE_AUDIO, pass_val == 2 ? SWITCH_TRUE : SWITCH_FALSE);
+                       last_pass_val = pass_val;
+               }
+               
                if (switch_channel_test_flag(chan_a, CF_TRANSFER)) {
                        data->clean_exit = 1;
                }
@@ -702,6 +727,8 @@ static void *audio_bridge_thread(switch_thread_t *thread, void *obj)
        }
 #endif
 
+       switch_core_session_passthru(session_a, SWITCH_MEDIA_TYPE_AUDIO, SWITCH_FALSE);
+
 
        if (silence_val) {
                switch_core_codec_destroy(&silence_codec);
index 8554c5c9f3b3f83010ae9560dec65ca0bf6c0916..b450f13b3194b5ea6e3e4c1ce6911e985d076937 100644 (file)
@@ -386,6 +386,14 @@ static switch_status_t timer_generic_sync(switch_timer_t *timer)
        timer->tick = (elapsed / timer->interval) / 1000;
        timer->samplecount = (uint32_t)(timer->tick * timer->samples);
 
+       if (timer->interval == 1 && timer->samplecount == timer->last_samplecount) {
+               timer->samplecount++;
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "Timer sync too often\n");
+       }
+       timer->last_samplecount = timer->samplecount;
+
+
+
        return SWITCH_STATUS_SUCCESS;
 }