MythTV  master
v2capture.cpp
Go to the documentation of this file.
1 // Program Name: capture.cpp
3 // Created : Sep. 21, 2011
4 //
5 // Copyright (c) 2011 Robert McNamara <rmcnamara@mythtv.org>
6 //
7 // This program is free software; you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License as published by
9 // the Free Software Foundation; either version 2 of the License, or
10 // (at your option) any later version.
11 //
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software
19 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 //
21 // You should have received a copy of the GNU General Public License
22 // along with this program. If not, see <http://www.gnu.org/licenses/>.
23 //
25 
26 // Qt
27 #include <QList>
28 #include <QFile>
29 #include <QMutex>
30 
31 // MythTV
33 #include "libmythbase/compat.h"
36 #include "libmythbase/mythdate.h"
37 #include "libmythbase/mythversion.h"
38 #include "libmythtv/cardutil.h"
40 
41 // MythBackend
42 #include "v2capture.h"
43 #include "v2serviceUtil.h"
44 
45 // This will be initialised in a thread safe manner on first use
47  (CAPTURE_HANDLE, V2Capture::staticMetaObject, &V2Capture::RegisterCustomTypes))
48 
50 {
51  qRegisterMetaType<V2CaptureCardList*>("V2CaptureCardList");
52  qRegisterMetaType<V2CaptureCard*>("V2CaptureCard");
53  qRegisterMetaType<V2CardTypeList*>("V2CardTypeList");
54  qRegisterMetaType<V2CardType*>("V2CardType");
55  qRegisterMetaType<V2CaptureDeviceList*>("V2CaptureDeviceList");
56  qRegisterMetaType<V2CaptureDevice*>("V2CaptureDevice");
57  qRegisterMetaType<V2DiseqcTree*>("V2DiseqcTree");
58  qRegisterMetaType<V2DiseqcTreeList*>("V2DiseqcTreeList");
59  qRegisterMetaType<V2InputGroupList*>("V2InputGroupList");
60  qRegisterMetaType<V2InputGroup*>("V2InputGroup");
61  qRegisterMetaType<V2DiseqcConfig*>("V2DiseqcConfig");
62  qRegisterMetaType<V2DiseqcConfigList*>("V2DiseqcConfigList");
63  qRegisterMetaType<V2RecProfParam*>("V2RecProfParam");
64  qRegisterMetaType<V2RecProfile*>("V2RecProfile");
65  qRegisterMetaType<V2RecProfileGroup*>("V2RecProfileGroup");
66  qRegisterMetaType<V2RecProfileGroupList*>("V2RecProfileGroupList");
67 }
68 
70  : MythHTTPService(s_service)
71 {
72 }
73 
75 //
77 
79  const QString &CardType )
80 {
82 
83  if (!query.isConnected())
84  throw( QString("Database not open while trying to list "
85  "V2Capture Cards."));
86 
87  QString str = "SELECT cardid, parentid, videodevice, audiodevice, vbidevice, "
88  "cardtype, defaultinput, audioratelimit, hostname, "
89  "dvb_swfilter, dvb_sat_type, dvb_wait_for_seqstart, "
90  "skipbtaudio, dvb_on_demand, dvb_diseqc_type, "
91  "firewire_speed, firewire_model, firewire_connection, "
92  "signal_timeout, channel_timeout, dvb_tuning_delay, "
93  "contrast, brightness, colour, hue, diseqcid, dvb_eitscan, "
94  "inputname, sourceid, externalcommand, changer_device, "
95  "changer_model, tunechan, startchan, displayname, "
96  "dishnet_eit, recpriority, quicktune, schedorder, "
97  "livetvorder, reclimit, schedgroup "
98  "from capturecard";
99 
100  if (!sHostName.isEmpty())
101  str += " WHERE hostname = :HOSTNAME";
102  else if (!CardType.isEmpty())
103  str += " WHERE cardtype = :CARDTYPE";
104 
105  if (!sHostName.isEmpty() && !CardType.isEmpty())
106  str += " AND cardtype = :CARDTYPE";
107 
108  query.prepare(str);
109 
110  if (!sHostName.isEmpty())
111  query.bindValue(":HOSTNAME", sHostName);
112  if (!CardType.isEmpty())
113  query.bindValue(":CARDTYPE", CardType);
114 
115  if (!query.exec())
116  {
117  MythDB::DBError("MythAPI::GetCaptureCardList()", query);
118  throw( QString( "Database Error executing query." ));
119  }
120 
121  // ----------------------------------------------------------------------
122  // return the results of the query
123  // ----------------------------------------------------------------------
124 
125  auto* pList = new V2CaptureCardList();
126 
127  while (query.next())
128  {
129 
130  V2CaptureCard *pCaptureCard = pList->AddNewCaptureCard();
131 
132  pCaptureCard->setCardId ( query.value(0).toInt() );
133  pCaptureCard->setParentId ( query.value(1).toInt() );
134  pCaptureCard->setVideoDevice ( query.value(2).toString() );
135  pCaptureCard->setAudioDevice ( query.value(3).toString() );
136  pCaptureCard->setVBIDevice ( query.value(4).toString() );
137  pCaptureCard->setCardType ( query.value(5).toString() );
138  pCaptureCard->setDefaultInput ( query.value(6).toString() );
139  pCaptureCard->setAudioRateLimit ( query.value(7).toUInt() );
140  pCaptureCard->setHostName ( query.value(8).toString() );
141  pCaptureCard->setDVBSWFilter ( query.value(9).toUInt() );
142  pCaptureCard->setDVBSatType ( query.value(10).toUInt() );
143  pCaptureCard->setDVBWaitForSeqStart( query.value(11).toBool() );
144  pCaptureCard->setSkipBTAudio ( query.value(12).toBool() );
145  pCaptureCard->setDVBOnDemand ( query.value(13).toBool() );
146  pCaptureCard->setDVBDiSEqCType ( query.value(14).toUInt() );
147  pCaptureCard->setFirewireSpeed ( query.value(15).toUInt() );
148  pCaptureCard->setFirewireModel ( query.value(16).toString() );
149  pCaptureCard->setFirewireConnection( query.value(17).toUInt() );
150  pCaptureCard->setSignalTimeout ( query.value(18).toUInt() );
151  pCaptureCard->setChannelTimeout ( query.value(19).toUInt() );
152  pCaptureCard->setDVBTuningDelay ( query.value(20).toUInt() );
153  pCaptureCard->setContrast ( query.value(21).toUInt() );
154  pCaptureCard->setBrightness ( query.value(22).toUInt() );
155  pCaptureCard->setColour ( query.value(23).toUInt() );
156  pCaptureCard->setHue ( query.value(24).toUInt() );
157  pCaptureCard->setDiSEqCId ( query.value(25).toUInt() );
158  pCaptureCard->setDVBEITScan ( query.value(26).toBool() );
159  pCaptureCard->setInputName ( query.value(27).toString() );
160  pCaptureCard->setSourceId ( query.value(28).toInt() );
161  pCaptureCard->setExternalCommand ( query.value(29).toString() );
162  pCaptureCard->setChangerDevice ( query.value(30).toString() );
163  pCaptureCard->setChangerModel ( query.value(31).toString() );
164  pCaptureCard->setTuneChannel ( query.value(32).toString() );
165  pCaptureCard->setStartChannel ( query.value(33).toString() );
166  pCaptureCard->setDisplayName ( query.value(34).toString() );
167  pCaptureCard->setDishnetEit ( query.value(35).toBool() );
168  pCaptureCard->setRecPriority ( query.value(36).toInt() );
169  pCaptureCard->setQuickTune ( query.value(37).toBool() );
170  pCaptureCard->setSchedOrder ( query.value(38).toUInt() );
171  pCaptureCard->setLiveTVOrder ( query.value(39).toUInt() );
172  pCaptureCard->setRecLimit ( query.value(40).toUInt() );
173  pCaptureCard->setSchedGroup ( query.value(41).toBool() );
174  }
175 
176  return pList;
177 }
178 
180 //
182 
184 {
185  if ( nCardId < 1 )
186  throw( QString( "The Card ID is invalid."));
187 
188  MSqlQuery query(MSqlQuery::InitCon());
189 
190  if (!query.isConnected())
191  throw( QString("Database not open while trying to list "
192  "V2Capture Cards."));
193 
194  QString str = "SELECT cardid, parentid, videodevice, audiodevice, vbidevice, "
195  "cardtype, defaultinput, audioratelimit, hostname, "
196  "dvb_swfilter, dvb_sat_type, dvb_wait_for_seqstart, "
197  "skipbtaudio, dvb_on_demand, dvb_diseqc_type, "
198  "firewire_speed, firewire_model, firewire_connection, "
199  "signal_timeout, channel_timeout, dvb_tuning_delay, "
200  "contrast, brightness, colour, hue, diseqcid, dvb_eitscan, "
201  "inputname, sourceid, externalcommand, changer_device, "
202  "changer_model, tunechan, startchan, displayname, "
203  "dishnet_eit, recpriority, quicktune, schedorder, "
204  "livetvorder, reclimit, schedgroup "
205  "from capturecard WHERE cardid = :CARDID";
206 
207  query.prepare(str);
208  query.bindValue(":CARDID", nCardId);
209 
210  if (!query.exec())
211  {
212  MythDB::DBError("MythAPI::GetCaptureCard()", query);
213  throw( QString( "Database Error executing query." ));
214  }
215 
216  auto* pCaptureCard = new V2CaptureCard();
217 
218  if (query.next())
219  {
220  pCaptureCard->setCardId ( query.value(0).toInt() );
221  pCaptureCard->setParentId ( query.value(1).toInt() );
222  pCaptureCard->setVideoDevice ( query.value(2).toString() );
223  pCaptureCard->setAudioDevice ( query.value(3).toString() );
224  pCaptureCard->setVBIDevice ( query.value(4).toString() );
225  pCaptureCard->setCardType ( query.value(5).toString() );
226  pCaptureCard->setDefaultInput ( query.value(6).toString() );
227  pCaptureCard->setAudioRateLimit ( query.value(7).toUInt() );
228  pCaptureCard->setHostName ( query.value(8).toString() );
229  pCaptureCard->setDVBSWFilter ( query.value(9).toUInt() );
230  pCaptureCard->setDVBSatType ( query.value(10).toUInt() );
231  pCaptureCard->setDVBWaitForSeqStart( query.value(11).toBool() );
232  pCaptureCard->setSkipBTAudio ( query.value(12).toBool() );
233  pCaptureCard->setDVBOnDemand ( query.value(13).toBool() );
234  pCaptureCard->setDVBDiSEqCType ( query.value(14).toUInt() );
235  pCaptureCard->setFirewireSpeed ( query.value(15).toUInt() );
236  pCaptureCard->setFirewireModel ( query.value(16).toString() );
237  pCaptureCard->setFirewireConnection( query.value(17).toUInt() );
238  pCaptureCard->setSignalTimeout ( query.value(18).toUInt() );
239  pCaptureCard->setChannelTimeout ( query.value(19).toUInt() );
240  pCaptureCard->setDVBTuningDelay ( query.value(20).toUInt() );
241  pCaptureCard->setContrast ( query.value(21).toUInt() );
242  pCaptureCard->setBrightness ( query.value(22).toUInt() );
243  pCaptureCard->setColour ( query.value(23).toUInt() );
244  pCaptureCard->setHue ( query.value(24).toUInt() );
245  pCaptureCard->setDiSEqCId ( query.value(25).toUInt() );
246  pCaptureCard->setDVBEITScan ( query.value(26).toBool() );
247  pCaptureCard->setInputName ( query.value(27).toString() );
248  pCaptureCard->setSourceId ( query.value(28).toInt() );
249  pCaptureCard->setExternalCommand ( query.value(29).toString() );
250  pCaptureCard->setChangerDevice ( query.value(30).toString() );
251  pCaptureCard->setChangerModel ( query.value(31).toString() );
252  pCaptureCard->setTuneChannel ( query.value(32).toString() );
253  pCaptureCard->setStartChannel ( query.value(33).toString() );
254  pCaptureCard->setDisplayName ( query.value(34).toString() );
255  pCaptureCard->setDishnetEit ( query.value(35).toBool() );
256  pCaptureCard->setRecPriority ( query.value(36).toInt() );
257  pCaptureCard->setQuickTune ( query.value(37).toBool() );
258  pCaptureCard->setSchedOrder ( query.value(38).toUInt() );
259  pCaptureCard->setLiveTVOrder ( query.value(39).toUInt() );
260  pCaptureCard->setRecLimit ( query.value(40).toUInt() );
261  pCaptureCard->setSchedGroup ( query.value(41).toBool() );
262  }
263 
264  return pCaptureCard;
265 }
266 
268 //
270 
272 {
273  return CardUtil::DeleteAllInputs();
274 }
275 
276 bool V2Capture::RemoveCaptureCard( int nCardId )
277 {
278  if ( nCardId < 1 )
279  throw( QString( "The Card ID is invalid."));
280 
281  bool bResult = CardUtil::DeleteInput(nCardId);
282 
283  return bResult;
284 }
285 
287 //
289 
290 int V2Capture::AddCaptureCard ( const QString &sVideoDevice,
291  const QString &sAudioDevice,
292  const QString &sVBIDevice,
293  const QString &CardType,
294  const uint nAudioRateLimit,
295  const QString &sHostName,
296  const uint nDVBSWFilter,
297  const uint nDVBSatType,
298  bool bDVBWaitForSeqStart,
299  bool bSkipBTAudio,
300  bool bDVBOnDemand,
301  const uint nDVBDiSEqCType,
302  const uint nFirewireSpeed,
303  const QString &sFirewireModel,
304  const uint nFirewireConnection,
305  const uint nSignalTimeout,
306  const uint nChannelTimeout,
307  const uint nDVBTuningDelay,
308  const uint nContrast,
309  const uint nBrightness,
310  const uint nColour,
311  const uint nHue,
312  const uint nDiSEqCId,
313  bool bDVBEITScan)
314 {
315  if ( sVideoDevice.isEmpty() || CardType.isEmpty() || sHostName.isEmpty() )
316  throw( QString( "This API requires at least a video device node, a card type, "
317  "and a hostname." ));
318 
319  int nResult = CardUtil::CreateCaptureCard(sVideoDevice, sAudioDevice,
320  sVBIDevice, CardType, nAudioRateLimit,
321  sHostName, nDVBSWFilter, nDVBSatType, bDVBWaitForSeqStart,
322  bSkipBTAudio, bDVBOnDemand, nDVBDiSEqCType, nFirewireSpeed,
323  sFirewireModel, nFirewireConnection, std::chrono::milliseconds(nSignalTimeout),
324  std::chrono::milliseconds(nChannelTimeout), nDVBTuningDelay, nContrast, nBrightness,
325  nColour, nHue, nDiSEqCId, bDVBEITScan);
326 
327  if ( nResult < 1 )
328  throw( QString( "Unable to create capture device." ));
329 
330  return nResult;
331 }
332 
333 bool V2Capture::UpdateCaptureCard ( int nCardId,
334  const QString &sSetting,
335  const QString &sValue )
336 {
337  if ( nCardId < 1 || sSetting.isEmpty() || sValue.isEmpty() )
338  throw( QString( "Card ID, Setting Name, and Value are required." ));
339 
340  return set_on_input(sSetting, nCardId, sValue);
341 }
342 
343 // Card Inputs
344 
345 bool V2Capture::RemoveCardInput( int nCardInputId )
346 {
347  if ( nCardInputId < 1 )
348  throw( QString( "The Input ID is invalid."));
349 
350  bool bResult = CardUtil::DeleteInput(nCardInputId);
351 
352  return bResult;
353 }
354 
355 int V2Capture::AddCardInput ( const uint nCardId,
356  const uint nSourceId,
357  const QString &sInputName,
358  const QString &sExternalCommand,
359  const QString &sChangerDevice,
360  const QString &sChangerModel,
361  const QString &sHostName,
362  const QString &sTuneChan,
363  const QString &sStartChan,
364  const QString &sDisplayName,
365  bool bDishnetEIT,
366  const uint nRecPriority,
367  const uint nQuicktune,
368  const uint nSchedOrder,
369  const uint nLiveTVOrder)
370 {
371  if ( nCardId < 1 || nSourceId < 1 ||
372  sInputName.isEmpty() || sInputName == "None" )
373  throw( QString( "This API requires at least a card ID, a source ID, "
374  "and an input name." ));
375 
376  if ( !CardUtil::IsUniqueDisplayName(sDisplayName, 0 ))
377  throw QString(" DisplayName is not set or is not unique.");
378 
379  int nResult = CardUtil::CreateCardInput(nCardId, nSourceId, sInputName,
380  sExternalCommand, sChangerDevice, sChangerModel,
381  sHostName, sTuneChan, sStartChan, sDisplayName,
382  bDishnetEIT, nRecPriority, nQuicktune, nSchedOrder,
383  nLiveTVOrder);
384 
385  return nResult;
386 }
387 
388 bool V2Capture::UpdateCardInput ( int nCardInputId,
389  const QString &sSetting,
390  const QString &sValue )
391 {
392  if ( nCardInputId < 1 || sSetting.isEmpty() || sValue.isEmpty() )
393  throw( QString( "Input ID, Setting Name, and Value are required." ));
394 
395  return set_on_input(sSetting, nCardInputId, sValue);
396 }
397 
399 {
400  auto* pCardTypeList = new V2CardTypeList();
401 
402 #ifdef USING_DVB
403  pCardTypeList->AddCardType(
404  QObject::tr("DVB-T/S/C, ATSC or ISDB-T tuner card"), "DVB");
405 #endif // USING_DVB
406 
407 #ifdef USING_V4L2
408  pCardTypeList->AddCardType(
409  QObject::tr("V4L2 encoder"), "V4L2ENC");
410  pCardTypeList->AddCardType(
411  QObject::tr("HD-PVR H.264 encoder"), "HDPVR");
412 #endif // USING_V4L2
413 
414 #ifdef USING_HDHOMERUN
415  pCardTypeList->AddCardType(
416  QObject::tr("HDHomeRun networked tuner"), "HDHOMERUN");
417 #endif // USING_HDHOMERUN
418 
419 #ifdef USING_SATIP
420  pCardTypeList->AddCardType(
421  QObject::tr("Sat>IP networked tuner"), "SATIP");
422 #endif // USING_SATIP
423 
424 #ifdef USING_VBOX
425  pCardTypeList->AddCardType(
426  QObject::tr("V@Box TV Gateway networked tuner"), "VBOX");
427 #endif // USING_VBOX
428 
429 #ifdef USING_FIREWIRE
430  pCardTypeList->AddCardType(
431  QObject::tr("FireWire cable box"), "FIREWIRE");
432 #endif // USING_FIREWIRE
433 
434 #ifdef USING_CETON
435  pCardTypeList->AddCardType(
436  QObject::tr("Ceton Cablecard tuner"), "CETON");
437 #endif // USING_CETON
438 
439 #ifdef USING_IPTV
440  pCardTypeList->AddCardType(QObject::tr("IPTV recorder"), "FREEBOX");
441 #endif // USING_IPTV
442 
443 #ifdef USING_V4L2
444  pCardTypeList->AddCardType(
445  QObject::tr("Analog to MPEG-2 encoder card (PVR-150/250/350, etc)"), "MPEG");
446  pCardTypeList->AddCardType(
447  QObject::tr("Analog to MJPEG encoder card (Matrox G200, DC10, etc)"), "MJPEG");
448  pCardTypeList->AddCardType(
449  QObject::tr("Analog to MPEG-4 encoder (Plextor ConvertX USB, etc)"),
450  "GO7007");
451  pCardTypeList->AddCardType(
452  QObject::tr("Analog capture card"), "V4L");
453 #endif // USING_V4L2
454 
455 #ifdef USING_ASI
456  pCardTypeList->AddCardType(QObject::tr("DVEO ASI recorder"), "ASI");
457 #endif
458 
459  pCardTypeList->AddCardType(QObject::tr("Import test recorder"), "IMPORT");
460  pCardTypeList->AddCardType(QObject::tr("Demo test recorder"), "DEMO");
461 #if !defined( USING_MINGW ) && !defined( _MSC_VER )
462  pCardTypeList->AddCardType(QObject::tr("External (black box) recorder"),
463  "EXTERNAL");
464 #endif
465  return pCardTypeList;
466 }
467 
469 {
470  auto* pInputGroupList = new V2InputGroupList();
471 
472  MSqlQuery query(MSqlQuery::InitCon());
473 
474  if (!query.isConnected())
475  throw( QString("Database not open while trying to list "
476  "Input Groups."));
477 
478  QString q = "SELECT cardinputid,inputgroupid,inputgroupname "
479  "FROM inputgroup WHERE inputgroupname LIKE 'user:%' "
480  "ORDER BY inputgroupid, cardinputid";
481  query.prepare(q);
482 
483  if (!query.exec())
484  {
485  MythDB::DBError("GetUserInputGroupList", query);
486  return pInputGroupList;
487  }
488 
489  while (query.next())
490  {
491  pInputGroupList->AddInputGroup(query.value(0).toUInt(),
492  query.value(1).toUInt(),
493  query.value(2).toString());
494  }
495 
496  return pInputGroupList;
497 }
498 
499 int V2Capture::AddUserInputGroup(const QString & Name)
500 {
501  if (Name.isEmpty())
502  throw( QString( "Input group name cannot be empty." ) );
503 
504  QString new_name = QString("user:") + Name;
505 
506  uint inputgroupid = CardUtil::CreateInputGroup(new_name);
507 
508  if (inputgroupid == 0)
509  {
510  throw( QString( "Failed to add or retrieve %1" ).arg(new_name) );
511  }
512 
513  return inputgroupid;
514 }
515 
516 bool V2Capture::LinkInputGroup(const uint InputId,
517  const uint InputGroupId)
518 {
519  if (!CardUtil::LinkInputGroup(InputId, InputGroupId))
520  throw( QString ( "Failed to link input %1 to group %2" )
521  .arg(InputId).arg(InputGroupId));
522  return true;
523 }
524 
525 
527  const uint InputGroupId)
528 {
529  if (!CardUtil::UnlinkInputGroup(InputId, InputGroupId))
530  throw( QString ( "Failed to unlink input %1 from group %2" )
531  .arg(InputId).arg(InputGroupId));
532  return true;
533 }
534 
536  const uint Max )
537 {
538  return CardUtil::InputSetMaxRecordings(InputId, Max);
539 }
540 
541 
542 #ifdef USING_DVB
543 static QString remove_chaff(const QString &name)
544 {
545  // Trim off some of the chaff.
546  QString short_name = name;
547  if (short_name.startsWith("LG Electronics"))
548  short_name = short_name.right(short_name.length() - 15);
549  if (short_name.startsWith("Oren"))
550  short_name = short_name.right(short_name.length() - 5);
551  if (short_name.startsWith("Nextwave"))
552  short_name = short_name.right(short_name.length() - 9);
553  if (short_name.startsWith("frontend", Qt::CaseInsensitive))
554  short_name = short_name.left(short_name.length() - 9);
555  if (short_name.endsWith("VSB/QAM"))
556  short_name = short_name.left(short_name.length() - 8);
557  if (short_name.endsWith("VSB"))
558  short_name = short_name.left(short_name.length() - 4);
559  if (short_name.endsWith("DVB-T"))
560  short_name = short_name.left(short_name.length() - 6);
561 
562  // It would be infinitely better if DVB allowed us to query
563  // the vendor ID. But instead we have to guess based on the
564  // demodulator name. This means cards like the Air2PC HD5000
565  // and DViCO Fusion HDTV cards are not identified correctly.
566  short_name = short_name.simplified();
567  if (short_name.startsWith("or51211", Qt::CaseInsensitive))
568  short_name = "pcHDTV HD-2000";
569  else if (short_name.startsWith("or51132", Qt::CaseInsensitive))
570  short_name = "pcHDTV HD-3000";
571  else if (short_name.startsWith("bcm3510", Qt::CaseInsensitive))
572  short_name = "Air2PC v1";
573  else if (short_name.startsWith("nxt2002", Qt::CaseInsensitive) ||
574  short_name.startsWith("nxt200x", Qt::CaseInsensitive))
575  short_name = "Air2PC v2";
576  else if (short_name.startsWith("lgdt3302", Qt::CaseInsensitive))
577  short_name = "DViCO HDTV3";
578  else if (short_name.startsWith("lgdt3303", Qt::CaseInsensitive))
579  short_name = "DViCO v2 or Air2PC v3 or pcHDTV HD-5500";
580 
581  return short_name;
582 }
583 #endif // USING_DVB
584 
585 
586 
588 {
589 
590  if (CardType == "V4L2ENC") {
591  QRegularExpression drv { "^(?!ivtv|hdpvr|(saa7164(.*))).*$" };
592  return getV4l2List(drv, CardType);
593  }
594  // Get devices from system
595  QStringList sdevs = CardUtil::ProbeVideoDevices(CardType);
596 
597  auto* pList = new V2CaptureDeviceList();
598  for (const auto & it : qAsConst(sdevs))
599  {
600  auto* pDev = pList->AddCaptureDevice();
601  pDev->setCardType (CardType);
602  pDev->setVideoDevice (it);
603 #ifdef USING_DVB
604  // From DVBConfigurationGroup::probeCard in Videosource.cpp
605  if (CardType == "DVB")
606  {
607  QString frontendName = CardUtil::ProbeDVBFrontendName(it);
608  pDev->setInputNames( CardUtil::ProbeDeliverySystems (it));
609  pDev->setDefaultInputName( CardUtil::ProbeDefaultDeliverySystem (it));
610  QString subType = CardUtil::ProbeDVBType(it);
611  int signalTimeout = 0;
612  int channelTimeout = 0;
613  int tuningDelay = 0;
614  QString err_open = tr("Could not open card %1").arg(it);
615  QString err_other = tr("Could not get card info for card %1").arg(it);
616 
617  switch (CardUtil::toInputType(subType))
618  {
620  frontendName = err_open;
621  subType = strerror(errno);
622  break;
624  frontendName = err_other;
625  subType = "Unknown error";
626  break;
628  frontendName = err_other;
629  subType = strerror(errno);
630  break;
631  case CardUtil::QPSK:
632  subType = "DVB-S";
633  signalTimeout = 7000;
634  channelTimeout = 10000;
635  break;
636  case CardUtil::DVBS2:
637  subType = "DVB-S2";
638  signalTimeout = 7000;
639  channelTimeout = 10000;
640  break;
641  case CardUtil::QAM:
642  subType = "DVB-C";
643  signalTimeout = 3000;
644  channelTimeout = 6000;
645  break;
646  case CardUtil::DVBT2:
647  subType = "DVB-T2";
648  signalTimeout = 3000;
649  channelTimeout = 6000;
650  break;
651  case CardUtil::OFDM:
652  {
653  subType = "DVB-T";
654  signalTimeout = 3000;
655  channelTimeout = 6000;
656  if (frontendName.toLower().indexOf("usb") >= 0)
657  {
658  signalTimeout = 40000;
659  channelTimeout = 42500;
660  }
661 
662  // slow down tuning for buggy drivers
663  if ((frontendName == "DiBcom 3000P/M-C DVB-T") ||
664  (frontendName ==
665  "TerraTec/qanu USB2.0 Highspeed DVB-T Receiver"))
666  {
667  tuningDelay = 200;
668  }
669  break;
670  }
671  case CardUtil::ATSC:
672  {
673  QString short_name = remove_chaff(frontendName);
674  subType = "ATSC";
675  frontendName = short_name;
676  signalTimeout = 2000;
677  channelTimeout = 4000;
678 
679  // According to #1779 and #1935 the AverMedia 180 needs
680  // a 3000 ms signal timeout, at least for QAM tuning.
681  if (frontendName == "Nextwave NXT200X VSB/QAM frontend")
682  {
683  signalTimeout = 3000;
684  channelTimeout = 5500;
685  }
686  break;
687  }
688  default:
689  break;
690  }
691 
692  pDev->setFrontendName ( frontendName );
693  pDev->setSubType ( subType );
694  pDev->setSignalTimeout ( signalTimeout );
695  pDev->setChannelTimeout ( channelTimeout );
696  pDev->setTuningDelay ( tuningDelay );
697  } // endif (CardType == "DVB")
698 #endif // USING_DVB
699 #ifdef USING_HDHOMERUN
700  if (CardType == "HDHOMERUN")
701  {
702  pDev->setSignalTimeout ( 3000 );
703  pDev->setChannelTimeout ( 6000 );
704  }
705 #endif //USING_HDHOMERUN
706  } // endfor (const auto & it : qAsConst(sdevs))
707  return pList;
708 }
709 
710 
711 
713 {
714  MSqlQuery query(MSqlQuery::InitCon());
715 
716  if (!query.isConnected())
717  throw( QString("Database not open while trying to list "
718  "DiseqcTrees."));
719 
720  QString str = "SELECT diseqcid, "
721  "parentid, "
722  "ordinal, "
723  "type, "
724  "subtype, "
725  "description, "
726  "switch_ports, "
727  "rotor_hi_speed, "
728  "rotor_lo_speed, "
729  "rotor_positions, "
730  "lnb_lof_switch, "
731  "lnb_lof_hi, "
732  "lnb_lof_lo, "
733  "cmd_repeat, "
734  "lnb_pol_inv, "
735  "address, "
736  "scr_userband, "
737  "scr_frequency, "
738  "scr_pin "
739  "FROM diseqc_tree ORDER BY diseqcid";
740 
741  query.prepare(str);
742 
743  if (!query.exec())
744  {
745  MythDB::DBError("MythAPI::GetDiseqcTreeList()", query);
746  throw( QString( "Database Error executing query." ));
747  }
748 
749  // ----------------------------------------------------------------------
750  // return the results of the query
751  // ----------------------------------------------------------------------
752 
753  auto* pList = new V2DiseqcTreeList();
754 
755  while (query.next())
756  {
757  auto *pRec = pList->AddDiseqcTree();
758  pRec->setDiSEqCId ( query.value( 0 ).toUInt() );
759  pRec->setParentId ( query.value( 1 ).toUInt() );
760  pRec->setOrdinal ( query.value( 2 ).toUInt() );
761  pRec->setType ( query.value( 3 ).toString() );
762  pRec->setSubType ( query.value( 4 ).toString() );
763  pRec->setDescription ( query.value( 5 ).toString() );
764  pRec->setSwitchPorts ( query.value( 6 ).toUInt() );
765  pRec->setRotorHiSpeed ( query.value( 7 ).toFloat() );
766  pRec->setRotorLoSpeed ( query.value( 8 ).toFloat() );
767  pRec->setRotorPositions ( query.value( 9 ).toString() );
768  pRec->setLnbLofSwitch ( query.value( 10 ).toInt() );
769  pRec->setLnbLofHi ( query.value( 11 ).toInt() );
770  pRec->setLnbLofLo ( query.value( 12 ).toInt() );
771  pRec->setCmdRepeat ( query.value( 13 ).toInt() );
772  pRec->setLnbPolInv ( query.value( 14 ).toBool() );
773  pRec->setAddress ( query.value( 15 ).toInt() );
774  pRec->setScrUserband ( query.value( 16 ).toUInt() );
775  pRec->setScrFrequency ( query.value( 17 ).toUInt() );
776  pRec->setScrPin ( query.value( 18 ).toInt() );
777  }
778 
779  return pList;
780 }
781 
783  uint Ordinal,
784  const QString& Type,
785  const QString& SubType,
786  const QString& Description,
787  uint SwitchPorts,
788  float RotorHiSpeed,
789  float RotorLoSpeed,
790  const QString& RotorPositions,
791  int LnbLofSwitch,
792  int LnbLofHi,
793  int LnbLofLo,
794  int CmdRepeat,
795  bool LnbPolInv,
796  int Address,
797  uint ScrUserband,
798  uint ScrFrequency,
799  int ScrPin)
800 {
801  MSqlQuery query(MSqlQuery::InitCon());
802 
803  query.prepare(
804  "INSERT INTO diseqc_tree "
805  "(parentid, "
806  "ordinal, "
807  "type, "
808  "subtype, "
809  "description, "
810  "switch_ports, "
811  "rotor_hi_speed, "
812  "rotor_lo_speed, "
813  "rotor_positions, "
814  "lnb_lof_switch, "
815  "lnb_lof_hi, "
816  "lnb_lof_lo, "
817  "cmd_repeat, "
818  "lnb_pol_inv, "
819  "address, "
820  "scr_userband, "
821  "scr_frequency, "
822  "scr_pin) "
823  "VALUES "
824  "(:PARENTID, "
825  ":ORDINAL, "
826  ":TYPE, "
827  ":SUBTYPE, "
828  ":DESCRIPTION, "
829  ":SWITCH_PORTS, "
830  ":ROTOR_HI_SPEED, "
831  ":ROTOR_LO_SPEED, "
832  ":ROTOR_POSITIONS, "
833  ":LNB_LOF_SWITCH, "
834  ":LNB_LOF_HI, "
835  ":LNB_LOF_LO, "
836  ":CMD_REPEAT, "
837  ":LNB_POL_INV, "
838  ":ADDRESS, "
839  ":SCR_USERBAND, "
840  ":SCR_FREQUENCY, "
841  ":SCR_PIN ) " );
842 
843  if (ParentId == 0) // Value 0 is set to null
844  {
845 #if QT_VERSION < QT_VERSION_CHECK(6,0,0)
846  query.bindValue(":PARENTID", QVariant(QVariant::UInt));
847 #else
848  query.bindValue(":PARENTID", QVariant(QMetaType(QMetaType::UInt)));
849 #endif
850  }
851  else
852  query.bindValue(":PARENTID", ParentId);
853  query.bindValue(":ORDINAL", Ordinal);
854  query.bindValue(":TYPE", Type);
855  query.bindValue(":SUBTYPE", SubType);
856  query.bindValue(":DESCRIPTION", Description);
857  query.bindValue(":SWITCH_PORTS", SwitchPorts);
858  query.bindValue(":ROTOR_HI_SPEED", RotorHiSpeed);
859  query.bindValue(":ROTOR_LO_SPEED", RotorLoSpeed);
860  query.bindValue(":ROTOR_POSITIONS", RotorPositions);
861  query.bindValue(":LNB_LOF_SWITCH", LnbLofSwitch);
862  query.bindValue(":LNB_LOF_HI", LnbLofHi);
863  query.bindValue(":LNB_LOF_LO", LnbLofLo);
864  query.bindValue(":CMD_REPEAT", CmdRepeat);
865  query.bindValue(":LNB_POL_INV", LnbPolInv);
866  query.bindValue(":ADDRESS", Address);
867  query.bindValue(":SCR_USERBAND", ScrUserband);
868  query.bindValue(":SCR_FREQUENCY", ScrFrequency);
869  query.bindValue(":SCR_PIN", ScrPin);
870 
871  if (!query.exec())
872  {
873  MythDB::DBError("MythAPI::AddDiseqcTree()", query);
874  throw( QString( "Database Error executing query." ));
875  }
876  uint DiSEqCId = query.lastInsertId().toInt();
877  return DiSEqCId;
878 }
879 
881  uint ParentId,
882  uint Ordinal,
883  const QString& Type,
884  const QString& SubType,
885  const QString& Description,
886  uint SwitchPorts,
887  float RotorHiSpeed,
888  float RotorLoSpeed,
889  const QString& RotorPositions,
890  int LnbLofSwitch,
891  int LnbLofHi,
892  int LnbLofLo,
893  int CmdRepeat,
894  bool LnbPolInv,
895  int Address,
896  uint ScrUserband,
897  uint ScrFrequency,
898  int ScrPin)
899 {
900  MSqlQuery query(MSqlQuery::InitCon());
901 
902  query.prepare(
903  "UPDATE diseqc_tree SET "
904  "parentid = :PARENTID, "
905  "ordinal = :ORDINAL, "
906  "type = :TYPE, "
907  "subtype = :SUBTYPE, "
908  "description = :DESCRIPTION, "
909  "switch_ports = :SWITCH_PORTS, "
910  "rotor_hi_speed = :ROTOR_HI_SPEED, "
911  "rotor_lo_speed = :ROTOR_LO_SPEED, "
912  "rotor_positions = :ROTOR_POSITIONS, "
913  "lnb_lof_switch = :LNB_LOF_SWITCH, "
914  "lnb_lof_hi = :LNB_LOF_HI, "
915  "lnb_lof_lo = :LNB_LOF_LO, "
916  "cmd_repeat = :CMD_REPEAT, "
917  "lnb_pol_inv = :LNB_POL_INV, "
918  "address = :ADDRESS, "
919  "scr_userband = :SCR_USERBAND, "
920  "scr_frequency = :SCR_FREQUENCY, "
921  "scr_pin = :SCR_PIN "
922  "WHERE diseqcid = :DISEQCID " );
923 
924  query.bindValue(":DISEQCID", DiSEqCId);
925  if (ParentId == 0) // Value 0 is set to null
926  {
927 #if QT_VERSION < QT_VERSION_CHECK(6,0,0)
928  query.bindValue(":PARENTID", QVariant(QVariant::UInt));
929 #else
930  query.bindValue(":PARENTID", QVariant(QMetaType(QMetaType::UInt)));
931 #endif
932  }
933  else
934  query.bindValue(":PARENTID", ParentId);
935  query.bindValue(":ORDINAL", Ordinal);
936  query.bindValue(":TYPE", Type);
937  query.bindValue(":SUBTYPE", SubType);
938  query.bindValue(":DESCRIPTION", Description);
939  query.bindValue(":SWITCH_PORTS", SwitchPorts);
940  query.bindValue(":ROTOR_HI_SPEED", RotorHiSpeed);
941  query.bindValue(":ROTOR_LO_SPEED", RotorLoSpeed);
942  query.bindValue(":ROTOR_POSITIONS", RotorPositions);
943  query.bindValue(":LNB_LOF_SWITCH", LnbLofSwitch);
944  query.bindValue(":LNB_LOF_HI", LnbLofHi);
945  query.bindValue(":LNB_LOF_LO", LnbLofLo);
946  query.bindValue(":CMD_REPEAT", CmdRepeat);
947  query.bindValue(":LNB_POL_INV", LnbPolInv);
948  query.bindValue(":ADDRESS", Address);
949  query.bindValue(":SCR_USERBAND", ScrUserband);
950  query.bindValue(":SCR_FREQUENCY", ScrFrequency);
951  query.bindValue(":SCR_PIN", ScrPin);
952 
953  if (!query.exec())
954  {
955  MythDB::DBError("MythAPI::UpdateDiseqcTree()", query);
956  throw( QString( "Database Error executing query." ));
957  }
958  return true;
959 }
960 
962 {
963  // Find and remove children
964  MSqlQuery query(MSqlQuery::InitCon());
965  query.prepare("SELECT diseqcid FROM diseqc_tree WHERE parentid = :PARENTID ");
966  query.bindValue(":PARENTID", DiSEqCId);
967 
968  if (!query.exec())
969  {
970  MythDB::DBError("MythAPI::RemoveDiseqcTree()", query);
971  throw( QString( "Database Error executing query." ));
972  }
973 
974  bool childOK = true;
975  while (query.next())
976  {
977  uint child = query.value( 0 ).toUInt();
978  childOK = RemoveDiseqcTree(child) && childOK;
979  }
980  // remove this row
981  MSqlQuery query2(MSqlQuery::InitCon());
982  query2.prepare("DELETE FROM diseqc_tree WHERE diseqcid = :DISEQCID ");
983  query2.bindValue(":DISEQCID", DiSEqCId);
984  if (!query2.exec())
985  {
986  MythDB::DBError("MythAPI::RemoveDiseqcTree()", query2);
987  throw( QString( "Database Error executing query." ));
988  }
989  int numrows = query2.numRowsAffected();
990  return numrows > 0 && childOK;
991 }
992 
993 
995 {
996 
997  MSqlQuery query(MSqlQuery::InitCon());
998 
999  if (!query.isConnected())
1000  throw( QString("Database not open while trying to list "
1001  "DiseqcConfigs."));
1002 
1003  QString str = "SELECT cardinputid, "
1004  "diseqcid, "
1005  "value "
1006  "FROM diseqc_config ORDER BY cardinputid, diseqcid";
1007 
1008  query.prepare(str);
1009 
1010  if (!query.exec())
1011  {
1012  MythDB::DBError("MythAPI::GetDiseqcConfigList()", query);
1013  throw( QString( "Database Error executing query." ));
1014  }
1015 
1016  // ----------------------------------------------------------------------
1017  // return the results of the query
1018  // ----------------------------------------------------------------------
1019 
1020  auto* pList = new V2DiseqcConfigList();
1021 
1022  while (query.next())
1023  {
1024  auto *pRec = pList->AddDiseqcConfig();
1025  pRec->setCardId ( query.value( 0 ).toUInt() );
1026  pRec->setDiSEqCId ( query.value( 1 ).toUInt() );
1027  pRec->setValue ( query.value( 2 ).toString() );
1028  }
1029  return pList;
1030 }
1031 
1033  uint DiSEqCId,
1034  const QString& Value)
1035 {
1036  MSqlQuery query(MSqlQuery::InitCon());
1037 
1038  query.prepare(
1039  "INSERT INTO diseqc_config "
1040  "(cardinputid, "
1041  "diseqcid, "
1042  "value) "
1043  "VALUES "
1044  "(:CARDID, "
1045  ":DISEQCID, "
1046  ":VALUE) ");
1047 
1048  query.bindValue(":CARDID", CardId);
1049  query.bindValue(":DISEQCID", DiSEqCId);
1050  query.bindValue(":VALUE", Value);
1051 
1052  if (!query.exec())
1053  {
1054  MythDB::DBError("MythAPI::AddDiseqcConfig()", query);
1055  throw( QString( "Database Error executing query." ));
1056  }
1057  return true;
1058 }
1059 
1060 
1062 {
1063  MSqlQuery query(MSqlQuery::InitCon());
1064  query.prepare("DELETE FROM diseqc_config WHERE cardinputid = :CARDID ");
1065  query.bindValue(":CARDID", CardId);
1066  if (!query.exec())
1067  {
1068  MythDB::DBError("MythAPI::RemoveDiseqcConfig()", query);
1069  throw( QString( "Database Error executing query." ));
1070  }
1071  int numrows = query.numRowsAffected();
1072  return numrows > 0;
1073 }
1074 
1075 
1076 V2RecProfileGroupList* V2Capture::GetRecProfileGroupList ( uint GroupId, uint ProfileId, bool OnlyInUse ) {
1077 
1078  MSqlQuery query(MSqlQuery::InitCon());
1079 
1080  QString str =
1081  "SELECT profilegroups.id, profilegroups.name, cardtype, recordingprofiles.id, recordingprofiles.name, "
1082  "videocodec, audiocodec, "
1083  "codecparams.name, codecparams.value "
1084  "FROM profilegroups "
1085  "INNER JOIN recordingprofiles on profilegroups.id = recordingprofiles.profilegroup "
1086  "LEFT OUTER JOIN codecparams on codecparams.profile = recordingprofiles.id ";
1087  QString where = "WHERE ";
1088  if (OnlyInUse)
1089  {
1090  str.append(where).append("CARDTYPE = 'TRANSCODE' OR (cardtype in (SELECT cardtype FROM capturecard)) ");
1091  where = "AND ";
1092  }
1093  if (GroupId > 0)
1094  {
1095  str.append(where).append("profilegroups.id = :GROUPID ");
1096  where = "AND ";
1097  }
1098  if (ProfileId > 0)
1099  {
1100  str.append(where).append("recordingprofiles.id = :PROFILEID ");
1101  where = "AND ";
1102  }
1103  str.append(
1104  // Force TRANSCODE entry to be at the end
1105  "ORDER BY IF(cardtype = 'TRANSCODE', 9999, profilegroups.id), recordingprofiles.id, codecparams.name ");
1106 
1107  query.prepare(str);
1108 
1109  if (GroupId > 0)
1110  query.bindValue(":GROUPID", GroupId);
1111  if (ProfileId > 0)
1112  query.bindValue(":PROFILEID", ProfileId);
1113 
1114  if (!query.exec())
1115  {
1116  MythDB::DBError("MythAPI::GetRecProfileGroupList()", query);
1117  throw( QString( "Database Error executing query." ));
1118  }
1119 
1120  // ----------------------------------------------------------------------
1121  // return the results of the query
1122  // ----------------------------------------------------------------------
1123 
1124  auto* pList = new V2RecProfileGroupList();
1125 
1126  int prevGroupId = -1;
1127  int prevProfileId = -1;
1128 
1129  V2RecProfileGroup * pGroup = nullptr;
1130  V2RecProfile *pProfile = nullptr;
1131 
1132  while (query.next())
1133  {
1134  int groupId = query.value(0).toInt();
1135  if (groupId != prevGroupId)
1136  {
1137  pGroup = pList->AddProfileGroup();
1138  pGroup->setId ( groupId );
1139  pGroup->setName ( query.value(1).toString() );
1140  pGroup->setCardType ( query.value(2).toString() );
1141  prevGroupId = groupId;
1142  }
1143  int profileId = query.value(3).toInt();
1144  if (profileId != prevProfileId)
1145  {
1146  pProfile = pGroup->AddProfile();
1147  pProfile->setId ( profileId );
1148  pProfile->setName ( query.value(4).toString() );
1149  pProfile->setVideoCodec ( query.value(5).toString() );
1150  pProfile->setAudioCodec ( query.value(6).toString() );
1151  prevProfileId = profileId;
1152  }
1153  if (!query.isNull(7))
1154  {
1155  auto *pParam = pProfile->AddParam();
1156  pParam->setName ( query.value(7).toString() );
1157  pParam->setValue ( query.value(8).toString() );
1158  }
1159  }
1160 
1161  return pList;
1162 }
1163 
1164 int V2Capture::AddRecProfile ( uint GroupId, const QString& ProfileName,
1165  const QString& VideoCodec, const QString& AudioCodec )
1166 {
1167  if (GroupId == 0 || ProfileName.isEmpty())
1168  {
1169  LOG(VB_GENERAL, LOG_ERR,
1170  QString( "AddRecProfile: GroupId and ProfileName are required." ));
1171  return false;
1172  }
1173 
1174  MSqlQuery query(MSqlQuery::InitCon());
1175 
1176  // Check if it already exists
1177  query.prepare(
1178  "SELECT id "
1179  "FROM recordingprofiles "
1180  "WHERE name = :NAME AND profilegroup = :PROFILEGROUP;");
1181  query.bindValue(":NAME", ProfileName);
1182  query.bindValue(":PROFILEGROUP", GroupId);
1183  if (!query.exec())
1184  {
1185  MythDB::DBError("V2Capture::AddRecProfile", query);
1186  throw( QString( "Database Error executing SELECT." ));
1187  }
1188  int id;
1189  if (query.next())
1190  {
1191  id = query.value(0).toInt();
1192  LOG(VB_GENERAL, LOG_ERR,
1193  QString( "Profile %1 already exists in group id %2 with id %3").arg(ProfileName).arg(GroupId).arg(id));
1194  return false;
1195  }
1196 
1197  query.prepare(
1198  "INSERT INTO recordingprofiles "
1199  "(name, videocodec, audiocodec, profilegroup) "
1200  "VALUES "
1201  "(:NAME, :VIDEOCODEC, :AUDIOCODEC, :PROFILEGROUP);");
1202  query.bindValue(":NAME", ProfileName);
1203  query.bindValue(":VIDEOCODEC", VideoCodec);
1204  query.bindValue(":AUDIOCODEC", AudioCodec);
1205  query.bindValue(":PROFILEGROUP", GroupId);
1206  if (!query.exec())
1207  {
1208  MythDB::DBError("V2Capture::AddRecProfile", query);
1209  throw( QString( "Database Error executing INSERT." ));
1210  }
1211  id = query.lastInsertId().toInt();
1212  RecordingProfile profile(ProfileName);
1213  profile.loadByID(id);
1214  profile.setCodecTypes();
1215  profile.Save();
1216  return id;
1217 }
1218 
1220  const QString& VideoCodec,
1221  const QString& AudioCodec )
1222 {
1223  MSqlQuery query(MSqlQuery::InitCon());
1224  query.prepare(
1225  "SELECT id from recordingprofiles "
1226  "WHERE id = :ID; ");
1227  query.bindValue(":ID", ProfileId);
1228  if (!query.exec())
1229  {
1230  MythDB::DBError("V2Capture::UpdateRecProfileParam", query);
1231  throw( QString( "Database Error executing SELECT." ));
1232  }
1233  uint id = -1;
1234  if (query.next())
1235  {
1236  id = query.value(0).toUInt();
1237  }
1238  if (id != ProfileId)
1239  {
1240  LOG(VB_GENERAL, LOG_ERR,
1241  QString("UpdateRecProfile: Profile id %1 does not exist").arg(ProfileId));
1242  return false;
1243  }
1244  query.prepare(
1245  "UPDATE recordingprofiles "
1246  "SET videocodec = :VIDEOCODEC, "
1247  "audiocodec = :AUDIOCODEC "
1248  "WHERE id = :ID; ");
1249  query.bindValue(":VIDEOCODEC", VideoCodec);
1250  query.bindValue(":AUDIOCODEC", AudioCodec);
1251  query.bindValue(":ID", ProfileId);
1252  if (!query.exec())
1253  {
1254  MythDB::DBError("V2Capture::UpdateRecProfileParam", query);
1255  throw( QString( "Database Error executing UPDATE." ));
1256  }
1258  profile.loadByID(ProfileId);
1259  profile.setCodecTypes();
1260  profile.Save();
1261  return true;
1262 }
1263 
1265 {
1266  // Delete profile parameters
1267  MSqlQuery query(MSqlQuery::InitCon());
1268  query.prepare(
1269  "DELETE from codecparams "
1270  "WHERE profile = :ID; ");
1271  query.bindValue(":ID", ProfileId);
1272  if (!query.exec())
1273  {
1274  MythDB::DBError("V2Capture::UpdateRecProfileParam", query);
1275  throw( QString( "Database Error executing DELETE." ));
1276  }
1277  int rows = query.numRowsAffected();
1278  query.prepare(
1279  "DELETE from recordingprofiles "
1280  "WHERE id = :ID; ");
1281  query.bindValue(":ID", ProfileId);
1282  if (!query.exec())
1283  {
1284  MythDB::DBError("V2Capture::UpdateRecProfileParam", query);
1285  throw( QString( "Database Error executing DELETE." ));
1286  }
1287  return (rows > 0);
1288 }
1289 
1290 
1291 
1292 bool V2Capture::UpdateRecProfileParam ( uint ProfileId, const QString &Name, const QString &Value )
1293 {
1294  MSqlQuery query(MSqlQuery::InitCon());
1295  query.prepare(
1296  "REPLACE INTO codecparams "
1297  "(profile, name, value) "
1298  "VALUES "
1299  "(:PROFILE, :NAME, :VALUE);");
1300  query.bindValue(":PROFILE", ProfileId);
1301  query.bindValue(":NAME", Name);
1302  query.bindValue(":VALUE", Value);
1303  if (!query.exec())
1304  {
1305  MythDB::DBError("V2Capture::UpdateRecProfileParam", query);
1306  throw( QString( "Database Error executing REPLACE." ));
1307  }
1308  return true;
1309 }
MSqlQuery::next
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
Definition: mythdbcon.cpp:807
MSqlQuery
QSqlQuery wrapper that fetches a DB connection from the connection pool.
Definition: mythdbcon.h:128
V2CardTypeList
Definition: v2captureCardList.h:58
CardUtil::CreateCardInput
static int CreateCardInput(uint inputid, uint sourceid, const QString &inputname, const QString &externalcommand, const QString &changer_device, const QString &changer_model, const QString &hostname, const QString &tunechan, const QString &startchan, const QString &displayname, bool dishnet_eit, uint recpriority, uint quicktune, uint schedorder, uint livetvorder)
Definition: cardutil.cpp:1986
MSqlQuery::isNull
bool isNull(int field) const
Definition: mythdbcon.h:220
V2Capture::UpdateCardInput
static bool UpdateCardInput(int CardInputId, const QString &Setting, const QString &Value)
Definition: v2capture.cpp:388
V2Capture::UpdateRecProfileParam
static bool UpdateRecProfileParam(uint ProfileId, const QString &Name, const QString &Value)
Definition: v2capture.cpp:1292
V2Capture::LinkInputGroup
static bool LinkInputGroup(uint InputId, uint InputGroupId)
Definition: v2capture.cpp:516
CardUtil::ProbeDeliverySystems
static QStringList ProbeDeliverySystems(const QString &device)
Definition: cardutil.cpp:635
remove_chaff
static QString remove_chaff(const QString &name)
Definition: v2capture.cpp:543
CardUtil::toInputType
static enum INPUT_TYPES toInputType(const QString &name)
Definition: cardutil.h:73
CardUtil::ERROR_UNKNOWN
@ ERROR_UNKNOWN
Definition: cardutil.h:49
CardUtil::DVBT2
@ DVBT2
Definition: cardutil.h:68
CardUtil::DeleteAllInputs
static bool DeleteAllInputs(void)
Definition: cardutil.cpp:2909
MSqlQuery::lastInsertId
QVariant lastInsertId()
Return the id of the last inserted row.
Definition: mythdbcon.cpp:912
V2DiseqcConfigList
Definition: v2captureCardList.h:213
V2Capture::GetRecProfileGroupList
static V2RecProfileGroupList * GetRecProfileGroupList(uint GroupId, uint ProfileId, bool OnlyInUse)
Definition: v2capture.cpp:1076
V2Capture::AddCardInput
static int AddCardInput(uint CardId, uint SourceId, const QString &InputName, const QString &ExternalCommand, const QString &ChangerDevice, const QString &ChangerModel, const QString &HostName, const QString &TuneChan, const QString &StartChan, const QString &DisplayName, bool DishnetEIT, uint RecPriority, uint Quicktune, uint SchedOrder, uint LiveTVOrder)
Definition: v2capture.cpp:355
V2Capture::RemoveAllCaptureCards
static bool RemoveAllCaptureCards(void)
Definition: v2capture.cpp:271
MSqlQuery::value
QVariant value(int i) const
Definition: mythdbcon.h:205
V2Capture::GetDiseqcTreeList
static V2DiseqcTreeList * GetDiseqcTreeList(void)
Definition: v2capture.cpp:712
mythhttpmetaservice.h
MSqlQuery::exec
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
Definition: mythdbcon.cpp:608
V2Capture::GetCaptureCardList
static V2CaptureCardList * GetCaptureCardList(const QString &HostName, const QString &CardType)
Definition: v2capture.cpp:78
set_on_input
bool set_on_input(const QString &to_set, uint inputid, const QString &value)
Definition: cardutil.cpp:1302
V2CaptureCardList
Definition: v2captureCardList.h:21
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
V2Capture::UpdateCaptureCard
static bool UpdateCaptureCard(int CardId, const QString &Setting, const QString &Value)
Definition: v2capture.cpp:333
getV4l2List
V2CaptureDeviceList * getV4l2List(const QRegularExpression &driver, const QString &cardType)
Definition: v2serviceUtil.cpp:893
V2CaptureDeviceList
Definition: v2captureCardList.h:97
V2Capture::UpdateRecProfile
static bool UpdateRecProfile(uint ProfileId, const QString &VideoCodec, const QString &AudioCodec)
Definition: v2capture.cpp:1219
CardUtil::IsUniqueDisplayName
static bool IsUniqueDisplayName(const QString &name, uint exclude_inputid)
Definition: cardutil.cpp:1920
CardUtil::ProbeDefaultDeliverySystem
static QString ProbeDefaultDeliverySystem(const QString &device)
Definition: cardutil.cpp:714
CardUtil::ProbeDVBType
static QString ProbeDVBType(const QString &device)
Definition: cardutil.cpp:732
V2Capture::SetInputMaxRecordings
static bool SetInputMaxRecordings(uint InputId, uint Max)
Definition: v2capture.cpp:535
CardUtil::ProbeVideoDevices
static QStringList ProbeVideoDevices(const QString &rawtype)
Definition: cardutil.cpp:450
V2InputGroupList
Definition: v2captureCardList.h:134
CardUtil::ProbeDVBFrontendName
static QString ProbeDVBFrontendName(const QString &device)
Returns the input type from the video device.
Definition: cardutil.cpp:753
CardUtil::DVBS2
@ DVBS2
Definition: cardutil.h:61
mythdate.h
CardUtil::UnlinkInputGroup
static bool UnlinkInputGroup(uint inputid, uint inputgroupid)
Definition: cardutil.cpp:2176
CardUtil::QPSK
@ QPSK
Definition: cardutil.h:51
v2serviceUtil.h
hardwareprofile.scan.profile
profile
Definition: scan.py:99
V2Capture::AddDiseqcConfig
static bool AddDiseqcConfig(uint CardId, uint DiSEqCId, const QString &Value)
Definition: v2capture.cpp:1032
V2RecProfileGroupList
Definition: v2recordingProfile.h:113
MSqlQuery::InitCon
static MSqlQueryInfo InitCon(ConnectionReuse _reuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
Definition: mythdbcon.cpp:540
compat.h
V2RecProfile
Definition: v2recordingProfile.h:42
MythDB::DBError
static void DBError(const QString &where, const MSqlQuery &query)
Definition: mythdb.cpp:227
CardUtil::QAM
@ QAM
Definition: cardutil.h:52
V2CaptureCard
Definition: v2captureCard.h:20
v2capture.h
V2Capture::GetUserInputGroupList
static V2InputGroupList * GetUserInputGroupList(void)
Definition: v2capture.cpp:468
CAPTURE_HANDLE
#define CAPTURE_HANDLE
Definition: v2capture.h:34
MSqlQuery::isConnected
bool isConnected(void) const
Only updated once during object creation.
Definition: mythdbcon.h:138
V2Capture::AddDiseqcTree
static int AddDiseqcTree(uint ParentId, uint Ordinal, const QString &Type, const QString &SubType, const QString &Description, uint SwitchPorts, float RotorHiSpeed, float RotorLoSpeed, const QString &RotorPositions, int LnbLofSwitch, int LnbLofHi, int LnbLofLo, int CmdRepeat, bool LnbPolInv, int Address, uint ScrUserband, uint ScrFrequency, int ScrPin)
Definition: v2capture.cpp:782
uint
unsigned int uint
Definition: compat.h:81
MythHTTPService
Definition: mythhttpservice.h:19
CardUtil::InputSetMaxRecordings
static bool InputSetMaxRecordings(uint parentid, uint max_recordings)
Definition: cardutil.cpp:1588
V2Capture::V2Capture
V2Capture()
Definition: v2capture.cpp:69
V2Capture::RemoveDiseqcTree
static bool RemoveDiseqcTree(uint DiSEqCId)
Definition: v2capture.cpp:961
CardType
Definition: videosource.h:327
standardsettings.h
Q_GLOBAL_STATIC_WITH_ARGS
Q_GLOBAL_STATIC_WITH_ARGS(MythHTTPMetaService, s_service,(CAPTURE_HANDLE, V2Capture::staticMetaObject, &V2Capture::RegisterCustomTypes)) void V2Capture
Definition: v2capture.cpp:46
MythHTTPService::Name
QString & Name()
Definition: mythhttpservice.cpp:227
V2Capture::RegisterCustomTypes
static void RegisterCustomTypes()
V2Capture::RemoveDiseqcConfig
static bool RemoveDiseqcConfig(uint CardId)
Definition: v2capture.cpp:1061
V2Capture::DeleteRecProfile
static bool DeleteRecProfile(uint ProfileId)
Definition: v2capture.cpp:1264
V2Capture::GetDiseqcConfigList
static V2DiseqcConfigList * GetDiseqcConfigList(void)
Definition: v2capture.cpp:994
mythcorecontext.h
cardutil.h
CardUtil::CreateCaptureCard
static int CreateCaptureCard(const QString &videodevice, const QString &audiodevice, const QString &vbidevice, const QString &inputtype, uint audioratelimit, const QString &hostname, uint dvb_swfilter, uint dvb_sat_type, bool dvb_wait_for_seqstart, bool skipbtaudio, bool dvb_on_demand, uint dvb_diseqc_type, uint firewire_speed, const QString &firewire_model, uint firewire_connection, std::chrono::milliseconds signal_timeout, std::chrono::milliseconds channel_timeout, uint dvb_tuning_delay, uint contrast, uint brightness, uint colour, uint hue, uint diseqcid, bool dvb_eitscan)
Definition: cardutil.cpp:2700
Name
Definition: channelsettings.cpp:47
MSqlQuery::bindValue
void bindValue(const QString &placeholder, const QVariant &val)
Add a single binding.
Definition: mythdbcon.cpp:883
V2RecProfileGroup
Definition: v2recordingProfile.h:79
V2DiseqcTreeList
Definition: v2captureCardList.h:177
V2Capture::UnlinkInputGroup
static bool UnlinkInputGroup(uint InputId, uint InputGroupId)
Definition: v2capture.cpp:526
V2RecProfileGroup::AddProfile
V2RecProfile * AddProfile()
Definition: v2recordingProfile.h:97
V2Capture::GetCardTypeList
static V2CardTypeList * GetCardTypeList(void)
Definition: v2capture.cpp:398
V2Capture::RemoveCaptureCard
static bool RemoveCaptureCard(int CardId)
Definition: v2capture.cpp:276
V2Capture::UpdateDiseqcTree
static bool UpdateDiseqcTree(uint DiSEqCId, uint ParentId, uint Ordinal, const QString &Type, const QString &SubType, const QString &Description, uint SwitchPorts, float RotorHiSpeed, float RotorLoSpeed, const QString &RotorPositions, int LnbLofSwitch, int LnbLofHi, int LnbLofLo, int CmdRepeat, bool LnbPolInv, int Address, uint ScrUserband, uint ScrFrequency, int ScrPin)
Definition: v2capture.cpp:880
CardUtil::OFDM
@ OFDM
Definition: cardutil.h:53
V2Capture::AddCaptureCard
static int AddCaptureCard(const QString &VideoDevice, const QString &AudioDevice, const QString &VBIDevice, const QString &CardType, uint AudioRateLimit, const QString &HostName, uint DVBSWFilter, uint DVBSatType, bool DVBWaitForSeqStart, bool SkipBTAudio, bool DVBOnDemand, uint DVBDiSEqCType, uint FirewireSpeed, const QString &FirewireModel, uint FirewireConnection, uint SignalTimeout, uint ChannelTimeout, uint DVBTuningDelay, uint Contrast, uint Brightness, uint Colour, uint Hue, uint DiSEqCId, bool DVBEITScan)
Definition: v2capture.cpp:290
MSqlQuery::numRowsAffected
int numRowsAffected() const
Definition: mythdbcon.h:218
recordingprofile.h
V2Capture::AddUserInputGroup
static int AddUserInputGroup(const QString &Name)
Definition: v2capture.cpp:499
RecordingProfile
Definition: recordingprofile.h:41
V2RecProfile::AddParam
V2RecProfParam * AddParam()
Definition: v2recordingProfile.h:56
V2Capture::GetCaptureDeviceList
static V2CaptureDeviceList * GetCaptureDeviceList(const QString &CardType)
Definition: v2capture.cpp:587
CardUtil::ATSC
@ ATSC
Definition: cardutil.h:54
V2Capture::GetCaptureCard
static V2CaptureCard * GetCaptureCard(int CardId)
Definition: v2capture.cpp:183
CardUtil::CreateInputGroup
static uint CreateInputGroup(const QString &name)
Definition: cardutil.cpp:2046
CardUtil::LinkInputGroup
static bool LinkInputGroup(uint inputid, uint inputgroupid)
Definition: cardutil.cpp:2125
MythHTTPMetaService
Definition: mythhttpmetaservice.h:10
CardUtil::ERROR_OPEN
@ ERROR_OPEN
Definition: cardutil.h:48
V2Capture::AddRecProfile
static int AddRecProfile(uint GroupId, const QString &ProfileName, const QString &VideoCodec, const QString &AudioCodec)
Definition: v2capture.cpp:1164
MSqlQuery::prepare
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.
Definition: mythdbcon.cpp:832
CardUtil::ERROR_PROBE
@ ERROR_PROBE
Definition: cardutil.h:50
CardUtil::DeleteInput
static bool DeleteInput(uint inputid)
Definition: cardutil.cpp:2839
V2Capture::RemoveCardInput
static bool RemoveCardInput(int CardInputId)
Definition: v2capture.cpp:345