From bc16bb8862c13dc253251dd348e34609f66ec5f2 Mon Sep 17 00:00:00 2001 From: rigaya Date: Sun, 19 Nov 2023 21:11:31 +0900 Subject: [PATCH] =?UTF-8?q?--vpp-nnedi=E3=81=A7bob=E5=8C=96=E3=81=99?= =?UTF-8?q?=E3=82=8B=E9=9A=9B=E3=80=81--vpp-rff=E3=81=AA=E3=81=97=E3=81=A7?= =?UTF-8?q?rff=E3=81=AA=E5=8B=95=E7=94=BB=E3=82=92=E5=87=A6=E7=90=86?= =?UTF-8?q?=E3=81=99=E3=82=8B=E3=81=A8timestamp=E5=91=A8=E3=82=8A=E3=81=AE?= =?UTF-8?q?=E8=A8=88=E7=AE=97=E3=81=8C=E3=81=8A=E3=81=8B=E3=81=97=E3=81=8F?= =?UTF-8?q?=E3=81=AA=E3=82=8A=E3=82=A8=E3=83=A9=E3=83=BC=E7=B5=82=E4=BA=86?= =?UTF-8?q?=E3=81=99=E3=82=8B=E5=95=8F=E9=A1=8C=E3=82=92=E4=BF=AE=E6=AD=A3?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- NVEncCore/NVEncCore.cpp | 1 + NVEncCore/NVEncFilterNnedi.cu | 20 ++++++++++ NVEncCore/NVEncFilterNnedi.h | 4 +- NVEncCore/NVEncFilterYadif.cu | 71 ++++++++++++++++++++++------------- NVEncCore/NVEncFilterYadif.h | 1 + 5 files changed, 69 insertions(+), 28 deletions(-) diff --git a/NVEncCore/NVEncCore.cpp b/NVEncCore/NVEncCore.cpp index 878648d1..ed020672 100644 --- a/NVEncCore/NVEncCore.cpp +++ b/NVEncCore/NVEncCore.cpp @@ -2479,6 +2479,7 @@ RGY_ERR NVEncCore::InitFilters(const InEncodeVideoParam *inputParam) { param->frameIn = inputFrame; param->frameOut = inputFrame; param->baseFps = m_encFps; + param->timebase = m_outputTimebase; param->bOutOverwrite = false; NVEncCtxAutoLock(cxtlock(m_dev->vidCtxLock())); auto sts = filter->init(param, m_pNVLog); diff --git a/NVEncCore/NVEncFilterNnedi.cu b/NVEncCore/NVEncFilterNnedi.cu index 6fe14a11..977f3e75 100644 --- a/NVEncCore/NVEncFilterNnedi.cu +++ b/NVEncCore/NVEncFilterNnedi.cu @@ -1801,6 +1801,10 @@ RGY_ERR NVEncFilterNnedi::run_filter(const RGYFrameInfo *pInputFrame, RGYFrameIn || pNnediParam->nnedi.field == VPP_NNEDI_FIELD_BOB_AUTO) { if ((pInputFrame->picstruct & RGY_PICSTRUCT_INTERLACED) == 0) { copyFrameAsync(ppOutputFrames[0], pInputFrame, stream); + if (pNnediParam->nnedi.isbob()) { + copyFrameAsync(ppOutputFrames[1], pInputFrame, stream); + setBobTimestamp(pInputFrame, ppOutputFrames); + } return RGY_ERR_NONE; } else if ((pInputFrame->picstruct & RGY_PICSTRUCT_FRAME_TFF) == RGY_PICSTRUCT_FRAME_TFF) { targetField = NNEDI_GEN_FIELD_BOTTOM; @@ -1882,6 +1886,22 @@ RGY_ERR NVEncFilterNnedi::run_filter(const RGYFrameInfo *pInputFrame, RGYFrameIn return sts; } +void NVEncFilterNnedi::setBobTimestamp(const RGYFrameInfo *pInputFrame, RGYFrameInfo **ppOutputFrames) { + auto prm = std::dynamic_pointer_cast(m_pParam); + + auto frameDuration = pInputFrame->duration; + if (frameDuration == 0) { + frameDuration = (decltype(frameDuration))((prm->timebase.inv() / prm->baseFps * 2).qdouble() + 0.5); + } + ppOutputFrames[1]->picstruct = RGY_PICSTRUCT_FRAME; + ppOutputFrames[0]->timestamp = pInputFrame->timestamp; + ppOutputFrames[0]->duration = (frameDuration + 1) / 2; + ppOutputFrames[1]->timestamp = ppOutputFrames[0]->timestamp + ppOutputFrames[0]->duration; + ppOutputFrames[1]->duration = frameDuration - ppOutputFrames[0]->duration; + ppOutputFrames[0]->inputFrameId = pInputFrame->inputFrameId; + ppOutputFrames[1]->inputFrameId = pInputFrame->inputFrameId; +} + void NVEncFilterNnedi::close() { m_pFrameBuf.clear(); } diff --git a/NVEncCore/NVEncFilterNnedi.h b/NVEncCore/NVEncFilterNnedi.h index 9169f62f..3185ae33 100644 --- a/NVEncCore/NVEncFilterNnedi.h +++ b/NVEncCore/NVEncFilterNnedi.h @@ -42,8 +42,9 @@ class NVEncFilterParamNnedi : public NVEncFilterParam { VppNnedi nnedi; std::pair compute_capability; HMODULE hModule; + rgy_rational timebase; - NVEncFilterParamNnedi() : nnedi(), compute_capability(std::make_pair(0, 0)), hModule(NULL) {}; + NVEncFilterParamNnedi() : nnedi(), compute_capability(std::make_pair(0, 0)), hModule(NULL), timebase() {}; virtual ~NVEncFilterParamNnedi() {}; virtual tstring print() const override; }; @@ -64,6 +65,7 @@ class NVEncFilterNnedi : public NVEncFilter { virtual void close() override; virtual RGY_ERR checkParam(const std::shared_ptr pParam); virtual RGY_ERR initParams(const std::shared_ptr pNnediParam); + void setBobTimestamp(const RGYFrameInfo *pInputFrame, RGYFrameInfo **ppOutputFrames); template void setWeight0(TypeWeight *ptrDst, const float *ptrW, const std::shared_ptr pNnediParam); diff --git a/NVEncCore/NVEncFilterYadif.cu b/NVEncCore/NVEncFilterYadif.cu index 3acc5bba..89e85378 100644 --- a/NVEncCore/NVEncFilterYadif.cu +++ b/NVEncCore/NVEncFilterYadif.cu @@ -453,15 +453,18 @@ RGY_ERR NVEncFilterYadif::run_filter(const RGYFrameInfo *pInputFrame, RGYFrameIn ppOutputFrames[0]->picstruct = RGY_PICSTRUCT_FRAME; ppOutputFrames[0]->timestamp = pSourceFrame->timestamp; ppOutputFrames[0]->inputFrameId = pSourceFrame->inputFrameId; - copyFrameAsync(ppOutputFrames[0], pSourceFrame, stream); + sts = err_to_rgy(copyFrameAsync(ppOutputFrames[0], pSourceFrame, stream)); + if (sts != RGY_ERR_NONE) { + AddMessage(RGY_LOG_ERROR, _T("failed to copy frame: %s.\n"), get_err_mes(sts)); + return sts; + } if (prmYadif->yadif.mode & VPP_YADIF_MODE_BOB) { - ppOutputFrames[1]->picstruct = RGY_PICSTRUCT_FRAME; - ppOutputFrames[0]->timestamp = pSourceFrame->timestamp; - ppOutputFrames[0]->duration = (pSourceFrame->duration + 1) / 2; - ppOutputFrames[1]->timestamp = ppOutputFrames[0]->timestamp + ppOutputFrames[0]->duration; - ppOutputFrames[1]->duration = pSourceFrame->duration - ppOutputFrames[0]->duration; - ppOutputFrames[1]->inputFrameId = pSourceFrame->inputFrameId; - copyFrameAsync(ppOutputFrames[1], pSourceFrame, stream); + sts = err_to_rgy(copyFrameAsync(ppOutputFrames[1], pSourceFrame, stream)); + if (sts != RGY_ERR_NONE) { + AddMessage(RGY_LOG_ERROR, _T("failed to copy frame: %s.\n"), get_err_mes(sts)); + return sts; + } + setBobTimestamp(iframe, ppOutputFrames); } m_nFrame++; return RGY_ERR_NONE; @@ -489,14 +492,18 @@ RGY_ERR NVEncFilterYadif::run_filter(const RGYFrameInfo *pInputFrame, RGYFrameIn AddMessage(RGY_LOG_ERROR, _T("unsupported csp %s.\n"), RGY_CSP_NAMES[pSourceFrame->csp]); return RGY_ERR_UNSUPPORTED; } - func_list.at(pSourceFrame->csp)(ppOutputFrames[0], + sts = err_to_rgy(func_list.at(pSourceFrame->csp)(ppOutputFrames[0], &m_source.get(m_nFrame-1)->frame, &m_source.get(m_nFrame+0)->frame, &m_source.get(m_nFrame+1)->frame, targetField, pSourceFrame->picstruct, stream - ); + )); + if (sts != RGY_ERR_NONE) { + AddMessage(RGY_LOG_ERROR, _T("failed to copy frame: %s.\n"), get_err_mes(sts)); + return sts; + } ppOutputFrames[0]->picstruct = RGY_PICSTRUCT_FRAME; ppOutputFrames[0]->timestamp = pSourceFrame->timestamp; @@ -508,30 +515,19 @@ RGY_ERR NVEncFilterYadif::run_filter(const RGYFrameInfo *pInputFrame, RGYFrameIn AddMessage(RGY_LOG_ERROR, _T("unsupported csp %s.\n"), RGY_CSP_NAMES[pSourceFrame->csp]); return RGY_ERR_UNSUPPORTED; } - func_list.at(pSourceFrame->csp)(ppOutputFrames[1], + sts = err_to_rgy(func_list.at(pSourceFrame->csp)(ppOutputFrames[1], &m_source.get(m_nFrame-1)->frame, &m_source.get(m_nFrame+0)->frame, &m_source.get(m_nFrame+1)->frame, targetField, pSourceFrame->picstruct, stream - ); - auto frameDuration = pSourceFrame->duration; - if (frameDuration == 0) { - if (iframe <= 1) { - frameDuration = (decltype(frameDuration))((prmYadif->timebase / prmYadif->baseFps * 2).qdouble() + 0.5); - } else if (m_nFrame + 1 >= iframe) { - frameDuration = m_source.get(m_nFrame + 0)->frame.timestamp - m_source.get(m_nFrame - 1)->frame.timestamp; - } else { - frameDuration = m_source.get(m_nFrame + 1)->frame.timestamp - m_source.get(m_nFrame + 0)->frame.timestamp; - } + )); + if (sts != RGY_ERR_NONE) { + AddMessage(RGY_LOG_ERROR, _T("failed to copy frame: %s.\n"), get_err_mes(sts)); + return sts; } - ppOutputFrames[1]->picstruct = RGY_PICSTRUCT_FRAME; - ppOutputFrames[0]->timestamp = pSourceFrame->timestamp; - ppOutputFrames[0]->duration = (frameDuration + 1) / 2; - ppOutputFrames[1]->timestamp = ppOutputFrames[0]->timestamp + ppOutputFrames[0]->duration; - ppOutputFrames[1]->duration = frameDuration - ppOutputFrames[0]->duration; - ppOutputFrames[1]->inputFrameId = pSourceFrame->inputFrameId; + setBobTimestamp(iframe, ppOutputFrames); } m_nFrame++; } else { @@ -542,6 +538,27 @@ RGY_ERR NVEncFilterYadif::run_filter(const RGYFrameInfo *pInputFrame, RGYFrameIn return sts; } +void NVEncFilterYadif::setBobTimestamp(const int iframe, RGYFrameInfo **ppOutputFrames) { + auto prm = std::dynamic_pointer_cast(m_pParam); + + auto frameDuration = m_source.get(m_nFrame + 0)->frame.duration; + if (frameDuration == 0) { + if (iframe <= 1) { + frameDuration = (decltype(frameDuration))((prm->timebase.inv() / prm->baseFps * 2).qdouble() + 0.5); + } else if (m_nFrame + 1 >= iframe) { + frameDuration = m_source.get(m_nFrame + 0)->frame.timestamp - m_source.get(m_nFrame - 1)->frame.timestamp; + } else { + frameDuration = m_source.get(m_nFrame + 1)->frame.timestamp - m_source.get(m_nFrame + 0)->frame.timestamp; + } + } + ppOutputFrames[1]->picstruct = RGY_PICSTRUCT_FRAME; + ppOutputFrames[0]->timestamp = m_source.get(m_nFrame + 0)->frame.timestamp; + ppOutputFrames[0]->duration = (frameDuration + 1) / 2; + ppOutputFrames[1]->timestamp = ppOutputFrames[0]->timestamp + ppOutputFrames[0]->duration; + ppOutputFrames[1]->duration = frameDuration - ppOutputFrames[0]->duration; + ppOutputFrames[1]->inputFrameId = m_source.get(m_nFrame + 0)->frame.inputFrameId; +} + void NVEncFilterYadif::close() { m_nFrame = 0; m_pts = 0; diff --git a/NVEncCore/NVEncFilterYadif.h b/NVEncCore/NVEncFilterYadif.h index 8787341c..27d5d127 100644 --- a/NVEncCore/NVEncFilterYadif.h +++ b/NVEncCore/NVEncFilterYadif.h @@ -77,6 +77,7 @@ class NVEncFilterYadif : public NVEncFilter { virtual RGY_ERR run_filter(const RGYFrameInfo *pInputFrame, RGYFrameInfo **ppOutputFrames, int *pOutputFrameNum, cudaStream_t stream) override; virtual void close() override; RGY_ERR check_param(shared_ptr prmYadif); + void setBobTimestamp(const int iframe, RGYFrameInfo **ppOutputFrames); int m_nFrame; int64_t m_pts;