mirror of
https://github.com/obsproject/obs-studio.git
synced 2024-09-20 21:13:04 +02:00
Merge pull request #1452 from cg2121/slideshow-memory-usage
image-source: Decrease slideshow source memory usage
This commit is contained in:
commit
274bf52deb
@ -57,6 +57,9 @@
|
|||||||
|
|
||||||
/* ------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
#define MOD(a,b) ((((a)%(b))+(b))%(b))
|
||||||
|
#define MAX_LOADED 11 /* needs to be an odd number */
|
||||||
|
|
||||||
struct image_file_data {
|
struct image_file_data {
|
||||||
char *path;
|
char *path;
|
||||||
obs_source_t *source;
|
obs_source_t *source;
|
||||||
@ -75,7 +78,6 @@ struct slideshow {
|
|||||||
bool loop;
|
bool loop;
|
||||||
bool restart_on_activate;
|
bool restart_on_activate;
|
||||||
bool pause_on_deactivate;
|
bool pause_on_deactivate;
|
||||||
bool restart;
|
|
||||||
bool manual;
|
bool manual;
|
||||||
bool hide;
|
bool hide;
|
||||||
bool use_cut;
|
bool use_cut;
|
||||||
@ -87,13 +89,14 @@ struct slideshow {
|
|||||||
obs_source_t *transition;
|
obs_source_t *transition;
|
||||||
|
|
||||||
float elapsed;
|
float elapsed;
|
||||||
size_t cur_item;
|
int cur_item;
|
||||||
|
|
||||||
uint32_t cx;
|
uint32_t cx;
|
||||||
uint32_t cy;
|
uint32_t cy;
|
||||||
|
|
||||||
pthread_mutex_t mutex;
|
pthread_mutex_t mutex;
|
||||||
DARRAY(struct image_file_data) files;
|
DARRAY(struct image_file_data) files;
|
||||||
|
DARRAY(char*) paths;
|
||||||
|
|
||||||
enum behavior behavior;
|
enum behavior behavior;
|
||||||
|
|
||||||
@ -164,7 +167,18 @@ static void free_files(struct darray *array)
|
|||||||
|
|
||||||
static inline size_t random_file(struct slideshow *ss)
|
static inline size_t random_file(struct slideshow *ss)
|
||||||
{
|
{
|
||||||
return (size_t)rand() % ss->files.num;
|
return (size_t)rand() % ss->paths.num;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void free_paths(struct darray *array)
|
||||||
|
{
|
||||||
|
DARRAY(char*) paths;
|
||||||
|
paths.da = *array;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < paths.num; i++)
|
||||||
|
bfree(paths.array[i]);
|
||||||
|
|
||||||
|
da_free(paths);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------- */
|
||||||
@ -176,7 +190,7 @@ static const char *ss_getname(void *unused)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void add_file(struct slideshow *ss, struct darray *array,
|
static void add_file(struct slideshow *ss, struct darray *array,
|
||||||
const char *path, uint32_t *cx, uint32_t *cy)
|
const char *path, uint32_t *cx, uint32_t *cy, bool next)
|
||||||
{
|
{
|
||||||
DARRAY(struct image_file_data) new_files;
|
DARRAY(struct image_file_data) new_files;
|
||||||
struct image_file_data data;
|
struct image_file_data data;
|
||||||
@ -199,7 +213,11 @@ static void add_file(struct slideshow *ss, struct darray *array,
|
|||||||
|
|
||||||
data.path = bstrdup(path);
|
data.path = bstrdup(path);
|
||||||
data.source = new_source;
|
data.source = new_source;
|
||||||
|
|
||||||
|
if (next)
|
||||||
da_push_back(new_files, &data);
|
da_push_back(new_files, &data);
|
||||||
|
else
|
||||||
|
da_insert(new_files, 0, &data);
|
||||||
|
|
||||||
if (new_cx > *cx) *cx = new_cx;
|
if (new_cx > *cx) *cx = new_cx;
|
||||||
if (new_cy > *cy) *cy = new_cy;
|
if (new_cy > *cy) *cy = new_cy;
|
||||||
@ -208,6 +226,48 @@ static void add_file(struct slideshow *ss, struct darray *array,
|
|||||||
*array = new_files.da;
|
*array = new_files.da;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void clear_buffer(struct slideshow *ss, bool next)
|
||||||
|
{
|
||||||
|
if (ss->paths.num <= MAX_LOADED || !ss->paths.num || !ss->files.num)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (next) {
|
||||||
|
bfree(ss->files.array[0].path);
|
||||||
|
obs_source_release(ss->files.array[0].source);
|
||||||
|
da_erase(ss->files, 0);
|
||||||
|
} else {
|
||||||
|
bfree(ss->files.array[ss->files.num - 1].path);
|
||||||
|
obs_source_release(ss->files.array[ss->files.num - 1].source);
|
||||||
|
da_pop_back(ss->files);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t index = 0;
|
||||||
|
|
||||||
|
if (ss->randomize)
|
||||||
|
index = random_file(ss);
|
||||||
|
else if (!ss->randomize && next)
|
||||||
|
index = MOD((ss->cur_item + ((MAX_LOADED / 2) + 1)),
|
||||||
|
ss->paths.num);
|
||||||
|
else if (!ss->randomize && !next)
|
||||||
|
index = MOD((ss->cur_item - ((MAX_LOADED / 2) + 1)),
|
||||||
|
ss->paths.num);
|
||||||
|
|
||||||
|
uint32_t cx, cy;
|
||||||
|
add_file(ss, &ss->files.da, ss->paths.array[index], &cx, &cy,
|
||||||
|
next);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void add_path(struct darray *array, const char *path)
|
||||||
|
{
|
||||||
|
DARRAY(char*) new_paths;
|
||||||
|
new_paths.da = *array;
|
||||||
|
|
||||||
|
const char *new_path = bstrdup(path);
|
||||||
|
da_push_back(new_paths, &new_path);
|
||||||
|
|
||||||
|
*array = new_paths.da;
|
||||||
|
}
|
||||||
|
|
||||||
static bool valid_extension(const char *ext)
|
static bool valid_extension(const char *ext)
|
||||||
{
|
{
|
||||||
if (!ext)
|
if (!ext)
|
||||||
@ -222,35 +282,54 @@ static bool valid_extension(const char *ext)
|
|||||||
|
|
||||||
static inline bool item_valid(struct slideshow *ss)
|
static inline bool item_valid(struct slideshow *ss)
|
||||||
{
|
{
|
||||||
return ss->files.num && ss->cur_item < ss->files.num;
|
return ss->files.num && ss->paths.num &&
|
||||||
|
(size_t)ss->cur_item < ss->paths.num;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void do_transition(void *data, bool to_null)
|
static void do_transition(void *data, bool to_null, bool next)
|
||||||
{
|
{
|
||||||
struct slideshow *ss = data;
|
struct slideshow *ss = data;
|
||||||
bool valid = item_valid(ss);
|
bool valid = item_valid(ss);
|
||||||
|
|
||||||
if (valid && ss->use_cut)
|
if (to_null) {
|
||||||
obs_transition_set(ss->transition,
|
obs_transition_start(ss->transition, OBS_TRANSITION_MODE_AUTO,
|
||||||
ss->files.array[ss->cur_item].source);
|
|
||||||
|
|
||||||
else if (valid && !to_null)
|
|
||||||
obs_transition_start(ss->transition,
|
|
||||||
OBS_TRANSITION_MODE_AUTO,
|
|
||||||
ss->tr_speed,
|
|
||||||
ss->files.array[ss->cur_item].source);
|
|
||||||
|
|
||||||
else
|
|
||||||
obs_transition_start(ss->transition,
|
|
||||||
OBS_TRANSITION_MODE_AUTO,
|
|
||||||
ss->tr_speed,
|
ss->tr_speed,
|
||||||
NULL);
|
NULL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!valid)
|
||||||
|
return;
|
||||||
|
|
||||||
|
clear_buffer(ss, next);
|
||||||
|
|
||||||
|
obs_source_t *source;
|
||||||
|
|
||||||
|
if (next && ss->paths.num > MAX_LOADED)
|
||||||
|
source = ss->files.array[(MAX_LOADED / 2) + 1].source;
|
||||||
|
else if (!next && ss->paths.num > MAX_LOADED)
|
||||||
|
source = ss->files.array[(MAX_LOADED / 2) - 1].source;
|
||||||
|
else if (ss->paths.num <= MAX_LOADED)
|
||||||
|
source = ss->files.array[(size_t)ss->cur_item].source;
|
||||||
|
|
||||||
|
if (!source)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (ss->use_cut)
|
||||||
|
obs_transition_set(ss->transition, source);
|
||||||
|
|
||||||
|
else if (!to_null)
|
||||||
|
obs_transition_start(ss->transition,
|
||||||
|
OBS_TRANSITION_MODE_AUTO,
|
||||||
|
ss->tr_speed, source);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ss_update(void *data, obs_data_t *settings)
|
static void ss_update(void *data, obs_data_t *settings)
|
||||||
{
|
{
|
||||||
DARRAY(struct image_file_data) new_files;
|
DARRAY(struct image_file_data) new_files;
|
||||||
DARRAY(struct image_file_data) old_files;
|
DARRAY(struct image_file_data) old_files;
|
||||||
|
DARRAY(char*) new_paths;
|
||||||
|
DARRAY(char*) old_paths;
|
||||||
obs_source_t *new_tr = NULL;
|
obs_source_t *new_tr = NULL;
|
||||||
obs_source_t *old_tr = NULL;
|
obs_source_t *old_tr = NULL;
|
||||||
struct slideshow *ss = data;
|
struct slideshow *ss = data;
|
||||||
@ -260,6 +339,8 @@ static void ss_update(void *data, obs_data_t *settings)
|
|||||||
uint32_t new_speed;
|
uint32_t new_speed;
|
||||||
uint32_t cx = 0;
|
uint32_t cx = 0;
|
||||||
uint32_t cy = 0;
|
uint32_t cy = 0;
|
||||||
|
uint32_t last_cx = 0;
|
||||||
|
uint32_t last_cy = 0;
|
||||||
size_t count;
|
size_t count;
|
||||||
const char *behavior;
|
const char *behavior;
|
||||||
const char *mode;
|
const char *mode;
|
||||||
@ -268,6 +349,7 @@ static void ss_update(void *data, obs_data_t *settings)
|
|||||||
/* get settings data */
|
/* get settings data */
|
||||||
|
|
||||||
da_init(new_files);
|
da_init(new_files);
|
||||||
|
da_init(new_paths);
|
||||||
|
|
||||||
behavior = obs_data_get_string(settings, S_BEHAVIOR);
|
behavior = obs_data_get_string(settings, S_BEHAVIOR);
|
||||||
|
|
||||||
@ -333,14 +415,13 @@ static void ss_update(void *data, obs_data_t *settings)
|
|||||||
dstr_copy(&dir_path, path);
|
dstr_copy(&dir_path, path);
|
||||||
dstr_cat_ch(&dir_path, '/');
|
dstr_cat_ch(&dir_path, '/');
|
||||||
dstr_cat(&dir_path, ent->d_name);
|
dstr_cat(&dir_path, ent->d_name);
|
||||||
add_file(ss, &new_files.da, dir_path.array,
|
add_path(&new_paths.da, dir_path.array);
|
||||||
&cx, &cy);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dstr_free(&dir_path);
|
dstr_free(&dir_path);
|
||||||
os_closedir(dir);
|
os_closedir(dir);
|
||||||
} else {
|
} else {
|
||||||
add_file(ss, &new_files.da, path, &cx, &cy);
|
add_path(&new_paths.da, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
obs_data_release(item);
|
obs_data_release(item);
|
||||||
@ -353,6 +434,8 @@ static void ss_update(void *data, obs_data_t *settings)
|
|||||||
|
|
||||||
old_files.da = ss->files.da;
|
old_files.da = ss->files.da;
|
||||||
ss->files.da = new_files.da;
|
ss->files.da = new_files.da;
|
||||||
|
old_paths.da = ss->paths.da;
|
||||||
|
ss->paths.da = new_paths.da;
|
||||||
if (new_tr) {
|
if (new_tr) {
|
||||||
old_tr = ss->transition;
|
old_tr = ss->transition;
|
||||||
ss->transition = new_tr;
|
ss->transition = new_tr;
|
||||||
@ -369,12 +452,31 @@ static void ss_update(void *data, obs_data_t *settings)
|
|||||||
|
|
||||||
pthread_mutex_unlock(&ss->mutex);
|
pthread_mutex_unlock(&ss->mutex);
|
||||||
|
|
||||||
|
if (ss->paths.num > MAX_LOADED && !ss->randomize) {
|
||||||
|
for (int i = -(MAX_LOADED / 2); i <= (MAX_LOADED / 2); i++) {
|
||||||
|
size_t index = MOD(i, ss->paths.num);
|
||||||
|
add_file(ss, &ss->files.da, ss->paths.array[index],
|
||||||
|
&cx, &cy, true);
|
||||||
|
}
|
||||||
|
} else if (ss->paths.num > MAX_LOADED && ss->randomize) {
|
||||||
|
for (size_t i = 0; i < MAX_LOADED; i++) {
|
||||||
|
size_t index = random_file(ss);
|
||||||
|
add_file(ss, &ss->files.da, ss->paths.array[index],
|
||||||
|
&cx, &cy, true);
|
||||||
|
}
|
||||||
|
} else if (ss->paths.num <= MAX_LOADED) {
|
||||||
|
for (size_t i = 0; i < ss->paths.num; i++)
|
||||||
|
add_file(ss, &ss->files.da, ss->paths.array[i],
|
||||||
|
&cx, &cy, true);
|
||||||
|
}
|
||||||
|
|
||||||
/* ------------------------------------- */
|
/* ------------------------------------- */
|
||||||
/* clean up and restart transition */
|
/* clean up and restart transition */
|
||||||
|
|
||||||
if (old_tr)
|
if (old_tr)
|
||||||
obs_source_release(old_tr);
|
obs_source_release(old_tr);
|
||||||
free_files(&old_files.da);
|
free_files(&old_files.da);
|
||||||
|
free_paths(&old_paths.da);
|
||||||
|
|
||||||
/* ------------------------- */
|
/* ------------------------- */
|
||||||
|
|
||||||
@ -418,21 +520,32 @@ static void ss_update(void *data, obs_data_t *settings)
|
|||||||
|
|
||||||
/* ------------------------- */
|
/* ------------------------- */
|
||||||
|
|
||||||
|
obs_data_t *priv_settings = obs_source_get_private_settings(ss->source);
|
||||||
|
last_cx = (uint32_t)obs_data_get_int(priv_settings, "last_cx");
|
||||||
|
last_cy = (uint32_t)obs_data_get_int(priv_settings, "last_cy");
|
||||||
|
|
||||||
|
if (ss->randomize && last_cx > 0 && last_cy > 0) {
|
||||||
|
cx = last_cx;
|
||||||
|
cy = last_cy;
|
||||||
|
}
|
||||||
|
|
||||||
|
obs_data_set_int(priv_settings, "last_cx", cx);
|
||||||
|
obs_data_set_int(priv_settings, "last_cy", cy);
|
||||||
|
obs_data_release(priv_settings);
|
||||||
|
|
||||||
ss->cx = cx;
|
ss->cx = cx;
|
||||||
ss->cy = cy;
|
ss->cy = cy;
|
||||||
ss->cur_item = 0;
|
|
||||||
ss->elapsed = 0.0f;
|
ss->elapsed = 0.0f;
|
||||||
|
ss->cur_item = 0;
|
||||||
obs_transition_set_size(ss->transition, cx, cy);
|
obs_transition_set_size(ss->transition, cx, cy);
|
||||||
obs_transition_set_alignment(ss->transition, OBS_ALIGN_CENTER);
|
obs_transition_set_alignment(ss->transition, OBS_ALIGN_CENTER);
|
||||||
obs_transition_set_scale_type(ss->transition,
|
obs_transition_set_scale_type(ss->transition,
|
||||||
OBS_TRANSITION_SCALE_ASPECT);
|
OBS_TRANSITION_SCALE_ASPECT);
|
||||||
|
|
||||||
if (ss->randomize && ss->files.num)
|
|
||||||
ss->cur_item = random_file(ss);
|
|
||||||
if (new_tr)
|
if (new_tr)
|
||||||
obs_source_add_active_child(ss->source, new_tr);
|
obs_source_add_active_child(ss->source, new_tr);
|
||||||
if (ss->files.num)
|
if (ss->files.num)
|
||||||
do_transition(ss, false);
|
do_transition(ss, false, true);
|
||||||
|
|
||||||
obs_data_array_release(array);
|
obs_data_array_release(array);
|
||||||
}
|
}
|
||||||
@ -449,14 +562,15 @@ static void ss_restart(void *data)
|
|||||||
{
|
{
|
||||||
struct slideshow *ss = data;
|
struct slideshow *ss = data;
|
||||||
|
|
||||||
ss->elapsed = 0.0f;
|
|
||||||
ss->cur_item = 0;
|
|
||||||
|
|
||||||
obs_transition_set(ss->transition,
|
|
||||||
ss->files.array[ss->cur_item].source);
|
|
||||||
|
|
||||||
ss->stop = false;
|
ss->stop = false;
|
||||||
ss->paused = false;
|
ss->use_cut = true;
|
||||||
|
ss->restart_on_activate = false;
|
||||||
|
|
||||||
|
obs_data_t *settings = obs_source_get_settings(ss->source);
|
||||||
|
ss_update(ss, settings);
|
||||||
|
obs_data_release(settings);
|
||||||
|
|
||||||
|
ss->use_cut = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ss_stop(void *data)
|
static void ss_stop(void *data)
|
||||||
@ -466,7 +580,7 @@ static void ss_stop(void *data)
|
|||||||
ss->elapsed = 0.0f;
|
ss->elapsed = 0.0f;
|
||||||
ss->cur_item = 0;
|
ss->cur_item = 0;
|
||||||
|
|
||||||
do_transition(ss, true);
|
do_transition(ss, true, true);
|
||||||
ss->stop = true;
|
ss->stop = true;
|
||||||
ss->paused = false;
|
ss->paused = false;
|
||||||
}
|
}
|
||||||
@ -475,28 +589,26 @@ static void ss_next_slide(void *data)
|
|||||||
{
|
{
|
||||||
struct slideshow *ss = data;
|
struct slideshow *ss = data;
|
||||||
|
|
||||||
if (!ss->files.num)
|
if (!ss->paths.num)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (++ss->cur_item >= ss->files.num)
|
if (++ss->cur_item >= (int)ss->paths.num)
|
||||||
ss->cur_item = 0;
|
ss->cur_item = 0;
|
||||||
|
|
||||||
do_transition(ss, false);
|
do_transition(ss, false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ss_previous_slide(void *data)
|
static void ss_previous_slide(void *data)
|
||||||
{
|
{
|
||||||
struct slideshow *ss = data;
|
struct slideshow *ss = data;
|
||||||
|
|
||||||
if (!ss->files.num)
|
if (!ss->paths.num)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (ss->cur_item == 0)
|
if (--ss->cur_item < 0)
|
||||||
ss->cur_item = ss->files.num - 1;
|
ss->cur_item = (int)(ss->paths.num - 1);
|
||||||
else
|
|
||||||
--ss->cur_item;
|
|
||||||
|
|
||||||
do_transition(ss, false);
|
do_transition(ss, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void play_pause_hotkey(void *data, obs_hotkey_id id,
|
static void play_pause_hotkey(void *data, obs_hotkey_id id,
|
||||||
@ -571,6 +683,7 @@ static void ss_destroy(void *data)
|
|||||||
|
|
||||||
obs_source_release(ss->transition);
|
obs_source_release(ss->transition);
|
||||||
free_files(&ss->files.da);
|
free_files(&ss->files.da);
|
||||||
|
free_paths(&ss->paths.da);
|
||||||
pthread_mutex_destroy(&ss->mutex);
|
pthread_mutex_destroy(&ss->mutex);
|
||||||
bfree(ss);
|
bfree(ss);
|
||||||
}
|
}
|
||||||
@ -644,13 +757,8 @@ static void ss_video_tick(void *data, float seconds)
|
|||||||
if (!ss->transition || !ss->slide_time)
|
if (!ss->transition || !ss->slide_time)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (ss->restart_on_activate && !ss->randomize && ss->use_cut) {
|
if (ss->restart_on_activate && ss->use_cut) {
|
||||||
ss->elapsed = 0.0f;
|
ss_restart(ss);
|
||||||
ss->cur_item = 0;
|
|
||||||
do_transition(ss, false);
|
|
||||||
ss->restart_on_activate = false;
|
|
||||||
ss->use_cut = false;
|
|
||||||
ss->stop = false;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -659,13 +767,13 @@ static void ss_video_tick(void *data, float seconds)
|
|||||||
|
|
||||||
/* ----------------------------------------------------- */
|
/* ----------------------------------------------------- */
|
||||||
/* fade to transparency when the file list becomes empty */
|
/* fade to transparency when the file list becomes empty */
|
||||||
if (!ss->files.num) {
|
if (!ss->paths.num) {
|
||||||
obs_source_t* active_transition_source =
|
obs_source_t* active_transition_source =
|
||||||
obs_transition_get_active_source(ss->transition);
|
obs_transition_get_active_source(ss->transition);
|
||||||
|
|
||||||
if (active_transition_source) {
|
if (active_transition_source) {
|
||||||
obs_source_release(active_transition_source);
|
obs_source_release(active_transition_source);
|
||||||
do_transition(ss, true);
|
do_transition(ss, true, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -676,29 +784,17 @@ static void ss_video_tick(void *data, float seconds)
|
|||||||
if (ss->elapsed > ss->slide_time) {
|
if (ss->elapsed > ss->slide_time) {
|
||||||
ss->elapsed -= ss->slide_time;
|
ss->elapsed -= ss->slide_time;
|
||||||
|
|
||||||
if (!ss->loop && ss->cur_item == ss->files.num - 1) {
|
if (!ss->loop && ss->cur_item == (int)ss->paths.num - 1 &&
|
||||||
|
!ss->randomize) {
|
||||||
if (ss->hide)
|
if (ss->hide)
|
||||||
do_transition(ss, true);
|
do_transition(ss, true, true);
|
||||||
else
|
else
|
||||||
do_transition(ss, false);
|
do_transition(ss, false, true);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ss->randomize) {
|
ss_next_slide(ss);
|
||||||
size_t next = ss->cur_item;
|
|
||||||
if (ss->files.num > 1) {
|
|
||||||
while (next == ss->cur_item)
|
|
||||||
next = random_file(ss);
|
|
||||||
}
|
|
||||||
ss->cur_item = next;
|
|
||||||
|
|
||||||
} else if (++ss->cur_item >= ss->files.num) {
|
|
||||||
ss->cur_item = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ss->files.num)
|
|
||||||
do_transition(ss, false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -861,11 +957,14 @@ static obs_properties_t *ss_properties(void *data)
|
|||||||
|
|
||||||
if (ss) {
|
if (ss) {
|
||||||
pthread_mutex_lock(&ss->mutex);
|
pthread_mutex_lock(&ss->mutex);
|
||||||
if (ss->files.num) {
|
if (ss->paths.num) {
|
||||||
struct image_file_data *last = da_end(ss->files);
|
char **p_last_path = da_end(ss->paths);
|
||||||
|
const char *last_path;
|
||||||
const char *slash;
|
const char *slash;
|
||||||
|
|
||||||
dstr_copy(&path, last->path);
|
last_path = p_last_path ? *p_last_path : "";
|
||||||
|
|
||||||
|
dstr_copy(&path, last_path);
|
||||||
dstr_replace(&path, "\\", "/");
|
dstr_replace(&path, "\\", "/");
|
||||||
slash = strrchr(path.array, '/');
|
slash = strrchr(path.array, '/');
|
||||||
if (slash)
|
if (slash)
|
||||||
|
Loading…
Reference in New Issue
Block a user