mirror of
https://github.com/obsproject/obs-studio.git
synced 2024-09-20 04:42:18 +02:00
libobs: Add ability to preload async frames
Prevents any delay when starting up certain async video sources. Additionally prevents old frames from being presented as well.
This commit is contained in:
parent
d85224bb9b
commit
0941a9c13d
@ -603,6 +603,7 @@ struct obs_source {
|
||||
bool async_flip;
|
||||
bool async_active;
|
||||
bool async_update_texture;
|
||||
struct obs_source_frame *async_preload_frame;
|
||||
DARRAY(struct async_frame) async_cache;
|
||||
DARRAY(struct obs_source_frame*)async_frames;
|
||||
pthread_mutex_t async_mutex;
|
||||
|
@ -567,6 +567,8 @@ void obs_source_destroy(struct obs_source *source)
|
||||
audio_resampler_destroy(source->resampler);
|
||||
bfree(source->audio_output_buf[0][0]);
|
||||
|
||||
obs_source_frame_destroy(source->async_preload_frame);
|
||||
|
||||
if (source->info.type == OBS_SOURCE_TYPE_TRANSITION)
|
||||
obs_transition_free(source);
|
||||
|
||||
@ -1072,6 +1074,7 @@ static void reset_audio_data(obs_source_t *source, uint64_t os_time)
|
||||
|
||||
source->last_audio_input_buf_size = 0;
|
||||
source->audio_ts = os_time;
|
||||
source->next_audio_sys_ts_min = os_time;
|
||||
}
|
||||
|
||||
static void handle_ts_jump(obs_source_t *source, uint64_t expected,
|
||||
@ -2348,6 +2351,62 @@ void obs_source_output_video(obs_source_t *source,
|
||||
}
|
||||
}
|
||||
|
||||
static inline bool preload_frame_changed(obs_source_t *source,
|
||||
const struct obs_source_frame *in)
|
||||
{
|
||||
if (!source->async_preload_frame)
|
||||
return true;
|
||||
|
||||
return in->width != source->async_preload_frame->width ||
|
||||
in->height != source->async_preload_frame->height ||
|
||||
in->format != source->async_preload_frame->format;
|
||||
}
|
||||
|
||||
void obs_source_preload_video(obs_source_t *source,
|
||||
const struct obs_source_frame *frame)
|
||||
{
|
||||
if (!obs_source_valid(source, "obs_source_preload_video"))
|
||||
return;
|
||||
if (!frame)
|
||||
return;
|
||||
|
||||
obs_enter_graphics();
|
||||
|
||||
if (preload_frame_changed(source, frame)) {
|
||||
obs_source_frame_destroy(source->async_preload_frame);
|
||||
source->async_preload_frame = obs_source_frame_create(
|
||||
frame->format,
|
||||
frame->width,
|
||||
frame->height);
|
||||
}
|
||||
|
||||
copy_frame_data(source->async_preload_frame, frame);
|
||||
set_async_texture_size(source, source->async_preload_frame);
|
||||
update_async_texture(source, source->async_preload_frame,
|
||||
source->async_texture,
|
||||
source->async_texrender);
|
||||
|
||||
source->last_frame_ts = frame->timestamp;
|
||||
|
||||
obs_leave_graphics();
|
||||
}
|
||||
|
||||
void obs_source_show_preloaded_video(obs_source_t *source)
|
||||
{
|
||||
uint64_t sys_ts;
|
||||
|
||||
if (!obs_source_valid(source, "obs_source_show_preloaded_video"))
|
||||
return;
|
||||
|
||||
source->async_active = true;
|
||||
|
||||
pthread_mutex_lock(&source->audio_buf_mutex);
|
||||
sys_ts = os_gettime_ns();
|
||||
reset_audio_timing(source, source->last_frame_ts, sys_ts);
|
||||
reset_audio_data(source, sys_ts);
|
||||
pthread_mutex_unlock(&source->audio_buf_mutex);
|
||||
}
|
||||
|
||||
static inline struct obs_audio_data *filter_async_audio(obs_source_t *source,
|
||||
struct obs_audio_data *in)
|
||||
{
|
||||
|
@ -976,6 +976,13 @@ EXPORT void obs_source_draw(gs_texture_t *image, int x, int y,
|
||||
EXPORT void obs_source_output_video(obs_source_t *source,
|
||||
const struct obs_source_frame *frame);
|
||||
|
||||
/** Preloads asynchronous video data to allow instantaneous playback */
|
||||
EXPORT void obs_source_preload_video(obs_source_t *source,
|
||||
const struct obs_source_frame *frame);
|
||||
|
||||
/** Shows any preloaded video data */
|
||||
EXPORT void obs_source_show_preloaded_video(obs_source_t *source);
|
||||
|
||||
/** Outputs audio data (always asynchronous) */
|
||||
EXPORT void obs_source_output_audio(obs_source_t *source,
|
||||
const struct obs_source_audio *audio);
|
||||
|
Loading…
Reference in New Issue
Block a user