|
MythTV
0.26-pre
|
00001 /* -*- Mode: c++ -*- 00002 * Class ImportRecorder 00003 * 00004 * Copyright (C) Daniel Kristjansson 2009 00005 * 00006 * This program is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation; either version 2 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software 00018 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00019 */ 00020 00021 // POSIX 00022 #ifndef USING_MINGW 00023 #include <sys/select.h> 00024 #endif 00025 #include <sys/types.h> 00026 #include <sys/stat.h> 00027 #include <fcntl.h> 00028 00029 // Qt 00030 #include <QDir> 00031 00032 // MythTV 00033 #include "mythcommflagplayer.h" 00034 #include "importrecorder.h" 00035 #include "mythdirs.h" 00036 #include "tv_rec.h" 00037 #include "mythmiscutil.h" 00038 00039 #define TVREC_CARDNUM \ 00040 ((tvrec != NULL) ? QString::number(tvrec->GetCaptureCardNum()) : "NULL") 00041 00042 #define LOC QString("ImportRec(%1:%2): ") \ 00043 .arg(TVREC_CARDNUM).arg(videodevice) 00044 00045 ImportRecorder::ImportRecorder(TVRec *rec) : 00046 DTVRecorder(rec), _import_fd(-1) 00047 { 00048 } 00049 00050 ImportRecorder::~ImportRecorder() 00051 { 00052 } 00053 00054 void ImportRecorder::SetOptionsFromProfile(RecordingProfile *profile, 00055 const QString &videodev, 00056 const QString &audiodev, 00057 const QString &vbidev) 00058 { 00059 (void)audiodev; 00060 (void)vbidev; 00061 (void)profile; 00062 00063 QString testVideoDev = videodev; 00064 00065 if (videodev.toLower().startsWith("file:")) 00066 testVideoDev = videodev.mid(5); 00067 00068 QFileInfo fi(testVideoDev); 00069 if (fi.exists() && fi.isReadable() && fi.isFile() && fi.size() > 1560) 00070 SetOption("videodevice", testVideoDev); 00071 else 00072 SetOption("videodevice", "unknown file"); 00073 00074 SetOption("tvformat", gCoreContext->GetSetting("TVFormat")); 00075 SetOption("vbiformat", gCoreContext->GetSetting("VbiFormat")); 00076 } 00077 00078 void ImportRecorder::run(void) 00079 { 00080 LOG(VB_RECORD, LOG_INFO, LOC + "run -- begin"); 00081 00082 { 00083 QMutexLocker locker(&pauseLock); 00084 request_recording = true; 00085 recording = true; 00086 recordingWait.wakeAll(); 00087 } 00088 00089 LOG(VB_RECORD, LOG_INFO, LOC + "run -- " + 00090 QString("attempting to open '%1'") 00091 .arg(curRecording->GetPathname())); 00092 00093 // retry opening the file until StopRecording() is called. 00094 while (!Open() && IsRecordingRequested() && !IsErrored()) 00095 { // sleep 250 milliseconds unless StopRecording() or Unpause() 00096 // is called, just to avoid running this loop too often. 00097 QMutexLocker locker(&pauseLock); 00098 if (request_recording) 00099 unpauseWait.wait(&pauseLock, 250); 00100 } 00101 00102 curRecording->SaveFilesize(ringBuffer->GetRealFileSize()); 00103 00104 // build seek table 00105 if (_import_fd && IsRecordingRequested() && !IsErrored()) 00106 { 00107 MythCommFlagPlayer *cfp = 00108 new MythCommFlagPlayer((PlayerFlags)(kAudioMuted | kVideoIsNull)); 00109 RingBuffer *rb = RingBuffer::Create( 00110 ringBuffer->GetFilename(), false, true, 6000); 00111 00112 PlayerContext *ctx = new PlayerContext(kImportRecorderInUseID); 00113 ctx->SetPlayingInfo(curRecording); 00114 ctx->SetRingBuffer(rb); 00115 ctx->SetPlayer(cfp); 00116 cfp->SetPlayerInfo(NULL, NULL, ctx); 00117 00118 cfp->RebuildSeekTable(false); 00119 00120 delete ctx; 00121 } 00122 00123 curRecording->SaveFilesize(ringBuffer->GetRealFileSize()); 00124 00125 // cleanup... 00126 Close(); 00127 00128 FinishRecording(); 00129 00130 QMutexLocker locker(&pauseLock); 00131 recording = false; 00132 recordingWait.wakeAll(); 00133 00134 LOG(VB_RECORD, LOG_INFO, LOC + "run -- end"); 00135 } 00136 00137 bool ImportRecorder::Open(void) 00138 { 00139 if (_import_fd >= 0) // already open 00140 return true; 00141 00142 if (!curRecording) 00143 { 00144 LOG(VB_RECORD, LOG_ERR, LOC + "no current recording!"); 00145 return false; 00146 } 00147 00148 ResetForNewFile(); 00149 00150 QString fn = curRecording->GetPathname(); 00151 00152 // Quick-and-dirty "copy" of sample prerecorded file. 00153 // Sadly, won't work on Windows. 00154 // 00155 QFile preRecorded(videodevice); 00156 QFile copy(fn); 00157 if (preRecorded.exists() && (!copy.exists() || copy.size() == 0)) 00158 { 00159 if (copy.exists()) // always created by RecorderBase? 00160 { 00161 QDir targetDir("."); // QDir::remove() needs an object 00162 targetDir.remove(fn); 00163 } 00164 00165 LOG(VB_RECORD, LOG_INFO, LOC + QString("Trying to link %1 to %2") 00166 .arg(videodevice).arg(fn)); 00167 00168 if (preRecorded.link(fn)) 00169 LOG(VB_RECORD, LOG_DEBUG, LOC + "success!"); 00170 else 00171 LOG(VB_RECORD, LOG_ERR, LOC + preRecorded.errorString()); 00172 } 00173 00174 if (fn.toLower().startsWith("myth://")) 00175 { 00176 LOG(VB_RECORD, LOG_ERR, LOC + "Malformed recording ProgramInfo."); 00177 return false; 00178 } 00179 00180 QFileInfo f(fn); 00181 if (!f.exists()) 00182 { 00183 LOG(VB_RECORD, LOG_INFO, LOC + 00184 QString("'%1' does not exist yet").arg(fn)); 00185 00186 // Slow down run open loop when debugging -v record. 00187 // This is just to make the debugging output less spammy. 00188 if (VERBOSE_LEVEL_CHECK(VB_RECORD, LOG_ANY)) 00189 usleep(250 * 1000); 00190 00191 return false; 00192 } 00193 else if (!f.isReadable()) 00194 { 00195 LOG(VB_GENERAL, LOG_ERR, LOC + 00196 QString("'%1' is not readable").arg(fn)); 00197 return false; 00198 } 00199 00200 _import_fd = open(fn.toLocal8Bit().constData(), O_RDONLY); 00201 if (_import_fd < 0) 00202 { 00203 LOG(VB_GENERAL, LOG_ERR, LOC + 00204 QString("Couldn't open '%1'").arg(fn) + ENO); 00205 } 00206 00207 return _import_fd >= 0; 00208 } 00209 00210 void ImportRecorder::Close(void) 00211 { 00212 if (_import_fd >= 0) 00213 { 00214 close(_import_fd); 00215 _import_fd = -1; 00216 } 00217 }
1.7.6.1