Accepting request 314559 from KDE:Extra

1

OBS-URL: https://build.opensuse.org/request/show/314559
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/kaffeine?expand=0&rev=56
This commit is contained in:
Dominique Leuenberger 2015-07-02 20:49:49 +00:00 committed by Git OBS Bridge
commit 3a204758f7
3 changed files with 324 additions and 0 deletions

View File

@ -1,3 +1,9 @@
-------------------------------------------------------------------
Sat Jun 27 11:00:45 UTC 2015 - wbauer@tmo.at
- Add support_for_sundtek_tv_tuners.patch: add support for Sundtek
(local and networkbased) TV devices (boo#827097)
-------------------------------------------------------------------
Sat Nov 15 14:32:20 UTC 2014 - wbauer@tmo.at

View File

@ -41,6 +41,8 @@ Patch5: support_mimetypes_bnc671581.diff
Patch6: crash-on-resume-fix.patch
# PATCH-FIX-UPSTREAM kaffeine-gcc47.patch dimstar@opensuse.org -- Fix build with gcc 4.7
Patch7: kaffeine-gcc47.patch
# PATCH-FEATURE-UPSTREAM support_for_sundtek_tv_tuners.patch boo#827097 -- Add support for Sundtek DVB Devices
Patch8: support_for_sundtek_tv_tuners.patch
BuildRoot: %{_tmppath}/%{name}-%{version}-build
BuildRequires: libkde4-devel
@ -76,6 +78,7 @@ and Ogg Vorbis. It also handles Video CDs, DVDs, and DVB cards.
%endif
%patch6 -p1
%patch7
%patch8 -p1
%build
%cmake_kde4 -d build

View File

@ -0,0 +1,315 @@
From: Jonathan Riddell <jr@jriddell.org>
Date: Wed, 03 Dec 2014 14:23:17 +0000
Subject: Support for Sundtek TV Tuners (Networkbased and local devices)
X-Git-Url: http://quickgit.kde.org/?p=kaffeine.git&a=commitdiff&h=333ba6c927df747b61d8ba25b097741ac353dfc2
---
Support for Sundtek TV Tuners (Networkbased and local devices)
The attached patch only adds support for our new tuners which can be
network based or locally. Due the different architecture there is no
need for additional kernel drivers.
The change does not affect legacy devices.
by Markus Rechberger kontakt@sundtek.de
REVIEW:120583
---
--- a/src/dvb/dvbdevice_linux.cpp
+++ b/src/dvb/dvbdevice_linux.cpp
@@ -29,7 +29,15 @@
#include <fcntl.h>
#include <frontend.h>
#include <poll.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <sys/types.h>
#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <sys/inotify.h>
+#include <vector>
+#include <stdlib.h>
#include <unistd.h>
#include "dvbtransponder.h"
@@ -808,15 +816,179 @@
}
}
+struct dvbdev {
+ time_t stctime;
+ char checked;
+ char adapter_name[50];
+ char node_name[75];
+ int adapternum;
+ char lnode[20];
+};
+
+class DvbDeviceMonitor : public QThread
+{
+public:
+ DvbDeviceMonitor(DvbLinuxDeviceManager *ddm)
+ {
+ this->ddm = ddm;
+ }
+ ~DvbDeviceMonitor()
+ {
+ }
+ void run() {
+ DIR *dvbdir, *adapterdirp;
+ struct dirent *dp, *dp2;
+ struct stat stbuf;
+ int adapter;
+ int rescan=0;
+ int rv;
+ int ifd;
+ int found=0;
+ char adapterdir[50];
+ char nodename[75];
+ char buffer[1024];
+ struct pollfd pfd;
+ char firstrun_complete=0;
+ std::vector<struct dvbdev*>adapterlist;
+ std::vector<struct dvbdev*>::iterator iter;
+
+ runstate = 1;
+
+ ifd = inotify_init();
+ inotify_add_watch(ifd, "/dev/dvb", IN_CREATE|IN_DELETE);
+ fcntl(ifd, F_SETFL, O_NONBLOCK);
+ pfd.fd = ifd;
+ pfd.events = POLLIN;
+
+ while(runstate) {
+ if (firstrun_complete) {
+ rv = poll(&pfd, 1, 100);
+ switch (rv) {
+ case -1:
+ break;
+ case 0:
+ continue;
+ default:
+ usleep(100000); /* give it some time to settle down */
+ while(read(ifd, buffer, 1024)>0);
+ break;
+ }
+ } else {
+ firstrun_complete=1;
+ }
+
+ dvbdir = opendir("/dev/dvb");
+ for (iter=adapterlist.begin();iter!=adapterlist.end();iter++) {
+ (*iter)->checked=0;
+ }
+ if (dvbdir) {
+ while((dp=readdir(dvbdir))!= 0) {
+ if (strcmp(dp->d_name, ".") == 0 ||
+ strcmp(dp->d_name, "..") == 0)
+ continue;
+ adapter = strtol(&dp->d_name[7], NULL, 10);
+ sprintf(adapterdir, "/dev/dvb/%s", dp->d_name);
+ adapterdirp = opendir(adapterdir);
+ if (adapterdirp) {
+ while((dp2=readdir(adapterdirp))!=0) {
+ found=0;
+ if (strcmp(dp2->d_name, ".")==0 ||
+ strcmp(dp2->d_name, "..")==0)
+ continue;
+ sprintf(nodename, "/dev/dvb/%s/%s", dp->d_name, dp2->d_name);
+ rv = stat(nodename, &stbuf);
+ for (iter=adapterlist.begin();iter!=adapterlist.end();iter++) {
+ if (strcmp((*iter)->node_name, nodename)==0 && (*iter)->stctime == stbuf.st_ctime) {
+ (*iter)->checked=1;
+ found=1;
+ break;
+ }
+ }
+ if (found == 0) {
+ struct dvbdev *dvbdev = (struct dvbdev*)calloc(1, sizeof(struct dvbdev));
+ dvbdev->checked=1;
+ dvbdev->stctime = stbuf.st_ctime;
+ strcpy(dvbdev->adapter_name, dp->d_name);
+ strcpy(dvbdev->node_name, nodename);
+ dvbdev->adapternum = adapter;
+ strcpy(dvbdev->lnode, dp2->d_name);
+ adapterlist.push_back(dvbdev);
+ ddm->componentAdded(dp2->d_name, adapter, 0);
+ }
+
+ }
+ closedir(adapterdirp);
+ }
+ }
+ closedir(dvbdir);
+ }
+ do {
+ rescan=0;
+ for (iter=adapterlist.begin();iter!=adapterlist.end();iter++) {
+ if ((*iter)->checked==0) {
+ ddm->componentRemoved((*iter)->lnode, (*iter)->adapternum, 0);
+ free(*iter);
+ adapterlist.erase(iter);
+ rescan=1;
+ break;
+ }
+ }
+ } while (rescan!=0);
+ }
+ }
+ void stop() {
+ runstate = 0;
+ wait();
+ }
+private:
+ int runstate;
+ DvbLinuxDeviceManager *ddm;
+};
+
+#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__sun)
+#define MACHADDRESS "/tmp/.mediasocket"
+#else
+#define ADDRESS "/de/sundtek/mediasocket" /* addr to connect */
+#endif
+
DvbLinuxDeviceManager::DvbLinuxDeviceManager(QObject *parent) : QObject(parent)
{
+ int fd;
+ int len;
+ int ret;
+ struct sockaddr_un saun;
QObject *notifier = Solid::DeviceNotifier::instance();
connect(notifier, SIGNAL(deviceAdded(QString)), this, SLOT(componentAdded(QString)));
connect(notifier, SIGNAL(deviceRemoved(QString)), this, SLOT(componentRemoved(QString)));
+
+ memset(&saun, 0x0, sizeof(struct sockaddr_un));
+ fd = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (fd==-1) {
+ monitor = NULL;
+ return;
+ }
+ saun.sun_family = AF_UNIX;
+#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__sun)
+ strcpy(saun.sun_path, MACHADDRESS);
+ len = sizeof(saun.sun_family) + strlen(saun.sun_path)+1;
+#else
+ strcpy(&saun.sun_path[1], ADDRESS);
+ len = sizeof(saun.sun_family) + strlen(&saun.sun_path[1])+1;
+#endif
+ if ((ret=::connect(fd, (struct sockaddr*)&saun, len)) < 0) {
+ close(fd);
+ monitor = NULL;
+ return;
+ }
+ close(fd);
+ monitor = new DvbDeviceMonitor(this);
+ monitor->start();
}
DvbLinuxDeviceManager::~DvbLinuxDeviceManager()
{
+ if (monitor)
+ monitor->stop();
}
void DvbLinuxDeviceManager::doColdPlug()
@@ -824,6 +996,36 @@
foreach (const Solid::Device &device,
Solid::Device::listFromType(Solid::DeviceInterface::DvbInterface)) {
componentAdded(device.udi());
+ }
+}
+
+void DvbLinuxDeviceManager::componentAdded(QString node, int adapter, int index) {
+ int deviceIndex = (adapter << 16) | index;
+ char adapterstring[10];
+ DvbLinuxDevice *device = devices.value(deviceIndex, NULL);
+ if (device == NULL) {
+ device = new DvbLinuxDevice(this);
+ devices.insert(deviceIndex, device);
+ }
+ sprintf(adapterstring, "adapter%d", adapter);
+
+ if (node == "frontend0") {
+ device->frontendPath.sprintf("/dev/dvb/%s/%s", adapterstring, node.toAscii().data());
+ } else if (node == "dvr0") {
+ device->dvrPath.sprintf("/dev/dvb/%s/%s", adapterstring, node.toAscii().data());
+ } else if (node == "demux0") {
+ device->demuxPath.sprintf("/dev/dvb/%s/%s", adapterstring, node.toAscii().data());
+ } else {
+ return;
+ }
+
+ if (!device->demuxPath.isEmpty() && !device->dvrPath.isEmpty() &&
+ !device->frontendPath.isEmpty()) {
+ device->startDevice("");
+
+ if (device->isReady()) {
+ emit deviceAdded(device);
+ }
}
}
@@ -941,6 +1143,31 @@
if (device->isReady()) {
emit deviceAdded(device);
}
+ }
+}
+
+void DvbLinuxDeviceManager::componentRemoved(QString node, int adapter, int index) {
+ int deviceIndex = (adapter << 16) | index;
+ char adapterstring[10];
+ DvbLinuxDevice *device = devices.value(deviceIndex, NULL);
+ if (device == NULL) {
+ return;
+ }
+ sprintf(adapterstring, "adapter%d", adapter);
+ if (node == "frontend0") {
+ device->frontendPath.clear();
+ } else if (node == "dvr0") {
+ device->dvrPath.clear();
+ } else if (node == "demux0") {
+ device->demuxPath.clear();
+ } else {
+ return;
+ }
+
+ if (device->frontendPath.isEmpty() && device->dvrPath.isEmpty() &&
+ device->demuxPath.isEmpty() && device->isReady()) {
+ emit deviceRemoved(device);
+ device->stopDevice();
}
}
--- a/src/dvb/dvbdevice_linux.h
+++ b/src/dvb/dvbdevice_linux.h
@@ -90,6 +90,7 @@
DvbLinuxCam cam;
};
+class DvbDeviceMonitor;
class DvbLinuxDeviceManager : public QObject
{
Q_OBJECT
@@ -97,6 +98,8 @@
explicit DvbLinuxDeviceManager(QObject *parent);
~DvbLinuxDeviceManager();
+ void componentAdded(QString node, int adapter, int index);
+ void componentRemoved(QString node, int adapter, int index);
public slots:
void doColdPlug();
@@ -114,6 +117,7 @@
QMap<int, DvbLinuxDevice *> devices;
QMap<QString, DvbLinuxDevice *> udis;
+ class DvbDeviceMonitor *monitor;
};
#endif /* DVBDEVICE_LINUX_H */