d3f92ca5d6
This makes FFmpeg usable as an output, and removes or changes most of the code that was originally intended for testing purposes. Changes the settings for the FFmpeg output to the following: * url: Sets the output URL or file path * video_bitrate: Sets the video bitrate * audio_bitrate: Sets the audio bitrate * video_encoder: Sets the video encoder (by name, blank for default) * audio_encoder: Sets the audio encoder (by name, blank for default) * video_settings: Sets custom video encoder FFmpeg settings * audio_settings: Sets custom audio encoder FFmpeg settings * scale_width: Image scale width (0 if none) * scale_height: Image scale height (0 if none) The reason why scale_width and scale_height are provided is because it may internally convert formats, and it may be a bit more optimal to use that scaler instead of the pre-output scaler just in case it already has to convert formats internally anyway (though you can do it either way you wish). Video format handling has also changed; it will now attempt to use the closest format to the current format if available for a given video codec.
116 lines
2.4 KiB
C
116 lines
2.4 KiB
C
#pragma once
|
|
|
|
static const enum AVPixelFormat i420_formats[] = {
|
|
AV_PIX_FMT_YUV420P,
|
|
AV_PIX_FMT_NV12,
|
|
AV_PIX_FMT_NV21,
|
|
AV_PIX_FMT_YUYV422,
|
|
AV_PIX_FMT_UYVY422,
|
|
AV_PIX_FMT_YUV422P,
|
|
AV_PIX_FMT_NONE
|
|
};
|
|
|
|
static const enum AVPixelFormat nv12_formats[] = {
|
|
AV_PIX_FMT_NV12,
|
|
AV_PIX_FMT_NV21,
|
|
AV_PIX_FMT_YUV420P,
|
|
AV_PIX_FMT_YUYV422,
|
|
AV_PIX_FMT_UYVY422,
|
|
AV_PIX_FMT_NONE
|
|
};
|
|
|
|
static const enum AVPixelFormat yuy2_formats[] = {
|
|
AV_PIX_FMT_YUYV422,
|
|
AV_PIX_FMT_UYVY422,
|
|
AV_PIX_FMT_NV12,
|
|
AV_PIX_FMT_NV21,
|
|
AV_PIX_FMT_YUV420P,
|
|
AV_PIX_FMT_NONE
|
|
};
|
|
|
|
static const enum AVPixelFormat uyvy_formats[] = {
|
|
AV_PIX_FMT_UYVY422,
|
|
AV_PIX_FMT_YUYV422,
|
|
AV_PIX_FMT_NV12,
|
|
AV_PIX_FMT_NV21,
|
|
AV_PIX_FMT_YUV420P,
|
|
AV_PIX_FMT_NONE
|
|
};
|
|
|
|
static const enum AVPixelFormat rgba_formats[] = {
|
|
AV_PIX_FMT_RGBA,
|
|
AV_PIX_FMT_BGRA,
|
|
AV_PIX_FMT_YUYV422,
|
|
AV_PIX_FMT_UYVY422,
|
|
AV_PIX_FMT_NV12,
|
|
AV_PIX_FMT_NV21,
|
|
AV_PIX_FMT_NONE
|
|
};
|
|
|
|
static const enum AVPixelFormat bgra_formats[] = {
|
|
AV_PIX_FMT_BGRA,
|
|
AV_PIX_FMT_RGBA,
|
|
AV_PIX_FMT_YUYV422,
|
|
AV_PIX_FMT_UYVY422,
|
|
AV_PIX_FMT_NV12,
|
|
AV_PIX_FMT_NV21,
|
|
AV_PIX_FMT_NONE
|
|
};
|
|
|
|
static enum AVPixelFormat get_best_format(
|
|
const enum AVPixelFormat *best,
|
|
const enum AVPixelFormat *formats)
|
|
{
|
|
while (*best != AV_PIX_FMT_NONE) {
|
|
enum AVPixelFormat best_format = *best;
|
|
const enum AVPixelFormat *cur_formats = formats;
|
|
|
|
while (*cur_formats != AV_PIX_FMT_NONE) {
|
|
enum AVPixelFormat avail_format = *cur_formats;
|
|
|
|
if (best_format == avail_format)
|
|
return best_format;
|
|
|
|
cur_formats++;
|
|
}
|
|
|
|
best++;
|
|
}
|
|
|
|
return AV_PIX_FMT_NONE;
|
|
}
|
|
|
|
static inline enum AVPixelFormat get_closest_format(
|
|
enum AVPixelFormat format,
|
|
const enum AVPixelFormat *formats)
|
|
{
|
|
enum AVPixelFormat best_format = AV_PIX_FMT_NONE;
|
|
|
|
if (!formats || formats[0] == AV_PIX_FMT_NONE)
|
|
return format;
|
|
|
|
switch ((int)format) {
|
|
|
|
case AV_PIX_FMT_YUV420P:
|
|
best_format = get_best_format(i420_formats, formats);
|
|
break;
|
|
case AV_PIX_FMT_NV12:
|
|
best_format = get_best_format(nv12_formats, formats);
|
|
break;
|
|
case AV_PIX_FMT_YUYV422:
|
|
best_format = get_best_format(yuy2_formats, formats);
|
|
break;
|
|
case AV_PIX_FMT_UYVY422:
|
|
best_format = get_best_format(uyvy_formats, formats);
|
|
break;
|
|
case AV_PIX_FMT_RGBA:
|
|
best_format = get_best_format(rgba_formats, formats);
|
|
break;
|
|
case AV_PIX_FMT_BGRA:
|
|
best_format = get_best_format(bgra_formats, formats);
|
|
break;
|
|
}
|
|
|
|
return (best_format == AV_PIX_FMT_NONE) ? formats[0] : best_format;
|
|
}
|