📄 newdenoise.cc
字号:
// Initialization was successful. return 0;}// Shut down the denoising system.intnewdenoise_shutdown (void){ // If color was denoised in a separate thread, shut that down. if (g_bMotionSearcherCbCr && denoiser.threads == 2) g_oDenoiserThreadCbCr.Shutdown(); if (denoiser.threads >= 1) { g_oDenoiserThreadRead.Shutdown(); g_oDenoiserThreadWrite.Shutdown(); } // No errors. return 0;}/* Read another frame. Usable only in multi-threaded situations. */intnewdenoise_read_frame (uint8_t **a_apPlanes){ // Make sure the read/write threads are being used. assert (denoiser.threads >= 1); // Easy enough. return g_oDenoiserThreadRead.ReadFrame (a_apPlanes);}/* Get space to write another frame. Usable only in multi-threaded situations. */intnewdenoise_get_write_frame (uint8_t **a_apPlanes){ // Make sure the read/write threads are being used. assert (denoiser.threads >= 1); // Easy enough. return g_oDenoiserThreadWrite.GetSpaceToWriteFrame (a_apPlanes);}/* Write another frame. Usable only in multi-threaded situations. */intnewdenoise_write_frame (void){ // Make sure the read/write threads are being used. assert (denoiser.threads >= 1); // Easy enough. g_oDenoiserThreadWrite.WriteFrame(); return Y4M_OK;}intnewdenoise_frame0 (const uint8_t *a_pInputY, const uint8_t *a_pInputCb, const uint8_t *a_pInputCr, uint8_t *a_pOutputY, uint8_t *a_pOutputCb, uint8_t *a_pOutputCr){ Status_t eStatus; // An error that may occur. const MotionSearcherY::ReferenceFrame_t *pFrameY; const MotionSearcherCbCr::ReferenceFrame_t *pFrameCbCr; // Denoised frame data, ready for output. int i; // Used to loop through pixels. // No errors yet. eStatus = g_kNoError; // No output frames have been received yet. pFrameY = NULL; pFrameCbCr = NULL; // If it's time to purge, do so. { extern int frame; if (frame % 10 == 0) { g_oMotionSearcherY.Purge(); g_oMotionSearcherCbCr.Purge(); } } // If the end of input has been reached, then return the next // remaining denoised frame, if available. if ((g_bMotionSearcherY && a_pInputY == NULL) || (g_bMotionSearcherCbCr && a_pInputCr == NULL)) { // Get any remaining frame. if (g_bMotionSearcherY) pFrameY = g_oMotionSearcherY.GetRemainingFrames(); if (g_bMotionSearcherCbCr) pFrameCbCr = g_oMotionSearcherCbCr.GetRemainingFrames(); // Output it. output_frame (pFrameY, pFrameCbCr, a_pOutputY, a_pOutputCb, a_pOutputCr); } // Otherwise, if there is more input, feed the frame into the // denoiser & possibly get a frame back. else { // Get any frame that's ready for output. if (g_bMotionSearcherY) pFrameY = g_oMotionSearcherY.GetFrameReadyForOutput(); if (g_bMotionSearcherCbCr) pFrameCbCr = g_oMotionSearcherCbCr.GetFrameReadyForOutput(); // Output it. output_frame (pFrameY, pFrameCbCr, a_pOutputY, a_pOutputCb, a_pOutputCr); // Pass the input frame to the denoiser. if (g_bMotionSearcherY) { // Convert the input frame into the format needed by the // denoiser. (This step is a big waste of time & cache. // I wish there was another way.) for (i = 0; i < g_nPixelsY; ++i) g_pPixelsY[i] = PixelY (a_pInputY + i); // Pass the frame to the denoiser. g_oMotionSearcherY.AddFrame (eStatus, g_pPixelsY); if (eStatus != g_kNoError) return -1; } if (g_bMotionSearcherCbCr) { PixelCbCr::Num_t aCbCr[2]; // Convert the input frame into the format needed by the // denoiser. (This step is a big waste of time & cache. // I wish there was another way.) for (i = 0; i < g_nPixelsCbCr; ++i) { aCbCr[0] = a_pInputCb[i]; aCbCr[1] = a_pInputCr[i]; g_pPixelsCbCr[i] = PixelCbCr (aCbCr); } // Pass the frame to the denoiser. g_oMotionSearcherCbCr.AddFrame (eStatus, g_pPixelsCbCr); if (eStatus != g_kNoError) return -1; } } // If we're denoising both color & intensity, make sure we // either got two reference frames or none at all. assert (!g_bMotionSearcherY || !g_bMotionSearcherCbCr || (pFrameY == NULL && pFrameCbCr == NULL) || (pFrameY != NULL && pFrameCbCr != NULL)); // Return whether there was an output frame this time. return (g_bMotionSearcherY && pFrameY != NULL || g_bMotionSearcherCbCr && pFrameCbCr != NULL) ? 0 : 1;}intnewdenoise_frame_intensity (const uint8_t *a_pInputY, uint8_t *a_pOutputY){ Status_t eStatus; // An error that may occur. const MotionSearcherY::ReferenceFrame_t *pFrameY; // Denoised frame data, ready for output. int i; // Used to loop through pixels. // Make sure intensity is being denoised. assert (g_bMotionSearcherY); // No errors yet. eStatus = g_kNoError; // No output frames have been received yet. pFrameY = NULL; // If it's time to purge, do so. { extern int frame; if (frame % denoiser.frames == 0) g_oMotionSearcherY.Purge(); } // If the end of input has been reached, then return the next // remaining denoised frame, if available. if (a_pInputY == NULL) { // Get any remaining frame. pFrameY = g_oMotionSearcherY.GetRemainingFrames(); // Output it. output_frame (pFrameY, NULL, a_pOutputY, NULL, NULL); } // Otherwise, if there is more input, feed the frame into the // denoiser & possibly get a frame back. else { // Get any frame that's ready for output. pFrameY = g_oMotionSearcherY.GetFrameReadyForOutput(); // Output it. output_frame (pFrameY, NULL, a_pOutputY, NULL, NULL); // Convert the input frame into the format needed by the // denoiser. (This step is a big waste of time & cache. // I wish there was another way.) for (i = 0; i < g_nPixelsY; ++i) g_pPixelsY[i] = PixelY (a_pInputY + i); // Pass the frame to the denoiser. g_oMotionSearcherY.AddFrame (eStatus, g_pPixelsY); if (eStatus != g_kNoError) return -1; } // Return whether there was an output frame this time. return (pFrameY != NULL) ? 0 : 1;}intnewdenoise_frame_color (const uint8_t *a_pInputCb, const uint8_t *a_pInputCr, uint8_t *a_pOutputCb, uint8_t *a_pOutputCr){ Status_t eStatus; // An error that may occur. const MotionSearcherCbCr::ReferenceFrame_t *pFrameCbCr; // Denoised frame data, ready for output. int i; // Used to loop through pixels. // Make sure color is being denoised. assert (g_bMotionSearcherCbCr); // No errors yet. eStatus = g_kNoError; // No output frames have been received yet. pFrameCbCr = NULL; // If it's time to purge, do so. { extern int frame; if (frame % denoiser.frames == 0) g_oMotionSearcherCbCr.Purge(); } // If the end of input has been reached, then return the next // remaining denoised frame, if available. if (a_pInputCr == NULL) { // Get any remaining frame. pFrameCbCr = g_oMotionSearcherCbCr.GetRemainingFrames(); // Output it. output_frame (NULL, pFrameCbCr, NULL, a_pOutputCb, a_pOutputCr); } // Otherwise, if there is more input, feed the frame into the // denoiser & possibly get a frame back. else { // Get any frame that's ready for output. pFrameCbCr = g_oMotionSearcherCbCr.GetFrameReadyForOutput(); // Output it. output_frame (NULL, pFrameCbCr, NULL, a_pOutputCb, a_pOutputCr); // Pass the input frame to the denoiser. { PixelCbCr::Num_t aCbCr[2]; // Convert the input frame into the format needed by the // denoiser. (This step is a big waste of time & cache. // I wish there was another way.) for (i = 0; i < g_nPixelsCbCr; ++i) { aCbCr[0] = a_pInputCb[i]; aCbCr[1] = a_pInputCr[i]; g_pPixelsCbCr[i] = PixelCbCr (aCbCr); } // Pass the frame to the denoiser. g_oMotionSearcherCbCr.AddFrame (eStatus, g_pPixelsCbCr); if (eStatus != g_kNoError) return -1; } } // Return whether there was an output frame this time. return (pFrameCbCr != NULL) ? 0 : 1;}intnewdenoise_frame (const uint8_t *a_pInputY, const uint8_t *a_pInputCb, const uint8_t *a_pInputCr, uint8_t *a_pOutputY, uint8_t *a_pOutputCb, uint8_t *a_pOutputCr){ int bY, bCbCr; // Make the compiler shut up. bY = bCbCr = 0; // Denoise intensity & color. if (g_bMotionSearcherCbCr && denoiser.threads == 2) g_oDenoiserThreadCbCr.AddFrame (a_pInputCb, a_pInputCr, a_pOutputCb, a_pOutputCr); if (g_bMotionSearcherY) bY = newdenoise_frame_intensity (a_pInputY, a_pOutputY); if (g_bMotionSearcherCbCr && denoiser.threads != 2) bCbCr = newdenoise_frame_color (a_pInputCb, a_pInputCr, a_pOutputCb, a_pOutputCr); if (g_bMotionSearcherCbCr && denoiser.threads == 2) bCbCr = g_oDenoiserThreadCbCr.WaitForAddFrame(); // If we're denoising both color & intensity, make sure we // either got two reference frames or none at all. assert (!g_bMotionSearcherY || !g_bMotionSearcherCbCr || (bY != 0 && bCbCr != 0) || (bY == 0 && bCbCr == 0)); // Return 0 if there are no errors. return (bY) ? bY : bCbCr;}static void output_frame (const MotionSearcherY::ReferenceFrame_t *a_pFrameY, const MotionSearcherCbCr::ReferenceFrame_t *a_pFrameCbCr, uint8_t *a_pOutputY, uint8_t *a_pOutputCb, uint8_t *a_pOutputCr){ int i; // Used to loop through pixels. // Convert any denoised intensity frame into the format expected // by our caller. if (a_pFrameY != NULL) { ReferencePixelY *pY; // The pixel, as it's being converted to the output format. // Make sure our caller gave us somewhere to write output. assert (a_pOutputY != NULL); // Loop through all the pixels, convert them to the output // format. for (i = 0; i < g_nPixelsY; ++i) { pY = a_pFrameY->GetPixel (i); assert (pY != NULL); a_pOutputY[i] = pY->GetValue()[0]; } } if (a_pFrameCbCr != NULL) { ReferencePixelCbCr *pCbCr; // The pixel, as it's being converted to the output format. // Make sure our caller gave us somewhere to write output. assert (a_pOutputCb != NULL && a_pOutputCr != NULL); // Loop through all the pixels, convert them to the output // format. for (i = 0; i < g_nPixelsCbCr; ++i) { pCbCr = a_pFrameCbCr->GetPixel (i); assert (pCbCr != NULL); const PixelCbCr &rCbCr = pCbCr->GetValue(); a_pOutputCb[i] = rCbCr[0]; a_pOutputCr[i] = rCbCr[1]; } }}intnewdenoise_interlaced_frame0 (const uint8_t *a_pInputY, const uint8_t *a_pInputCb, const uint8_t *a_pInputCr, uint8_t *a_pOutputY, uint8_t *a_pOutputCb, uint8_t *a_pOutputCr){ Status_t eStatus; // An error that may occur. const MotionSearcherY::ReferenceFrame_t *pFrameY; const MotionSearcherCbCr::ReferenceFrame_t *pFrameCbCr; // Denoised frame data, ready for output. int i, x, y; // Used to loop through pixels. int nMask; // Used to switch between top-field interlacing and bottom-field // interlacing. // No errors yet. eStatus = g_kNoError; // No output frames have been received yet. pFrameY = NULL; pFrameCbCr = NULL; // If it's time to purge, do so. { extern int frame; if (frame % 10 == 0) { g_oMotionSearcherY.Purge(); g_oMotionSearcherCbCr.Purge(); } } // Set up for the type of interlacing. nMask = (denoiser.interlaced == 2) ? 1 : 0; // If the end of input has been reached, then return the next // remaining denoised frame, if available. if ((g_bMotionSearcherY && a_pInputY == NULL) || (g_bMotionSearcherCbCr && a_pInputCr == NULL)) { // Get 1/2 any remaining frame. if (g_bMotionSearcherY) pFrameY = g_oMotionSearcherY.GetRemainingFrames(); if (g_bMotionSearcherCbCr) pFrameCbCr = g_oMotionSearcherCbCr.GetRemainingFrames(); // Output it. output_field (nMask ^ 0, pFrameY, pFrameCbCr, a_pOutputY, a_pOutputCb, a_pOutputCr); // Get 1/2 any remaining frame. if (g_bMotionSearcherY) pFrameY = g_oMotionSearcherY.GetRemainingFrames(); if (g_bMotionSearcherCbCr) pFrameCbCr = g_oMotionSearcherCbCr.GetRemainingFrames(); // Output it. output_field (nMask ^ 1, pFrameY, pFrameCbCr, a_pOutputY, a_pOutputCb, a_pOutputCr); } // Otherwise, if there is more input, feed the frame into the // denoiser & possibly get a frame back. else { // Get 1/2 any frame that's ready for output. if (g_bMotionSearcherY) pFrameY = g_oMotionSearcherY.GetFrameReadyForOutput(); if (g_bMotionSearcherCbCr) pFrameCbCr = g_oMotionSearcherCbCr.GetFrameReadyForOutput(); // Output it. output_field (nMask ^ 0, pFrameY, pFrameCbCr, a_pOutputY, a_pOutputCb, a_pOutputCr); // Pass the input frame to the denoiser. if (g_bMotionSearcherY) { // Convert the input frame into the format needed by the // denoiser. for (i = 0, y = (nMask ^ 0); y < g_nHeightY; y += 2) for (x = 0; x < g_nWidthY; ++x, ++i) g_pPixelsY[i] = PixelY (a_pInputY + (y * g_nWidthY + x)); assert (i == g_nPixelsY); // Pass the frame to the denoiser. g_oMotionSearcherY.AddFrame (eStatus, g_pPixelsY); if (eStatus != g_kNoError) return -1; } if (g_bMotionSearcherCbCr) { PixelCbCr::Num_t aCbCr[2]; // Convert the input frame into the format needed by the // denoiser. for (i = 0, y = (nMask ^ 0); y < g_nHeightCbCr; y += 2) { for (x = 0; x < g_nWidthCbCr; ++x, ++i) { aCbCr[0] = a_pInputCb[y * g_nWidthCbCr + x]; aCbCr[1] = a_pInputCr[y * g_nWidthCbCr + x]; g_pPixelsCbCr[i] = PixelCbCr (aCbCr); } } assert (i == g_nPixelsCbCr); // Pass the frame to the denoiser. g_oMotionSearcherCbCr.AddFrame (eStatus, g_pPixelsCbCr); if (eStatus != g_kNoError) return -1; } // Get 1/2 any frame that's ready for output. if (g_bMotionSearcherY) pFrameY = g_oMotionSearcherY.GetFrameReadyForOutput(); if (g_bMotionSearcherCbCr) pFrameCbCr = g_oMotionSearcherCbCr.GetFrameReadyForOutput(); // Output it. output_field (nMask ^ 1, pFrameY, pFrameCbCr, a_pOutputY, a_pOutputCb, a_pOutputCr); // Pass the input frame to the denoiser. if (g_bMotionSearcherY) { // Convert the input frame into the format needed by the // denoiser. for (i = 0, y = (nMask ^ 1); y < g_nHeightY; y += 2) for (x = 0; x < g_nWidthY; ++x, ++i) g_pPixelsY[i] = PixelY (a_pInputY + (y * g_nWidthY + x)); assert (i == g_nPixelsY); // Pass the frame to the denoiser. g_oMotionSearcherY.AddFrame (eStatus, g_pPixelsY); if (eStatus != g_kNoError) return -1; } if (g_bMotionSearcherCbCr) { PixelCbCr::Num_t aCbCr[2]; // Convert the input frame into the format needed by the // denoiser. for (i = 0, y = (nMask ^ 1); y < g_nHeightCbCr; y += 2) { for (x = 0; x < g_nWidthCbCr; ++x, ++i) { aCbCr[0] = a_pInputCb[y * g_nWidthCbCr + x]; aCbCr[1] = a_pInputCr[y * g_nWidthCbCr + x];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -