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