bool V4L2encRecorder::PauseAndWait(int timeout) { QMutexLocker locker(&m_pauseLock); if (m_request_pause) { if (!IsPaused(true)) { LOG(VB_RECORD, LOG_INFO, LOC + "PauseAndWait() -- pause"); StopEncoding(); m_paused = true; m_pauseWait.wakeAll(); if (m_tvrec) m_tvrec->RecorderPaused(); } } else if (IsPaused(true)) { LOG(VB_RECORD, LOG_INFO, LOC + "PauseAndWait() -- unpause"); StartEncoding(); if (m_stream_data) m_stream_data->Reset(m_stream_data->DesiredProgram()); m_paused = false; } // Always wait a little bit, unless woken up m_unpauseWait.wait(&m_pauseLock, timeout); return IsPaused(true); }
void V4L2encStreamHandler::RestartEncoding(void) { LOG(VB_RECORD, LOG_INFO, LOC + "RestartEncoding()"); StopEncoding(); StartEncoding(); }
void V4L2encRecorder::run(void) { LOG(VB_RECORD, LOG_INFO, LOC + "run() -- begin"); bool failing, failed; bool is_TS = false; if (!m_stream_data) { m_error = "MPEGStreamData pointer has not been set"; LOG(VB_GENERAL, LOG_ERR, LOC + "run() -- " + m_error); Close(); return; } m_stream_handler->Configure(); { QMutexLocker locker(&m_pauseLock); m_request_recording = true; m_recording = true; m_recordingWait.wakeAll(); } if (m_channel->HasGeneratedPAT()) { const ProgramAssociationTable *pat = m_channel->GetGeneratedPAT(); const ProgramMapTable *pmt = m_channel->GetGeneratedPMT(); m_stream_data->Reset(pat->ProgramNumber(0)); m_stream_data->HandleTables(MPEG_PAT_PID, *pat); m_stream_data->HandleTables(pat->ProgramPID(0), *pmt); LOG(VB_GENERAL, LOG_INFO, LOC + "PMT set"); // debugging } StartNewFile(); is_TS = (m_stream_handler->GetStreamType() == V4L2_MPEG_STREAM_TYPE_MPEG2_TS); if (is_TS) { LOG(VB_RECORD, LOG_INFO, LOC + "mpeg2ts"); m_stream_data->AddAVListener(this); m_stream_data->AddWritingListener(this); } else { LOG(VB_RECORD, LOG_INFO, LOC + "program stream (non mpeg2ts)"); m_stream_data->AddPSStreamListener(this); } m_stream_handler->AddListener(m_stream_data, false, true); StartEncoding(); while (IsRecordingRequested() && !IsErrored()) { if (PauseAndWait()) continue; if (is_TS && !m_input_pmt) { LOG(VB_GENERAL, LOG_WARNING, LOC + "Recording will not commence until a PMT is set."); std::this_thread::sleep_for(std::chrono::milliseconds(5)); continue; } if (!m_stream_handler->Status(failed, failing)) { if (failed) { m_error = "Stream handler died unexpectedly."; LOG(VB_GENERAL, LOG_ERR, LOC + "run() -- " + m_error); } else if (failing) { SetRecordingStatus(RecStatus::Failing, __FILE__, __LINE__); } } } LOG(VB_RECORD, LOG_INFO, LOC + "Shutting down"); StopEncoding(); m_stream_handler->RemoveListener(m_stream_data); if (m_stream_handler->GetStreamType() == V4L2_MPEG_STREAM_TYPE_MPEG2_TS) { m_stream_data->RemoveWritingListener(this); m_stream_data->RemoveAVListener(this); } else m_stream_data->RemovePSStreamListener(this); Close(); FinishRecording(); QMutexLocker locker(&m_pauseLock); m_recording = false; m_recordingWait.wakeAll(); LOG(VB_RECORD, LOG_INFO, LOC + "run() -- end"); }