Add API functions for output/encoder scaling
API functions added: ----------------------------------------------- obs_output_set_preferred_size obs_output_get_width obs_output_get_height obs_encoder_set_scaled_size obs_encoder_get_width obs_encoder_get_height These functions allow for easier means of setting a custom resolution on an output or encoder. If an output uses an encoder and you set the preferred width/height using the output, then the output will attempt to set the scaled width/height for the encoder it's currently using. Outputs and encoders now should use these functions to determine the width/height of the raw frame data instead of using the video-io functions.
This commit is contained in:
parent
f36f82b036
commit
a0f679bc40
@ -130,6 +130,16 @@ static inline struct video_scale_info *get_video_info(
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline bool has_scaling(struct obs_encoder *encoder)
|
||||
{
|
||||
uint32_t video_width = video_output_get_width(encoder->media);
|
||||
uint32_t video_height = video_output_get_height(encoder->media);
|
||||
|
||||
return encoder->scaled_width && encoder->scaled_height &&
|
||||
(video_width != encoder->scaled_width ||
|
||||
video_height != encoder->scaled_height);
|
||||
}
|
||||
|
||||
static void add_connection(struct obs_encoder *encoder)
|
||||
{
|
||||
struct audio_convert_info audio_info = {0};
|
||||
@ -140,11 +150,23 @@ static void add_connection(struct obs_encoder *encoder)
|
||||
audio_output_connect(encoder->media, &audio_info, receive_audio,
|
||||
encoder);
|
||||
} else {
|
||||
struct video_scale_info *info = NULL;
|
||||
struct video_scale_info *info =
|
||||
get_video_info(encoder, &video_info);
|
||||
|
||||
if (!info && has_scaling(encoder)) {
|
||||
info = &video_info;
|
||||
info->format = video_output_get_format(encoder->media);
|
||||
info->colorspace = VIDEO_CS_DEFAULT;
|
||||
info->range = VIDEO_RANGE_DEFAULT;
|
||||
}
|
||||
|
||||
if (info && (!info->width || !info->height)) {
|
||||
info->width = obs_encoder_get_width(encoder);
|
||||
info->height = obs_encoder_get_height(encoder);
|
||||
}
|
||||
|
||||
info = get_video_info(encoder, &video_info);
|
||||
video_output_connect(encoder->media, info, receive_video,
|
||||
encoder);
|
||||
encoder);
|
||||
}
|
||||
|
||||
encoder->active = true;
|
||||
@ -410,6 +432,45 @@ const char *obs_encoder_get_codec(obs_encoder_t encoder)
|
||||
return encoder ? encoder->info.codec : NULL;
|
||||
}
|
||||
|
||||
void obs_encoder_set_scaled_size(obs_encoder_t encoder, uint32_t width,
|
||||
uint32_t height)
|
||||
{
|
||||
if (!encoder || encoder->info.type != OBS_ENCODER_VIDEO)
|
||||
return;
|
||||
|
||||
if (encoder->active) {
|
||||
blog(LOG_WARNING, "encoder '%s': Cannot set the scaled "
|
||||
"resolution while the encoder is active",
|
||||
obs_encoder_get_name(encoder));
|
||||
return;
|
||||
}
|
||||
|
||||
encoder->scaled_width = width;
|
||||
encoder->scaled_height = height;
|
||||
}
|
||||
|
||||
uint32_t obs_encoder_get_width(obs_encoder_t encoder)
|
||||
{
|
||||
if (!encoder || !encoder->media ||
|
||||
encoder->info.type != OBS_ENCODER_VIDEO)
|
||||
return 0;
|
||||
|
||||
return encoder->scaled_width != 0 ?
|
||||
encoder->scaled_width :
|
||||
video_output_get_width(encoder->media);
|
||||
}
|
||||
|
||||
uint32_t obs_encoder_get_height(obs_encoder_t encoder)
|
||||
{
|
||||
if (!encoder || !encoder->media ||
|
||||
encoder->info.type != OBS_ENCODER_VIDEO)
|
||||
return 0;
|
||||
|
||||
return encoder->scaled_width != 0 ?
|
||||
encoder->scaled_height :
|
||||
video_output_get_height(encoder->media);
|
||||
}
|
||||
|
||||
void obs_encoder_set_video(obs_encoder_t encoder, video_t video)
|
||||
{
|
||||
const struct video_output_info *voi;
|
||||
|
@ -419,6 +419,9 @@ struct obs_output {
|
||||
obs_encoder_t audio_encoder;
|
||||
obs_service_t service;
|
||||
|
||||
uint32_t scaled_width;
|
||||
uint32_t scaled_height;
|
||||
|
||||
bool video_conversion_set;
|
||||
bool audio_conversion_set;
|
||||
struct video_scale_info video_conversion;
|
||||
@ -452,6 +455,9 @@ struct obs_encoder {
|
||||
size_t framesize;
|
||||
size_t framesize_bytes;
|
||||
|
||||
uint32_t scaled_width;
|
||||
uint32_t scaled_height;
|
||||
|
||||
bool active;
|
||||
|
||||
uint32_t timebase_num;
|
||||
|
@ -296,6 +296,11 @@ void obs_output_set_video_encoder(obs_output_t output, obs_encoder_t encoder)
|
||||
obs_encoder_remove_output(encoder, output);
|
||||
obs_encoder_add_output(encoder, output);
|
||||
output->video_encoder = encoder;
|
||||
|
||||
/* set the preferred resolution on the encoder */
|
||||
if (output->scaled_width && output->scaled_height)
|
||||
obs_encoder_set_scaled_size(output->video_encoder,
|
||||
output->scaled_width, output->scaled_height);
|
||||
}
|
||||
|
||||
void obs_output_set_audio_encoder(obs_output_t output, obs_encoder_t encoder)
|
||||
@ -365,6 +370,55 @@ int obs_output_get_total_frames(obs_output_t output)
|
||||
return output ? output->total_frames : 0;
|
||||
}
|
||||
|
||||
void obs_output_set_preferred_size(obs_output_t output, uint32_t width,
|
||||
uint32_t height)
|
||||
{
|
||||
if (!output || (output->info.flags & OBS_OUTPUT_VIDEO) == 0)
|
||||
return;
|
||||
|
||||
if (output->active) {
|
||||
blog(LOG_WARNING, "output '%s': Cannot set the preferred "
|
||||
"resolution while the output is active",
|
||||
obs_output_get_name(output));
|
||||
return;
|
||||
}
|
||||
|
||||
output->scaled_width = width;
|
||||
output->scaled_height = height;
|
||||
|
||||
if (output->info.flags & OBS_OUTPUT_ENCODED) {
|
||||
if (output->video_encoder)
|
||||
obs_encoder_set_scaled_size(output->video_encoder,
|
||||
width, height);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t obs_output_get_width(obs_output_t output)
|
||||
{
|
||||
if (!output || (output->info.flags & OBS_OUTPUT_VIDEO) == 0)
|
||||
return 0;
|
||||
|
||||
if (output->info.flags & OBS_OUTPUT_ENCODED)
|
||||
return obs_encoder_get_width(output->video_encoder);
|
||||
else
|
||||
return output->scaled_width != 0 ?
|
||||
output->scaled_width :
|
||||
video_output_get_width(output->video);
|
||||
}
|
||||
|
||||
uint32_t obs_output_get_height(obs_output_t output)
|
||||
{
|
||||
if (!output || (output->info.flags & OBS_OUTPUT_VIDEO) == 0)
|
||||
return 0;
|
||||
|
||||
if (output->info.flags & OBS_OUTPUT_ENCODED)
|
||||
return obs_encoder_get_height(output->video_encoder);
|
||||
else
|
||||
return output->scaled_height != 0 ?
|
||||
output->scaled_height :
|
||||
video_output_get_height(output->video);
|
||||
}
|
||||
|
||||
void obs_output_set_video_conversion(obs_output_t output,
|
||||
const struct video_scale_info *conversion)
|
||||
{
|
||||
@ -412,10 +466,43 @@ static bool can_begin_data_capture(struct obs_output *output, bool encoded,
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool has_scaling(struct obs_output *output)
|
||||
{
|
||||
uint32_t video_width = video_output_get_width(output->video);
|
||||
uint32_t video_height = video_output_get_height(output->video);
|
||||
|
||||
return output->scaled_width && output->scaled_height &&
|
||||
(video_width != output->scaled_width ||
|
||||
video_height != output->scaled_height);
|
||||
}
|
||||
|
||||
static inline struct video_scale_info *get_video_conversion(
|
||||
struct obs_output *output)
|
||||
{
|
||||
return output->video_conversion_set ? &output->video_conversion : NULL;
|
||||
if (output->video_conversion_set) {
|
||||
if (!output->video_conversion.width)
|
||||
output->video_conversion.width =
|
||||
obs_output_get_width(output);
|
||||
|
||||
if (!output->video_conversion.height)
|
||||
output->video_conversion.height =
|
||||
obs_output_get_height(output);
|
||||
|
||||
return &output->video_conversion;
|
||||
|
||||
} else if (has_scaling(output)) {
|
||||
const struct video_output_info *info =
|
||||
video_output_get_info(output->video);
|
||||
|
||||
output->video_conversion.format = info->format;
|
||||
output->video_conversion.colorspace = VIDEO_CS_DEFAULT;
|
||||
output->video_conversion.range = VIDEO_RANGE_DEFAULT;
|
||||
output->video_conversion.width = output->scaled_width;
|
||||
output->video_conversion.height = output->scaled_height;
|
||||
return &output->video_conversion;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline struct audio_convert_info *get_audio_conversion(
|
||||
|
31
libobs/obs.h
31
libobs/obs.h
@ -953,6 +953,23 @@ EXPORT uint64_t obs_output_get_total_bytes(obs_output_t output);
|
||||
EXPORT int obs_output_get_frames_dropped(obs_output_t output);
|
||||
EXPORT int obs_output_get_total_frames(obs_output_t output);
|
||||
|
||||
/**
|
||||
* Sets the preferred scaled resolution for this output. Set width and height
|
||||
* to 0 to disable scaling.
|
||||
*
|
||||
* If this output uses an encoder, it will call obs_encoder_set_scaled_size on
|
||||
* the encoder before the stream is started. If the encoder is already active,
|
||||
* then this function will trigger a warning and do nothing.
|
||||
*/
|
||||
EXPORT void obs_output_set_preferred_size(obs_output_t output, uint32_t width,
|
||||
uint32_t height);
|
||||
|
||||
/** For video outputs, returns the width of the encoded image */
|
||||
EXPORT uint32_t obs_output_get_width(obs_output_t output);
|
||||
|
||||
/** For video outputs, returns the height of the encoded image */
|
||||
EXPORT uint32_t obs_output_get_height(obs_output_t output);
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* Functions used by outputs */
|
||||
|
||||
@ -1032,6 +1049,20 @@ EXPORT const char *obs_encoder_get_name(obs_encoder_t encoder);
|
||||
/** Returns the codec of the encoder */
|
||||
EXPORT const char *obs_encoder_get_codec(obs_encoder_t encoder);
|
||||
|
||||
/**
|
||||
* Sets the scaled resolution for a video encoder. Set width and height to 0
|
||||
* to disable scaling. If the encoder is active, this function will trigger
|
||||
* a warning, and do nothing.
|
||||
*/
|
||||
EXPORT void obs_encoder_set_scaled_size(obs_encoder_t encoder, uint32_t width,
|
||||
uint32_t height);
|
||||
|
||||
/** For video encoders, returns the width of the encoded image */
|
||||
EXPORT uint32_t obs_encoder_get_width(obs_encoder_t encoder);
|
||||
|
||||
/** For video encoders, returns the height of the encoded image */
|
||||
EXPORT uint32_t obs_encoder_get_height(obs_encoder_t encoder);
|
||||
|
||||
/** Gets the default settings for an encoder type */
|
||||
EXPORT obs_data_t obs_encoder_defaults(const char *id);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user