|
@@ -2436,7 +2436,7 @@ static inline struct obs_source_frame *cache_video(struct obs_source *source,
|
|
|
return new_frame;
|
|
|
}
|
|
|
|
|
|
-void obs_source_output_video(obs_source_t *source,
|
|
|
+static void obs_source_output_video_internal(obs_source_t *source,
|
|
|
const struct obs_source_frame *frame)
|
|
|
{
|
|
|
if (!obs_source_valid(source, "obs_source_output_video"))
|
|
@@ -2464,6 +2464,56 @@ void obs_source_output_video(obs_source_t *source,
|
|
|
pthread_mutex_unlock(&source->async_mutex);
|
|
|
}
|
|
|
|
|
|
+void obs_source_output_video(obs_source_t *source,
|
|
|
+ const struct obs_source_frame *frame)
|
|
|
+{
|
|
|
+ if (!frame) {
|
|
|
+ obs_source_output_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_output_video_internal(source, &new_frame);
|
|
|
+}
|
|
|
+
|
|
|
+void obs_source_output_video2(obs_source_t *source,
|
|
|
+ const struct obs_source_frame2 *frame)
|
|
|
+{
|
|
|
+ if (!frame) {
|
|
|
+ obs_source_output_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_output_video_internal(source, &new_frame);
|
|
|
+}
|
|
|
+
|
|
|
static inline bool preload_frame_changed(obs_source_t *source,
|
|
|
const struct obs_source_frame *in)
|
|
|
{
|
|
@@ -2475,7 +2525,7 @@ static inline bool preload_frame_changed(obs_source_t *source,
|
|
|
in->format != source->async_preload_frame->format;
|
|
|
}
|
|
|
|
|
|
-void obs_source_preload_video(obs_source_t *source,
|
|
|
+static void obs_source_preload_video_internal(obs_source_t *source,
|
|
|
const struct obs_source_frame *frame)
|
|
|
{
|
|
|
if (!obs_source_valid(source, "obs_source_preload_video"))
|
|
@@ -2504,6 +2554,56 @@ void obs_source_preload_video(obs_source_t *source,
|
|
|
obs_leave_graphics();
|
|
|
}
|
|
|
|
|
|
+void obs_source_preload_video(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_preload_video_internal(source, &new_frame);
|
|
|
+}
|
|
|
+
|
|
|
+void obs_source_preload_video2(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_preload_video_internal(source, &new_frame);
|
|
|
+}
|
|
|
+
|
|
|
void obs_source_show_preloaded_video(obs_source_t *source)
|
|
|
{
|
|
|
uint64_t sys_ts;
|