libobs: Add func to set async video frame immediately

Allows the ability to directly override the current async frame
immediately.
This commit is contained in:
jp9000 2020-07-28 13:54:53 -07:00
parent 80bb9b4675
commit d117908440
2 changed files with 88 additions and 0 deletions

View file

@ -2976,6 +2976,82 @@ void obs_source_show_preloaded_video(obs_source_t *source)
pthread_mutex_unlock(&source->audio_buf_mutex);
}
static void
obs_source_set_video_frame_internal(obs_source_t *source,
const struct obs_source_frame *frame)
{
if (!obs_source_valid(source, "obs_source_set_video_frame"))
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_textures(source, source->async_preload_frame,
source->async_textures, source->async_texrender);
source->last_frame_ts = frame->timestamp;
obs_leave_graphics();
}
void obs_source_set_video_frame(obs_source_t *source,
const struct obs_source_frame *frame)
{
if (!frame) {
obs_source_preload_video_internal(source, NULL);
return;
}
struct obs_source_frame new_frame = *frame;
new_frame.full_range =
format_is_yuv(frame->format) ? new_frame.full_range : true;
obs_source_set_video_frame_internal(source, &new_frame);
}
void obs_source_set_video_frame2(obs_source_t *source,
const struct obs_source_frame2 *frame)
{
if (!frame) {
obs_source_preload_video_internal(source, NULL);
return;
}
struct obs_source_frame new_frame;
enum video_range_type range =
resolve_video_range(frame->format, frame->range);
for (size_t i = 0; i < MAX_AV_PLANES; i++) {
new_frame.data[i] = frame->data[i];
new_frame.linesize[i] = frame->linesize[i];
}
new_frame.width = frame->width;
new_frame.height = frame->height;
new_frame.timestamp = frame->timestamp;
new_frame.format = frame->format;
new_frame.full_range = range == VIDEO_RANGE_FULL;
new_frame.flip = frame->flip;
memcpy(&new_frame.color_matrix, &frame->color_matrix,
sizeof(frame->color_matrix));
memcpy(&new_frame.color_range_min, &frame->color_range_min,
sizeof(frame->color_range_min));
memcpy(&new_frame.color_range_max, &frame->color_range_max,
sizeof(frame->color_range_max));
obs_source_set_video_frame_internal(source, &new_frame);
}
static inline struct obs_audio_data *
filter_async_audio(obs_source_t *source, struct obs_audio_data *in)
{

View file

@ -1210,6 +1210,18 @@ EXPORT void obs_source_preload_video2(obs_source_t *source,
/** Shows any preloaded video data */
EXPORT void obs_source_show_preloaded_video(obs_source_t *source);
/**
* Sets current async video frame immediately
*
* NOTE: Non-YUV formats will always be treated as full range with this
* function! Use obs_source_preload_video2 instead if partial range support is
* desired for non-YUV video formats.
*/
EXPORT void obs_source_set_video_frame(obs_source_t *source,
const struct obs_source_frame *frame);
EXPORT void obs_source_set_video_frame2(obs_source_t *source,
const struct obs_source_frame2 *frame);
/** Outputs audio data (always asynchronous) */
EXPORT void obs_source_output_audio(obs_source_t *source,
const struct obs_source_audio *audio);