Replace SDL types by C99 standard types
Scrcpy is a C11 project. Use the C99 standard types instead of the SDL-specific types: SDL_bool -> bool SintXX -> intXX_t UintXX -> uintXX_t
This commit is contained in:
parent
8655ba7197
commit
dfed1b250e
40 changed files with 456 additions and 438 deletions
|
@ -1,32 +1,33 @@
|
||||||
#ifndef BUFFER_UTIL_H
|
#ifndef BUFFER_UTIL_H
|
||||||
#define BUFFER_UTIL_H
|
#define BUFFER_UTIL_H
|
||||||
|
|
||||||
#include <SDL2/SDL_stdinc.h>
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
buffer_write16be(Uint8 *buf, Uint16 value) {
|
buffer_write16be(uint8_t *buf, uint16_t value) {
|
||||||
buf[0] = value >> 8;
|
buf[0] = value >> 8;
|
||||||
buf[1] = value;
|
buf[1] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
buffer_write32be(Uint8 *buf, Uint32 value) {
|
buffer_write32be(uint8_t *buf, uint32_t value) {
|
||||||
buf[0] = value >> 24;
|
buf[0] = value >> 24;
|
||||||
buf[1] = value >> 16;
|
buf[1] = value >> 16;
|
||||||
buf[2] = value >> 8;
|
buf[2] = value >> 8;
|
||||||
buf[3] = value;
|
buf[3] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline Uint32
|
static inline uint32_t
|
||||||
buffer_read32be(Uint8 *buf) {
|
buffer_read32be(uint8_t *buf) {
|
||||||
return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
|
return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline
|
static inline
|
||||||
Uint64 buffer_read64be(Uint8 *buf) {
|
uint64_t buffer_read64be(uint8_t *buf) {
|
||||||
Uint32 msb = buffer_read32be(buf);
|
uint32_t msb = buffer_read32be(buf);
|
||||||
Uint32 lsb = buffer_read32be(&buf[4]);
|
uint32_t lsb = buffer_read32be(&buf[4]);
|
||||||
return ((Uint64) msb << 32) | lsb;
|
return ((uint64_t) msb << 32) | lsb;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -146,11 +146,11 @@ adb_install(const char *serial, const char *local) {
|
||||||
return proc;
|
return proc;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_bool
|
bool
|
||||||
process_check_success(process_t proc, const char *name) {
|
process_check_success(process_t proc, const char *name) {
|
||||||
if (proc == PROCESS_NONE) {
|
if (proc == PROCESS_NONE) {
|
||||||
LOGE("Could not execute \"%s\"", name);
|
LOGE("Could not execute \"%s\"", name);
|
||||||
return SDL_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
exit_code_t exit_code;
|
exit_code_t exit_code;
|
||||||
if (!cmd_simple_wait(proc, &exit_code)) {
|
if (!cmd_simple_wait(proc, &exit_code)) {
|
||||||
|
@ -159,7 +159,7 @@ process_check_success(process_t proc, const char *name) {
|
||||||
} else {
|
} else {
|
||||||
LOGE("\"%s\" exited unexpectedly", name);
|
LOGE("\"%s\" exited unexpectedly", name);
|
||||||
}
|
}
|
||||||
return SDL_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
return SDL_TRUE;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
#ifndef COMMAND_H
|
#ifndef COMMAND_H
|
||||||
#define COMMAND_H
|
#define COMMAND_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <SDL2/SDL_stdinc.h>
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
|
||||||
|
@ -42,10 +42,10 @@ enum process_result {
|
||||||
enum process_result
|
enum process_result
|
||||||
cmd_execute(const char *path, const char *const argv[], process_t *process);
|
cmd_execute(const char *path, const char *const argv[], process_t *process);
|
||||||
|
|
||||||
SDL_bool
|
bool
|
||||||
cmd_terminate(process_t pid);
|
cmd_terminate(process_t pid);
|
||||||
|
|
||||||
SDL_bool
|
bool
|
||||||
cmd_simple_wait(process_t pid, exit_code_t *exit_code);
|
cmd_simple_wait(process_t pid, exit_code_t *exit_code);
|
||||||
|
|
||||||
process_t
|
process_t
|
||||||
|
@ -73,7 +73,7 @@ adb_install(const char *serial, const char *local);
|
||||||
|
|
||||||
// convenience function to wait for a successful process execution
|
// convenience function to wait for a successful process execution
|
||||||
// automatically log process errors with the provided process name
|
// automatically log process errors with the provided process name
|
||||||
SDL_bool
|
bool
|
||||||
process_check_success(process_t process, const char *name);
|
process_check_success(process_t process, const char *name);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,20 +1,20 @@
|
||||||
#ifndef COMMON_H
|
#ifndef COMMON_H
|
||||||
#define COMMON_H
|
#define COMMON_H
|
||||||
|
|
||||||
#include <SDL2/SDL_stdinc.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#define ARRAY_LEN(a) (sizeof(a) / sizeof(a[0]))
|
#define ARRAY_LEN(a) (sizeof(a) / sizeof(a[0]))
|
||||||
#define MIN(X,Y) (X) < (Y) ? (X) : (Y)
|
#define MIN(X,Y) (X) < (Y) ? (X) : (Y)
|
||||||
#define MAX(X,Y) (X) > (Y) ? (X) : (Y)
|
#define MAX(X,Y) (X) > (Y) ? (X) : (Y)
|
||||||
|
|
||||||
struct size {
|
struct size {
|
||||||
Uint16 width;
|
uint16_t width;
|
||||||
Uint16 height;
|
uint16_t height;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct point {
|
struct point {
|
||||||
Sint32 x;
|
int32_t x;
|
||||||
Sint32 y;
|
int32_t y;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct position {
|
struct position {
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
#include "control_event.h"
|
#include "control_event.h"
|
||||||
|
|
||||||
#include <SDL2/SDL_stdinc.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "buffer_util.h"
|
#include "buffer_util.h"
|
||||||
|
@ -8,7 +7,7 @@
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
static void
|
static void
|
||||||
write_position(Uint8 *buf, const struct position *position) {
|
write_position(uint8_t *buf, const struct position *position) {
|
||||||
buffer_write32be(&buf[0], position->point.x);
|
buffer_write32be(&buf[0], position->point.x);
|
||||||
buffer_write32be(&buf[4], position->point.y);
|
buffer_write32be(&buf[4], position->point.y);
|
||||||
buffer_write16be(&buf[8], position->screen_size.width);
|
buffer_write16be(&buf[8], position->screen_size.width);
|
||||||
|
@ -31,7 +30,7 @@ control_event_serialize(const struct control_event *event, unsigned char *buf) {
|
||||||
// injecting a text takes time, so limit the text length
|
// injecting a text takes time, so limit the text length
|
||||||
len = TEXT_MAX_LENGTH;
|
len = TEXT_MAX_LENGTH;
|
||||||
}
|
}
|
||||||
buffer_write16be(&buf[1], (Uint16) len);
|
buffer_write16be(&buf[1], (uint16_t) len);
|
||||||
memcpy(&buf[3], event->text_event.text, len);
|
memcpy(&buf[3], event->text_event.text, len);
|
||||||
return 3 + len;
|
return 3 + len;
|
||||||
}
|
}
|
||||||
|
@ -42,8 +41,8 @@ control_event_serialize(const struct control_event *event, unsigned char *buf) {
|
||||||
return 18;
|
return 18;
|
||||||
case CONTROL_EVENT_TYPE_SCROLL:
|
case CONTROL_EVENT_TYPE_SCROLL:
|
||||||
write_position(&buf[1], &event->scroll_event.position);
|
write_position(&buf[1], &event->scroll_event.position);
|
||||||
buffer_write32be(&buf[13], (Uint32) event->scroll_event.hscroll);
|
buffer_write32be(&buf[13], (uint32_t) event->scroll_event.hscroll);
|
||||||
buffer_write32be(&buf[17], (Uint32) event->scroll_event.vscroll);
|
buffer_write32be(&buf[17], (uint32_t) event->scroll_event.vscroll);
|
||||||
return 21;
|
return 21;
|
||||||
case CONTROL_EVENT_TYPE_COMMAND:
|
case CONTROL_EVENT_TYPE_COMMAND:
|
||||||
buf[1] = event->command_event.action;
|
buf[1] = event->command_event.action;
|
||||||
|
@ -61,22 +60,22 @@ control_event_destroy(struct control_event *event) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_bool
|
bool
|
||||||
control_event_queue_is_empty(const struct control_event_queue *queue) {
|
control_event_queue_is_empty(const struct control_event_queue *queue) {
|
||||||
return queue->head == queue->tail;
|
return queue->head == queue->tail;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_bool
|
bool
|
||||||
control_event_queue_is_full(const struct control_event_queue *queue) {
|
control_event_queue_is_full(const struct control_event_queue *queue) {
|
||||||
return (queue->head + 1) % CONTROL_EVENT_QUEUE_SIZE == queue->tail;
|
return (queue->head + 1) % CONTROL_EVENT_QUEUE_SIZE == queue->tail;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_bool
|
bool
|
||||||
control_event_queue_init(struct control_event_queue *queue) {
|
control_event_queue_init(struct control_event_queue *queue) {
|
||||||
queue->head = 0;
|
queue->head = 0;
|
||||||
queue->tail = 0;
|
queue->tail = 0;
|
||||||
// the current implementation may not fail
|
// the current implementation may not fail
|
||||||
return SDL_TRUE;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -88,24 +87,24 @@ control_event_queue_destroy(struct control_event_queue *queue) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_bool
|
bool
|
||||||
control_event_queue_push(struct control_event_queue *queue,
|
control_event_queue_push(struct control_event_queue *queue,
|
||||||
const struct control_event *event) {
|
const struct control_event *event) {
|
||||||
if (control_event_queue_is_full(queue)) {
|
if (control_event_queue_is_full(queue)) {
|
||||||
return SDL_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
queue->data[queue->head] = *event;
|
queue->data[queue->head] = *event;
|
||||||
queue->head = (queue->head + 1) % CONTROL_EVENT_QUEUE_SIZE;
|
queue->head = (queue->head + 1) % CONTROL_EVENT_QUEUE_SIZE;
|
||||||
return SDL_TRUE;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_bool
|
bool
|
||||||
control_event_queue_take(struct control_event_queue *queue,
|
control_event_queue_take(struct control_event_queue *queue,
|
||||||
struct control_event *event) {
|
struct control_event *event) {
|
||||||
if (control_event_queue_is_empty(queue)) {
|
if (control_event_queue_is_empty(queue)) {
|
||||||
return SDL_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
*event = queue->data[queue->tail];
|
*event = queue->data[queue->tail];
|
||||||
queue->tail = (queue->tail + 1) % CONTROL_EVENT_QUEUE_SIZE;
|
queue->tail = (queue->tail + 1) % CONTROL_EVENT_QUEUE_SIZE;
|
||||||
return SDL_TRUE;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
#ifndef CONTROLEVENT_H
|
#ifndef CONTROLEVENT_H
|
||||||
#define CONTROLEVENT_H
|
#define CONTROLEVENT_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
#include <SDL2/SDL_mutex.h>
|
#include <SDL2/SDL_mutex.h>
|
||||||
#include <SDL2/SDL_stdinc.h>
|
|
||||||
|
|
||||||
#include "android/input.h"
|
#include "android/input.h"
|
||||||
#include "android/keycodes.h"
|
#include "android/keycodes.h"
|
||||||
|
@ -44,8 +45,8 @@ struct control_event {
|
||||||
} mouse_event;
|
} mouse_event;
|
||||||
struct {
|
struct {
|
||||||
struct position position;
|
struct position position;
|
||||||
Sint32 hscroll;
|
int32_t hscroll;
|
||||||
Sint32 vscroll;
|
int32_t vscroll;
|
||||||
} scroll_event;
|
} scroll_event;
|
||||||
struct {
|
struct {
|
||||||
enum control_event_command action;
|
enum control_event_command action;
|
||||||
|
@ -63,24 +64,24 @@ struct control_event_queue {
|
||||||
int
|
int
|
||||||
control_event_serialize(const struct control_event *event, unsigned char *buf);
|
control_event_serialize(const struct control_event *event, unsigned char *buf);
|
||||||
|
|
||||||
SDL_bool
|
bool
|
||||||
control_event_queue_init(struct control_event_queue *queue);
|
control_event_queue_init(struct control_event_queue *queue);
|
||||||
|
|
||||||
void
|
void
|
||||||
control_event_queue_destroy(struct control_event_queue *queue);
|
control_event_queue_destroy(struct control_event_queue *queue);
|
||||||
|
|
||||||
SDL_bool
|
bool
|
||||||
control_event_queue_is_empty(const struct control_event_queue *queue);
|
control_event_queue_is_empty(const struct control_event_queue *queue);
|
||||||
|
|
||||||
SDL_bool
|
bool
|
||||||
control_event_queue_is_full(const struct control_event_queue *queue);
|
control_event_queue_is_full(const struct control_event_queue *queue);
|
||||||
|
|
||||||
// event is copied, the queue does not use the event after the function returns
|
// event is copied, the queue does not use the event after the function returns
|
||||||
SDL_bool
|
bool
|
||||||
control_event_queue_push(struct control_event_queue *queue,
|
control_event_queue_push(struct control_event_queue *queue,
|
||||||
const struct control_event *event);
|
const struct control_event *event);
|
||||||
|
|
||||||
SDL_bool
|
bool
|
||||||
control_event_queue_take(struct control_event_queue *queue,
|
control_event_queue_take(struct control_event_queue *queue,
|
||||||
struct control_event *event);
|
struct control_event *event);
|
||||||
|
|
||||||
|
|
|
@ -1,29 +1,30 @@
|
||||||
#include "controller.h"
|
#include "controller.h"
|
||||||
|
|
||||||
#include <SDL2/SDL_assert.h>
|
#include <SDL2/SDL_assert.h>
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "lock_util.h"
|
#include "lock_util.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
SDL_bool
|
bool
|
||||||
controller_init(struct controller *controller, socket_t video_socket) {
|
controller_init(struct controller *controller, socket_t video_socket) {
|
||||||
if (!control_event_queue_init(&controller->queue)) {
|
if (!control_event_queue_init(&controller->queue)) {
|
||||||
return SDL_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(controller->mutex = SDL_CreateMutex())) {
|
if (!(controller->mutex = SDL_CreateMutex())) {
|
||||||
return SDL_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(controller->event_cond = SDL_CreateCond())) {
|
if (!(controller->event_cond = SDL_CreateCond())) {
|
||||||
SDL_DestroyMutex(controller->mutex);
|
SDL_DestroyMutex(controller->mutex);
|
||||||
return SDL_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
controller->video_socket = video_socket;
|
controller->video_socket = video_socket;
|
||||||
controller->stopped = SDL_FALSE;
|
controller->stopped = false;
|
||||||
|
|
||||||
return SDL_TRUE;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -33,12 +34,12 @@ controller_destroy(struct controller *controller) {
|
||||||
control_event_queue_destroy(&controller->queue);
|
control_event_queue_destroy(&controller->queue);
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_bool
|
bool
|
||||||
controller_push_event(struct controller *controller,
|
controller_push_event(struct controller *controller,
|
||||||
const struct control_event *event) {
|
const struct control_event *event) {
|
||||||
SDL_bool res;
|
bool res;
|
||||||
mutex_lock(controller->mutex);
|
mutex_lock(controller->mutex);
|
||||||
SDL_bool was_empty = control_event_queue_is_empty(&controller->queue);
|
bool was_empty = control_event_queue_is_empty(&controller->queue);
|
||||||
res = control_event_queue_push(&controller->queue, event);
|
res = control_event_queue_push(&controller->queue, event);
|
||||||
if (was_empty) {
|
if (was_empty) {
|
||||||
cond_signal(controller->event_cond);
|
cond_signal(controller->event_cond);
|
||||||
|
@ -47,13 +48,13 @@ controller_push_event(struct controller *controller,
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SDL_bool
|
static bool
|
||||||
process_event(struct controller *controller,
|
process_event(struct controller *controller,
|
||||||
const struct control_event *event) {
|
const struct control_event *event) {
|
||||||
unsigned char serialized_event[SERIALIZED_EVENT_MAX_SIZE];
|
unsigned char serialized_event[SERIALIZED_EVENT_MAX_SIZE];
|
||||||
int length = control_event_serialize(event, serialized_event);
|
int length = control_event_serialize(event, serialized_event);
|
||||||
if (!length) {
|
if (!length) {
|
||||||
return SDL_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
int w = net_send_all(controller->video_socket, serialized_event, length);
|
int w = net_send_all(controller->video_socket, serialized_event, length);
|
||||||
return w == length;
|
return w == length;
|
||||||
|
@ -75,12 +76,12 @@ run_controller(void *data) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
struct control_event event;
|
struct control_event event;
|
||||||
SDL_bool non_empty = control_event_queue_take(&controller->queue,
|
bool non_empty = control_event_queue_take(&controller->queue,
|
||||||
&event);
|
&event);
|
||||||
SDL_assert(non_empty);
|
SDL_assert(non_empty);
|
||||||
mutex_unlock(controller->mutex);
|
mutex_unlock(controller->mutex);
|
||||||
|
|
||||||
SDL_bool ok = process_event(controller, &event);
|
bool ok = process_event(controller, &event);
|
||||||
control_event_destroy(&event);
|
control_event_destroy(&event);
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
LOGD("Cannot write event to socket");
|
LOGD("Cannot write event to socket");
|
||||||
|
@ -90,7 +91,7 @@ run_controller(void *data) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_bool
|
bool
|
||||||
controller_start(struct controller *controller) {
|
controller_start(struct controller *controller) {
|
||||||
LOGD("Starting controller thread");
|
LOGD("Starting controller thread");
|
||||||
|
|
||||||
|
@ -98,16 +99,16 @@ controller_start(struct controller *controller) {
|
||||||
controller);
|
controller);
|
||||||
if (!controller->thread) {
|
if (!controller->thread) {
|
||||||
LOGC("Could not start controller thread");
|
LOGC("Could not start controller thread");
|
||||||
return SDL_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return SDL_TRUE;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
controller_stop(struct controller *controller) {
|
controller_stop(struct controller *controller) {
|
||||||
mutex_lock(controller->mutex);
|
mutex_lock(controller->mutex);
|
||||||
controller->stopped = SDL_TRUE;
|
controller->stopped = true;
|
||||||
cond_signal(controller->event_cond);
|
cond_signal(controller->event_cond);
|
||||||
mutex_unlock(controller->mutex);
|
mutex_unlock(controller->mutex);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
|
|
||||||
#include "control_event.h"
|
#include "control_event.h"
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
#include <SDL2/SDL_mutex.h>
|
#include <SDL2/SDL_mutex.h>
|
||||||
#include <SDL2/SDL_stdinc.h>
|
|
||||||
#include <SDL2/SDL_thread.h>
|
#include <SDL2/SDL_thread.h>
|
||||||
|
|
||||||
#include "net.h"
|
#include "net.h"
|
||||||
|
@ -14,17 +14,17 @@ struct controller {
|
||||||
SDL_Thread *thread;
|
SDL_Thread *thread;
|
||||||
SDL_mutex *mutex;
|
SDL_mutex *mutex;
|
||||||
SDL_cond *event_cond;
|
SDL_cond *event_cond;
|
||||||
SDL_bool stopped;
|
bool stopped;
|
||||||
struct control_event_queue queue;
|
struct control_event_queue queue;
|
||||||
};
|
};
|
||||||
|
|
||||||
SDL_bool
|
bool
|
||||||
controller_init(struct controller *controller, socket_t video_socket);
|
controller_init(struct controller *controller, socket_t video_socket);
|
||||||
|
|
||||||
void
|
void
|
||||||
controller_destroy(struct controller *controller);
|
controller_destroy(struct controller *controller);
|
||||||
|
|
||||||
SDL_bool
|
bool
|
||||||
controller_start(struct controller *controller);
|
controller_start(struct controller *controller);
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -34,7 +34,7 @@ void
|
||||||
controller_join(struct controller *controller);
|
controller_join(struct controller *controller);
|
||||||
|
|
||||||
// expose simple API to hide control_event_queue
|
// expose simple API to hide control_event_queue
|
||||||
SDL_bool
|
bool
|
||||||
controller_push_event(struct controller *controller,
|
controller_push_event(struct controller *controller,
|
||||||
const struct control_event *event);
|
const struct control_event *event);
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
#include "convert.h"
|
#include "convert.h"
|
||||||
|
|
||||||
#define MAP(FROM, TO) case FROM: *to = TO; return SDL_TRUE
|
#define MAP(FROM, TO) case FROM: *to = TO; return true
|
||||||
#define FAIL default: return SDL_FALSE
|
#define FAIL default: return false
|
||||||
|
|
||||||
static SDL_bool
|
static bool
|
||||||
convert_keycode_action(SDL_EventType from, enum android_keyevent_action *to) {
|
convert_keycode_action(SDL_EventType from, enum android_keyevent_action *to) {
|
||||||
switch (from) {
|
switch (from) {
|
||||||
MAP(SDL_KEYDOWN, AKEY_EVENT_ACTION_DOWN);
|
MAP(SDL_KEYDOWN, AKEY_EVENT_ACTION_DOWN);
|
||||||
|
@ -73,8 +73,8 @@ convert_meta_state(SDL_Keymod mod) {
|
||||||
return autocomplete_metastate(metastate);
|
return autocomplete_metastate(metastate);
|
||||||
}
|
}
|
||||||
|
|
||||||
static SDL_bool
|
static bool
|
||||||
convert_keycode(SDL_Keycode from, enum android_keycode *to, Uint16 mod) {
|
convert_keycode(SDL_Keycode from, enum android_keycode *to, uint16_t mod) {
|
||||||
switch (from) {
|
switch (from) {
|
||||||
MAP(SDLK_RETURN, AKEYCODE_ENTER);
|
MAP(SDLK_RETURN, AKEYCODE_ENTER);
|
||||||
MAP(SDLK_KP_ENTER, AKEYCODE_NUMPAD_ENTER);
|
MAP(SDLK_KP_ENTER, AKEYCODE_NUMPAD_ENTER);
|
||||||
|
@ -92,7 +92,7 @@ convert_keycode(SDL_Keycode from, enum android_keycode *to, Uint16 mod) {
|
||||||
MAP(SDLK_UP, AKEYCODE_DPAD_UP);
|
MAP(SDLK_UP, AKEYCODE_DPAD_UP);
|
||||||
}
|
}
|
||||||
if (mod & (KMOD_LALT | KMOD_RALT | KMOD_LGUI | KMOD_RGUI)) {
|
if (mod & (KMOD_LALT | KMOD_RALT | KMOD_LGUI | KMOD_RGUI)) {
|
||||||
return SDL_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
// if ALT and META are not pressed, also handle letters and space
|
// if ALT and META are not pressed, also handle letters and space
|
||||||
switch (from) {
|
switch (from) {
|
||||||
|
@ -127,7 +127,7 @@ convert_keycode(SDL_Keycode from, enum android_keycode *to, Uint16 mod) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static SDL_bool
|
static bool
|
||||||
convert_mouse_action(SDL_EventType from, enum android_motionevent_action *to) {
|
convert_mouse_action(SDL_EventType from, enum android_motionevent_action *to) {
|
||||||
switch (from) {
|
switch (from) {
|
||||||
MAP(SDL_MOUSEBUTTONDOWN, AMOTION_EVENT_ACTION_DOWN);
|
MAP(SDL_MOUSEBUTTONDOWN, AMOTION_EVENT_ACTION_DOWN);
|
||||||
|
@ -137,7 +137,7 @@ convert_mouse_action(SDL_EventType from, enum android_motionevent_action *to) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum android_motionevent_buttons
|
static enum android_motionevent_buttons
|
||||||
convert_mouse_buttons(Uint32 state) {
|
convert_mouse_buttons(uint32_t state) {
|
||||||
enum android_motionevent_buttons buttons = 0;
|
enum android_motionevent_buttons buttons = 0;
|
||||||
if (state & SDL_BUTTON_LMASK) {
|
if (state & SDL_BUTTON_LMASK) {
|
||||||
buttons |= AMOTION_EVENT_BUTTON_PRIMARY;
|
buttons |= AMOTION_EVENT_BUTTON_PRIMARY;
|
||||||
|
@ -157,33 +157,33 @@ convert_mouse_buttons(Uint32 state) {
|
||||||
return buttons;
|
return buttons;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_bool
|
bool
|
||||||
input_key_from_sdl_to_android(const SDL_KeyboardEvent *from,
|
input_key_from_sdl_to_android(const SDL_KeyboardEvent *from,
|
||||||
struct control_event *to) {
|
struct control_event *to) {
|
||||||
to->type = CONTROL_EVENT_TYPE_KEYCODE;
|
to->type = CONTROL_EVENT_TYPE_KEYCODE;
|
||||||
|
|
||||||
if (!convert_keycode_action(from->type, &to->keycode_event.action)) {
|
if (!convert_keycode_action(from->type, &to->keycode_event.action)) {
|
||||||
return SDL_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Uint16 mod = from->keysym.mod;
|
uint16_t mod = from->keysym.mod;
|
||||||
if (!convert_keycode(from->keysym.sym, &to->keycode_event.keycode, mod)) {
|
if (!convert_keycode(from->keysym.sym, &to->keycode_event.keycode, mod)) {
|
||||||
return SDL_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
to->keycode_event.metastate = convert_meta_state(mod);
|
to->keycode_event.metastate = convert_meta_state(mod);
|
||||||
|
|
||||||
return SDL_TRUE;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_bool
|
bool
|
||||||
mouse_button_from_sdl_to_android(const SDL_MouseButtonEvent *from,
|
mouse_button_from_sdl_to_android(const SDL_MouseButtonEvent *from,
|
||||||
struct size screen_size,
|
struct size screen_size,
|
||||||
struct control_event *to) {
|
struct control_event *to) {
|
||||||
to->type = CONTROL_EVENT_TYPE_MOUSE;
|
to->type = CONTROL_EVENT_TYPE_MOUSE;
|
||||||
|
|
||||||
if (!convert_mouse_action(from->type, &to->mouse_event.action)) {
|
if (!convert_mouse_action(from->type, &to->mouse_event.action)) {
|
||||||
return SDL_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
to->mouse_event.buttons = convert_mouse_buttons(SDL_BUTTON(from->button));
|
to->mouse_event.buttons = convert_mouse_buttons(SDL_BUTTON(from->button));
|
||||||
|
@ -191,10 +191,10 @@ mouse_button_from_sdl_to_android(const SDL_MouseButtonEvent *from,
|
||||||
to->mouse_event.position.point.x = from->x;
|
to->mouse_event.position.point.x = from->x;
|
||||||
to->mouse_event.position.point.y = from->y;
|
to->mouse_event.position.point.y = from->y;
|
||||||
|
|
||||||
return SDL_TRUE;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_bool
|
bool
|
||||||
mouse_motion_from_sdl_to_android(const SDL_MouseMotionEvent *from,
|
mouse_motion_from_sdl_to_android(const SDL_MouseMotionEvent *from,
|
||||||
struct size screen_size,
|
struct size screen_size,
|
||||||
struct control_event *to) {
|
struct control_event *to) {
|
||||||
|
@ -205,10 +205,10 @@ mouse_motion_from_sdl_to_android(const SDL_MouseMotionEvent *from,
|
||||||
to->mouse_event.position.point.x = from->x;
|
to->mouse_event.position.point.x = from->x;
|
||||||
to->mouse_event.position.point.y = from->y;
|
to->mouse_event.position.point.y = from->y;
|
||||||
|
|
||||||
return SDL_TRUE;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_bool
|
bool
|
||||||
mouse_wheel_from_sdl_to_android(const SDL_MouseWheelEvent *from,
|
mouse_wheel_from_sdl_to_android(const SDL_MouseWheelEvent *from,
|
||||||
struct position position,
|
struct position position,
|
||||||
struct control_event *to) {
|
struct control_event *to) {
|
||||||
|
@ -223,5 +223,5 @@ mouse_wheel_from_sdl_to_android(const SDL_MouseWheelEvent *from,
|
||||||
to->scroll_event.hscroll = -mul * from->x;
|
to->scroll_event.hscroll = -mul * from->x;
|
||||||
to->scroll_event.vscroll = mul * from->y;
|
to->scroll_event.vscroll = mul * from->y;
|
||||||
|
|
||||||
return SDL_TRUE;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
#ifndef CONVERT_H
|
#ifndef CONVERT_H
|
||||||
#define CONVERT_H
|
#define CONVERT_H
|
||||||
|
|
||||||
#include <SDL2/SDL_stdinc.h>
|
#include <stdbool.h>
|
||||||
#include <SDL2/SDL_events.h>
|
#include <SDL2/SDL_events.h>
|
||||||
|
|
||||||
#include "control_event.h"
|
#include "control_event.h"
|
||||||
|
|
||||||
struct complete_mouse_motion_event {
|
struct complete_mouse_motion_event {
|
||||||
|
@ -15,24 +16,24 @@ struct complete_mouse_wheel_event {
|
||||||
struct point position;
|
struct point position;
|
||||||
};
|
};
|
||||||
|
|
||||||
SDL_bool
|
bool
|
||||||
input_key_from_sdl_to_android(const SDL_KeyboardEvent *from,
|
input_key_from_sdl_to_android(const SDL_KeyboardEvent *from,
|
||||||
struct control_event *to);
|
struct control_event *to);
|
||||||
|
|
||||||
SDL_bool
|
bool
|
||||||
mouse_button_from_sdl_to_android(const SDL_MouseButtonEvent *from,
|
mouse_button_from_sdl_to_android(const SDL_MouseButtonEvent *from,
|
||||||
struct size screen_size,
|
struct size screen_size,
|
||||||
struct control_event *to);
|
struct control_event *to);
|
||||||
|
|
||||||
// the video size may be different from the real device size, so we need the
|
// the video size may be different from the real device size, so we need the
|
||||||
// size to which the absolute position apply, to scale it accordingly
|
// size to which the absolute position apply, to scale it accordingly
|
||||||
SDL_bool
|
bool
|
||||||
mouse_motion_from_sdl_to_android(const SDL_MouseMotionEvent *from,
|
mouse_motion_from_sdl_to_android(const SDL_MouseMotionEvent *from,
|
||||||
struct size screen_size,
|
struct size screen_size,
|
||||||
struct control_event *to);
|
struct control_event *to);
|
||||||
|
|
||||||
// on Android, a scroll event requires the current mouse position
|
// on Android, a scroll event requires the current mouse position
|
||||||
SDL_bool
|
bool
|
||||||
mouse_wheel_from_sdl_to_android(const SDL_MouseWheelEvent *from,
|
mouse_wheel_from_sdl_to_android(const SDL_MouseWheelEvent *from,
|
||||||
struct position position,
|
struct position position,
|
||||||
struct control_event *to);
|
struct control_event *to);
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
// set the decoded frame as ready for rendering, and notify
|
// set the decoded frame as ready for rendering, and notify
|
||||||
static void
|
static void
|
||||||
push_frame(struct decoder *decoder) {
|
push_frame(struct decoder *decoder) {
|
||||||
SDL_bool previous_frame_consumed =
|
bool previous_frame_consumed =
|
||||||
video_buffer_offer_decoded_frame(decoder->video_buffer);
|
video_buffer_offer_decoded_frame(decoder->video_buffer);
|
||||||
if (!previous_frame_consumed) {
|
if (!previous_frame_consumed) {
|
||||||
// the previous EVENT_NEW_FRAME will consume this frame
|
// the previous EVENT_NEW_FRAME will consume this frame
|
||||||
|
@ -37,21 +37,21 @@ decoder_init(struct decoder *decoder, struct video_buffer *vb) {
|
||||||
decoder->video_buffer = vb;
|
decoder->video_buffer = vb;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_bool
|
bool
|
||||||
decoder_open(struct decoder *decoder, AVCodec *codec) {
|
decoder_open(struct decoder *decoder, AVCodec *codec) {
|
||||||
decoder->codec_ctx = avcodec_alloc_context3(codec);
|
decoder->codec_ctx = avcodec_alloc_context3(codec);
|
||||||
if (!decoder->codec_ctx) {
|
if (!decoder->codec_ctx) {
|
||||||
LOGC("Could not allocate decoder context");
|
LOGC("Could not allocate decoder context");
|
||||||
return SDL_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (avcodec_open2(decoder->codec_ctx, codec, NULL) < 0) {
|
if (avcodec_open2(decoder->codec_ctx, codec, NULL) < 0) {
|
||||||
LOGE("Could not open codec");
|
LOGE("Could not open codec");
|
||||||
avcodec_free_context(&decoder->codec_ctx);
|
avcodec_free_context(&decoder->codec_ctx);
|
||||||
return SDL_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return SDL_TRUE;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -60,7 +60,7 @@ decoder_close(struct decoder *decoder) {
|
||||||
avcodec_free_context(&decoder->codec_ctx);
|
avcodec_free_context(&decoder->codec_ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_bool
|
bool
|
||||||
decoder_push(struct decoder *decoder, AVPacket *packet) {
|
decoder_push(struct decoder *decoder, AVPacket *packet) {
|
||||||
// the new decoding/encoding API has been introduced by:
|
// the new decoding/encoding API has been introduced by:
|
||||||
// <http://git.videolan.org/?p=ffmpeg.git;a=commitdiff;h=7fc329e2dd6226dfecaa4a1d7adf353bf2773726>
|
// <http://git.videolan.org/?p=ffmpeg.git;a=commitdiff;h=7fc329e2dd6226dfecaa4a1d7adf353bf2773726>
|
||||||
|
@ -68,7 +68,7 @@ decoder_push(struct decoder *decoder, AVPacket *packet) {
|
||||||
int ret;
|
int ret;
|
||||||
if ((ret = avcodec_send_packet(decoder->codec_ctx, packet)) < 0) {
|
if ((ret = avcodec_send_packet(decoder->codec_ctx, packet)) < 0) {
|
||||||
LOGE("Could not send video packet: %d", ret);
|
LOGE("Could not send video packet: %d", ret);
|
||||||
return SDL_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
ret = avcodec_receive_frame(decoder->codec_ctx,
|
ret = avcodec_receive_frame(decoder->codec_ctx,
|
||||||
decoder->video_buffer->decoding_frame);
|
decoder->video_buffer->decoding_frame);
|
||||||
|
@ -77,7 +77,7 @@ decoder_push(struct decoder *decoder, AVPacket *packet) {
|
||||||
push_frame(decoder);
|
push_frame(decoder);
|
||||||
} else if (ret != AVERROR(EAGAIN)) {
|
} else if (ret != AVERROR(EAGAIN)) {
|
||||||
LOGE("Could not receive video frame: %d", ret);
|
LOGE("Could not receive video frame: %d", ret);
|
||||||
return SDL_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
int got_picture;
|
int got_picture;
|
||||||
|
@ -87,13 +87,13 @@ decoder_push(struct decoder *decoder, AVPacket *packet) {
|
||||||
packet);
|
packet);
|
||||||
if (len < 0) {
|
if (len < 0) {
|
||||||
LOGE("Could not decode video packet: %d", len);
|
LOGE("Could not decode video packet: %d", len);
|
||||||
return SDL_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
if (got_picture) {
|
if (got_picture) {
|
||||||
push_frame(decoder);
|
push_frame(decoder);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return SDL_TRUE;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
#ifndef DECODER_H
|
#ifndef DECODER_H
|
||||||
#define DECODER_H
|
#define DECODER_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
#include <libavformat/avformat.h>
|
#include <libavformat/avformat.h>
|
||||||
#include <SDL2/SDL_stdinc.h>
|
|
||||||
|
|
||||||
struct video_buffer;
|
struct video_buffer;
|
||||||
|
|
||||||
|
@ -14,13 +14,13 @@ struct decoder {
|
||||||
void
|
void
|
||||||
decoder_init(struct decoder *decoder, struct video_buffer *vb);
|
decoder_init(struct decoder *decoder, struct video_buffer *vb);
|
||||||
|
|
||||||
SDL_bool
|
bool
|
||||||
decoder_open(struct decoder *decoder, AVCodec *codec);
|
decoder_open(struct decoder *decoder, AVCodec *codec);
|
||||||
|
|
||||||
void
|
void
|
||||||
decoder_close(struct decoder *decoder);
|
decoder_close(struct decoder *decoder);
|
||||||
|
|
||||||
SDL_bool
|
bool
|
||||||
decoder_push(struct decoder *decoder, AVPacket *packet);
|
decoder_push(struct decoder *decoder, AVPacket *packet);
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
#include "device.h"
|
#include "device.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
SDL_bool
|
bool
|
||||||
device_read_info(socket_t device_socket, char *device_name, struct size *size) {
|
device_read_info(socket_t device_socket, char *device_name, struct size *size) {
|
||||||
unsigned char buf[DEVICE_NAME_FIELD_LENGTH + 4];
|
unsigned char buf[DEVICE_NAME_FIELD_LENGTH + 4];
|
||||||
int r = net_recv_all(device_socket, buf, sizeof(buf));
|
int r = net_recv_all(device_socket, buf, sizeof(buf));
|
||||||
if (r < DEVICE_NAME_FIELD_LENGTH + 4) {
|
if (r < DEVICE_NAME_FIELD_LENGTH + 4) {
|
||||||
LOGE("Could not retrieve device information");
|
LOGE("Could not retrieve device information");
|
||||||
return SDL_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
// in case the client sends garbage
|
// in case the client sends garbage
|
||||||
buf[DEVICE_NAME_FIELD_LENGTH - 1] = '\0';
|
buf[DEVICE_NAME_FIELD_LENGTH - 1] = '\0';
|
||||||
|
@ -18,5 +18,5 @@ device_read_info(socket_t device_socket, char *device_name, struct size *size) {
|
||||||
| buf[DEVICE_NAME_FIELD_LENGTH + 1];
|
| buf[DEVICE_NAME_FIELD_LENGTH + 1];
|
||||||
size->height = (buf[DEVICE_NAME_FIELD_LENGTH + 2] << 8)
|
size->height = (buf[DEVICE_NAME_FIELD_LENGTH + 2] << 8)
|
||||||
| buf[DEVICE_NAME_FIELD_LENGTH + 3];
|
| buf[DEVICE_NAME_FIELD_LENGTH + 3];
|
||||||
return SDL_TRUE;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef DEVICE_H
|
#ifndef DEVICE_H
|
||||||
#define DEVICE_H
|
#define DEVICE_H
|
||||||
|
|
||||||
#include <SDL2/SDL_stdinc.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "net.h"
|
#include "net.h"
|
||||||
|
@ -10,7 +10,7 @@
|
||||||
#define DEVICE_SDCARD_PATH "/sdcard/"
|
#define DEVICE_SDCARD_PATH "/sdcard/"
|
||||||
|
|
||||||
// name must be at least DEVICE_NAME_FIELD_LENGTH bytes
|
// name must be at least DEVICE_NAME_FIELD_LENGTH bytes
|
||||||
SDL_bool
|
bool
|
||||||
device_read_info(socket_t device_socket, char *name, struct size *frame_size);
|
device_read_info(socket_t device_socket, char *name, struct size *frame_size);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -33,21 +33,21 @@ request_free(struct request *req) {
|
||||||
SDL_free((void *) req);
|
SDL_free((void *) req);
|
||||||
}
|
}
|
||||||
|
|
||||||
static SDL_bool
|
static bool
|
||||||
request_queue_is_empty(const struct request_queue *queue) {
|
request_queue_is_empty(const struct request_queue *queue) {
|
||||||
return queue->head == queue->tail;
|
return queue->head == queue->tail;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SDL_bool
|
static bool
|
||||||
request_queue_is_full(const struct request_queue *queue) {
|
request_queue_is_full(const struct request_queue *queue) {
|
||||||
return (queue->head + 1) % REQUEST_QUEUE_SIZE == queue->tail;
|
return (queue->head + 1) % REQUEST_QUEUE_SIZE == queue->tail;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SDL_bool
|
static bool
|
||||||
request_queue_init(struct request_queue *queue) {
|
request_queue_init(struct request_queue *queue) {
|
||||||
queue->head = 0;
|
queue->head = 0;
|
||||||
queue->tail = 0;
|
queue->tail = 0;
|
||||||
return SDL_TRUE;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -59,41 +59,41 @@ request_queue_destroy(struct request_queue *queue) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static SDL_bool
|
static bool
|
||||||
request_queue_push(struct request_queue *queue, struct request *req) {
|
request_queue_push(struct request_queue *queue, struct request *req) {
|
||||||
if (request_queue_is_full(queue)) {
|
if (request_queue_is_full(queue)) {
|
||||||
return SDL_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
queue->reqs[queue->head] = req;
|
queue->reqs[queue->head] = req;
|
||||||
queue->head = (queue->head + 1) % REQUEST_QUEUE_SIZE;
|
queue->head = (queue->head + 1) % REQUEST_QUEUE_SIZE;
|
||||||
return SDL_TRUE;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SDL_bool
|
static bool
|
||||||
request_queue_take(struct request_queue *queue, struct request **req) {
|
request_queue_take(struct request_queue *queue, struct request **req) {
|
||||||
if (request_queue_is_empty(queue)) {
|
if (request_queue_is_empty(queue)) {
|
||||||
return SDL_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
// transfer ownership
|
// transfer ownership
|
||||||
*req = queue->reqs[queue->tail];
|
*req = queue->reqs[queue->tail];
|
||||||
queue->tail = (queue->tail + 1) % REQUEST_QUEUE_SIZE;
|
queue->tail = (queue->tail + 1) % REQUEST_QUEUE_SIZE;
|
||||||
return SDL_TRUE;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_bool
|
bool
|
||||||
file_handler_init(struct file_handler *file_handler, const char *serial) {
|
file_handler_init(struct file_handler *file_handler, const char *serial) {
|
||||||
|
|
||||||
if (!request_queue_init(&file_handler->queue)) {
|
if (!request_queue_init(&file_handler->queue)) {
|
||||||
return SDL_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(file_handler->mutex = SDL_CreateMutex())) {
|
if (!(file_handler->mutex = SDL_CreateMutex())) {
|
||||||
return SDL_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(file_handler->event_cond = SDL_CreateCond())) {
|
if (!(file_handler->event_cond = SDL_CreateCond())) {
|
||||||
SDL_DestroyMutex(file_handler->mutex);
|
SDL_DestroyMutex(file_handler->mutex);
|
||||||
return SDL_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (serial) {
|
if (serial) {
|
||||||
|
@ -101,19 +101,19 @@ file_handler_init(struct file_handler *file_handler, const char *serial) {
|
||||||
if (!file_handler->serial) {
|
if (!file_handler->serial) {
|
||||||
LOGW("Cannot strdup serial");
|
LOGW("Cannot strdup serial");
|
||||||
SDL_DestroyMutex(file_handler->mutex);
|
SDL_DestroyMutex(file_handler->mutex);
|
||||||
return SDL_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
file_handler->serial = NULL;
|
file_handler->serial = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// lazy initialization
|
// lazy initialization
|
||||||
file_handler->initialized = SDL_FALSE;
|
file_handler->initialized = false;
|
||||||
|
|
||||||
file_handler->stopped = SDL_FALSE;
|
file_handler->stopped = false;
|
||||||
file_handler->current_process = PROCESS_NONE;
|
file_handler->current_process = PROCESS_NONE;
|
||||||
|
|
||||||
return SDL_TRUE;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -134,18 +134,18 @@ push_file(const char *serial, const char *file) {
|
||||||
return adb_push(serial, file, DEVICE_SDCARD_PATH);
|
return adb_push(serial, file, DEVICE_SDCARD_PATH);
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_bool
|
bool
|
||||||
file_handler_request(struct file_handler *file_handler,
|
file_handler_request(struct file_handler *file_handler,
|
||||||
file_handler_action_t action,
|
file_handler_action_t action,
|
||||||
const char *file) {
|
const char *file) {
|
||||||
SDL_bool res;
|
bool res;
|
||||||
|
|
||||||
// start file_handler if it's used for the first time
|
// start file_handler if it's used for the first time
|
||||||
if (!file_handler->initialized) {
|
if (!file_handler->initialized) {
|
||||||
if (!file_handler_start(file_handler)) {
|
if (!file_handler_start(file_handler)) {
|
||||||
return SDL_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
file_handler->initialized = SDL_TRUE;
|
file_handler->initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOGI("Request to %s %s", action == ACTION_INSTALL_APK ? "install" : "push",
|
LOGI("Request to %s %s", action == ACTION_INSTALL_APK ? "install" : "push",
|
||||||
|
@ -153,11 +153,11 @@ file_handler_request(struct file_handler *file_handler,
|
||||||
struct request *req = request_new(action, file);
|
struct request *req = request_new(action, file);
|
||||||
if (!req) {
|
if (!req) {
|
||||||
LOGE("Could not create request");
|
LOGE("Could not create request");
|
||||||
return SDL_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_lock(file_handler->mutex);
|
mutex_lock(file_handler->mutex);
|
||||||
SDL_bool was_empty = request_queue_is_empty(&file_handler->queue);
|
bool was_empty = request_queue_is_empty(&file_handler->queue);
|
||||||
res = request_queue_push(&file_handler->queue, req);
|
res = request_queue_push(&file_handler->queue, req);
|
||||||
if (was_empty) {
|
if (was_empty) {
|
||||||
cond_signal(file_handler->event_cond);
|
cond_signal(file_handler->event_cond);
|
||||||
|
@ -183,7 +183,7 @@ run_file_handler(void *data) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
struct request *req;
|
struct request *req;
|
||||||
SDL_bool non_empty = request_queue_take(&file_handler->queue, &req);
|
bool non_empty = request_queue_take(&file_handler->queue, &req);
|
||||||
SDL_assert(non_empty);
|
SDL_assert(non_empty);
|
||||||
|
|
||||||
process_t process;
|
process_t process;
|
||||||
|
@ -216,7 +216,7 @@ run_file_handler(void *data) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_bool
|
bool
|
||||||
file_handler_start(struct file_handler *file_handler) {
|
file_handler_start(struct file_handler *file_handler) {
|
||||||
LOGD("Starting file_handler thread");
|
LOGD("Starting file_handler thread");
|
||||||
|
|
||||||
|
@ -224,16 +224,16 @@ file_handler_start(struct file_handler *file_handler) {
|
||||||
file_handler);
|
file_handler);
|
||||||
if (!file_handler->thread) {
|
if (!file_handler->thread) {
|
||||||
LOGC("Could not start file_handler thread");
|
LOGC("Could not start file_handler thread");
|
||||||
return SDL_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return SDL_TRUE;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
file_handler_stop(struct file_handler *file_handler) {
|
file_handler_stop(struct file_handler *file_handler) {
|
||||||
mutex_lock(file_handler->mutex);
|
mutex_lock(file_handler->mutex);
|
||||||
file_handler->stopped = SDL_TRUE;
|
file_handler->stopped = true;
|
||||||
cond_signal(file_handler->event_cond);
|
cond_signal(file_handler->event_cond);
|
||||||
if (file_handler->current_process != PROCESS_NONE) {
|
if (file_handler->current_process != PROCESS_NONE) {
|
||||||
if (!cmd_terminate(file_handler->current_process)) {
|
if (!cmd_terminate(file_handler->current_process)) {
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
#ifndef FILE_HANDLER_H
|
#ifndef FILE_HANDLER_H
|
||||||
#define FILE_HANDLER_H
|
#define FILE_HANDLER_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
#include <SDL2/SDL_mutex.h>
|
#include <SDL2/SDL_mutex.h>
|
||||||
#include <SDL2/SDL_stdinc.h>
|
|
||||||
#include <SDL2/SDL_thread.h>
|
#include <SDL2/SDL_thread.h>
|
||||||
|
|
||||||
#include "command.h"
|
#include "command.h"
|
||||||
|
|
||||||
#define REQUEST_QUEUE_SIZE 16
|
#define REQUEST_QUEUE_SIZE 16
|
||||||
|
@ -24,19 +25,19 @@ struct file_handler {
|
||||||
SDL_Thread *thread;
|
SDL_Thread *thread;
|
||||||
SDL_mutex *mutex;
|
SDL_mutex *mutex;
|
||||||
SDL_cond *event_cond;
|
SDL_cond *event_cond;
|
||||||
SDL_bool stopped;
|
bool stopped;
|
||||||
SDL_bool initialized;
|
bool initialized;
|
||||||
process_t current_process;
|
process_t current_process;
|
||||||
struct request_queue queue;
|
struct request_queue queue;
|
||||||
};
|
};
|
||||||
|
|
||||||
SDL_bool
|
bool
|
||||||
file_handler_init(struct file_handler *file_handler, const char *serial);
|
file_handler_init(struct file_handler *file_handler, const char *serial);
|
||||||
|
|
||||||
void
|
void
|
||||||
file_handler_destroy(struct file_handler *file_handler);
|
file_handler_destroy(struct file_handler *file_handler);
|
||||||
|
|
||||||
SDL_bool
|
bool
|
||||||
file_handler_start(struct file_handler *file_handler);
|
file_handler_start(struct file_handler *file_handler);
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -45,7 +46,7 @@ file_handler_stop(struct file_handler *file_handler);
|
||||||
void
|
void
|
||||||
file_handler_join(struct file_handler *file_handler);
|
file_handler_join(struct file_handler *file_handler);
|
||||||
|
|
||||||
SDL_bool
|
bool
|
||||||
file_handler_request(struct file_handler *file_handler,
|
file_handler_request(struct file_handler *file_handler,
|
||||||
file_handler_action_t action,
|
file_handler_action_t action,
|
||||||
const char *file);
|
const char *file);
|
||||||
|
|
|
@ -6,14 +6,14 @@
|
||||||
|
|
||||||
void
|
void
|
||||||
fps_counter_init(struct fps_counter *counter) {
|
fps_counter_init(struct fps_counter *counter) {
|
||||||
counter->started = SDL_FALSE;
|
counter->started = false;
|
||||||
// no need to initialize the other fields, they are meaningful only when
|
// no need to initialize the other fields, they are meaningful only when
|
||||||
// started is true
|
// started is true
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
fps_counter_start(struct fps_counter *counter) {
|
fps_counter_start(struct fps_counter *counter) {
|
||||||
counter->started = SDL_TRUE;
|
counter->started = true;
|
||||||
counter->slice_start = SDL_GetTicks();
|
counter->slice_start = SDL_GetTicks();
|
||||||
counter->nr_rendered = 0;
|
counter->nr_rendered = 0;
|
||||||
#ifdef SKIP_FRAMES
|
#ifdef SKIP_FRAMES
|
||||||
|
@ -23,7 +23,7 @@ fps_counter_start(struct fps_counter *counter) {
|
||||||
|
|
||||||
void
|
void
|
||||||
fps_counter_stop(struct fps_counter *counter) {
|
fps_counter_stop(struct fps_counter *counter) {
|
||||||
counter->started = SDL_FALSE;
|
counter->started = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -42,11 +42,11 @@ display_fps(struct fps_counter *counter) {
|
||||||
|
|
||||||
static void
|
static void
|
||||||
check_expired(struct fps_counter *counter) {
|
check_expired(struct fps_counter *counter) {
|
||||||
Uint32 now = SDL_GetTicks();
|
uint32_t now = SDL_GetTicks();
|
||||||
if (now - counter->slice_start >= 1000) {
|
if (now - counter->slice_start >= 1000) {
|
||||||
display_fps(counter);
|
display_fps(counter);
|
||||||
// add a multiple of one second
|
// add a multiple of one second
|
||||||
Uint32 elapsed_slices = (now - counter->slice_start) / 1000;
|
uint32_t elapsed_slices = (now - counter->slice_start) / 1000;
|
||||||
counter->slice_start += 1000 * elapsed_slices;
|
counter->slice_start += 1000 * elapsed_slices;
|
||||||
counter->nr_rendered = 0;
|
counter->nr_rendered = 0;
|
||||||
#ifdef SKIP_FRAMES
|
#ifdef SKIP_FRAMES
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
#ifndef FPSCOUNTER_H
|
#ifndef FPSCOUNTER_H
|
||||||
#define FPSCOUNTER_H
|
#define FPSCOUNTER_H
|
||||||
|
|
||||||
#include <SDL2/SDL_stdinc.h>
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
struct fps_counter {
|
struct fps_counter {
|
||||||
SDL_bool started;
|
bool started;
|
||||||
Uint32 slice_start; // initialized by SDL_GetTicks()
|
uint32_t slice_start; // initialized by SDL_GetTicks()
|
||||||
int nr_rendered;
|
int nr_rendered;
|
||||||
#ifdef SKIP_FRAMES
|
#ifdef SKIP_FRAMES
|
||||||
int nr_skipped;
|
int nr_skipped;
|
||||||
|
|
|
@ -192,9 +192,9 @@ input_manager_process_text_input(struct input_manager *input_manager,
|
||||||
void
|
void
|
||||||
input_manager_process_key(struct input_manager *input_manager,
|
input_manager_process_key(struct input_manager *input_manager,
|
||||||
const SDL_KeyboardEvent *event) {
|
const SDL_KeyboardEvent *event) {
|
||||||
SDL_bool ctrl = event->keysym.mod & (KMOD_LCTRL | KMOD_RCTRL);
|
bool ctrl = event->keysym.mod & (KMOD_LCTRL | KMOD_RCTRL);
|
||||||
SDL_bool alt = event->keysym.mod & (KMOD_LALT | KMOD_RALT);
|
bool alt = event->keysym.mod & (KMOD_LALT | KMOD_RALT);
|
||||||
SDL_bool meta = event->keysym.mod & (KMOD_LGUI | KMOD_RGUI);
|
bool meta = event->keysym.mod & (KMOD_LGUI | KMOD_RGUI);
|
||||||
|
|
||||||
if (alt) {
|
if (alt) {
|
||||||
// no shortcut involves Alt or Meta, and they should not be forwarded
|
// no shortcut involves Alt or Meta, and they should not be forwarded
|
||||||
|
@ -203,14 +203,14 @@ input_manager_process_key(struct input_manager *input_manager,
|
||||||
}
|
}
|
||||||
|
|
||||||
// false if the user requested not to interact with the device
|
// false if the user requested not to interact with the device
|
||||||
SDL_bool control = input_manager->control;
|
bool control = input_manager->control;
|
||||||
|
|
||||||
// capture all Ctrl events
|
// capture all Ctrl events
|
||||||
if (ctrl | meta) {
|
if (ctrl | meta) {
|
||||||
SDL_Keycode keycode = event->keysym.sym;
|
SDL_Keycode keycode = event->keysym.sym;
|
||||||
int action = event->type == SDL_KEYDOWN ? ACTION_DOWN : ACTION_UP;
|
int action = event->type == SDL_KEYDOWN ? ACTION_DOWN : ACTION_UP;
|
||||||
SDL_bool repeat = event->repeat;
|
bool repeat = event->repeat;
|
||||||
SDL_bool shift = event->keysym.mod & (KMOD_LSHIFT | KMOD_RSHIFT);
|
bool shift = event->keysym.mod & (KMOD_LSHIFT | KMOD_RSHIFT);
|
||||||
switch (keycode) {
|
switch (keycode) {
|
||||||
case SDLK_h:
|
case SDLK_h:
|
||||||
if (control && ctrl && !meta && !shift && !repeat) {
|
if (control && ctrl && !meta && !shift && !repeat) {
|
||||||
|
@ -332,7 +332,7 @@ input_manager_process_mouse_motion(struct input_manager *input_manager,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static SDL_bool
|
static bool
|
||||||
is_outside_device_screen(struct input_manager *input_manager, int x, int y)
|
is_outside_device_screen(struct input_manager *input_manager, int x, int y)
|
||||||
{
|
{
|
||||||
return x < 0 || x >= input_manager->screen->frame_size.width ||
|
return x < 0 || x >= input_manager->screen->frame_size.width ||
|
||||||
|
@ -343,7 +343,7 @@ void
|
||||||
input_manager_process_mouse_button(struct input_manager *input_manager,
|
input_manager_process_mouse_button(struct input_manager *input_manager,
|
||||||
const SDL_MouseButtonEvent *event) {
|
const SDL_MouseButtonEvent *event) {
|
||||||
// false if the user requested not to interact with the device
|
// false if the user requested not to interact with the device
|
||||||
SDL_bool control = input_manager->control;
|
bool control = input_manager->control;
|
||||||
|
|
||||||
if (event->type == SDL_MOUSEBUTTONDOWN) {
|
if (event->type == SDL_MOUSEBUTTONDOWN) {
|
||||||
if (control && event->button == SDL_BUTTON_RIGHT) {
|
if (control && event->button == SDL_BUTTON_RIGHT) {
|
||||||
|
@ -356,7 +356,7 @@ input_manager_process_mouse_button(struct input_manager *input_manager,
|
||||||
}
|
}
|
||||||
// double-click on black borders resize to fit the device screen
|
// double-click on black borders resize to fit the device screen
|
||||||
if (event->button == SDL_BUTTON_LEFT && event->clicks == 2) {
|
if (event->button == SDL_BUTTON_LEFT && event->clicks == 2) {
|
||||||
SDL_bool outside = is_outside_device_screen(input_manager,
|
bool outside = is_outside_device_screen(input_manager,
|
||||||
event->x,
|
event->x,
|
||||||
event->y);
|
event->y);
|
||||||
if (outside) {
|
if (outside) {
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#ifndef INPUTMANAGER_H
|
#ifndef INPUTMANAGER_H
|
||||||
#define INPUTMANAGER_H
|
#define INPUTMANAGER_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "controller.h"
|
#include "controller.h"
|
||||||
#include "fps_counter.h"
|
#include "fps_counter.h"
|
||||||
|
@ -11,7 +13,7 @@ struct input_manager {
|
||||||
struct controller *controller;
|
struct controller *controller;
|
||||||
struct video_buffer *video_buffer;
|
struct video_buffer *video_buffer;
|
||||||
struct screen *screen;
|
struct screen *screen;
|
||||||
SDL_bool control;
|
bool control;
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
126
app/src/main.c
126
app/src/main.c
|
@ -1,6 +1,8 @@
|
||||||
#include "scrcpy.h"
|
#include "scrcpy.h"
|
||||||
|
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <libavformat/avformat.h>
|
#include <libavformat/avformat.h>
|
||||||
#include <SDL2/SDL.h>
|
#include <SDL2/SDL.h>
|
||||||
|
@ -15,16 +17,16 @@ struct args {
|
||||||
const char *crop;
|
const char *crop;
|
||||||
const char *record_filename;
|
const char *record_filename;
|
||||||
enum recorder_format record_format;
|
enum recorder_format record_format;
|
||||||
SDL_bool fullscreen;
|
bool fullscreen;
|
||||||
SDL_bool no_control;
|
bool no_control;
|
||||||
SDL_bool no_display;
|
bool no_display;
|
||||||
SDL_bool help;
|
bool help;
|
||||||
SDL_bool version;
|
bool version;
|
||||||
SDL_bool show_touches;
|
bool show_touches;
|
||||||
Uint16 port;
|
uint16_t port;
|
||||||
Uint16 max_size;
|
uint16_t max_size;
|
||||||
Uint32 bit_rate;
|
uint32_t bit_rate;
|
||||||
SDL_bool always_on_top;
|
bool always_on_top;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void usage(const char *arg0) {
|
static void usage(const char *arg0) {
|
||||||
|
@ -168,19 +170,19 @@ print_version(void) {
|
||||||
LIBAVUTIL_VERSION_MICRO);
|
LIBAVUTIL_VERSION_MICRO);
|
||||||
}
|
}
|
||||||
|
|
||||||
static SDL_bool
|
static bool
|
||||||
parse_bit_rate(char *optarg, Uint32 *bit_rate) {
|
parse_bit_rate(char *optarg, uint32_t *bit_rate) {
|
||||||
char *endptr;
|
char *endptr;
|
||||||
if (*optarg == '\0') {
|
if (*optarg == '\0') {
|
||||||
LOGE("Bit-rate parameter is empty");
|
LOGE("Bit-rate parameter is empty");
|
||||||
return SDL_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
long value = strtol(optarg, &endptr, 0);
|
long value = strtol(optarg, &endptr, 0);
|
||||||
int mul = 1;
|
int mul = 1;
|
||||||
if (*endptr != '\0') {
|
if (*endptr != '\0') {
|
||||||
if (optarg == endptr) {
|
if (optarg == endptr) {
|
||||||
LOGE("Invalid bit-rate: %s", optarg);
|
LOGE("Invalid bit-rate: %s", optarg);
|
||||||
return SDL_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
if ((*endptr == 'M' || *endptr == 'm') && endptr[1] == '\0') {
|
if ((*endptr == 'M' || *endptr == 'm') && endptr[1] == '\0') {
|
||||||
mul = 1000000;
|
mul = 1000000;
|
||||||
|
@ -188,72 +190,72 @@ parse_bit_rate(char *optarg, Uint32 *bit_rate) {
|
||||||
mul = 1000;
|
mul = 1000;
|
||||||
} else {
|
} else {
|
||||||
LOGE("Invalid bit-rate unit: %s", optarg);
|
LOGE("Invalid bit-rate unit: %s", optarg);
|
||||||
return SDL_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (value < 0 || ((Uint32) -1) / mul < value) {
|
if (value < 0 || ((uint32_t) -1) / mul < value) {
|
||||||
LOGE("Bitrate must be positive and less than 2^32: %s", optarg);
|
LOGE("Bitrate must be positive and less than 2^32: %s", optarg);
|
||||||
return SDL_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
*bit_rate = (Uint32) value * mul;
|
*bit_rate = (uint32_t) value * mul;
|
||||||
return SDL_TRUE;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SDL_bool
|
static bool
|
||||||
parse_max_size(char *optarg, Uint16 *max_size) {
|
parse_max_size(char *optarg, uint16_t *max_size) {
|
||||||
char *endptr;
|
char *endptr;
|
||||||
if (*optarg == '\0') {
|
if (*optarg == '\0') {
|
||||||
LOGE("Max size parameter is empty");
|
LOGE("Max size parameter is empty");
|
||||||
return SDL_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
long value = strtol(optarg, &endptr, 0);
|
long value = strtol(optarg, &endptr, 0);
|
||||||
if (*endptr != '\0') {
|
if (*endptr != '\0') {
|
||||||
LOGE("Invalid max size: %s", optarg);
|
LOGE("Invalid max size: %s", optarg);
|
||||||
return SDL_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
if (value & ~0xffff) {
|
if (value & ~0xffff) {
|
||||||
LOGE("Max size must be between 0 and 65535: %ld", value);
|
LOGE("Max size must be between 0 and 65535: %ld", value);
|
||||||
return SDL_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
*max_size = (Uint16) value;
|
*max_size = (uint16_t) value;
|
||||||
return SDL_TRUE;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SDL_bool
|
static bool
|
||||||
parse_port(char *optarg, Uint16 *port) {
|
parse_port(char *optarg, uint16_t *port) {
|
||||||
char *endptr;
|
char *endptr;
|
||||||
if (*optarg == '\0') {
|
if (*optarg == '\0') {
|
||||||
LOGE("Invalid port parameter is empty");
|
LOGE("Invalid port parameter is empty");
|
||||||
return SDL_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
long value = strtol(optarg, &endptr, 0);
|
long value = strtol(optarg, &endptr, 0);
|
||||||
if (*endptr != '\0') {
|
if (*endptr != '\0') {
|
||||||
LOGE("Invalid port: %s", optarg);
|
LOGE("Invalid port: %s", optarg);
|
||||||
return SDL_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
if (value & ~0xffff) {
|
if (value & ~0xffff) {
|
||||||
LOGE("Port out of range: %ld", value);
|
LOGE("Port out of range: %ld", value);
|
||||||
return SDL_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
*port = (Uint16) value;
|
*port = (uint16_t) value;
|
||||||
return SDL_TRUE;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SDL_bool
|
static bool
|
||||||
parse_record_format(const char *optarg, enum recorder_format *format) {
|
parse_record_format(const char *optarg, enum recorder_format *format) {
|
||||||
if (!strcmp(optarg, "mp4")) {
|
if (!strcmp(optarg, "mp4")) {
|
||||||
*format = RECORDER_FORMAT_MP4;
|
*format = RECORDER_FORMAT_MP4;
|
||||||
return SDL_TRUE;
|
return true;
|
||||||
}
|
}
|
||||||
if (!strcmp(optarg, "mkv")) {
|
if (!strcmp(optarg, "mkv")) {
|
||||||
*format = RECORDER_FORMAT_MKV;
|
*format = RECORDER_FORMAT_MKV;
|
||||||
return SDL_TRUE;
|
return true;
|
||||||
}
|
}
|
||||||
LOGE("Unsupported format: %s (expected mp4 or mkv)", optarg);
|
LOGE("Unsupported format: %s (expected mp4 or mkv)", optarg);
|
||||||
return SDL_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum recorder_format
|
static enum recorder_format
|
||||||
|
@ -272,7 +274,7 @@ guess_record_format(const char *filename) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SDL_bool
|
static bool
|
||||||
parse_args(struct args *args, int argc, char *argv[]) {
|
parse_args(struct args *args, int argc, char *argv[]) {
|
||||||
static const struct option long_options[] = {
|
static const struct option long_options[] = {
|
||||||
{"always-on-top", no_argument, NULL, 'T'},
|
{"always-on-top", no_argument, NULL, 'T'},
|
||||||
|
@ -297,37 +299,37 @@ parse_args(struct args *args, int argc, char *argv[]) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'b':
|
case 'b':
|
||||||
if (!parse_bit_rate(optarg, &args->bit_rate)) {
|
if (!parse_bit_rate(optarg, &args->bit_rate)) {
|
||||||
return SDL_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'c':
|
case 'c':
|
||||||
args->crop = optarg;
|
args->crop = optarg;
|
||||||
break;
|
break;
|
||||||
case 'f':
|
case 'f':
|
||||||
args->fullscreen = SDL_TRUE;
|
args->fullscreen = true;
|
||||||
break;
|
break;
|
||||||
case 'F':
|
case 'F':
|
||||||
if (!parse_record_format(optarg, &args->record_format)) {
|
if (!parse_record_format(optarg, &args->record_format)) {
|
||||||
return SDL_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'h':
|
case 'h':
|
||||||
args->help = SDL_TRUE;
|
args->help = true;
|
||||||
break;
|
break;
|
||||||
case 'm':
|
case 'm':
|
||||||
if (!parse_max_size(optarg, &args->max_size)) {
|
if (!parse_max_size(optarg, &args->max_size)) {
|
||||||
return SDL_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'n':
|
case 'n':
|
||||||
args->no_control = SDL_TRUE;
|
args->no_control = true;
|
||||||
break;
|
break;
|
||||||
case 'N':
|
case 'N':
|
||||||
args->no_display = SDL_TRUE;
|
args->no_display = true;
|
||||||
break;
|
break;
|
||||||
case 'p':
|
case 'p':
|
||||||
if (!parse_port(optarg, &args->port)) {
|
if (!parse_port(optarg, &args->port)) {
|
||||||
return SDL_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'r':
|
case 'r':
|
||||||
|
@ -337,39 +339,39 @@ parse_args(struct args *args, int argc, char *argv[]) {
|
||||||
args->serial = optarg;
|
args->serial = optarg;
|
||||||
break;
|
break;
|
||||||
case 't':
|
case 't':
|
||||||
args->show_touches = SDL_TRUE;
|
args->show_touches = true;
|
||||||
break;
|
break;
|
||||||
case 'T':
|
case 'T':
|
||||||
args->always_on_top = SDL_TRUE;
|
args->always_on_top = true;
|
||||||
break;
|
break;
|
||||||
case 'v':
|
case 'v':
|
||||||
args->version = SDL_TRUE;
|
args->version = true;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// getopt prints the error message on stderr
|
// getopt prints the error message on stderr
|
||||||
return SDL_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (args->no_display && !args->record_filename) {
|
if (args->no_display && !args->record_filename) {
|
||||||
LOGE("-N/--no-display requires screen recording (-r/--record)");
|
LOGE("-N/--no-display requires screen recording (-r/--record)");
|
||||||
return SDL_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (args->no_display && args->fullscreen) {
|
if (args->no_display && args->fullscreen) {
|
||||||
LOGE("-f/--fullscreen-window is incompatible with -N/--no-display");
|
LOGE("-f/--fullscreen-window is incompatible with -N/--no-display");
|
||||||
return SDL_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int index = optind;
|
int index = optind;
|
||||||
if (index < argc) {
|
if (index < argc) {
|
||||||
LOGE("Unexpected additional argument: %s", argv[index]);
|
LOGE("Unexpected additional argument: %s", argv[index]);
|
||||||
return SDL_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (args->record_format && !args->record_filename) {
|
if (args->record_format && !args->record_filename) {
|
||||||
LOGE("Record format specified without recording");
|
LOGE("Record format specified without recording");
|
||||||
return SDL_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (args->record_filename && !args->record_format) {
|
if (args->record_filename && !args->record_format) {
|
||||||
|
@ -377,11 +379,11 @@ parse_args(struct args *args, int argc, char *argv[]) {
|
||||||
if (!args->record_format) {
|
if (!args->record_format) {
|
||||||
LOGE("No format specified for \"%s\" (try with -F mkv)",
|
LOGE("No format specified for \"%s\" (try with -F mkv)",
|
||||||
args->record_filename);
|
args->record_filename);
|
||||||
return SDL_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return SDL_TRUE;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -397,15 +399,15 @@ main(int argc, char *argv[]) {
|
||||||
.crop = NULL,
|
.crop = NULL,
|
||||||
.record_filename = NULL,
|
.record_filename = NULL,
|
||||||
.record_format = 0,
|
.record_format = 0,
|
||||||
.help = SDL_FALSE,
|
.help = false,
|
||||||
.version = SDL_FALSE,
|
.version = false,
|
||||||
.show_touches = SDL_FALSE,
|
.show_touches = false,
|
||||||
.port = DEFAULT_LOCAL_PORT,
|
.port = DEFAULT_LOCAL_PORT,
|
||||||
.max_size = DEFAULT_MAX_SIZE,
|
.max_size = DEFAULT_MAX_SIZE,
|
||||||
.bit_rate = DEFAULT_BIT_RATE,
|
.bit_rate = DEFAULT_BIT_RATE,
|
||||||
.always_on_top = SDL_FALSE,
|
.always_on_top = false,
|
||||||
.no_control = SDL_FALSE,
|
.no_control = false,
|
||||||
.no_display = SDL_FALSE,
|
.no_display = false,
|
||||||
};
|
};
|
||||||
if (!parse_args(&args, argc, argv)) {
|
if (!parse_args(&args, argc, argv)) {
|
||||||
return 1;
|
return 1;
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
socket_t
|
socket_t
|
||||||
net_connect(Uint32 addr, Uint16 port) {
|
net_connect(uint32_t addr, uint16_t port) {
|
||||||
socket_t sock = socket(AF_INET, SOCK_STREAM, 0);
|
socket_t sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
if (sock == INVALID_SOCKET) {
|
if (sock == INVALID_SOCKET) {
|
||||||
perror("socket");
|
perror("socket");
|
||||||
|
@ -40,7 +40,7 @@ net_connect(Uint32 addr, Uint16 port) {
|
||||||
}
|
}
|
||||||
|
|
||||||
socket_t
|
socket_t
|
||||||
net_listen(Uint32 addr, Uint16 port, int backlog) {
|
net_listen(uint32_t addr, uint16_t port, int backlog) {
|
||||||
socket_t sock = socket(AF_INET, SOCK_STREAM, 0);
|
socket_t sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
if (sock == INVALID_SOCKET) {
|
if (sock == INVALID_SOCKET) {
|
||||||
perror("socket");
|
perror("socket");
|
||||||
|
@ -107,7 +107,7 @@ net_send_all(socket_t socket, const void *buf, size_t len) {
|
||||||
return w;
|
return w;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_bool
|
bool
|
||||||
net_shutdown(socket_t socket, int how) {
|
net_shutdown(socket_t socket, int how) {
|
||||||
return !shutdown(socket, how);
|
return !shutdown(socket, how);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
#ifndef NET_H
|
#ifndef NET_H
|
||||||
#define NET_H
|
#define NET_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
#include <SDL2/SDL_platform.h>
|
#include <SDL2/SDL_platform.h>
|
||||||
#include <SDL2/SDL_stdinc.h>
|
|
||||||
|
|
||||||
#ifdef __WINDOWS__
|
#ifdef __WINDOWS__
|
||||||
# include <winsock2.h>
|
# include <winsock2.h>
|
||||||
|
@ -16,17 +17,17 @@
|
||||||
typedef int socket_t;
|
typedef int socket_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
SDL_bool
|
bool
|
||||||
net_init(void);
|
net_init(void);
|
||||||
|
|
||||||
void
|
void
|
||||||
net_cleanup(void);
|
net_cleanup(void);
|
||||||
|
|
||||||
socket_t
|
socket_t
|
||||||
net_connect(Uint32 addr, Uint16 port);
|
net_connect(uint32_t addr, uint16_t port);
|
||||||
|
|
||||||
socket_t
|
socket_t
|
||||||
net_listen(Uint32 addr, Uint16 port, int backlog);
|
net_listen(uint32_t addr, uint16_t port, int backlog);
|
||||||
|
|
||||||
socket_t
|
socket_t
|
||||||
net_accept(socket_t server_socket);
|
net_accept(socket_t server_socket);
|
||||||
|
@ -45,10 +46,10 @@ ssize_t
|
||||||
net_send_all(socket_t socket, const void *buf, size_t len);
|
net_send_all(socket_t socket, const void *buf, size_t len);
|
||||||
|
|
||||||
// how is SHUT_RD (read), SHUT_WR (write) or SHUT_RDWR (both)
|
// how is SHUT_RD (read), SHUT_WR (write) or SHUT_RDWR (both)
|
||||||
SDL_bool
|
bool
|
||||||
net_shutdown(socket_t socket, int how);
|
net_shutdown(socket_t socket, int how);
|
||||||
|
|
||||||
SDL_bool
|
bool
|
||||||
net_close(socket_t socket);
|
net_close(socket_t socket);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -26,7 +26,7 @@ find_muxer(const char *name) {
|
||||||
return oformat;
|
return oformat;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_bool
|
bool
|
||||||
recorder_init(struct recorder *recorder,
|
recorder_init(struct recorder *recorder,
|
||||||
const char *filename,
|
const char *filename,
|
||||||
enum recorder_format format,
|
enum recorder_format format,
|
||||||
|
@ -34,14 +34,14 @@ recorder_init(struct recorder *recorder,
|
||||||
recorder->filename = SDL_strdup(filename);
|
recorder->filename = SDL_strdup(filename);
|
||||||
if (!recorder->filename) {
|
if (!recorder->filename) {
|
||||||
LOGE("Cannot strdup filename");
|
LOGE("Cannot strdup filename");
|
||||||
return SDL_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
recorder->format = format;
|
recorder->format = format;
|
||||||
recorder->declared_frame_size = declared_frame_size;
|
recorder->declared_frame_size = declared_frame_size;
|
||||||
recorder->header_written = SDL_FALSE;
|
recorder->header_written = false;
|
||||||
|
|
||||||
return SDL_TRUE;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -58,20 +58,20 @@ recorder_get_format_name(enum recorder_format format) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_bool
|
bool
|
||||||
recorder_open(struct recorder *recorder, AVCodec *input_codec) {
|
recorder_open(struct recorder *recorder, AVCodec *input_codec) {
|
||||||
const char *format_name = recorder_get_format_name(recorder->format);
|
const char *format_name = recorder_get_format_name(recorder->format);
|
||||||
SDL_assert(format_name);
|
SDL_assert(format_name);
|
||||||
const AVOutputFormat *format = find_muxer(format_name);
|
const AVOutputFormat *format = find_muxer(format_name);
|
||||||
if (!format) {
|
if (!format) {
|
||||||
LOGE("Could not find muxer");
|
LOGE("Could not find muxer");
|
||||||
return SDL_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
recorder->ctx = avformat_alloc_context();
|
recorder->ctx = avformat_alloc_context();
|
||||||
if (!recorder->ctx) {
|
if (!recorder->ctx) {
|
||||||
LOGE("Could not allocate output context");
|
LOGE("Could not allocate output context");
|
||||||
return SDL_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// contrary to the deprecated API (av_oformat_next()), av_muxer_iterate()
|
// contrary to the deprecated API (av_oformat_next()), av_muxer_iterate()
|
||||||
|
@ -83,7 +83,7 @@ recorder_open(struct recorder *recorder, AVCodec *input_codec) {
|
||||||
AVStream *ostream = avformat_new_stream(recorder->ctx, input_codec);
|
AVStream *ostream = avformat_new_stream(recorder->ctx, input_codec);
|
||||||
if (!ostream) {
|
if (!ostream) {
|
||||||
avformat_free_context(recorder->ctx);
|
avformat_free_context(recorder->ctx);
|
||||||
return SDL_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef SCRCPY_LAVF_HAS_NEW_CODEC_PARAMS_API
|
#ifdef SCRCPY_LAVF_HAS_NEW_CODEC_PARAMS_API
|
||||||
|
@ -106,12 +106,12 @@ recorder_open(struct recorder *recorder, AVCodec *input_codec) {
|
||||||
LOGE("Failed to open output file: %s", recorder->filename);
|
LOGE("Failed to open output file: %s", recorder->filename);
|
||||||
// ostream will be cleaned up during context cleaning
|
// ostream will be cleaned up during context cleaning
|
||||||
avformat_free_context(recorder->ctx);
|
avformat_free_context(recorder->ctx);
|
||||||
return SDL_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOGI("Recording started to %s file: %s", format_name, recorder->filename);
|
LOGI("Recording started to %s file: %s", format_name, recorder->filename);
|
||||||
|
|
||||||
return SDL_TRUE;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -127,14 +127,14 @@ recorder_close(struct recorder *recorder) {
|
||||||
LOGI("Recording complete to %s file: %s", format_name, recorder->filename);
|
LOGI("Recording complete to %s file: %s", format_name, recorder->filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
static SDL_bool
|
static bool
|
||||||
recorder_write_header(struct recorder *recorder, AVPacket *packet) {
|
recorder_write_header(struct recorder *recorder, AVPacket *packet) {
|
||||||
AVStream *ostream = recorder->ctx->streams[0];
|
AVStream *ostream = recorder->ctx->streams[0];
|
||||||
|
|
||||||
uint8_t *extradata = av_malloc(packet->size * sizeof(uint8_t));
|
uint8_t *extradata = av_malloc(packet->size * sizeof(uint8_t));
|
||||||
if (!extradata) {
|
if (!extradata) {
|
||||||
LOGC("Cannot allocate extradata");
|
LOGC("Cannot allocate extradata");
|
||||||
return SDL_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// copy the first packet to the extra data
|
// copy the first packet to the extra data
|
||||||
|
@ -154,10 +154,10 @@ recorder_write_header(struct recorder *recorder, AVPacket *packet) {
|
||||||
SDL_free(extradata);
|
SDL_free(extradata);
|
||||||
avio_closep(&recorder->ctx->pb);
|
avio_closep(&recorder->ctx->pb);
|
||||||
avformat_free_context(recorder->ctx);
|
avformat_free_context(recorder->ctx);
|
||||||
return SDL_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return SDL_TRUE;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -166,14 +166,14 @@ recorder_rescale_packet(struct recorder *recorder, AVPacket *packet) {
|
||||||
av_packet_rescale_ts(packet, SCRCPY_TIME_BASE, ostream->time_base);
|
av_packet_rescale_ts(packet, SCRCPY_TIME_BASE, ostream->time_base);
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_bool
|
bool
|
||||||
recorder_write(struct recorder *recorder, AVPacket *packet) {
|
recorder_write(struct recorder *recorder, AVPacket *packet) {
|
||||||
if (!recorder->header_written) {
|
if (!recorder->header_written) {
|
||||||
SDL_bool ok = recorder_write_header(recorder, packet);
|
bool ok = recorder_write_header(recorder, packet);
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
return SDL_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
recorder->header_written = SDL_TRUE;
|
recorder->header_written = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
recorder_rescale_packet(recorder, packet);
|
recorder_rescale_packet(recorder, packet);
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
#ifndef RECORDER_H
|
#ifndef RECORDER_H
|
||||||
#define RECORDER_H
|
#define RECORDER_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
#include <libavformat/avformat.h>
|
#include <libavformat/avformat.h>
|
||||||
#include <SDL2/SDL_stdinc.h>
|
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
|
@ -16,23 +16,23 @@ struct recorder {
|
||||||
enum recorder_format format;
|
enum recorder_format format;
|
||||||
AVFormatContext *ctx;
|
AVFormatContext *ctx;
|
||||||
struct size declared_frame_size;
|
struct size declared_frame_size;
|
||||||
SDL_bool header_written;
|
bool header_written;
|
||||||
};
|
};
|
||||||
|
|
||||||
SDL_bool
|
bool
|
||||||
recorder_init(struct recorder *recoder, const char *filename,
|
recorder_init(struct recorder *recoder, const char *filename,
|
||||||
enum recorder_format format, struct size declared_frame_size);
|
enum recorder_format format, struct size declared_frame_size);
|
||||||
|
|
||||||
void
|
void
|
||||||
recorder_destroy(struct recorder *recorder);
|
recorder_destroy(struct recorder *recorder);
|
||||||
|
|
||||||
SDL_bool
|
bool
|
||||||
recorder_open(struct recorder *recorder, AVCodec *input_codec);
|
recorder_open(struct recorder *recorder, AVCodec *input_codec);
|
||||||
|
|
||||||
void
|
void
|
||||||
recorder_close(struct recorder *recorder);
|
recorder_close(struct recorder *recorder);
|
||||||
|
|
||||||
SDL_bool
|
bool
|
||||||
recorder_write(struct recorder *recorder, AVPacket *packet);
|
recorder_write(struct recorder *recorder, AVPacket *packet);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -39,7 +39,7 @@ static struct input_manager input_manager = {
|
||||||
.controller = &controller,
|
.controller = &controller,
|
||||||
.video_buffer = &video_buffer,
|
.video_buffer = &video_buffer,
|
||||||
.screen = &screen,
|
.screen = &screen,
|
||||||
.control = SDL_TRUE,
|
.control = true,
|
||||||
};
|
};
|
||||||
|
|
||||||
#if defined(__APPLE__) || defined(__WINDOWS__)
|
#if defined(__APPLE__) || defined(__WINDOWS__)
|
||||||
|
@ -63,7 +63,7 @@ event_watcher(void *data, SDL_Event *event) {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static SDL_bool
|
static bool
|
||||||
is_apk(const char *file) {
|
is_apk(const char *file) {
|
||||||
const char *ext = strrchr(file, '.');
|
const char *ext = strrchr(file, '.');
|
||||||
return ext && !strcmp(ext, ".apk");
|
return ext && !strcmp(ext, ".apk");
|
||||||
|
@ -76,7 +76,7 @@ enum event_result {
|
||||||
};
|
};
|
||||||
|
|
||||||
static enum event_result
|
static enum event_result
|
||||||
handle_event(SDL_Event *event, SDL_bool control) {
|
handle_event(SDL_Event *event, bool control) {
|
||||||
switch (event->type) {
|
switch (event->type) {
|
||||||
case EVENT_STREAM_STOPPED:
|
case EVENT_STREAM_STOPPED:
|
||||||
LOGD("Video stream stopped");
|
LOGD("Video stream stopped");
|
||||||
|
@ -86,12 +86,12 @@ handle_event(SDL_Event *event, SDL_bool control) {
|
||||||
return EVENT_RESULT_STOPPED_BY_USER;
|
return EVENT_RESULT_STOPPED_BY_USER;
|
||||||
case EVENT_NEW_FRAME:
|
case EVENT_NEW_FRAME:
|
||||||
if (!screen.has_frame) {
|
if (!screen.has_frame) {
|
||||||
screen.has_frame = SDL_TRUE;
|
screen.has_frame = 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);
|
||||||
}
|
}
|
||||||
if (!screen_update_frame(&screen, &video_buffer)) {
|
if (!screen_update_frame(&screen, &video_buffer)) {
|
||||||
return SDL_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SDL_WINDOWEVENT:
|
case SDL_WINDOWEVENT:
|
||||||
|
@ -149,8 +149,8 @@ handle_event(SDL_Event *event, SDL_bool control) {
|
||||||
return EVENT_RESULT_CONTINUE;
|
return EVENT_RESULT_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SDL_bool
|
static bool
|
||||||
event_loop(SDL_bool display, SDL_bool control) {
|
event_loop(bool display, bool control) {
|
||||||
#ifdef CONTINUOUS_RESIZING_WORKAROUND
|
#ifdef CONTINUOUS_RESIZING_WORKAROUND
|
||||||
if (display) {
|
if (display) {
|
||||||
SDL_AddEventWatch(event_watcher, NULL);
|
SDL_AddEventWatch(event_watcher, NULL);
|
||||||
|
@ -161,18 +161,18 @@ event_loop(SDL_bool display, SDL_bool control) {
|
||||||
enum event_result result = handle_event(&event, control);
|
enum event_result result = handle_event(&event, control);
|
||||||
switch (result) {
|
switch (result) {
|
||||||
case EVENT_RESULT_STOPPED_BY_USER:
|
case EVENT_RESULT_STOPPED_BY_USER:
|
||||||
return SDL_TRUE;
|
return true;
|
||||||
case EVENT_RESULT_STOPPED_BY_EOS:
|
case EVENT_RESULT_STOPPED_BY_EOS:
|
||||||
return SDL_FALSE;
|
return false;
|
||||||
case EVENT_RESULT_CONTINUE:
|
case EVENT_RESULT_CONTINUE:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return SDL_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static process_t
|
static process_t
|
||||||
set_show_touches_enabled(const char *serial, SDL_bool enabled) {
|
set_show_touches_enabled(const char *serial, bool enabled) {
|
||||||
const char *value = enabled ? "1" : "0";
|
const char *value = enabled ? "1" : "0";
|
||||||
const char *const adb_cmd[] = {
|
const char *const adb_cmd[] = {
|
||||||
"shell", "settings", "put", "system", "show_touches", value
|
"shell", "settings", "put", "system", "show_touches", value
|
||||||
|
@ -221,34 +221,34 @@ av_log_callback(void *avcl, int level, const char *fmt, va_list vl) {
|
||||||
SDL_free(local_fmt);
|
SDL_free(local_fmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_bool
|
bool
|
||||||
scrcpy(const struct scrcpy_options *options) {
|
scrcpy(const struct scrcpy_options *options) {
|
||||||
SDL_bool record = !!options->record_filename;
|
bool record = !!options->record_filename;
|
||||||
if (!server_start(&server, options->serial, options->port,
|
if (!server_start(&server, options->serial, options->port,
|
||||||
options->max_size, options->bit_rate, options->crop,
|
options->max_size, options->bit_rate, options->crop,
|
||||||
record)) {
|
record)) {
|
||||||
return SDL_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
process_t proc_show_touches = PROCESS_NONE;
|
process_t proc_show_touches = PROCESS_NONE;
|
||||||
SDL_bool show_touches_waited;
|
bool show_touches_waited;
|
||||||
if (options->show_touches) {
|
if (options->show_touches) {
|
||||||
LOGI("Enable show_touches");
|
LOGI("Enable show_touches");
|
||||||
proc_show_touches = set_show_touches_enabled(options->serial, SDL_TRUE);
|
proc_show_touches = set_show_touches_enabled(options->serial, true);
|
||||||
show_touches_waited = SDL_FALSE;
|
show_touches_waited = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_bool ret = SDL_TRUE;
|
bool ret = true;
|
||||||
|
|
||||||
if (!sdl_init_and_configure()) {
|
if (!sdl_init_and_configure()) {
|
||||||
ret = SDL_FALSE;
|
ret = false;
|
||||||
goto finally_destroy_server;
|
goto finally_destroy_server;
|
||||||
}
|
}
|
||||||
|
|
||||||
socket_t device_socket = server_connect_to(&server);
|
socket_t device_socket = server_connect_to(&server);
|
||||||
if (device_socket == INVALID_SOCKET) {
|
if (device_socket == INVALID_SOCKET) {
|
||||||
server_stop(&server);
|
server_stop(&server);
|
||||||
ret = SDL_FALSE;
|
ret = false;
|
||||||
goto finally_destroy_server;
|
goto finally_destroy_server;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -260,12 +260,12 @@ scrcpy(const struct scrcpy_options *options) {
|
||||||
// to be able to init the window immediately
|
// to be able to init the window immediately
|
||||||
if (!device_read_info(device_socket, device_name, &frame_size)) {
|
if (!device_read_info(device_socket, device_name, &frame_size)) {
|
||||||
server_stop(&server);
|
server_stop(&server);
|
||||||
ret = SDL_FALSE;
|
ret = false;
|
||||||
goto finally_destroy_server;
|
goto finally_destroy_server;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_bool display = !options->no_display;
|
bool display = !options->no_display;
|
||||||
SDL_bool control = !options->no_control;
|
bool control = !options->no_control;
|
||||||
|
|
||||||
input_manager.control = control;
|
input_manager.control = control;
|
||||||
|
|
||||||
|
@ -273,12 +273,12 @@ scrcpy(const struct scrcpy_options *options) {
|
||||||
if (display) {
|
if (display) {
|
||||||
if (!video_buffer_init(&video_buffer)) {
|
if (!video_buffer_init(&video_buffer)) {
|
||||||
server_stop(&server);
|
server_stop(&server);
|
||||||
ret = SDL_FALSE;
|
ret = false;
|
||||||
goto finally_destroy_server;
|
goto finally_destroy_server;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (control && !file_handler_init(&file_handler, server.serial)) {
|
if (control && !file_handler_init(&file_handler, server.serial)) {
|
||||||
ret = SDL_FALSE;
|
ret = false;
|
||||||
server_stop(&server);
|
server_stop(&server);
|
||||||
goto finally_destroy_video_buffer;
|
goto finally_destroy_video_buffer;
|
||||||
}
|
}
|
||||||
|
@ -293,7 +293,7 @@ scrcpy(const struct scrcpy_options *options) {
|
||||||
options->record_filename,
|
options->record_filename,
|
||||||
options->record_format,
|
options->record_format,
|
||||||
frame_size)) {
|
frame_size)) {
|
||||||
ret = SDL_FALSE;
|
ret = false;
|
||||||
server_stop(&server);
|
server_stop(&server);
|
||||||
goto finally_destroy_file_handler;
|
goto finally_destroy_file_handler;
|
||||||
}
|
}
|
||||||
|
@ -307,7 +307,7 @@ scrcpy(const struct scrcpy_options *options) {
|
||||||
// now we consumed the header values, the socket receives the video stream
|
// now we consumed the header values, the socket receives the video stream
|
||||||
// start the stream
|
// start the stream
|
||||||
if (!stream_start(&stream)) {
|
if (!stream_start(&stream)) {
|
||||||
ret = SDL_FALSE;
|
ret = false;
|
||||||
server_stop(&server);
|
server_stop(&server);
|
||||||
goto finally_destroy_recorder;
|
goto finally_destroy_recorder;
|
||||||
}
|
}
|
||||||
|
@ -315,19 +315,19 @@ scrcpy(const struct scrcpy_options *options) {
|
||||||
if (display) {
|
if (display) {
|
||||||
if (control) {
|
if (control) {
|
||||||
if (!controller_init(&controller, device_socket)) {
|
if (!controller_init(&controller, device_socket)) {
|
||||||
ret = SDL_FALSE;
|
ret = false;
|
||||||
goto finally_stop_stream;
|
goto finally_stop_stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!controller_start(&controller)) {
|
if (!controller_start(&controller)) {
|
||||||
ret = SDL_FALSE;
|
ret = false;
|
||||||
goto finally_destroy_controller;
|
goto finally_destroy_controller;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!screen_init_rendering(&screen, device_name, frame_size,
|
if (!screen_init_rendering(&screen, device_name, frame_size,
|
||||||
options->always_on_top)) {
|
options->always_on_top)) {
|
||||||
ret = SDL_FALSE;
|
ret = false;
|
||||||
goto finally_stop_and_join_controller;
|
goto finally_stop_and_join_controller;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -338,7 +338,7 @@ scrcpy(const struct scrcpy_options *options) {
|
||||||
|
|
||||||
if (options->show_touches) {
|
if (options->show_touches) {
|
||||||
wait_show_touches(proc_show_touches);
|
wait_show_touches(proc_show_touches);
|
||||||
show_touches_waited = SDL_TRUE;
|
show_touches_waited = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = event_loop(display, control);
|
ret = event_loop(display, control);
|
||||||
|
@ -382,7 +382,7 @@ finally_destroy_server:
|
||||||
}
|
}
|
||||||
LOGI("Disable show_touches");
|
LOGI("Disable show_touches");
|
||||||
proc_show_touches = set_show_touches_enabled(options->serial,
|
proc_show_touches = set_show_touches_enabled(options->serial,
|
||||||
SDL_FALSE);
|
false);
|
||||||
wait_show_touches(proc_show_touches);
|
wait_show_touches(proc_show_touches);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
#ifndef SCRCPY_H
|
#ifndef SCRCPY_H
|
||||||
#define SCRCPY_H
|
#define SCRCPY_H
|
||||||
|
|
||||||
#include <SDL2/SDL_stdinc.h>
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
#include <recorder.h>
|
#include <recorder.h>
|
||||||
|
|
||||||
struct scrcpy_options {
|
struct scrcpy_options {
|
||||||
|
@ -9,17 +10,17 @@ struct scrcpy_options {
|
||||||
const char *crop;
|
const char *crop;
|
||||||
const char *record_filename;
|
const char *record_filename;
|
||||||
enum recorder_format record_format;
|
enum recorder_format record_format;
|
||||||
Uint16 port;
|
uint16_t port;
|
||||||
Uint16 max_size;
|
uint16_t max_size;
|
||||||
Uint32 bit_rate;
|
uint32_t bit_rate;
|
||||||
SDL_bool show_touches;
|
bool show_touches;
|
||||||
SDL_bool fullscreen;
|
bool fullscreen;
|
||||||
SDL_bool always_on_top;
|
bool always_on_top;
|
||||||
SDL_bool no_control;
|
bool no_control;
|
||||||
SDL_bool no_display;
|
bool no_display;
|
||||||
};
|
};
|
||||||
|
|
||||||
SDL_bool
|
bool
|
||||||
scrcpy(const struct scrcpy_options *options);
|
scrcpy(const struct scrcpy_options *options);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
#include "screen.h"
|
#include "screen.h"
|
||||||
|
|
||||||
#include <SDL2/SDL.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <SDL2/SDL.h>
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
#include "compat.h"
|
#include "compat.h"
|
||||||
#include "icon.xpm"
|
#include "icon.xpm"
|
||||||
#include "lock_util.h"
|
#include "lock_util.h"
|
||||||
|
@ -12,11 +13,11 @@
|
||||||
|
|
||||||
#define DISPLAY_MARGINS 96
|
#define DISPLAY_MARGINS 96
|
||||||
|
|
||||||
SDL_bool
|
bool
|
||||||
sdl_init_and_configure(void) {
|
sdl_init_and_configure(void) {
|
||||||
if (SDL_Init(SDL_INIT_VIDEO)) {
|
if (SDL_Init(SDL_INIT_VIDEO)) {
|
||||||
LOGC("Could not initialize SDL: %s", SDL_GetError());
|
LOGC("Could not initialize SDL: %s", SDL_GetError());
|
||||||
return SDL_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
atexit(SDL_Quit);
|
atexit(SDL_Quit);
|
||||||
|
@ -36,7 +37,7 @@ sdl_init_and_configure(void) {
|
||||||
// Do not disable the screensaver when scrcpy is running
|
// Do not disable the screensaver when scrcpy is running
|
||||||
SDL_EnableScreenSaver();
|
SDL_EnableScreenSaver();
|
||||||
|
|
||||||
return SDL_TRUE;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// get the window size in a struct size
|
// get the window size in a struct size
|
||||||
|
@ -75,7 +76,7 @@ set_window_size(struct screen *screen, struct size new_size) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// get the preferred display bounds (i.e. the screen bounds with some margins)
|
// get the preferred display bounds (i.e. the screen bounds with some margins)
|
||||||
static SDL_bool
|
static bool
|
||||||
get_preferred_display_bounds(struct size *bounds) {
|
get_preferred_display_bounds(struct size *bounds) {
|
||||||
SDL_Rect rect;
|
SDL_Rect rect;
|
||||||
#ifdef SCRCPY_SDL_HAS_GET_DISPLAY_USABLE_BOUNDS
|
#ifdef SCRCPY_SDL_HAS_GET_DISPLAY_USABLE_BOUNDS
|
||||||
|
@ -85,12 +86,12 @@ get_preferred_display_bounds(struct size *bounds) {
|
||||||
#endif
|
#endif
|
||||||
if (GET_DISPLAY_BOUNDS(0, &rect)) {
|
if (GET_DISPLAY_BOUNDS(0, &rect)) {
|
||||||
LOGW("Could not get display usable bounds: %s", SDL_GetError());
|
LOGW("Could not get display usable bounds: %s", SDL_GetError());
|
||||||
return SDL_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bounds->width = MAX(0, rect.w - DISPLAY_MARGINS);
|
bounds->width = MAX(0, rect.w - DISPLAY_MARGINS);
|
||||||
bounds->height = MAX(0, rect.h - DISPLAY_MARGINS);
|
bounds->height = MAX(0, rect.h - DISPLAY_MARGINS);
|
||||||
return SDL_TRUE;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// return the optimal size of the window, with the following constraints:
|
// return the optimal size of the window, with the following constraints:
|
||||||
|
@ -107,8 +108,8 @@ get_optimal_size(struct size current_size, struct size frame_size) {
|
||||||
|
|
||||||
struct size display_size;
|
struct size display_size;
|
||||||
// 32 bits because we need to multiply two 16 bits values
|
// 32 bits because we need to multiply two 16 bits values
|
||||||
Uint32 w;
|
uint32_t w;
|
||||||
Uint32 h;
|
uint32_t h;
|
||||||
|
|
||||||
if (!get_preferred_display_bounds(&display_size)) {
|
if (!get_preferred_display_bounds(&display_size)) {
|
||||||
// cannot get display bounds, do not constraint the size
|
// cannot get display bounds, do not constraint the size
|
||||||
|
@ -119,7 +120,7 @@ get_optimal_size(struct size current_size, struct size frame_size) {
|
||||||
h = MIN(current_size.height, display_size.height);
|
h = MIN(current_size.height, display_size.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_bool keep_width = frame_size.width * h > frame_size.height * w;
|
bool keep_width = frame_size.width * h > frame_size.height * w;
|
||||||
if (keep_width) {
|
if (keep_width) {
|
||||||
// remove black borders on top and bottom
|
// remove black borders on top and bottom
|
||||||
h = frame_size.height * w / frame_size.width;
|
h = frame_size.height * w / frame_size.width;
|
||||||
|
@ -159,13 +160,13 @@ create_texture(SDL_Renderer *renderer, struct size frame_size) {
|
||||||
frame_size.width, frame_size.height);
|
frame_size.width, frame_size.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_bool
|
bool
|
||||||
screen_init_rendering(struct screen *screen, const char *device_name,
|
screen_init_rendering(struct screen *screen, const char *device_name,
|
||||||
struct size frame_size, SDL_bool always_on_top) {
|
struct size frame_size, bool always_on_top) {
|
||||||
screen->frame_size = frame_size;
|
screen->frame_size = frame_size;
|
||||||
|
|
||||||
struct size window_size = get_initial_optimal_size(frame_size);
|
struct size window_size = get_initial_optimal_size(frame_size);
|
||||||
Uint32 window_flags = SDL_WINDOW_HIDDEN | SDL_WINDOW_RESIZABLE;
|
uint32_t window_flags = SDL_WINDOW_HIDDEN | SDL_WINDOW_RESIZABLE;
|
||||||
#ifdef HIDPI_SUPPORT
|
#ifdef HIDPI_SUPPORT
|
||||||
window_flags |= SDL_WINDOW_ALLOW_HIGHDPI;
|
window_flags |= SDL_WINDOW_ALLOW_HIGHDPI;
|
||||||
#endif
|
#endif
|
||||||
|
@ -184,7 +185,7 @@ screen_init_rendering(struct screen *screen, const char *device_name,
|
||||||
window_flags);
|
window_flags);
|
||||||
if (!screen->window) {
|
if (!screen->window) {
|
||||||
LOGC("Could not create window: %s", SDL_GetError());
|
LOGC("Could not create window: %s", SDL_GetError());
|
||||||
return SDL_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
screen->renderer = SDL_CreateRenderer(screen->window, -1,
|
screen->renderer = SDL_CreateRenderer(screen->window, -1,
|
||||||
|
@ -192,21 +193,21 @@ screen_init_rendering(struct screen *screen, const char *device_name,
|
||||||
if (!screen->renderer) {
|
if (!screen->renderer) {
|
||||||
LOGC("Could not create renderer: %s", SDL_GetError());
|
LOGC("Could not create renderer: %s", SDL_GetError());
|
||||||
screen_destroy(screen);
|
screen_destroy(screen);
|
||||||
return SDL_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SDL_RenderSetLogicalSize(screen->renderer, frame_size.width,
|
if (SDL_RenderSetLogicalSize(screen->renderer, frame_size.width,
|
||||||
frame_size.height)) {
|
frame_size.height)) {
|
||||||
LOGE("Could not set renderer logical size: %s", SDL_GetError());
|
LOGE("Could not set renderer logical size: %s", SDL_GetError());
|
||||||
screen_destroy(screen);
|
screen_destroy(screen);
|
||||||
return SDL_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_Surface *icon = read_xpm(icon_xpm);
|
SDL_Surface *icon = read_xpm(icon_xpm);
|
||||||
if (!icon) {
|
if (!icon) {
|
||||||
LOGE("Could not load icon: %s", SDL_GetError());
|
LOGE("Could not load icon: %s", SDL_GetError());
|
||||||
screen_destroy(screen);
|
screen_destroy(screen);
|
||||||
return SDL_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
SDL_SetWindowIcon(screen->window, icon);
|
SDL_SetWindowIcon(screen->window, icon);
|
||||||
SDL_FreeSurface(icon);
|
SDL_FreeSurface(icon);
|
||||||
|
@ -217,10 +218,10 @@ screen_init_rendering(struct screen *screen, const char *device_name,
|
||||||
if (!screen->texture) {
|
if (!screen->texture) {
|
||||||
LOGC("Could not create texture: %s", SDL_GetError());
|
LOGC("Could not create texture: %s", SDL_GetError());
|
||||||
screen_destroy(screen);
|
screen_destroy(screen);
|
||||||
return SDL_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return SDL_TRUE;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -242,14 +243,14 @@ screen_destroy(struct screen *screen) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// recreate the texture and resize the window if the frame size has changed
|
// recreate the texture and resize the window if the frame size has changed
|
||||||
static SDL_bool
|
static bool
|
||||||
prepare_for_frame(struct screen *screen, struct size new_frame_size) {
|
prepare_for_frame(struct screen *screen, struct size new_frame_size) {
|
||||||
if (screen->frame_size.width != new_frame_size.width
|
if (screen->frame_size.width != new_frame_size.width
|
||||||
|| screen->frame_size.height != new_frame_size.height) {
|
|| screen->frame_size.height != new_frame_size.height) {
|
||||||
if (SDL_RenderSetLogicalSize(screen->renderer, new_frame_size.width,
|
if (SDL_RenderSetLogicalSize(screen->renderer, new_frame_size.width,
|
||||||
new_frame_size.height)) {
|
new_frame_size.height)) {
|
||||||
LOGE("Could not set renderer logical size: %s", SDL_GetError());
|
LOGE("Could not set renderer logical size: %s", SDL_GetError());
|
||||||
return SDL_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// frame dimension changed, destroy texture
|
// frame dimension changed, destroy texture
|
||||||
|
@ -257,9 +258,9 @@ prepare_for_frame(struct screen *screen, struct size new_frame_size) {
|
||||||
|
|
||||||
struct size current_size = get_window_size(screen);
|
struct size current_size = get_window_size(screen);
|
||||||
struct size target_size = {
|
struct size target_size = {
|
||||||
(Uint32) current_size.width * new_frame_size.width
|
(uint32_t) current_size.width * new_frame_size.width
|
||||||
/ screen->frame_size.width,
|
/ screen->frame_size.width,
|
||||||
(Uint32) current_size.height * new_frame_size.height
|
(uint32_t) current_size.height * new_frame_size.height
|
||||||
/ screen->frame_size.height,
|
/ screen->frame_size.height,
|
||||||
};
|
};
|
||||||
target_size = get_optimal_size(target_size, new_frame_size);
|
target_size = get_optimal_size(target_size, new_frame_size);
|
||||||
|
@ -272,11 +273,11 @@ prepare_for_frame(struct screen *screen, struct size new_frame_size) {
|
||||||
screen->texture = create_texture(screen->renderer, new_frame_size);
|
screen->texture = create_texture(screen->renderer, new_frame_size);
|
||||||
if (!screen->texture) {
|
if (!screen->texture) {
|
||||||
LOGC("Could not create texture: %s", SDL_GetError());
|
LOGC("Could not create texture: %s", SDL_GetError());
|
||||||
return SDL_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return SDL_TRUE;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// write the frame into the texture
|
// write the frame into the texture
|
||||||
|
@ -288,20 +289,20 @@ update_texture(struct screen *screen, const AVFrame *frame) {
|
||||||
frame->data[2], frame->linesize[2]);
|
frame->data[2], frame->linesize[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_bool
|
bool
|
||||||
screen_update_frame(struct screen *screen, struct video_buffer *vb) {
|
screen_update_frame(struct screen *screen, struct video_buffer *vb) {
|
||||||
mutex_lock(vb->mutex);
|
mutex_lock(vb->mutex);
|
||||||
const AVFrame *frame = video_buffer_consume_rendered_frame(vb);
|
const AVFrame *frame = video_buffer_consume_rendered_frame(vb);
|
||||||
struct size new_frame_size = {frame->width, frame->height};
|
struct size new_frame_size = {frame->width, frame->height};
|
||||||
if (!prepare_for_frame(screen, new_frame_size)) {
|
if (!prepare_for_frame(screen, new_frame_size)) {
|
||||||
mutex_unlock(vb->mutex);
|
mutex_unlock(vb->mutex);
|
||||||
return SDL_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
update_texture(screen, frame);
|
update_texture(screen, frame);
|
||||||
mutex_unlock(vb->mutex);
|
mutex_unlock(vb->mutex);
|
||||||
|
|
||||||
screen_render(screen);
|
screen_render(screen);
|
||||||
return SDL_TRUE;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -317,7 +318,7 @@ screen_switch_fullscreen(struct screen *screen) {
|
||||||
// going to fullscreen, store the current windowed window size
|
// going to fullscreen, store the current windowed window size
|
||||||
screen->windowed_window_size = get_native_window_size(screen->window);
|
screen->windowed_window_size = get_native_window_size(screen->window);
|
||||||
}
|
}
|
||||||
Uint32 new_mode = screen->fullscreen ? 0 : SDL_WINDOW_FULLSCREEN_DESKTOP;
|
uint32_t new_mode = screen->fullscreen ? 0 : SDL_WINDOW_FULLSCREEN_DESKTOP;
|
||||||
if (SDL_SetWindowFullscreen(screen->window, new_mode)) {
|
if (SDL_SetWindowFullscreen(screen->window, new_mode)) {
|
||||||
LOGW("Could not switch fullscreen mode: %s", SDL_GetError());
|
LOGW("Could not switch fullscreen mode: %s", SDL_GetError());
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#ifndef SCREEN_H
|
#ifndef SCREEN_H
|
||||||
#define SCREEN_H
|
#define SCREEN_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
#include <SDL2/SDL.h>
|
#include <SDL2/SDL.h>
|
||||||
#include <libavformat/avformat.h>
|
#include <libavformat/avformat.h>
|
||||||
|
|
||||||
|
@ -15,9 +16,9 @@ struct screen {
|
||||||
struct size frame_size;
|
struct size frame_size;
|
||||||
//used only in fullscreen mode to know the windowed window size
|
//used only in fullscreen mode to know the windowed window size
|
||||||
struct size windowed_window_size;
|
struct size windowed_window_size;
|
||||||
SDL_bool has_frame;
|
bool has_frame;
|
||||||
SDL_bool fullscreen;
|
bool fullscreen;
|
||||||
SDL_bool no_window;
|
bool no_window;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SCREEN_INITIALIZER { \
|
#define SCREEN_INITIALIZER { \
|
||||||
|
@ -32,13 +33,13 @@ struct screen {
|
||||||
.width = 0, \
|
.width = 0, \
|
||||||
.height = 0, \
|
.height = 0, \
|
||||||
}, \
|
}, \
|
||||||
.has_frame = SDL_FALSE, \
|
.has_frame = false, \
|
||||||
.fullscreen = SDL_FALSE, \
|
.fullscreen = false, \
|
||||||
.no_window = SDL_FALSE, \
|
.no_window = false, \
|
||||||
}
|
}
|
||||||
|
|
||||||
// init SDL and set appropriate hints
|
// init SDL and set appropriate hints
|
||||||
SDL_bool
|
bool
|
||||||
sdl_init_and_configure(void);
|
sdl_init_and_configure(void);
|
||||||
|
|
||||||
// initialize default values
|
// initialize default values
|
||||||
|
@ -46,9 +47,9 @@ void
|
||||||
screen_init(struct screen *screen);
|
screen_init(struct screen *screen);
|
||||||
|
|
||||||
// initialize screen, create window, renderer and texture (window is hidden)
|
// initialize screen, create window, renderer and texture (window is hidden)
|
||||||
SDL_bool
|
bool
|
||||||
screen_init_rendering(struct screen *screen, const char *device_name,
|
screen_init_rendering(struct screen *screen, const char *device_name,
|
||||||
struct size frame_size, SDL_bool always_on_top);
|
struct size frame_size, bool always_on_top);
|
||||||
|
|
||||||
// show the window
|
// show the window
|
||||||
void
|
void
|
||||||
|
@ -59,7 +60,7 @@ void
|
||||||
screen_destroy(struct screen *screen);
|
screen_destroy(struct screen *screen);
|
||||||
|
|
||||||
// resize if necessary and write the rendered frame into the texture
|
// resize if necessary and write the rendered frame into the texture
|
||||||
SDL_bool
|
bool
|
||||||
screen_update_frame(struct screen *screen, struct video_buffer *vb);
|
screen_update_frame(struct screen *screen, struct video_buffer *vb);
|
||||||
|
|
||||||
// render the texture to the renderer
|
// render the texture to the renderer
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <SDL2/SDL_assert.h>
|
#include <SDL2/SDL_assert.h>
|
||||||
#include <SDL2/SDL_timer.h>
|
#include <SDL2/SDL_timer.h>
|
||||||
|
@ -30,48 +29,48 @@ get_server_path(void) {
|
||||||
return server_path;
|
return server_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SDL_bool
|
static bool
|
||||||
push_server(const char *serial) {
|
push_server(const char *serial) {
|
||||||
process_t process = adb_push(serial, get_server_path(), DEVICE_SERVER_PATH);
|
process_t process = adb_push(serial, get_server_path(), DEVICE_SERVER_PATH);
|
||||||
return process_check_success(process, "adb push");
|
return process_check_success(process, "adb push");
|
||||||
}
|
}
|
||||||
|
|
||||||
static SDL_bool
|
static bool
|
||||||
enable_tunnel_reverse(const char *serial, Uint16 local_port) {
|
enable_tunnel_reverse(const char *serial, uint16_t local_port) {
|
||||||
process_t process = adb_reverse(serial, SOCKET_NAME, local_port);
|
process_t process = adb_reverse(serial, SOCKET_NAME, local_port);
|
||||||
return process_check_success(process, "adb reverse");
|
return process_check_success(process, "adb reverse");
|
||||||
}
|
}
|
||||||
|
|
||||||
static SDL_bool
|
static bool
|
||||||
disable_tunnel_reverse(const char *serial) {
|
disable_tunnel_reverse(const char *serial) {
|
||||||
process_t process = adb_reverse_remove(serial, SOCKET_NAME);
|
process_t process = adb_reverse_remove(serial, SOCKET_NAME);
|
||||||
return process_check_success(process, "adb reverse --remove");
|
return process_check_success(process, "adb reverse --remove");
|
||||||
}
|
}
|
||||||
|
|
||||||
static SDL_bool
|
static bool
|
||||||
enable_tunnel_forward(const char *serial, Uint16 local_port) {
|
enable_tunnel_forward(const char *serial, uint16_t local_port) {
|
||||||
process_t process = adb_forward(serial, local_port, SOCKET_NAME);
|
process_t process = adb_forward(serial, local_port, SOCKET_NAME);
|
||||||
return process_check_success(process, "adb forward");
|
return process_check_success(process, "adb forward");
|
||||||
}
|
}
|
||||||
|
|
||||||
static SDL_bool
|
static bool
|
||||||
disable_tunnel_forward(const char *serial, Uint16 local_port) {
|
disable_tunnel_forward(const char *serial, uint16_t local_port) {
|
||||||
process_t process = adb_forward_remove(serial, local_port);
|
process_t process = adb_forward_remove(serial, local_port);
|
||||||
return process_check_success(process, "adb forward --remove");
|
return process_check_success(process, "adb forward --remove");
|
||||||
}
|
}
|
||||||
|
|
||||||
static SDL_bool
|
static bool
|
||||||
enable_tunnel(struct server *server) {
|
enable_tunnel(struct server *server) {
|
||||||
if (enable_tunnel_reverse(server->serial, server->local_port)) {
|
if (enable_tunnel_reverse(server->serial, server->local_port)) {
|
||||||
return SDL_TRUE;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOGW("'adb reverse' failed, fallback to 'adb forward'");
|
LOGW("'adb reverse' failed, fallback to 'adb forward'");
|
||||||
server->tunnel_forward = SDL_TRUE;
|
server->tunnel_forward = true;
|
||||||
return enable_tunnel_forward(server->serial, server->local_port);
|
return enable_tunnel_forward(server->serial, server->local_port);
|
||||||
}
|
}
|
||||||
|
|
||||||
static SDL_bool
|
static bool
|
||||||
disable_tunnel(struct server *server) {
|
disable_tunnel(struct server *server) {
|
||||||
if (server->tunnel_forward) {
|
if (server->tunnel_forward) {
|
||||||
return disable_tunnel_forward(server->serial, server->local_port);
|
return disable_tunnel_forward(server->serial, server->local_port);
|
||||||
|
@ -81,9 +80,9 @@ disable_tunnel(struct server *server) {
|
||||||
|
|
||||||
static process_t
|
static process_t
|
||||||
execute_server(const char *serial,
|
execute_server(const char *serial,
|
||||||
Uint16 max_size, Uint32 bit_rate,
|
uint16_t max_size, uint32_t bit_rate,
|
||||||
SDL_bool tunnel_forward, const char *crop,
|
bool tunnel_forward, const char *crop,
|
||||||
SDL_bool send_frame_meta) {
|
bool send_frame_meta) {
|
||||||
char max_size_string[6];
|
char max_size_string[6];
|
||||||
char bit_rate_string[11];
|
char bit_rate_string[11];
|
||||||
sprintf(max_size_string, "%"PRIu16, max_size);
|
sprintf(max_size_string, "%"PRIu16, max_size);
|
||||||
|
@ -106,12 +105,12 @@ execute_server(const char *serial,
|
||||||
#define IPV4_LOCALHOST 0x7F000001
|
#define IPV4_LOCALHOST 0x7F000001
|
||||||
|
|
||||||
static socket_t
|
static socket_t
|
||||||
listen_on_port(Uint16 port) {
|
listen_on_port(uint16_t port) {
|
||||||
return net_listen(IPV4_LOCALHOST, port, 1);
|
return net_listen(IPV4_LOCALHOST, port, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static socket_t
|
static socket_t
|
||||||
connect_and_read_byte(Uint16 port) {
|
connect_and_read_byte(uint16_t port) {
|
||||||
socket_t socket = net_connect(IPV4_LOCALHOST, port);
|
socket_t socket = net_connect(IPV4_LOCALHOST, port);
|
||||||
if (socket == INVALID_SOCKET) {
|
if (socket == INVALID_SOCKET) {
|
||||||
return INVALID_SOCKET;
|
return INVALID_SOCKET;
|
||||||
|
@ -128,7 +127,7 @@ connect_and_read_byte(Uint16 port) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static socket_t
|
static socket_t
|
||||||
connect_to_server(Uint16 port, Uint32 attempts, Uint32 delay) {
|
connect_to_server(uint16_t port, uint32_t attempts, uint32_t delay) {
|
||||||
do {
|
do {
|
||||||
LOGD("Remaining connection attempts: %d", (int) attempts);
|
LOGD("Remaining connection attempts: %d", (int) attempts);
|
||||||
socket_t socket = connect_and_read_byte(port);
|
socket_t socket = connect_and_read_byte(port);
|
||||||
|
@ -159,27 +158,27 @@ server_init(struct server *server) {
|
||||||
*server = (struct server) SERVER_INITIALIZER;
|
*server = (struct server) SERVER_INITIALIZER;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_bool
|
bool
|
||||||
server_start(struct server *server, const char *serial,
|
server_start(struct server *server, const char *serial,
|
||||||
Uint16 local_port, Uint16 max_size, Uint32 bit_rate,
|
uint16_t local_port, uint16_t max_size, uint32_t bit_rate,
|
||||||
const char *crop, SDL_bool send_frame_meta) {
|
const char *crop, bool send_frame_meta) {
|
||||||
server->local_port = local_port;
|
server->local_port = local_port;
|
||||||
|
|
||||||
if (serial) {
|
if (serial) {
|
||||||
server->serial = SDL_strdup(serial);
|
server->serial = SDL_strdup(serial);
|
||||||
if (!server->serial) {
|
if (!server->serial) {
|
||||||
return SDL_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!push_server(serial)) {
|
if (!push_server(serial)) {
|
||||||
SDL_free((void *) server->serial);
|
SDL_free((void *) server->serial);
|
||||||
return SDL_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!enable_tunnel(server)) {
|
if (!enable_tunnel(server)) {
|
||||||
SDL_free((void *) server->serial);
|
SDL_free((void *) server->serial);
|
||||||
return SDL_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if "adb reverse" does not work (e.g. over "adb connect"), it fallbacks to
|
// if "adb reverse" does not work (e.g. over "adb connect"), it fallbacks to
|
||||||
|
@ -197,7 +196,7 @@ server_start(struct server *server, const char *serial,
|
||||||
LOGE("Could not listen on port %" PRIu16, local_port);
|
LOGE("Could not listen on port %" PRIu16, local_port);
|
||||||
disable_tunnel(server);
|
disable_tunnel(server);
|
||||||
SDL_free((void *) server->serial);
|
SDL_free((void *) server->serial);
|
||||||
return SDL_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,12 +211,12 @@ server_start(struct server *server, const char *serial,
|
||||||
}
|
}
|
||||||
disable_tunnel(server);
|
disable_tunnel(server);
|
||||||
SDL_free((void *) server->serial);
|
SDL_free((void *) server->serial);
|
||||||
return SDL_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
server->tunnel_enabled = SDL_TRUE;
|
server->tunnel_enabled = true;
|
||||||
|
|
||||||
return SDL_TRUE;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
socket_t
|
socket_t
|
||||||
|
@ -225,8 +224,8 @@ server_connect_to(struct server *server) {
|
||||||
if (!server->tunnel_forward) {
|
if (!server->tunnel_forward) {
|
||||||
server->device_socket = net_accept(server->server_socket);
|
server->device_socket = net_accept(server->server_socket);
|
||||||
} else {
|
} else {
|
||||||
Uint32 attempts = 100;
|
uint32_t attempts = 100;
|
||||||
Uint32 delay = 100; // ms
|
uint32_t delay = 100; // ms
|
||||||
server->device_socket = connect_to_server(server->local_port, attempts,
|
server->device_socket = connect_to_server(server->local_port, attempts,
|
||||||
delay);
|
delay);
|
||||||
}
|
}
|
||||||
|
@ -242,7 +241,7 @@ server_connect_to(struct server *server) {
|
||||||
|
|
||||||
// we don't need the adb tunnel anymore
|
// we don't need the adb tunnel anymore
|
||||||
disable_tunnel(server); // ignore failure
|
disable_tunnel(server); // ignore failure
|
||||||
server->tunnel_enabled = SDL_FALSE;
|
server->tunnel_enabled = false;
|
||||||
|
|
||||||
return server->device_socket;
|
return server->device_socket;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
#ifndef SERVER_H
|
#ifndef SERVER_H
|
||||||
#define SERVER_H
|
#define SERVER_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "command.h"
|
#include "command.h"
|
||||||
#include "net.h"
|
#include "net.h"
|
||||||
|
|
||||||
|
@ -9,10 +12,10 @@ struct server {
|
||||||
process_t process;
|
process_t process;
|
||||||
socket_t server_socket; // only used if !tunnel_forward
|
socket_t server_socket; // only used if !tunnel_forward
|
||||||
socket_t device_socket;
|
socket_t device_socket;
|
||||||
Uint16 local_port;
|
uint16_t local_port;
|
||||||
SDL_bool tunnel_enabled;
|
bool tunnel_enabled;
|
||||||
SDL_bool tunnel_forward; // use "adb forward" instead of "adb reverse"
|
bool tunnel_forward; // use "adb forward" instead of "adb reverse"
|
||||||
SDL_bool send_frame_meta; // request frame PTS to be able to record properly
|
bool send_frame_meta; // request frame PTS to be able to record properly
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SERVER_INITIALIZER { \
|
#define SERVER_INITIALIZER { \
|
||||||
|
@ -21,9 +24,9 @@ struct server {
|
||||||
.server_socket = INVALID_SOCKET, \
|
.server_socket = INVALID_SOCKET, \
|
||||||
.device_socket = INVALID_SOCKET, \
|
.device_socket = INVALID_SOCKET, \
|
||||||
.local_port = 0, \
|
.local_port = 0, \
|
||||||
.tunnel_enabled = SDL_FALSE, \
|
.tunnel_enabled = false, \
|
||||||
.tunnel_forward = SDL_FALSE, \
|
.tunnel_forward = false, \
|
||||||
.send_frame_meta = SDL_FALSE, \
|
.send_frame_meta = false, \
|
||||||
}
|
}
|
||||||
|
|
||||||
// init default values
|
// init default values
|
||||||
|
@ -31,10 +34,10 @@ void
|
||||||
server_init(struct server *server);
|
server_init(struct server *server);
|
||||||
|
|
||||||
// push, enable tunnel et start the server
|
// push, enable tunnel et start the server
|
||||||
SDL_bool
|
bool
|
||||||
server_start(struct server *server, const char *serial,
|
server_start(struct server *server, const char *serial,
|
||||||
Uint16 local_port, Uint16 max_size, Uint32 bit_rate,
|
uint16_t local_port, uint16_t max_size, uint32_t bit_rate,
|
||||||
const char *crop, SDL_bool send_frame_meta);
|
const char *crop, bool send_frame_meta);
|
||||||
|
|
||||||
// block until the communication with the server is established
|
// block until the communication with the server is established
|
||||||
socket_t
|
socket_t
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
#define NO_PTS UINT64_C(-1)
|
#define NO_PTS UINT64_C(-1)
|
||||||
|
|
||||||
static struct frame_meta *
|
static struct frame_meta *
|
||||||
frame_meta_new(Uint64 pts) {
|
frame_meta_new(uint64_t pts) {
|
||||||
struct frame_meta *meta = malloc(sizeof(*meta));
|
struct frame_meta *meta = malloc(sizeof(*meta));
|
||||||
if (!meta) {
|
if (!meta) {
|
||||||
return meta;
|
return meta;
|
||||||
|
@ -38,11 +38,11 @@ frame_meta_delete(struct frame_meta *frame_meta) {
|
||||||
free(frame_meta);
|
free(frame_meta);
|
||||||
}
|
}
|
||||||
|
|
||||||
static SDL_bool
|
static bool
|
||||||
receiver_state_push_meta(struct receiver_state *state, Uint64 pts) {
|
receiver_state_push_meta(struct receiver_state *state, uint64_t pts) {
|
||||||
struct frame_meta *frame_meta = frame_meta_new(pts);
|
struct frame_meta *frame_meta = frame_meta_new(pts);
|
||||||
if (!frame_meta) {
|
if (!frame_meta) {
|
||||||
return SDL_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// append to the list
|
// append to the list
|
||||||
|
@ -52,14 +52,14 @@ receiver_state_push_meta(struct receiver_state *state, Uint64 pts) {
|
||||||
p = &(*p)->next;
|
p = &(*p)->next;
|
||||||
}
|
}
|
||||||
*p = frame_meta;
|
*p = frame_meta;
|
||||||
return SDL_TRUE;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Uint64
|
static uint64_t
|
||||||
receiver_state_take_meta(struct receiver_state *state) {
|
receiver_state_take_meta(struct receiver_state *state) {
|
||||||
struct frame_meta *frame_meta = state->frame_meta_queue; // first item
|
struct frame_meta *frame_meta = state->frame_meta_queue; // first item
|
||||||
SDL_assert(frame_meta); // must not be empty
|
SDL_assert(frame_meta); // must not be empty
|
||||||
Uint64 pts = frame_meta->pts;
|
uint64_t pts = frame_meta->pts;
|
||||||
state->frame_meta_queue = frame_meta->next; // remove the item
|
state->frame_meta_queue = frame_meta->next; // remove the item
|
||||||
frame_meta_delete(frame_meta);
|
frame_meta_delete(frame_meta);
|
||||||
return pts;
|
return pts;
|
||||||
|
@ -95,7 +95,7 @@ read_packet_with_meta(void *opaque, uint8_t *buf, int buf_size) {
|
||||||
// no partial read (net_recv_all())
|
// no partial read (net_recv_all())
|
||||||
SDL_assert_release(r == HEADER_SIZE);
|
SDL_assert_release(r == HEADER_SIZE);
|
||||||
|
|
||||||
Uint64 pts = buffer_read64be(header);
|
uint64_t pts = buffer_read64be(header);
|
||||||
state->remaining = buffer_read32be(&header[8]);
|
state->remaining = buffer_read32be(&header[8]);
|
||||||
|
|
||||||
if (pts != NO_PTS && !receiver_state_push_meta(state, pts)) {
|
if (pts != NO_PTS && !receiver_state_push_meta(state, pts)) {
|
||||||
|
@ -215,7 +215,7 @@ run_stream(void *data) {
|
||||||
if (stream->recorder) {
|
if (stream->recorder) {
|
||||||
// we retrieve the PTS in order they were received, so they will
|
// we retrieve the PTS in order they were received, so they will
|
||||||
// be assigned to the correct frame
|
// be assigned to the correct frame
|
||||||
Uint64 pts = receiver_state_take_meta(&stream->receiver_state);
|
uint64_t pts = receiver_state_take_meta(&stream->receiver_state);
|
||||||
packet.pts = pts;
|
packet.pts = pts;
|
||||||
packet.dts = pts;
|
packet.dts = pts;
|
||||||
|
|
||||||
|
@ -261,16 +261,16 @@ stream_init(struct stream *stream, socket_t socket,
|
||||||
stream->recorder = recorder;
|
stream->recorder = recorder;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_bool
|
bool
|
||||||
stream_start(struct stream *stream) {
|
stream_start(struct stream *stream) {
|
||||||
LOGD("Starting stream thread");
|
LOGD("Starting stream thread");
|
||||||
|
|
||||||
stream->thread = SDL_CreateThread(run_stream, "stream", stream);
|
stream->thread = SDL_CreateThread(run_stream, "stream", stream);
|
||||||
if (!stream->thread) {
|
if (!stream->thread) {
|
||||||
LOGC("Could not start stream thread");
|
LOGC("Could not start stream thread");
|
||||||
return SDL_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
return SDL_TRUE;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
#ifndef STREAM_H
|
#ifndef STREAM_H
|
||||||
#define STREAM_H
|
#define STREAM_H
|
||||||
|
|
||||||
#include <SDL2/SDL_stdinc.h>
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
#include <SDL2/SDL_thread.h>
|
#include <SDL2/SDL_thread.h>
|
||||||
|
|
||||||
#include "net.h"
|
#include "net.h"
|
||||||
|
@ -9,7 +10,7 @@
|
||||||
struct video_buffer;
|
struct video_buffer;
|
||||||
|
|
||||||
struct frame_meta {
|
struct frame_meta {
|
||||||
Uint64 pts;
|
uint64_t pts;
|
||||||
struct frame_meta *next;
|
struct frame_meta *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -30,7 +31,7 @@ void
|
||||||
stream_init(struct stream *stream, socket_t socket,
|
stream_init(struct stream *stream, socket_t socket,
|
||||||
struct decoder *decoder, struct recorder *recorder);
|
struct decoder *decoder, struct recorder *recorder);
|
||||||
|
|
||||||
SDL_bool
|
bool
|
||||||
stream_start(struct stream *stream);
|
stream_start(struct stream *stream);
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -73,7 +73,7 @@ end:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_bool
|
bool
|
||||||
cmd_terminate(pid_t pid) {
|
cmd_terminate(pid_t pid) {
|
||||||
if (pid <= 0) {
|
if (pid <= 0) {
|
||||||
LOGC("Requested to kill %d, this is an error. Please report the bug.\n",
|
LOGC("Requested to kill %d, this is an error. Please report the bug.\n",
|
||||||
|
@ -83,7 +83,7 @@ cmd_terminate(pid_t pid) {
|
||||||
return kill(pid, SIGTERM) != -1;
|
return kill(pid, SIGTERM) != -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_bool
|
bool
|
||||||
cmd_simple_wait(pid_t pid, int *exit_code) {
|
cmd_simple_wait(pid_t pid, int *exit_code) {
|
||||||
int status;
|
int status;
|
||||||
int code;
|
int code;
|
||||||
|
|
|
@ -2,10 +2,10 @@
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
SDL_bool
|
bool
|
||||||
net_init(void) {
|
net_init(void) {
|
||||||
// do nothing
|
// do nothing
|
||||||
return SDL_TRUE;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -13,7 +13,7 @@ net_cleanup(void) {
|
||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_bool
|
bool
|
||||||
net_close(socket_t socket) {
|
net_close(socket_t socket) {
|
||||||
return !close(socket);
|
return !close(socket);
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,12 +57,12 @@ cmd_execute(const char *path, const char *const argv[], HANDLE *handle) {
|
||||||
return PROCESS_SUCCESS;
|
return PROCESS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_bool
|
bool
|
||||||
cmd_terminate(HANDLE handle) {
|
cmd_terminate(HANDLE handle) {
|
||||||
return TerminateProcess(handle, 1) && CloseHandle(handle);
|
return TerminateProcess(handle, 1) && CloseHandle(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_bool
|
bool
|
||||||
cmd_simple_wait(HANDLE handle, DWORD *exit_code) {
|
cmd_simple_wait(HANDLE handle, DWORD *exit_code) {
|
||||||
DWORD code;
|
DWORD code;
|
||||||
if (WaitForSingleObject(handle, INFINITE) != WAIT_OBJECT_0
|
if (WaitForSingleObject(handle, INFINITE) != WAIT_OBJECT_0
|
||||||
|
|
|
@ -2,15 +2,15 @@
|
||||||
|
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
SDL_bool
|
bool
|
||||||
net_init(void) {
|
net_init(void) {
|
||||||
WSADATA wsa;
|
WSADATA wsa;
|
||||||
int res = WSAStartup(MAKEWORD(2, 2), &wsa) < 0;
|
int res = WSAStartup(MAKEWORD(2, 2), &wsa) < 0;
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
LOGC("WSAStartup failed with error %d", res);
|
LOGC("WSAStartup failed with error %d", res);
|
||||||
return SDL_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
return SDL_TRUE;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -18,7 +18,7 @@ net_cleanup(void) {
|
||||||
WSACleanup();
|
WSACleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_bool
|
bool
|
||||||
net_close(socket_t socket) {
|
net_close(socket_t socket) {
|
||||||
return !closesocket(socket);
|
return !closesocket(socket);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
#include "tiny_xpm.h"
|
#include "tiny_xpm.h"
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
@ -7,20 +9,20 @@
|
||||||
|
|
||||||
struct index {
|
struct index {
|
||||||
char c;
|
char c;
|
||||||
Uint32 color;
|
uint32_t color;
|
||||||
};
|
};
|
||||||
|
|
||||||
static SDL_bool
|
static bool
|
||||||
find_color(struct index *index, int len, char c, Uint32 *color) {
|
find_color(struct index *index, int len, char c, uint32_t *color) {
|
||||||
// there are typically very few color, so it's ok to iterate over the array
|
// there are typically very few color, so it's ok to iterate over the array
|
||||||
for (int i = 0; i < len; ++i) {
|
for (int i = 0; i < len; ++i) {
|
||||||
if (index[i].c == c) {
|
if (index[i].c == c) {
|
||||||
*color = index[i].color;
|
*color = index[i].color;
|
||||||
return SDL_TRUE;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*color = 0;
|
*color = 0;
|
||||||
return SDL_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We encounter some problems with SDL2_image on MSYS2 (Windows),
|
// We encounter some problems with SDL2_image on MSYS2 (Windows),
|
||||||
|
@ -71,7 +73,7 @@ read_xpm(char *xpm[]) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// parse image
|
// parse image
|
||||||
Uint32 *pixels = SDL_malloc(4 * width * height);
|
uint32_t *pixels = SDL_malloc(4 * width * height);
|
||||||
if (!pixels) {
|
if (!pixels) {
|
||||||
LOGE("Could not allocate icon memory");
|
LOGE("Could not allocate icon memory");
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -80,23 +82,23 @@ read_xpm(char *xpm[]) {
|
||||||
const char *line = xpm[1 + colors + y];
|
const char *line = xpm[1 + colors + y];
|
||||||
for (int x = 0; x < width; ++x) {
|
for (int x = 0; x < width; ++x) {
|
||||||
char c = line[x];
|
char c = line[x];
|
||||||
Uint32 color;
|
uint32_t color;
|
||||||
SDL_bool color_found = find_color(index, colors, c, &color);
|
bool color_found = find_color(index, colors, c, &color);
|
||||||
SDL_assert(color_found);
|
SDL_assert(color_found);
|
||||||
pixels[y * width + x] = color;
|
pixels[y * width + x] = color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
|
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
|
||||||
Uint32 amask = 0x000000ff;
|
uint32_t amask = 0x000000ff;
|
||||||
Uint32 rmask = 0x0000ff00;
|
uint32_t rmask = 0x0000ff00;
|
||||||
Uint32 gmask = 0x00ff0000;
|
uint32_t gmask = 0x00ff0000;
|
||||||
Uint32 bmask = 0xff000000;
|
uint32_t bmask = 0xff000000;
|
||||||
#else // little endian, like x86
|
#else // little endian, like x86
|
||||||
Uint32 amask = 0xff000000;
|
uint32_t amask = 0xff000000;
|
||||||
Uint32 rmask = 0x00ff0000;
|
uint32_t rmask = 0x00ff0000;
|
||||||
Uint32 gmask = 0x0000ff00;
|
uint32_t gmask = 0x0000ff00;
|
||||||
Uint32 bmask = 0x000000ff;
|
uint32_t bmask = 0x000000ff;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
SDL_Surface *surface = SDL_CreateRGBSurfaceFrom(pixels,
|
SDL_Surface *surface = SDL_CreateRGBSurfaceFrom(pixels,
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
#include "lock_util.h"
|
#include "lock_util.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
SDL_bool
|
bool
|
||||||
video_buffer_init(struct video_buffer *vb) {
|
video_buffer_init(struct video_buffer *vb) {
|
||||||
if (!(vb->decoding_frame = av_frame_alloc())) {
|
if (!(vb->decoding_frame = av_frame_alloc())) {
|
||||||
goto error_0;
|
goto error_0;
|
||||||
|
@ -28,22 +28,22 @@ video_buffer_init(struct video_buffer *vb) {
|
||||||
SDL_DestroyMutex(vb->mutex);
|
SDL_DestroyMutex(vb->mutex);
|
||||||
goto error_2;
|
goto error_2;
|
||||||
}
|
}
|
||||||
vb->interrupted = SDL_FALSE;
|
vb->interrupted = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// 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
|
||||||
vb->rendering_frame_consumed = SDL_TRUE;
|
vb->rendering_frame_consumed = true;
|
||||||
fps_counter_init(&vb->fps_counter);
|
fps_counter_init(&vb->fps_counter);
|
||||||
|
|
||||||
return SDL_TRUE;
|
return true;
|
||||||
|
|
||||||
error_2:
|
error_2:
|
||||||
av_frame_free(&vb->rendering_frame);
|
av_frame_free(&vb->rendering_frame);
|
||||||
error_1:
|
error_1:
|
||||||
av_frame_free(&vb->decoding_frame);
|
av_frame_free(&vb->decoding_frame);
|
||||||
error_0:
|
error_0:
|
||||||
return SDL_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -63,7 +63,7 @@ video_buffer_swap_frames(struct video_buffer *vb) {
|
||||||
vb->rendering_frame = tmp;
|
vb->rendering_frame = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_bool
|
bool
|
||||||
video_buffer_offer_decoded_frame(struct video_buffer *vb) {
|
video_buffer_offer_decoded_frame(struct video_buffer *vb) {
|
||||||
mutex_lock(vb->mutex);
|
mutex_lock(vb->mutex);
|
||||||
#ifndef SKIP_FRAMES
|
#ifndef SKIP_FRAMES
|
||||||
|
@ -80,8 +80,8 @@ video_buffer_offer_decoded_frame(struct video_buffer *vb) {
|
||||||
|
|
||||||
video_buffer_swap_frames(vb);
|
video_buffer_swap_frames(vb);
|
||||||
|
|
||||||
SDL_bool previous_frame_consumed = vb->rendering_frame_consumed;
|
bool previous_frame_consumed = vb->rendering_frame_consumed;
|
||||||
vb->rendering_frame_consumed = SDL_FALSE;
|
vb->rendering_frame_consumed = false;
|
||||||
|
|
||||||
mutex_unlock(vb->mutex);
|
mutex_unlock(vb->mutex);
|
||||||
return previous_frame_consumed;
|
return previous_frame_consumed;
|
||||||
|
@ -90,7 +90,7 @@ video_buffer_offer_decoded_frame(struct video_buffer *vb) {
|
||||||
const AVFrame *
|
const AVFrame *
|
||||||
video_buffer_consume_rendered_frame(struct video_buffer *vb) {
|
video_buffer_consume_rendered_frame(struct video_buffer *vb) {
|
||||||
SDL_assert(!vb->rendering_frame_consumed);
|
SDL_assert(!vb->rendering_frame_consumed);
|
||||||
vb->rendering_frame_consumed = SDL_TRUE;
|
vb->rendering_frame_consumed = true;
|
||||||
if (vb->fps_counter.started) {
|
if (vb->fps_counter.started) {
|
||||||
fps_counter_add_rendered_frame(&vb->fps_counter);
|
fps_counter_add_rendered_frame(&vb->fps_counter);
|
||||||
}
|
}
|
||||||
|
@ -108,7 +108,7 @@ video_buffer_interrupt(struct video_buffer *vb) {
|
||||||
(void) vb; // unused
|
(void) vb; // unused
|
||||||
#else
|
#else
|
||||||
mutex_lock(vb->mutex);
|
mutex_lock(vb->mutex);
|
||||||
vb->interrupted = SDL_TRUE;
|
vb->interrupted = true;
|
||||||
mutex_unlock(vb->mutex);
|
mutex_unlock(vb->mutex);
|
||||||
// wake up blocking wait
|
// wake up blocking wait
|
||||||
cond_signal(vb->rendering_frame_consumed_cond);
|
cond_signal(vb->rendering_frame_consumed_cond);
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
#ifndef VIDEO_BUFFER_H
|
#ifndef VIDEO_BUFFER_H
|
||||||
#define VIDEO_BUFFER_H
|
#define VIDEO_BUFFER_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
#include <SDL2/SDL_mutex.h>
|
#include <SDL2/SDL_mutex.h>
|
||||||
#include <SDL2/SDL_stdinc.h>
|
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "fps_counter.h"
|
#include "fps_counter.h"
|
||||||
|
@ -15,14 +15,14 @@ struct video_buffer {
|
||||||
AVFrame *rendering_frame;
|
AVFrame *rendering_frame;
|
||||||
SDL_mutex *mutex;
|
SDL_mutex *mutex;
|
||||||
#ifndef SKIP_FRAMES
|
#ifndef SKIP_FRAMES
|
||||||
SDL_bool interrupted;
|
bool interrupted;
|
||||||
SDL_cond *rendering_frame_consumed_cond;
|
SDL_cond *rendering_frame_consumed_cond;
|
||||||
#endif
|
#endif
|
||||||
SDL_bool rendering_frame_consumed;
|
bool rendering_frame_consumed;
|
||||||
struct fps_counter fps_counter;
|
struct fps_counter fps_counter;
|
||||||
};
|
};
|
||||||
|
|
||||||
SDL_bool
|
bool
|
||||||
video_buffer_init(struct video_buffer *vb);
|
video_buffer_init(struct video_buffer *vb);
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -31,7 +31,7 @@ video_buffer_destroy(struct video_buffer *vb);
|
||||||
// set the decoded frame as ready for rendering
|
// set the decoded frame as ready for rendering
|
||||||
// this function locks frames->mutex during its execution
|
// this function locks frames->mutex during its execution
|
||||||
// returns true if the previous frame had been consumed
|
// returns true if the previous frame had been consumed
|
||||||
SDL_bool
|
bool
|
||||||
video_buffer_offer_decoded_frame(struct video_buffer *vb);
|
video_buffer_offer_decoded_frame(struct video_buffer *vb);
|
||||||
|
|
||||||
// mark the rendering frame as consumed and return it
|
// mark the rendering frame as consumed and return it
|
||||||
|
|
Loading…
Reference in a new issue