00001
00008
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
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
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 {
00088
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