From 7f710cbd28883b356139f4ed6131893dca26bb18 Mon Sep 17 00:00:00 2001 From: Gerard CL Date: Wed, 21 May 2014 13:14:45 +0200 Subject: [PATCH] add set_standard_transmission_frame_rate method inside capturers to properly set actual framerate and the timestamp --- src/tv.c | 64 ++++++++++++++--------------- src/tv.h | 9 ++++ src/video_capture.c | 11 +++++ src/video_capture.h | 1 + src/video_capture/aggregate.c | 1 + src/video_capture/bluefish444.cpp | 1 + src/video_capture/decklink.cpp | 1 + src/video_capture/deltacast.cpp | 1 + src/video_capture/deltacast_dvi.cpp | 1 + src/video_capture/dvs.c | 1 + src/video_capture/import.c | 1 + src/video_capture/quicktime.c | 1 + src/video_capture/rtsp.c | 1 + src/video_capture/screen_osx.c | 1 + src/video_capture/screen_x11.c | 1 + src/video_capture/swmix.cpp | 1 + src/video_capture/testcard.c | 1 + src/video_capture/testcard2.c | 1 + src/video_capture/v4l2.c | 1 + 19 files changed, 66 insertions(+), 34 deletions(-) diff --git a/src/tv.c b/src/tv.c index a8f1a5ecf..2be02f047 100644 --- a/src/tv.c +++ b/src/tv.c @@ -137,58 +137,54 @@ int tv_gt(struct timeval a, struct timeval b) * Calculate initial time on first execution, add per 'sample' time otherwise. */ -//shared struct for audio and video streams (sync.) -typedef struct { - bool init; - uint32_t random_startime_offset; - struct timeval vtime; - struct timeval atime; - struct timeval start_time; -} std_time_struct; - -std_time_struct start_time = { true, 0, 0 }; +std_time_struct standard_time = { true, 0, 0, 25, 0, 0 }; uint32_t get_std_audio_local_mediatime(double samples) { - if (start_time.init) { - gettimeofday(&start_time.start_time, NULL); - start_time.atime = start_time.start_time; - start_time.vtime = start_time.start_time; - start_time.random_startime_offset = lbl_random(); - tv_add_usec(&start_time.vtime, start_time.random_startime_offset); - tv_add_usec(&start_time.atime, start_time.random_startime_offset); + if (standard_time.init) { + gettimeofday(&standard_time.start_time, NULL); + standard_time.atime = standard_time.start_time; + standard_time.vtime = standard_time.start_time; + standard_time.random_startime_offset = lbl_random(); + tv_add_usec(&standard_time.vtime, standard_time.random_startime_offset); + tv_add_usec(&standard_time.atime, standard_time.random_startime_offset); - start_time.init = false; + standard_time.init = false; } else { - tv_add(&start_time.atime, samples); + tv_add(&standard_time.atime, samples); } - return (double)start_time.atime.tv_sec + (((double)start_time.atime.tv_usec) / 1000000.0); + return (double)standard_time.atime.tv_sec + (((double)standard_time.atime.tv_usec) / 1000000.0); } -uint32_t get_std_video_local_mediatime(double framerate) +uint32_t get_std_video_local_mediatime(double framerate) //this is set from input params., but could be different from actual capturer { double vrate = 90000; //default and standard video sample rate (Hz) double nextFraction; unsigned nextSecsIncrement; - if (start_time.init) { - gettimeofday(&start_time.start_time, NULL); - start_time.atime = start_time.start_time; - start_time.vtime = start_time.start_time; - start_time.random_startime_offset = lbl_random(); - tv_add_usec(&start_time.vtime, start_time.random_startime_offset); - tv_add_usec(&start_time.atime, start_time.random_startime_offset); + if (standard_time.init) { + gettimeofday(&standard_time.start_time, NULL); + standard_time.atime = standard_time.start_time; + standard_time.vtime = standard_time.start_time; + standard_time.random_startime_offset = lbl_random(); + tv_add_usec(&standard_time.vtime, standard_time.random_startime_offset); + tv_add_usec(&standard_time.atime, standard_time.random_startime_offset); - start_time.init = false; + standard_time.init = false; } else { - nextFraction = ( start_time.vtime.tv_usec / 1000000.0 ) + ( 1 / framerate ); - nextSecsIncrement = (long) nextFraction; - start_time.vtime.tv_sec += (long) nextSecsIncrement; - start_time.vtime.tv_usec = (long) ((nextFraction - nextSecsIncrement) * 1000000); + if(standard_time.vfps == 0){ + nextFraction = ( standard_time.vtime.tv_usec / 1000000.0 ) + ( 1 / framerate ); + } + else{ + nextFraction = ( standard_time.vtime.tv_usec / 1000000.0 ) + ( 1 / standard_time.vfps ); + } + nextSecsIncrement = (long) nextFraction; + standard_time.vtime.tv_sec += (long) nextSecsIncrement; + standard_time.vtime.tv_usec = (long) ((nextFraction - nextSecsIncrement) * 1000000); } - return ((double)start_time.vtime.tv_sec + (((double)start_time.vtime.tv_usec) / 1000000.0)) * vrate; + return ((double)standard_time.vtime.tv_sec + (((double)standard_time.vtime.tv_usec) / 1000000.0)) * vrate; } diff --git a/src/tv.h b/src/tv.h index eb70c8313..bb2441087 100644 --- a/src/tv.h +++ b/src/tv.h @@ -48,6 +48,15 @@ extern "C" { #endif +typedef struct { //shared struct for audio and video streams (sync.) + bool init; + uint32_t random_startime_offset; + struct timeval vtime; + double vfps; + struct timeval atime; + struct timeval start_time; +} std_time_struct; + uint32_t get_local_mediatime(void); double tv_diff(struct timeval curr_time, struct timeval prev_time); uint32_t tv_diff_usec(struct timeval curr_time, struct timeval prev_time); diff --git a/src/video_capture.c b/src/video_capture.c index 46ab6bd7e..60dfaec20 100644 --- a/src/video_capture.c +++ b/src/video_capture.c @@ -63,6 +63,7 @@ #include "module.h" #include "utils/config_file.h" #include "video.h" +#include "tv.h" #include "video_capture.h" #include "video_capture/DirectShowGrabber.h" #include "video_capture/aggregate.h" @@ -747,3 +748,13 @@ void vidcap_params_free_struct(struct vidcap_params *buf) free(buf); } + +/** + * Standard transmission util: set current fps to standard transmission struct in order to get correct timestamp calculus + */ +extern std_time_struct standard_time; + +void set_standard_transmission_frame_rate(double framerate){ + standard_time.vfps = framerate; +} + diff --git a/src/video_capture.h b/src/video_capture.h index 991355ad2..66654255f 100644 --- a/src/video_capture.h +++ b/src/video_capture.h @@ -132,6 +132,7 @@ void vidcap_params_set_device(struct vidcap_params *params, con void vidcap_params_set_capture_filter(struct vidcap_params *params, const char *req_capture_filter); void vidcap_params_set_flags(struct vidcap_params *params, unsigned int flags); +void set_standard_transmission_frame_rate(double framerate); /// @} int vidcap_init_devices(void); diff --git a/src/video_capture/aggregate.c b/src/video_capture/aggregate.c index 94915e0fb..bbdf4ad58 100644 --- a/src/video_capture/aggregate.c +++ b/src/video_capture/aggregate.c @@ -236,6 +236,7 @@ vidcap_aggregate_grab(void *state, struct audio_frame **audio) double seconds = tv_diff(s->t, s->t0); if (seconds >= 5) { float fps = s->frames / seconds; + set_standard_transmission_frame_rate(fps); fprintf(stderr, "[aggregate cap.] %d frames in %g seconds = %g FPS\n", s->frames, seconds, fps); s->t0 = s->t; s->frames = 0; diff --git a/src/video_capture/bluefish444.cpp b/src/video_capture/bluefish444.cpp index ce2ec0e18..b77da615f 100644 --- a/src/video_capture/bluefish444.cpp +++ b/src/video_capture/bluefish444.cpp @@ -699,6 +699,7 @@ static void *worker(void *arg) double seconds = tv_diff(t, s->t0); if (seconds >= 5) { float fps = s->frames / seconds; + set_standard_transmission_frame_rate(fps); fprintf(stderr, "[Blue cap] %d frames in %g seconds = %g FPS\n", s->frames, seconds, fps); s->t0 = t; s->frames = 0; diff --git a/src/video_capture/decklink.cpp b/src/video_capture/decklink.cpp index 2d9d36369..e7216d640 100644 --- a/src/video_capture/decklink.cpp +++ b/src/video_capture/decklink.cpp @@ -1401,6 +1401,7 @@ vidcap_decklink_grab(void *state, struct audio_frame **audio) double seconds = tv_diff(t, s->t0); if (seconds >= 5) { float fps = s->frames / seconds; + set_standard_transmission_frame_rate(fps); fprintf(stderr, "[Decklink capture] %d frames in %g seconds = %g FPS\n", s->frames, seconds, fps); s->t0 = t; s->frames = 0; diff --git a/src/video_capture/deltacast.cpp b/src/video_capture/deltacast.cpp index 7bf766f21..31b4bb12d 100644 --- a/src/video_capture/deltacast.cpp +++ b/src/video_capture/deltacast.cpp @@ -567,6 +567,7 @@ vidcap_deltacast_grab(void *state, struct audio_frame **audio) double seconds = tv_diff(s->t, s->t0); if (seconds >= 5) { float fps = s->frames / seconds; + set_standard_transmission_frame_rate(fps); fprintf(stderr, "[DELTACAST cap.] %d frames in %g seconds = %g FPS\n", s->frames, seconds, fps); s->t0 = s->t; s->frames = 0; diff --git a/src/video_capture/deltacast_dvi.cpp b/src/video_capture/deltacast_dvi.cpp index 22b4591d5..352eb9723 100644 --- a/src/video_capture/deltacast_dvi.cpp +++ b/src/video_capture/deltacast_dvi.cpp @@ -777,6 +777,7 @@ vidcap_deltacast_dvi_grab(void *state, struct audio_frame **audio) double seconds = tv_diff(s->t, s->t0); if (seconds >= 5) { float fps = s->frames / seconds; + set_standard_transmission_frame_rate(fps); fprintf(stderr, "[DELTACAST cap.] %d frames in %g seconds = %g FPS\n", s->frames, seconds, fps); s->t0 = s->t; s->frames = 0; diff --git a/src/video_capture/dvs.c b/src/video_capture/dvs.c index 0db38d90d..8576467c6 100644 --- a/src/video_capture/dvs.c +++ b/src/video_capture/dvs.c @@ -587,6 +587,7 @@ struct video_frame *vidcap_dvs_grab(void *state, struct audio_frame **audio) double seconds = tv_diff(s->t, s->t0); if (seconds >= 5) { float fps = s->frames / seconds; + set_standard_transmission_frame_rate(fps); fprintf(stderr, "[DVS cap.] %d frames in %g seconds = %g FPS\n", s->frames, seconds, fps); s->t0 = s->t; s->frames = 0; diff --git a/src/video_capture/import.c b/src/video_capture/import.c index 3630859b7..a26c0de5b 100644 --- a/src/video_capture/import.c +++ b/src/video_capture/import.c @@ -1288,6 +1288,7 @@ vidcap_import_grab(void *state, struct audio_frame **audio) double seconds = tv_diff(cur_time, s->t0); if (seconds >= 5) { float fps = (s->frames - s->frames_prev) / seconds; + set_standard_transmission_frame_rate(fps); fprintf(stderr, "[import] %d frames in %g seconds = %g FPS\n", s->frames - s->frames_prev, seconds, fps); s->t0 = cur_time; s->frames_prev = s->frames; diff --git a/src/video_capture/quicktime.c b/src/video_capture/quicktime.c index 8da334b51..64f828a04 100644 --- a/src/video_capture/quicktime.c +++ b/src/video_capture/quicktime.c @@ -211,6 +211,7 @@ qt_data_proc(SGChannel c, Ptr p, long len, long *offset, long chRefCon, double seconds = tv_diff(t, s->t0); if (seconds >= 5) { float fps = s->frames / seconds; + set_standard_transmission_frame_rate(fps); fprintf(stderr, "[QuickTime cap.] %d frames in %g seconds = %g FPS\n", s->frames, seconds, fps); s->t0 = t; diff --git a/src/video_capture/rtsp.c b/src/video_capture/rtsp.c index 50e4d5bcf..81cc0bdd9 100644 --- a/src/video_capture/rtsp.c +++ b/src/video_capture/rtsp.c @@ -414,6 +414,7 @@ vidcap_rtsp_grab(void *state, struct audio_frame **audio) { double seconds = tv_diff(s->vrtsp_state->t, s->vrtsp_state->t0); if (seconds >= 5) { float fps = s->vrtsp_state->frames / seconds; + set_standard_transmission_frame_rate(fps); fprintf(stderr, "[rtsp capture] %d frames in %g seconds = %g FPS\n", s->vrtsp_state->frames, seconds, fps); s->vrtsp_state->t0 = s->vrtsp_state->t; diff --git a/src/video_capture/screen_osx.c b/src/video_capture/screen_osx.c index d9d3e7e74..d5406095c 100644 --- a/src/video_capture/screen_osx.c +++ b/src/video_capture/screen_osx.c @@ -220,6 +220,7 @@ struct video_frame * vidcap_screen_osx_grab(void *state, struct audio_frame **au double seconds = tv_diff(s->t, s->t0); if (seconds >= 5) { float fps = s->frames / seconds; + set_standard_transmission_frame_rate(fps); fprintf(stderr, "[screen capture] %d frames in %g seconds = %g FPS\n", s->frames, seconds, fps); s->t0 = s->t; s->frames = 0; diff --git a/src/video_capture/screen_x11.c b/src/video_capture/screen_x11.c index 2d225a1e1..f23ab767d 100644 --- a/src/video_capture/screen_x11.c +++ b/src/video_capture/screen_x11.c @@ -396,6 +396,7 @@ struct video_frame * vidcap_screen_x11_grab(void *state, struct audio_frame **au double seconds = tv_diff(s->t, s->t0); if (seconds >= 5) { float fps = s->frames / seconds; + set_standard_transmission_frame_rate(fps); fprintf(stderr, "[screen capture] %d frames in %g seconds = %g FPS\n", s->frames, seconds, fps); s->t0 = s->t; s->frames = 0; diff --git a/src/video_capture/swmix.cpp b/src/video_capture/swmix.cpp index bbaa800ac..8cc1475ff 100644 --- a/src/video_capture/swmix.cpp +++ b/src/video_capture/swmix.cpp @@ -1298,6 +1298,7 @@ vidcap_swmix_grab(void *state, struct audio_frame **audio) double seconds = tv_diff(s->t, s->t0); if (seconds >= 5) { float fps = s->frames / seconds; + set_standard_transmission_frame_rate(fps); fprintf(stderr, "[swmix cap.] %d frames in %g seconds = %g FPS\n", s->frames, seconds, fps); s->t0 = s->t; s->frames = 0; diff --git a/src/video_capture/testcard.c b/src/video_capture/testcard.c index 368ffb13c..1b44920e7 100644 --- a/src/video_capture/testcard.c +++ b/src/video_capture/testcard.c @@ -555,6 +555,7 @@ struct video_frame *vidcap_testcard_grab(void *arg, struct audio_frame **audio) double seconds = tv_diff(curr_time, state->t0); if (seconds >= 5) { float fps = state->count / seconds; + set_standard_transmission_frame_rate(fps); fprintf(stderr, "[testcard] %d frames in %g seconds = %g FPS\n", state->count, seconds, fps); state->t0 = curr_time; diff --git a/src/video_capture/testcard2.c b/src/video_capture/testcard2.c index 8c0d72006..94f96a735 100644 --- a/src/video_capture/testcard2.c +++ b/src/video_capture/testcard2.c @@ -473,6 +473,7 @@ next_frame: double seconds = tv_diff(curr_time, s->t0); if (seconds >= 5) { float fps = (s->count - stat_count_prev) / seconds; + set_standard_transmission_frame_rate(fps); fprintf(stderr, "[testcard2] %d frames in %g seconds = %g FPS\n", (s->count - stat_count_prev), seconds, fps); s->t0 = curr_time; diff --git a/src/video_capture/v4l2.c b/src/video_capture/v4l2.c index a3d8f5337..d6ce5bc5d 100644 --- a/src/video_capture/v4l2.c +++ b/src/video_capture/v4l2.c @@ -646,6 +646,7 @@ struct video_frame * vidcap_v4l2_grab(void *state, struct audio_frame **audio) double seconds = tv_diff(t, s->t0); if (seconds >= 5) { float fps = s->frames / seconds; + set_standard_transmission_frame_rate(fps); fprintf(stderr, "[V4L2 capture] %d frames in %g seconds = %g FPS\n", s->frames, seconds, fps); s->t0 = t; s->frames = 0;