Split up video_monitor code into separate file

This commit is contained in:
twinaphex 2015-01-18 18:28:14 +01:00
parent 0286078f8f
commit 5c32acf91f
8 changed files with 247 additions and 177 deletions

View File

@ -100,6 +100,7 @@ OBJ += frontend/frontend.o \
audio/audio_driver.o \
input/input_driver.o \
gfx/video_driver.o \
gfx/video_monitor.o \
osk/osk_driver.o \
camera/camera_driver.o \
menu/menu_driver.o \

155
driver.c
View File

@ -21,6 +21,7 @@
#include <string.h>
#include "compat/posix_string.h"
#include "gfx/video_thread_wrapper.h"
#include "gfx/video_monitor.h"
#include "gfx/gfx_common.h"
#ifdef HAVE_X11
@ -202,71 +203,9 @@ void init_drivers_pre(void)
#endif
}
static void adjust_system_rates(void)
void driver_adjust_system_rates(void)
{
float timing_skew;
const struct retro_system_timing *info =
(const struct retro_system_timing*)&g_extern.system.av_info.timing;
g_extern.system.force_nonblock = false;
if (info->fps <= 0.0 || info->sample_rate <= 0.0)
return;
timing_skew = fabs(1.0f - info->fps / g_settings.video.refresh_rate);
if (timing_skew > g_settings.audio.max_timing_skew)
{
/* We don't want to adjust pitch too much. If we have extreme cases,
* just don't readjust at all. */
RARCH_LOG("Timings deviate too much. Will not adjust. (Display = %.2f Hz, Game = %.2f Hz)\n",
g_settings.video.refresh_rate,
(float)info->fps);
/* We won't be able to do VSync reliably as game FPS > monitor FPS. */
if (info->fps > g_settings.video.refresh_rate)
{
g_extern.system.force_nonblock = true;
RARCH_LOG("Game FPS > Monitor FPS. Cannot rely on VSync.\n");
}
g_extern.audio_data.in_rate = info->sample_rate;
}
else
g_extern.audio_data.in_rate = info->sample_rate *
(g_settings.video.refresh_rate / info->fps);
RARCH_LOG("Set audio input rate to: %.2f Hz.\n",
g_extern.audio_data.in_rate);
if (driver.video_data)
{
if (g_extern.system.force_nonblock)
rarch_main_command(RARCH_CMD_VIDEO_SET_NONBLOCKING_STATE);
else
driver_set_nonblock_state(driver.nonblock_state);
}
}
/**
* video_monitor_set_refresh_rate:
* @hz : New refresh rate for monitor.
*
* Sets monitor refresh rate to new value.
**/
void video_monitor_set_refresh_rate(float hz)
{
char msg[PATH_MAX_LENGTH];
snprintf(msg, sizeof(msg), "Setting refresh rate to: %.3f Hz.", hz);
msg_queue_push(g_extern.msg_queue, msg, 1, 180);
RARCH_LOG("%s\n", msg);
g_settings.video.refresh_rate = hz;
adjust_system_rates();
g_extern.audio_data.orig_src_ratio =
g_extern.audio_data.src_ratio =
(double)g_settings.audio.out_rate / g_extern.audio_data.in_rate;
video_monitor_adjust_system_rates();
}
/**
@ -716,7 +655,7 @@ void init_drivers(int flags)
#endif
if (flags & (DRIVER_VIDEO | DRIVER_AUDIO))
adjust_system_rates();
driver_adjust_system_rates();
if (flags & DRIVER_VIDEO)
{
@ -764,38 +703,6 @@ void init_drivers(int flags)
}
}
/**
* video_monitor_compute_fps_statistics:
*
* Computes monitor FPS statistics.
**/
static void video_monitor_compute_fps_statistics(void)
{
double avg_fps = 0.0, stddev = 0.0;
unsigned samples = 0;
if (g_settings.video.threaded)
{
RARCH_LOG("Monitor FPS estimation is disabled for threaded video.\n");
return;
}
if (g_extern.measure_data.frame_time_samples_count <
2 * MEASURE_FRAME_TIME_SAMPLES_COUNT)
{
RARCH_LOG(
"Does not have enough samples for monitor refresh rate estimation. Requires to run for at least %u frames.\n",
2 * MEASURE_FRAME_TIME_SAMPLES_COUNT);
return;
}
if (video_monitor_fps_statistics(&avg_fps, &stddev, &samples))
{
RARCH_LOG("Average monitor Hz: %.6f Hz. (%.3f %% frame time deviation, based on %u last samples).\n",
avg_fps, 100.0 * stddev, samples);
}
}
static void uninit_video_input(void)
{
rarch_main_command(RARCH_CMD_OVERLAY_DEINIT);
@ -886,57 +793,3 @@ void uninit_drivers(int flags)
if ((flags & DRIVER_AUDIO) && !driver.audio_data_own)
driver.audio_data = NULL;
}
/**
* video_monitor_fps_statistics
* @refresh_rate : Monitor refresh rate.
* @deviation : Deviation from measured refresh rate.
* @sample_points : Amount of sampled points.
*
* Gets the monitor FPS statistics based on the current
* runtime.
*
* Returns: true (1) on success.
* false (0) if:
* a) threaded video mode is enabled
* b) less than 2 frame time samples.
* c) FPS monitor enable is off.
**/
bool video_monitor_fps_statistics(double *refresh_rate,
double *deviation, unsigned *sample_points)
{
unsigned i;
retro_time_t accum = 0, avg, accum_var = 0;
unsigned samples = min(MEASURE_FRAME_TIME_SAMPLES_COUNT,
g_extern.measure_data.frame_time_samples_count);
if (!g_settings.fps_monitor_enable ||
g_settings.video.threaded || (samples < 2))
return false;
/* Measure statistics on frame time (microsecs), *not* FPS. */
for (i = 0; i < samples; i++)
accum += g_extern.measure_data.frame_time_samples[i];
#if 0
for (i = 0; i < samples; i++)
RARCH_LOG("Interval #%u: %d usec / frame.\n",
i, (int)g_extern.measure_data.frame_time_samples[i]);
#endif
avg = accum / samples;
/* Drop first measurement. It is likely to be bad. */
for (i = 0; i < samples; i++)
{
retro_time_t diff = g_extern.measure_data.frame_time_samples[i] - avg;
accum_var += diff * diff;
}
*deviation = sqrt((double)accum_var / (samples - 1)) / avg;
*refresh_rate = 1000000.0 / avg;
*sample_points = samples;
return true;
}

