mirror of
https://github.com/Genymobile/scrcpy.git
synced 2025-08-04 07:09:06 +00:00
Working version
This commit is contained in:
parent
1f6f68dba4
commit
108f785c12
17 changed files with 97 additions and 123 deletions
|
@ -1,66 +0,0 @@
|
||||||
# Generated from CLion C/C++ Code Style settings
|
|
||||||
BasedOnStyle: LLVM
|
|
||||||
AccessModifierOffset: -4
|
|
||||||
AlignAfterOpenBracket: Align
|
|
||||||
AlignConsecutiveAssignments: None
|
|
||||||
AlignOperands: Align
|
|
||||||
AllowAllArgumentsOnNextLine: false
|
|
||||||
AllowAllConstructorInitializersOnNextLine: false
|
|
||||||
AllowAllParametersOfDeclarationOnNextLine: false
|
|
||||||
AllowShortBlocksOnASingleLine: Always
|
|
||||||
AllowShortCaseLabelsOnASingleLine: false
|
|
||||||
AllowShortFunctionsOnASingleLine: All
|
|
||||||
AllowShortIfStatementsOnASingleLine: Always
|
|
||||||
AllowShortLambdasOnASingleLine: All
|
|
||||||
AllowShortLoopsOnASingleLine: true
|
|
||||||
AlwaysBreakAfterReturnType: None
|
|
||||||
AlwaysBreakTemplateDeclarations: Yes
|
|
||||||
BreakBeforeBraces: Custom
|
|
||||||
BraceWrapping:
|
|
||||||
AfterCaseLabel: false
|
|
||||||
AfterClass: false
|
|
||||||
AfterControlStatement: Never
|
|
||||||
AfterEnum: false
|
|
||||||
AfterFunction: false
|
|
||||||
AfterNamespace: false
|
|
||||||
AfterUnion: false
|
|
||||||
BeforeCatch: false
|
|
||||||
BeforeElse: false
|
|
||||||
IndentBraces: false
|
|
||||||
SplitEmptyFunction: false
|
|
||||||
SplitEmptyRecord: true
|
|
||||||
BreakBeforeBinaryOperators: None
|
|
||||||
BreakBeforeTernaryOperators: true
|
|
||||||
BreakConstructorInitializers: BeforeColon
|
|
||||||
BreakInheritanceList: BeforeColon
|
|
||||||
ColumnLimit: 0
|
|
||||||
CompactNamespaces: false
|
|
||||||
ContinuationIndentWidth: 4
|
|
||||||
IndentCaseLabels: true
|
|
||||||
IndentPPDirectives: None
|
|
||||||
IndentWidth: 4
|
|
||||||
KeepEmptyLinesAtTheStartOfBlocks: true
|
|
||||||
MaxEmptyLinesToKeep: 2
|
|
||||||
NamespaceIndentation: All
|
|
||||||
ObjCSpaceAfterProperty: false
|
|
||||||
ObjCSpaceBeforeProtocolList: true
|
|
||||||
PointerAlignment: Right
|
|
||||||
ReflowComments: false
|
|
||||||
SpaceAfterCStyleCast: true
|
|
||||||
SpaceAfterLogicalNot: false
|
|
||||||
SpaceAfterTemplateKeyword: false
|
|
||||||
SpaceBeforeAssignmentOperators: true
|
|
||||||
SpaceBeforeCpp11BracedList: false
|
|
||||||
SpaceBeforeCtorInitializerColon: true
|
|
||||||
SpaceBeforeInheritanceColon: true
|
|
||||||
SpaceBeforeParens: ControlStatements
|
|
||||||
SpaceBeforeRangeBasedForLoopColon: true
|
|
||||||
SpaceInEmptyParentheses: false
|
|
||||||
SpacesBeforeTrailingComments: 0
|
|
||||||
SpacesInAngles: false
|
|
||||||
SpacesInCStyleCastParentheses: false
|
|
||||||
SpacesInContainerLiterals: false
|
|
||||||
SpacesInParentheses: false
|
|
||||||
SpacesInSquareBrackets: false
|
|
||||||
TabWidth: 4
|
|
||||||
UseTab: Never
|
|
|
@ -1,8 +1,19 @@
|
||||||
cmake_minimum_required(VERSION 3.14)
|
cmake_minimum_required(VERSION 3.14)
|
||||||
project(scrcpy C)
|
project(scrcpy LANGUAGES C VERSION 1.17)
|
||||||
|
|
||||||
|
set(SCRCPY_VERSION ${PROJECT_VERSION})
|
||||||
|
|
||||||
|
option(PORTABLE "Whether should search scrcpy-server in the same dir" ON)
|
||||||
|
|
||||||
configure_file(src/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h)
|
configure_file(src/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h)
|
||||||
|
|
||||||
|
if (CMAKE_SYSTEM_NAME MATCHES "Windows")
|
||||||
|
set(SYSDIR ${CMAKE_CURRENT_LIST_DIR}/src/sys/win/)
|
||||||
|
else ()
|
||||||
|
set(SYSDIR ${CMAKE_CURRENT_LIST_DIR}/src/sys/unix/)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
|
||||||
add_executable(scrcpy
|
add_executable(scrcpy
|
||||||
src/main.c
|
src/main.c
|
||||||
src/cli.c
|
src/cli.c
|
||||||
|
@ -27,16 +38,29 @@ add_executable(scrcpy
|
||||||
src/video_buffer.c
|
src/video_buffer.c
|
||||||
src/util/net.c
|
src/util/net.c
|
||||||
src/util/str_util.c
|
src/util/str_util.c
|
||||||
$<$<PLATFORM_ID:Windows>:
|
${SYSDIR}/command.c
|
||||||
${CMAKE_CURRENT_LIST_DIR}/src/sys/win/getopt.c
|
|
||||||
>)
|
|
||||||
|
|
||||||
find_package(SDL2 CONFIG REQUIRED)
|
$<$<PLATFORM_ID:Windows>:
|
||||||
|
${SYSDIR}/getopt.c
|
||||||
|
>
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/config.h
|
||||||
|
)
|
||||||
|
|
||||||
|
find_package(SDL2 REQUIRED)
|
||||||
find_package(FFMPEG COMPONENTS avformat avcodec avutil REQUIRED)
|
find_package(FFMPEG COMPONENTS avformat avcodec avutil REQUIRED)
|
||||||
|
|
||||||
target_include_directories(scrcpy
|
target_include_directories(scrcpy
|
||||||
PRIVATE
|
PRIVATE
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/src
|
||||||
${CMAKE_CURRENT_BINARY_DIR}
|
${CMAKE_CURRENT_BINARY_DIR}
|
||||||
${FFMPEG_INCLUDE_DIRS}
|
${FFMPEG_INCLUDE_DIRS}
|
||||||
$<$<PLATFORM_ID:Windows>:${CMAKE_CURRENT_LIST_DIR}/src/sys/win/>)
|
${SYSDIR}
|
||||||
target_link_libraries(scrcpy SDL2::SDL2 SDL2::SDL2main ${FFMPEG_LIBRARIES})
|
)
|
||||||
|
|
||||||
|
target_link_libraries(scrcpy
|
||||||
|
PRIVATE
|
||||||
|
SDL2::SDL2
|
||||||
|
SDL2::SDL2main
|
||||||
|
${FFMPEG_LIBRARIES}
|
||||||
|
$<$<PLATFORM_ID:Windows>:ws2_32>
|
||||||
|
)
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
|
|
||||||
// build a "portable" version (with scrcpy-server accessible from the same
|
// build a "portable" version (with scrcpy-server accessible from the same
|
||||||
// directory as the executable)
|
// directory as the executable)
|
||||||
#cmakedefine01 PORTABLE
|
#cmakedefine PORTABLE
|
||||||
|
|
||||||
// the default client TCP port range for the "adb reverse" tunnel
|
// the default client TCP port range for the "adb reverse" tunnel
|
||||||
// overridden by option --port
|
// overridden by option --port
|
||||||
|
@ -40,7 +40,7 @@
|
||||||
// overridden by option --lock-video-orientation
|
// overridden by option --lock-video-orientation
|
||||||
#cmakedefine DEFAULT_LOCK_VIDEO_ORIENTATION ${DEFAULT_LOCK_VIDEO_ORIENTATION}
|
#cmakedefine DEFAULT_LOCK_VIDEO_ORIENTATION ${DEFAULT_LOCK_VIDEO_ORIENTATION}
|
||||||
#ifndef DEFAULT_LOCK_VIDEO_ORIENTATION
|
#ifndef DEFAULT_LOCK_VIDEO_ORIENTATION
|
||||||
#define DEFAULT_LOCK_VIDEO_ORIENTATION -1 /* -1 - unlocked */
|
#define DEFAULT_LOCK_VIDEO_ORIENTATION (-1) /* -1 - unlocked */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// the default video bitrate, in bits/second
|
// the default video bitrate, in bits/second
|
||||||
|
@ -53,10 +53,10 @@
|
||||||
#define HIDPI_SUPPORT ${HIDPI_SUPPORT}
|
#define HIDPI_SUPPORT ${HIDPI_SUPPORT}
|
||||||
|
|
||||||
// run a server debugger and wait for a client to be attached
|
// run a server debugger and wait for a client to be attached
|
||||||
#define SERVER_DEBUGGER ${SERVER_DEBUGGER}
|
#cmakedefine SERVER_DEBUGGER
|
||||||
|
|
||||||
// select the debugger method ('old' for Android < 9, 'new' for Android >= 9)
|
// select the debugger method ('old' for Android < 9, 'new' for Android >= 9)
|
||||||
#cmakedefine01 SERVER_DEBUGGER_METHOD_NEW
|
#cmakedefine SERVER_DEBUGGER_METHOD_NEW
|
||||||
|
|
||||||
|
|
||||||
#endif //SCRCPY_CONFIG_H_IN_H
|
#endif //SCRCPY_CONFIG_H_IN_H
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "util/buffer_util.h"
|
#include "util/buffer_util.h"
|
||||||
#include "util/log.h"
|
#include "util/log.h"
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ fps_counter_init(struct fps_counter *counter) {
|
||||||
}
|
}
|
||||||
|
|
||||||
counter->thread = NULL;
|
counter->thread = NULL;
|
||||||
atomic_init(&counter->started, 0);
|
SDL_AtomicSet(&counter->started, 0);
|
||||||
// no need to initialize the other fields, they are unused until started
|
// no need to initialize the other fields, they are unused until started
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -37,12 +37,12 @@ fps_counter_destroy(struct fps_counter *counter) {
|
||||||
|
|
||||||
static inline bool
|
static inline bool
|
||||||
is_started(struct fps_counter *counter) {
|
is_started(struct fps_counter *counter) {
|
||||||
return atomic_load_explicit(&counter->started, memory_order_acquire);
|
return SDL_AtomicGet(&counter->started);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
set_started(struct fps_counter *counter, bool started) {
|
set_started(struct fps_counter *counter, bool started) {
|
||||||
atomic_store_explicit(&counter->started, started, memory_order_release);
|
SDL_AtomicSet(&counter->started, started);
|
||||||
}
|
}
|
||||||
|
|
||||||
// must be called with mutex locked
|
// must be called with mutex locked
|
||||||
|
|
|
@ -5,8 +5,6 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <SDL2/SDL_mutex.h>
|
#include <SDL2/SDL_mutex.h>
|
||||||
#include <SDL2/SDL_thread.h>
|
#include <SDL2/SDL_thread.h>
|
||||||
/* todo: this */
|
|
||||||
#define atomic_bool bool
|
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
|
@ -17,7 +15,7 @@ struct fps_counter {
|
||||||
|
|
||||||
// atomic so that we can check without locking the mutex
|
// atomic so that we can check without locking the mutex
|
||||||
// if the FPS counter is disabled, we don't want to lock unnecessarily
|
// if the FPS counter is disabled, we don't want to lock unnecessarily
|
||||||
atomic_bool started;
|
SDL_atomic_t started;
|
||||||
|
|
||||||
// the following fields are protected by the mutex
|
// the following fields are protected by the mutex
|
||||||
bool interrupted;
|
bool interrupted;
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <libavformat/avformat.h>
|
#include <libavformat/avformat.h>
|
||||||
#define SDL_MAIN_HANDLED // avoid link error on Linux Windows Subsystem
|
/*#define SDL_MAIN_HANDLED // avoid link error on Linux Windows Subsystem*/
|
||||||
#include <SDL2/SDL.h>
|
#include <SDL2/SDL.h>
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
|
@ -76,7 +76,7 @@ run_receiver(void *data) {
|
||||||
assert(head < DEVICE_MSG_MAX_SIZE);
|
assert(head < DEVICE_MSG_MAX_SIZE);
|
||||||
size_t r = net_recv(receiver->control_socket, buf + head,
|
size_t r = net_recv(receiver->control_socket, buf + head,
|
||||||
DEVICE_MSG_MAX_SIZE - head);
|
DEVICE_MSG_MAX_SIZE - head);
|
||||||
if (r <= 0) {
|
if (!r || r == -1) {
|
||||||
LOGD("Receiver stopped");
|
LOGD("Receiver stopped");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,15 +2,13 @@
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
|
||||||
#include <libavformat/avformat.h>
|
#include <libavformat/avformat.h>
|
||||||
#include <sys/time.h>
|
|
||||||
#include <SDL2/SDL.h>
|
#include <SDL2/SDL.h>
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
// not needed here, but winsock2.h must never be included AFTER windows.h
|
// not needed here, but winsock2.h must never be included AFTER windows.h
|
||||||
# include <winsock2.h>
|
# include <winsock2.h>
|
||||||
# include <windows.h>
|
# include <Windows.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
@ -74,7 +72,7 @@ BOOL WINAPI windows_ctrl_handler(DWORD ctrl_type) {
|
||||||
static bool
|
static bool
|
||||||
sdl_init_and_configure(bool display, const char *render_driver,
|
sdl_init_and_configure(bool display, const char *render_driver,
|
||||||
bool disable_screensaver) {
|
bool disable_screensaver) {
|
||||||
uint32_t flags = display ? SDL_INIT_VIDEO : SDL_INIT_EVENTS;
|
uint32_t flags = SDL_INIT_EVENTS | (display ? SDL_INIT_VIDEO : 0);
|
||||||
if (SDL_Init(flags)) {
|
if (SDL_Init(flags)) {
|
||||||
LOGC("Could not initialize SDL: %s", SDL_GetError());
|
LOGC("Could not initialize SDL: %s", SDL_GetError());
|
||||||
return false;
|
return false;
|
||||||
|
@ -462,6 +460,7 @@ end:
|
||||||
if (stream_started) {
|
if (stream_started) {
|
||||||
stream_stop(&stream);
|
stream_stop(&stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (controller_started) {
|
if (controller_started) {
|
||||||
controller_stop(&controller);
|
controller_stop(&controller);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <libgen.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <SDL2/SDL_thread.h>
|
#include <SDL2/SDL_thread.h>
|
||||||
#include <SDL2/SDL_timer.h>
|
#include <SDL2/SDL_timer.h>
|
||||||
|
@ -22,6 +21,20 @@
|
||||||
#define DEFAULT_SERVER_PATH PREFIX "/share/scrcpy/" SERVER_FILENAME
|
#define DEFAULT_SERVER_PATH PREFIX "/share/scrcpy/" SERVER_FILENAME
|
||||||
#define DEVICE_SERVER_PATH "/data/local/tmp/scrcpy-server.jar"
|
#define DEVICE_SERVER_PATH "/data/local/tmp/scrcpy-server.jar"
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#include <string.h>
|
||||||
|
char *dirname(char *path){
|
||||||
|
char *iter = path, *base = path;
|
||||||
|
while ((iter = strpbrk(iter, "/\\"))){
|
||||||
|
path = iter++;
|
||||||
|
}
|
||||||
|
*path = '\0';
|
||||||
|
return base;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#include <libgen.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
get_server_path(void) {
|
get_server_path(void) {
|
||||||
#ifdef __WINDOWS__
|
#ifdef __WINDOWS__
|
||||||
|
@ -359,8 +372,7 @@ server_init(struct server *server) {
|
||||||
server->serial = NULL;
|
server->serial = NULL;
|
||||||
server->process = PROCESS_NONE;
|
server->process = PROCESS_NONE;
|
||||||
server->wait_server_thread = NULL;
|
server->wait_server_thread = NULL;
|
||||||
atomic_flag_clear_explicit(&server->server_socket_closed,
|
SDL_AtomicSet(&server->server_socket_closed, 0);
|
||||||
memory_order_relaxed);
|
|
||||||
|
|
||||||
server->mutex = SDL_CreateMutex();
|
server->mutex = SDL_CreateMutex();
|
||||||
if (!server->mutex) {
|
if (!server->mutex) {
|
||||||
|
@ -402,7 +414,7 @@ run_wait_server(void *data) {
|
||||||
// no need for synchronization, server_socket is initialized before this
|
// no need for synchronization, server_socket is initialized before this
|
||||||
// thread was created
|
// thread was created
|
||||||
if (server->server_socket != INVALID_SOCKET
|
if (server->server_socket != INVALID_SOCKET
|
||||||
&& !atomic_flag_test_and_set(&server->server_socket_closed)) {
|
&& !SDL_AtomicSet(&server->server_socket_closed, 1)) {
|
||||||
// On Linux, accept() is unblocked by shutdown(), but on Windows, it is
|
// On Linux, accept() is unblocked by shutdown(), but on Windows, it is
|
||||||
// unblocked by closesocket(). Therefore, call both (close_socket()).
|
// unblocked by closesocket(). Therefore, call both (close_socket()).
|
||||||
close_socket(server->server_socket);
|
close_socket(server->server_socket);
|
||||||
|
@ -459,7 +471,7 @@ server_start(struct server *server, const char *serial,
|
||||||
error2:
|
error2:
|
||||||
if (!server->tunnel_forward) {
|
if (!server->tunnel_forward) {
|
||||||
bool was_closed =
|
bool was_closed =
|
||||||
atomic_flag_test_and_set(&server->server_socket_closed);
|
SDL_AtomicSet(&server->server_socket_closed, 1);
|
||||||
// the thread is not started, the flag could not be already set
|
// the thread is not started, the flag could not be already set
|
||||||
assert(!was_closed);
|
assert(!was_closed);
|
||||||
(void) was_closed;
|
(void) was_closed;
|
||||||
|
@ -486,7 +498,7 @@ server_connect_to(struct server *server) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// we don't need the server socket anymore
|
// we don't need the server socket anymore
|
||||||
if (!atomic_flag_test_and_set(&server->server_socket_closed)) {
|
if (!SDL_AtomicSet(&server->server_socket_closed, 1)) {
|
||||||
// close it from here
|
// close it from here
|
||||||
close_socket(server->server_socket);
|
close_socket(server->server_socket);
|
||||||
// otherwise, it is closed by run_wait_server()
|
// otherwise, it is closed by run_wait_server()
|
||||||
|
@ -518,7 +530,7 @@ server_connect_to(struct server *server) {
|
||||||
void
|
void
|
||||||
server_stop(struct server *server) {
|
server_stop(struct server *server) {
|
||||||
if (server->server_socket != INVALID_SOCKET
|
if (server->server_socket != INVALID_SOCKET
|
||||||
&& !atomic_flag_test_and_set(&server->server_socket_closed)) {
|
&& !SDL_AtomicSet(&server->server_socket_closed, 1)) {
|
||||||
close_socket(server->server_socket);
|
close_socket(server->server_socket);
|
||||||
}
|
}
|
||||||
if (server->video_socket != INVALID_SOCKET) {
|
if (server->video_socket != INVALID_SOCKET) {
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
#ifndef SERVER_H
|
#ifndef SERVER_H
|
||||||
#define SERVER_H
|
#define SERVER_H
|
||||||
|
|
||||||
#include <stdatomic.h>
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <SDL2/SDL_thread.h>
|
#include <SDL2/SDL_thread.h>
|
||||||
|
@ -17,7 +16,7 @@ struct server {
|
||||||
char *serial;
|
char *serial;
|
||||||
process_t process;
|
process_t process;
|
||||||
SDL_Thread *wait_server_thread;
|
SDL_Thread *wait_server_thread;
|
||||||
atomic_flag server_socket_closed;
|
SDL_atomic_t server_socket_closed;
|
||||||
|
|
||||||
SDL_mutex *mutex;
|
SDL_mutex *mutex;
|
||||||
SDL_cond *process_terminated_cond;
|
SDL_cond *process_terminated_cond;
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
#include <SDL2/SDL_events.h>
|
#include <SDL2/SDL_events.h>
|
||||||
#include <SDL2/SDL_mutex.h>
|
#include <SDL2/SDL_mutex.h>
|
||||||
#include <SDL2/SDL_thread.h>
|
#include <SDL2/SDL_thread.h>
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "compat.h"
|
#include "compat.h"
|
||||||
|
@ -43,7 +42,7 @@ stream_recv_packet(struct stream *stream, AVPacket *packet) {
|
||||||
|
|
||||||
uint64_t pts = buffer_read64be(header);
|
uint64_t pts = buffer_read64be(header);
|
||||||
uint32_t len = buffer_read32be(&header[8]);
|
uint32_t len = buffer_read32be(&header[8]);
|
||||||
assert(pts == NO_PTS || (pts & 0x8000000000000000) == 0);
|
assert(pts == NO_PTS || (pts >> 63) == 0);
|
||||||
assert(len);
|
assert(len);
|
||||||
|
|
||||||
if (av_new_packet(packet, len)) {
|
if (av_new_packet(packet, len)) {
|
||||||
|
@ -52,7 +51,7 @@ stream_recv_packet(struct stream *stream, AVPacket *packet) {
|
||||||
}
|
}
|
||||||
|
|
||||||
r = net_recv_all(stream->socket, packet->data, len);
|
r = net_recv_all(stream->socket, packet->data, len);
|
||||||
if (r < 0 || ((uint32_t) r) < len) {
|
if (r == -1 || ((uint32_t) r) < len) {
|
||||||
av_packet_unref(packet);
|
av_packet_unref(packet);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,11 @@
|
||||||
#include "util/log.h"
|
#include "util/log.h"
|
||||||
#include "util/str_util.h"
|
#include "util/str_util.h"
|
||||||
|
|
||||||
|
#if !defined(S_ISREG) && defined(S_IFMT) && defined(S_IFREG)
|
||||||
|
#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
build_cmd(char *cmd, size_t len, const char *const argv[]) {
|
build_cmd(char *cmd, size_t len, const char *const argv[]) {
|
||||||
// Windows command-line parsing is WTF:
|
// Windows command-line parsing is WTF:
|
||||||
|
@ -27,7 +32,7 @@ cmd_execute(const char *const argv[], HANDLE *handle) {
|
||||||
memset(&si, 0, sizeof(si));
|
memset(&si, 0, sizeof(si));
|
||||||
si.cb = sizeof(si);
|
si.cb = sizeof(si);
|
||||||
|
|
||||||
char cmd[256];
|
char cmd[512];
|
||||||
if (build_cmd(cmd, sizeof(cmd), argv)) {
|
if (build_cmd(cmd, sizeof(cmd), argv)) {
|
||||||
*handle = NULL;
|
*handle = NULL;
|
||||||
return PROCESS_ERROR_GENERIC;
|
return PROCESS_ERROR_GENERIC;
|
||||||
|
|
|
@ -60,7 +60,7 @@ read_xpm(char *xpm[]) {
|
||||||
(void) chars;
|
(void) chars;
|
||||||
|
|
||||||
// init index
|
// init index
|
||||||
struct index index[colors];
|
struct index *index = SDL_malloc(sizeof(*index) * colors);
|
||||||
for (int i = 0; i < colors; ++i) {
|
for (int i = 0; i < colors; ++i) {
|
||||||
const char *line = xpm[1+i];
|
const char *line = xpm[1+i];
|
||||||
index[i].c = line[0];
|
index[i].c = line[0];
|
||||||
|
@ -116,5 +116,6 @@ read_xpm(char *xpm[]) {
|
||||||
}
|
}
|
||||||
// make the surface own the raw pixels
|
// make the surface own the raw pixels
|
||||||
surface->flags &= ~SDL_PREALLOC;
|
surface->flags &= ~SDL_PREALLOC;
|
||||||
|
SDL_free(index);
|
||||||
return surface;
|
return surface;
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,7 @@
|
||||||
|
|
||||||
#define cbuf_take(PCBUF, PITEM) \
|
#define cbuf_take(PCBUF, PITEM) \
|
||||||
( \
|
( \
|
||||||
cbuf_is_empty(PCBUF) \
|
(!cbuf_is_empty(PCBUF)) \
|
||||||
? ( \
|
? ( \
|
||||||
*(PITEM) = (PCBUF)->data[(PCBUF)->tail], \
|
*(PITEM) = (PCBUF)->data[(PCBUF)->tail], \
|
||||||
(PCBUF)->tail = ((PCBUF)->tail + 1) % cbuf_size_(PCBUF), \
|
(PCBUF)->tail = ((PCBUF)->tail + 1) % cbuf_size_(PCBUF), \
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
(void) ((PQ)->first = (PQ)->last = NULL)
|
(void) ((PQ)->first = (PQ)->last = NULL)
|
||||||
|
|
||||||
#define queue_is_empty(PQ) \
|
#define queue_is_empty(PQ) \
|
||||||
!(PQ)->first
|
(!(PQ)->first)
|
||||||
|
|
||||||
// NEXTFIELD is the field in the ITEM type used for intrusive linked-list
|
// NEXTFIELD is the field in the ITEM type used for intrusive linked-list
|
||||||
//
|
//
|
||||||
|
@ -50,28 +50,29 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
// push a new item into the queue
|
// push a new item into the queue
|
||||||
#define queue_push(PQ, NEXTFIELD, ITEM) \
|
#define queue_push(PQ, NEXTFIELD, ITEM) \
|
||||||
(void) ({ \
|
(void) ( \
|
||||||
(ITEM)->NEXTFIELD = NULL; \
|
(ITEM)->NEXTFIELD = NULL, \
|
||||||
if (queue_is_empty(PQ)) { \
|
(queue_is_empty(PQ)) \
|
||||||
(PQ)->first = (PQ)->last = (ITEM); \
|
? (PQ)->first = (PQ)->last = (ITEM) \
|
||||||
} else { \
|
: ( \
|
||||||
(PQ)->last->NEXTFIELD = (ITEM); \
|
(PQ)->last->NEXTFIELD = (ITEM), \
|
||||||
(PQ)->last = (ITEM); \
|
(PQ)->last = (ITEM) \
|
||||||
} \
|
) \
|
||||||
})
|
\
|
||||||
|
)
|
||||||
|
|
||||||
// take the next item and remove it from the queue (the queue must not be empty)
|
// take the next item and remove it from the queue (the queue must not be empty)
|
||||||
// the result is stored in *(PITEM)
|
// the result is stored in *(PITEM)
|
||||||
// (without typeof(), we could not store a local variable having the correct
|
// (without typeof(), we could not store a local variable having the correct
|
||||||
// type so that we can "return" it)
|
// type so that we can "return" it)
|
||||||
#define queue_take(PQ, NEXTFIELD, PITEM) \
|
#define queue_take(PQ, NEXTFIELD, PITEM) \
|
||||||
(void) ({ \
|
(void) ( \
|
||||||
assert(!queue_is_empty(PQ)); \
|
assert(!queue_is_empty(PQ)), \
|
||||||
*(PITEM) = (PQ)->first; \
|
*(PITEM) = (PQ)->first, \
|
||||||
(PQ)->first = (PQ)->first->NEXTFIELD; \
|
(PQ)->first = (PQ)->first->NEXTFIELD \
|
||||||
})
|
)
|
||||||
// no need to update (PQ)->last if the queue is left empty:
|
// no need to update (PQ)->last if the queue is left empty:
|
||||||
// (PQ)->last is undefined if !(PQ)->first anyway
|
// (PQ)->last is undefined if !(PQ)->first anyway
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue