]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
[core] some mods for file playback to get proper bitrate and timing
authorAnthony Minessale <anthm@freeswitch.org>
Wed, 20 Feb 2019 19:15:13 +0000 (13:15 -0600)
committerAndrey Volk <andywolk@gmail.com>
Sat, 23 Oct 2021 19:00:31 +0000 (22:00 +0300)
src/include/switch_types.h
src/mod/applications/mod_av/avformat.c
src/switch_core_media.c

index e978d33f2ddac15f25008cc537ef821a78cbd0ac..47a50869d847271313b053fc20b739f7ae7d4591 100644 (file)
@@ -2816,6 +2816,7 @@ typedef struct switch_mm_s {
        int cbr;
        float fps;
        float source_fps;
+       int source_kps;
        int vbuf;
        switch_video_profile_t vprofile;
        switch_video_encode_speed_t vencspd;
index 94dd545c6f37eeddd5234358d1f4c6f719a48478..5ffd12d923cd9de08618f293fadfdaf341f3c75a 100644 (file)
@@ -1188,6 +1188,11 @@ GCC_DIAG_ON(deprecated-declarations)
                                handle->duration = av_rescale_q(context->video_st.st->duration != AV_NOPTS_VALUE ? context->video_st.st->duration : context->fc->duration / AV_TIME_BASE * 1000,
                                        context->video_st.st->time_base, AV_TIME_BASE_Q);
                        }
+
+                       if (context->fc->bit_rate) {
+                               handle->mm.source_kps = context->fc->bit_rate / 1024;
+                       }
+
                        if (context->video_st.st->avg_frame_rate.num) {
                                handle->mm.source_fps = ceil(av_q2d(context->video_st.st->avg_frame_rate));
                        } else {
index 340d9c29241f5724e7243fb9d4716ae20a8d9a5a..ec0b5978a13342356cd0ec7b4039a4d77acc5b1a 100644 (file)
@@ -6840,12 +6840,13 @@ static void *SWITCH_THREAD_FUNC video_write_thread(switch_thread_t *thread, void
        switch_rtp_engine_t *v_engine;
        int buflen = SWITCH_RTP_MAX_BUF_LEN;
        switch_timer_t timer = { 0 };
-       switch_video_read_flag_t read_flags = SVR_BLOCK;
+       switch_video_read_flag_t read_flags = SVR_FLUSH;
        switch_core_session_t *b_session = NULL;
        switch_fps_t fps_data = { 0 };
        float fps;
        switch_image_t *last_frame = NULL;
-       
+       int last_w = 0, last_h = 0, kps = 0;
+
        if (switch_core_session_read_lock(session) != SWITCH_STATUS_SUCCESS) {
                return NULL;
        }
@@ -6888,11 +6889,36 @@ static void *SWITCH_THREAD_FUNC video_write_thread(switch_thread_t *thread, void
 
        switch_core_timer_init(&timer, "soft", fps_data.ms, fps_data.samples, switch_core_session_get_pool(session));
 
+       if (smh->video_write_fh && smh->video_write_fh->mm.source_kps) {
+               int min = 0, max = 10000000;
+               const char *var;
+
+               kps = smh->video_write_fh->mm.source_kps;
+
+               if ((var = switch_channel_get_variable(session->channel, "video_file_min_kps"))) {
+                       min = atoi(var);
+                       if (min < 0) min = 0;
+               }
+
+               if ((var = switch_channel_get_variable(session->channel, "video_file_max_kps"))) {
+                       max = atoi(var);
+                       if (max < 0) max = 10000000;
+               }
+
+               if (min && kps < min) kps = min;
+               if (max != 10000000 && kps > max) kps = max;
+               
+               switch_core_media_set_outgoing_bitrate(session, SWITCH_MEDIA_TYPE_VIDEO, kps);
+       }
+
        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)) {
                switch_status_t wstatus = SWITCH_STATUS_FALSE;
 
+
+
                switch_core_timer_next(&timer);
+
                switch_mutex_lock(v_engine->mh.file_write_mutex);
 
                //if (smh->video_write_fh && smh->video_write_fh->mm.source_fps && smh->video_write_fh->mm.source_fps != fps) {
@@ -6903,15 +6929,25 @@ static void *SWITCH_THREAD_FUNC video_write_thread(switch_thread_t *thread, void
 
                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_BREAK) {
+                               switch_core_timer_sync(&timer);
+                       }
 
                        if (wstatus == SWITCH_STATUS_SUCCESS) {
+                               if (!kps && fr.img && (last_w != fr.img->d_w || last_h != fr.img->d_h)) {
+                                       kps = switch_calc_bitrate(fr.img->d_w, fr.img->d_h, 1, fps);
+                                       switch_core_media_set_outgoing_bitrate(session, SWITCH_MEDIA_TYPE_VIDEO, kps);
+                                       last_w = fr.img->d_w;
+                                       last_h = fr.img->d_h;
+                               }
+                               
                                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) {
+                               if (fr.img && 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);