@@ -156,6 +156,7 @@ get_default_crf(const char *codec_name)
156156
157157struct 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);
183184static void setparam_default (AVCodecContext *, struct setparam_param *);
184185static void setparam_h264_h265_av1 (AVCodecContext *, struct setparam_param *);
185186static void setparam_jpeg (AVCodecContext *, struct setparam_param *);
187+ static void setparam_oapv (AVCodecContext *, struct setparam_param *);
186188static void setparam_vp8_vp9 (AVCodecContext *, struct setparam_param *);
187189static void set_codec_thread_mode (AVCodecContext *codec_ctx, struct setparam_param *param);
188190
@@ -202,6 +204,7 @@ const char *get_vp9_encoder(bool /* rgb */) {
202204codec_params_t
203205get_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+
17351786static 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