00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "dvbstreamhandler.h"
00026 #include "mpegstreamdata.h"
00027 #include "dvbrecorder.h"
00028 #include "dvbchannel.h"
00029 #include "tv_rec.h"
00030 #include "mythlogging.h"
00031
00032 #define LOC QString("DVBRec(%1:%2): ") \
00033 .arg(tvrec->GetCaptureCardNum()).arg(videodevice)
00034
00035 DVBRecorder::DVBRecorder(TVRec *rec, DVBChannel *channel)
00036 : DTVRecorder(rec), _channel(channel), _stream_handler(NULL)
00037 {
00038 videodevice = QString::null;
00039 }
00040
00041 bool DVBRecorder::Open(void)
00042 {
00043 if (IsOpen())
00044 {
00045 LOG(VB_GENERAL, LOG_WARNING, LOC + "Card already open");
00046 return true;
00047 }
00048
00049 if (videodevice.isEmpty())
00050 return false;
00051
00052 ResetForNewFile();
00053
00054 _stream_handler = DVBStreamHandler::Get(videodevice);
00055
00056 LOG(VB_RECORD, LOG_INFO, LOC + "Card opened successfully");
00057
00058 return true;
00059 }
00060
00061 bool DVBRecorder::IsOpen(void) const
00062 {
00063 return (NULL != _stream_handler);
00064 }
00065
00066 void DVBRecorder::Close(void)
00067 {
00068 LOG(VB_RECORD, LOG_INFO, LOC + "Close() -- begin");
00069
00070 DVBStreamHandler::Return(_stream_handler);
00071
00072 LOG(VB_RECORD, LOG_INFO, LOC + "Close() -- end");
00073 }
00074
00075 void DVBRecorder::run(void)
00076 {
00077 if (!Open())
00078 {
00079 _error = "Failed to open DVB device";
00080 LOG(VB_GENERAL, LOG_ERR, LOC + _error);
00081 return;
00082 }
00083
00084 {
00085 QMutexLocker locker(&pauseLock);
00086 request_recording = true;
00087 recording = true;
00088 recordingWait.wakeAll();
00089 }
00090
00091
00092 if (_channel && (_channel->GetSIStandard() == "dvb"))
00093 _stream_data->AddListeningPID(DVB_TDT_PID);
00094
00095
00096 bool tmp = _wait_for_keyframe_option;
00097 _wait_for_keyframe_option = false;
00098 HandleSingleProgramPAT(_stream_data->PATSingleProgram());
00099 HandleSingleProgramPMT(_stream_data->PMTSingleProgram());
00100 _wait_for_keyframe_option = tmp;
00101
00102 _stream_data->AddAVListener(this);
00103 _stream_data->AddWritingListener(this);
00104 _stream_handler->AddListener(_stream_data, false, true);
00105
00106 while (IsRecordingRequested() && !IsErrored())
00107 {
00108 if (PauseAndWait())
00109 continue;
00110
00111 {
00112
00113 QMutexLocker locker(&pauseLock);
00114 if (!request_recording || request_pause)
00115 continue;
00116 unpauseWait.wait(&pauseLock, 100);
00117 }
00118
00119 if (!_input_pmt)
00120 {
00121 LOG(VB_GENERAL, LOG_WARNING, LOC +
00122 "Recording will not commence until a PMT is set.");
00123 usleep(5000);
00124 continue;
00125 }
00126
00127 if (!_stream_handler->IsRunning())
00128 {
00129 _error = "Stream handler died unexpectedly.";
00130 LOG(VB_GENERAL, LOG_ERR, LOC + _error);
00131 }
00132 }
00133
00134 _stream_handler->RemoveListener(_stream_data);
00135 _stream_data->RemoveWritingListener(this);
00136 _stream_data->RemoveAVListener(this);
00137
00138 Close();
00139
00140 FinishRecording();
00141
00142 QMutexLocker locker(&pauseLock);
00143 recording = false;
00144 recordingWait.wakeAll();
00145 }
00146
00147 bool DVBRecorder::PauseAndWait(int timeout)
00148 {
00149 QMutexLocker locker(&pauseLock);
00150 if (request_pause)
00151 {
00152 if (!IsPaused(true))
00153 {
00154 _stream_handler->RemoveListener(_stream_data);
00155
00156 paused = true;
00157 pauseWait.wakeAll();
00158 if (tvrec)
00159 tvrec->RecorderPaused();
00160 }
00161
00162 unpauseWait.wait(&pauseLock, timeout);
00163 }
00164
00165 if (!request_pause && IsPaused(true))
00166 {
00167 paused = false;
00168 _stream_handler->AddListener(_stream_data, false, true);
00169 unpauseWait.wakeAll();
00170 }
00171
00172 return IsPaused(true);
00173 }
00174
00175 QString DVBRecorder::GetSIStandard(void) const
00176 {
00177 return _channel->GetSIStandard();
00178 }
00179
00180 void DVBRecorder::SetCAMPMT(const ProgramMapTable *pmt)
00181 {
00182 _channel->SetPMT(pmt);
00183 }
00184
00185 void DVBRecorder::UpdateCAMTimeOffset(void)
00186 {
00187 _channel->SetTimeOffset(GetStreamData()->TimeOffset());
00188 }
00189
00190