New upstream version 24.0.1+dfsg1

This commit is contained in:
Sebastian Ramacher 2019-09-22 23:19:10 +02:00
parent b14f9eae6d
commit 5a730d6ec3
842 changed files with 42245 additions and 33385 deletions

View file

@ -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;

View file

@ -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
View file

@ -0,0 +1,3 @@
Language: Cpp
SortIncludes: false
DisableFormat: true

View file

@ -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;

View file

@ -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)

View file

@ -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
View file

@ -0,0 +1,3 @@
Language: Cpp
SortIncludes: false
DisableFormat: true

View file

@ -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);
}

View file

@ -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;

View file

@ -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
}

View file

@ -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);
}

View file

@ -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);

View file

@ -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;
}
}

View file

@ -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
}

View file

@ -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;

View file

@ -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
}

View file

@ -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;
}
}

View file

@ -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);

View file

@ -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)

View file

@ -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);

View file

@ -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;

View file

@ -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);

View file

@ -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, &current, 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;

View file

@ -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
}

View file

@ -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);

View file

@ -9,6 +9,7 @@ include_directories(
)
set(media-playback_HEADERS
media-playback/closest-format.h
media-playback/decode.h
media-playback/media.h
)

View file

@ -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:

View file

@ -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;

View file

@ -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);

View file

@ -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;
}

View file

@ -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);

View file

@ -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__)

View file

@ -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;

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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(&current_lua_script->mutex);
#define unlock_callback() \
#define unlock_callback() \
pthread_mutex_unlock(&current_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);

View file

@ -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);
}

View file

@ -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);

View file

@ -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

View file

@ -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);

View file

@ -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);

View file

@ -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

View file

@ -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);

View file

@ -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)

View file

@ -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
View file

@ -0,0 +1,3 @@
Language: Cpp
SortIncludes: false
DisableFormat: true