libobs: Add ability to rotate async sources
parent
88e8ffc1e0
commit
b9d6675e2c
|
@ -1186,6 +1186,14 @@ Functions used by sources
|
||||||
|
|
||||||
---------------------
|
---------------------
|
||||||
|
|
||||||
|
.. function:: void obs_source_set_async_rotation(obs_source_t *source, long rotation)
|
||||||
|
|
||||||
|
Allows the ability to set rotation (0, 90, 180, -90, 270) for an
|
||||||
|
async video source. The rotation will be automatically applied to
|
||||||
|
the source.
|
||||||
|
|
||||||
|
---------------------
|
||||||
|
|
||||||
.. function:: void obs_source_preload_video(obs_source_t *source, const struct obs_source_frame *frame)
|
.. function:: void obs_source_preload_video(obs_source_t *source, const struct obs_source_frame *frame)
|
||||||
|
|
||||||
Preloads a video frame to ensure a frame is ready for playback as
|
Preloads a video frame to ensure a frame is ready for playback as
|
||||||
|
|
|
@ -641,6 +641,7 @@ struct obs_source {
|
||||||
bool async_cache_full_range;
|
bool async_cache_full_range;
|
||||||
enum gs_color_format async_texture_formats[MAX_AV_PLANES];
|
enum gs_color_format async_texture_formats[MAX_AV_PLANES];
|
||||||
int async_channel_count;
|
int async_channel_count;
|
||||||
|
long async_rotation;
|
||||||
bool async_flip;
|
bool async_flip;
|
||||||
bool async_active;
|
bool async_active;
|
||||||
bool async_update_texture;
|
bool async_update_texture;
|
||||||
|
|
|
@ -2038,10 +2038,41 @@ static void obs_source_update_async_video(obs_source_t *source)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void rotate_async_video(obs_source_t *source, long rotation)
|
||||||
|
{
|
||||||
|
float x = 0;
|
||||||
|
float y = 0;
|
||||||
|
|
||||||
|
switch (rotation) {
|
||||||
|
case 90:
|
||||||
|
y = (float)source->async_width;
|
||||||
|
break;
|
||||||
|
case 270:
|
||||||
|
case -90:
|
||||||
|
x = (float)source->async_height;
|
||||||
|
break;
|
||||||
|
case 180:
|
||||||
|
x = (float)source->async_width;
|
||||||
|
y = (float)source->async_height;
|
||||||
|
}
|
||||||
|
|
||||||
|
gs_matrix_translate3f(x, y, 0);
|
||||||
|
gs_matrix_rotaa4f(0.0f, 0.0f, -1.0f, RAD((float)rotation));
|
||||||
|
}
|
||||||
|
|
||||||
static inline void obs_source_render_async_video(obs_source_t *source)
|
static inline void obs_source_render_async_video(obs_source_t *source)
|
||||||
{
|
{
|
||||||
if (source->async_textures[0] && source->async_active)
|
if (source->async_textures[0] && source->async_active) {
|
||||||
|
long rotation = source->async_rotation;
|
||||||
|
if (rotation) {
|
||||||
|
gs_matrix_push();
|
||||||
|
rotate_async_video(source, rotation);
|
||||||
|
}
|
||||||
obs_source_draw_async_texture(source);
|
obs_source_draw_async_texture(source);
|
||||||
|
if (rotation) {
|
||||||
|
gs_matrix_pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void obs_source_render_filters(obs_source_t *source)
|
static inline void obs_source_render_filters(obs_source_t *source)
|
||||||
|
@ -2165,6 +2196,18 @@ void obs_source_video_render(obs_source_t *source)
|
||||||
obs_source_release(source);
|
obs_source_release(source);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline uint32_t get_async_width(const obs_source_t *source)
|
||||||
|
{
|
||||||
|
return ((source->async_rotation % 180) == 0) ? source->async_width
|
||||||
|
: source->async_height;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t get_async_height(const obs_source_t *source)
|
||||||
|
{
|
||||||
|
return ((source->async_rotation % 180) == 0) ? source->async_height
|
||||||
|
: source->async_width;
|
||||||
|
}
|
||||||
|
|
||||||
static uint32_t get_base_width(const obs_source_t *source)
|
static uint32_t get_base_width(const obs_source_t *source)
|
||||||
{
|
{
|
||||||
bool is_filter = !!source->filter_parent;
|
bool is_filter = !!source->filter_parent;
|
||||||
|
@ -2180,7 +2223,7 @@ static uint32_t get_base_width(const obs_source_t *source)
|
||||||
return get_base_width(source->filter_target);
|
return get_base_width(source->filter_target);
|
||||||
}
|
}
|
||||||
|
|
||||||
return source->async_active ? source->async_width : 0;
|
return source->async_active ? get_async_width(source) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t get_base_height(const obs_source_t *source)
|
static uint32_t get_base_height(const obs_source_t *source)
|
||||||
|
@ -2198,7 +2241,7 @@ static uint32_t get_base_height(const obs_source_t *source)
|
||||||
return get_base_height(source->filter_target);
|
return get_base_height(source->filter_target);
|
||||||
}
|
}
|
||||||
|
|
||||||
return source->async_active ? source->async_height : 0;
|
return source->async_active ? get_async_height(source) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t get_recurse_width(obs_source_t *source)
|
static uint32_t get_recurse_width(obs_source_t *source)
|
||||||
|
@ -2800,6 +2843,12 @@ void obs_source_output_video2(obs_source_t *source,
|
||||||
obs_source_output_video_internal(source, &new_frame);
|
obs_source_output_video_internal(source, &new_frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void obs_source_set_async_rotation(obs_source_t *source, long rotation)
|
||||||
|
{
|
||||||
|
if (source)
|
||||||
|
source->async_rotation = rotation;
|
||||||
|
}
|
||||||
|
|
||||||
static inline bool preload_frame_changed(obs_source_t *source,
|
static inline bool preload_frame_changed(obs_source_t *source,
|
||||||
const struct obs_source_frame *in)
|
const struct obs_source_frame *in)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1175,6 +1175,8 @@ EXPORT void obs_source_output_video(obs_source_t *source,
|
||||||
EXPORT void obs_source_output_video2(obs_source_t *source,
|
EXPORT void obs_source_output_video2(obs_source_t *source,
|
||||||
const struct obs_source_frame2 *frame);
|
const struct obs_source_frame2 *frame);
|
||||||
|
|
||||||
|
EXPORT void obs_source_set_async_rotation(obs_source_t *source, long rotation);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Preloads asynchronous video data to allow instantaneous playback
|
* Preloads asynchronous video data to allow instantaneous playback
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in New Issue