MythTV  0.26-pre
cetonrecorder.cpp
Go to the documentation of this file.
00001 
00008 // MythTV includes
00009 #include "cetonstreamhandler.h"
00010 #include "cetonrecorder.h"
00011 #include "cetonchannel.h"
00012 #include "mythlogging.h"
00013 #include "tv_rec.h"
00014 
00015 #define LOC QString("CetonRec(%1): ").arg(tvrec->GetCaptureCardNum())
00016 
00017 CetonRecorder::CetonRecorder(TVRec *rec, CetonChannel *channel) :
00018     DTVRecorder(rec), _channel(channel), _stream_handler(NULL)
00019 {
00020 }
00021 
00022 bool CetonRecorder::Open(void)
00023 {
00024     if (IsOpen())
00025     {
00026         LOG(VB_GENERAL, LOG_WARNING, LOC + "Card already open");
00027         return true;
00028     }
00029 
00030     ResetForNewFile();
00031 
00032     _stream_handler = CetonStreamHandler::Get(_channel->GetDevice());
00033 
00034     LOG(VB_RECORD, LOG_INFO, LOC + "Ceton opened successfully");
00035 
00036     return true;
00037 }
00038 
00039 void CetonRecorder::Close(void)
00040 {
00041     LOG(VB_RECORD, LOG_INFO, LOC + "Close() -- begin");
00042 
00043     if (IsOpen())
00044         CetonStreamHandler::Return(_stream_handler);
00045 
00046     LOG(VB_RECORD, LOG_INFO, LOC + "Close() -- end");
00047 }
00048 
00049 void CetonRecorder::run(void)
00050 {
00051     LOG(VB_RECORD, LOG_INFO, LOC + "run -- begin");
00052 
00053     /* Create video socket. */
00054     if (!Open())
00055     {
00056         _error = "Failed to open CetonRecorder device";
00057         LOG(VB_GENERAL, LOG_ERR, LOC + _error);
00058         return;
00059     }
00060 
00061     {
00062         QMutexLocker locker(&pauseLock);
00063         request_recording = true;
00064         recording = true;
00065         recordingWait.wakeAll();
00066     }
00067 
00068     // Make sure the first things in the file are a PAT & PMT
00069     bool tmp = _wait_for_keyframe_option;
00070     _wait_for_keyframe_option = false;
00071     HandleSingleProgramPAT(_stream_data->PATSingleProgram());
00072     HandleSingleProgramPMT(_stream_data->PMTSingleProgram());
00073     _wait_for_keyframe_option = tmp;
00074 
00075     _stream_data->AddAVListener(this);
00076     _stream_data->AddWritingListener(this);
00077     _stream_handler->AddListener(_stream_data);
00078 
00079     while (IsRecordingRequested() && !IsErrored())
00080     {
00081         if (PauseAndWait())
00082             continue;
00083 
00084         if (!IsRecordingRequested())
00085             break;
00086 
00087         {   // sleep 100 milliseconds unless StopRecording() or Unpause()
00088             // is called, just to avoid running this too often.
00089             QMutexLocker locker(&pauseLock);
00090             if (!request_recording || request_pause)
00091                 continue;
00092             unpauseWait.wait(&pauseLock, 100);
00093         }
00094 
00095         if (!_input_pmt)
00096         {
00097             LOG(VB_GENERAL, LOG_WARNING, LOC +
00098                     "Recording will not commence until a PMT is set.");
00099             usleep(5000);
00100             continue;
00101         }
00102 
00103         if (!_stream_handler->IsRunning())
00104         {
00105             _error = "Stream handler died unexpectedly.";
00106             LOG(VB_GENERAL, LOG_ERR, LOC + _error);
00107         }
00108     }
00109 
00110     LOG(VB_RECORD, LOG_INFO, LOC + "run -- ending...");
00111 
00112     _stream_handler->RemoveListener(_stream_data);
00113     _stream_data->RemoveWritingListener(this);
00114     _stream_data->RemoveAVListener(this);
00115 
00116     Close();
00117 
00118     FinishRecording();
00119 
00120     QMutexLocker locker(&pauseLock);
00121     recording = false;
00122     recordingWait.wakeAll();
00123 
00124     LOG(VB_RECORD, LOG_INFO, LOC + "run -- end");
00125 }
00126 
00127 bool CetonRecorder::PauseAndWait(int timeout)
00128 {
00129     QMutexLocker locker(&pauseLock);
00130     if (request_pause)
00131     {
00132         if (!IsPaused(true))
00133         {
00134             _stream_handler->RemoveListener(_stream_data);
00135 
00136             paused = true;
00137             pauseWait.wakeAll();
00138             if (tvrec)
00139                 tvrec->RecorderPaused();
00140         }
00141 
00142         unpauseWait.wait(&pauseLock, timeout);
00143     }
00144 
00145     if (!request_pause && IsPaused(true))
00146     {
00147         paused = false;
00148         _stream_handler->AddListener(_stream_data);
00149         unpauseWait.wakeAll();
00150     }
00151 
00152     return IsPaused(true);
00153 }
00154 
00155 QString CetonRecorder::GetSIStandard(void) const
00156 {
00157     return _channel->GetSIStandard();
00158 }
00159 
00160 /* vim: set expandtab tabstop=4 shiftwidth=4: */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends