Add FPS counter
Remove frame counter from scrcpy.c and add a new FPS counter, logging as INFO the measured frame rate every second (on new frame).
This commit is contained in:
parent
c6c17af840
commit
38e6682875
6 changed files with 99 additions and 21 deletions
|
@ -6,6 +6,7 @@ src = [
|
||||||
'src/convert.c',
|
'src/convert.c',
|
||||||
'src/decoder.c',
|
'src/decoder.c',
|
||||||
'src/device.c',
|
'src/device.c',
|
||||||
|
'src/fpscounter.c',
|
||||||
'src/frames.c',
|
'src/frames.c',
|
||||||
'src/lockutil.c',
|
'src/lockutil.c',
|
||||||
'src/netutil.c',
|
'src/netutil.c',
|
||||||
|
|
62
app/src/fpscounter.c
Normal file
62
app/src/fpscounter.c
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
#include "fpscounter.h"
|
||||||
|
|
||||||
|
#include <SDL2/SDL_timer.h>
|
||||||
|
|
||||||
|
#include "log.h"
|
||||||
|
|
||||||
|
void fps_counter_init(struct fps_counter *counter) {
|
||||||
|
counter->started = SDL_FALSE;
|
||||||
|
// no need to initialize the other fields, they are meaningful only when
|
||||||
|
// started is true
|
||||||
|
}
|
||||||
|
|
||||||
|
void fps_counter_start(struct fps_counter *counter) {
|
||||||
|
counter->started = SDL_TRUE;
|
||||||
|
counter->slice_start = SDL_GetTicks();
|
||||||
|
counter->nr_rendered = 0;
|
||||||
|
#ifdef SKIP_FRAMES
|
||||||
|
counter->nr_skipped = 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void fps_counter_stop(struct fps_counter *counter) {
|
||||||
|
counter->started = SDL_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void display_fps(struct fps_counter *counter) {
|
||||||
|
#ifdef SKIP_FRAMES
|
||||||
|
if (counter->nr_skipped) {
|
||||||
|
LOGI("%d fps (+%d frames skipped)", counter->nr_rendered, counter->nr_skipped);
|
||||||
|
} else {
|
||||||
|
#endif
|
||||||
|
LOGI("%d fps", counter->nr_rendered);
|
||||||
|
#ifdef SKIP_FRAMES
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static void check_expired(struct fps_counter *counter) {
|
||||||
|
Uint32 now = SDL_GetTicks();
|
||||||
|
if (now - counter->slice_start >= 1000) {
|
||||||
|
display_fps(counter);
|
||||||
|
// add a multiple of one second
|
||||||
|
Uint32 elapsed_slices = (now - counter->slice_start) / 1000;
|
||||||
|
counter->slice_start += 1000 * elapsed_slices;
|
||||||
|
counter->nr_rendered = 0;
|
||||||
|
#ifdef SKIP_FRAMES
|
||||||
|
counter->nr_skipped = 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void fps_counter_add_rendered_frame(struct fps_counter *counter) {
|
||||||
|
check_expired(counter);
|
||||||
|
++counter->nr_rendered;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef SKIP_FRAMES
|
||||||
|
void fps_counter_add_skipped_frame(struct fps_counter *counter) {
|
||||||
|
check_expired(counter);
|
||||||
|
++counter->nr_skipped;
|
||||||
|
}
|
||||||
|
#endif
|
26
app/src/fpscounter.h
Normal file
26
app/src/fpscounter.h
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
#ifndef FPSCOUNTER_H
|
||||||
|
#define FPSCOUNTER_H
|
||||||
|
|
||||||
|
#include <SDL2/SDL_stdinc.h>
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
struct fps_counter {
|
||||||
|
SDL_bool started;
|
||||||
|
Uint32 slice_start; // initialized by SDL_GetTicks()
|
||||||
|
int nr_rendered;
|
||||||
|
#ifdef SKIP_FRAMES
|
||||||
|
int nr_skipped;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
void fps_counter_init(struct fps_counter *counter);
|
||||||
|
void fps_counter_start(struct fps_counter *counter);
|
||||||
|
void fps_counter_stop(struct fps_counter *counter);
|
||||||
|
|
||||||
|
void fps_counter_add_rendered_frame(struct fps_counter *counter);
|
||||||
|
#ifdef SKIP_FRAMES
|
||||||
|
void fps_counter_add_skipped_frame(struct fps_counter *counter);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
|
@ -33,6 +33,7 @@ SDL_bool frames_init(struct frames *frames) {
|
||||||
// there is initially no rendering frame, so consider it has already been
|
// there is initially no rendering frame, so consider it has already been
|
||||||
// consumed
|
// consumed
|
||||||
frames->rendering_frame_consumed = SDL_TRUE;
|
frames->rendering_frame_consumed = SDL_TRUE;
|
||||||
|
fps_counter_init(&frames->fps_counter);
|
||||||
|
|
||||||
return SDL_TRUE;
|
return SDL_TRUE;
|
||||||
|
|
||||||
|
@ -68,8 +69,8 @@ SDL_bool frames_offer_decoded_frame(struct frames *frames) {
|
||||||
cond_wait(frames->rendering_frame_consumed_cond, frames->mutex);
|
cond_wait(frames->rendering_frame_consumed_cond, frames->mutex);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if (!frames->rendering_frame_consumed) {
|
if (frames->fps_counter.started && !frames->rendering_frame_consumed) {
|
||||||
LOGD("Skip frame");
|
fps_counter_add_skipped_frame(&frames->fps_counter);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -85,6 +86,9 @@ SDL_bool frames_offer_decoded_frame(struct frames *frames) {
|
||||||
const AVFrame *frames_consume_rendered_frame(struct frames *frames) {
|
const AVFrame *frames_consume_rendered_frame(struct frames *frames) {
|
||||||
SDL_assert(!frames->rendering_frame_consumed);
|
SDL_assert(!frames->rendering_frame_consumed);
|
||||||
frames->rendering_frame_consumed = SDL_TRUE;
|
frames->rendering_frame_consumed = SDL_TRUE;
|
||||||
|
if (frames->fps_counter.started) {
|
||||||
|
fps_counter_add_rendered_frame(&frames->fps_counter);
|
||||||
|
}
|
||||||
#ifndef SKIP_FRAMES
|
#ifndef SKIP_FRAMES
|
||||||
// if SKIP_FRAMES is disabled, then notify the decoder the current frame is
|
// if SKIP_FRAMES is disabled, then notify the decoder the current frame is
|
||||||
// consumed, so that it may push a new one
|
// consumed, so that it may push a new one
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include <SDL2/SDL_stdinc.h>
|
#include <SDL2/SDL_stdinc.h>
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#include "fpscounter.h"
|
||||||
|
|
||||||
// forward declarations
|
// forward declarations
|
||||||
typedef struct AVFrame AVFrame;
|
typedef struct AVFrame AVFrame;
|
||||||
|
@ -18,6 +19,7 @@ struct frames {
|
||||||
SDL_cond *rendering_frame_consumed_cond;
|
SDL_cond *rendering_frame_consumed_cond;
|
||||||
#endif
|
#endif
|
||||||
SDL_bool rendering_frame_consumed;
|
SDL_bool rendering_frame_consumed;
|
||||||
|
struct fps_counter fps_counter;
|
||||||
};
|
};
|
||||||
|
|
||||||
SDL_bool frames_init(struct frames *frames);
|
SDL_bool frames_init(struct frames *frames);
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include "device.h"
|
#include "device.h"
|
||||||
#include "events.h"
|
#include "events.h"
|
||||||
#include "frames.h"
|
#include "frames.h"
|
||||||
|
#include "fpscounter.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "lockutil.h"
|
#include "lockutil.h"
|
||||||
#include "netutil.h"
|
#include "netutil.h"
|
||||||
|
@ -29,24 +30,6 @@ static struct frames frames;
|
||||||
static struct decoder decoder;
|
static struct decoder decoder;
|
||||||
static struct controller controller;
|
static struct controller controller;
|
||||||
|
|
||||||
static long timestamp_ms(void) {
|
|
||||||
struct timeval tv;
|
|
||||||
gettimeofday(&tv, NULL);
|
|
||||||
return tv.tv_sec * 1000 + tv.tv_usec / 1000;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void count_frame(void) {
|
|
||||||
static long ts = 0;
|
|
||||||
static int nbframes = 0;
|
|
||||||
long now = timestamp_ms();
|
|
||||||
++nbframes;
|
|
||||||
if (now - ts > 1000) {
|
|
||||||
LOGD("%d fps", nbframes);
|
|
||||||
ts = now;
|
|
||||||
nbframes = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void event_loop(void) {
|
static void event_loop(void) {
|
||||||
SDL_Event event;
|
SDL_Event event;
|
||||||
while (SDL_WaitEvent(&event)) {
|
while (SDL_WaitEvent(&event)) {
|
||||||
|
@ -62,11 +45,11 @@ static void event_loop(void) {
|
||||||
screen.has_frame = SDL_TRUE;
|
screen.has_frame = SDL_TRUE;
|
||||||
// this is the very first frame, show the window
|
// this is the very first frame, show the window
|
||||||
screen_show_window(&screen);
|
screen_show_window(&screen);
|
||||||
|
fps_counter_start(&frames.fps_counter);
|
||||||
}
|
}
|
||||||
if (!screen_update_frame(&screen, &frames)) {
|
if (!screen_update_frame(&screen, &frames)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
count_frame(); // display fps for debug
|
|
||||||
break;
|
break;
|
||||||
case SDL_WINDOWEVENT:
|
case SDL_WINDOWEVENT:
|
||||||
switch (event.window.event) {
|
switch (event.window.event) {
|
||||||
|
|
Loading…
Reference in a new issue