View File

@ -347,32 +347,6 @@ void find_prev_driver(const char *label, char *str, size_t sizeof_str);
**/
void find_next_driver(const char *label, char *str, size_t sizeof_str);
/**
* video_monitor_set_refresh_rate:
* @hz : New refresh rate for monitor.
*
* Sets monitor refresh rate to new value.
**/
void video_monitor_set_refresh_rate(float hz);
/**
* video_monitor_fps_statistics
* @refresh_rate : Monitor refresh rate.
* @deviation : Deviation from measured refresh rate.
* @sample_points : Amount of sampled points.
*
* Gets the monitor FPS statistics based on the current
* runtime.
*
* Returns: true (1) on success.
* false (0) if:
* a) threaded video mode is enabled
* b) less than 2 frame time samples.
* c) FPS monitor enable is off.
**/
bool video_monitor_fps_statistics(double *refresh_rate,
double *deviation, unsigned *sample_points);
/**
* driver_set_nonblock_state:
* @enable : Enable nonblock state?
@ -384,6 +358,8 @@ bool video_monitor_fps_statistics(double *refresh_rate,
**/
void driver_set_nonblock_state(bool enable);
void driver_adjust_system_rates(void);
/**
* driver_get_current_framebuffer:
*

View File

@ -20,6 +20,7 @@
#include "../drivers_font_renderer/bitmap.h"
#include "../../menu/menu.h"
#include "../gfx_common.h"
#include "../video_monitor.h"
#ifdef HW_RVL
#include "../../wii/mem2_manager.h"

172
gfx/video_monitor.c Normal file
View File

@ -0,0 +1,172 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
* Copyright (C) 2011-2015 - Daniel De Matteis
*
* RetroArch is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with RetroArch.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "video_monitor.h"
#include "../driver.h"
#include "../general.h"
#include "../retroarch.h"
void video_monitor_adjust_system_rates(void)
{
float timing_skew;
const struct retro_system_timing *info =
(const struct retro_system_timing*)&g_extern.system.av_info.timing;
g_extern.system.force_nonblock = false;
if (info->fps <= 0.0 || info->sample_rate <= 0.0)
return;
timing_skew = fabs(1.0f - info->fps / g_settings.video.refresh_rate);
if (timing_skew > g_settings.audio.max_timing_skew)
{
/* We don't want to adjust pitch too much. If we have extreme cases,
* just don't readjust at all. */
RARCH_LOG("Timings deviate too much. Will not adjust. (Display = %.2f Hz, Game = %.2f Hz)\n",
g_settings.video.refresh_rate,
(float)info->fps);
/* We won't be able to do VSync reliably as game FPS > monitor FPS. */
if (info->fps > g_settings.video.refresh_rate)
{
g_extern.system.force_nonblock = true;
RARCH_LOG("Game FPS > Monitor FPS. Cannot rely on VSync.\n");
}
g_extern.audio_data.in_rate = info->sample_rate;
}
else
g_extern.audio_data.in_rate = info->sample_rate *
(g_settings.video.refresh_rate / info->fps);
RARCH_LOG("Set audio input rate to: %.2f Hz.\n",
g_extern.audio_data.in_rate);
if (!driver.video_data)
return;
if (g_extern.system.force_nonblock)
rarch_main_command(RARCH_CMD_VIDEO_SET_NONBLOCKING_STATE);
else
driver_set_nonblock_state(driver.nonblock_state);
}
/**
* video_monitor_set_refresh_rate:
* @hz : New refresh rate for monitor.
*
* Sets monitor refresh rate to new value.
**/
void video_monitor_set_refresh_rate(float hz)
{
char msg[PATH_MAX_LENGTH];
snprintf(msg, sizeof(msg), "Setting refresh rate to: %.3f Hz.", hz);
msg_queue_push(g_extern.msg_queue, msg, 1, 180);
RARCH_LOG("%s\n", msg);
g_settings.video.refresh_rate = hz;
driver_adjust_system_rates();
g_extern.audio_data.orig_src_ratio =
g_extern.audio_data.src_ratio =
(double)g_settings.audio.out_rate / g_extern.audio_data.in_rate;
}
/**
* video_monitor_compute_fps_statistics:
*
* Computes monitor FPS statistics.
**/
void video_monitor_compute_fps_statistics(void)
{
double avg_fps = 0.0, stddev = 0.0;
unsigned samples = 0;
if (g_settings.video.threaded)
{
RARCH_LOG("Monitor FPS estimation is disabled for threaded video.\n");
return;
}
if (g_extern.measure_data.frame_time_samples_count <
2 * MEASURE_FRAME_TIME_SAMPLES_COUNT)
{
RARCH_LOG(
"Does not have enough samples for monitor refresh rate estimation. Requires to run for at least %u frames.\n",
2 * MEASURE_FRAME_TIME_SAMPLES_COUNT);
return;
}
if (video_monitor_fps_statistics(&avg_fps, &stddev, &samples))
{
RARCH_LOG("Average monitor Hz: %.6f Hz. (%.3f %% frame time deviation, based on %u last samples).\n",
avg_fps, 100.0 * stddev, samples);
}
}
/**
* video_monitor_fps_statistics
* @refresh_rate : Monitor refresh rate.
* @deviation : Deviation from measured refresh rate.
* @sample_points : Amount of sampled points.
*
* Gets the monitor FPS statistics based on the current
* runtime.
*
* Returns: true (1) on success.
* false (0) if:
* a) threaded video mode is enabled
* b) less than 2 frame time samples.
* c) FPS monitor enable is off.
**/
bool video_monitor_fps_statistics(double *refresh_rate,
double *deviation, unsigned *sample_points)
{
unsigned i;
retro_time_t accum = 0, avg, accum_var = 0;
unsigned samples = min(MEASURE_FRAME_TIME_SAMPLES_COUNT,
g_extern.measure_data.frame_time_samples_count);
if (!g_settings.fps_monitor_enable ||
g_settings.video.threaded || (samples < 2))
return false;
/* Measure statistics on frame time (microsecs), *not* FPS. */
for (i = 0; i < samples; i++)
accum += g_extern.measure_data.frame_time_samples[i];
#if 0
for (i = 0; i < samples; i++)
RARCH_LOG("Interval #%u: %d usec / frame.\n",
i, (int)g_extern.measure_data.frame_time_samples[i]);
#endif
avg = accum / samples;
/* Drop first measurement. It is likely to be bad. */
for (i = 0; i < samples; i++)
{
retro_time_t diff = g_extern.measure_data.frame_time_samples[i] - avg;
accum_var += diff * diff;
}
*deviation = sqrt((double)accum_var / (samples - 1)) / avg;
*refresh_rate = 1000000.0 / avg;
*sample_points = samples;
return true;
}

65
gfx/video_monitor.h Normal file
View File

@ -0,0 +1,65 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
* Copyright (C) 2011-2015 - Daniel De Matteis
*
* RetroArch is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with RetroArch.
* If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __VIDEO_MONITOR_H
#define __VIDEO_MONITOR_H
#include <boolean.h>
#ifdef __cplusplus
extern "C" {
#endif
void video_monitor_adjust_system_rates(void);
/**
* video_monitor_set_refresh_rate:
* @hz : New refresh rate for monitor.
*
* Sets monitor refresh rate to new value.
**/
void video_monitor_set_refresh_rate(float hz);
/**
* video_monitor_compute_fps_statistics:
*
* Computes monitor FPS statistics.
**/
void video_monitor_compute_fps_statistics(void);
/**
* video_monitor_fps_statistics
* @refresh_rate : Monitor refresh rate.
* @deviation : Deviation from measured refresh rate.
* @sample_points : Amount of sampled points.
*
* Gets the monitor FPS statistics based on the current
* runtime.
*
* Returns: true (1) on success.
* false (0) if:
* a) threaded video mode is enabled
* b) less than 2 frame time samples.
* c) FPS monitor enable is off.
**/
bool video_monitor_fps_statistics(double *refresh_rate,
double *deviation, unsigned *sample_points);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -505,6 +505,7 @@ AUDIO
DRIVERS
============================================================ */
#include "../gfx/video_driver.c"
#include "../gfx/video_monitor.c"
#include "../input/input_driver.c"
#include "../audio/audio_driver.c"
#include "../osk/osk_driver.c"

View File

@ -19,6 +19,7 @@
#include "settings_data.h"
#include "dynamic.h"
#include <file/file_path.h>
#include "gfx/video_monitor.h"
#include "input/input_autodetect.h"
#include "input/input_common.h"
#include "config.def.h"