|
MythTV
0.26-pre
|
00001 /* 00002 * Class DVBRecorder 00003 * 00004 * Copyright (C) Daniel Thor Kristjansson 2010 00005 * 00006 * This class glues the DVBStreamHandler which handles the DVB devices 00007 * to the DTVRecorder that handles recordings in MythTV. 00008 * 00009 * This program is free software; you can redistribute it and/or modify 00010 * it under the terms of the GNU General Public License as published by 00011 * the Free Software Foundation; either version 2 of the License, or 00012 * (at your option) any later version. 00013 * 00014 * This program is distributed in the hope that it will be useful, 00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 * GNU General Public License for more details. 00018 * 00019 * You should have received a copy of the GNU General Public License 00020 * along with this program; if not, write to the Free Software 00021 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00022 */ 00023 00024 // MythTV includes 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 // Listen for time table on DVB standard streams 00092 if (_channel && (_channel->GetSIStandard() == "dvb")) 00093 _stream_data->AddListeningPID(DVB_TDT_PID); 00094 00095 // Make sure the first things in the file are a PAT & PMT 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 { // sleep 100 milliseconds unless StopRecording() or Unpause() 00112 // is called, just to avoid running this too often. 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 /* vim: set expandtab tabstop=4 shiftwidth=4: */
1.7.6.1