New upstream version 24.0.1+dfsg1
This commit is contained in:
parent
b14f9eae6d
commit
5a730d6ec3
842 changed files with 42245 additions and 33385 deletions
90
deps/file-updater/file-updater/file-updater.c
vendored
90
deps/file-updater/file-updater/file-updater.c
vendored
|
|
@ -7,9 +7,9 @@
|
|||
#include "file-updater.h"
|
||||
|
||||
#define warn(msg, ...) \
|
||||
blog(LOG_WARNING, "%s"msg, info->log_prefix, ##__VA_ARGS__)
|
||||
blog(LOG_WARNING, "%s" msg, info->log_prefix, ##__VA_ARGS__)
|
||||
#define info(msg, ...) \
|
||||
blog(LOG_WARNING, "%s"msg, info->log_prefix, ##__VA_ARGS__)
|
||||
blog(LOG_WARNING, "%s" msg, info->log_prefix, ##__VA_ARGS__)
|
||||
|
||||
struct update_info {
|
||||
char error[CURL_ERROR_SIZE];
|
||||
|
|
@ -70,7 +70,7 @@ void update_info_destroy(struct update_info *info)
|
|||
}
|
||||
|
||||
static size_t http_write(uint8_t *ptr, size_t size, size_t nmemb,
|
||||
struct update_info *info)
|
||||
struct update_info *info)
|
||||
{
|
||||
size_t total = size * nmemb;
|
||||
if (total)
|
||||
|
|
@ -80,10 +80,9 @@ static size_t http_write(uint8_t *ptr, size_t size, size_t nmemb,
|
|||
}
|
||||
|
||||
static size_t http_header(char *buffer, size_t size, size_t nitems,
|
||||
struct update_info *info)
|
||||
struct update_info *info)
|
||||
{
|
||||
if (!strncmp(buffer, "ETag: ", 6))
|
||||
{
|
||||
if (!strncmp(buffer, "ETag: ", 6)) {
|
||||
char *etag = buffer + 6;
|
||||
if (*etag) {
|
||||
char *etag_clean, *p;
|
||||
|
|
@ -105,7 +104,7 @@ static size_t http_header(char *buffer, size_t size, size_t nitems,
|
|||
}
|
||||
|
||||
static bool do_http_request(struct update_info *info, const char *url,
|
||||
long *response_code)
|
||||
long *response_code)
|
||||
{
|
||||
CURLcode code;
|
||||
uint8_t null_terminator = 0;
|
||||
|
|
@ -118,10 +117,12 @@ static bool do_http_request(struct update_info *info, const char *url,
|
|||
curl_easy_setopt(info->curl, CURLOPT_WRITEDATA, info);
|
||||
curl_easy_setopt(info->curl, CURLOPT_FAILONERROR, true);
|
||||
curl_easy_setopt(info->curl, CURLOPT_NOSIGNAL, 1);
|
||||
curl_easy_setopt(info->curl, CURLOPT_ACCEPT_ENCODING, "");
|
||||
|
||||
if (!info->remote_url) {
|
||||
// We only care about headers from the main package file
|
||||
curl_easy_setopt(info->curl, CURLOPT_HEADERFUNCTION, http_header);
|
||||
curl_easy_setopt(info->curl, CURLOPT_HEADERFUNCTION,
|
||||
http_header);
|
||||
curl_easy_setopt(info->curl, CURLOPT_HEADERDATA, info);
|
||||
}
|
||||
|
||||
|
|
@ -133,17 +134,17 @@ static bool do_http_request(struct update_info *info, const char *url,
|
|||
code = curl_easy_perform(info->curl);
|
||||
if (code != CURLE_OK) {
|
||||
warn("Remote update of URL \"%s\" failed: %s", url,
|
||||
info->error);
|
||||
info->error);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (curl_easy_getinfo(info->curl, CURLINFO_RESPONSE_CODE,
|
||||
response_code) != CURLE_OK)
|
||||
response_code) != CURLE_OK)
|
||||
return false;
|
||||
|
||||
if (*response_code >= 400) {
|
||||
warn("Remote update of URL \"%s\" failed: HTTP/%ld", url,
|
||||
*response_code);
|
||||
*response_code);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -190,14 +191,14 @@ static bool init_update(struct update_info *info)
|
|||
if (metadata) {
|
||||
const char *etag = obs_data_get_string(metadata, "etag");
|
||||
if (etag) {
|
||||
struct dstr if_none_match = { 0 };
|
||||
struct dstr if_none_match = {0};
|
||||
dstr_copy(&if_none_match, "If-None-Match: ");
|
||||
dstr_cat(&if_none_match, etag);
|
||||
|
||||
info->etag_local = bstrdup(etag);
|
||||
|
||||
info->header = curl_slist_append(info->header,
|
||||
if_none_match.array);
|
||||
if_none_match.array);
|
||||
|
||||
dstr_free(&if_none_match);
|
||||
}
|
||||
|
|
@ -218,7 +219,7 @@ static void copy_local_to_cache(struct update_info *info, const char *file)
|
|||
{
|
||||
char *local_file_path = get_path(info->local, file);
|
||||
char *cache_file_path = get_path(info->cache, file);
|
||||
char *temp_file_path = get_path(info->temp, file);
|
||||
char *temp_file_path = get_path(info->temp, file);
|
||||
|
||||
os_copyfile(local_file_path, temp_file_path);
|
||||
os_unlink(cache_file_path);
|
||||
|
|
@ -230,8 +231,8 @@ static void copy_local_to_cache(struct update_info *info, const char *file)
|
|||
}
|
||||
|
||||
static void enum_files(obs_data_t *package,
|
||||
bool (*enum_func)(void *param, obs_data_t *file),
|
||||
void *param)
|
||||
bool (*enum_func)(void *param, obs_data_t *file),
|
||||
void *param)
|
||||
{
|
||||
obs_data_array_t *array = obs_data_get_array(package, "files");
|
||||
size_t num;
|
||||
|
|
@ -280,8 +281,7 @@ static bool update_files_to_local(void *param, obs_data_t *local_file)
|
|||
struct update_info *info = param;
|
||||
struct file_update_data data = {
|
||||
.name = obs_data_get_string(local_file, "name"),
|
||||
.version = (int)obs_data_get_int(local_file, "version")
|
||||
};
|
||||
.version = (int)obs_data_get_int(local_file, "version")};
|
||||
|
||||
enum_files(info->cache_package, newer_than_cache, &data);
|
||||
if (data.newer || !data.found)
|
||||
|
|
@ -314,7 +314,7 @@ static int update_local_version(struct update_info *info)
|
|||
}
|
||||
|
||||
static inline bool do_relative_http_request(struct update_info *info,
|
||||
const char *url, const char *file)
|
||||
const char *url, const char *file)
|
||||
{
|
||||
long response_code;
|
||||
char *full_url = get_path(url, file);
|
||||
|
|
@ -324,17 +324,16 @@ static inline bool do_relative_http_request(struct update_info *info,
|
|||
}
|
||||
|
||||
static inline void write_file_data(struct update_info *info,
|
||||
const char *base_path, const char *file)
|
||||
const char *base_path, const char *file)
|
||||
{
|
||||
char *full_path = get_path(base_path, file);
|
||||
os_quick_write_utf8_file(full_path,
|
||||
(char*)info->file_data.array,
|
||||
info->file_data.num - 1, false);
|
||||
os_quick_write_utf8_file(full_path, (char *)info->file_data.array,
|
||||
info->file_data.num - 1, false);
|
||||
bfree(full_path);
|
||||
}
|
||||
|
||||
static inline void replace_file(const char *src_base_path,
|
||||
const char *dst_base_path, const char *file)
|
||||
const char *dst_base_path, const char *file)
|
||||
{
|
||||
char *src_path = get_path(src_base_path, file);
|
||||
char *dst_path = get_path(dst_base_path, file);
|
||||
|
|
@ -354,8 +353,7 @@ static bool update_remote_files(void *param, obs_data_t *remote_file)
|
|||
|
||||
struct file_update_data data = {
|
||||
.name = obs_data_get_string(remote_file, "name"),
|
||||
.version = (int)obs_data_get_int(remote_file, "version")
|
||||
};
|
||||
.version = (int)obs_data_get_int(remote_file, "version")};
|
||||
|
||||
enum_files(info->cache_package, newer_than_cache, &data);
|
||||
if (!data.newer && data.found)
|
||||
|
|
@ -378,7 +376,7 @@ static bool update_remote_files(void *param, obs_data_t *remote_file)
|
|||
|
||||
if (!confirm) {
|
||||
info("Update file '%s' (version %d) rejected",
|
||||
data.name, data.version);
|
||||
data.name, data.version);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -386,14 +384,14 @@ static bool update_remote_files(void *param, obs_data_t *remote_file)
|
|||
write_file_data(info, info->temp, data.name);
|
||||
replace_file(info->temp, info->cache, data.name);
|
||||
|
||||
info("Successfully updated file '%s' (version %d)",
|
||||
data.name, data.version);
|
||||
info("Successfully updated file '%s' (version %d)", data.name,
|
||||
data.version);
|
||||
return true;
|
||||
}
|
||||
|
||||
static void update_save_metadata(struct update_info *info)
|
||||
{
|
||||
struct dstr path = { 0 };
|
||||
struct dstr path = {0};
|
||||
|
||||
if (!info->etag_remote)
|
||||
return;
|
||||
|
|
@ -428,8 +426,8 @@ static void update_remote_version(struct update_info *info, int cur_version)
|
|||
|
||||
update_save_metadata(info);
|
||||
|
||||
info->remote_package = obs_data_create_from_json(
|
||||
(char*)info->file_data.array);
|
||||
info->remote_package =
|
||||
obs_data_create_from_json((char *)info->file_data.array);
|
||||
if (!info->remote_package) {
|
||||
warn("Failed to initialize remote package json");
|
||||
return;
|
||||
|
|
@ -476,14 +474,12 @@ static void *update_thread(void *data)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
update_info_t *update_info_create(
|
||||
const char *log_prefix,
|
||||
const char *user_agent,
|
||||
const char *update_url,
|
||||
const char *local_dir,
|
||||
const char *cache_dir,
|
||||
confirm_file_callback_t confirm_callback,
|
||||
void *param)
|
||||
update_info_t *update_info_create(const char *log_prefix,
|
||||
const char *user_agent,
|
||||
const char *update_url, const char *local_dir,
|
||||
const char *cache_dir,
|
||||
confirm_file_callback_t confirm_callback,
|
||||
void *param)
|
||||
{
|
||||
struct update_info *info;
|
||||
struct dstr dir = {0};
|
||||
|
|
@ -493,7 +489,7 @@ update_info_t *update_info_create(
|
|||
|
||||
if (os_mkdir(cache_dir) < 0) {
|
||||
blog(LOG_WARNING, "%sCould not create cache directory %s",
|
||||
log_prefix, cache_dir);
|
||||
log_prefix, cache_dir);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -504,7 +500,7 @@ update_info_t *update_info_create(
|
|||
|
||||
if (os_mkdir(dir.array) < 0) {
|
||||
blog(LOG_WARNING, "%sCould not create temp directory %s",
|
||||
log_prefix, cache_dir);
|
||||
log_prefix, cache_dir);
|
||||
dstr_free(&dir);
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -550,12 +546,10 @@ static void *single_file_thread(void *data)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
update_info_t *update_info_create_single(
|
||||
const char *log_prefix,
|
||||
const char *user_agent,
|
||||
const char *file_url,
|
||||
confirm_file_callback_t confirm_callback,
|
||||
void *param)
|
||||
update_info_t *
|
||||
update_info_create_single(const char *log_prefix, const char *user_agent,
|
||||
const char *file_url,
|
||||
confirm_file_callback_t confirm_callback, void *param)
|
||||
{
|
||||
struct update_info *info;
|
||||
|
||||
|
|
|
|||
23
deps/file-updater/file-updater/file-updater.h
vendored
23
deps/file-updater/file-updater/file-updater.h
vendored
|
|
@ -13,20 +13,15 @@ struct file_download_data {
|
|||
};
|
||||
|
||||
typedef bool (*confirm_file_callback_t)(void *param,
|
||||
struct file_download_data *file);
|
||||
struct file_download_data *file);
|
||||
|
||||
update_info_t *update_info_create(
|
||||
const char *log_prefix,
|
||||
const char *user_agent,
|
||||
const char *update_url,
|
||||
const char *local_dir,
|
||||
const char *cache_dir,
|
||||
confirm_file_callback_t confirm_callback,
|
||||
void *param);
|
||||
update_info_t *update_info_create(const char *log_prefix,
|
||||
const char *user_agent,
|
||||
const char *update_url, const char *local_dir,
|
||||
const char *cache_dir,
|
||||
confirm_file_callback_t confirm_callback,
|
||||
void *param);
|
||||
update_info_t *update_info_create_single(
|
||||
const char *log_prefix,
|
||||
const char *user_agent,
|
||||
const char *file_url,
|
||||
confirm_file_callback_t confirm_callback,
|
||||
void *param);
|
||||
const char *log_prefix, const char *user_agent, const char *file_url,
|
||||
confirm_file_callback_t confirm_callback, void *param);
|
||||
void update_info_destroy(update_info_t *info);
|
||||
|
|
|
|||
3
deps/glad/.clang-format
vendored
Normal file
3
deps/glad/.clang-format
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
Language: Cpp
|
||||
SortIncludes: false
|
||||
DisableFormat: true
|
||||
40
deps/ipc-util/ipc-util/pipe-windows.c
vendored
40
deps/ipc-util/ipc-util/pipe-windows.c
vendored
|
|
@ -47,15 +47,14 @@ error:
|
|||
}
|
||||
|
||||
static inline bool ipc_pipe_internal_create_pipe(ipc_pipe_server_t *pipe,
|
||||
const char *name)
|
||||
const char *name)
|
||||
{
|
||||
SECURITY_ATTRIBUTES sa;
|
||||
char new_name[512];
|
||||
void *sd;
|
||||
const DWORD access = PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED;
|
||||
const DWORD flags = PIPE_TYPE_MESSAGE |
|
||||
PIPE_READMODE_MESSAGE |
|
||||
PIPE_WAIT;
|
||||
const DWORD flags = PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE |
|
||||
PIPE_WAIT;
|
||||
|
||||
strcpy_s(new_name, sizeof(new_name), "\\\\.\\pipe\\");
|
||||
strcat_s(new_name, sizeof(new_name), name);
|
||||
|
|
@ -70,14 +69,15 @@ static inline bool ipc_pipe_internal_create_pipe(ipc_pipe_server_t *pipe,
|
|||
sa.bInheritHandle = false;
|
||||
|
||||
pipe->handle = CreateNamedPipeA(new_name, access, flags, 1,
|
||||
IPC_PIPE_BUF_SIZE, IPC_PIPE_BUF_SIZE, 0, &sa);
|
||||
IPC_PIPE_BUF_SIZE, IPC_PIPE_BUF_SIZE, 0,
|
||||
&sa);
|
||||
free(sd);
|
||||
|
||||
return pipe->handle != INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
static inline void ipc_pipe_internal_ensure_capacity(ipc_pipe_server_t *pipe,
|
||||
size_t new_size)
|
||||
size_t new_size)
|
||||
{
|
||||
if (pipe->capacity >= new_size) {
|
||||
return;
|
||||
|
|
@ -88,7 +88,7 @@ static inline void ipc_pipe_internal_ensure_capacity(ipc_pipe_server_t *pipe,
|
|||
}
|
||||
|
||||
static inline void ipc_pipe_internal_append_bytes(ipc_pipe_server_t *pipe,
|
||||
uint8_t *bytes, size_t size)
|
||||
uint8_t *bytes, size_t size)
|
||||
{
|
||||
size_t new_size = pipe->size + size;
|
||||
ipc_pipe_internal_ensure_capacity(pipe, new_size);
|
||||
|
|
@ -118,7 +118,7 @@ static DWORD CALLBACK ipc_pipe_internal_server_thread(LPVOID param)
|
|||
bool success;
|
||||
|
||||
success = !!ReadFile(pipe->handle, buf, IPC_PIPE_BUF_SIZE, NULL,
|
||||
&pipe->overlap);
|
||||
&pipe->overlap);
|
||||
if (!success && !ipc_pipe_internal_io_pending()) {
|
||||
break;
|
||||
}
|
||||
|
|
@ -129,7 +129,7 @@ static DWORD CALLBACK ipc_pipe_internal_server_thread(LPVOID param)
|
|||
}
|
||||
|
||||
success = !!GetOverlappedResult(pipe->handle, &pipe->overlap,
|
||||
&bytes, true);
|
||||
&bytes, true);
|
||||
if (!success || !bytes) {
|
||||
break;
|
||||
}
|
||||
|
|
@ -138,7 +138,7 @@ static DWORD CALLBACK ipc_pipe_internal_server_thread(LPVOID param)
|
|||
|
||||
if (success) {
|
||||
pipe->read_callback(pipe->param, pipe->read_data,
|
||||
pipe->size);
|
||||
pipe->size);
|
||||
pipe->size = 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -147,16 +147,16 @@ static DWORD CALLBACK ipc_pipe_internal_server_thread(LPVOID param)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static inline bool ipc_pipe_internal_start_server_thread(
|
||||
ipc_pipe_server_t *pipe)
|
||||
static inline bool
|
||||
ipc_pipe_internal_start_server_thread(ipc_pipe_server_t *pipe)
|
||||
{
|
||||
pipe->thread = CreateThread(NULL, 0, ipc_pipe_internal_server_thread,
|
||||
pipe, 0, NULL);
|
||||
pipe, 0, NULL);
|
||||
return pipe->thread != NULL;
|
||||
}
|
||||
|
||||
static inline bool ipc_pipe_internal_wait_for_connection(
|
||||
ipc_pipe_server_t *pipe)
|
||||
static inline bool
|
||||
ipc_pipe_internal_wait_for_connection(ipc_pipe_server_t *pipe)
|
||||
{
|
||||
bool success;
|
||||
|
||||
|
|
@ -166,7 +166,7 @@ static inline bool ipc_pipe_internal_wait_for_connection(
|
|||
}
|
||||
|
||||
static inline bool ipc_pipe_internal_open_pipe(ipc_pipe_client_t *pipe,
|
||||
const char *name)
|
||||
const char *name)
|
||||
{
|
||||
DWORD mode = PIPE_READMODE_MESSAGE;
|
||||
char new_name[512];
|
||||
|
|
@ -174,8 +174,8 @@ static inline bool ipc_pipe_internal_open_pipe(ipc_pipe_client_t *pipe,
|
|||
strcpy_s(new_name, sizeof(new_name), "\\\\.\\pipe\\");
|
||||
strcat_s(new_name, sizeof(new_name), name);
|
||||
|
||||
pipe->handle = CreateFileA(new_name, GENERIC_READ | GENERIC_WRITE,
|
||||
0, NULL, OPEN_EXISTING, 0, NULL);
|
||||
pipe->handle = CreateFileA(new_name, GENERIC_READ | GENERIC_WRITE, 0,
|
||||
NULL, OPEN_EXISTING, 0, NULL);
|
||||
if (pipe->handle == INVALID_HANDLE_VALUE) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -186,7 +186,7 @@ static inline bool ipc_pipe_internal_open_pipe(ipc_pipe_client_t *pipe,
|
|||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
bool ipc_pipe_server_start(ipc_pipe_server_t *pipe, const char *name,
|
||||
ipc_pipe_read_t read_callback, void *param)
|
||||
ipc_pipe_read_t read_callback, void *param)
|
||||
{
|
||||
pipe->read_callback = read_callback;
|
||||
pipe->param = param;
|
||||
|
|
@ -253,7 +253,7 @@ void ipc_pipe_client_free(ipc_pipe_client_t *pipe)
|
|||
}
|
||||
|
||||
bool ipc_pipe_client_write(ipc_pipe_client_t *pipe, const void *data,
|
||||
size_t size)
|
||||
size_t size)
|
||||
{
|
||||
DWORD bytes;
|
||||
|
||||
|
|
|
|||
20
deps/ipc-util/ipc-util/pipe-windows.h
vendored
20
deps/ipc-util/ipc-util/pipe-windows.h
vendored
|
|
@ -19,21 +19,21 @@
|
|||
#include <windows.h>
|
||||
|
||||
struct ipc_pipe_server {
|
||||
OVERLAPPED overlap;
|
||||
HANDLE handle;
|
||||
HANDLE ready_event;
|
||||
HANDLE thread;
|
||||
OVERLAPPED overlap;
|
||||
HANDLE handle;
|
||||
HANDLE ready_event;
|
||||
HANDLE thread;
|
||||
|
||||
uint8_t *read_data;
|
||||
size_t size;
|
||||
size_t capacity;
|
||||
uint8_t *read_data;
|
||||
size_t size;
|
||||
size_t capacity;
|
||||
|
||||
ipc_pipe_read_t read_callback;
|
||||
void *param;
|
||||
ipc_pipe_read_t read_callback;
|
||||
void *param;
|
||||
};
|
||||
|
||||
struct ipc_pipe_client {
|
||||
HANDLE handle;
|
||||
HANDLE handle;
|
||||
};
|
||||
|
||||
static inline bool ipc_pipe_client_valid(ipc_pipe_client_t *pipe)
|
||||
|
|
|
|||
4
deps/ipc-util/ipc-util/pipe.h
vendored
4
deps/ipc-util/ipc-util/pipe.h
vendored
|
|
@ -35,13 +35,13 @@ typedef struct ipc_pipe_client ipc_pipe_client_t;
|
|||
typedef void (*ipc_pipe_read_t)(void *param, uint8_t *data, size_t size);
|
||||
|
||||
bool ipc_pipe_server_start(ipc_pipe_server_t *pipe, const char *name,
|
||||
ipc_pipe_read_t read_callback, void *param);
|
||||
ipc_pipe_read_t read_callback, void *param);
|
||||
void ipc_pipe_server_free(ipc_pipe_server_t *pipe);
|
||||
|
||||
bool ipc_pipe_client_open(ipc_pipe_client_t *pipe, const char *name);
|
||||
void ipc_pipe_client_free(ipc_pipe_client_t *pipe);
|
||||
bool ipc_pipe_client_write(ipc_pipe_client_t *pipe, const void *data,
|
||||
size_t size);
|
||||
size_t size);
|
||||
static inline bool ipc_pipe_client_valid(ipc_pipe_client_t *pipe);
|
||||
|
||||
#ifdef _WIN32
|
||||
|
|
|
|||
3
deps/json11/.clang-format
vendored
Normal file
3
deps/json11/.clang-format
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
Language: Cpp
|
||||
SortIncludes: false
|
||||
DisableFormat: true
|
||||
39
deps/libff/libff/ff-audio-decoder.c
vendored
39
deps/libff/libff/ff-audio-decoder.c
vendored
|
|
@ -36,13 +36,13 @@ static inline void shrink_packet(struct ff_packet *packet, int packet_length)
|
|||
int remaining = packet->base.size - packet_length;
|
||||
|
||||
memmove(packet->base.data, &packet->base.data[packet_length],
|
||||
remaining);
|
||||
remaining);
|
||||
av_shrink_packet(&packet->base, remaining);
|
||||
}
|
||||
}
|
||||
|
||||
static bool handle_reset_packet(struct ff_decoder *decoder,
|
||||
struct ff_packet *packet)
|
||||
struct ff_packet *packet)
|
||||
{
|
||||
if (decoder->clock != NULL)
|
||||
ff_clock_release(&decoder->clock);
|
||||
|
|
@ -53,27 +53,29 @@ static bool handle_reset_packet(struct ff_decoder *decoder,
|
|||
}
|
||||
|
||||
static void drop_late_packets(struct ff_decoder *decoder,
|
||||
struct ff_packet *packet)
|
||||
struct ff_packet *packet)
|
||||
{
|
||||
int64_t start_time = ff_clock_start_time(decoder->clock);
|
||||
if (start_time != AV_NOPTS_VALUE) {
|
||||
if (ff_decoder_set_frame_drop_state(decoder, start_time,
|
||||
packet->base.pts))
|
||||
packet->base.pts))
|
||||
shrink_packet(packet, packet->base.size);
|
||||
}
|
||||
}
|
||||
|
||||
static int decode_frame(struct ff_decoder *decoder,
|
||||
struct ff_packet *packet, AVFrame *frame, bool *frame_complete)
|
||||
static int decode_frame(struct ff_decoder *decoder, struct ff_packet *packet,
|
||||
AVFrame *frame, bool *frame_complete)
|
||||
{
|
||||
int packet_length;
|
||||
int ret;
|
||||
|
||||
while (true) {
|
||||
if (decoder->eof)
|
||||
ret = packet_queue_get(&decoder->packet_queue, packet, 0);
|
||||
ret = packet_queue_get(&decoder->packet_queue, packet,
|
||||
0);
|
||||
else
|
||||
ret = packet_queue_get(&decoder->packet_queue, packet, 1);
|
||||
ret = packet_queue_get(&decoder->packet_queue, packet,
|
||||
1);
|
||||
|
||||
if (ret == FF_PACKET_EMPTY) {
|
||||
return 0;
|
||||
|
|
@ -82,7 +84,7 @@ static int decode_frame(struct ff_decoder *decoder,
|
|||
}
|
||||
|
||||
if (packet->base.data ==
|
||||
decoder->packet_queue.flush_packet.base.data) {
|
||||
decoder->packet_queue.flush_packet.base.data) {
|
||||
avcodec_flush_buffers(decoder->codec);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -98,8 +100,8 @@ static int decode_frame(struct ff_decoder *decoder,
|
|||
drop_late_packets(decoder, packet);
|
||||
|
||||
packet_length = avcodec_decode_audio4(decoder->codec,
|
||||
frame, &complete,
|
||||
&packet->base);
|
||||
frame, &complete,
|
||||
&packet->base);
|
||||
|
||||
if (packet_length < 0)
|
||||
break;
|
||||
|
|
@ -112,7 +114,7 @@ static int decode_frame(struct ff_decoder *decoder,
|
|||
*frame_complete = complete != 0;
|
||||
|
||||
return frame->nb_samples *
|
||||
av_get_bytes_per_sample(frame->format);
|
||||
av_get_bytes_per_sample(frame->format);
|
||||
}
|
||||
|
||||
if (packet->base.data != NULL)
|
||||
|
|
@ -121,7 +123,7 @@ static int decode_frame(struct ff_decoder *decoder,
|
|||
}
|
||||
|
||||
static bool queue_frame(struct ff_decoder *decoder, AVFrame *frame,
|
||||
double best_effort_pts)
|
||||
double best_effort_pts)
|
||||
{
|
||||
struct ff_frame *queue_frame;
|
||||
bool call_initialize;
|
||||
|
|
@ -135,10 +137,11 @@ static bool queue_frame(struct ff_decoder *decoder, AVFrame *frame,
|
|||
queue_frame = ff_circular_queue_peek_write(&decoder->frame_queue);
|
||||
|
||||
AVCodecContext *codec = decoder->codec;
|
||||
call_initialize = (queue_frame->frame == NULL
|
||||
|| queue_frame->frame->channels != codec->channels
|
||||
|| queue_frame->frame->sample_rate != codec->sample_rate
|
||||
|| queue_frame->frame->format != codec->sample_fmt);
|
||||
call_initialize =
|
||||
(queue_frame->frame == NULL ||
|
||||
queue_frame->frame->channels != codec->channels ||
|
||||
queue_frame->frame->sample_rate != codec->sample_rate ||
|
||||
queue_frame->frame->format != codec->sample_fmt);
|
||||
|
||||
if (queue_frame->frame != NULL) {
|
||||
//FIXME: this shouldn't happen any more!
|
||||
|
|
@ -183,7 +186,7 @@ void *ff_audio_decoder_thread(void *opaque_audio_decoder)
|
|||
// This function returns a pts scaled to stream
|
||||
// time base
|
||||
double best_effort_pts =
|
||||
ff_decoder_get_best_effort_pts(decoder, frame);
|
||||
ff_decoder_get_best_effort_pts(decoder, frame);
|
||||
queue_frame(decoder, frame, best_effort_pts);
|
||||
av_frame_unref(frame);
|
||||
}
|
||||
|
|
|
|||
9
deps/libff/libff/ff-callbacks.c
vendored
9
deps/libff/libff/ff-callbacks.c
vendored
|
|
@ -16,8 +16,7 @@
|
|||
|
||||
#include "ff-callbacks.h"
|
||||
|
||||
bool ff_callbacks_frame(struct ff_callbacks *callbacks,
|
||||
struct ff_frame *frame)
|
||||
bool ff_callbacks_frame(struct ff_callbacks *callbacks, struct ff_frame *frame)
|
||||
{
|
||||
if (callbacks->frame == NULL)
|
||||
return true;
|
||||
|
|
@ -26,7 +25,7 @@ bool ff_callbacks_frame(struct ff_callbacks *callbacks,
|
|||
}
|
||||
|
||||
bool ff_callbacks_format(struct ff_callbacks *callbacks,
|
||||
AVCodecContext *codec_context)
|
||||
AVCodecContext *codec_context)
|
||||
{
|
||||
if (callbacks->format == NULL)
|
||||
return true;
|
||||
|
|
@ -43,7 +42,7 @@ bool ff_callbacks_initialize(struct ff_callbacks *callbacks)
|
|||
}
|
||||
|
||||
bool ff_callbacks_frame_initialize(struct ff_frame *frame,
|
||||
struct ff_callbacks *callbacks)
|
||||
struct ff_callbacks *callbacks)
|
||||
{
|
||||
if (callbacks->frame_initialize == NULL)
|
||||
return true;
|
||||
|
|
@ -52,7 +51,7 @@ bool ff_callbacks_frame_initialize(struct ff_frame *frame,
|
|||
}
|
||||
|
||||
bool ff_callbacks_frame_free(struct ff_frame *frame,
|
||||
struct ff_callbacks *callbacks)
|
||||
struct ff_callbacks *callbacks)
|
||||
{
|
||||
if (callbacks->frame_free == NULL)
|
||||
return true;
|
||||
|
|
|
|||
10
deps/libff/libff/ff-callbacks.h
vendored
10
deps/libff/libff/ff-callbacks.h
vendored
|
|
@ -29,7 +29,6 @@ typedef bool (*ff_callback_frame)(struct ff_frame *frame, void *opaque);
|
|||
typedef bool (*ff_callback_format)(AVCodecContext *codec_context, void *opaque);
|
||||
typedef bool (*ff_callback_initialize)(void *opaque);
|
||||
|
||||
|
||||
struct ff_callbacks {
|
||||
ff_callback_frame frame;
|
||||
ff_callback_format format;
|
||||
|
|
@ -39,15 +38,14 @@ struct ff_callbacks {
|
|||
void *opaque;
|
||||
};
|
||||
|
||||
bool ff_callbacks_frame(struct ff_callbacks *callbacks,
|
||||
struct ff_frame *frame);
|
||||
bool ff_callbacks_frame(struct ff_callbacks *callbacks, struct ff_frame *frame);
|
||||
bool ff_callbacks_format(struct ff_callbacks *callbacks,
|
||||
AVCodecContext *codec_context);
|
||||
AVCodecContext *codec_context);
|
||||
bool ff_callbacks_initialize(struct ff_callbacks *callbacks);
|
||||
bool ff_callbacks_frame_initialize(struct ff_frame *frame,
|
||||
struct ff_callbacks *callbacks);
|
||||
struct ff_callbacks *callbacks);
|
||||
bool ff_callbacks_frame_free(struct ff_frame *frame,
|
||||
struct ff_callbacks *callbacks);
|
||||
struct ff_callbacks *callbacks);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
|||
7
deps/libff/libff/ff-circular-queue.c
vendored
7
deps/libff/libff/ff-circular-queue.c
vendored
|
|
@ -16,8 +16,7 @@
|
|||
|
||||
#include "ff-circular-queue.h"
|
||||
|
||||
static void *queue_fetch_or_alloc(struct ff_circular_queue *cq,
|
||||
int index)
|
||||
static void *queue_fetch_or_alloc(struct ff_circular_queue *cq, int index)
|
||||
{
|
||||
if (cq->slots[index] == NULL)
|
||||
cq->slots[index] = av_mallocz(cq->item_size);
|
||||
|
|
@ -46,7 +45,7 @@ static void queue_wait(struct ff_circular_queue *cq)
|
|||
}
|
||||
|
||||
bool ff_circular_queue_init(struct ff_circular_queue *cq, int item_size,
|
||||
int capacity)
|
||||
int capacity)
|
||||
{
|
||||
memset(cq, 0, sizeof(struct ff_circular_queue));
|
||||
|
||||
|
|
@ -136,5 +135,3 @@ void ff_circular_queue_advance_read(struct ff_circular_queue *cq)
|
|||
queue_signal(cq);
|
||||
queue_unlock(cq);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
2
deps/libff/libff/ff-circular-queue.h
vendored
2
deps/libff/libff/ff-circular-queue.h
vendored
|
|
@ -43,7 +43,7 @@ struct ff_circular_queue {
|
|||
typedef struct ff_circular_queue ff_circular_queue_t;
|
||||
|
||||
bool ff_circular_queue_init(struct ff_circular_queue *cq, int item_size,
|
||||
int capacity);
|
||||
int capacity);
|
||||
void ff_circular_queue_abort(struct ff_circular_queue *cq);
|
||||
void ff_circular_queue_free(struct ff_circular_queue *cq);
|
||||
|
||||
|
|
|
|||
23
deps/libff/libff/ff-clock.c
vendored
23
deps/libff/libff/ff-clock.c
vendored
|
|
@ -41,7 +41,7 @@ int64_t ff_clock_start_time(struct ff_clock *clock)
|
|||
}
|
||||
|
||||
bool ff_clock_start(struct ff_clock *clock, enum ff_av_sync_type sync_type,
|
||||
const bool *abort)
|
||||
const bool *abort)
|
||||
{
|
||||
bool release = false;
|
||||
bool aborted = false;
|
||||
|
|
@ -57,14 +57,14 @@ bool ff_clock_start(struct ff_clock *clock, enum ff_av_sync_type sync_type,
|
|||
} else {
|
||||
while (!clock->started) {
|
||||
pthread_mutex_lock(&clock->mutex);
|
||||
int64_t current_time = av_gettime()
|
||||
+ CLOCK_START_CHECK_INTERVAL;
|
||||
int64_t current_time =
|
||||
av_gettime() + CLOCK_START_CHECK_INTERVAL;
|
||||
struct timespec sleep_time = {
|
||||
.tv_sec = current_time / AV_TIME_BASE,
|
||||
.tv_nsec = (current_time % AV_TIME_BASE) * 1000
|
||||
};
|
||||
.tv_sec = current_time / AV_TIME_BASE,
|
||||
.tv_nsec =
|
||||
(current_time % AV_TIME_BASE) * 1000};
|
||||
pthread_cond_timedwait(&clock->cond, &clock->mutex,
|
||||
&sleep_time);
|
||||
&sleep_time);
|
||||
|
||||
aborted = *abort;
|
||||
|
||||
|
|
@ -75,10 +75,11 @@ bool ff_clock_start(struct ff_clock *clock, enum ff_av_sync_type sync_type,
|
|||
pthread_mutex_unlock(&clock->mutex);
|
||||
|
||||
if (aborted || release) {
|
||||
av_log(NULL, AV_LOG_ERROR, "could not start "
|
||||
"slave clock as master clock "
|
||||
"was never started before "
|
||||
"being released or aborted");
|
||||
av_log(NULL, AV_LOG_ERROR,
|
||||
"could not start "
|
||||
"slave clock as master clock "
|
||||
"was never started before "
|
||||
"being released or aborted");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
4
deps/libff/libff/ff-clock.h
vendored
4
deps/libff/libff/ff-clock.h
vendored
|
|
@ -50,7 +50,7 @@ struct ff_clock {
|
|||
|
||||
typedef struct ff_clock ff_clock_t;
|
||||
|
||||
struct ff_clock * ff_clock_init(void);
|
||||
struct ff_clock *ff_clock_init(void);
|
||||
double ff_get_sync_clock(struct ff_clock *clock);
|
||||
struct ff_clock *ff_clock_retain(struct ff_clock *clock);
|
||||
struct ff_clock *ff_clock_move(struct ff_clock **clock);
|
||||
|
|
@ -58,7 +58,7 @@ void ff_clock_release(struct ff_clock **clock);
|
|||
|
||||
int64_t ff_clock_start_time(struct ff_clock *clock);
|
||||
bool ff_clock_start(struct ff_clock *clock, enum ff_av_sync_type sync_type,
|
||||
const bool *abort);
|
||||
const bool *abort);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
|||
79
deps/libff/libff/ff-decoder.c
vendored
79
deps/libff/libff/ff-decoder.c
vendored
|
|
@ -25,8 +25,9 @@ extern void *ff_audio_decoder_thread(void *opaque_audio_decoder);
|
|||
extern void *ff_video_decoder_thread(void *opaque_video_decoder);
|
||||
|
||||
struct ff_decoder *ff_decoder_init(AVCodecContext *codec_context,
|
||||
AVStream *stream, unsigned int packet_queue_size,
|
||||
unsigned int frame_queue_size)
|
||||
AVStream *stream,
|
||||
unsigned int packet_queue_size,
|
||||
unsigned int frame_queue_size)
|
||||
{
|
||||
bool success;
|
||||
|
||||
|
|
@ -56,12 +57,13 @@ struct ff_decoder *ff_decoder_init(AVCodecContext *codec_context,
|
|||
decoder->first_frame = true;
|
||||
|
||||
success = ff_timer_init(&decoder->refresh_timer, ff_decoder_refresh,
|
||||
decoder);
|
||||
decoder);
|
||||
if (!success)
|
||||
goto fail2;
|
||||
|
||||
success = ff_circular_queue_init(&decoder->frame_queue,
|
||||
sizeof(struct ff_frame), frame_queue_size);
|
||||
sizeof(struct ff_frame),
|
||||
frame_queue_size);
|
||||
if (!success)
|
||||
goto fail3;
|
||||
|
||||
|
|
@ -88,14 +90,14 @@ bool ff_decoder_start(struct ff_decoder *decoder)
|
|||
decoder_thread = ff_video_decoder_thread;
|
||||
} else {
|
||||
av_log(NULL, AV_LOG_ERROR, "no decoder found for type %d",
|
||||
decoder->codec->codec_type);
|
||||
decoder->codec->codec_type);
|
||||
return false;
|
||||
}
|
||||
|
||||
ff_decoder_schedule_refresh(decoder, 40);
|
||||
|
||||
return (pthread_create(&decoder->decoder_thread, NULL,
|
||||
decoder_thread, decoder) != 0);
|
||||
return (pthread_create(&decoder->decoder_thread, NULL, decoder_thread,
|
||||
decoder) != 0);
|
||||
}
|
||||
|
||||
void ff_decoder_free(struct ff_decoder *decoder)
|
||||
|
|
@ -139,7 +141,7 @@ void ff_decoder_free(struct ff_decoder *decoder)
|
|||
|
||||
void ff_decoder_schedule_refresh(struct ff_decoder *decoder, int delay)
|
||||
{
|
||||
ff_timer_schedule(&decoder->refresh_timer, 1000*delay);
|
||||
ff_timer_schedule(&decoder->refresh_timer, 1000 * delay);
|
||||
}
|
||||
|
||||
double ff_decoder_clock(void *opaque)
|
||||
|
|
@ -149,16 +151,16 @@ double ff_decoder_clock(void *opaque)
|
|||
return decoder->current_pts + delta;
|
||||
}
|
||||
|
||||
static double get_sync_adjusted_pts_diff(struct ff_clock *clock,
|
||||
double pts, double pts_diff)
|
||||
static double get_sync_adjusted_pts_diff(struct ff_clock *clock, double pts,
|
||||
double pts_diff)
|
||||
{
|
||||
double new_pts_diff = pts_diff;
|
||||
double sync_time = ff_get_sync_clock(clock);
|
||||
double diff = pts - sync_time;
|
||||
double sync_threshold;
|
||||
|
||||
sync_threshold = (pts_diff > AV_SYNC_THRESHOLD)
|
||||
? pts_diff : AV_SYNC_THRESHOLD;
|
||||
sync_threshold = (pts_diff > AV_SYNC_THRESHOLD) ? pts_diff
|
||||
: AV_SYNC_THRESHOLD;
|
||||
|
||||
if (fabs(diff) < AV_NOSYNC_THRESHOLD) {
|
||||
if (diff <= -sync_threshold) {
|
||||
|
|
@ -183,7 +185,7 @@ void ff_decoder_refresh(void *opaque)
|
|||
if (!decoder->eof || !decoder->finished) {
|
||||
// We expected a frame, but there were none
|
||||
// available
|
||||
|
||||
|
||||
// Schedule another call as soon as possible
|
||||
ff_decoder_schedule_refresh(decoder, 1);
|
||||
} else {
|
||||
|
|
@ -191,7 +193,7 @@ void ff_decoder_refresh(void *opaque)
|
|||
decoder->refresh_timer.abort = true;
|
||||
// no more refreshes, we are at the eof
|
||||
av_log(NULL, AV_LOG_INFO,
|
||||
"refresh timer stopping; eof");
|
||||
"refresh timer stopping; eof");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
|
|
@ -200,12 +202,12 @@ void ff_decoder_refresh(void *opaque)
|
|||
bool late_first_frame = false;
|
||||
|
||||
frame = ff_circular_queue_peek_read(
|
||||
&decoder->frame_queue);
|
||||
&decoder->frame_queue);
|
||||
|
||||
// Get frame clock and start it if needed
|
||||
ff_clock_t *clock = ff_clock_move(&frame->clock);
|
||||
if (!ff_clock_start(clock, decoder->natural_sync_clock,
|
||||
&decoder->refresh_timer.abort)) {
|
||||
&decoder->refresh_timer.abort)) {
|
||||
ff_clock_release(&clock);
|
||||
|
||||
// Our clock was never started and deleted or
|
||||
|
|
@ -213,7 +215,7 @@ void ff_decoder_refresh(void *opaque)
|
|||
|
||||
if (decoder->refresh_timer.abort) {
|
||||
av_log(NULL, AV_LOG_INFO,
|
||||
"refresh timer aborted");
|
||||
"refresh timer aborted");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -227,7 +229,7 @@ void ff_decoder_refresh(void *opaque)
|
|||
// Drop this frame as we have no way of timing
|
||||
// it
|
||||
ff_circular_queue_advance_read(
|
||||
&decoder->frame_queue);
|
||||
&decoder->frame_queue);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -256,17 +258,16 @@ void ff_decoder_refresh(void *opaque)
|
|||
decoder->previous_pts = frame->pts;
|
||||
|
||||
// if not synced against natural clock
|
||||
if (clock->sync_type
|
||||
!= decoder->natural_sync_clock) {
|
||||
pts_diff = get_sync_adjusted_pts_diff(clock,
|
||||
frame->pts, pts_diff);
|
||||
if (clock->sync_type != decoder->natural_sync_clock) {
|
||||
pts_diff = get_sync_adjusted_pts_diff(
|
||||
clock, frame->pts, pts_diff);
|
||||
}
|
||||
|
||||
decoder->timer_next_wake += pts_diff;
|
||||
|
||||
// compute the amount of time until next refresh
|
||||
delay_until_next_wake = decoder->timer_next_wake -
|
||||
(av_gettime() / 1000000.0L);
|
||||
(av_gettime() / 1000000.0L);
|
||||
if (delay_until_next_wake < 0.010L) {
|
||||
delay_until_next_wake = 0.010L;
|
||||
}
|
||||
|
|
@ -277,9 +278,9 @@ void ff_decoder_refresh(void *opaque)
|
|||
ff_clock_release(&clock);
|
||||
ff_callbacks_frame(decoder->callbacks, frame);
|
||||
|
||||
ff_decoder_schedule_refresh(decoder,
|
||||
(int)(delay_until_next_wake * 1000
|
||||
+ 0.5L));
|
||||
ff_decoder_schedule_refresh(
|
||||
decoder,
|
||||
(int)(delay_until_next_wake * 1000 + 0.5L));
|
||||
|
||||
av_frame_free(&frame->frame);
|
||||
|
||||
|
|
@ -309,7 +310,7 @@ bool ff_decoder_accept(struct ff_decoder *decoder, struct ff_packet *packet)
|
|||
}
|
||||
|
||||
double ff_decoder_get_best_effort_pts(struct ff_decoder *decoder,
|
||||
AVFrame *frame)
|
||||
AVFrame *frame)
|
||||
{
|
||||
// this is how long each frame is added to the amount of repeated frames
|
||||
// according to the codec
|
||||
|
|
@ -328,9 +329,10 @@ double ff_decoder_get_best_effort_pts(struct ff_decoder *decoder,
|
|||
if (decoder->first_frame) {
|
||||
best_effort_pts = decoder->start_pts;
|
||||
} else {
|
||||
av_log(NULL, AV_LOG_WARNING, "multiple pts < "
|
||||
"start_pts; setting start pts "
|
||||
"to 0");
|
||||
av_log(NULL, AV_LOG_WARNING,
|
||||
"multiple pts < "
|
||||
"start_pts; setting start pts "
|
||||
"to 0");
|
||||
decoder->start_pts = 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -347,11 +349,11 @@ double ff_decoder_get_best_effort_pts(struct ff_decoder *decoder,
|
|||
|
||||
// Update our predicted pts to include the repeated picture count
|
||||
// Our predicted pts clock is based on the codecs time base
|
||||
estimated_frame_delay = av_frame_get_pkt_duration(frame)
|
||||
* av_q2d(decoder->codec->time_base);
|
||||
estimated_frame_delay = av_frame_get_pkt_duration(frame) *
|
||||
av_q2d(decoder->codec->time_base);
|
||||
// Add repeat frame delay
|
||||
estimated_frame_delay += frame->repeat_pict
|
||||
/ (1.0L / estimated_frame_delay);
|
||||
estimated_frame_delay +=
|
||||
frame->repeat_pict / (1.0L / estimated_frame_delay);
|
||||
|
||||
decoder->predicted_pts += estimated_frame_delay;
|
||||
|
||||
|
|
@ -359,13 +361,12 @@ double ff_decoder_get_best_effort_pts(struct ff_decoder *decoder,
|
|||
}
|
||||
|
||||
bool ff_decoder_set_frame_drop_state(struct ff_decoder *decoder,
|
||||
int64_t start_time, int64_t pts)
|
||||
int64_t start_time, int64_t pts)
|
||||
{
|
||||
if (pts != AV_NOPTS_VALUE) {
|
||||
int64_t rescaled_pts = av_rescale_q(pts,
|
||||
decoder->stream->time_base, AV_TIME_BASE_Q);
|
||||
int64_t master_clock = av_gettime() -
|
||||
start_time;
|
||||
int64_t rescaled_pts = av_rescale_q(
|
||||
pts, decoder->stream->time_base, AV_TIME_BASE_Q);
|
||||
int64_t master_clock = av_gettime() - start_time;
|
||||
|
||||
int64_t diff = master_clock - rescaled_pts;
|
||||
|
||||
|
|
|
|||
19
deps/libff/libff/ff-decoder.h
vendored
19
deps/libff/libff/ff-decoder.h
vendored
|
|
@ -41,11 +41,11 @@ struct ff_decoder {
|
|||
unsigned int packet_queue_size;
|
||||
|
||||
double timer_next_wake;
|
||||
double previous_pts; // previous decoded frame's pts
|
||||
double previous_pts_diff; // previous decoded frame pts delay
|
||||
double predicted_pts; // predicted pts of next frame
|
||||
double current_pts; // pts of the most recently dispatched frame
|
||||
int64_t current_pts_time; // clock time when current_pts was set
|
||||
double previous_pts; // previous decoded frame's pts
|
||||
double previous_pts_diff; // previous decoded frame pts delay
|
||||
double predicted_pts; // predicted pts of next frame
|
||||
double current_pts; // pts of the most recently dispatched frame
|
||||
int64_t current_pts_time; // clock time when current_pts was set
|
||||
int64_t start_pts;
|
||||
|
||||
bool hwaccel_decoder;
|
||||
|
|
@ -62,8 +62,9 @@ struct ff_decoder {
|
|||
typedef struct ff_decoder ff_decoder_t;
|
||||
|
||||
struct ff_decoder *ff_decoder_init(AVCodecContext *codec_context,
|
||||
AVStream *stream, unsigned int packet_queue_size,
|
||||
unsigned int frame_queue_size);
|
||||
AVStream *stream,
|
||||
unsigned int packet_queue_size,
|
||||
unsigned int frame_queue_size);
|
||||
bool ff_decoder_start(struct ff_decoder *decoder);
|
||||
void ff_decoder_free(struct ff_decoder *decoder);
|
||||
|
||||
|
|
@ -76,10 +77,10 @@ void ff_decoder_schedule_refresh(struct ff_decoder *decoder, int delay);
|
|||
void ff_decoder_refresh(void *opaque);
|
||||
|
||||
double ff_decoder_get_best_effort_pts(struct ff_decoder *decoder,
|
||||
AVFrame *frame);
|
||||
AVFrame *frame);
|
||||
|
||||
bool ff_decoder_set_frame_drop_state(struct ff_decoder *decoder,
|
||||
int64_t start_time, int64_t pts);
|
||||
int64_t start_time, int64_t pts);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
|||
148
deps/libff/libff/ff-demuxer.c
vendored
148
deps/libff/libff/ff-demuxer.c
vendored
|
|
@ -43,7 +43,7 @@ struct ff_demuxer *ff_demuxer_init()
|
|||
avdevice_register_all();
|
||||
avfilter_register_all();
|
||||
avformat_network_init();
|
||||
|
||||
|
||||
demuxer = av_mallocz(sizeof(struct ff_demuxer));
|
||||
if (demuxer == NULL)
|
||||
return NULL;
|
||||
|
|
@ -60,7 +60,7 @@ struct ff_demuxer *ff_demuxer_init()
|
|||
}
|
||||
|
||||
bool ff_demuxer_open(struct ff_demuxer *demuxer, char *input,
|
||||
char *input_format)
|
||||
char *input_format)
|
||||
{
|
||||
int ret;
|
||||
|
||||
|
|
@ -69,7 +69,7 @@ bool ff_demuxer_open(struct ff_demuxer *demuxer, char *input,
|
|||
demuxer->input_format = av_strdup(input_format);
|
||||
|
||||
ret = pthread_create(&demuxer->demuxer_thread, NULL, demux_thread,
|
||||
demuxer);
|
||||
demuxer);
|
||||
return ret == 0;
|
||||
}
|
||||
|
||||
|
|
@ -100,12 +100,11 @@ void ff_demuxer_free(struct ff_demuxer *demuxer)
|
|||
}
|
||||
|
||||
void ff_demuxer_set_callbacks(struct ff_callbacks *callbacks,
|
||||
ff_callback_frame frame,
|
||||
ff_callback_format format,
|
||||
ff_callback_initialize initialize,
|
||||
ff_callback_frame frame_initialize,
|
||||
ff_callback_frame frame_free,
|
||||
void *opaque)
|
||||
ff_callback_frame frame,
|
||||
ff_callback_format format,
|
||||
ff_callback_initialize initialize,
|
||||
ff_callback_frame frame_initialize,
|
||||
ff_callback_frame frame_free, void *opaque)
|
||||
{
|
||||
callbacks->opaque = opaque;
|
||||
callbacks->frame = frame;
|
||||
|
|
@ -165,19 +164,18 @@ AVHWAccel *find_hwaccel_codec(AVCodecContext *codec_context)
|
|||
|
||||
while ((hwaccel = av_hwaccel_next(hwaccel)) != NULL) {
|
||||
if (hwaccel->id == codec_context->codec_id &&
|
||||
(hwaccel->pix_fmt == AV_PIX_FMT_VDA_VLD ||
|
||||
(hwaccel->pix_fmt == AV_PIX_FMT_VDA_VLD ||
|
||||
hwaccel->pix_fmt == AV_PIX_FMT_DXVA2_VLD ||
|
||||
hwaccel->pix_fmt == AV_PIX_FMT_VAAPI_VLD)) {
|
||||
return hwaccel;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
enum AVPixelFormat get_hwaccel_format(struct AVCodecContext *s,
|
||||
const enum AVPixelFormat * fmt)
|
||||
const enum AVPixelFormat *fmt)
|
||||
{
|
||||
(void)s;
|
||||
(void)fmt;
|
||||
|
|
@ -187,25 +185,25 @@ enum AVPixelFormat get_hwaccel_format(struct AVCodecContext *s,
|
|||
}
|
||||
|
||||
static bool initialize_decoder(struct ff_demuxer *demuxer,
|
||||
AVCodecContext *codec_context, AVStream *stream,
|
||||
bool hwaccel_decoder)
|
||||
AVCodecContext *codec_context, AVStream *stream,
|
||||
bool hwaccel_decoder)
|
||||
{
|
||||
switch (codec_context->codec_type) {
|
||||
case AVMEDIA_TYPE_AUDIO:
|
||||
demuxer->audio_decoder = ff_decoder_init(
|
||||
codec_context, stream,
|
||||
demuxer->options.audio_packet_queue_size,
|
||||
demuxer->options.audio_frame_queue_size);
|
||||
codec_context, stream,
|
||||
demuxer->options.audio_packet_queue_size,
|
||||
demuxer->options.audio_frame_queue_size);
|
||||
|
||||
demuxer->audio_decoder->hwaccel_decoder = hwaccel_decoder;
|
||||
demuxer->audio_decoder->frame_drop =
|
||||
demuxer->options.frame_drop;
|
||||
demuxer->options.frame_drop;
|
||||
demuxer->audio_decoder->natural_sync_clock =
|
||||
AV_SYNC_AUDIO_MASTER;
|
||||
AV_SYNC_AUDIO_MASTER;
|
||||
demuxer->audio_decoder->callbacks = &demuxer->audio_callbacks;
|
||||
|
||||
if (!ff_callbacks_format(&demuxer->audio_callbacks,
|
||||
codec_context)) {
|
||||
codec_context)) {
|
||||
ff_decoder_free(demuxer->audio_decoder);
|
||||
demuxer->audio_decoder = NULL;
|
||||
return false;
|
||||
|
|
@ -216,19 +214,19 @@ static bool initialize_decoder(struct ff_demuxer *demuxer,
|
|||
|
||||
case AVMEDIA_TYPE_VIDEO:
|
||||
demuxer->video_decoder = ff_decoder_init(
|
||||
codec_context, stream,
|
||||
demuxer->options.video_packet_queue_size,
|
||||
demuxer->options.video_frame_queue_size);
|
||||
codec_context, stream,
|
||||
demuxer->options.video_packet_queue_size,
|
||||
demuxer->options.video_frame_queue_size);
|
||||
|
||||
demuxer->video_decoder->hwaccel_decoder = hwaccel_decoder;
|
||||
demuxer->video_decoder->frame_drop =
|
||||
demuxer->options.frame_drop;
|
||||
demuxer->options.frame_drop;
|
||||
demuxer->video_decoder->natural_sync_clock =
|
||||
AV_SYNC_VIDEO_MASTER;
|
||||
AV_SYNC_VIDEO_MASTER;
|
||||
demuxer->video_decoder->callbacks = &demuxer->video_callbacks;
|
||||
|
||||
if (!ff_callbacks_format(&demuxer->video_callbacks,
|
||||
codec_context)) {
|
||||
codec_context)) {
|
||||
ff_decoder_free(demuxer->video_decoder);
|
||||
demuxer->video_decoder = NULL;
|
||||
return false;
|
||||
|
|
@ -240,8 +238,8 @@ static bool initialize_decoder(struct ff_demuxer *demuxer,
|
|||
}
|
||||
}
|
||||
|
||||
typedef enum AVPixelFormat (*AVGetFormatCb)(
|
||||
struct AVCodecContext *s, const enum AVPixelFormat * fmt);
|
||||
typedef enum AVPixelFormat (*AVGetFormatCb)(struct AVCodecContext *s,
|
||||
const enum AVPixelFormat *fmt);
|
||||
|
||||
static bool find_decoder(struct ff_demuxer *demuxer, AVStream *stream)
|
||||
{
|
||||
|
|
@ -258,10 +256,10 @@ static bool find_decoder(struct ff_demuxer *demuxer, AVStream *stream)
|
|||
codec_context->refcounted_frames = 1;
|
||||
|
||||
// png/tiff decoders have serious issues with multiple threads
|
||||
if (codec_context->codec_id == AV_CODEC_ID_PNG
|
||||
|| codec_context->codec_id == AV_CODEC_ID_TIFF
|
||||
|| codec_context->codec_id == AV_CODEC_ID_JPEG2000
|
||||
|| codec_context->codec_id == AV_CODEC_ID_WEBP)
|
||||
if (codec_context->codec_id == AV_CODEC_ID_PNG ||
|
||||
codec_context->codec_id == AV_CODEC_ID_TIFF ||
|
||||
codec_context->codec_id == AV_CODEC_ID_JPEG2000 ||
|
||||
codec_context->codec_id == AV_CODEC_ID_WEBP)
|
||||
codec_context->thread_count = 1;
|
||||
|
||||
if (demuxer->options.is_hw_decoding) {
|
||||
|
|
@ -269,24 +267,24 @@ static bool find_decoder(struct ff_demuxer *demuxer, AVStream *stream)
|
|||
|
||||
if (hwaccel) {
|
||||
AVCodec *codec_vda =
|
||||
avcodec_find_decoder_by_name(hwaccel->name);
|
||||
avcodec_find_decoder_by_name(hwaccel->name);
|
||||
|
||||
if (codec_vda != NULL) {
|
||||
AVGetFormatCb original_get_format =
|
||||
codec_context->get_format;
|
||||
codec_context->get_format;
|
||||
|
||||
codec_context->get_format = get_hwaccel_format;
|
||||
codec_context->opaque = hwaccel;
|
||||
|
||||
ret = avcodec_open2(codec_context, codec_vda,
|
||||
&options_dict);
|
||||
&options_dict);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_WARNING,
|
||||
"no hardware decoder found for"
|
||||
" codec with id %d",
|
||||
codec_context->codec_id);
|
||||
"no hardware decoder found for"
|
||||
" codec with id %d",
|
||||
codec_context->codec_id);
|
||||
codec_context->get_format =
|
||||
original_get_format;
|
||||
original_get_format;
|
||||
codec_context->opaque = NULL;
|
||||
} else {
|
||||
codec = codec_vda;
|
||||
|
|
@ -305,21 +303,23 @@ static bool find_decoder(struct ff_demuxer *demuxer, AVStream *stream)
|
|||
if (!codec)
|
||||
codec = avcodec_find_decoder(codec_context->codec_id);
|
||||
if (codec == NULL) {
|
||||
av_log(NULL, AV_LOG_WARNING, "no decoder found for"
|
||||
" codec with id %d",
|
||||
codec_context->codec_id);
|
||||
av_log(NULL, AV_LOG_WARNING,
|
||||
"no decoder found for"
|
||||
" codec with id %d",
|
||||
codec_context->codec_id);
|
||||
return false;
|
||||
}
|
||||
if (avcodec_open2(codec_context, codec, &options_dict) < 0) {
|
||||
av_log(NULL, AV_LOG_WARNING, "unable to open decoder"
|
||||
" with codec id %d",
|
||||
codec_context->codec_id);
|
||||
av_log(NULL, AV_LOG_WARNING,
|
||||
"unable to open decoder"
|
||||
" with codec id %d",
|
||||
codec_context->codec_id);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return initialize_decoder(demuxer, codec_context, stream,
|
||||
hwaccel_decoder);
|
||||
hwaccel_decoder);
|
||||
}
|
||||
|
||||
void ff_demuxer_flush(struct ff_demuxer *demuxer)
|
||||
|
|
@ -328,14 +328,14 @@ void ff_demuxer_flush(struct ff_demuxer *demuxer)
|
|||
demuxer->video_decoder->stream != NULL) {
|
||||
packet_queue_flush(&demuxer->video_decoder->packet_queue);
|
||||
packet_queue_put_flush_packet(
|
||||
&demuxer->video_decoder->packet_queue);
|
||||
&demuxer->video_decoder->packet_queue);
|
||||
}
|
||||
|
||||
if (demuxer->audio_decoder != NULL &&
|
||||
demuxer->audio_decoder->stream != NULL) {
|
||||
packet_queue_flush(&demuxer->audio_decoder->packet_queue);
|
||||
packet_queue_put_flush_packet(
|
||||
&demuxer->audio_decoder->packet_queue);
|
||||
&demuxer->audio_decoder->packet_queue);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -352,18 +352,18 @@ void ff_demuxer_reset(struct ff_demuxer *demuxer)
|
|||
if (demuxer->audio_decoder != NULL) {
|
||||
ff_clock_retain(clock);
|
||||
packet_queue_put(&demuxer->audio_decoder->packet_queue,
|
||||
&packet);
|
||||
&packet);
|
||||
}
|
||||
|
||||
if (demuxer->video_decoder != NULL) {
|
||||
ff_clock_retain(clock);
|
||||
packet_queue_put(&demuxer->video_decoder->packet_queue,
|
||||
&packet);
|
||||
&packet);
|
||||
}
|
||||
}
|
||||
|
||||
static bool open_input(struct ff_demuxer *demuxer,
|
||||
AVFormatContext **format_context)
|
||||
AVFormatContext **format_context)
|
||||
{
|
||||
AVInputFormat *input_format = NULL;
|
||||
|
||||
|
|
@ -377,24 +377,25 @@ static bool open_input(struct ff_demuxer *demuxer,
|
|||
if (demuxer->input_format != NULL) {
|
||||
input_format = av_find_input_format(demuxer->input_format);
|
||||
if (input_format == NULL)
|
||||
av_log(NULL, AV_LOG_WARNING, "unable to find input "
|
||||
"format %s",
|
||||
demuxer->input_format);
|
||||
av_log(NULL, AV_LOG_WARNING,
|
||||
"unable to find input "
|
||||
"format %s",
|
||||
demuxer->input_format);
|
||||
}
|
||||
|
||||
if (avformat_open_input(format_context, demuxer->input,
|
||||
input_format, &demuxer->options.custom_options) != 0)
|
||||
if (avformat_open_input(format_context, demuxer->input, input_format,
|
||||
&demuxer->options.custom_options) != 0)
|
||||
return false;
|
||||
|
||||
return avformat_find_stream_info(*format_context, NULL) >= 0;
|
||||
}
|
||||
|
||||
static inline void set_decoder_start_time(struct ff_decoder *decoder,
|
||||
int64_t start_time)
|
||||
int64_t start_time)
|
||||
{
|
||||
if (decoder)
|
||||
decoder->start_pts = av_rescale_q(start_time, AV_TIME_BASE_Q,
|
||||
decoder->stream->time_base);
|
||||
decoder->stream->time_base);
|
||||
}
|
||||
|
||||
static bool find_and_initialize_stream_decoders(struct ff_demuxer *demuxer)
|
||||
|
|
@ -415,12 +416,12 @@ static bool find_and_initialize_stream_decoders(struct ff_demuxer *demuxer)
|
|||
audio_stream = format_context->streams[i];
|
||||
}
|
||||
|
||||
int default_stream_index = av_find_default_stream_index(
|
||||
demuxer->format_context);
|
||||
int default_stream_index =
|
||||
av_find_default_stream_index(demuxer->format_context);
|
||||
|
||||
if (default_stream_index >= 0) {
|
||||
AVStream *stream =
|
||||
format_context->streams[default_stream_index];
|
||||
format_context->streams[default_stream_index];
|
||||
|
||||
if (stream->codec->codec_type == AVMEDIA_TYPE_AUDIO)
|
||||
demuxer->clock.sync_type = AV_SYNC_AUDIO_MASTER;
|
||||
|
|
@ -452,7 +453,7 @@ static bool find_and_initialize_stream_decoders(struct ff_demuxer *demuxer)
|
|||
}
|
||||
|
||||
st_start_time = av_rescale_q(st->start_time, st->time_base,
|
||||
AV_TIME_BASE_Q);
|
||||
AV_TIME_BASE_Q);
|
||||
start_time = FFMIN(start_time, st_start_time);
|
||||
}
|
||||
|
||||
|
|
@ -508,18 +509,17 @@ static bool handle_seek(struct ff_demuxer *demuxer)
|
|||
seek_stream = demuxer->audio_decoder->stream;
|
||||
}
|
||||
|
||||
if (seek_stream != NULL && demuxer->format_context->duration != AV_NOPTS_VALUE) {
|
||||
seek_target = av_rescale_q(seek_target,
|
||||
AV_TIME_BASE_Q,
|
||||
seek_stream->time_base);
|
||||
if (seek_stream != NULL &&
|
||||
demuxer->format_context->duration != AV_NOPTS_VALUE) {
|
||||
seek_target = av_rescale_q(seek_target, AV_TIME_BASE_Q,
|
||||
seek_stream->time_base);
|
||||
}
|
||||
|
||||
ret = av_seek_frame(demuxer->format_context,
|
||||
0, seek_target,
|
||||
demuxer->seek_flags);
|
||||
ret = av_seek_frame(demuxer->format_context, 0, seek_target,
|
||||
demuxer->seek_flags);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "unable to seek stream: %s",
|
||||
av_err2str(ret));
|
||||
av_err2str(ret));
|
||||
demuxer->seek_pos = 0;
|
||||
demuxer->seek_request = false;
|
||||
return false;
|
||||
|
|
@ -551,7 +551,7 @@ static void seek_beginning(struct ff_demuxer *demuxer)
|
|||
|
||||
static void *demux_thread(void *opaque)
|
||||
{
|
||||
struct ff_demuxer *demuxer = (struct ff_demuxer *) opaque;
|
||||
struct ff_demuxer *demuxer = (struct ff_demuxer *)opaque;
|
||||
int result;
|
||||
|
||||
struct ff_packet packet = {0};
|
||||
|
|
@ -584,7 +584,7 @@ static void *demux_thread(void *opaque)
|
|||
eof = true;
|
||||
} else if (demuxer->format_context->pb != NULL) {
|
||||
AVIOContext *io_context =
|
||||
demuxer->format_context->pb;
|
||||
demuxer->format_context->pb;
|
||||
if (io_context->error == 0) {
|
||||
av_usleep(100 * 1000); // 100ms
|
||||
continue;
|
||||
|
|
@ -603,8 +603,8 @@ static void *demux_thread(void *opaque)
|
|||
continue;
|
||||
} else {
|
||||
av_log(NULL, AV_LOG_ERROR,
|
||||
"av_read_frame() failed: %s",
|
||||
av_err2str(result));
|
||||
"av_read_frame() failed: %s",
|
||||
av_err2str(result));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
17
deps/libff/libff/ff-demuxer.h
vendored
17
deps/libff/libff/ff-demuxer.h
vendored
|
|
@ -31,8 +31,7 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct ff_demuxer_options
|
||||
{
|
||||
struct ff_demuxer_options {
|
||||
int audio_packet_queue_size;
|
||||
int video_packet_queue_size;
|
||||
int audio_frame_queue_size;
|
||||
|
|
@ -75,16 +74,16 @@ struct ff_demuxer {
|
|||
typedef struct ff_demuxer ff_demuxer_t;
|
||||
|
||||
struct ff_demuxer *ff_demuxer_init();
|
||||
bool ff_demuxer_open(struct ff_demuxer *demuxer, char *input, char *input_format);
|
||||
bool ff_demuxer_open(struct ff_demuxer *demuxer, char *input,
|
||||
char *input_format);
|
||||
void ff_demuxer_free(struct ff_demuxer *demuxer);
|
||||
|
||||
void ff_demuxer_set_callbacks(struct ff_callbacks *callbacks,
|
||||
ff_callback_frame frame,
|
||||
ff_callback_format format,
|
||||
ff_callback_initialize initialize,
|
||||
ff_callback_frame frame_initialize,
|
||||
ff_callback_frame frame_free,
|
||||
void *opaque);
|
||||
ff_callback_frame frame,
|
||||
ff_callback_format format,
|
||||
ff_callback_initialize initialize,
|
||||
ff_callback_frame frame_initialize,
|
||||
ff_callback_frame frame_free, void *opaque);
|
||||
|
||||
void ff_demuxer_flush(struct ff_demuxer *demuxer);
|
||||
|
||||
|
|
|
|||
5
deps/libff/libff/ff-packet-queue.c
vendored
5
deps/libff/libff/ff-packet-queue.c
vendored
|
|
@ -36,7 +36,6 @@ fail1:
|
|||
pthread_mutex_destroy(&q->mutex);
|
||||
fail:
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
void packet_queue_abort(struct ff_packet_queue *q)
|
||||
|
|
@ -93,7 +92,7 @@ int packet_queue_put_flush_packet(struct ff_packet_queue *q)
|
|||
}
|
||||
|
||||
int packet_queue_get(struct ff_packet_queue *q, struct ff_packet *packet,
|
||||
bool block)
|
||||
bool block)
|
||||
{
|
||||
struct ff_packet_list *potential_packet;
|
||||
int return_status;
|
||||
|
|
@ -141,7 +140,7 @@ void packet_queue_flush(struct ff_packet_queue *q)
|
|||
pthread_mutex_lock(&q->mutex);
|
||||
|
||||
for (packet = q->first_packet; packet != NULL;
|
||||
packet = q->first_packet) {
|
||||
packet = q->first_packet) {
|
||||
q->first_packet = packet->next;
|
||||
av_free_packet(&packet->packet.base);
|
||||
if (packet->packet.clock != NULL)
|
||||
|
|
|
|||
6
deps/libff/libff/ff-packet-queue.h
vendored
6
deps/libff/libff/ff-packet-queue.h
vendored
|
|
@ -36,8 +36,8 @@ struct ff_packet {
|
|||
};
|
||||
|
||||
struct ff_packet_list {
|
||||
struct ff_packet packet;
|
||||
struct ff_packet_list *next;
|
||||
struct ff_packet packet;
|
||||
struct ff_packet_list *next;
|
||||
};
|
||||
|
||||
struct ff_packet_queue {
|
||||
|
|
@ -59,7 +59,7 @@ void packet_queue_free(struct ff_packet_queue *q);
|
|||
int packet_queue_put(struct ff_packet_queue *q, struct ff_packet *packet);
|
||||
int packet_queue_put_flush_packet(struct ff_packet_queue *q);
|
||||
int packet_queue_get(struct ff_packet_queue *q, struct ff_packet *packet,
|
||||
bool block);
|
||||
bool block);
|
||||
|
||||
void packet_queue_flush(struct ff_packet_queue *q);
|
||||
|
||||
|
|
|
|||
22
deps/libff/libff/ff-timer.c
vendored
22
deps/libff/libff/ff-timer.c
vendored
|
|
@ -38,17 +38,16 @@ static void *timer_thread(void *opaque)
|
|||
uint64_t current_time = av_gettime();
|
||||
if (current_time < timer->next_wake) {
|
||||
struct timespec sleep_time = {
|
||||
.tv_sec = timer->next_wake / AV_TIME_BASE,
|
||||
.tv_nsec = (timer->next_wake % AV_TIME_BASE)
|
||||
* 1000
|
||||
};
|
||||
.tv_sec = timer->next_wake / AV_TIME_BASE,
|
||||
.tv_nsec = (timer->next_wake % AV_TIME_BASE) *
|
||||
1000};
|
||||
|
||||
ret = pthread_cond_timedwait(&timer->cond,
|
||||
&timer->mutex, &sleep_time);
|
||||
ret = pthread_cond_timedwait(
|
||||
&timer->cond, &timer->mutex, &sleep_time);
|
||||
if (ret != ETIMEDOUT) {
|
||||
// failed to wait, just sleep
|
||||
av_usleep((unsigned)(timer->next_wake
|
||||
- current_time));
|
||||
av_usleep((unsigned)(timer->next_wake -
|
||||
current_time));
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&timer->mutex);
|
||||
|
|
@ -78,7 +77,7 @@ static void *timer_thread(void *opaque)
|
|||
}
|
||||
|
||||
bool ff_timer_init(struct ff_timer *timer, ff_timer_callback callback,
|
||||
void *opaque)
|
||||
void *opaque)
|
||||
{
|
||||
memset(timer, 0, sizeof(struct ff_timer));
|
||||
timer->abort = false;
|
||||
|
|
@ -88,14 +87,15 @@ bool ff_timer_init(struct ff_timer *timer, ff_timer_callback callback,
|
|||
if (pthread_mutexattr_init(&timer->mutexattr) != 0)
|
||||
goto fail;
|
||||
if (pthread_mutexattr_settype(&timer->mutexattr,
|
||||
PTHREAD_MUTEX_RECURSIVE))
|
||||
PTHREAD_MUTEX_RECURSIVE))
|
||||
goto fail1;
|
||||
if (pthread_mutex_init(&timer->mutex, &timer->mutexattr) != 0)
|
||||
goto fail1;
|
||||
if (pthread_cond_init(&timer->cond, NULL) != 0)
|
||||
goto fail2;
|
||||
|
||||
if (pthread_create(&timer->timer_thread, NULL, timer_thread, timer) != 0)
|
||||
if (pthread_create(&timer->timer_thread, NULL, timer_thread, timer) !=
|
||||
0)
|
||||
goto fail3;
|
||||
|
||||
return true;
|
||||
|
|
|
|||
4
deps/libff/libff/ff-timer.h
vendored
4
deps/libff/libff/ff-timer.h
vendored
|
|
@ -43,8 +43,8 @@ struct ff_timer {
|
|||
|
||||
typedef struct ff_timer ff_timer_t;
|
||||
|
||||
bool ff_timer_init(struct ff_timer *timer,
|
||||
ff_timer_callback callback, void *opaque);
|
||||
bool ff_timer_init(struct ff_timer *timer, ff_timer_callback callback,
|
||||
void *opaque);
|
||||
void ff_timer_free(struct ff_timer *timer);
|
||||
void ff_timer_schedule(struct ff_timer *timer, uint64_t microseconds);
|
||||
|
||||
|
|
|
|||
115
deps/libff/libff/ff-util.c
vendored
115
deps/libff/libff/ff-util.c
vendored
|
|
@ -40,7 +40,7 @@ struct ff_format_desc {
|
|||
const char *extensions;
|
||||
enum AVCodecID audio_codec;
|
||||
enum AVCodecID video_codec;
|
||||
const struct AVCodecTag * const *codec_tags;
|
||||
const struct AVCodecTag *const *codec_tags;
|
||||
const struct ff_format_desc *next;
|
||||
};
|
||||
|
||||
|
|
@ -56,9 +56,11 @@ struct ff_codec_desc {
|
|||
|
||||
void ff_init()
|
||||
{
|
||||
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58, 9, 100)
|
||||
av_register_all();
|
||||
//avdevice_register_all();
|
||||
avcodec_register_all();
|
||||
#endif
|
||||
avformat_network_init();
|
||||
}
|
||||
|
||||
|
|
@ -71,7 +73,7 @@ const char *ff_codec_name_from_id(int codec_id)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static bool get_codecs(const AVCodecDescriptor*** descs, unsigned int *size)
|
||||
static bool get_codecs(const AVCodecDescriptor ***descs, unsigned int *size)
|
||||
{
|
||||
const AVCodecDescriptor *desc = NULL;
|
||||
const AVCodecDescriptor **codecs;
|
||||
|
|
@ -84,8 +86,10 @@ static bool get_codecs(const AVCodecDescriptor*** descs, unsigned int *size)
|
|||
codecs = av_calloc(codec_count, sizeof(AVCodecDescriptor *));
|
||||
|
||||
if (codecs == NULL) {
|
||||
av_log(NULL, AV_LOG_ERROR, "unable to allocate sorted codec "
|
||||
"array with size %d", codec_count);
|
||||
av_log(NULL, AV_LOG_ERROR,
|
||||
"unable to allocate sorted codec "
|
||||
"array with size %d",
|
||||
codec_count);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -99,18 +103,37 @@ static bool get_codecs(const AVCodecDescriptor*** descs, unsigned int *size)
|
|||
|
||||
static const AVCodec *next_codec_for_id(enum AVCodecID id, const AVCodec *prev)
|
||||
{
|
||||
while ((prev = av_codec_next(prev)) != NULL) {
|
||||
if (prev->id == id && av_codec_is_encoder(prev))
|
||||
return prev;
|
||||
}
|
||||
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(58, 9, 100)
|
||||
const AVCodec *cur = NULL;
|
||||
void *i = 0;
|
||||
bool found_prev = false;
|
||||
|
||||
return NULL;
|
||||
while ((cur = av_codec_iterate(&i)) != NULL) {
|
||||
if (cur->id == id && av_codec_is_encoder(cur)) {
|
||||
if (!prev) {
|
||||
return cur;
|
||||
} else if (!found_prev) {
|
||||
if (cur == prev) {
|
||||
found_prev = true;
|
||||
}
|
||||
} else {
|
||||
return cur;
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
while ((prev = av_codec_next(prev)) != NULL) {
|
||||
if (prev->id == id && av_codec_is_encoder(prev))
|
||||
return prev;
|
||||
}
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void add_codec_to_list(const struct ff_format_desc *format_desc,
|
||||
struct ff_codec_desc **first, struct ff_codec_desc **current,
|
||||
enum AVCodecID id, const AVCodec *codec,
|
||||
bool ignore_compatability)
|
||||
struct ff_codec_desc **first,
|
||||
struct ff_codec_desc **current, enum AVCodecID id,
|
||||
const AVCodec *codec, bool ignore_compatability)
|
||||
{
|
||||
if (codec == NULL)
|
||||
codec = avcodec_find_encoder(id);
|
||||
|
|
@ -125,8 +148,8 @@ static void add_codec_to_list(const struct ff_format_desc *format_desc,
|
|||
|
||||
if (!ignore_compatability) {
|
||||
// Format doesn't support this codec
|
||||
unsigned int tag = av_codec_get_tag(format_desc->codec_tags,
|
||||
codec->id);
|
||||
unsigned int tag =
|
||||
av_codec_get_tag(format_desc->codec_tags, codec->id);
|
||||
if (tag == 0)
|
||||
return;
|
||||
}
|
||||
|
|
@ -162,18 +185,19 @@ static void add_codec_to_list(const struct ff_format_desc *format_desc,
|
|||
}
|
||||
|
||||
static void get_codecs_for_id(const struct ff_format_desc *format_desc,
|
||||
struct ff_codec_desc **first, struct ff_codec_desc **current,
|
||||
enum AVCodecID id, bool ignore_compatability)
|
||||
struct ff_codec_desc **first,
|
||||
struct ff_codec_desc **current, enum AVCodecID id,
|
||||
bool ignore_compatability)
|
||||
{
|
||||
const AVCodec *codec = NULL;
|
||||
while ((codec = next_codec_for_id(id, codec)) != NULL)
|
||||
add_codec_to_list(format_desc, first, current, codec->id,
|
||||
codec, ignore_compatability);
|
||||
add_codec_to_list(format_desc, first, current, codec->id, codec,
|
||||
ignore_compatability);
|
||||
}
|
||||
|
||||
const struct ff_codec_desc *ff_codec_supported(
|
||||
const struct ff_format_desc *format_desc,
|
||||
bool ignore_compatability)
|
||||
const struct ff_codec_desc *
|
||||
ff_codec_supported(const struct ff_format_desc *format_desc,
|
||||
bool ignore_compatability)
|
||||
{
|
||||
const AVCodecDescriptor **codecs;
|
||||
unsigned int size;
|
||||
|
|
@ -184,10 +208,10 @@ const struct ff_codec_desc *ff_codec_supported(
|
|||
if (!get_codecs(&codecs, &size))
|
||||
return NULL;
|
||||
|
||||
for(i = 0; i < size; i++) {
|
||||
for (i = 0; i < size; i++) {
|
||||
const AVCodecDescriptor *codec = codecs[i];
|
||||
get_codecs_for_id(format_desc, &first, ¤t, codec->id,
|
||||
ignore_compatability);
|
||||
ignore_compatability);
|
||||
}
|
||||
|
||||
av_free((void *)codecs);
|
||||
|
|
@ -235,8 +259,8 @@ enum ff_codec_type ff_codec_desc_type(const struct ff_codec_desc *codec_desc)
|
|||
return FF_CODEC_UNKNOWN;
|
||||
}
|
||||
|
||||
const struct ff_codec_desc *ff_codec_desc_next(
|
||||
const struct ff_codec_desc *codec_desc)
|
||||
const struct ff_codec_desc *
|
||||
ff_codec_desc_next(const struct ff_codec_desc *codec_desc)
|
||||
{
|
||||
if (codec_desc != NULL)
|
||||
return codec_desc->next;
|
||||
|
|
@ -255,7 +279,7 @@ int ff_codec_desc_id(const struct ff_codec_desc *codec_desc)
|
|||
void ff_codec_desc_free(const struct ff_codec_desc *codec_desc)
|
||||
{
|
||||
const struct ff_codec_desc *desc = codec_desc;
|
||||
while(desc != NULL) {
|
||||
while (desc != NULL) {
|
||||
const struct ff_codec_desc *next = desc->next;
|
||||
av_free((void *)desc);
|
||||
desc = next;
|
||||
|
|
@ -283,11 +307,17 @@ static inline bool is_output_device(const AVClass *avclass)
|
|||
|
||||
const struct ff_format_desc *ff_format_supported()
|
||||
{
|
||||
AVOutputFormat *output_format = NULL;
|
||||
const AVOutputFormat *output_format = NULL;
|
||||
struct ff_format_desc *desc = NULL;
|
||||
struct ff_format_desc *current = NULL;
|
||||
|
||||
#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(58, 9, 100)
|
||||
void *i = 0;
|
||||
|
||||
while ((output_format = av_muxer_iterate(&i)) != NULL) {
|
||||
#else
|
||||
while ((output_format = av_oformat_next(output_format)) != NULL) {
|
||||
#endif
|
||||
struct ff_format_desc *d;
|
||||
if (is_output_device(output_format->priv_class))
|
||||
continue;
|
||||
|
|
@ -377,8 +407,8 @@ int ff_format_desc_video(const struct ff_format_desc *format_desc)
|
|||
return false;
|
||||
}
|
||||
|
||||
const struct ff_format_desc *ff_format_desc_next(
|
||||
const struct ff_format_desc *format_desc)
|
||||
const struct ff_format_desc *
|
||||
ff_format_desc_next(const struct ff_format_desc *format_desc)
|
||||
{
|
||||
if (format_desc != NULL)
|
||||
return format_desc->next;
|
||||
|
|
@ -387,7 +417,7 @@ const struct ff_format_desc *ff_format_desc_next(
|
|||
}
|
||||
|
||||
static const char *get_encoder_name(const struct ff_format_desc *format_desc,
|
||||
enum AVCodecID codec_id)
|
||||
enum AVCodecID codec_id)
|
||||
{
|
||||
AVCodec *codec = avcodec_find_encoder(codec_id);
|
||||
if (codec == NULL && codec_id == AV_CODEC_ID_NONE)
|
||||
|
|
@ -398,27 +428,24 @@ static const char *get_encoder_name(const struct ff_format_desc *format_desc,
|
|||
return codec->name;
|
||||
}
|
||||
|
||||
const char *ff_format_desc_get_default_name(
|
||||
const struct ff_format_desc *format_desc,
|
||||
enum ff_codec_type codec_type)
|
||||
const char *
|
||||
ff_format_desc_get_default_name(const struct ff_format_desc *format_desc,
|
||||
enum ff_codec_type codec_type)
|
||||
{
|
||||
switch (codec_type)
|
||||
{
|
||||
case FF_CODEC_AUDIO:
|
||||
return get_encoder_name(format_desc,
|
||||
format_desc->audio_codec);
|
||||
case FF_CODEC_VIDEO:
|
||||
return get_encoder_name(format_desc,
|
||||
format_desc->video_codec);
|
||||
default:
|
||||
return NULL;
|
||||
switch (codec_type) {
|
||||
case FF_CODEC_AUDIO:
|
||||
return get_encoder_name(format_desc, format_desc->audio_codec);
|
||||
case FF_CODEC_VIDEO:
|
||||
return get_encoder_name(format_desc, format_desc->video_codec);
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void ff_format_desc_free(const struct ff_format_desc *format_desc)
|
||||
{
|
||||
const struct ff_format_desc *desc = format_desc;
|
||||
while(desc != NULL) {
|
||||
while (desc != NULL) {
|
||||
const struct ff_format_desc *next = desc->next;
|
||||
av_free((void *)desc);
|
||||
desc = next;
|
||||
|
|
|
|||
26
deps/libff/libff/ff-util.h
vendored
26
deps/libff/libff/ff-util.h
vendored
|
|
@ -22,11 +22,7 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum ff_codec_type {
|
||||
FF_CODEC_AUDIO,
|
||||
FF_CODEC_VIDEO,
|
||||
FF_CODEC_UNKNOWN
|
||||
};
|
||||
enum ff_codec_type { FF_CODEC_AUDIO, FF_CODEC_VIDEO, FF_CODEC_UNKNOWN };
|
||||
|
||||
struct ff_format_desc;
|
||||
struct ff_codec_desc;
|
||||
|
|
@ -36,9 +32,9 @@ void ff_init();
|
|||
const char *ff_codec_name_from_id(int codec_id);
|
||||
|
||||
// Codec Description
|
||||
const struct ff_codec_desc *ff_codec_supported(
|
||||
const struct ff_format_desc *format_desc,
|
||||
bool ignore_compatability);
|
||||
const struct ff_codec_desc *
|
||||
ff_codec_supported(const struct ff_format_desc *format_desc,
|
||||
bool ignore_compatability);
|
||||
void ff_codec_desc_free(const struct ff_codec_desc *codec_desc);
|
||||
const char *ff_codec_desc_name(const struct ff_codec_desc *codec_desc);
|
||||
const char *ff_codec_desc_long_name(const struct ff_codec_desc *codec_desc);
|
||||
|
|
@ -46,8 +42,8 @@ enum ff_codec_type ff_codec_desc_type(const struct ff_codec_desc *codec_desc);
|
|||
bool ff_codec_desc_is_alias(const struct ff_codec_desc *codec_desc);
|
||||
const char *ff_codec_desc_base_name(const struct ff_codec_desc *codec_desc);
|
||||
int ff_codec_desc_id(const struct ff_codec_desc *codec_desc);
|
||||
const struct ff_codec_desc *ff_codec_desc_next(
|
||||
const struct ff_codec_desc *codec_desc);
|
||||
const struct ff_codec_desc *
|
||||
ff_codec_desc_next(const struct ff_codec_desc *codec_desc);
|
||||
|
||||
// Format Description
|
||||
const struct ff_format_desc *ff_format_supported();
|
||||
|
|
@ -60,11 +56,11 @@ bool ff_format_desc_has_audio(const struct ff_format_desc *format_desc);
|
|||
bool ff_format_desc_has_video(const struct ff_format_desc *format_desc);
|
||||
int ff_format_desc_audio(const struct ff_format_desc *format_desc);
|
||||
int ff_format_desc_video(const struct ff_format_desc *format_desc);
|
||||
const char *ff_format_desc_get_default_name(
|
||||
const struct ff_format_desc *format_desc,
|
||||
enum ff_codec_type codec_type);
|
||||
const struct ff_format_desc *ff_format_desc_next(
|
||||
const struct ff_format_desc *format_desc);
|
||||
const char *
|
||||
ff_format_desc_get_default_name(const struct ff_format_desc *format_desc,
|
||||
enum ff_codec_type codec_type);
|
||||
const struct ff_format_desc *
|
||||
ff_format_desc_next(const struct ff_format_desc *format_desc);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
|||
31
deps/libff/libff/ff-video-decoder.c
vendored
31
deps/libff/libff/ff-video-decoder.c
vendored
|
|
@ -30,7 +30,7 @@
|
|||
#include "ff-compat.h"
|
||||
|
||||
static bool queue_frame(struct ff_decoder *decoder, AVFrame *frame,
|
||||
double best_effort_pts)
|
||||
double best_effort_pts)
|
||||
{
|
||||
struct ff_frame *queue_frame;
|
||||
bool call_initialize;
|
||||
|
|
@ -46,10 +46,10 @@ static bool queue_frame(struct ff_decoder *decoder, AVFrame *frame,
|
|||
// Check if we need to communicate a different format has been received
|
||||
// to any callbacks
|
||||
AVCodecContext *codec = decoder->codec;
|
||||
call_initialize = (queue_frame->frame == NULL
|
||||
|| queue_frame->frame->width != codec->width
|
||||
|| queue_frame->frame->height != codec->height
|
||||
|| queue_frame->frame->format != codec->pix_fmt);
|
||||
call_initialize = (queue_frame->frame == NULL ||
|
||||
queue_frame->frame->width != codec->width ||
|
||||
queue_frame->frame->height != codec->height ||
|
||||
queue_frame->frame->format != codec->pix_fmt);
|
||||
|
||||
if (queue_frame->frame != NULL) {
|
||||
// This shouldn't happen any more, the frames are freed in
|
||||
|
|
@ -72,7 +72,7 @@ static bool queue_frame(struct ff_decoder *decoder, AVFrame *frame,
|
|||
|
||||
void *ff_video_decoder_thread(void *opaque_video_decoder)
|
||||
{
|
||||
struct ff_decoder *decoder = (struct ff_decoder*)opaque_video_decoder;
|
||||
struct ff_decoder *decoder = (struct ff_decoder *)opaque_video_decoder;
|
||||
|
||||
struct ff_packet packet = {0};
|
||||
int complete;
|
||||
|
|
@ -82,16 +82,19 @@ void *ff_video_decoder_thread(void *opaque_video_decoder)
|
|||
|
||||
while (!decoder->abort) {
|
||||
if (decoder->eof)
|
||||
ret = packet_queue_get(&decoder->packet_queue, &packet, 0);
|
||||
ret = packet_queue_get(&decoder->packet_queue, &packet,
|
||||
0);
|
||||
else
|
||||
ret = packet_queue_get(&decoder->packet_queue, &packet, 1);
|
||||
ret = packet_queue_get(&decoder->packet_queue, &packet,
|
||||
1);
|
||||
|
||||
if (ret == FF_PACKET_EMPTY || ret == FF_PACKET_FAIL) {
|
||||
// should we just use abort here?
|
||||
break;
|
||||
}
|
||||
|
||||
if (packet.base.data == decoder->packet_queue.flush_packet.base.data) {
|
||||
if (packet.base.data ==
|
||||
decoder->packet_queue.flush_packet.base.data) {
|
||||
avcodec_flush_buffers(decoder->codec);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -116,11 +119,11 @@ void *ff_video_decoder_thread(void *opaque_video_decoder)
|
|||
frame_drop_check &= start_time != AV_NOPTS_VALUE;
|
||||
|
||||
if (frame_drop_check)
|
||||
ff_decoder_set_frame_drop_state(decoder,
|
||||
start_time, packet.base.pts);
|
||||
ff_decoder_set_frame_drop_state(decoder, start_time,
|
||||
packet.base.pts);
|
||||
|
||||
avcodec_decode_video2(decoder->codec, frame,
|
||||
&complete, &packet.base);
|
||||
avcodec_decode_video2(decoder->codec, frame, &complete,
|
||||
&packet.base);
|
||||
|
||||
// Did we get an entire video frame? This doesn't guarantee
|
||||
// there is a picture to show for some codecs, but we still want
|
||||
|
|
@ -131,7 +134,7 @@ void *ff_video_decoder_thread(void *opaque_video_decoder)
|
|||
// This function returns a pts scaled to stream
|
||||
// time base
|
||||
double best_effort_pts =
|
||||
ff_decoder_get_best_effort_pts(decoder, frame);
|
||||
ff_decoder_get_best_effort_pts(decoder, frame);
|
||||
|
||||
queue_frame(decoder, frame, best_effort_pts);
|
||||
av_frame_unref(frame);
|
||||
|
|
|
|||
1
deps/media-playback/CMakeLists.txt
vendored
1
deps/media-playback/CMakeLists.txt
vendored
|
|
@ -9,6 +9,7 @@ include_directories(
|
|||
)
|
||||
|
||||
set(media-playback_HEADERS
|
||||
media-playback/closest-format.h
|
||||
media-playback/decode.h
|
||||
media-playback/media.h
|
||||
)
|
||||
|
|
|
|||
|
|
@ -61,6 +61,15 @@ static enum AVPixelFormat closest_format(enum AVPixelFormat fmt)
|
|||
case AV_PIX_FMT_YUV420P14LE:
|
||||
return AV_PIX_FMT_YUV420P;
|
||||
|
||||
case AV_PIX_FMT_YUVA420P:
|
||||
return AV_PIX_FMT_YUVA420P;
|
||||
|
||||
case AV_PIX_FMT_YUVA422P:
|
||||
return AV_PIX_FMT_YUVA422P;
|
||||
|
||||
case AV_PIX_FMT_YUVA444P:
|
||||
return AV_PIX_FMT_YUVA444P;
|
||||
|
||||
case AV_PIX_FMT_RGBA:
|
||||
case AV_PIX_FMT_BGRA:
|
||||
case AV_PIX_FMT_BGR0:
|
||||
|
|
|
|||
235
deps/media-playback/media-playback/decode.c
vendored
235
deps/media-playback/media-playback/decode.c
vendored
|
|
@ -17,29 +17,62 @@
|
|||
#include "decode.h"
|
||||
#include "media.h"
|
||||
|
||||
static AVCodec *find_hardware_decoder(enum AVCodecID id)
|
||||
{
|
||||
AVHWAccel *hwa = av_hwaccel_next(NULL);
|
||||
AVCodec *c = NULL;
|
||||
#if LIBAVCODEC_VERSION_INT > AV_VERSION_INT(58, 4, 100)
|
||||
#define USE_NEW_HARDWARE_CODEC_METHOD
|
||||
#endif
|
||||
|
||||
while (hwa) {
|
||||
if (hwa->id == id) {
|
||||
if (hwa->pix_fmt == AV_PIX_FMT_VDTOOL ||
|
||||
hwa->pix_fmt == AV_PIX_FMT_DXVA2_VLD ||
|
||||
hwa->pix_fmt == AV_PIX_FMT_VAAPI_VLD) {
|
||||
c = avcodec_find_decoder_by_name(hwa->name);
|
||||
if (c)
|
||||
break;
|
||||
}
|
||||
#ifdef USE_NEW_HARDWARE_CODEC_METHOD
|
||||
enum AVHWDeviceType hw_priority[] = {
|
||||
AV_HWDEVICE_TYPE_D3D11VA, AV_HWDEVICE_TYPE_DXVA2,
|
||||
AV_HWDEVICE_TYPE_VAAPI, AV_HWDEVICE_TYPE_VDPAU,
|
||||
AV_HWDEVICE_TYPE_QSV, AV_HWDEVICE_TYPE_NONE,
|
||||
};
|
||||
|
||||
static bool has_hw_type(AVCodec *c, enum AVHWDeviceType type,
|
||||
enum AVPixelFormat *hw_format)
|
||||
{
|
||||
for (int i = 0;; i++) {
|
||||
const AVCodecHWConfig *config = avcodec_get_hw_config(c, i);
|
||||
if (!config) {
|
||||
break;
|
||||
}
|
||||
|
||||
hwa = av_hwaccel_next(hwa);
|
||||
if (config->methods & AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX &&
|
||||
config->device_type == type) {
|
||||
*hw_format = config->pix_fmt;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return c;
|
||||
return false;
|
||||
}
|
||||
|
||||
static int mp_open_codec(struct mp_decode *d)
|
||||
static void init_hw_decoder(struct mp_decode *d, AVCodecContext *c)
|
||||
{
|
||||
enum AVHWDeviceType *priority = hw_priority;
|
||||
AVBufferRef *hw_ctx = NULL;
|
||||
|
||||
while (*priority != AV_HWDEVICE_TYPE_NONE) {
|
||||
if (has_hw_type(d->codec, *priority, &d->hw_format)) {
|
||||
int ret = av_hwdevice_ctx_create(&hw_ctx, *priority,
|
||||
NULL, NULL, 0);
|
||||
if (ret == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
priority++;
|
||||
}
|
||||
|
||||
if (hw_ctx) {
|
||||
c->hw_device_ctx = av_buffer_ref(hw_ctx);
|
||||
c->opaque = d;
|
||||
d->hw_ctx = hw_ctx;
|
||||
d->hw = true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static int mp_open_codec(struct mp_decode *d, bool hw)
|
||||
{
|
||||
AVCodecContext *c;
|
||||
int ret;
|
||||
|
|
@ -58,12 +91,17 @@ static int mp_open_codec(struct mp_decode *d)
|
|||
c = d->stream->codec;
|
||||
#endif
|
||||
|
||||
if (c->thread_count == 1 &&
|
||||
c->codec_id != AV_CODEC_ID_PNG &&
|
||||
d->hw = false;
|
||||
|
||||
#ifdef USE_NEW_HARDWARE_CODEC_METHOD
|
||||
if (hw)
|
||||
init_hw_decoder(d, c);
|
||||
#endif
|
||||
|
||||
if (c->thread_count == 1 && c->codec_id != AV_CODEC_ID_PNG &&
|
||||
c->codec_id != AV_CODEC_ID_TIFF &&
|
||||
c->codec_id != AV_CODEC_ID_JPEG2000 &&
|
||||
c->codec_id != AV_CODEC_ID_MPEG4 &&
|
||||
c->codec_id != AV_CODEC_ID_WEBP)
|
||||
c->codec_id != AV_CODEC_ID_MPEG4 && c->codec_id != AV_CODEC_ID_WEBP)
|
||||
c->thread_count = 0;
|
||||
|
||||
ret = avcodec_open2(c, d->codec, NULL);
|
||||
|
|
@ -103,45 +141,54 @@ bool mp_decode_init(mp_media_t *m, enum AVMediaType type, bool hw)
|
|||
id = stream->codec->codec_id;
|
||||
#endif
|
||||
|
||||
if (hw) {
|
||||
d->codec = find_hardware_decoder(id);
|
||||
if (d->codec) {
|
||||
ret = mp_open_codec(d);
|
||||
if (ret < 0)
|
||||
d->codec = NULL;
|
||||
if (id == AV_CODEC_ID_VP8 || id == AV_CODEC_ID_VP9) {
|
||||
AVDictionaryEntry *tag = NULL;
|
||||
tag = av_dict_get(stream->metadata, "alpha_mode", tag,
|
||||
AV_DICT_IGNORE_SUFFIX);
|
||||
|
||||
if (tag && strcmp(tag->value, "1") == 0) {
|
||||
char *codec = (id == AV_CODEC_ID_VP8) ? "libvpx"
|
||||
: "libvpx-vp9";
|
||||
d->codec = avcodec_find_decoder_by_name(codec);
|
||||
}
|
||||
}
|
||||
|
||||
if (!d->codec)
|
||||
d->codec = avcodec_find_decoder(id);
|
||||
|
||||
if (!d->codec) {
|
||||
if (id == AV_CODEC_ID_VP8)
|
||||
d->codec = avcodec_find_decoder_by_name("libvpx");
|
||||
else if (id == AV_CODEC_ID_VP9)
|
||||
d->codec = avcodec_find_decoder_by_name("libvpx-vp9");
|
||||
|
||||
if (!d->codec)
|
||||
d->codec = avcodec_find_decoder(id);
|
||||
if (!d->codec) {
|
||||
blog(LOG_WARNING, "MP: Failed to find %s codec",
|
||||
av_get_media_type_string(type));
|
||||
return false;
|
||||
}
|
||||
|
||||
ret = mp_open_codec(d);
|
||||
if (ret < 0) {
|
||||
blog(LOG_WARNING, "MP: Failed to open %s decoder: %s",
|
||||
av_get_media_type_string(type),
|
||||
av_err2str(ret));
|
||||
return false;
|
||||
}
|
||||
blog(LOG_WARNING, "MP: Failed to find %s codec",
|
||||
av_get_media_type_string(type));
|
||||
return false;
|
||||
}
|
||||
|
||||
d->frame = av_frame_alloc();
|
||||
if (!d->frame) {
|
||||
blog(LOG_WARNING, "MP: Failed to allocate %s frame",
|
||||
av_get_media_type_string(type));
|
||||
ret = mp_open_codec(d, hw);
|
||||
if (ret < 0) {
|
||||
blog(LOG_WARNING, "MP: Failed to open %s decoder: %s",
|
||||
av_get_media_type_string(type), av_err2str(ret));
|
||||
return false;
|
||||
}
|
||||
|
||||
d->sw_frame = av_frame_alloc();
|
||||
if (!d->sw_frame) {
|
||||
blog(LOG_WARNING, "MP: Failed to allocate %s frame",
|
||||
av_get_media_type_string(type));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (d->hw) {
|
||||
d->hw_frame = av_frame_alloc();
|
||||
if (!d->hw_frame) {
|
||||
blog(LOG_WARNING, "MP: Failed to allocate %s hw frame",
|
||||
av_get_media_type_string(type));
|
||||
return false;
|
||||
}
|
||||
|
||||
d->in_frame = d->hw_frame;
|
||||
} else {
|
||||
d->in_frame = d->sw_frame;
|
||||
}
|
||||
|
||||
if (d->codec->capabilities & CODEC_CAP_TRUNC)
|
||||
d->decoder->flags |= CODEC_FLAG_TRUNC;
|
||||
return true;
|
||||
|
|
@ -166,6 +213,10 @@ void mp_decode_free(struct mp_decode *d)
|
|||
mp_decode_clear_packets(d);
|
||||
circlebuf_free(&d->packets);
|
||||
|
||||
if (d->hw_frame) {
|
||||
av_frame_unref(d->hw_frame);
|
||||
av_free(d->hw_frame);
|
||||
}
|
||||
if (d->decoder) {
|
||||
#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(57, 40, 101)
|
||||
avcodec_free_context(&d->decoder);
|
||||
|
|
@ -173,11 +224,17 @@ void mp_decode_free(struct mp_decode *d)
|
|||
avcodec_close(d->decoder);
|
||||
#endif
|
||||
}
|
||||
if (d->frame) {
|
||||
av_frame_unref(d->frame);
|
||||
av_free(d->frame);
|
||||
if (d->sw_frame) {
|
||||
av_frame_unref(d->sw_frame);
|
||||
av_free(d->sw_frame);
|
||||
}
|
||||
|
||||
#ifdef USE_NEW_HARDWARE_CODEC_METHOD
|
||||
if (d->hw_ctx) {
|
||||
av_buffer_unref(&d->hw_ctx);
|
||||
}
|
||||
#endif
|
||||
|
||||
memset(d, 0, sizeof(*d));
|
||||
}
|
||||
|
||||
|
|
@ -187,22 +244,22 @@ void mp_decode_push_packet(struct mp_decode *decode, AVPacket *packet)
|
|||
}
|
||||
|
||||
static inline int64_t get_estimated_duration(struct mp_decode *d,
|
||||
int64_t last_pts)
|
||||
int64_t last_pts)
|
||||
{
|
||||
if (last_pts)
|
||||
return d->frame_pts - last_pts;
|
||||
|
||||
if (d->audio) {
|
||||
return av_rescale_q(d->frame->nb_samples,
|
||||
(AVRational){1, d->frame->sample_rate},
|
||||
(AVRational){1, 1000000000});
|
||||
return av_rescale_q(d->in_frame->nb_samples,
|
||||
(AVRational){1, d->in_frame->sample_rate},
|
||||
(AVRational){1, 1000000000});
|
||||
} else {
|
||||
if (d->last_duration)
|
||||
return d->last_duration;
|
||||
|
||||
return av_rescale_q(d->decoder->time_base.num,
|
||||
d->decoder->time_base,
|
||||
(AVRational){1, 1000000000});
|
||||
d->decoder->time_base,
|
||||
(AVRational){1, 1000000000});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -212,7 +269,7 @@ static int decode_packet(struct mp_decode *d, int *got_frame)
|
|||
*got_frame = 0;
|
||||
|
||||
#ifdef USE_NEW_FFMPEG_DECODE_API
|
||||
ret = avcodec_receive_frame(d->decoder, d->frame);
|
||||
ret = avcodec_receive_frame(d->decoder, d->in_frame);
|
||||
if (ret != 0 && ret != AVERROR(EAGAIN)) {
|
||||
if (ret == AVERROR_EOF)
|
||||
ret = 0;
|
||||
|
|
@ -227,7 +284,7 @@ static int decode_packet(struct mp_decode *d, int *got_frame)
|
|||
return ret;
|
||||
}
|
||||
|
||||
ret = avcodec_receive_frame(d->decoder, d->frame);
|
||||
ret = avcodec_receive_frame(d->decoder, d->in_frame);
|
||||
if (ret != 0 && ret != AVERROR(EAGAIN)) {
|
||||
if (ret == AVERROR_EOF)
|
||||
ret = 0;
|
||||
|
|
@ -243,13 +300,30 @@ static int decode_packet(struct mp_decode *d, int *got_frame)
|
|||
|
||||
#else
|
||||
if (d->audio) {
|
||||
ret = avcodec_decode_audio4(d->decoder,
|
||||
d->frame, got_frame, &d->pkt);
|
||||
ret = avcodec_decode_audio4(d->decoder, d->in_frame, got_frame,
|
||||
&d->pkt);
|
||||
} else {
|
||||
ret = avcodec_decode_video2(d->decoder,
|
||||
d->frame, got_frame, &d->pkt);
|
||||
ret = avcodec_decode_video2(d->decoder, d->in_frame, got_frame,
|
||||
&d->pkt);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_NEW_HARDWARE_CODEC_METHOD
|
||||
if (*got_frame && d->hw) {
|
||||
if (d->hw_frame->format != d->hw_format) {
|
||||
d->frame = d->hw_frame;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int err = av_hwframe_transfer_data(d->sw_frame, d->hw_frame, 0);
|
||||
if (err != 0) {
|
||||
ret = 0;
|
||||
*got_frame = false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
d->frame = d->sw_frame;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -275,7 +349,7 @@ bool mp_decode_next(struct mp_decode *d)
|
|||
}
|
||||
} else {
|
||||
circlebuf_pop_front(&d->packets, &d->orig_pkt,
|
||||
sizeof(d->orig_pkt));
|
||||
sizeof(d->orig_pkt));
|
||||
d->pkt = d->orig_pkt;
|
||||
d->packet_pending = true;
|
||||
}
|
||||
|
|
@ -290,7 +364,7 @@ bool mp_decode_next(struct mp_decode *d)
|
|||
if (ret < 0) {
|
||||
#ifdef DETAILED_DEBUG_INFO
|
||||
blog(LOG_DEBUG, "MP: decode failed: %s",
|
||||
av_err2str(ret));
|
||||
av_err2str(ret));
|
||||
#endif
|
||||
|
||||
if (d->packet_pending) {
|
||||
|
|
@ -322,29 +396,28 @@ bool mp_decode_next(struct mp_decode *d)
|
|||
if (d->frame_ready) {
|
||||
int64_t last_pts = d->frame_pts;
|
||||
|
||||
if (d->frame->best_effort_timestamp == AV_NOPTS_VALUE)
|
||||
if (d->in_frame->best_effort_timestamp == AV_NOPTS_VALUE)
|
||||
d->frame_pts = d->next_pts;
|
||||
else
|
||||
d->frame_pts = av_rescale_q(
|
||||
d->frame->best_effort_timestamp,
|
||||
d->stream->time_base,
|
||||
(AVRational){1, 1000000000});
|
||||
d->frame_pts =
|
||||
av_rescale_q(d->in_frame->best_effort_timestamp,
|
||||
d->stream->time_base,
|
||||
(AVRational){1, 1000000000});
|
||||
|
||||
int64_t duration = d->frame->pkt_duration;
|
||||
int64_t duration = d->in_frame->pkt_duration;
|
||||
if (!duration)
|
||||
duration = get_estimated_duration(d, last_pts);
|
||||
else
|
||||
duration = av_rescale_q(duration,
|
||||
d->stream->time_base,
|
||||
(AVRational){1, 1000000000});
|
||||
duration = av_rescale_q(duration, d->stream->time_base,
|
||||
(AVRational){1, 1000000000});
|
||||
|
||||
if (d->m->speed != 100) {
|
||||
d->frame_pts = av_rescale_q(d->frame_pts,
|
||||
(AVRational){1, d->m->speed},
|
||||
(AVRational){1, 100});
|
||||
d->frame_pts = av_rescale_q(
|
||||
d->frame_pts, (AVRational){1, d->m->speed},
|
||||
(AVRational){1, 100});
|
||||
duration = av_rescale_q(duration,
|
||||
(AVRational){1, d->m->speed},
|
||||
(AVRational){1, 100});
|
||||
(AVRational){1, d->m->speed},
|
||||
(AVRational){1, 100});
|
||||
}
|
||||
|
||||
d->last_duration = duration;
|
||||
|
|
|
|||
40
deps/media-playback/media-playback/decode.h
vendored
40
deps/media-playback/media-playback/decode.h
vendored
|
|
@ -53,29 +53,35 @@ extern "C" {
|
|||
struct mp_media;
|
||||
|
||||
struct mp_decode {
|
||||
struct mp_media *m;
|
||||
AVStream *stream;
|
||||
bool audio;
|
||||
struct mp_media *m;
|
||||
AVStream *stream;
|
||||
bool audio;
|
||||
|
||||
AVCodecContext *decoder;
|
||||
AVCodec *codec;
|
||||
AVCodecContext *decoder;
|
||||
AVBufferRef *hw_ctx;
|
||||
AVCodec *codec;
|
||||
|
||||
int64_t last_duration;
|
||||
int64_t frame_pts;
|
||||
int64_t next_pts;
|
||||
AVFrame *frame;
|
||||
bool got_first_keyframe;
|
||||
bool frame_ready;
|
||||
bool eof;
|
||||
int64_t last_duration;
|
||||
int64_t frame_pts;
|
||||
int64_t next_pts;
|
||||
AVFrame *in_frame;
|
||||
AVFrame *sw_frame;
|
||||
AVFrame *hw_frame;
|
||||
AVFrame *frame;
|
||||
enum AVPixelFormat hw_format;
|
||||
bool got_first_keyframe;
|
||||
bool frame_ready;
|
||||
bool eof;
|
||||
bool hw;
|
||||
|
||||
AVPacket orig_pkt;
|
||||
AVPacket pkt;
|
||||
bool packet_pending;
|
||||
struct circlebuf packets;
|
||||
AVPacket orig_pkt;
|
||||
AVPacket pkt;
|
||||
bool packet_pending;
|
||||
struct circlebuf packets;
|
||||
};
|
||||
|
||||
extern bool mp_decode_init(struct mp_media *media, enum AVMediaType type,
|
||||
bool hw);
|
||||
bool hw);
|
||||
extern void mp_decode_free(struct mp_decode *decode);
|
||||
|
||||
extern void mp_decode_clear_packets(struct mp_decode *decode);
|
||||
|
|
|
|||
174
deps/media-playback/media-playback/media.c
vendored
174
deps/media-playback/media-playback/media.c
vendored
|
|
@ -30,15 +30,30 @@ static int64_t base_sys_ts = 0;
|
|||
static inline enum video_format convert_pixel_format(int f)
|
||||
{
|
||||
switch (f) {
|
||||
case AV_PIX_FMT_NONE: return VIDEO_FORMAT_NONE;
|
||||
case AV_PIX_FMT_YUV420P: return VIDEO_FORMAT_I420;
|
||||
case AV_PIX_FMT_NV12: return VIDEO_FORMAT_NV12;
|
||||
case AV_PIX_FMT_YUYV422: return VIDEO_FORMAT_YUY2;
|
||||
case AV_PIX_FMT_YUV444P: return VIDEO_FORMAT_I444;
|
||||
case AV_PIX_FMT_UYVY422: return VIDEO_FORMAT_UYVY;
|
||||
case AV_PIX_FMT_RGBA: return VIDEO_FORMAT_RGBA;
|
||||
case AV_PIX_FMT_BGRA: return VIDEO_FORMAT_BGRA;
|
||||
case AV_PIX_FMT_BGR0: return VIDEO_FORMAT_BGRX;
|
||||
case AV_PIX_FMT_NONE:
|
||||
return VIDEO_FORMAT_NONE;
|
||||
case AV_PIX_FMT_YUV420P:
|
||||
return VIDEO_FORMAT_I420;
|
||||
case AV_PIX_FMT_NV12:
|
||||
return VIDEO_FORMAT_NV12;
|
||||
case AV_PIX_FMT_YUYV422:
|
||||
return VIDEO_FORMAT_YUY2;
|
||||
case AV_PIX_FMT_YUV444P:
|
||||
return VIDEO_FORMAT_I444;
|
||||
case AV_PIX_FMT_UYVY422:
|
||||
return VIDEO_FORMAT_UYVY;
|
||||
case AV_PIX_FMT_RGBA:
|
||||
return VIDEO_FORMAT_RGBA;
|
||||
case AV_PIX_FMT_BGRA:
|
||||
return VIDEO_FORMAT_BGRA;
|
||||
case AV_PIX_FMT_BGR0:
|
||||
return VIDEO_FORMAT_BGRX;
|
||||
case AV_PIX_FMT_YUVA420P:
|
||||
return VIDEO_FORMAT_I40A;
|
||||
case AV_PIX_FMT_YUVA422P:
|
||||
return VIDEO_FORMAT_I42A;
|
||||
case AV_PIX_FMT_YUVA444P:
|
||||
return VIDEO_FORMAT_YUVA;
|
||||
default:;
|
||||
}
|
||||
|
||||
|
|
@ -48,14 +63,22 @@ static inline enum video_format convert_pixel_format(int f)
|
|||
static inline enum audio_format convert_sample_format(int f)
|
||||
{
|
||||
switch (f) {
|
||||
case AV_SAMPLE_FMT_U8: return AUDIO_FORMAT_U8BIT;
|
||||
case AV_SAMPLE_FMT_S16: return AUDIO_FORMAT_16BIT;
|
||||
case AV_SAMPLE_FMT_S32: return AUDIO_FORMAT_32BIT;
|
||||
case AV_SAMPLE_FMT_FLT: return AUDIO_FORMAT_FLOAT;
|
||||
case AV_SAMPLE_FMT_U8P: return AUDIO_FORMAT_U8BIT_PLANAR;
|
||||
case AV_SAMPLE_FMT_S16P: return AUDIO_FORMAT_16BIT_PLANAR;
|
||||
case AV_SAMPLE_FMT_S32P: return AUDIO_FORMAT_32BIT_PLANAR;
|
||||
case AV_SAMPLE_FMT_FLTP: return AUDIO_FORMAT_FLOAT_PLANAR;
|
||||
case AV_SAMPLE_FMT_U8:
|
||||
return AUDIO_FORMAT_U8BIT;
|
||||
case AV_SAMPLE_FMT_S16:
|
||||
return AUDIO_FORMAT_16BIT;
|
||||
case AV_SAMPLE_FMT_S32:
|
||||
return AUDIO_FORMAT_32BIT;
|
||||
case AV_SAMPLE_FMT_FLT:
|
||||
return AUDIO_FORMAT_FLOAT;
|
||||
case AV_SAMPLE_FMT_U8P:
|
||||
return AUDIO_FORMAT_U8BIT_PLANAR;
|
||||
case AV_SAMPLE_FMT_S16P:
|
||||
return AUDIO_FORMAT_16BIT_PLANAR;
|
||||
case AV_SAMPLE_FMT_S32P:
|
||||
return AUDIO_FORMAT_32BIT_PLANAR;
|
||||
case AV_SAMPLE_FMT_FLTP:
|
||||
return AUDIO_FORMAT_FLOAT_PLANAR;
|
||||
default:;
|
||||
}
|
||||
|
||||
|
|
@ -65,15 +88,24 @@ static inline enum audio_format convert_sample_format(int f)
|
|||
static inline enum speaker_layout convert_speaker_layout(uint8_t channels)
|
||||
{
|
||||
switch (channels) {
|
||||
case 0: return SPEAKERS_UNKNOWN;
|
||||
case 1: return SPEAKERS_MONO;
|
||||
case 2: return SPEAKERS_STEREO;
|
||||
case 3: return SPEAKERS_2POINT1;
|
||||
case 4: return SPEAKERS_4POINT0;
|
||||
case 5: return SPEAKERS_4POINT1;
|
||||
case 6: return SPEAKERS_5POINT1;
|
||||
case 8: return SPEAKERS_7POINT1;
|
||||
default: return SPEAKERS_UNKNOWN;
|
||||
case 0:
|
||||
return SPEAKERS_UNKNOWN;
|
||||
case 1:
|
||||
return SPEAKERS_MONO;
|
||||
case 2:
|
||||
return SPEAKERS_STEREO;
|
||||
case 3:
|
||||
return SPEAKERS_2POINT1;
|
||||
case 4:
|
||||
return SPEAKERS_4POINT0;
|
||||
case 5:
|
||||
return SPEAKERS_4POINT1;
|
||||
case 6:
|
||||
return SPEAKERS_5POINT1;
|
||||
case 8:
|
||||
return SPEAKERS_7POINT1;
|
||||
default:
|
||||
return SPEAKERS_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -88,7 +120,7 @@ static inline enum video_range_type convert_color_range(enum AVColorRange r)
|
|||
}
|
||||
|
||||
static inline struct mp_decode *get_packet_decoder(mp_media_t *media,
|
||||
AVPacket *pkt)
|
||||
AVPacket *pkt)
|
||||
{
|
||||
if (media->has_audio && pkt->stream_index == media->a.stream->index)
|
||||
return &media->a;
|
||||
|
|
@ -109,7 +141,7 @@ static int mp_media_next_packet(mp_media_t *media)
|
|||
if (ret < 0) {
|
||||
if (ret != AVERROR_EOF)
|
||||
blog(LOG_WARNING, "MP: av_read_frame failed: %s (%d)",
|
||||
av_err2str(ret), ret);
|
||||
av_err2str(ret), ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -160,7 +192,7 @@ static inline int get_sws_range(enum AVColorRange r)
|
|||
return r == AVCOL_RANGE_JPEG ? 1 : 0;
|
||||
}
|
||||
|
||||
#define FIXED_1_0 (1<<16)
|
||||
#define FIXED_1_0 (1 << 16)
|
||||
|
||||
static bool mp_media_init_scaling(mp_media_t *m)
|
||||
{
|
||||
|
|
@ -168,23 +200,23 @@ static bool mp_media_init_scaling(mp_media_t *m)
|
|||
int range = get_sws_range(m->v.decoder->color_range);
|
||||
const int *coeff = sws_getCoefficients(space);
|
||||
|
||||
m->swscale = sws_getCachedContext(NULL,
|
||||
m->v.decoder->width, m->v.decoder->height,
|
||||
m->v.decoder->pix_fmt,
|
||||
m->v.decoder->width, m->v.decoder->height,
|
||||
m->scale_format,
|
||||
SWS_FAST_BILINEAR, NULL, NULL, NULL);
|
||||
m->swscale = sws_getCachedContext(NULL, m->v.decoder->width,
|
||||
m->v.decoder->height,
|
||||
m->v.decoder->pix_fmt,
|
||||
m->v.decoder->width,
|
||||
m->v.decoder->height, m->scale_format,
|
||||
SWS_FAST_BILINEAR, NULL, NULL, NULL);
|
||||
if (!m->swscale) {
|
||||
blog(LOG_WARNING, "MP: Failed to initialize scaler");
|
||||
return false;
|
||||
}
|
||||
|
||||
sws_setColorspaceDetails(m->swscale, coeff, range, coeff, range, 0,
|
||||
FIXED_1_0, FIXED_1_0);
|
||||
FIXED_1_0, FIXED_1_0);
|
||||
|
||||
int ret = av_image_alloc(m->scale_pic, m->scale_linesizes,
|
||||
m->v.decoder->width, m->v.decoder->height,
|
||||
m->scale_format, 1);
|
||||
m->v.decoder->width, m->v.decoder->height,
|
||||
m->scale_format, 1);
|
||||
if (ret < 0) {
|
||||
blog(LOG_WARNING, "MP: Failed to create scale pic data");
|
||||
return false;
|
||||
|
|
@ -250,8 +282,7 @@ static inline int64_t mp_media_get_base_pts(mp_media_t *m)
|
|||
return base_ts;
|
||||
}
|
||||
|
||||
static inline bool mp_media_can_play_frame(mp_media_t *m,
|
||||
struct mp_decode *d)
|
||||
static inline bool mp_media_can_play_frame(mp_media_t *m, struct mp_decode *d)
|
||||
{
|
||||
return d->frame_ready && d->frame_pts <= m->next_pts_ns;
|
||||
}
|
||||
|
|
@ -277,7 +308,7 @@ static void mp_media_next_audio(mp_media_t *m)
|
|||
audio.format = convert_sample_format(f->format);
|
||||
audio.frames = f->nb_samples;
|
||||
audio.timestamp = m->base_ts + d->frame_pts - m->start_ts +
|
||||
m->play_sys_ts - base_sys_ts;
|
||||
m->play_sys_ts - base_sys_ts;
|
||||
|
||||
if (audio.format == AUDIO_FORMAT_UNKNOWN)
|
||||
return;
|
||||
|
|
@ -308,10 +339,9 @@ static void mp_media_next_video(mp_media_t *m, bool preload)
|
|||
|
||||
bool flip = false;
|
||||
if (m->swscale) {
|
||||
int ret = sws_scale(m->swscale,
|
||||
(const uint8_t *const *)f->data, f->linesize,
|
||||
0, f->height,
|
||||
m->scale_pic, m->scale_linesizes);
|
||||
int ret = sws_scale(m->swscale, (const uint8_t *const *)f->data,
|
||||
f->linesize, 0, f->height, m->scale_pic,
|
||||
m->scale_linesizes);
|
||||
if (ret < 0)
|
||||
return;
|
||||
|
||||
|
|
@ -334,25 +364,22 @@ static void mp_media_next_video(mp_media_t *m, bool preload)
|
|||
frame->data[0] -= frame->linesize[0] * (f->height - 1);
|
||||
|
||||
new_format = convert_pixel_format(m->scale_format);
|
||||
new_space = convert_color_space(f->colorspace);
|
||||
new_range = m->force_range == VIDEO_RANGE_DEFAULT
|
||||
? convert_color_range(f->color_range)
|
||||
: m->force_range;
|
||||
new_space = convert_color_space(f->colorspace);
|
||||
new_range = m->force_range == VIDEO_RANGE_DEFAULT
|
||||
? convert_color_range(f->color_range)
|
||||
: m->force_range;
|
||||
|
||||
if (new_format != frame->format ||
|
||||
new_space != m->cur_space ||
|
||||
new_range != m->cur_range) {
|
||||
if (new_format != frame->format || new_space != m->cur_space ||
|
||||
new_range != m->cur_range) {
|
||||
bool success;
|
||||
|
||||
frame->format = new_format;
|
||||
frame->full_range = new_range == VIDEO_RANGE_FULL;
|
||||
|
||||
success = video_format_get_parameters(
|
||||
new_space,
|
||||
new_range,
|
||||
frame->color_matrix,
|
||||
frame->color_range_min,
|
||||
frame->color_range_max);
|
||||
success = video_format_get_parameters(new_space, new_range,
|
||||
frame->color_matrix,
|
||||
frame->color_range_min,
|
||||
frame->color_range_max);
|
||||
|
||||
frame->format = new_format;
|
||||
m->cur_space = new_space;
|
||||
|
|
@ -368,7 +395,7 @@ static void mp_media_next_video(mp_media_t *m, bool preload)
|
|||
return;
|
||||
|
||||
frame->timestamp = m->base_ts + d->frame_pts - m->start_ts +
|
||||
m->play_sys_ts - base_sys_ts;
|
||||
m->play_sys_ts - base_sys_ts;
|
||||
frame->width = f->width;
|
||||
frame->height = f->height;
|
||||
frame->flip = flip;
|
||||
|
|
@ -420,14 +447,15 @@ static bool mp_media_reset(mp_media_t *m)
|
|||
}
|
||||
|
||||
int64_t seek_target = seek_flags == AVSEEK_FLAG_BACKWARD
|
||||
? av_rescale_q(seek_pos, AV_TIME_BASE_Q, stream->time_base)
|
||||
: seek_pos;
|
||||
? av_rescale_q(seek_pos, AV_TIME_BASE_Q,
|
||||
stream->time_base)
|
||||
: seek_pos;
|
||||
|
||||
if (m->is_local_file) {
|
||||
int ret = av_seek_frame(m->fmt, 0, seek_target, seek_flags);
|
||||
if (ret < 0) {
|
||||
blog(LOG_WARNING, "MP: Failed to seek: %s",
|
||||
av_err2str(ret));
|
||||
av_err2str(ret));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -538,8 +566,10 @@ static bool init_avformat(mp_media_t *m)
|
|||
if (m->format_name && *m->format_name) {
|
||||
format = av_find_input_format(m->format_name);
|
||||
if (!format)
|
||||
blog(LOG_INFO, "MP: Unable to find input format for "
|
||||
"'%s'", m->path);
|
||||
blog(LOG_INFO,
|
||||
"MP: Unable to find input format for "
|
||||
"'%s'",
|
||||
m->path);
|
||||
}
|
||||
|
||||
AVDictionary *opts = NULL;
|
||||
|
|
@ -551,7 +581,7 @@ static bool init_avformat(mp_media_t *m)
|
|||
m->fmt->interrupt_callback.opaque = m;
|
||||
|
||||
int ret = avformat_open_input(&m->fmt, m->path, format,
|
||||
opts ? &opts : NULL);
|
||||
opts ? &opts : NULL);
|
||||
av_dict_free(&opts);
|
||||
|
||||
if (ret < 0) {
|
||||
|
|
@ -561,7 +591,7 @@ static bool init_avformat(mp_media_t *m)
|
|||
|
||||
if (avformat_find_stream_info(m->fmt, NULL) < 0) {
|
||||
blog(LOG_WARNING, "MP: Failed to find stream info for '%s'",
|
||||
m->path);
|
||||
m->path);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -569,8 +599,10 @@ static bool init_avformat(mp_media_t *m)
|
|||
m->has_audio = mp_decode_init(m, AVMEDIA_TYPE_AUDIO, m->hw);
|
||||
|
||||
if (!m->has_video && !m->has_audio) {
|
||||
blog(LOG_WARNING, "MP: Could not initialize audio or video: "
|
||||
"'%s'", m->path);
|
||||
blog(LOG_WARNING,
|
||||
"MP: Could not initialize audio or video: "
|
||||
"'%s'",
|
||||
m->path);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -653,7 +685,7 @@ static void *mp_media_thread_start(void *opaque)
|
|||
}
|
||||
|
||||
static inline bool mp_media_init_internal(mp_media_t *m,
|
||||
const struct mp_media_info *info)
|
||||
const struct mp_media_info *info)
|
||||
{
|
||||
if (pthread_mutex_init(&m->mutex, NULL) != 0) {
|
||||
blog(LOG_WARNING, "MP: Failed to init mutex");
|
||||
|
|
@ -696,9 +728,11 @@ bool mp_media_init(mp_media_t *media, const struct mp_media_info *info)
|
|||
|
||||
static bool initialized = false;
|
||||
if (!initialized) {
|
||||
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58, 9, 100)
|
||||
av_register_all();
|
||||
avdevice_register_all();
|
||||
avcodec_register_all();
|
||||
#endif
|
||||
avdevice_register_all();
|
||||
avformat_network_init();
|
||||
initialized = true;
|
||||
}
|
||||
|
|
|
|||
18
deps/obs-scripting/obs-scripting-callback.h
vendored
18
deps/obs-scripting/obs-scripting-callback.h
vendored
|
|
@ -36,10 +36,8 @@ struct script_callback {
|
|||
bool removed;
|
||||
};
|
||||
|
||||
static inline void *add_script_callback(
|
||||
struct script_callback **first,
|
||||
obs_script_t *script,
|
||||
size_t extra_size)
|
||||
static inline void *add_script_callback(struct script_callback **first,
|
||||
obs_script_t *script, size_t extra_size)
|
||||
{
|
||||
struct script_callback *cb = bzalloc(sizeof(*cb) + extra_size);
|
||||
cb->script = script;
|
||||
|
|
@ -47,7 +45,8 @@ static inline void *add_script_callback(
|
|||
struct script_callback *next = *first;
|
||||
cb->next = next;
|
||||
cb->p_prev_next = first;
|
||||
if (next) next->p_prev_next = &cb->next;
|
||||
if (next)
|
||||
next->p_prev_next = &cb->next;
|
||||
*first = cb;
|
||||
|
||||
return cb;
|
||||
|
|
@ -58,13 +57,15 @@ static inline void remove_script_callback(struct script_callback *cb)
|
|||
cb->removed = true;
|
||||
|
||||
struct script_callback *next = cb->next;
|
||||
if (next) next->p_prev_next = cb->p_prev_next;
|
||||
if (next)
|
||||
next->p_prev_next = cb->p_prev_next;
|
||||
*cb->p_prev_next = cb->next;
|
||||
|
||||
pthread_mutex_lock(&detach_mutex);
|
||||
next = detached_callbacks;
|
||||
cb->next = next;
|
||||
if (next) next->p_prev_next = &cb->next;
|
||||
if (next)
|
||||
next->p_prev_next = &cb->next;
|
||||
cb->p_prev_next = &detached_callbacks;
|
||||
detached_callbacks = cb;
|
||||
pthread_mutex_unlock(&detach_mutex);
|
||||
|
|
@ -83,7 +84,8 @@ static inline void free_script_callback(struct script_callback *cb)
|
|||
{
|
||||
pthread_mutex_lock(&detach_mutex);
|
||||
struct script_callback *next = cb->next;
|
||||
if (next) next->p_prev_next = cb->p_prev_next;
|
||||
if (next)
|
||||
next->p_prev_next = cb->p_prev_next;
|
||||
*cb->p_prev_next = cb->next;
|
||||
pthread_mutex_unlock(&detach_mutex);
|
||||
|
||||
|
|
|
|||
5
deps/obs-scripting/obs-scripting-internal.h
vendored
5
deps/obs-scripting/obs-scripting-internal.h
vendored
|
|
@ -37,9 +37,10 @@ typedef void (*defer_call_cb)(void *param);
|
|||
|
||||
extern void defer_call_post(defer_call_cb call, void *cb);
|
||||
|
||||
extern void script_log(obs_script_t *script, int level, const char *format, ...);
|
||||
extern void script_log(obs_script_t *script, int level, const char *format,
|
||||
...);
|
||||
extern void script_log_va(obs_script_t *script, int level, const char *format,
|
||||
va_list args);
|
||||
va_list args);
|
||||
|
||||
#define script_error(script, format, ...) \
|
||||
script_log(script, LOG_ERROR, format, ##__VA_ARGS__)
|
||||
|
|
|
|||
20
deps/obs-scripting/obs-scripting-logging.c
vendored
20
deps/obs-scripting/obs-scripting-logging.c
vendored
|
|
@ -22,7 +22,7 @@ static scripting_log_handler_t callback = NULL;
|
|||
static void *param = NULL;
|
||||
|
||||
void script_log_va(obs_script_t *script, int level, const char *format,
|
||||
va_list args)
|
||||
va_list args)
|
||||
{
|
||||
char msg[2048];
|
||||
const char *lang = "(Unknown)";
|
||||
|
|
@ -30,13 +30,19 @@ void script_log_va(obs_script_t *script, int level, const char *format,
|
|||
|
||||
if (script) {
|
||||
switch (script->type) {
|
||||
case OBS_SCRIPT_LANG_UNKNOWN: lang = "(Unknown language)"; break;
|
||||
case OBS_SCRIPT_LANG_LUA: lang = "Lua"; break;
|
||||
case OBS_SCRIPT_LANG_PYTHON: lang = "Python"; break;
|
||||
case OBS_SCRIPT_LANG_UNKNOWN:
|
||||
lang = "(Unknown language)";
|
||||
break;
|
||||
case OBS_SCRIPT_LANG_LUA:
|
||||
lang = "Lua";
|
||||
break;
|
||||
case OBS_SCRIPT_LANG_PYTHON:
|
||||
lang = "Python";
|
||||
break;
|
||||
}
|
||||
|
||||
start_len = snprintf(msg, sizeof(msg), "[%s: %s] ",
|
||||
lang, script->file.array);
|
||||
start_len = snprintf(msg, sizeof(msg), "[%s: %s] ", lang,
|
||||
script->file.array);
|
||||
} else {
|
||||
start_len = snprintf(msg, sizeof(msg), "[Unknown Script] ");
|
||||
}
|
||||
|
|
@ -57,7 +63,7 @@ void script_log(obs_script_t *script, int level, const char *format, ...)
|
|||
}
|
||||
|
||||
void obs_scripting_set_log_callback(scripting_log_handler_t handler,
|
||||
void *log_param)
|
||||
void *log_param)
|
||||
{
|
||||
callback = handler;
|
||||
param = log_param;
|
||||
|
|
|
|||
24
deps/obs-scripting/obs-scripting-lua-frontend.c
vendored
24
deps/obs-scripting/obs-scripting-lua-frontend.c
vendored
|
|
@ -20,12 +20,12 @@
|
|||
|
||||
#include "obs-scripting-lua.h"
|
||||
|
||||
#define ls_get_libobs_obj(type, lua_index, obs_obj) \
|
||||
ls_get_libobs_obj_(script, #type " *", lua_index, obs_obj, \
|
||||
NULL, __FUNCTION__, __LINE__)
|
||||
#define ls_push_libobs_obj(type, obs_obj, ownership) \
|
||||
ls_push_libobs_obj_(script, #type " *", obs_obj, ownership, \
|
||||
NULL, __FUNCTION__, __LINE__)
|
||||
#define ls_get_libobs_obj(type, lua_index, obs_obj) \
|
||||
ls_get_libobs_obj_(script, #type " *", lua_index, obs_obj, NULL, \
|
||||
__FUNCTION__, __LINE__)
|
||||
#define ls_push_libobs_obj(type, obs_obj, ownership) \
|
||||
ls_push_libobs_obj_(script, #type " *", obs_obj, ownership, NULL, \
|
||||
__FUNCTION__, __LINE__)
|
||||
#define call_func(func, args, rets) \
|
||||
call_func_(script, cb->reg_idx, args, rets, #func, "frontend API")
|
||||
|
||||
|
|
@ -191,7 +191,7 @@ static void frontend_event_callback(enum obs_frontend_event event, void *priv)
|
|||
lua_State *script = cb->script;
|
||||
|
||||
if (cb->base.removed) {
|
||||
obs_frontend_remove_event_callback(frontend_event_callback, cb);
|
||||
obs_frontend_remove_event_callback(frontend_event_callback, cb);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -233,7 +233,7 @@ static int add_event_callback(lua_State *script)
|
|||
/* ----------------------------------- */
|
||||
|
||||
static void frontend_save_callback(obs_data_t *save_data, bool saving,
|
||||
void *priv)
|
||||
void *priv)
|
||||
{
|
||||
struct lua_obs_callback *cb = priv;
|
||||
lua_State *script = cb->script;
|
||||
|
|
@ -285,11 +285,11 @@ void add_lua_frontend_funcs(lua_State *script)
|
|||
{
|
||||
lua_getglobal(script, "obslua");
|
||||
|
||||
#define add_func(name) \
|
||||
do { \
|
||||
#define add_func(name) \
|
||||
do { \
|
||||
lua_pushstring(script, "obs_frontend_" #name); \
|
||||
lua_pushcfunction(script, name); \
|
||||
lua_rawset(script, -3); \
|
||||
lua_pushcfunction(script, name); \
|
||||
lua_rawset(script, -3); \
|
||||
} while (false)
|
||||
|
||||
add_func(get_scene_names);
|
||||
|
|
|
|||
229
deps/obs-scripting/obs-scripting-lua-source.c
vendored
229
deps/obs-scripting/obs-scripting-lua-source.c
vendored
|
|
@ -23,7 +23,7 @@
|
|||
/* ========================================================================= */
|
||||
|
||||
static inline const char *get_table_string_(lua_State *script, int idx,
|
||||
const char *name, const char *func)
|
||||
const char *name, const char *func)
|
||||
{
|
||||
const char *str = "";
|
||||
|
||||
|
|
@ -38,8 +38,8 @@ static inline const char *get_table_string_(lua_State *script, int idx,
|
|||
return str;
|
||||
}
|
||||
|
||||
static inline int get_table_int_(lua_State *script, int idx,
|
||||
const char *name, const char *func)
|
||||
static inline int get_table_int_(lua_State *script, int idx, const char *name,
|
||||
const char *func)
|
||||
{
|
||||
int val = 0;
|
||||
|
||||
|
|
@ -54,7 +54,8 @@ static inline int get_table_int_(lua_State *script, int idx,
|
|||
}
|
||||
|
||||
static inline void get_callback_from_table_(lua_State *script, int idx,
|
||||
const char *name, int *p_reg_idx, const char *func)
|
||||
const char *name, int *p_reg_idx,
|
||||
const char *func)
|
||||
{
|
||||
*p_reg_idx = LUA_REFNIL;
|
||||
|
||||
|
|
@ -77,22 +78,14 @@ static inline void get_callback_from_table_(lua_State *script, int idx,
|
|||
#define get_callback_from_table(script, idx, name, p_reg_idx) \
|
||||
get_callback_from_table_(script, idx, name, p_reg_idx, __FUNCTION__)
|
||||
|
||||
bool ls_get_libobs_obj_(lua_State * script,
|
||||
const char *type,
|
||||
int lua_idx,
|
||||
void * libobs_out,
|
||||
const char *id,
|
||||
const char *func,
|
||||
int line)
|
||||
bool ls_get_libobs_obj_(lua_State *script, const char *type, int lua_idx,
|
||||
void *libobs_out, const char *id, const char *func,
|
||||
int line)
|
||||
{
|
||||
swig_type_info *info = SWIG_TypeQuery(script, type);
|
||||
if (info == NULL) {
|
||||
warn("%s:%d: SWIG could not find type: %s%s%s",
|
||||
func,
|
||||
line,
|
||||
id ? id : "",
|
||||
id ? "::" : "",
|
||||
type);
|
||||
warn("%s:%d: SWIG could not find type: %s%s%s", func, line,
|
||||
id ? id : "", id ? "::" : "", type);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -100,37 +93,25 @@ bool ls_get_libobs_obj_(lua_State * script,
|
|||
if (!SWIG_IsOK(ret)) {
|
||||
warn("%s:%d: SWIG failed to convert lua object to obs "
|
||||
"object: %s%s%s",
|
||||
func,
|
||||
line,
|
||||
id ? id : "",
|
||||
id ? "::" : "",
|
||||
type);
|
||||
func, line, id ? id : "", id ? "::" : "", type);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#define ls_get_libobs_obj(type, lua_index, obs_obj) \
|
||||
ls_get_libobs_obj_(ls->script, #type " *", lua_index, obs_obj, \
|
||||
ls->id, __FUNCTION__, __LINE__)
|
||||
#define ls_get_libobs_obj(type, lua_index, obs_obj) \
|
||||
ls_get_libobs_obj_(ls->script, #type " *", lua_index, obs_obj, ls->id, \
|
||||
__FUNCTION__, __LINE__)
|
||||
|
||||
bool ls_push_libobs_obj_(lua_State * script,
|
||||
const char *type,
|
||||
void * libobs_in,
|
||||
bool ownership,
|
||||
const char *id,
|
||||
const char *func,
|
||||
int line)
|
||||
bool ls_push_libobs_obj_(lua_State *script, const char *type, void *libobs_in,
|
||||
bool ownership, const char *id, const char *func,
|
||||
int line)
|
||||
{
|
||||
swig_type_info *info = SWIG_TypeQuery(script, type);
|
||||
if (info == NULL) {
|
||||
warn("%s:%d: SWIG could not find type: %s%s%s",
|
||||
func,
|
||||
line,
|
||||
id ? id : "",
|
||||
id ? "::" : "",
|
||||
type);
|
||||
warn("%s:%d: SWIG could not find type: %s%s%s", func, line,
|
||||
id ? id : "", id ? "::" : "", type);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -138,9 +119,9 @@ bool ls_push_libobs_obj_(lua_State * script,
|
|||
return true;
|
||||
}
|
||||
|
||||
#define ls_push_libobs_obj(type, obs_obj, ownership) \
|
||||
#define ls_push_libobs_obj(type, obs_obj, ownership) \
|
||||
ls_push_libobs_obj_(ls->script, #type " *", obs_obj, ownership, \
|
||||
ls->id, __FUNCTION__, __LINE__)
|
||||
ls->id, __FUNCTION__, __LINE__)
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
|
|
@ -149,24 +130,24 @@ struct obs_lua_data;
|
|||
struct obs_lua_source {
|
||||
struct obs_lua_script *data;
|
||||
|
||||
lua_State * script;
|
||||
lua_State *script;
|
||||
const char *id;
|
||||
const char *display_name;
|
||||
int func_create;
|
||||
int func_destroy;
|
||||
int func_get_width;
|
||||
int func_get_height;
|
||||
int func_get_defaults;
|
||||
int func_get_properties;
|
||||
int func_update;
|
||||
int func_activate;
|
||||
int func_deactivate;
|
||||
int func_show;
|
||||
int func_hide;
|
||||
int func_video_tick;
|
||||
int func_video_render;
|
||||
int func_save;
|
||||
int func_load;
|
||||
int func_create;
|
||||
int func_destroy;
|
||||
int func_get_width;
|
||||
int func_get_height;
|
||||
int func_get_defaults;
|
||||
int func_get_properties;
|
||||
int func_update;
|
||||
int func_activate;
|
||||
int func_deactivate;
|
||||
int func_show;
|
||||
int func_hide;
|
||||
int func_video_tick;
|
||||
int func_video_render;
|
||||
int func_save;
|
||||
int func_load;
|
||||
|
||||
pthread_mutex_t definition_mutex;
|
||||
struct obs_lua_data *first_source;
|
||||
|
|
@ -179,29 +160,27 @@ extern pthread_mutex_t lua_source_def_mutex;
|
|||
struct obs_lua_source *first_source_def = NULL;
|
||||
|
||||
struct obs_lua_data {
|
||||
obs_source_t * source;
|
||||
obs_source_t *source;
|
||||
struct obs_lua_source *ls;
|
||||
int lua_data_ref;
|
||||
int lua_data_ref;
|
||||
|
||||
struct obs_lua_data *next;
|
||||
struct obs_lua_data **p_prev_next;
|
||||
};
|
||||
|
||||
#define call_func(name, args, rets) \
|
||||
call_func_(ls->script, ls->func_ ## name, args, rets, #name, \
|
||||
ls->display_name)
|
||||
#define have_func(name) \
|
||||
(ls->func_ ## name != LUA_REFNIL)
|
||||
#define call_func(name, args, rets) \
|
||||
call_func_(ls->script, ls->func_##name, args, rets, #name, \
|
||||
ls->display_name)
|
||||
#define have_func(name) (ls->func_##name != LUA_REFNIL)
|
||||
#define ls_push_data() \
|
||||
lua_rawgeti(ls->script, LUA_REGISTRYINDEX, ld->lua_data_ref)
|
||||
#define ls_pop(count) \
|
||||
lua_pop(ls->script, count)
|
||||
#define lock_script() \
|
||||
struct obs_lua_script *__data = ls->data; \
|
||||
#define ls_pop(count) lua_pop(ls->script, count)
|
||||
#define lock_script() \
|
||||
struct obs_lua_script *__data = ls->data; \
|
||||
struct obs_lua_script *__prev_script = current_lua_script; \
|
||||
current_lua_script = __data; \
|
||||
current_lua_script = __data; \
|
||||
pthread_mutex_lock(&__data->mutex);
|
||||
#define unlock_script() \
|
||||
#define unlock_script() \
|
||||
pthread_mutex_unlock(&__data->mutex); \
|
||||
current_lua_script = __prev_script;
|
||||
|
||||
|
|
@ -230,9 +209,9 @@ static void *obs_lua_source_create(obs_data_t *settings, obs_source_t *source)
|
|||
|
||||
int lua_data_ref = luaL_ref(ls->script, LUA_REGISTRYINDEX);
|
||||
if (lua_data_ref != LUA_REFNIL) {
|
||||
data = bmalloc(sizeof(*data));
|
||||
data->source = source;
|
||||
data->ls = ls;
|
||||
data = bmalloc(sizeof(*data));
|
||||
data->source = source;
|
||||
data->ls = ls;
|
||||
data->lua_data_ref = lua_data_ref;
|
||||
}
|
||||
|
||||
|
|
@ -242,7 +221,8 @@ static void *obs_lua_source_create(obs_data_t *settings, obs_source_t *source)
|
|||
struct obs_lua_data *next = ls->first_source;
|
||||
data->next = next;
|
||||
data->p_prev_next = &ls->first_source;
|
||||
if (next) next->p_prev_next = &data->next;
|
||||
if (next)
|
||||
next->p_prev_next = &data->next;
|
||||
ls->first_source = data;
|
||||
}
|
||||
|
||||
|
|
@ -263,9 +243,9 @@ static void call_destroy(struct obs_lua_data *ld)
|
|||
|
||||
static void obs_lua_source_destroy(void *data)
|
||||
{
|
||||
struct obs_lua_data * ld = data;
|
||||
struct obs_lua_data *ld = data;
|
||||
struct obs_lua_source *ls = ld->ls;
|
||||
struct obs_lua_data * next;
|
||||
struct obs_lua_data *next;
|
||||
|
||||
pthread_mutex_lock(&ls->definition_mutex);
|
||||
if (!ls->script)
|
||||
|
|
@ -280,7 +260,8 @@ static void obs_lua_source_destroy(void *data)
|
|||
fail:
|
||||
next = ld->next;
|
||||
*ld->p_prev_next = next;
|
||||
if (next) next->p_prev_next = ld->p_prev_next;
|
||||
if (next)
|
||||
next->p_prev_next = ld->p_prev_next;
|
||||
|
||||
bfree(data);
|
||||
pthread_mutex_unlock(&ls->definition_mutex);
|
||||
|
|
@ -288,9 +269,9 @@ fail:
|
|||
|
||||
static uint32_t obs_lua_source_get_width(void *data)
|
||||
{
|
||||
struct obs_lua_data * ld = data;
|
||||
struct obs_lua_source *ls = ld->ls;
|
||||
uint32_t width = 0;
|
||||
struct obs_lua_data *ld = data;
|
||||
struct obs_lua_source *ls = ld->ls;
|
||||
uint32_t width = 0;
|
||||
|
||||
pthread_mutex_lock(&ls->definition_mutex);
|
||||
if (!ls->script)
|
||||
|
|
@ -315,9 +296,9 @@ fail:
|
|||
|
||||
static uint32_t obs_lua_source_get_height(void *data)
|
||||
{
|
||||
struct obs_lua_data * ld = data;
|
||||
struct obs_lua_source *ls = ld->ls;
|
||||
uint32_t height = 0;
|
||||
struct obs_lua_data *ld = data;
|
||||
struct obs_lua_source *ls = ld->ls;
|
||||
uint32_t height = 0;
|
||||
|
||||
pthread_mutex_lock(&ls->definition_mutex);
|
||||
if (!ls->script)
|
||||
|
|
@ -363,9 +344,9 @@ fail:
|
|||
|
||||
static obs_properties_t *obs_lua_source_get_properties(void *data)
|
||||
{
|
||||
struct obs_lua_data * ld = data;
|
||||
struct obs_lua_source *ls = ld->ls;
|
||||
obs_properties_t * props = NULL;
|
||||
struct obs_lua_data *ld = data;
|
||||
struct obs_lua_source *ls = ld->ls;
|
||||
obs_properties_t *props = NULL;
|
||||
|
||||
pthread_mutex_lock(&ls->definition_mutex);
|
||||
if (!ls->script)
|
||||
|
|
@ -390,7 +371,7 @@ fail:
|
|||
|
||||
static void obs_lua_source_update(void *data, obs_data_t *settings)
|
||||
{
|
||||
struct obs_lua_data * ld = data;
|
||||
struct obs_lua_data *ld = data;
|
||||
struct obs_lua_source *ls = ld->ls;
|
||||
|
||||
pthread_mutex_lock(&ls->definition_mutex);
|
||||
|
|
@ -411,17 +392,17 @@ fail:
|
|||
pthread_mutex_unlock(&ls->definition_mutex);
|
||||
}
|
||||
|
||||
#define DEFINE_VOID_DATA_CALLBACK(name) \
|
||||
static void obs_lua_source_ ## name(void *data) \
|
||||
{ \
|
||||
struct obs_lua_data * ld = data; \
|
||||
struct obs_lua_source *ls = ld->ls; \
|
||||
if (!have_func(name)) \
|
||||
return; \
|
||||
lock_script(); \
|
||||
ls_push_data(); \
|
||||
call_func(name, 1, 0); \
|
||||
unlock_script(); \
|
||||
#define DEFINE_VOID_DATA_CALLBACK(name) \
|
||||
static void obs_lua_source_##name(void *data) \
|
||||
{ \
|
||||
struct obs_lua_data *ld = data; \
|
||||
struct obs_lua_source *ls = ld->ls; \
|
||||
if (!have_func(name)) \
|
||||
return; \
|
||||
lock_script(); \
|
||||
ls_push_data(); \
|
||||
call_func(name, 1, 0); \
|
||||
unlock_script(); \
|
||||
}
|
||||
DEFINE_VOID_DATA_CALLBACK(activate)
|
||||
DEFINE_VOID_DATA_CALLBACK(deactivate)
|
||||
|
|
@ -431,7 +412,7 @@ DEFINE_VOID_DATA_CALLBACK(hide)
|
|||
|
||||
static void obs_lua_source_video_tick(void *data, float seconds)
|
||||
{
|
||||
struct obs_lua_data * ld = data;
|
||||
struct obs_lua_data *ld = data;
|
||||
struct obs_lua_source *ls = ld->ls;
|
||||
|
||||
pthread_mutex_lock(&ls->definition_mutex);
|
||||
|
|
@ -454,7 +435,7 @@ fail:
|
|||
|
||||
static void obs_lua_source_video_render(void *data, gs_effect_t *effect)
|
||||
{
|
||||
struct obs_lua_data * ld = data;
|
||||
struct obs_lua_data *ld = data;
|
||||
struct obs_lua_source *ls = ld->ls;
|
||||
|
||||
pthread_mutex_lock(&ls->definition_mutex);
|
||||
|
|
@ -477,7 +458,7 @@ fail:
|
|||
|
||||
static void obs_lua_source_save(void *data, obs_data_t *settings)
|
||||
{
|
||||
struct obs_lua_data * ld = data;
|
||||
struct obs_lua_data *ld = data;
|
||||
struct obs_lua_source *ls = ld->ls;
|
||||
|
||||
pthread_mutex_lock(&ls->definition_mutex);
|
||||
|
|
@ -500,7 +481,7 @@ fail:
|
|||
|
||||
static void obs_lua_source_load(void *data, obs_data_t *settings)
|
||||
{
|
||||
struct obs_lua_data * ld = data;
|
||||
struct obs_lua_data *ld = data;
|
||||
struct obs_lua_source *ls = ld->ls;
|
||||
|
||||
pthread_mutex_lock(&ls->definition_mutex);
|
||||
|
|
@ -523,7 +504,7 @@ fail:
|
|||
|
||||
static void source_type_unload(struct obs_lua_source *ls)
|
||||
{
|
||||
#define unref(name) \
|
||||
#define unref(name) \
|
||||
luaL_unref(ls->script, LUA_REGISTRYINDEX, name); \
|
||||
name = LUA_REFNIL
|
||||
|
||||
|
|
@ -614,9 +595,9 @@ static int obs_lua_register_source(lua_State *script)
|
|||
v = existing ? existing : &ls;
|
||||
|
||||
v->script = script;
|
||||
v->id = id;
|
||||
v->id = id;
|
||||
|
||||
info.id = v->id;
|
||||
info.id = v->id;
|
||||
info.type = (enum obs_source_type)get_table_int(script, -1, "type");
|
||||
|
||||
info.output_flags = get_table_int(script, -1, "output_flags");
|
||||
|
|
@ -628,16 +609,14 @@ static int obs_lua_register_source(lua_State *script)
|
|||
lua_pop(script, 1);
|
||||
}
|
||||
|
||||
if (!v->display_name ||
|
||||
!*v->display_name ||
|
||||
!*info.id ||
|
||||
if (!v->display_name || !*v->display_name || !*info.id ||
|
||||
!info.output_flags)
|
||||
goto fail;
|
||||
|
||||
#define get_callback(val) \
|
||||
do { \
|
||||
get_callback_from_table(script, -1, #val, &v->func_ ## val); \
|
||||
info.val = obs_lua_source_ ## val; \
|
||||
#define get_callback(val) \
|
||||
do { \
|
||||
get_callback_from_table(script, -1, #val, &v->func_##val); \
|
||||
info.val = obs_lua_source_##val; \
|
||||
} while (false)
|
||||
|
||||
get_callback(create);
|
||||
|
|
@ -657,16 +636,21 @@ static int obs_lua_register_source(lua_State *script)
|
|||
#undef get_callback
|
||||
|
||||
get_callback_from_table(script, -1, "get_defaults",
|
||||
&v->func_get_defaults);
|
||||
&v->func_get_defaults);
|
||||
|
||||
if (!existing) {
|
||||
ls.data = current_lua_script;
|
||||
|
||||
pthread_mutex_init(&ls.definition_mutex, NULL);
|
||||
info.type_data = bmemdup(&ls, sizeof(ls));
|
||||
pthread_mutexattr_t mutexattr;
|
||||
pthread_mutexattr_init(&mutexattr);
|
||||
pthread_mutexattr_settype(&mutexattr, PTHREAD_MUTEX_RECURSIVE);
|
||||
pthread_mutex_init(&ls.definition_mutex, &mutexattr);
|
||||
pthread_mutexattr_destroy(&mutexattr);
|
||||
|
||||
info.type_data = bmemdup(&ls, sizeof(ls));
|
||||
info.free_type_data = obs_lua_source_free_type_data;
|
||||
info.get_name = obs_lua_source_get_name;
|
||||
info.get_defaults2 = obs_lua_source_get_defaults;
|
||||
info.get_name = obs_lua_source_get_name;
|
||||
info.get_defaults2 = obs_lua_source_get_defaults;
|
||||
obs_register_source(&info);
|
||||
|
||||
pthread_mutex_lock(&lua_source_def_mutex);
|
||||
|
|
@ -674,7 +658,8 @@ static int obs_lua_register_source(lua_State *script)
|
|||
|
||||
struct obs_lua_source *next = first_source_def;
|
||||
v->next = next;
|
||||
if (next) next->p_prev_next = &v->next;
|
||||
if (next)
|
||||
next->p_prev_next = &v->next;
|
||||
v->p_prev_next = &first_source_def;
|
||||
first_source_def = v;
|
||||
|
||||
|
|
@ -690,15 +675,15 @@ static int obs_lua_register_source(lua_State *script)
|
|||
|
||||
if (have_func(create)) {
|
||||
obs_source_t *source = ld->source;
|
||||
obs_data_t *settings = obs_source_get_settings(
|
||||
source);
|
||||
obs_data_t *settings =
|
||||
obs_source_get_settings(source);
|
||||
|
||||
ls_push_libobs_obj(obs_data_t, settings, false);
|
||||
ls_push_libobs_obj(obs_source_t, source, false);
|
||||
call_func(create, 2, 1);
|
||||
|
||||
ld->lua_data_ref = luaL_ref(ls->script,
|
||||
LUA_REGISTRYINDEX);
|
||||
ld->lua_data_ref =
|
||||
luaL_ref(ls->script, LUA_REGISTRYINDEX);
|
||||
obs_data_release(settings);
|
||||
}
|
||||
|
||||
|
|
@ -727,7 +712,7 @@ void add_lua_source_functions(lua_State *script)
|
|||
}
|
||||
|
||||
static inline void undef_source_type(struct obs_lua_script *data,
|
||||
struct obs_lua_source *ls)
|
||||
struct obs_lua_source *ls)
|
||||
{
|
||||
pthread_mutex_lock(&ls->definition_mutex);
|
||||
pthread_mutex_lock(&data->mutex);
|
||||
|
|
|
|||
169
deps/obs-scripting/obs-scripting-lua.c
vendored
169
deps/obs-scripting/obs-scripting-lua.c
vendored
|
|
@ -26,17 +26,17 @@
|
|||
/* ========================================================================= */
|
||||
|
||||
#if ARCH_BITS == 64
|
||||
# define ARCH_DIR "64bit"
|
||||
#define ARCH_DIR "64bit"
|
||||
#else
|
||||
# define ARCH_DIR "32bit"
|
||||
#define ARCH_DIR "32bit"
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
# define SO_EXT "dylib"
|
||||
#define SO_EXT "dylib"
|
||||
#elif _WIN32
|
||||
# define SO_EXT "dll"
|
||||
#define SO_EXT "dll"
|
||||
#else
|
||||
# define SO_EXT "so"
|
||||
#define SO_EXT "so"
|
||||
#endif
|
||||
|
||||
static const char *startup_script_template = "\
|
||||
|
|
@ -59,15 +59,14 @@ static struct obs_lua_script *first_tick_script = NULL;
|
|||
|
||||
pthread_mutex_t lua_source_def_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
#define ls_get_libobs_obj(type, lua_index, obs_obj) \
|
||||
ls_get_libobs_obj_(script, #type " *", lua_index, obs_obj, \
|
||||
NULL, __FUNCTION__, __LINE__)
|
||||
#define ls_push_libobs_obj(type, obs_obj, ownership) \
|
||||
ls_push_libobs_obj_(script, #type " *", obs_obj, ownership, \
|
||||
NULL, __FUNCTION__, __LINE__)
|
||||
#define ls_get_libobs_obj(type, lua_index, obs_obj) \
|
||||
ls_get_libobs_obj_(script, #type " *", lua_index, obs_obj, NULL, \
|
||||
__FUNCTION__, __LINE__)
|
||||
#define ls_push_libobs_obj(type, obs_obj, ownership) \
|
||||
ls_push_libobs_obj_(script, #type " *", obs_obj, ownership, NULL, \
|
||||
__FUNCTION__, __LINE__)
|
||||
#define call_func(name, args, rets) \
|
||||
call_func_(script, cb->reg_idx, \
|
||||
args, rets, #name, __FUNCTION__)
|
||||
call_func_(script, cb->reg_idx, args, rets, #name, __FUNCTION__)
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
|
|
@ -98,7 +97,7 @@ static bool load_lua_script(struct obs_lua_script *data)
|
|||
|
||||
if (luaL_dostring(script, startup_script) != 0) {
|
||||
script_warn(&data->base, "Error executing startup script 1: %s",
|
||||
lua_tostring(script, -1));
|
||||
lua_tostring(script, -1));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
|
@ -108,7 +107,7 @@ static bool load_lua_script(struct obs_lua_script *data)
|
|||
|
||||
if (ret != 0) {
|
||||
script_warn(&data->base, "Error executing startup script 2: %s",
|
||||
lua_tostring(script, -1));
|
||||
lua_tostring(script, -1));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
|
@ -122,13 +121,13 @@ static bool load_lua_script(struct obs_lua_script *data)
|
|||
|
||||
if (luaL_loadfile(script, data->base.path.array) != 0) {
|
||||
script_warn(&data->base, "Error loading file: %s",
|
||||
lua_tostring(script, -1));
|
||||
lua_tostring(script, -1));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (lua_pcall(script, 0, LUA_MULTRET, 0) != 0) {
|
||||
script_warn(&data->base, "Error running file: %s",
|
||||
lua_tostring(script, -1));
|
||||
lua_tostring(script, -1));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
|
@ -148,7 +147,8 @@ static bool load_lua_script(struct obs_lua_script *data)
|
|||
struct obs_lua_script *next = first_tick_script;
|
||||
data->next_tick = next;
|
||||
data->p_prev_next_tick = &first_tick_script;
|
||||
if (next) next->p_prev_next_tick = &data->next_tick;
|
||||
if (next)
|
||||
next->p_prev_next_tick = &data->next_tick;
|
||||
first_tick_script = data;
|
||||
|
||||
data->tick = luaL_ref(script, LUA_REGISTRYINDEX);
|
||||
|
|
@ -178,18 +178,20 @@ static bool load_lua_script(struct obs_lua_script *data)
|
|||
if (lua_isfunction(script, -1)) {
|
||||
ls_push_libobs_obj(obs_data_t, data->base.settings, false);
|
||||
if (lua_pcall(script, 1, 0, 0) != 0) {
|
||||
script_warn(&data->base, "Error calling "
|
||||
"script_defaults: %s",
|
||||
lua_tostring(script, -1));
|
||||
script_warn(&data->base,
|
||||
"Error calling "
|
||||
"script_defaults: %s",
|
||||
lua_tostring(script, -1));
|
||||
}
|
||||
}
|
||||
|
||||
lua_getglobal(script, "script_description");
|
||||
if (lua_isfunction(script, -1)) {
|
||||
if (lua_pcall(script, 0, 1, 0) != 0) {
|
||||
script_warn(&data->base, "Error calling "
|
||||
"script_defaults: %s",
|
||||
lua_tostring(script, -1));
|
||||
script_warn(&data->base,
|
||||
"Error calling "
|
||||
"script_defaults: %s",
|
||||
lua_tostring(script, -1));
|
||||
} else {
|
||||
const char *desc = lua_tostring(script, -1);
|
||||
dstr_copy(&data->base.desc, desc);
|
||||
|
|
@ -200,9 +202,10 @@ static bool load_lua_script(struct obs_lua_script *data)
|
|||
if (lua_isfunction(script, -1)) {
|
||||
ls_push_libobs_obj(obs_data_t, data->base.settings, false);
|
||||
if (lua_pcall(script, 1, 0, 0) != 0) {
|
||||
script_warn(&data->base, "Error calling "
|
||||
"script_load: %s",
|
||||
lua_tostring(script, -1));
|
||||
script_warn(&data->base,
|
||||
"Error calling "
|
||||
"script_load: %s",
|
||||
lua_tostring(script, -1));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -248,7 +251,8 @@ static inline void lua_obs_timer_init(struct lua_obs_timer *timer)
|
|||
struct lua_obs_timer *next = first_timer;
|
||||
timer->next = next;
|
||||
timer->p_prev_next = &first_timer;
|
||||
if (next) next->p_prev_next = &timer->next;
|
||||
if (next)
|
||||
next->p_prev_next = &timer->next;
|
||||
first_timer = timer;
|
||||
|
||||
pthread_mutex_unlock(&timer_mutex);
|
||||
|
|
@ -257,12 +261,13 @@ static inline void lua_obs_timer_init(struct lua_obs_timer *timer)
|
|||
static inline void lua_obs_timer_remove(struct lua_obs_timer *timer)
|
||||
{
|
||||
struct lua_obs_timer *next = timer->next;
|
||||
if (next) next->p_prev_next = timer->p_prev_next;
|
||||
if (next)
|
||||
next->p_prev_next = timer->p_prev_next;
|
||||
*timer->p_prev_next = timer->next;
|
||||
}
|
||||
|
||||
static inline struct lua_obs_callback *lua_obs_timer_cb(
|
||||
struct lua_obs_timer *timer)
|
||||
static inline struct lua_obs_callback *
|
||||
lua_obs_timer_cb(struct lua_obs_timer *timer)
|
||||
{
|
||||
return &((struct lua_obs_callback *)timer)[-1];
|
||||
}
|
||||
|
|
@ -273,7 +278,8 @@ static int timer_remove(lua_State *script)
|
|||
return 0;
|
||||
|
||||
struct lua_obs_callback *cb = find_lua_obs_callback(script, 1);
|
||||
if (cb) remove_lua_obs_callback(cb);
|
||||
if (cb)
|
||||
remove_lua_obs_callback(cb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -304,8 +310,8 @@ static int timer_add(lua_State *script)
|
|||
if (!ms)
|
||||
return 0;
|
||||
|
||||
struct lua_obs_callback *cb = add_lua_obs_callback_extra(script, 1,
|
||||
sizeof(struct lua_obs_timer));
|
||||
struct lua_obs_callback *cb = add_lua_obs_callback_extra(
|
||||
script, 1, sizeof(struct lua_obs_timer));
|
||||
struct lua_obs_timer *timer = lua_obs_callback_extra_data(cb);
|
||||
|
||||
timer->interval = (uint64_t)ms * 1000000ULL;
|
||||
|
|
@ -324,7 +330,7 @@ static void obs_lua_main_render_callback(void *priv, uint32_t cx, uint32_t cy)
|
|||
|
||||
if (cb->base.removed) {
|
||||
obs_remove_main_render_callback(obs_lua_main_render_callback,
|
||||
cb);
|
||||
cb);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -343,7 +349,8 @@ static int obs_lua_remove_main_render_callback(lua_State *script)
|
|||
return 0;
|
||||
|
||||
struct lua_obs_callback *cb = find_lua_obs_callback(script, 1);
|
||||
if (cb) remove_lua_obs_callback(cb);
|
||||
if (cb)
|
||||
remove_lua_obs_callback(cb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -388,7 +395,8 @@ static int obs_lua_remove_tick_callback(lua_State *script)
|
|||
return 0;
|
||||
|
||||
struct lua_obs_callback *cb = find_lua_obs_callback(script, 1);
|
||||
if (cb) remove_lua_obs_callback(cb);
|
||||
if (cb)
|
||||
remove_lua_obs_callback(cb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -447,15 +455,15 @@ static int obs_lua_signal_handler_disconnect(lua_State *script)
|
|||
const char *cb_signal =
|
||||
calldata_string(&cb->base.extra, "signal");
|
||||
|
||||
if (cb_signal &&
|
||||
strcmp(signal, cb_signal) != 0 &&
|
||||
if (cb_signal && strcmp(signal, cb_signal) != 0 &&
|
||||
handler == cb_handler)
|
||||
break;
|
||||
|
||||
cb = find_next_lua_obs_callback(script, cb, 3);
|
||||
}
|
||||
|
||||
if (cb) remove_lua_obs_callback(cb);
|
||||
if (cb)
|
||||
remove_lua_obs_callback(cb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -465,7 +473,7 @@ static void defer_connect(void *p_cb)
|
|||
|
||||
signal_handler_t *handler = calldata_ptr(&cb->extra, "handler");
|
||||
const char *signal = calldata_string(&cb->extra, "signal");
|
||||
signal_handler_connect(handler, signal, calldata_signal_callback, cb);
|
||||
signal_handler_connect(handler, signal, calldata_signal_callback, cb);
|
||||
}
|
||||
|
||||
static int obs_lua_signal_handler_connect(lua_State *script)
|
||||
|
|
@ -491,7 +499,7 @@ static int obs_lua_signal_handler_connect(lua_State *script)
|
|||
/* -------------------------------------------- */
|
||||
|
||||
static void calldata_signal_callback_global(void *priv, const char *signal,
|
||||
calldata_t *cd)
|
||||
calldata_t *cd)
|
||||
{
|
||||
struct lua_obs_callback *cb = priv;
|
||||
lua_State *script = cb->script;
|
||||
|
|
@ -530,7 +538,8 @@ static int obs_lua_signal_handler_disconnect_global(lua_State *script)
|
|||
cb = find_next_lua_obs_callback(script, cb, 3);
|
||||
}
|
||||
|
||||
if (cb) remove_lua_obs_callback(cb);
|
||||
if (cb)
|
||||
remove_lua_obs_callback(cb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -539,8 +548,8 @@ static void defer_connect_global(void *p_cb)
|
|||
struct script_callback *cb = p_cb;
|
||||
|
||||
signal_handler_t *handler = calldata_ptr(&cb->extra, "handler");
|
||||
signal_handler_connect_global(handler,
|
||||
calldata_signal_callback_global, cb);
|
||||
signal_handler_connect_global(handler, calldata_signal_callback_global,
|
||||
cb);
|
||||
}
|
||||
|
||||
static int obs_lua_signal_handler_connect_global(lua_State *script)
|
||||
|
|
@ -581,8 +590,11 @@ static int enum_sources(lua_State *script)
|
|||
|
||||
/* -------------------------------------------- */
|
||||
|
||||
static bool source_enum_filters_proc(obs_source_t *source, obs_source_t *filter, void *param)
|
||||
static void source_enum_filters_proc(obs_source_t *source, obs_source_t *filter,
|
||||
void *param)
|
||||
{
|
||||
UNUSED_PARAMETER(source);
|
||||
|
||||
lua_State *script = param;
|
||||
|
||||
obs_source_get_ref(filter);
|
||||
|
|
@ -590,7 +602,6 @@ static bool source_enum_filters_proc(obs_source_t *source, obs_source_t *filter,
|
|||
|
||||
size_t idx = lua_rawlen(script, -2);
|
||||
lua_rawseti(script, -2, (int)idx + 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
static int source_enum_filters(lua_State *script)
|
||||
|
|
@ -604,11 +615,10 @@ static int source_enum_filters(lua_State *script)
|
|||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
||||
static bool enum_items_proc(obs_scene_t *scene, obs_sceneitem_t *item,
|
||||
void *param)
|
||||
void *param)
|
||||
{
|
||||
lua_State *script = param;
|
||||
|
||||
|
|
@ -644,7 +654,7 @@ static void on_remove_hotkey(void *p_cb)
|
|||
obs_hotkey_id id = (obs_hotkey_id)calldata_int(&cb->base.extra, "id");
|
||||
|
||||
if (id != OBS_INVALID_HOTKEY_ID)
|
||||
defer_call_post(defer_hotkey_unregister, (void*)(uintptr_t)id);
|
||||
defer_call_post(defer_hotkey_unregister, (void *)(uintptr_t)id);
|
||||
}
|
||||
|
||||
static void hotkey_pressed(void *p_cb, bool pressed)
|
||||
|
|
@ -673,8 +683,8 @@ static void defer_hotkey_unpressed(void *p_cb)
|
|||
hotkey_pressed(p_cb, false);
|
||||
}
|
||||
|
||||
static void hotkey_callback(void *p_cb, obs_hotkey_id id,
|
||||
obs_hotkey_t *hotkey, bool pressed)
|
||||
static void hotkey_callback(void *p_cb, obs_hotkey_id id, obs_hotkey_t *hotkey,
|
||||
bool pressed)
|
||||
{
|
||||
struct lua_obs_callback *cb = p_cb;
|
||||
|
||||
|
|
@ -696,7 +706,8 @@ static int hotkey_unregister(lua_State *script)
|
|||
return 0;
|
||||
|
||||
struct lua_obs_callback *cb = find_lua_obs_callback(script, 1);
|
||||
if (cb) remove_lua_obs_callback(cb);
|
||||
if (cb)
|
||||
remove_lua_obs_callback(cb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -727,7 +738,7 @@ static int hotkey_register_frontend(lua_State *script)
|
|||
/* -------------------------------------------- */
|
||||
|
||||
static bool button_prop_clicked(obs_properties_t *props, obs_property_t *p,
|
||||
void *p_cb)
|
||||
void *p_cb)
|
||||
{
|
||||
struct lua_obs_callback *cb = p_cb;
|
||||
lua_State *script = cb->script;
|
||||
|
|
@ -773,7 +784,7 @@ static int properties_add_button(lua_State *script)
|
|||
|
||||
struct lua_obs_callback *cb = add_lua_obs_callback(script, 4);
|
||||
p = obs_properties_add_button2(props, name, text, button_prop_clicked,
|
||||
cb);
|
||||
cb);
|
||||
|
||||
if (!p || !ls_push_libobs_obj(obs_property_t, p, false))
|
||||
return 0;
|
||||
|
|
@ -783,7 +794,7 @@ static int properties_add_button(lua_State *script)
|
|||
/* -------------------------------------------- */
|
||||
|
||||
static bool modified_callback(void *p_cb, obs_properties_t *props,
|
||||
obs_property_t *p, obs_data_t *settings)
|
||||
obs_property_t *p, obs_data_t *settings)
|
||||
{
|
||||
struct lua_obs_callback *cb = p_cb;
|
||||
lua_State *script = cb->script;
|
||||
|
|
@ -976,11 +987,11 @@ static int lua_script_log(lua_State *script)
|
|||
|
||||
static void add_hook_functions(lua_State *script)
|
||||
{
|
||||
#define add_func(name, func) \
|
||||
do { \
|
||||
lua_pushstring(script, name); \
|
||||
#define add_func(name, func) \
|
||||
do { \
|
||||
lua_pushstring(script, name); \
|
||||
lua_pushcfunction(script, func); \
|
||||
lua_rawset(script, -3); \
|
||||
lua_rawset(script, -3); \
|
||||
} while (false)
|
||||
|
||||
lua_getglobal(script, "_G");
|
||||
|
|
@ -1005,31 +1016,24 @@ static void add_hook_functions(lua_State *script)
|
|||
add_func("calldata_source", calldata_source);
|
||||
add_func("calldata_sceneitem", calldata_sceneitem);
|
||||
add_func("obs_add_main_render_callback",
|
||||
obs_lua_add_main_render_callback);
|
||||
obs_lua_add_main_render_callback);
|
||||
add_func("obs_remove_main_render_callback",
|
||||
obs_lua_remove_main_render_callback);
|
||||
add_func("obs_add_tick_callback",
|
||||
obs_lua_add_tick_callback);
|
||||
add_func("obs_remove_tick_callback",
|
||||
obs_lua_remove_tick_callback);
|
||||
add_func("signal_handler_connect",
|
||||
obs_lua_signal_handler_connect);
|
||||
obs_lua_remove_main_render_callback);
|
||||
add_func("obs_add_tick_callback", obs_lua_add_tick_callback);
|
||||
add_func("obs_remove_tick_callback", obs_lua_remove_tick_callback);
|
||||
add_func("signal_handler_connect", obs_lua_signal_handler_connect);
|
||||
add_func("signal_handler_disconnect",
|
||||
obs_lua_signal_handler_disconnect);
|
||||
obs_lua_signal_handler_disconnect);
|
||||
add_func("signal_handler_connect_global",
|
||||
obs_lua_signal_handler_connect_global);
|
||||
obs_lua_signal_handler_connect_global);
|
||||
add_func("signal_handler_disconnect_global",
|
||||
obs_lua_signal_handler_disconnect_global);
|
||||
add_func("obs_hotkey_unregister",
|
||||
hotkey_unregister);
|
||||
add_func("obs_hotkey_register_frontend",
|
||||
hotkey_register_frontend);
|
||||
add_func("obs_properties_add_button",
|
||||
properties_add_button);
|
||||
obs_lua_signal_handler_disconnect_global);
|
||||
add_func("obs_hotkey_unregister", hotkey_unregister);
|
||||
add_func("obs_hotkey_register_frontend", hotkey_register_frontend);
|
||||
add_func("obs_properties_add_button", properties_add_button);
|
||||
add_func("obs_property_set_modified_callback",
|
||||
property_set_modified_callback);
|
||||
add_func("remove_current_callback",
|
||||
remove_current_callback);
|
||||
property_set_modified_callback);
|
||||
add_func("remove_current_callback", remove_current_callback);
|
||||
|
||||
lua_pop(script, 1);
|
||||
#undef add_func
|
||||
|
|
@ -1166,7 +1170,8 @@ void obs_lua_script_unload(obs_script_t *s)
|
|||
pthread_mutex_lock(&tick_mutex);
|
||||
|
||||
struct obs_lua_script *next = data->next_tick;
|
||||
if (next) next->p_prev_next_tick = data->p_prev_next_tick;
|
||||
if (next)
|
||||
next->p_prev_next_tick = data->p_prev_next_tick;
|
||||
*data->p_prev_next_tick = next;
|
||||
|
||||
pthread_mutex_unlock(&tick_mutex);
|
||||
|
|
@ -1258,7 +1263,7 @@ obs_properties_t *obs_lua_script_get_properties(obs_script_t *s)
|
|||
pthread_mutex_lock(&data->mutex);
|
||||
|
||||
call_func_(script, data->get_properties, 0, 1, "script_properties",
|
||||
__FUNCTION__);
|
||||
__FUNCTION__);
|
||||
ls_get_libobs_obj(obs_properties_t, -1, &props);
|
||||
|
||||
pthread_mutex_unlock(&data->mutex);
|
||||
|
|
|
|||
87
deps/obs-scripting/obs-scripting-lua.h
vendored
87
deps/obs-scripting/obs-scripting-lua.h
vendored
|
|
@ -46,12 +46,11 @@
|
|||
#include "obs-scripting-internal.h"
|
||||
#include "obs-scripting-callback.h"
|
||||
|
||||
#define do_log(level, format, ...) \
|
||||
blog(level, "[Lua] " format, ##__VA_ARGS__)
|
||||
#define do_log(level, format, ...) blog(level, "[Lua] " format, ##__VA_ARGS__)
|
||||
|
||||
#define warn(format, ...) do_log(LOG_WARNING, format, ##__VA_ARGS__)
|
||||
#define info(format, ...) do_log(LOG_INFO, format, ##__VA_ARGS__)
|
||||
#define debug(format, ...) do_log(LOG_DEBUG, format, ##__VA_ARGS__)
|
||||
#define warn(format, ...) do_log(LOG_WARNING, format, ##__VA_ARGS__)
|
||||
#define info(format, ...) do_log(LOG_INFO, format, ##__VA_ARGS__)
|
||||
#define debug(format, ...) do_log(LOG_DEBUG, format, ##__VA_ARGS__)
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
||||
|
|
@ -87,15 +86,15 @@ struct obs_lua_script {
|
|||
bool defined_sources;
|
||||
};
|
||||
|
||||
#define lock_callback() \
|
||||
struct obs_lua_script *__last_script = current_lua_script; \
|
||||
struct lua_obs_callback *__last_callback = current_lua_cb; \
|
||||
current_lua_cb = cb; \
|
||||
#define lock_callback() \
|
||||
struct obs_lua_script *__last_script = current_lua_script; \
|
||||
struct lua_obs_callback *__last_callback = current_lua_cb; \
|
||||
current_lua_cb = cb; \
|
||||
current_lua_script = (struct obs_lua_script *)cb->base.script; \
|
||||
pthread_mutex_lock(¤t_lua_script->mutex);
|
||||
#define unlock_callback() \
|
||||
#define unlock_callback() \
|
||||
pthread_mutex_unlock(¤t_lua_script->mutex); \
|
||||
current_lua_script = __last_script; \
|
||||
current_lua_script = __last_script; \
|
||||
current_lua_cb = __last_callback;
|
||||
|
||||
/* ------------------------------------------------ */
|
||||
|
|
@ -107,16 +106,13 @@ struct lua_obs_callback {
|
|||
int reg_idx;
|
||||
};
|
||||
|
||||
static inline struct lua_obs_callback *add_lua_obs_callback_extra(
|
||||
lua_State *script,
|
||||
int stack_idx,
|
||||
size_t extra_size)
|
||||
static inline struct lua_obs_callback *
|
||||
add_lua_obs_callback_extra(lua_State *script, int stack_idx, size_t extra_size)
|
||||
{
|
||||
struct obs_lua_script *data = current_lua_script;
|
||||
struct lua_obs_callback *cb = add_script_callback(
|
||||
&data->first_callback,
|
||||
(obs_script_t *)data,
|
||||
sizeof(*cb) + extra_size);
|
||||
struct lua_obs_callback *cb =
|
||||
add_script_callback(&data->first_callback, (obs_script_t *)data,
|
||||
sizeof(*cb) + extra_size);
|
||||
|
||||
lua_pushvalue(script, stack_idx);
|
||||
cb->reg_idx = luaL_ref(script, LUA_REGISTRYINDEX);
|
||||
|
|
@ -124,25 +120,26 @@ static inline struct lua_obs_callback *add_lua_obs_callback_extra(
|
|||
return cb;
|
||||
}
|
||||
|
||||
static inline struct lua_obs_callback *add_lua_obs_callback(
|
||||
lua_State *script, int stack_idx)
|
||||
static inline struct lua_obs_callback *add_lua_obs_callback(lua_State *script,
|
||||
int stack_idx)
|
||||
{
|
||||
return add_lua_obs_callback_extra(script, stack_idx, 0);
|
||||
}
|
||||
|
||||
static inline void *lua_obs_callback_extra_data(struct lua_obs_callback *cb)
|
||||
{
|
||||
return (void*)&cb[1];
|
||||
return (void *)&cb[1];
|
||||
}
|
||||
|
||||
static inline struct obs_lua_script *lua_obs_callback_script(
|
||||
struct lua_obs_callback *cb)
|
||||
static inline struct obs_lua_script *
|
||||
lua_obs_callback_script(struct lua_obs_callback *cb)
|
||||
{
|
||||
return (struct obs_lua_script *)cb->base.script;
|
||||
}
|
||||
|
||||
static inline struct lua_obs_callback *find_next_lua_obs_callback(
|
||||
lua_State *script, struct lua_obs_callback *cb, int stack_idx)
|
||||
static inline struct lua_obs_callback *
|
||||
find_next_lua_obs_callback(lua_State *script, struct lua_obs_callback *cb,
|
||||
int stack_idx)
|
||||
{
|
||||
struct obs_lua_script *data = current_lua_script;
|
||||
|
||||
|
|
@ -163,8 +160,8 @@ static inline struct lua_obs_callback *find_next_lua_obs_callback(
|
|||
return cb;
|
||||
}
|
||||
|
||||
static inline struct lua_obs_callback *find_lua_obs_callback(
|
||||
lua_State *script, int stack_idx)
|
||||
static inline struct lua_obs_callback *find_lua_obs_callback(lua_State *script,
|
||||
int stack_idx)
|
||||
{
|
||||
return find_next_lua_obs_callback(script, NULL, stack_idx);
|
||||
}
|
||||
|
|
@ -204,9 +201,8 @@ static int is_function(lua_State *script, int idx)
|
|||
|
||||
typedef int (*param_cb)(lua_State *script, int idx);
|
||||
|
||||
static inline bool verify_args1_(lua_State *script,
|
||||
param_cb param1_check,
|
||||
const char *func)
|
||||
static inline bool verify_args1_(lua_State *script, param_cb param1_check,
|
||||
const char *func)
|
||||
{
|
||||
if (lua_gettop(script) != 1) {
|
||||
warn("Wrong number of parameters for %s", func);
|
||||
|
|
@ -223,9 +219,9 @@ static inline bool verify_args1_(lua_State *script,
|
|||
#define verify_args1(script, param1_check) \
|
||||
verify_args1_(script, param1_check, __FUNCTION__)
|
||||
|
||||
static inline bool call_func_(lua_State *script,
|
||||
int reg_idx, int args, int rets,
|
||||
const char *func, const char *display_name)
|
||||
static inline bool call_func_(lua_State *script, int reg_idx, int args,
|
||||
int rets, const char *func,
|
||||
const char *display_name)
|
||||
{
|
||||
if (reg_idx == LUA_REFNIL)
|
||||
return false;
|
||||
|
|
@ -237,8 +233,7 @@ static inline bool call_func_(lua_State *script,
|
|||
|
||||
if (lua_pcall(script, args, rets, 0) != 0) {
|
||||
script_warn(&data->base, "Failed to call %s for %s: %s", func,
|
||||
display_name,
|
||||
lua_tostring(script, -1));
|
||||
display_name, lua_tostring(script, -1));
|
||||
lua_pop(script, 1);
|
||||
return false;
|
||||
}
|
||||
|
|
@ -246,19 +241,11 @@ static inline bool call_func_(lua_State *script,
|
|||
return true;
|
||||
}
|
||||
|
||||
bool ls_get_libobs_obj_(lua_State * script,
|
||||
const char *type,
|
||||
int lua_idx,
|
||||
void * libobs_out,
|
||||
const char *id,
|
||||
const char *func,
|
||||
int line);
|
||||
bool ls_push_libobs_obj_(lua_State * script,
|
||||
const char *type,
|
||||
void * libobs_in,
|
||||
bool ownership,
|
||||
const char *id,
|
||||
const char *func,
|
||||
int line);
|
||||
bool ls_get_libobs_obj_(lua_State *script, const char *type, int lua_idx,
|
||||
void *libobs_out, const char *id, const char *func,
|
||||
int line);
|
||||
bool ls_push_libobs_obj_(lua_State *script, const char *type, void *libobs_in,
|
||||
bool ownership, const char *id, const char *func,
|
||||
int line);
|
||||
|
||||
extern void add_lua_source_functions(lua_State *script);
|
||||
|
|
|
|||
|
|
@ -20,12 +20,11 @@
|
|||
|
||||
#include "obs-scripting-python.h"
|
||||
|
||||
#define libobs_to_py(type, obs_obj, ownership, py_obj) \
|
||||
libobs_to_py_(#type " *", obs_obj, ownership, py_obj, \
|
||||
NULL, __func__, __LINE__)
|
||||
#define libobs_to_py(type, obs_obj, ownership, py_obj) \
|
||||
libobs_to_py_(#type " *", obs_obj, ownership, py_obj, NULL, __func__, \
|
||||
__LINE__)
|
||||
#define py_to_libobs(type, py_obj, libobs_out) \
|
||||
py_to_libobs_(#type " *", py_obj, libobs_out, \
|
||||
NULL, __func__, __LINE__)
|
||||
py_to_libobs_(#type " *", py_obj, libobs_out, NULL, __func__, __LINE__)
|
||||
|
||||
/* ----------------------------------- */
|
||||
|
||||
|
|
@ -257,7 +256,7 @@ static PyObject *set_current_profile(PyObject *self, PyObject *args)
|
|||
/* ----------------------------------- */
|
||||
|
||||
static void frontend_save_callback(obs_data_t *save_data, bool saving,
|
||||
void *priv)
|
||||
void *priv)
|
||||
{
|
||||
struct python_obs_callback *cb = priv;
|
||||
|
||||
|
|
@ -303,8 +302,10 @@ static PyObject *remove_save_callback(PyObject *self, PyObject *args)
|
|||
if (!py_cb || !PyFunction_Check(py_cb))
|
||||
return python_none();
|
||||
|
||||
struct python_obs_callback *cb = find_python_obs_callback(script, py_cb);
|
||||
if (cb) remove_python_obs_callback(cb);
|
||||
struct python_obs_callback *cb =
|
||||
find_python_obs_callback(script, py_cb);
|
||||
if (cb)
|
||||
remove_python_obs_callback(cb);
|
||||
return python_none();
|
||||
}
|
||||
|
||||
|
|
@ -354,8 +355,7 @@ void add_python_frontend_funcs(PyObject *module)
|
|||
DEF_FUNC(add_save_callback),
|
||||
|
||||
#undef DEF_FUNC
|
||||
{0}
|
||||
};
|
||||
{0}};
|
||||
|
||||
add_functions_to_py_module(module, funcs);
|
||||
}
|
||||
|
|
|
|||
16
deps/obs-scripting/obs-scripting-python-import.c
vendored
16
deps/obs-scripting/obs-scripting-python-import.c
vendored
|
|
@ -51,18 +51,18 @@ bool import_python(const char *python_path)
|
|||
lib = os_dlopen(lib_path.array);
|
||||
if (!lib) {
|
||||
blog(LOG_WARNING, "[Python] Could not load library: %s",
|
||||
lib_path.array);
|
||||
lib_path.array);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
#define IMPORT_FUNC(x) \
|
||||
do { \
|
||||
Import_##x = os_dlsym(lib, #x); \
|
||||
if (!Import_##x) { \
|
||||
#define IMPORT_FUNC(x) \
|
||||
do { \
|
||||
Import_##x = os_dlsym(lib, #x); \
|
||||
if (!Import_##x) { \
|
||||
blog(LOG_WARNING, "[Python] Failed to import: %s", \
|
||||
#x); \
|
||||
goto fail; \
|
||||
} \
|
||||
#x); \
|
||||
goto fail; \
|
||||
} \
|
||||
} while (false)
|
||||
|
||||
IMPORT_FUNC(PyType_Ready);
|
||||
|
|
|
|||
201
deps/obs-scripting/obs-scripting-python-import.h
vendored
201
deps/obs-scripting/obs-scripting-python-import.h
vendored
|
|
@ -32,11 +32,11 @@
|
|||
#endif
|
||||
|
||||
#if defined(_WIN32) && defined(_DEBUG)
|
||||
# undef _DEBUG
|
||||
# include <Python.h>
|
||||
# define _DEBUG
|
||||
#undef _DEBUG
|
||||
#include <Python.h>
|
||||
#define _DEBUG
|
||||
#else
|
||||
# include <Python.h>
|
||||
#include <Python.h>
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
|
@ -64,14 +64,17 @@ PY_EXTERN PyObject *(*Import_PyLong_FromVoidPtr)(void *);
|
|||
PY_EXTERN PyObject *(*Import_PyBool_FromLong)(long);
|
||||
PY_EXTERN PyGILState_STATE (*Import_PyGILState_Ensure)(void);
|
||||
PY_EXTERN PyThreadState *(*Import_PyGILState_GetThisThreadState)(void);
|
||||
PY_EXTERN void (*Import_PyErr_SetString)(PyObject *exception, const char *string);
|
||||
PY_EXTERN void (*Import_PyErr_SetString)(PyObject *exception,
|
||||
const char *string);
|
||||
PY_EXTERN PyObject *(*Import_PyErr_Occurred)(void);
|
||||
PY_EXTERN void (*Import_PyErr_Fetch)(PyObject **, PyObject **, PyObject **);
|
||||
PY_EXTERN void (*Import_PyErr_Restore)(PyObject *, PyObject *, PyObject *);
|
||||
PY_EXTERN void (*Import_PyErr_WriteUnraisable)(PyObject *);
|
||||
PY_EXTERN int (*Import_PyArg_UnpackTuple)(PyObject *, const char *, Py_ssize_t, Py_ssize_t, ...);
|
||||
PY_EXTERN int (*Import_PyArg_UnpackTuple)(PyObject *, const char *, Py_ssize_t,
|
||||
Py_ssize_t, ...);
|
||||
PY_EXTERN PyObject *(*Import_Py_BuildValue)(const char *, ...);
|
||||
PY_EXTERN int (*Import_PyRun_SimpleStringFlags)(const char *, PyCompilerFlags *);
|
||||
PY_EXTERN int (*Import_PyRun_SimpleStringFlags)(const char *,
|
||||
PyCompilerFlags *);
|
||||
PY_EXTERN void (*Import_PyErr_Print)(void);
|
||||
PY_EXTERN void (*Import_Py_SetPythonHome)(wchar_t *);
|
||||
PY_EXTERN void (*Import_Py_Initialize)(void);
|
||||
|
|
@ -82,117 +85,127 @@ PY_EXTERN int (*Import_PyEval_ThreadsInitialized)(void);
|
|||
PY_EXTERN void (*Import_PyEval_ReleaseThread)(PyThreadState *tstate);
|
||||
PY_EXTERN void (*Import_PySys_SetArgv)(int, wchar_t **);
|
||||
PY_EXTERN PyObject *(*Import_PyImport_ImportModule)(const char *name);
|
||||
PY_EXTERN PyObject *(*Import_PyObject_CallFunctionObjArgs)(PyObject *callable, ...);
|
||||
PY_EXTERN PyObject (*Import__Py_NotImplementedStruct);
|
||||
PY_EXTERN PyObject *(*Import_PyObject_CallFunctionObjArgs)(PyObject *callable,
|
||||
...);
|
||||
PY_EXTERN PyObject(*Import__Py_NotImplementedStruct);
|
||||
PY_EXTERN PyObject *(*Import_PyExc_TypeError);
|
||||
PY_EXTERN PyObject *(*Import_PyExc_RuntimeError);
|
||||
PY_EXTERN PyObject *(*Import_PyObject_GetAttr)(PyObject *, PyObject *);
|
||||
PY_EXTERN PyObject *(*Import_PyUnicode_FromString)(const char *u);
|
||||
PY_EXTERN PyObject *(*Import_PyDict_GetItemString)(PyObject *dp, const char *key);
|
||||
PY_EXTERN int (*Import_PyDict_SetItemString)(PyObject *dp, const char *key, PyObject *item);
|
||||
PY_EXTERN PyObject *(*Import_PyCFunction_NewEx)(PyMethodDef *, PyObject *, PyObject *);
|
||||
PY_EXTERN PyObject *(*Import_PyDict_GetItemString)(PyObject *dp,
|
||||
const char *key);
|
||||
PY_EXTERN int (*Import_PyDict_SetItemString)(PyObject *dp, const char *key,
|
||||
PyObject *item);
|
||||
PY_EXTERN PyObject *(*Import_PyCFunction_NewEx)(PyMethodDef *, PyObject *,
|
||||
PyObject *);
|
||||
PY_EXTERN PyObject *(*Import_PyModule_GetDict)(PyObject *);
|
||||
PY_EXTERN PyObject *(*Import_PyModule_GetNameObject)(PyObject *);
|
||||
PY_EXTERN int (*Import_PyModule_AddObject)(PyObject *, const char *, PyObject *);
|
||||
PY_EXTERN int (*Import_PyModule_AddStringConstant)(PyObject *, const char *, const char *);
|
||||
PY_EXTERN int (*Import_PyModule_AddObject)(PyObject *, const char *,
|
||||
PyObject *);
|
||||
PY_EXTERN int (*Import_PyModule_AddStringConstant)(PyObject *, const char *,
|
||||
const char *);
|
||||
PY_EXTERN PyObject *(*Import_PyImport_Import)(PyObject *name);
|
||||
PY_EXTERN PyObject *(*Import_PyObject_CallObject)(PyObject *callable_object, PyObject *args);
|
||||
PY_EXTERN struct _longobject (*Import__Py_FalseStruct);
|
||||
PY_EXTERN struct _longobject (*Import__Py_TrueStruct);
|
||||
PY_EXTERN PyObject *(*Import_PyObject_CallObject)(PyObject *callable_object,
|
||||
PyObject *args);
|
||||
PY_EXTERN struct _longobject(*Import__Py_FalseStruct);
|
||||
PY_EXTERN struct _longobject(*Import__Py_TrueStruct);
|
||||
PY_EXTERN void (*Import_PyGILState_Release)(PyGILState_STATE);
|
||||
PY_EXTERN int (*Import_PyList_Append)(PyObject *, PyObject *);
|
||||
PY_EXTERN PyObject *(*Import_PySys_GetObject)(const char *);
|
||||
PY_EXTERN PyObject *(*Import_PyImport_ReloadModule)(PyObject *m);
|
||||
PY_EXTERN PyObject *(*Import_PyObject_GetAttrString)(PyObject *, const char *);
|
||||
PY_EXTERN PyObject *(*Import_PyCapsule_New)(void *pointer, const char *name, PyCapsule_Destructor destructor);
|
||||
PY_EXTERN void *(*Import_PyCapsule_GetPointer)(PyObject *capsule, const char *name);
|
||||
PY_EXTERN PyObject *(*Import_PyCapsule_New)(void *pointer, const char *name,
|
||||
PyCapsule_Destructor destructor);
|
||||
PY_EXTERN void *(*Import_PyCapsule_GetPointer)(PyObject *capsule,
|
||||
const char *name);
|
||||
PY_EXTERN int (*Import_PyArg_ParseTuple)(PyObject *, const char *, ...);
|
||||
PY_EXTERN PyTypeObject (*Import_PyFunction_Type);
|
||||
PY_EXTERN PyTypeObject(*Import_PyFunction_Type);
|
||||
PY_EXTERN int (*Import_PyObject_SetAttr)(PyObject *, PyObject *, PyObject *);
|
||||
PY_EXTERN PyObject *(*Import__PyObject_New)(PyTypeObject *);
|
||||
PY_EXTERN void *(*Import_PyCapsule_Import)(const char *name, int no_block);
|
||||
PY_EXTERN void *(*Import_PyCapsule_Import)(const char *name, int no_block);
|
||||
PY_EXTERN void (*Import_PyErr_Clear)(void);
|
||||
PY_EXTERN PyObject *(*Import_PyObject_Call)(PyObject *callable_object, PyObject *args, PyObject *kwargs);
|
||||
PY_EXTERN PyObject *(*Import_PyObject_Call)(PyObject *callable_object,
|
||||
PyObject *args, PyObject *kwargs);
|
||||
PY_EXTERN PyObject *(*Import_PyList_New)(Py_ssize_t size);
|
||||
PY_EXTERN Py_ssize_t (*Import_PyList_Size)(PyObject *);
|
||||
PY_EXTERN PyObject *(*Import_PyList_GetItem)(PyObject *, Py_ssize_t);
|
||||
PY_EXTERN PyObject *(*Import_PyUnicode_AsUTF8String)(PyObject *unicode);
|
||||
PY_EXTERN PyObject *(*Import_PyLong_FromUnsignedLongLong)(unsigned long long);
|
||||
PY_EXTERN int (*Import_PyArg_VaParse)(PyObject *, const char *, va_list);
|
||||
PY_EXTERN PyObject (*Import__Py_NoneStruct);
|
||||
PY_EXTERN PyObject(*Import__Py_NoneStruct);
|
||||
|
||||
extern bool import_python(const char *python_path);
|
||||
|
||||
# ifndef NO_REDEFS
|
||||
# define PyType_Ready Import_PyType_Ready
|
||||
# define PyObject_GenericGetAttr Import_PyObject_GenericGetAttr
|
||||
# define PyObject_IsTrue Import_PyObject_IsTrue
|
||||
# define Py_DecRef Import_Py_DecRef
|
||||
# define PyObject_Malloc Import_PyObject_Malloc
|
||||
# define PyObject_Free Import_PyObject_Free
|
||||
# define PyObject_Init Import_PyObject_Init
|
||||
# define PyUnicode_FromFormat Import_PyUnicode_FromFormat
|
||||
# define PyUnicode_Concat Import_PyUnicode_Concat
|
||||
# define PyLong_FromVoidPtr Import_PyLong_FromVoidPtr
|
||||
# define PyBool_FromLong Import_PyBool_FromLong
|
||||
# define PyGILState_Ensure Import_PyGILState_Ensure
|
||||
# define PyGILState_GetThisThreadState Import_PyGILState_GetThisThreadState
|
||||
# define PyErr_SetString Import_PyErr_SetString
|
||||
# define PyErr_Occurred Import_PyErr_Occurred
|
||||
# define PyErr_Fetch Import_PyErr_Fetch
|
||||
# define PyErr_Restore Import_PyErr_Restore
|
||||
# define PyErr_WriteUnraisable Import_PyErr_WriteUnraisable
|
||||
# define PyArg_UnpackTuple Import_PyArg_UnpackTuple
|
||||
# define Py_BuildValue Import_Py_BuildValue
|
||||
# define PyRun_SimpleStringFlags Import_PyRun_SimpleStringFlags
|
||||
# define PyErr_Print Import_PyErr_Print
|
||||
# define Py_SetPythonHome Import_Py_SetPythonHome
|
||||
# define Py_Initialize Import_Py_Initialize
|
||||
# define Py_Finalize Import_Py_Finalize
|
||||
# define Py_IsInitialized Import_Py_IsInitialized
|
||||
# define PyEval_InitThreads Import_PyEval_InitThreads
|
||||
# define PyEval_ThreadsInitialized Import_PyEval_ThreadsInitialized
|
||||
# define PyEval_ReleaseThread Import_PyEval_ReleaseThread
|
||||
# define PySys_SetArgv Import_PySys_SetArgv
|
||||
# define PyImport_ImportModule Import_PyImport_ImportModule
|
||||
# define PyObject_CallFunctionObjArgs Import_PyObject_CallFunctionObjArgs
|
||||
# define _Py_NotImplementedStruct (*Import__Py_NotImplementedStruct)
|
||||
# define PyExc_TypeError (*Import_PyExc_TypeError)
|
||||
# define PyExc_RuntimeError (*Import_PyExc_RuntimeError)
|
||||
# define PyObject_GetAttr Import_PyObject_GetAttr
|
||||
# define PyUnicode_FromString Import_PyUnicode_FromString
|
||||
# define PyDict_GetItemString Import_PyDict_GetItemString
|
||||
# define PyDict_SetItemString Import_PyDict_SetItemString
|
||||
# define PyCFunction_NewEx Import_PyCFunction_NewEx
|
||||
# define PyModule_GetDict Import_PyModule_GetDict
|
||||
# define PyModule_GetNameObject Import_PyModule_GetNameObject
|
||||
# define PyModule_AddObject Import_PyModule_AddObject
|
||||
# define PyModule_AddStringConstant Import_PyModule_AddStringConstant
|
||||
# define PyImport_Import Import_PyImport_Import
|
||||
# define PyObject_CallObject Import_PyObject_CallObject
|
||||
# define _Py_FalseStruct (*Import__Py_FalseStruct)
|
||||
# define _Py_TrueStruct (*Import__Py_TrueStruct)
|
||||
# define PyGILState_Release Import_PyGILState_Release
|
||||
# define PyList_Append Import_PyList_Append
|
||||
# define PySys_GetObject Import_PySys_GetObject
|
||||
# define PyImport_ReloadModule Import_PyImport_ReloadModule
|
||||
# define PyObject_GetAttrString Import_PyObject_GetAttrString
|
||||
# define PyCapsule_New Import_PyCapsule_New
|
||||
# define PyCapsule_GetPointer Import_PyCapsule_GetPointer
|
||||
# define PyArg_ParseTuple Import_PyArg_ParseTuple
|
||||
# define PyFunction_Type (*Import_PyFunction_Type)
|
||||
# define PyObject_SetAttr Import_PyObject_SetAttr
|
||||
# define _PyObject_New Import__PyObject_New
|
||||
# define PyCapsule_Import Import_PyCapsule_Import
|
||||
# define PyErr_Clear Import_PyErr_Clear
|
||||
# define PyObject_Call Import_PyObject_Call
|
||||
# define PyList_New Import_PyList_New
|
||||
# define PyList_Size Import_PyList_Size
|
||||
# define PyList_GetItem Import_PyList_GetItem
|
||||
# define PyUnicode_AsUTF8String Import_PyUnicode_AsUTF8String
|
||||
# define PyLong_FromUnsignedLongLong Import_PyLong_FromUnsignedLongLong
|
||||
# define PyArg_VaParse Import_PyArg_VaParse
|
||||
# define _Py_NoneStruct (*Import__Py_NoneStruct)
|
||||
# endif
|
||||
#ifndef NO_REDEFS
|
||||
#define PyType_Ready Import_PyType_Ready
|
||||
#define PyObject_GenericGetAttr Import_PyObject_GenericGetAttr
|
||||
#define PyObject_IsTrue Import_PyObject_IsTrue
|
||||
#define Py_DecRef Import_Py_DecRef
|
||||
#define PyObject_Malloc Import_PyObject_Malloc
|
||||
#define PyObject_Free Import_PyObject_Free
|
||||
#define PyObject_Init Import_PyObject_Init
|
||||
#define PyUnicode_FromFormat Import_PyUnicode_FromFormat
|
||||
#define PyUnicode_Concat Import_PyUnicode_Concat
|
||||
#define PyLong_FromVoidPtr Import_PyLong_FromVoidPtr
|
||||
#define PyBool_FromLong Import_PyBool_FromLong
|
||||
#define PyGILState_Ensure Import_PyGILState_Ensure
|
||||
#define PyGILState_GetThisThreadState Import_PyGILState_GetThisThreadState
|
||||
#define PyErr_SetString Import_PyErr_SetString
|
||||
#define PyErr_Occurred Import_PyErr_Occurred
|
||||
#define PyErr_Fetch Import_PyErr_Fetch
|
||||
#define PyErr_Restore Import_PyErr_Restore
|
||||
#define PyErr_WriteUnraisable Import_PyErr_WriteUnraisable
|
||||
#define PyArg_UnpackTuple Import_PyArg_UnpackTuple
|
||||
#define Py_BuildValue Import_Py_BuildValue
|
||||
#define PyRun_SimpleStringFlags Import_PyRun_SimpleStringFlags
|
||||
#define PyErr_Print Import_PyErr_Print
|
||||
#define Py_SetPythonHome Import_Py_SetPythonHome
|
||||
#define Py_Initialize Import_Py_Initialize
|
||||
#define Py_Finalize Import_Py_Finalize
|
||||
#define Py_IsInitialized Import_Py_IsInitialized
|
||||
#define PyEval_InitThreads Import_PyEval_InitThreads
|
||||
#define PyEval_ThreadsInitialized Import_PyEval_ThreadsInitialized
|
||||
#define PyEval_ReleaseThread Import_PyEval_ReleaseThread
|
||||
#define PySys_SetArgv Import_PySys_SetArgv
|
||||
#define PyImport_ImportModule Import_PyImport_ImportModule
|
||||
#define PyObject_CallFunctionObjArgs Import_PyObject_CallFunctionObjArgs
|
||||
#define _Py_NotImplementedStruct (*Import__Py_NotImplementedStruct)
|
||||
#define PyExc_TypeError (*Import_PyExc_TypeError)
|
||||
#define PyExc_RuntimeError (*Import_PyExc_RuntimeError)
|
||||
#define PyObject_GetAttr Import_PyObject_GetAttr
|
||||
#define PyUnicode_FromString Import_PyUnicode_FromString
|
||||
#define PyDict_GetItemString Import_PyDict_GetItemString
|
||||
#define PyDict_SetItemString Import_PyDict_SetItemString
|
||||
#define PyCFunction_NewEx Import_PyCFunction_NewEx
|
||||
#define PyModule_GetDict Import_PyModule_GetDict
|
||||
#define PyModule_GetNameObject Import_PyModule_GetNameObject
|
||||
#define PyModule_AddObject Import_PyModule_AddObject
|
||||
#define PyModule_AddStringConstant Import_PyModule_AddStringConstant
|
||||
#define PyImport_Import Import_PyImport_Import
|
||||
#define PyObject_CallObject Import_PyObject_CallObject
|
||||
#define _Py_FalseStruct (*Import__Py_FalseStruct)
|
||||
#define _Py_TrueStruct (*Import__Py_TrueStruct)
|
||||
#define PyGILState_Release Import_PyGILState_Release
|
||||
#define PyList_Append Import_PyList_Append
|
||||
#define PySys_GetObject Import_PySys_GetObject
|
||||
#define PyImport_ReloadModule Import_PyImport_ReloadModule
|
||||
#define PyObject_GetAttrString Import_PyObject_GetAttrString
|
||||
#define PyCapsule_New Import_PyCapsule_New
|
||||
#define PyCapsule_GetPointer Import_PyCapsule_GetPointer
|
||||
#define PyArg_ParseTuple Import_PyArg_ParseTuple
|
||||
#define PyFunction_Type (*Import_PyFunction_Type)
|
||||
#define PyObject_SetAttr Import_PyObject_SetAttr
|
||||
#define _PyObject_New Import__PyObject_New
|
||||
#define PyCapsule_Import Import_PyCapsule_Import
|
||||
#define PyErr_Clear Import_PyErr_Clear
|
||||
#define PyObject_Call Import_PyObject_Call
|
||||
#define PyList_New Import_PyList_New
|
||||
#define PyList_Size Import_PyList_Size
|
||||
#define PyList_GetItem Import_PyList_GetItem
|
||||
#define PyUnicode_AsUTF8String Import_PyUnicode_AsUTF8String
|
||||
#define PyLong_FromUnsignedLongLong Import_PyLong_FromUnsignedLongLong
|
||||
#define PyArg_VaParse Import_PyArg_VaParse
|
||||
#define _Py_NoneStruct (*Import__Py_NoneStruct)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
|||
266
deps/obs-scripting/obs-scripting-python.c
vendored
266
deps/obs-scripting/obs-scripting-python.c
vendored
|
|
@ -51,7 +51,7 @@ sys.stderr = stderr_logger()\n";
|
|||
static wchar_t home_path[1024] = {0};
|
||||
#endif
|
||||
|
||||
DARRAY(char*) python_paths;
|
||||
DARRAY(char *) python_paths;
|
||||
static bool python_loaded = false;
|
||||
|
||||
static pthread_mutex_t tick_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
|
@ -63,21 +63,13 @@ struct python_obs_callback *cur_python_cb = NULL;
|
|||
|
||||
/* -------------------------------------------- */
|
||||
|
||||
bool py_to_libobs_(const char *type,
|
||||
PyObject * py_in,
|
||||
void * libobs_out,
|
||||
const char *id,
|
||||
const char *func,
|
||||
int line)
|
||||
bool py_to_libobs_(const char *type, PyObject *py_in, void *libobs_out,
|
||||
const char *id, const char *func, int line)
|
||||
{
|
||||
swig_type_info *info = SWIG_TypeQuery(type);
|
||||
if (info == NULL) {
|
||||
warn("%s:%d: SWIG could not find type: %s%s%s",
|
||||
func,
|
||||
line,
|
||||
id ? id : "",
|
||||
id ? "::" : "",
|
||||
type);
|
||||
warn("%s:%d: SWIG could not find type: %s%s%s", func, line,
|
||||
id ? id : "", id ? "::" : "", type);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -85,33 +77,21 @@ bool py_to_libobs_(const char *type,
|
|||
if (!SWIG_IsOK(ret)) {
|
||||
warn("%s:%d: SWIG failed to convert python object to obs "
|
||||
"object: %s%s%s",
|
||||
func,
|
||||
line,
|
||||
id ? id : "",
|
||||
id ? "::" : "",
|
||||
type);
|
||||
func, line, id ? id : "", id ? "::" : "", type);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool libobs_to_py_(const char *type,
|
||||
void * libobs_in,
|
||||
bool ownership,
|
||||
PyObject ** py_out,
|
||||
const char *id,
|
||||
const char *func,
|
||||
int line)
|
||||
bool libobs_to_py_(const char *type, void *libobs_in, bool ownership,
|
||||
PyObject **py_out, const char *id, const char *func,
|
||||
int line)
|
||||
{
|
||||
swig_type_info *info = SWIG_TypeQuery(type);
|
||||
if (info == NULL) {
|
||||
warn("%s:%d: SWIG could not find type: %s%s%s",
|
||||
func,
|
||||
line,
|
||||
id ? id : "",
|
||||
id ? "::" : "",
|
||||
type);
|
||||
warn("%s:%d: SWIG could not find type: %s%s%s", func, line,
|
||||
id ? id : "", id ? "::" : "", type);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -119,33 +99,27 @@ bool libobs_to_py_(const char *type,
|
|||
if (*py_out == Py_None) {
|
||||
warn("%s:%d: SWIG failed to convert obs object to python "
|
||||
"object: %s%s%s",
|
||||
func,
|
||||
line,
|
||||
id ? id : "",
|
||||
id ? "::" : "",
|
||||
type);
|
||||
func, line, id ? id : "", id ? "::" : "", type);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
#define libobs_to_py(type, obs_obj, ownership, py_obj) \
|
||||
libobs_to_py_(#type " *", obs_obj, ownership, py_obj, \
|
||||
NULL, __func__, __LINE__)
|
||||
#define libobs_to_py(type, obs_obj, ownership, py_obj) \
|
||||
libobs_to_py_(#type " *", obs_obj, ownership, py_obj, NULL, __func__, \
|
||||
__LINE__)
|
||||
#define py_to_libobs(type, py_obj, libobs_out) \
|
||||
py_to_libobs_(#type " *", py_obj, libobs_out, \
|
||||
NULL, __func__, __LINE__)
|
||||
py_to_libobs_(#type " *", py_obj, libobs_out, NULL, __func__, __LINE__)
|
||||
|
||||
#define lock_callback(cb) \
|
||||
lock_python(); \
|
||||
struct obs_python_script *__last_script = cur_python_script; \
|
||||
struct python_obs_callback *__last_cb = cur_python_cb; \
|
||||
#define lock_callback(cb) \
|
||||
lock_python(); \
|
||||
struct obs_python_script *__last_script = cur_python_script; \
|
||||
struct python_obs_callback *__last_cb = cur_python_cb; \
|
||||
cur_python_script = (struct obs_python_script *)cb->base.script; \
|
||||
cur_python_cb = cb
|
||||
#define unlock_callback() \
|
||||
cur_python_cb = __last_cb; \
|
||||
#define unlock_callback() \
|
||||
cur_python_cb = __last_cb; \
|
||||
cur_python_script = __last_script; \
|
||||
unlock_python()
|
||||
|
||||
|
|
@ -174,8 +148,7 @@ void add_functions_to_py_module(PyObject *module, PyMethodDef *method_list)
|
|||
static PyObject *py_get_current_script_path(PyObject *self, PyObject *args)
|
||||
{
|
||||
UNUSED_PARAMETER(args);
|
||||
return PyDict_GetItemString(PyModule_GetDict(self),
|
||||
"__script_dir__");
|
||||
return PyDict_GetItemString(PyModule_GetDict(self), "__script_dir__");
|
||||
}
|
||||
|
||||
static void get_defaults(struct obs_python_script *data, PyObject *get_defs)
|
||||
|
|
@ -194,19 +167,19 @@ static void get_defaults(struct obs_python_script *data, PyObject *get_defs)
|
|||
|
||||
static bool load_python_script(struct obs_python_script *data)
|
||||
{
|
||||
PyObject *py_file = NULL;
|
||||
PyObject *py_module = NULL;
|
||||
PyObject *py_success = NULL;
|
||||
PyObject *py_tick = NULL;
|
||||
PyObject *py_load = NULL;
|
||||
PyObject *py_file = NULL;
|
||||
PyObject *py_module = NULL;
|
||||
PyObject *py_success = NULL;
|
||||
PyObject *py_tick = NULL;
|
||||
PyObject *py_load = NULL;
|
||||
PyObject *py_defaults = NULL;
|
||||
bool success = false;
|
||||
int ret;
|
||||
bool success = false;
|
||||
int ret;
|
||||
|
||||
cur_python_script = data;
|
||||
|
||||
if (!data->module) {
|
||||
py_file = PyUnicode_FromString(data->name.array);
|
||||
py_file = PyUnicode_FromString(data->name.array);
|
||||
py_module = PyImport_Import(py_file);
|
||||
} else {
|
||||
py_module = PyImport_ReloadModule(data->module);
|
||||
|
|
@ -223,7 +196,7 @@ static bool load_python_script(struct obs_python_script *data)
|
|||
goto fail;
|
||||
|
||||
ret = PyModule_AddStringConstant(py_module, "__script_dir__",
|
||||
data->dir.array);
|
||||
data->dir.array);
|
||||
if (py_error() || ret != 0)
|
||||
goto fail;
|
||||
|
||||
|
|
@ -233,12 +206,9 @@ static bool load_python_script(struct obs_python_script *data)
|
|||
goto fail;
|
||||
|
||||
static PyMethodDef global_funcs[] = {
|
||||
{"script_path",
|
||||
py_get_current_script_path,
|
||||
METH_NOARGS,
|
||||
{"script_path", py_get_current_script_path, METH_NOARGS,
|
||||
"Gets the script path"},
|
||||
{0}
|
||||
};
|
||||
{0}};
|
||||
|
||||
add_functions_to_py_module(py_module, global_funcs);
|
||||
|
||||
|
|
@ -250,8 +220,8 @@ static bool load_python_script(struct obs_python_script *data)
|
|||
if (!data->save)
|
||||
PyErr_Clear();
|
||||
|
||||
data->get_properties = PyObject_GetAttrString(py_module,
|
||||
"script_properties");
|
||||
data->get_properties =
|
||||
PyObject_GetAttrString(py_module, "script_properties");
|
||||
if (!data->get_properties)
|
||||
PyErr_Clear();
|
||||
|
||||
|
|
@ -270,7 +240,8 @@ static bool load_python_script(struct obs_python_script *data)
|
|||
PyObject *py_desc = PyUnicode_AsUTF8String(py_ret);
|
||||
if (py_desc) {
|
||||
const char *desc = PyBytes_AS_STRING(py_desc);
|
||||
if (desc) dstr_copy(&data->base.desc, desc);
|
||||
if (desc)
|
||||
dstr_copy(&data->base.desc, desc);
|
||||
Py_DECREF(py_desc);
|
||||
}
|
||||
Py_XDECREF(py_ret);
|
||||
|
|
@ -286,7 +257,8 @@ static bool load_python_script(struct obs_python_script *data)
|
|||
struct obs_python_script *next = first_tick_script;
|
||||
data->next_tick = next;
|
||||
data->p_prev_next_tick = &first_tick_script;
|
||||
if (next) next->p_prev_next_tick = &data->next_tick;
|
||||
if (next)
|
||||
next->p_prev_next_tick = &data->next_tick;
|
||||
first_tick_script = data;
|
||||
|
||||
data->tick = py_tick;
|
||||
|
|
@ -332,9 +304,9 @@ fail:
|
|||
|
||||
static void unload_python_script(struct obs_python_script *data)
|
||||
{
|
||||
PyObject *py_module = data->module;
|
||||
PyObject *py_func = NULL;
|
||||
PyObject *py_ret = NULL;
|
||||
PyObject *py_module = data->module;
|
||||
PyObject *py_func = NULL;
|
||||
PyObject *py_ret = NULL;
|
||||
|
||||
cur_python_script = data;
|
||||
|
||||
|
|
@ -358,8 +330,8 @@ fail:
|
|||
static void add_to_python_path(const char *path)
|
||||
{
|
||||
PyObject *py_path_str = NULL;
|
||||
PyObject *py_path = NULL;
|
||||
int ret;
|
||||
PyObject *py_path = NULL;
|
||||
int ret;
|
||||
|
||||
if (!path || !*path)
|
||||
return;
|
||||
|
|
@ -411,7 +383,8 @@ static inline void python_obs_timer_init(struct python_obs_timer *timer)
|
|||
struct python_obs_timer *next = first_timer;
|
||||
timer->next = next;
|
||||
timer->p_prev_next = &first_timer;
|
||||
if (next) next->p_prev_next = &timer->next;
|
||||
if (next)
|
||||
next->p_prev_next = &timer->next;
|
||||
first_timer = timer;
|
||||
|
||||
pthread_mutex_unlock(&timer_mutex);
|
||||
|
|
@ -420,12 +393,13 @@ static inline void python_obs_timer_init(struct python_obs_timer *timer)
|
|||
static inline void python_obs_timer_remove(struct python_obs_timer *timer)
|
||||
{
|
||||
struct python_obs_timer *next = timer->next;
|
||||
if (next) next->p_prev_next = timer->p_prev_next;
|
||||
if (next)
|
||||
next->p_prev_next = timer->p_prev_next;
|
||||
*timer->p_prev_next = timer->next;
|
||||
}
|
||||
|
||||
static inline struct python_obs_callback *python_obs_timer_cb(
|
||||
struct python_obs_timer *timer)
|
||||
static inline struct python_obs_callback *
|
||||
python_obs_timer_cb(struct python_obs_timer *timer)
|
||||
{
|
||||
return &((struct python_obs_callback *)timer)[-1];
|
||||
}
|
||||
|
|
@ -440,8 +414,10 @@ static PyObject *timer_remove(PyObject *self, PyObject *args)
|
|||
if (!parse_args(args, "O", &py_cb))
|
||||
return python_none();
|
||||
|
||||
struct python_obs_callback *cb = find_python_obs_callback(script, py_cb);
|
||||
if (cb) remove_python_obs_callback(cb);
|
||||
struct python_obs_callback *cb =
|
||||
find_python_obs_callback(script, py_cb);
|
||||
if (cb)
|
||||
remove_python_obs_callback(cb);
|
||||
return python_none();
|
||||
}
|
||||
|
||||
|
|
@ -478,7 +454,7 @@ static PyObject *timer_add(PyObject *self, PyObject *args)
|
|||
return python_none();
|
||||
|
||||
struct python_obs_callback *cb = add_python_obs_callback_extra(
|
||||
script, py_cb, sizeof(struct python_obs_timer));
|
||||
script, py_cb, sizeof(struct python_obs_timer));
|
||||
struct python_obs_timer *timer = python_obs_callback_extra_data(cb);
|
||||
|
||||
timer->interval = (uint64_t)ms * 1000000ULL;
|
||||
|
|
@ -528,8 +504,10 @@ static PyObject *obs_python_remove_tick_callback(PyObject *self, PyObject *args)
|
|||
if (!py_cb || !PyFunction_Check(py_cb))
|
||||
return python_none();
|
||||
|
||||
struct python_obs_callback *cb = find_python_obs_callback(script, py_cb);
|
||||
if (cb) remove_python_obs_callback(cb);
|
||||
struct python_obs_callback *cb =
|
||||
find_python_obs_callback(script, py_cb);
|
||||
if (cb)
|
||||
remove_python_obs_callback(cb);
|
||||
return python_none();
|
||||
}
|
||||
|
||||
|
|
@ -583,8 +561,8 @@ static void calldata_signal_callback(void *priv, calldata_t *cd)
|
|||
unlock_callback();
|
||||
}
|
||||
|
||||
static PyObject *obs_python_signal_handler_disconnect(
|
||||
PyObject *self, PyObject *args)
|
||||
static PyObject *obs_python_signal_handler_disconnect(PyObject *self,
|
||||
PyObject *args)
|
||||
{
|
||||
struct obs_python_script *script = cur_python_script;
|
||||
PyObject *py_sh = NULL;
|
||||
|
|
@ -609,27 +587,28 @@ static PyObject *obs_python_signal_handler_disconnect(
|
|||
if (!py_cb || !PyFunction_Check(py_cb))
|
||||
return python_none();
|
||||
|
||||
struct python_obs_callback *cb = find_python_obs_callback(script, py_cb);
|
||||
struct python_obs_callback *cb =
|
||||
find_python_obs_callback(script, py_cb);
|
||||
while (cb) {
|
||||
signal_handler_t *cb_handler =
|
||||
calldata_ptr(&cb->base.extra, "handler");
|
||||
const char *cb_signal =
|
||||
calldata_string(&cb->base.extra, "signal");
|
||||
|
||||
if (cb_signal &&
|
||||
strcmp(signal, cb_signal) != 0 &&
|
||||
if (cb_signal && strcmp(signal, cb_signal) != 0 &&
|
||||
handler == cb_handler)
|
||||
break;
|
||||
|
||||
cb = find_next_python_obs_callback(script, cb, py_cb);
|
||||
}
|
||||
|
||||
if (cb) remove_python_obs_callback(cb);
|
||||
if (cb)
|
||||
remove_python_obs_callback(cb);
|
||||
return python_none();
|
||||
}
|
||||
|
||||
static PyObject *obs_python_signal_handler_connect(
|
||||
PyObject *self, PyObject *args)
|
||||
static PyObject *obs_python_signal_handler_connect(PyObject *self,
|
||||
PyObject *args)
|
||||
{
|
||||
struct obs_python_script *script = cur_python_script;
|
||||
PyObject *py_sh = NULL;
|
||||
|
|
@ -663,7 +642,7 @@ static PyObject *obs_python_signal_handler_connect(
|
|||
/* -------------------------------------------- */
|
||||
|
||||
static void calldata_signal_callback_global(void *priv, const char *signal,
|
||||
calldata_t *cd)
|
||||
calldata_t *cd)
|
||||
{
|
||||
struct python_obs_callback *cb = priv;
|
||||
|
||||
|
|
@ -688,8 +667,8 @@ static void calldata_signal_callback_global(void *priv, const char *signal,
|
|||
unlock_callback();
|
||||
}
|
||||
|
||||
static PyObject *obs_python_signal_handler_disconnect_global(
|
||||
PyObject *self, PyObject *args)
|
||||
static PyObject *obs_python_signal_handler_disconnect_global(PyObject *self,
|
||||
PyObject *args)
|
||||
{
|
||||
struct obs_python_script *script = cur_python_script;
|
||||
PyObject *py_sh = NULL;
|
||||
|
|
@ -713,7 +692,8 @@ static PyObject *obs_python_signal_handler_disconnect_global(
|
|||
if (!py_cb || !PyFunction_Check(py_cb))
|
||||
return python_none();
|
||||
|
||||
struct python_obs_callback *cb = find_python_obs_callback(script, py_cb);
|
||||
struct python_obs_callback *cb =
|
||||
find_python_obs_callback(script, py_cb);
|
||||
while (cb) {
|
||||
signal_handler_t *cb_handler =
|
||||
calldata_ptr(&cb->base.extra, "handler");
|
||||
|
|
@ -724,12 +704,13 @@ static PyObject *obs_python_signal_handler_disconnect_global(
|
|||
cb = find_next_python_obs_callback(script, cb, py_cb);
|
||||
}
|
||||
|
||||
if (cb) remove_python_obs_callback(cb);
|
||||
if (cb)
|
||||
remove_python_obs_callback(cb);
|
||||
return python_none();
|
||||
}
|
||||
|
||||
static PyObject *obs_python_signal_handler_connect_global(
|
||||
PyObject *self, PyObject *args)
|
||||
static PyObject *obs_python_signal_handler_connect_global(PyObject *self,
|
||||
PyObject *args)
|
||||
{
|
||||
struct obs_python_script *script = cur_python_script;
|
||||
PyObject *py_sh = NULL;
|
||||
|
|
@ -755,8 +736,8 @@ static PyObject *obs_python_signal_handler_connect_global(
|
|||
|
||||
struct python_obs_callback *cb = add_python_obs_callback(script, py_cb);
|
||||
calldata_set_ptr(&cb->base.extra, "handler", handler);
|
||||
signal_handler_connect_global(handler,
|
||||
calldata_signal_callback_global, cb);
|
||||
signal_handler_connect_global(handler, calldata_signal_callback_global,
|
||||
cb);
|
||||
return python_none();
|
||||
}
|
||||
|
||||
|
|
@ -773,7 +754,7 @@ static void on_remove_hotkey(void *p_cb)
|
|||
obs_hotkey_id id = (obs_hotkey_id)calldata_int(&cb->base.extra, "id");
|
||||
|
||||
if (id != OBS_INVALID_HOTKEY_ID)
|
||||
defer_call_post(defer_hotkey_unregister, (void*)(uintptr_t)id);
|
||||
defer_call_post(defer_hotkey_unregister, (void *)(uintptr_t)id);
|
||||
}
|
||||
|
||||
static void hotkey_pressed(void *p_cb, bool pressed)
|
||||
|
|
@ -811,8 +792,8 @@ static inline PyObject *py_invalid_hotkey_id()
|
|||
return PyLong_FromUnsignedLongLong(OBS_INVALID_HOTKEY_ID);
|
||||
}
|
||||
|
||||
static void hotkey_callback(void *p_cb, obs_hotkey_id id,
|
||||
obs_hotkey_t *hotkey, bool pressed)
|
||||
static void hotkey_callback(void *p_cb, obs_hotkey_id id, obs_hotkey_t *hotkey,
|
||||
bool pressed)
|
||||
{
|
||||
struct python_obs_callback *cb = p_cb;
|
||||
|
||||
|
|
@ -844,8 +825,10 @@ static PyObject *hotkey_unregister(PyObject *self, PyObject *args)
|
|||
if (!py_cb || !PyFunction_Check(py_cb))
|
||||
return python_none();
|
||||
|
||||
struct python_obs_callback *cb = find_python_obs_callback(script, py_cb);
|
||||
if (cb) remove_python_obs_callback(cb);
|
||||
struct python_obs_callback *cb =
|
||||
find_python_obs_callback(script, py_cb);
|
||||
if (cb)
|
||||
remove_python_obs_callback(cb);
|
||||
|
||||
UNUSED_PARAMETER(self);
|
||||
return python_none();
|
||||
|
|
@ -879,7 +862,7 @@ static PyObject *hotkey_register_frontend(PyObject *self, PyObject *args)
|
|||
/* -------------------------------------------- */
|
||||
|
||||
static bool button_prop_clicked(obs_properties_t *props, obs_property_t *p,
|
||||
void *p_cb)
|
||||
void *p_cb)
|
||||
{
|
||||
struct python_obs_callback *cb = p_cb;
|
||||
bool ret = false;
|
||||
|
|
@ -931,7 +914,7 @@ static PyObject *properties_add_button(PyObject *self, PyObject *args)
|
|||
|
||||
struct python_obs_callback *cb = add_python_obs_callback(script, py_cb);
|
||||
p = obs_properties_add_button2(props, name, text, button_prop_clicked,
|
||||
cb);
|
||||
cb);
|
||||
|
||||
if (!p || !libobs_to_py(obs_property_t, p, false, &py_ret))
|
||||
return python_none();
|
||||
|
|
@ -943,7 +926,7 @@ static PyObject *properties_add_button(PyObject *self, PyObject *args)
|
|||
/* -------------------------------------------- */
|
||||
|
||||
static bool modified_callback(void *p_cb, obs_properties_t *props,
|
||||
obs_property_t *p, obs_data_t *settings)
|
||||
obs_property_t *p, obs_data_t *settings)
|
||||
{
|
||||
struct python_obs_callback *cb = p_cb;
|
||||
bool ret = false;
|
||||
|
|
@ -961,8 +944,8 @@ static bool modified_callback(void *p_cb, obs_properties_t *props,
|
|||
libobs_to_py(obs_property_t, p, false, &py_p) &&
|
||||
libobs_to_py(obs_data_t, settings, false, &py_settings)) {
|
||||
|
||||
PyObject *args = Py_BuildValue("(OOO)", py_props, py_p,
|
||||
py_settings);
|
||||
PyObject *args =
|
||||
Py_BuildValue("(OOO)", py_props, py_p, py_settings);
|
||||
PyObject *py_ret = PyObject_CallObject(cb->func, args);
|
||||
if (!py_error())
|
||||
ret = py_ret == Py_True;
|
||||
|
|
@ -1017,7 +1000,7 @@ static PyObject *remove_current_callback(PyObject *self, PyObject *args)
|
|||
static PyObject *calldata_source(PyObject *self, PyObject *args)
|
||||
{
|
||||
PyObject *py_ret = NULL;
|
||||
PyObject *py_cd = NULL;
|
||||
PyObject *py_cd = NULL;
|
||||
|
||||
calldata_t *cd;
|
||||
const char *name;
|
||||
|
|
@ -1039,7 +1022,7 @@ fail:
|
|||
static PyObject *calldata_sceneitem(PyObject *self, PyObject *args)
|
||||
{
|
||||
PyObject *py_ret = NULL;
|
||||
PyObject *py_cd = NULL;
|
||||
PyObject *py_cd = NULL;
|
||||
|
||||
calldata_t *cd;
|
||||
const char *name;
|
||||
|
|
@ -1086,7 +1069,7 @@ static PyObject *enum_sources(PyObject *self, PyObject *args)
|
|||
/* -------------------------------------------- */
|
||||
|
||||
static bool enum_items_proc(obs_scene_t *scene, obs_sceneitem_t *item,
|
||||
void *param)
|
||||
void *param)
|
||||
{
|
||||
PyObject *list = param;
|
||||
PyObject *py_item;
|
||||
|
|
@ -1165,7 +1148,7 @@ static PyObject *sceneitem_list_release(PyObject *self, PyObject *args)
|
|||
struct dstr cur_py_log_chunk = {0};
|
||||
|
||||
static PyObject *py_script_log_internal(PyObject *self, PyObject *args,
|
||||
bool add_endl)
|
||||
bool add_endl)
|
||||
{
|
||||
static bool calling_self = false;
|
||||
int log_level;
|
||||
|
|
@ -1195,7 +1178,7 @@ static PyObject *py_script_log_internal(PyObject *self, PyObject *args,
|
|||
*endl = 0;
|
||||
if (cur_python_script)
|
||||
script_log(&cur_python_script->base, log_level, "%s",
|
||||
start);
|
||||
start);
|
||||
else
|
||||
script_log(NULL, log_level, "%s", start);
|
||||
*endl = '\n';
|
||||
|
|
@ -1206,7 +1189,8 @@ static PyObject *py_script_log_internal(PyObject *self, PyObject *args,
|
|||
|
||||
if (start) {
|
||||
size_t len = strlen(start);
|
||||
if (len) memmove(cur_py_log_chunk.array, start, len);
|
||||
if (len)
|
||||
memmove(cur_py_log_chunk.array, start, len);
|
||||
dstr_resize(&cur_py_log_chunk, len);
|
||||
}
|
||||
|
||||
|
|
@ -1245,31 +1229,26 @@ static void add_hook_functions(PyObject *module)
|
|||
DEF_FUNC("obs_enum_sources", enum_sources),
|
||||
DEF_FUNC("obs_scene_enum_items", scene_enum_items),
|
||||
DEF_FUNC("obs_remove_tick_callback",
|
||||
obs_python_remove_tick_callback),
|
||||
DEF_FUNC("obs_add_tick_callback",
|
||||
obs_python_add_tick_callback),
|
||||
obs_python_remove_tick_callback),
|
||||
DEF_FUNC("obs_add_tick_callback", obs_python_add_tick_callback),
|
||||
DEF_FUNC("signal_handler_disconnect",
|
||||
obs_python_signal_handler_disconnect),
|
||||
obs_python_signal_handler_disconnect),
|
||||
DEF_FUNC("signal_handler_connect",
|
||||
obs_python_signal_handler_connect),
|
||||
obs_python_signal_handler_connect),
|
||||
DEF_FUNC("signal_handler_disconnect_global",
|
||||
obs_python_signal_handler_disconnect_global),
|
||||
obs_python_signal_handler_disconnect_global),
|
||||
DEF_FUNC("signal_handler_connect_global",
|
||||
obs_python_signal_handler_connect_global),
|
||||
DEF_FUNC("obs_hotkey_unregister",
|
||||
hotkey_unregister),
|
||||
obs_python_signal_handler_connect_global),
|
||||
DEF_FUNC("obs_hotkey_unregister", hotkey_unregister),
|
||||
DEF_FUNC("obs_hotkey_register_frontend",
|
||||
hotkey_register_frontend),
|
||||
DEF_FUNC("obs_properties_add_button",
|
||||
properties_add_button),
|
||||
hotkey_register_frontend),
|
||||
DEF_FUNC("obs_properties_add_button", properties_add_button),
|
||||
DEF_FUNC("obs_property_set_modified_callback",
|
||||
property_set_modified_callback),
|
||||
DEF_FUNC("remove_current_callback",
|
||||
remove_current_callback),
|
||||
property_set_modified_callback),
|
||||
DEF_FUNC("remove_current_callback", remove_current_callback),
|
||||
|
||||
#undef DEF_FUNC
|
||||
{0}
|
||||
};
|
||||
{0}};
|
||||
|
||||
add_functions_to_py_module(module, funcs);
|
||||
}
|
||||
|
|
@ -1355,7 +1334,8 @@ void obs_python_script_unload(obs_script_t *s)
|
|||
pthread_mutex_lock(&tick_mutex);
|
||||
|
||||
struct obs_python_script *next = data->next_tick;
|
||||
if (next) next->p_prev_next_tick = data->p_prev_next_tick;
|
||||
if (next)
|
||||
next->p_prev_next_tick = data->p_prev_next_tick;
|
||||
*data->p_prev_next_tick = next;
|
||||
|
||||
pthread_mutex_unlock(&tick_mutex);
|
||||
|
|
@ -1520,7 +1500,8 @@ static void python_tick(void *param, float seconds)
|
|||
while (data) {
|
||||
cur_python_script = data;
|
||||
|
||||
PyObject *py_ret = PyObject_CallObject(data->tick, args);
|
||||
PyObject *py_ret =
|
||||
PyObject_CallObject(data->tick, args);
|
||||
Py_XDECREF(py_ret);
|
||||
py_error();
|
||||
|
||||
|
|
@ -1590,7 +1571,6 @@ void obs_python_load(void)
|
|||
|
||||
pthread_mutex_init(&tick_mutex, NULL);
|
||||
pthread_mutex_init(&timer_mutex, &attr);
|
||||
|
||||
}
|
||||
|
||||
extern void add_python_frontend_funcs(PyObject *module);
|
||||
|
|
@ -1602,12 +1582,12 @@ bool obs_scripting_load_python(const char *python_path)
|
|||
if (python_loaded)
|
||||
return true;
|
||||
|
||||
/* Use external python on windows and mac */
|
||||
/* Use external python on windows and mac */
|
||||
#if RUNTIME_LINK
|
||||
# if 0
|
||||
#if 0
|
||||
struct dstr old_path = {0};
|
||||
struct dstr new_path = {0};
|
||||
# endif
|
||||
#endif
|
||||
|
||||
if (!import_python(python_path))
|
||||
return false;
|
||||
|
|
@ -1615,11 +1595,11 @@ bool obs_scripting_load_python(const char *python_path)
|
|||
if (python_path && *python_path) {
|
||||
os_utf8_to_wcs(python_path, 0, home_path, 1024);
|
||||
Py_SetPythonHome(home_path);
|
||||
# if 0
|
||||
#if 0
|
||||
dstr_copy(&old_path, getenv("PATH"));
|
||||
_putenv("PYTHONPATH=");
|
||||
_putenv("PATH=");
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
UNUSED_PARAMETER(python_path);
|
||||
|
|
@ -1630,12 +1610,12 @@ bool obs_scripting_load_python(const char *python_path)
|
|||
return false;
|
||||
|
||||
#if 0
|
||||
# ifdef _DEBUG
|
||||
#ifdef _DEBUG
|
||||
if (pythondir && *pythondir) {
|
||||
dstr_printf(&new_path, "PATH=%s", old_path.array);
|
||||
_putenv(new_path.array);
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
|
||||
bfree(pythondir);
|
||||
dstr_free(&new_path);
|
||||
|
|
@ -1650,7 +1630,7 @@ bool obs_scripting_load_python(const char *python_path)
|
|||
/* Must set arguments for guis to work */
|
||||
|
||||
wchar_t *argv[] = {L"", NULL};
|
||||
int argc = sizeof(argv) / sizeof(wchar_t*) - 1;
|
||||
int argc = sizeof(argv) / sizeof(wchar_t *) - 1;
|
||||
|
||||
PySys_SetArgv(argc, argv);
|
||||
|
||||
|
|
|
|||
75
deps/obs-scripting/obs-scripting-python.h
vendored
75
deps/obs-scripting/obs-scripting-python.h
vendored
|
|
@ -55,9 +55,9 @@
|
|||
#define do_log(level, format, ...) \
|
||||
blog(level, "[Python] " format, ##__VA_ARGS__)
|
||||
|
||||
#define warn(format, ...) do_log(LOG_WARNING, format, ##__VA_ARGS__)
|
||||
#define info(format, ...) do_log(LOG_INFO, format, ##__VA_ARGS__)
|
||||
#define debug(format, ...) do_log(LOG_DEBUG, format, ##__VA_ARGS__)
|
||||
#define warn(format, ...) do_log(LOG_WARNING, format, ##__VA_ARGS__)
|
||||
#define info(format, ...) do_log(LOG_INFO, format, ##__VA_ARGS__)
|
||||
#define debug(format, ...) do_log(LOG_DEBUG, format, ##__VA_ARGS__)
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
||||
|
|
@ -90,43 +90,40 @@ struct python_obs_callback {
|
|||
PyObject *func;
|
||||
};
|
||||
|
||||
static inline struct python_obs_callback *add_python_obs_callback_extra(
|
||||
struct obs_python_script *script,
|
||||
PyObject *func,
|
||||
size_t extra_size)
|
||||
static inline struct python_obs_callback *
|
||||
add_python_obs_callback_extra(struct obs_python_script *script, PyObject *func,
|
||||
size_t extra_size)
|
||||
{
|
||||
struct python_obs_callback *cb = add_script_callback(
|
||||
&script->first_callback,
|
||||
(obs_script_t *)script,
|
||||
sizeof(*cb) + extra_size);
|
||||
&script->first_callback, (obs_script_t *)script,
|
||||
sizeof(*cb) + extra_size);
|
||||
|
||||
Py_XINCREF(func);
|
||||
cb->func = func;
|
||||
return cb;
|
||||
}
|
||||
|
||||
static inline struct python_obs_callback *add_python_obs_callback(
|
||||
struct obs_python_script *script,
|
||||
PyObject *func)
|
||||
static inline struct python_obs_callback *
|
||||
add_python_obs_callback(struct obs_python_script *script, PyObject *func)
|
||||
{
|
||||
return add_python_obs_callback_extra(script, func, 0);
|
||||
}
|
||||
|
||||
static inline void *python_obs_callback_extra_data(
|
||||
struct python_obs_callback *cb)
|
||||
static inline void *
|
||||
python_obs_callback_extra_data(struct python_obs_callback *cb)
|
||||
{
|
||||
return (void*)&cb[1];
|
||||
return (void *)&cb[1];
|
||||
}
|
||||
|
||||
static inline struct obs_python_script *python_obs_callback_script(
|
||||
struct python_obs_callback *cb)
|
||||
static inline struct obs_python_script *
|
||||
python_obs_callback_script(struct python_obs_callback *cb)
|
||||
{
|
||||
return (struct obs_python_script *)cb->base.script;
|
||||
}
|
||||
|
||||
static inline struct python_obs_callback *find_next_python_obs_callback(
|
||||
struct obs_python_script *script,
|
||||
struct python_obs_callback *cb, PyObject *func)
|
||||
static inline struct python_obs_callback *
|
||||
find_next_python_obs_callback(struct obs_python_script *script,
|
||||
struct python_obs_callback *cb, PyObject *func)
|
||||
{
|
||||
cb = cb ? (struct python_obs_callback *)cb->base.next
|
||||
: (struct python_obs_callback *)script->first_callback;
|
||||
|
|
@ -140,9 +137,8 @@ static inline struct python_obs_callback *find_next_python_obs_callback(
|
|||
return cb;
|
||||
}
|
||||
|
||||
static inline struct python_obs_callback *find_python_obs_callback(
|
||||
struct obs_python_script *script,
|
||||
PyObject *func)
|
||||
static inline struct python_obs_callback *
|
||||
find_python_obs_callback(struct obs_python_script *script, PyObject *func)
|
||||
{
|
||||
return find_next_python_obs_callback(script, NULL, func);
|
||||
}
|
||||
|
|
@ -167,7 +163,8 @@ static inline void free_python_obs_callback(struct python_obs_callback *cb)
|
|||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
||||
static int parse_args_(PyObject *args, const char *func, const char *format, ...)
|
||||
static int parse_args_(PyObject *args, const char *func, const char *format,
|
||||
...)
|
||||
{
|
||||
char new_format[128];
|
||||
va_list va_args;
|
||||
|
|
@ -197,15 +194,13 @@ static inline bool py_error_(const char *func, int line)
|
|||
|
||||
#define py_error() py_error_(__FUNCTION__, __LINE__)
|
||||
|
||||
#define lock_python() \
|
||||
PyGILState_STATE gstate = PyGILState_Ensure()
|
||||
#define unlock_python() \
|
||||
PyGILState_Release(gstate)
|
||||
#define lock_python() PyGILState_STATE gstate = PyGILState_Ensure()
|
||||
#define unlock_python() PyGILState_Release(gstate)
|
||||
|
||||
struct py_source;
|
||||
typedef struct py_source py_source_t;
|
||||
|
||||
extern PyObject* py_libobs;
|
||||
extern PyObject *py_libobs;
|
||||
extern struct python_obs_callback *cur_python_cb;
|
||||
extern struct obs_python_script *cur_python_script;
|
||||
|
||||
|
|
@ -213,25 +208,17 @@ extern void py_to_obs_source_info(py_source_t *py_info);
|
|||
extern PyObject *py_obs_register_source(PyObject *self, PyObject *args);
|
||||
extern PyObject *py_obs_get_script_config_path(PyObject *self, PyObject *args);
|
||||
extern void add_functions_to_py_module(PyObject *module,
|
||||
PyMethodDef *method_list);
|
||||
PyMethodDef *method_list);
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/* Warning: the following functions expect python to be locked! */
|
||||
|
||||
extern bool py_to_libobs_(const char *type,
|
||||
PyObject * py_in,
|
||||
void * libobs_out,
|
||||
const char *id,
|
||||
const char *func,
|
||||
int line);
|
||||
extern bool py_to_libobs_(const char *type, PyObject *py_in, void *libobs_out,
|
||||
const char *id, const char *func, int line);
|
||||
|
||||
extern bool libobs_to_py_(const char *type,
|
||||
void * libobs_in,
|
||||
bool ownership,
|
||||
PyObject ** py_out,
|
||||
const char *id,
|
||||
const char *func,
|
||||
int line);
|
||||
extern bool libobs_to_py_(const char *type, void *libobs_in, bool ownership,
|
||||
PyObject **py_out, const char *id, const char *func,
|
||||
int line);
|
||||
|
||||
extern bool py_call(PyObject *call, PyObject **ret, const char *arg_def, ...);
|
||||
extern bool py_import_script(const char *name);
|
||||
|
|
|
|||
21
deps/obs-scripting/obs-scripting.c
vendored
21
deps/obs-scripting/obs-scripting.c
vendored
|
|
@ -27,7 +27,7 @@
|
|||
|
||||
#if COMPILE_LUA
|
||||
extern obs_script_t *obs_lua_script_create(const char *path,
|
||||
obs_data_t *settings);
|
||||
obs_data_t *settings);
|
||||
extern bool obs_lua_script_load(obs_script_t *s);
|
||||
extern void obs_lua_script_unload(obs_script_t *s);
|
||||
extern void obs_lua_script_destroy(obs_script_t *s);
|
||||
|
|
@ -41,7 +41,7 @@ extern void obs_lua_script_save(obs_script_t *script);
|
|||
|
||||
#if COMPILE_PYTHON
|
||||
extern obs_script_t *obs_python_script_create(const char *path,
|
||||
obs_data_t *settings);
|
||||
obs_data_t *settings);
|
||||
extern bool obs_python_script_load(obs_script_t *s);
|
||||
extern void obs_python_script_unload(obs_script_t *s);
|
||||
extern void obs_python_script_destroy(obs_script_t *s);
|
||||
|
|
@ -49,7 +49,8 @@ extern void obs_python_load(void);
|
|||
extern void obs_python_unload(void);
|
||||
|
||||
extern obs_properties_t *obs_python_script_get_properties(obs_script_t *script);
|
||||
extern void obs_python_script_update(obs_script_t *script, obs_data_t *settings);
|
||||
extern void obs_python_script_update(obs_script_t *script,
|
||||
obs_data_t *settings);
|
||||
extern void obs_python_script_save(obs_script_t *script);
|
||||
#endif
|
||||
|
||||
|
|
@ -66,8 +67,7 @@ static const char *supported_formats[] = {
|
|||
#if COMPILE_PYTHON
|
||||
"py",
|
||||
#endif
|
||||
NULL
|
||||
};
|
||||
NULL};
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
||||
|
|
@ -164,7 +164,7 @@ void obs_scripting_unload(void)
|
|||
if (!scripting_loaded)
|
||||
return;
|
||||
|
||||
/* ---------------------- */
|
||||
/* ---------------------- */
|
||||
|
||||
#if COMPILE_LUA
|
||||
obs_lua_unload();
|
||||
|
|
@ -195,7 +195,7 @@ void obs_scripting_unload(void)
|
|||
pthread_mutex_destroy(&detach_mutex);
|
||||
|
||||
blog(LOG_INFO, "[Scripting] Total detached callbacks: %d",
|
||||
total_detached);
|
||||
total_detached);
|
||||
|
||||
/* ---------------------- */
|
||||
|
||||
|
|
@ -223,11 +223,10 @@ const char **obs_scripting_supported_formats(void)
|
|||
}
|
||||
|
||||
static inline bool pointer_valid(const void *x, const char *name,
|
||||
const char *func)
|
||||
const char *func)
|
||||
{
|
||||
if (!x) {
|
||||
blog(LOG_WARNING, "obs-scripting: [%s] %s is null",
|
||||
func, name);
|
||||
blog(LOG_WARNING, "obs-scripting: [%s] %s is null", func, name);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -256,7 +255,7 @@ obs_script_t *obs_script_create(const char *path, obs_data_t *settings)
|
|||
} else
|
||||
#endif
|
||||
#if COMPILE_PYTHON
|
||||
if (strcmp(ext, ".py") == 0) {
|
||||
if (strcmp(ext, ".py") == 0) {
|
||||
script = obs_python_script_create(path, settings);
|
||||
} else
|
||||
#endif
|
||||
|
|
|
|||
11
deps/obs-scripting/obs-scripting.h
vendored
11
deps/obs-scripting/obs-scripting.h
vendored
|
|
@ -39,14 +39,11 @@ EXPORT bool obs_scripting_load(void);
|
|||
EXPORT void obs_scripting_unload(void);
|
||||
EXPORT const char **obs_scripting_supported_formats(void);
|
||||
|
||||
typedef void (*scripting_log_handler_t)(
|
||||
void *p,
|
||||
obs_script_t *script,
|
||||
int lvl,
|
||||
const char *msg);
|
||||
typedef void (*scripting_log_handler_t)(void *p, obs_script_t *script, int lvl,
|
||||
const char *msg);
|
||||
|
||||
EXPORT void obs_scripting_set_log_callback(
|
||||
scripting_log_handler_t handler, void *param);
|
||||
EXPORT void obs_scripting_set_log_callback(scripting_log_handler_t handler,
|
||||
void *param);
|
||||
|
||||
EXPORT bool obs_scripting_python_runtime_linked(void);
|
||||
EXPORT bool obs_scripting_python_loaded(void);
|
||||
|
|
|
|||
13
deps/obs-scripting/obslua/CMakeLists.txt
vendored
13
deps/obs-scripting/obslua/CMakeLists.txt
vendored
|
|
@ -1,6 +1,10 @@
|
|||
cmake_minimum_required(VERSION 2.8)
|
||||
project(obslua)
|
||||
|
||||
if(POLICY CMP0078)
|
||||
cmake_policy(SET CMP0078 OLD)
|
||||
endif()
|
||||
|
||||
find_package(SWIG 2 REQUIRED)
|
||||
include(${SWIG_USE_FILE})
|
||||
|
||||
|
|
@ -16,7 +20,14 @@ endif()
|
|||
include_directories(SYSTEM "${CMAKE_SOURCE_DIR}/libobs")
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
SWIG_ADD_MODULE(obslua lua obslua.i ../cstrcache.cpp ../cstrcache.h)
|
||||
if(CMAKE_VERSION VERSION_GREATER 3.7.2)
|
||||
SWIG_ADD_LIBRARY(obslua
|
||||
LANGUAGE lua
|
||||
TYPE MODULE
|
||||
SOURCES obslua.i ../cstrcache.cpp ../cstrcache.h)
|
||||
else()
|
||||
SWIG_ADD_MODULE(obslua lua obslua.i ../cstrcache.cpp ../cstrcache.h)
|
||||
endif()
|
||||
SWIG_LINK_LIBRARIES(obslua obs-scripting libobs ${LUA_LIBRARIES} ${EXTRA_LIBS})
|
||||
|
||||
function(install_plugin_bin_swig target additional_target)
|
||||
|
|
|
|||
13
deps/obs-scripting/obspython/CMakeLists.txt
vendored
13
deps/obs-scripting/obspython/CMakeLists.txt
vendored
|
|
@ -1,6 +1,10 @@
|
|||
cmake_minimum_required(VERSION 2.8)
|
||||
project(obspython)
|
||||
|
||||
if(POLICY CMP0078)
|
||||
cmake_policy(SET CMP0078 OLD)
|
||||
endif()
|
||||
|
||||
find_package(SWIG 2 REQUIRED)
|
||||
include(${SWIG_USE_FILE})
|
||||
|
||||
|
|
@ -30,7 +34,14 @@ if(WIN32)
|
|||
string(REGEX REPLACE "_d" "" PYTHON_LIBRARIES "${PYTHON_LIBRARIES}")
|
||||
endif()
|
||||
|
||||
SWIG_ADD_MODULE(obspython python obspython.i ../cstrcache.cpp ../cstrcache.h)
|
||||
if(CMAKE_VERSION VERSION_GREATER 3.7.2)
|
||||
SWIG_ADD_LIBRARY(obspython
|
||||
LANGUAGE python
|
||||
TYPE MODULE
|
||||
SOURCES obspython.i ../cstrcache.cpp ../cstrcache.h)
|
||||
else()
|
||||
SWIG_ADD_MODULE(obspython python obspython.i ../cstrcache.cpp ../cstrcache.h)
|
||||
endif()
|
||||
SWIG_LINK_LIBRARIES(obspython obs-scripting libobs ${PYTHON_LIBRARIES})
|
||||
|
||||
function(install_plugin_bin_swig target additional_target)
|
||||
|
|
|
|||
3
deps/w32-pthreads/.clang-format
vendored
Normal file
3
deps/w32-pthreads/.clang-format
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
Language: Cpp
|
||||
SortIncludes: false
|
||||
DisableFormat: true
|
||||
Loading…
Add table
Add a link
Reference in a new issue