diff --git a/src/plumbing/transcoding.c b/src/plumbing/transcoding.c index 6decde3..b4117e8 100644 --- a/src/plumbing/transcoding.c +++ b/src/plumbing/transcoding.c @@ -1035,6 +1035,7 @@ create_video_filter(video_stream_t *vs, transcoder_t *t, { AVFilterInOut *flt_inputs, *flt_outputs; AVFilter *flt_bufsrc, *flt_bufsink; + enum AVPixelFormat pix_fmts[] = { 0, AV_PIX_FMT_NONE }; char opt[128]; int err; @@ -1088,6 +1089,15 @@ create_video_filter(video_stream_t *vs, transcoder_t *t, goto out_err; } + pix_fmts[0] = octx->pix_fmt; + err = av_opt_set_int_list(vs->flt_bufsinkctx, "pix_fmts", pix_fmts, + AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN); + if (err < 0) { + tvherror("transcode", "%08X: fltchain cannot set output pixfmt", + shortid(t)); + goto out_err; + } + flt_outputs->name = av_strdup("in"); flt_outputs->filter_ctx = vs->flt_bufsrcctx; flt_outputs->pad_idx = 0; @@ -1240,7 +1250,11 @@ transcoder_stream_video(transcoder_t *t, transcoder_stream_t *ts, th_pkt_t *pkt) switch (ts->ts_type) { case SCT_MPEG2VIDEO: - octx->pix_fmt = AV_PIX_FMT_YUV420P; + if (!strcmp(ocodec->name, "nvenc") || !strcmp(ocodec->name, "mpeg2_qsv")) + octx->pix_fmt = AV_PIX_FMT_NV12; + else + octx->pix_fmt = AV_PIX_FMT_YUV420P; octx->flags |= CODEC_FLAG_GLOBAL_HEADER; + octx->flags |= CODEC_FLAG_GLOBAL_HEADER; if (t->t_props.tp_vbitrate < 64) { @@ -1287,11 +1301,20 @@ transcoder_stream_video(transcoder_t *t, transcoder_stream_t *ts, th_pkt_t *pkt) break; case SCT_H264: - octx->pix_fmt = AV_PIX_FMT_YUV420P; + if (!strcmp(ocodec->name, "nvenc") || !strcmp(ocodec->name, "h264_qsv")) + octx->pix_fmt = AV_PIX_FMT_NV12; + else + octx->pix_fmt = AV_PIX_FMT_YUV420P; + octx->flags |= CODEC_FLAG_GLOBAL_HEADER; // Default = "medium". We gain more encoding speed compared to the loss of quality when lowering it _slightly_. - av_dict_set(&opts, "preset", "faster", 0); + if (!strcmp(ocodec->name, "nvenc")) + av_dict_set(&opts, "preset", "hq", 0); + else if (!strcmp(ocodec->name, "h264_qsv")) + av_dict_set(&opts, "preset", "medium", 0); + else + av_dict_set(&opts, "preset", "faster", 0); // All modern devices should support "high" profile av_dict_set(&opts, "profile", "high", 0);