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