Make SKIP_FRAMES a compilation flag

The skip_frames flag was a non-configurable runtime flag. Since it is
not exposed to the user, there is no need for a (possible) runtime cost.

For testing purpose, we still want it to be configurable, so make it a
compilation flag.
This commit is contained in:
Romain Vimont 2018-02-07 12:25:52 +01:00
parent 53ff1aa410
commit 8d30d40b79
6 changed files with 30 additions and 13 deletions

View file

@ -44,6 +44,11 @@ conf.set('DEFAULT_MAX_SIZE', '0') # 0: unlimited
# overridden by option --bit-rate
conf.set('DEFAULT_BIT_RATE', '4000000') # 4Mbps
# whether the app should always display the most recent available frame, even
# if the previous one has not been displayed
# SKIP_FRAMES improves latency at the cost of framerate
conf.set('SKIP_FRAMES', true)
configure_file(configuration: conf, output: 'config.h')
executable('scrcpy', src, dependencies: dependencies)

View file

@ -6,6 +6,7 @@
#include <SDL2/SDL_thread.h>
#include <unistd.h>
#include "config.h"
#include "events.h"
#include "frames.h"
#include "lockutil.h"
@ -22,13 +23,17 @@ static int read_packet(void *opaque, uint8_t *buf, int buf_size) {
static void push_frame(struct decoder *decoder) {
struct frames *frames = decoder->frames;
mutex_lock(frames->mutex);
if (!decoder->skip_frames) {
while (!frames->rendering_frame_consumed) {
cond_wait(frames->rendering_frame_consumed_cond, frames->mutex);
}
} else if (!frames->rendering_frame_consumed) {
#ifndef SKIP_FRAMES
// if SKIP_FRAMES is disabled, then the decoder must wait for the current
// frame to be consumed
while (!frames->rendering_frame_consumed) {
cond_wait(frames->rendering_frame_consumed_cond, frames->mutex);
}
#else
if (!frames->rendering_frame_consumed) {
SDL_LogInfo(SDL_LOG_CATEGORY_RENDER, "Skip frame");
}
#endif
frames_swap(frames);
frames->rendering_frame_consumed = SDL_FALSE;

View file

@ -11,7 +11,6 @@ struct decoder {
TCPsocket video_socket;
SDL_Thread *thread;
SDL_mutex *mutex;
SDL_bool skip_frames;
};
SDL_bool decoder_start(struct decoder *decoder);

View file

@ -17,16 +17,17 @@ SDL_bool frames_init(struct frames *frames) {
goto error_2;
}
#ifndef SKIP_FRAMES
if (!(frames->rendering_frame_consumed_cond = SDL_CreateCond())) {
goto error_3;
SDL_DestroyMutex(frames->mutex);
goto error_2;
}
#endif
frames->rendering_frame_consumed = SDL_TRUE;
return SDL_TRUE;
error_3:
SDL_DestroyMutex(frames->mutex);
error_2:
av_frame_free(&frames->rendering_frame);
error_1:
@ -36,7 +37,9 @@ error_0:
}
void frames_destroy(struct frames *frames) {
#ifndef SKIP_FRAMES
SDL_DestroyCond(frames->rendering_frame_consumed_cond);
#endif
SDL_DestroyMutex(frames->mutex);
av_frame_free(&frames->rendering_frame);
av_frame_free(&frames->decoding_frame);

View file

@ -4,6 +4,8 @@
#include <SDL2/SDL_mutex.h>
#include <SDL2/SDL_stdinc.h>
#include "config.h"
// forward declarations
typedef struct AVFrame AVFrame;
@ -11,7 +13,9 @@ struct frames {
AVFrame *decoding_frame;
AVFrame *rendering_frame;
SDL_mutex *mutex;
#ifndef SKIP_FRAMES
SDL_cond *rendering_frame_consumed_cond;
#endif
SDL_bool rendering_frame_consumed;
};

View file

@ -336,9 +336,11 @@ static SDL_bool handle_new_frame(void) {
mutex_lock(frames.mutex);
AVFrame *frame = frames.rendering_frame;
frames.rendering_frame_consumed = SDL_TRUE;
if (!decoder.skip_frames) {
cond_signal(frames.rendering_frame_consumed_cond);
}
#ifndef SKIP_FRAMES
// if SKIP_FRAMES is disabled, then notify the decoder the current frame is
// consumed, so that it may push a new one
cond_signal(frames.rendering_frame_consumed_cond);
#endif
struct size current_frame_size = {frame->width, frame->height};
if (!prepare_for_frame(window, renderer, &texture, frame_size, current_frame_size)) {
@ -583,7 +585,6 @@ SDL_bool scrcpy(const char *serial, Uint16 local_port, Uint16 max_size, Uint32 b
decoder.frames = &frames;
decoder.video_socket = device_socket;
decoder.skip_frames = SDL_TRUE;
// now we consumed the header values, the socket receives the video stream
// start the decoder