mirror of
https://github.com/outbackdingo/UltraGrid.git
synced 2026-03-21 23:40:26 +00:00
add set_standard_transmission_frame_rate method inside capturers to properly set actual framerate and the timestamp
This commit is contained in:
64
src/tv.c
64
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;
|
||||
}
|
||||
|
||||
9
src/tv.h
9
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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user