Skip to content

Commit a25392b

Browse files
committed
vcomp/lavc: add setparam for liboapv
This fixes the situations when selected AVPixelFormat is not AV_PIX_FMT_YUV422P10. closes <#472>
1 parent 2ebd7d6 commit a25392b

File tree

1 file changed

+52
-1
lines changed

1 file changed

+52
-1
lines changed

src/video_compress/libavcodec.cpp

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ get_default_crf(const char *codec_name)
156156

157157
struct setparam_param {
158158
struct video_desc desc {};
159+
AVPixelFormat av_pix_fmt;
159160
bool have_preset = false;
160161
int periodic_intra = -1; ///< -1 default; 0 disable/not enable; 1 enable
161162
int interlaced_dct = -1; ///< -1 default; 0 disable/not enable; 1 enable
@@ -183,6 +184,7 @@ static void libavcodec_compress_done(void *state);
183184
static void setparam_default(AVCodecContext *, struct setparam_param *);
184185
static void setparam_h264_h265_av1(AVCodecContext *, struct setparam_param *);
185186
static void setparam_jpeg(AVCodecContext *, struct setparam_param *);
187+
static void setparam_oapv(AVCodecContext *, struct setparam_param *);
186188
static void setparam_vp8_vp9(AVCodecContext *, struct setparam_param *);
187189
static void set_codec_thread_mode(AVCodecContext *codec_ctx, struct setparam_param *param);
188190

@@ -202,6 +204,7 @@ const char *get_vp9_encoder(bool /* rgb */) {
202204
codec_params_t
203205
get_codec_params(codec_t ug_codec)
204206
{
207+
int capabilities_priority = 500 + (int) ug_codec;
205208
switch (ug_codec) {
206209
case H264: return {
207210
[](bool is_rgb) { return is_rgb ? "libx264rgb" : "libx264"; },
@@ -229,10 +232,11 @@ get_codec_params(codec_t ug_codec)
229232
setparam_h264_h265_av1,
230233
600
231234
};
235+
case APV:
236+
return { nullptr, 0, setparam_oapv, capabilities_priority };
232237
default:
233238
break;
234239
}
235-
int capabilities_priority = 500 + (int) ug_codec;
236240
double avg_bpp = 0;
237241
if (ug_codec == J2K) {
238242
avg_bpp = 1;
@@ -884,6 +888,7 @@ bool set_codec_ctx_params(struct state_video_compress_libav *s, AVPixelFormat pi
884888

885889
// make a copy because set_param callbacks may adjust parameters
886890
struct setparam_param params = s->params;
891+
params.av_pix_fmt = pix_fmt;
887892
params.lavc_opts = s->req_lavc_opts;
888893

889894
// average bit per pixel
@@ -1732,6 +1737,52 @@ static void setparam_jpeg(AVCodecContext *codec_ctx, struct setparam_param *para
17321737
}
17331738
}
17341739

1740+
/**
1741+
* @details liboapv seem to require setting the profile to match the pixel
1742+
* format, otherwise oapv_encode() return -400 ([GH bug]). As the default
1743+
* profile is "422-10", we perhaps want to use this anyways, otherwise the codec
1744+
* would convert the input to match the profile according to the command
1745+
* `oapv_app_enc` help.
1746+
* [GH bug]: https://github.com/CESNET/UltraGrid/issues/472
1747+
*/
1748+
static void
1749+
setparam_oapv(AVCodecContext */*codec_ctx*/, struct setparam_param *param)
1750+
{
1751+
auto it = param->lavc_opts.find("oapv-params");
1752+
if (it->second.find("profile=") != std::string::npos) {
1753+
return; // do not overwrite profile if set explicitly
1754+
}
1755+
const char *profile = nullptr;
1756+
switch (param->av_pix_fmt) {
1757+
// clang-format off
1758+
case AV_PIX_FMT_GRAY10: profile = "400-10"; break;
1759+
case AV_PIX_FMT_YUV422P10: profile = "422-10"; break;
1760+
case AV_PIX_FMT_YUV422P12: profile = "422-12"; break;
1761+
case AV_PIX_FMT_YUV444P10: profile = "444-10"; break;
1762+
case AV_PIX_FMT_YUV444P12: profile = "444-12"; break;
1763+
case AV_PIX_FMT_YUVA444P10: profile = "4444-10"; break;
1764+
case AV_PIX_FMT_YUVA444P12: profile = "4444-14"; break;
1765+
// clang-format on
1766+
default:
1767+
MSG(WARNING,
1768+
"Unhandled APV (liboapv) pixel format %s, not setting "
1769+
"preset.\n",
1770+
av_get_pix_fmt_name(param->av_pix_fmt));
1771+
return;
1772+
}
1773+
char oapv_params[STR_LEN];
1774+
oapv_params[0] = '\0';
1775+
// if some oapv-params passed from command-line, append the preset after
1776+
if (it != param->lavc_opts.end()) {
1777+
snprintf_ch(oapv_params, "%s:", it->second.c_str());
1778+
}
1779+
int neeeded = snprintf(oapv_params + strlen(oapv_params),
1780+
sizeof oapv_params - strlen(oapv_params),
1781+
"profile=%s", profile);
1782+
assert(neeeded < (int) sizeof oapv_params);
1783+
param->lavc_opts["oapv-params"] = oapv_params;
1784+
}
1785+
17351786
static void configure_amf([[maybe_unused]] AVCodecContext *codec_ctx, [[maybe_unused]] struct setparam_param *param) {
17361787
check_av_opt_set(codec_ctx->priv_data, "rc", DEFAULT_AMF_RC);
17371788
const char *const usage = codec_ctx->codec->id == AV_CODEC_ID_AV1

0 commit comments

Comments
 (0)