📄 newdenoise.cc
字号:
m_apFrames[i].planes[2] = new uint8_t[nSizeCbCr]; } else { // This is a hack just to see if this solves the problem. m_apFrames[i].planes[1] = new uint8_t[denoiser.frame.Cw * denoiser.frame.Ch]; m_apFrames[i].planes[2] = new uint8_t[denoiser.frame.Cw * denoiser.frame.Ch]; } // Put each new frame into the free list. m_apFrames[i].next = m_pFreeFramesHead; m_pFreeFramesHead = &(m_apFrames[i]); } // Let the base class initialize. The thread will start. BaseClass::Initialize();}// Remove the first valid frame from the list and return it.ReadWriteThread::Frame *ReadWriteThread::GetFirstValidFrame (void){ Frame *pFrame; // The frame we get. // Make sure there's a valid frame. assert (m_pValidFramesHead != NULL); // Make the first valid frame the current frame. pFrame = m_pValidFramesHead; // Remove that frame from the valid-frame list. m_pValidFramesHead = m_pValidFramesHead->next; if (m_pValidFramesHead == NULL) m_pValidFramesTail = NULL; // Return the next valid frame. return pFrame;}// Add the given frame to the end of the valid-frame list.voidReadWriteThread::AddFrameToValidList (Frame *a_pFrame){ // Make sure they gave us a frame to add. assert (a_pFrame != NULL); // This will be at the end of the list. a_pFrame->next = NULL; // If the valid-frame list is empty, set it up. if (m_pValidFramesHead == NULL) { m_pValidFramesHead = m_pValidFramesTail = a_pFrame; } // Otherwise, append this frame to the end of the list. else { assert (m_pValidFramesTail->next == NULL); m_pValidFramesTail->next = a_pFrame; m_pValidFramesTail = m_pValidFramesTail->next; }}// Remove a frame from the free-frames list and return it.ReadWriteThread::Frame *ReadWriteThread::GetFreeFrame (void){ Frame *pFrame; // The frame we get. // Make sure there's a free frame. assert (m_pFreeFramesHead != NULL); // Make the first free frame the current frame. pFrame = m_pFreeFramesHead; // Remove that frame from the free-frames list. m_pFreeFramesHead = m_pFreeFramesHead->next; // Return the free frame. return pFrame;}// Add the given frame to the free-frames list.voidReadWriteThread::AddFrameToFreeList (Frame *a_pFrame){ // Make sure they gave us a frame. assert (a_pFrame != NULL); // Add this frame to the list. a_pFrame->next = m_pFreeFramesHead; m_pFreeFramesHead = a_pFrame;}// Remove the first valid frame, and make it the current frame.voidReadWriteThread::MoveValidFrameToCurrent (void){ // Make sure there's a valid frame. assert (m_pValidFramesHead != NULL); // Make sure there's no current frame. assert (m_pCurrentFrame == NULL); // Make the first valid frame the current frame. m_pCurrentFrame = GetFirstValidFrame();}// Move the current frame to the end of the valid-frame list.voidReadWriteThread::MoveCurrentFrameToValidList (void){ // Make sure there's a current frame. assert (m_pCurrentFrame != NULL); // Add the frame to the end of the valid-frame list. AddFrameToValidList (m_pCurrentFrame); // Now there's no current frame. m_pCurrentFrame = NULL;}// Remove a frame from the free list, and make it the current frame.voidReadWriteThread::MoveFreeFrameToCurrent (void){ // Make sure there's a free frame. assert (m_pFreeFramesHead != NULL); // Make sure there's no current frame. assert (m_pCurrentFrame == NULL); // Make the first free frame the current frame. m_pCurrentFrame = GetFreeFrame();}// Move the current frame to the free-frame list.voidReadWriteThread::MoveCurrentFrameToFreeList (void){ // Make sure there's a current frame. assert (m_pCurrentFrame != NULL); // Add this frame to the list. AddFrameToFreeList (m_pCurrentFrame); // Now there's no current frame. m_pCurrentFrame = NULL;}// The DenoiserThreadRead class.// Default constructor.DenoiserThreadRead::DenoiserThreadRead(){ // Nothing additional to do.}// Destructor.DenoiserThreadRead::~DenoiserThreadRead(){ // Nothing additional to do.}// Read a frame from input. a_apPlanes[] gets backpatched// with pointers to valid frame data, and they are valid until// the next call to ReadFrame().// Returns Y4M_OK if it succeeds, Y4M_ERR_EOF at the end of// the stream. (Returns other errors too.)intDenoiserThreadRead::ReadFrame (uint8_t **a_apPlanes){ // Get exclusive access. Lock(); // Any previous current frame can be reused now. if (m_pCurrentFrame != NULL) { // Now recycle the previous current frame. MoveCurrentFrameToFreeList(); // If there were no free frames before, then signal that input // can continue. if (m_bWaitingForInput) SignalInput(); } // If there are no valid frames, and the thread is still reading // frames, then wait for some valid output. if (m_pValidFramesHead == NULL && m_bWorkLoop) WaitForOutput(); // Make the next valid frame the current frame. If there are no // valid frames at this point, then we're at the end of the stream. if (m_pValidFramesHead != NULL) MoveValidFrameToCurrent(); // Release exclusive access. Unlock(); // Backpatch the frame info. if (m_pCurrentFrame != NULL) { a_apPlanes[0] = m_pCurrentFrame->planes[0]; a_apPlanes[1] = m_pCurrentFrame->planes[1]; a_apPlanes[2] = m_pCurrentFrame->planes[2]; return Y4M_OK; } // Make sure we got an error at the end of stream (hopefully // Y4M_ERR_EOF). assert (m_nWorkRetval != Y4M_OK); // Return whatever error we got at the end of the stream. return m_nWorkRetval;}// Stop the thread.voidDenoiserThreadRead::Shutdown (void){ // Get exclusive access. Lock(); // Call the base class version. BaseClass::Shutdown(); // Release exclusive access. Unlock(); // 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));}// Read frames from the raw-video stream.intDenoiserThreadRead::Work (void){ Frame *pFrame; // Space for reading a frame into memory. int nErr; // An error that may occur. // Get exclusive access. Lock(); // If there are no free buffers, wait for some. if (m_pFreeFramesHead == NULL) WaitForInput(); // Make sure there's a free buffer. assert (m_pFreeFramesHead != NULL); // Get the free buffer. pFrame = GetFreeFrame(); // Release exclusive access. Unlock(); // Read the next frame into the buffer. nErr = y4m_read_frame (m_nFD, m_pStreamInfo, m_pFrameInfo, pFrame->planes); // Get exclusive access. Lock(); // Did we successfully read a frame? if (nErr == Y4M_OK) { // Yes. Put the frame into the valid-frames list. AddFrameToValidList (pFrame); // If there are no other valid frames, then signal // that there's some output now. if (m_bWaitingForOutput) SignalOutput(); } else { // No. Put the frame back into the free-frames list. AddFrameToFreeList (pFrame); } // Release exclusive access. Unlock(); // Return whether we successfully read a frame. return nErr;}// The DenoiserThreadWrite class.// Default constructor.DenoiserThreadWrite::DenoiserThreadWrite(){ // Nothing additional to do.}// Destructor.DenoiserThreadWrite::~DenoiserThreadWrite(){ // Nothing additional to do.}// Get space for a frame to write to output. a_apPlanes[] gets// backpatched with pointers to valid frame data.// Returns Y4M_OK if it succeeds, something else if it fails.intDenoiserThreadWrite::GetSpaceToWriteFrame (uint8_t **a_apPlanes){ int nErr; // An error that may occur. // No errors yet. nErr = Y4M_OK; // Get exclusive access. Lock(); // Make sure there's no current frame. assert (m_pCurrentFrame == NULL); // If there are no free frames, wait for one. if (m_pFreeFramesHead == NULL) WaitForInput(); // If there are still no free frames, something is wrong. // Return that to our caller. if (m_pFreeFramesHead == NULL) { assert (m_nWorkRetval != Y4M_OK); nErr = m_nWorkRetval; } // Otherwise, make a free frame the current frame. else { MoveFreeFrameToCurrent(); // Backpatch the frame info, for all the info we're denoising. a_apPlanes[0] = m_pCurrentFrame->planes[0]; a_apPlanes[1] = m_pCurrentFrame->planes[1]; a_apPlanes[2] = m_pCurrentFrame->planes[2]; } // Release exclusive access. Unlock(); // Let our caller know what happened. return nErr;}// Write a frame to output. The a_apPlanes[] previously set up by// GetSpaceToWriteFrame() must be filled with video data by the client.voidDenoiserThreadWrite::WriteFrame (void){ // Get exclusive access. Lock(); // Make sure there's a current frame. assert (m_pCurrentFrame != NULL); // Move it to the end of the valid-frames list. MoveCurrentFrameToValidList(); // If that's the only valid frame, then signal that we're ready // for output again. if (m_bWaitingForOutput) SignalOutput(); // Release exclusive access. Unlock();}// Stop the thread.voidDenoiserThreadWrite::Shutdown (void){ // Get exclusive access. Lock(); // Call the base class version. BaseClass::Shutdown(); // Wake up the thread from waiting for output. SignalOutput(); // Release exclusive access. Unlock(); // 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));}// Write frames to the raw-video stream.intDenoiserThreadWrite::Work (void){ int nErr; // An error that may occur. Frame *pFrame; // A frame that gets written out. // No errors yet. nErr = Y4M_OK; // No frame yet. pFrame = NULL; // Get exclusive access. Lock(); // Are there no frames to write out? if (m_pValidFramesHead == NULL) { // If we've been asked to quit, do so. if (!m_bWorkLoop) nErr = Y4M_ERR_EOF; // Otherwise, wait for some frames to write out. else WaitForOutput(); } // If there are still no frames to write out, we're done. if (nErr == Y4M_OK && m_pValidFramesHead == NULL) nErr = Y4M_ERR_EOF; // Otherwise, fetch a frame to write to output. if (nErr == Y4M_OK) pFrame = GetFirstValidFrame(); // Release exclusive access. Unlock(); // If there's a frame to write to output, do so. if (nErr == Y4M_OK && pFrame != NULL) { // Write the frame to output. nErr = y4m_write_frame (m_nFD, m_pStreamInfo, m_pFrameInfo, pFrame->planes); // Whether or not that succeeds, put the frame into the // free-frames list. Lock(); AddFrameToFreeList (pFrame); if (m_bWaitingForInput) SignalInput(); Unlock(); } // Let our caller know what happened. return nErr;}// The thread function. Loop, calling Work(), until we're out of input.voidDenoiserThreadWrite::WorkLoop (void){ // Loop and do work until told to quit. for (;;) { // 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;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -