Skip to content

Commit

Permalink
CAM setup for multirec
Browse files Browse the repository at this point in the history
Remove duplicate service IDs when setting up the CAM. The CAM needs to be setup only once for each
service also if more than one program is being recorded from the same service. This solves the issue
of recordings having interrupts at the moment a second recording is started on the same channel.
This can happen with overlapping recordings on the same channel, when the recording starts before
the scheduled start time or the recording continues after the scheduled end time.
  • Loading branch information
kmdewaal committed Oct 4, 2020
1 parent cd034a0 commit 19abbf7
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 16 deletions.
80 changes: 68 additions & 12 deletions mythtv/libs/libmythtv/recorders/dvbcam.cpp
Expand Up @@ -33,35 +33,35 @@
*
*/

// C++
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <map>
#include <string>
#include <utility>
#include <vector>

// C
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/poll.h>
#include <linux/dvb/ca.h>

#include <dvbci.h>
// Qt
#include <QString>
#include <QList>
#include <QMap>

// MythTV
#include "dvbci.h"
#include "recorderbase.h"

#include "cardutil.h"

#include "dvbcam.h"
#include "mthread.h"
#include "dvbchannel.h"
#include "dvbrecorder.h"
#include "mythlogging.h"

#define LOC QString("DVB#%1 CA: ").arg(m_device)
#define LOC QString("DVBCam(%1): ").arg(m_device)

DVBCam::DVBCam(QString aDevice)
: m_device(std::move(aDevice))
DVBCam::DVBCam(QString device)
: m_device(std::move(device))
{
QString dvbdev = CardUtil::GetDeviceName(DVB_DEV_CA, m_device);
QByteArray dev = dvbdev.toLatin1();
Expand All @@ -73,7 +73,7 @@ DVBCam::DVBCam(QString aDevice)
if (ioctl(cafd, CA_GET_CAP, &caps) >= 0)
m_numslots = caps.slot_num;
else
LOG(VB_GENERAL, LOG_ERR, "ioctl CA_GET_CAP failed: " + ENO);
LOG(VB_GENERAL, LOG_ERR, LOC + "ioctl CA_GET_CAP failed: " + ENO);

close(cafd);
}
Expand Down Expand Up @@ -201,11 +201,67 @@ void DVBCam::HandleUserIO(void)
}
}

// Remove duplicate service IDs because the CAM needs to be setup only
// once for each service even if the service is recorded twice.
// This can happen with overlapping recordings on the same channel.
void DVBCam::RemoveDuplicateServices(void)
{
QList<uint> unique_sids;
pmt_list_t::iterator it;

// Remove duplicates in m_pmtList
for (it = m_pmtList.begin(); it != m_pmtList.end(); )
{
const ChannelBase *chan = it.key();
uint inputId = chan->GetInputID();
const ProgramMapTable *pmt = (*it);
uint serviceId = pmt->ProgramNumber();
if (unique_sids.contains(serviceId))
{
it = m_pmtList.erase(it);
LOG(VB_DVBCAM, LOG_DEBUG, LOC + QString("Service [%1]%2 duplicate, removed from pmtList")
.arg(inputId).arg(serviceId));
}
else
{
unique_sids.append(serviceId);
++it;
LOG(VB_DVBCAM, LOG_DEBUG, LOC + QString("Service [%1]%2 stays in pmtList")
.arg(inputId).arg(serviceId));
}
}

// Remove duplicates in m_pmtAddList
for (it = m_pmtAddList.begin(); it != m_pmtAddList.end(); )
{
const ChannelBase *chan = it.key();
uint inputId = chan->GetInputID();
const ProgramMapTable *pmt = (*it);
uint serviceId = pmt->ProgramNumber();
if (unique_sids.contains(serviceId))
{
it = m_pmtAddList.erase(it);
LOG(VB_DVBCAM, LOG_DEBUG, LOC + QString("Service [%1]%2 duplicate, removed from pmtAddList")
.arg(inputId).arg(serviceId));
}
else
{
unique_sids.append(serviceId);
++it;
LOG(VB_DVBCAM, LOG_DEBUG, LOC + QString("Service [%1]%2 stays in pmtAddList")
.arg(inputId).arg(serviceId));
}
}
}


void DVBCam::HandlePMT(void)
{
LOG(VB_DVBCAM, LOG_INFO, LOC + "CiHandler needs CA_PMT");
QMutexLocker locker(&m_pmtLock);

RemoveDuplicateServices();

if (m_pmtSent && m_pmtAdded && !m_pmtUpdated)
{
// Send added PMT
Expand Down
8 changes: 4 additions & 4 deletions mythtv/libs/libmythtv/recorders/dvbcam.h
@@ -1,15 +1,15 @@
#ifndef DVBCAM_H
#define DVBCAM_H

#include <deque>

// Qt
#include <QWaitCondition>
#include <QRunnable>
#include <QString>
#include <QMap>
#include <QMutex>

// MythTV
#include "mpegtables.h"

#include "dvbtypes.h"

class ChannelBase;
Expand Down Expand Up @@ -40,7 +40,7 @@ class DVBCam : public QRunnable
void run(void) override; // QRunnable
void HandleUserIO(void);
void HandlePMT(void);

void RemoveDuplicateServices(void);
void SendPMT(const ProgramMapTable &pmt, uint cplm);

QString m_device;
Expand Down

0 comments on commit 19abbf7

Please sign in to comment.