📄 newdenoise.cc
字号:
// The BasicThread class.// Default constructor.BasicThread::BasicThread() : m_oInputCondition (m_oMutex), m_oOutputCondition (m_oMutex){ // No waiting yet. m_bWaitingForInput = m_bWaitingForOutput = false; // No work yet. m_bWorkLoop = false; // No return value yet. m_nWorkRetval = Y4M_OK; // Nothing additional to do. m_oInputCondition and // m_oOutputCondition are already constructed, and m_oThreadInfo is // initialized by pthread_create().}// Destructor.BasicThread::~BasicThread(){ // Nothing additional to do. m_oInputCondition and // m_oOutputCondition are destroyed by default, and m_oThreadInfo // apparently does not need to be destroyed.}// Start the thread.voidBasicThread::Initialize (void){ int nErr; // An error that may occur. pthread_attr_t sThreadAttributes; // Where we set up thread attributes. // Set up to work. m_bWorkLoop = true; // Set up the initial, default set of thread attributes. nErr = pthread_attr_init (&sThreadAttributes); if (nErr != 0) mjpeg_error_exit1 ("pthread_attr_init() failed: %s", strerror (nErr)); // Inherit scheduling parameters from the main thread. nErr = pthread_attr_setinheritsched (&sThreadAttributes, PTHREAD_INHERIT_SCHED); if (nErr != 0) mjpeg_error_exit1 ("pthread_attr_setinheritsched() failed: %s", strerror (nErr)); // Create the thread. nErr = pthread_create (&m_oThreadInfo, &sThreadAttributes, WorkLoop, (void *)this); if (nErr != 0) mjpeg_error_exit1 ("pthread_create() failed: %s", strerror (nErr));} // Lock the mutex that guards the conditions.voidBasicThread::Lock (void){ // Easy enough. m_oMutex.Lock();}// Unlock the mutex that guards the conditions.voidBasicThread::Unlock (void){ // Easy enough. m_oMutex.Unlock();}// Signal that input has been provided to the thread.voidBasicThread::SignalInput (void){ // Make sure the mutex is locked. assert (m_oMutex.m_bLocked); // Easy enough. m_oInputCondition.Signal();}// Wait for input to be provided.// Called by the subclass' Work() method.voidBasicThread::WaitForInput (void){ // Make sure the mutex is locked. assert (m_oMutex.m_bLocked); // Easy enough. m_bWaitingForInput = true; m_oInputCondition.Wait(); m_bWaitingForInput = false;}// Signal that output has been provided to the thread.// Called by the subclass' Work() method.voidBasicThread::SignalOutput (void){ // Make sure the mutex is locked. assert (m_oMutex.m_bLocked); // Easy enough. m_oOutputCondition.Signal();}// Wait for output to be provided.voidBasicThread::WaitForOutput (void){ // Make sure the mutex is locked. assert (m_oMutex.m_bLocked); // Easy enough. m_bWaitingForOutput = true; m_oOutputCondition.Wait(); m_bWaitingForOutput = false;}// Stop the thread.voidBasicThread::Shutdown (void){ // Make sure we have exclusive access. assert (m_oMutex.m_bLocked); // Tell the thread to stop looping. m_bWorkLoop = false;}// The thread function.void *BasicThread::WorkLoop (void *a_pThread){ // Make sure they gave us a thread object. assert (a_pThread != NULL); // Call the real work loop. (static_cast<BasicThread *>(a_pThread))->WorkLoop(); // Mandatory return value. return NULL;}// The thread function. Loop, calling Work(), until told to stop.voidBasicThread::WorkLoop (void){ // Loop and do work until told to quit. for (;;) { // If we're out of work, stop. if (!m_bWorkLoop) break; // Do work. m_nWorkRetval = Work(); // If it returned non-OK, stop. if (m_nWorkRetval != Y4M_OK) break; } // Remember that the work loop has stopped. m_bWorkLoop = false;}// The DenoiserThread class.// Default constructor.DenoiserThread::DenoiserThread(){ // Nothing additional to do.}// Destructor.DenoiserThread::~DenoiserThread(){ // Nothing additional to do.}// Stop the thread.voidDenoiserThread::Shutdown (void){ // Get exclusive access. Lock(); // Call the base class version. BaseClass::Shutdown(); // Wake up the thread from waiting for input. SignalInput(); // Release exclusive access. Unlock();}// The thread function. Loop, calling Work(), until told to stop.voidDenoiserThread::WorkLoop (void){ // Loop and do work until told to quit. for (;;) { // Wait for an input frame. Lock(); WaitForInput(); Unlock(); // If we're out of work, stop. if (!m_bWorkLoop) break; // Do work. m_nWorkRetval = Work(); // Signal that there's output. Lock(); SignalOutput(); Unlock(); } // Remember that the work loop has stopped. m_bWorkLoop = false;}// The DenoiserThreadY class.// Default constructor.DenoiserThreadY::DenoiserThreadY(){ // No input/output buffers yet. m_pInputY = NULL; m_pOutputY = NULL;}// Destructor.DenoiserThreadY::~DenoiserThreadY(){ // Nothing to do.}// Initialize. Set up all private thread data and start the// worker thread.voidDenoiserThreadY::Initialize (void){ // Let the base class initialize itself. BaseClass::Initialize();}// Add a frame to the denoiser.voidDenoiserThreadY::AddFrame (const uint8_t *a_pInputY, uint8_t *a_pOutputY){ // Store the parameters. m_pInputY = a_pInputY; m_pOutputY = a_pOutputY; // Signal the availability of input. Lock(); SignalInput(); Unlock();}// Get the next denoised frame, if any.intDenoiserThreadY::WaitForAddFrame (void){ // Wait for output to be ready. Lock(); WaitForOutput(); Unlock(); return m_nWorkRetval;}// Stop the thread.voidDenoiserThreadY::Shutdown (void){ // Call the base class version. BaseClass::Shutdown(); // Wait for the loop to stop. int nErr = pthread_join (m_oThreadInfo, NULL); if (nErr != 0) mjpeg_error_exit1 ("DenoiserThreadRead pthread_join() " "failed: %s", strerror (nErr));}// Denoise the current frame.intDenoiserThreadY::Work (void){ return ((denoiser.interlaced != 0) ? newdenoise_interlaced_frame_intensity : newdenoise_frame_intensity) (m_pInputY, m_pOutputY);}// The DenoiserThreadCbCr class.// Default constructor.DenoiserThreadCbCr::DenoiserThreadCbCr(){ // No input/output buffers yet. m_pInputCb = NULL; m_pInputCr = NULL; m_pOutputCb = NULL; m_pOutputCr = NULL;}// Destructor.DenoiserThreadCbCr::~DenoiserThreadCbCr(){ // Nothing to do.}// Initialize. Set up all private thread data and start the// worker thread.voidDenoiserThreadCbCr::Initialize (void){ // Let the base class initialize itself. BaseClass::Initialize();}// Add a frame to the denoiser.voidDenoiserThreadCbCr::AddFrame (const uint8_t *a_pInputCb, const uint8_t *a_pInputCr, uint8_t *a_pOutputCb, uint8_t *a_pOutputCr){ // Store the parameters. m_pInputCb = a_pInputCb; m_pInputCr = a_pInputCr; m_pOutputCb = a_pOutputCb; m_pOutputCr = a_pOutputCr; // Signal the availability of input. Lock(); SignalInput(); Unlock();}// Get the next denoised frame, if any.intDenoiserThreadCbCr::WaitForAddFrame (void){ // Wait for output to be ready. Lock(); WaitForOutput(); Unlock(); return m_nWorkRetval;}// Stop the thread.voidDenoiserThreadCbCr::Shutdown (void){ // Call the base class version. BaseClass::Shutdown(); // Wait for the loop to stop. int nErr = pthread_join (m_oThreadInfo, NULL); if (nErr != 0) mjpeg_error_exit1 ("DenoiserThreadRead pthread_join() " "failed: %s", strerror (nErr));}// Denoise the current frame.intDenoiserThreadCbCr::Work (void){ return ((denoiser.interlaced != 0) ? newdenoise_interlaced_frame_color : newdenoise_frame_color) (m_pInputCb, m_pInputCr, m_pOutputCb, m_pOutputCr);}// The ReadWriteThread class.// Default constructor.ReadWriteThread::ReadWriteThread(){ // No input stream yet. m_nFD = -1; m_pStreamInfo = NULL; m_pFrameInfo = NULL; // No space for frames yet. m_apFrames = NULL; m_pValidFramesHead = m_pValidFramesTail = m_pCurrentFrame = m_pFreeFramesHead = NULL;}// Destructor.ReadWriteThread::~ReadWriteThread(){ // Free up all the frames. if (m_apFrames != NULL) { int i; for (i = 0; i < 4; ++i) { delete[] m_apFrames[i].planes[0]; delete[] m_apFrames[i].planes[1]; delete[] m_apFrames[i].planes[2]; } delete[] m_apFrames; }}// Initialize. Set up all private thread data and start the// worker thread.voidReadWriteThread::Initialize (int a_nFD, const y4m_stream_info_t *a_pStreamInfo, y4m_frame_info_t *a_pFrameInfo, int a_nWidthY, int a_nHeightY, int a_nWidthCbCr, int a_nHeightCbCr){ int i, nSizeY, nSizeCbCr; // Make sure we got stream/frame info. assert (a_pStreamInfo != NULL); assert (a_pFrameInfo != NULL); // Fill in the blanks. m_nFD = a_nFD; m_pStreamInfo = a_pStreamInfo; m_pFrameInfo = a_pFrameInfo; // Allocate space for frames. For now, hardcode the number of // frame buffers at 4. m_apFrames = new Frame[4]; nSizeY = a_nWidthY * a_nHeightY; assert (nSizeY > 0); nSizeCbCr = a_nWidthCbCr * a_nHeightCbCr; for (i = 0; i < 4; ++i) { // Allocate space for each frame. Don't allocate space for // color unless we're denoising color. m_apFrames[i].planes[0] = new uint8_t[nSizeY]; if (nSizeCbCr > 0) { m_apFrames[i].planes[1] = new uint8_t[nSizeCbCr];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -