mirror of
https://github.com/DigitalDevices/pvr.octonet.git
synced 2025-03-01 10:53:09 +00:00
Compare commits
28 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d4077a142c | ||
|
|
6ee28476fa | ||
|
|
de0a0f9a81 | ||
|
|
1b0c31654a | ||
|
|
f260cb07e9 | ||
|
|
8549a31c8d | ||
|
|
0a7fb087ac | ||
|
|
5c0f000a91 | ||
|
|
2b020cec9c | ||
|
|
96a19310ca | ||
|
|
3a6f4eb7b5 | ||
|
|
2067aba378 | ||
|
|
b52f50ef30 | ||
|
|
d1f9af2225 | ||
|
|
880d313bef | ||
|
|
94eb166783 | ||
|
|
ba7e50e79c | ||
|
|
5fc6fc2ebc | ||
|
|
8778ebe422 | ||
|
|
0adb1ade91 | ||
|
|
844a5c3cd4 | ||
|
|
838c0094b7 | ||
|
|
c5b90f130b | ||
|
|
415d2c98ac | ||
|
|
2aa320ee2d | ||
|
|
de0bf9c847 | ||
|
|
9abe9180b6 | ||
|
|
4665b282a2 |
@@ -36,7 +36,7 @@ before_install:
|
||||
#
|
||||
before_script:
|
||||
- cd $TRAVIS_BUILD_DIR/..
|
||||
- git clone --depth=1 https://github.com/xbmc/xbmc.git
|
||||
- git clone --depth=1 https://github.com/xbmc/xbmc.git -b Krypton
|
||||
- mkdir -p xbmc/project/cmake/addons/addons/pvr.octonet
|
||||
- echo "pvr.octonet https://github.com/DigitalDevices/pvr.octonet master" > xbmc/project/cmake/addons/addons/pvr.octonet/pvr.octonet.txt
|
||||
- cd $TRAVIS_BUILD_DIR && mkdir build && cd build
|
||||
|
||||
47
README.md
47
README.md
@@ -1,27 +1,40 @@
|
||||
# Octonet PVR
|
||||
DigitalDevices [Octonet] (http://www.digital-devices.eu/shop/de/netzwerk-tv/) PVR client addon for [Kodi] (http://kodi.tv)
|
||||
Digital Devices [Octonet](http://www.digital-devices.eu/shop/de/netzwerk-tv/) PVR client addon for [Kodi](http://kodi.tv)
|
||||
|
||||
| Platform | Status |
|
||||
|----------|--------|
|
||||
| Linux + OS X (Travis) | [](https://travis-ci.org/julianscheel/pvr.octonet) |
|
||||
| Windows (AppVeyor) | [](https://ci.appveyor.com/project/julianscheel/pvr-octonet) |
|
||||
|
||||
# Building
|
||||
|
||||
## Windows
|
||||
1. Create a file `project/cmake/addons/addons/kodi.pvr.octonet/kodi.pvr.octonet.txt` containing a
|
||||
single line `kodi.pvr.octonet file://C:\some\path`. The path doesn't matter and doesn't need to
|
||||
actually exist.
|
||||
These instructions work on all supported platforms for the most part. Obviously, paths need to be
|
||||
adjusted according to your OS (`/` vs `\`). We use Linux paths here as an example.
|
||||
|
||||
2. Use a shell that has environment variables setup by Visual Studio for the native x86 toolchain.
|
||||
Run the following in a new build directory and adjust paths accordingly:
|
||||
Clone the `pvr.octonet` repository:
|
||||
|
||||
```
|
||||
cmake -G "NMake Makefiles" ^
|
||||
-DCMAKE_BUILD_TYPE=Release ^
|
||||
-DADDONS_TO_BUILD="kodi.pvr.octonet" ^
|
||||
-DADDON_SRC_PREFIX="path_to_where_kodi.pvr.octonet_is" ^
|
||||
-DCMAKE_INSTALL_PREFIX="some_subdirectory" ^
|
||||
-DPACKAGE_ZIP=ON ^
|
||||
"path_to_kodi\project\cmake\addons"
|
||||
$ git clone https://github.com/DigitalDevices/pvr.octonet.git
|
||||
```
|
||||
|
||||
Make sure `ADDON_SRC_PREFIX` points to the parent directory of `kodi.pvr.octonet`.
|
||||
Clone the Kodi repository:
|
||||
|
||||
4. Build the addon by running `nmake`. Run `nmake package-addons` to package a zip file of the
|
||||
addon.
|
||||
```
|
||||
$ git clone https://github.com/xbmc/xbmc.git
|
||||
```
|
||||
|
||||
If you already have a local Kodi checkout, you can use that one. Just make sure it is recent enough
|
||||
(Kodi 17 Beta 5 or later should work).
|
||||
|
||||
```
|
||||
$ cd pvr.octonet
|
||||
$ mkdir build
|
||||
$ cd build
|
||||
$ cmake -DCMAKE_BUILD_TYPE=Release -DADDONS_TO_BUILD="pvr.octonet" -DADDON_SRC_PREFIX="path to parent of pvr.octonet" -DCMAKE_INSTALL_PREFIX="install" -DPACKAGE_ZIP=ON "path to kodi/project/cmake/addons"
|
||||
```
|
||||
|
||||
On Windows, you should add `-G "NMake Makefiles"` to the CMake invocation. Make sure that
|
||||
`ADDON_SRC_PREFIX` does _not_ point directly to `pvr.octonet` but instead to its parent directory.
|
||||
|
||||
Finally, build the plugin with `make` (or `nmake` on Windows). The plugin should be in an `install`
|
||||
subdirectory.
|
||||
|
||||
@@ -21,15 +21,20 @@ environment:
|
||||
- GENERATOR: "Visual Studio 14"
|
||||
CONFIG: Release
|
||||
|
||||
artifacts:
|
||||
- path: build/install/
|
||||
name: pvr.octonet
|
||||
type: zip
|
||||
|
||||
build_script:
|
||||
- cd ..
|
||||
- set ROOT=%cd%
|
||||
- git clone --depth=1 https://github.com/xbmc/xbmc.git
|
||||
- git clone --depth=1 https://github.com/xbmc/xbmc.git -b Krypton
|
||||
- mkdir xbmc\project\cmake\addons\addons\pvr.octonet
|
||||
- echo pvr.octonet https://github.com/DigitalDevices/pvr.octonet master > xbmc\project\cmake\addons\addons\pvr.octonet\pvr.octonet.txt
|
||||
- cd %ADDON%
|
||||
- mkdir build
|
||||
- cd build
|
||||
# Must use absolute path for cmake to build depends correctly
|
||||
- cmake -G "%GENERATOR%" -DADDONS_TO_BUILD=%ADDON% -DCMAKE_BUILD_TYPE=%CONFIG% -DADDON_SRC_PREFIX=%ROOT% -DCMAKE_INSTALL_PREFIX=%ROOT%\xbmc\addons -DPACKAGE_ZIP=1 %ROOT%\xbmc\project\cmake\addons
|
||||
- cmake -G "%GENERATOR%" -DADDONS_TO_BUILD=%ADDON% -DCMAKE_BUILD_TYPE=%CONFIG% -DADDON_SRC_PREFIX=%ROOT% -DCMAKE_INSTALL_PREFIX=install -DPACKAGE_ZIP=1 %ROOT%\xbmc\project\cmake\addons
|
||||
- cmake --build . --config %CONFIG%
|
||||
|
||||
7
debian/changelog.in
vendored
Normal file
7
debian/changelog.in
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
kodi-pvr-octonet (#PACKAGEVERSION#-#TAGREV#~#DIST#) #DIST#; urgency=low
|
||||
|
||||
[ kodi ]
|
||||
* autogenerated dummy changelog
|
||||
|
||||
-- Nobody <nobody@kodi.tv> Sat, 01 Jun 2013 00:59:22 +0200
|
||||
|
||||
1
debian/compat
vendored
Normal file
1
debian/compat
vendored
Normal file
@@ -0,0 +1 @@
|
||||
9
|
||||
22
debian/control
vendored
Normal file
22
debian/control
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
Source: kodi-pvr-octonet
|
||||
Priority: extra
|
||||
Maintainer: Julian Scheel <julian@jusst.de>
|
||||
Build-Depends: debhelper (>= 9.0.0), cmake, libjsoncpp-dev, kodi-pvr-dev,
|
||||
libkodiplatform-dev (>= 16.0.0), kodi-addon-dev
|
||||
Standards-Version: 3.9.4
|
||||
Section: libs
|
||||
Homepage: https://github.com/DigitalDevices/pvr.octonet
|
||||
|
||||
Package: kodi-pvr-octonet
|
||||
Section: libs
|
||||
Architecture: any
|
||||
Depends: ${shlibs:Depends}, ${misc:Depends}
|
||||
Description: Digital Devices Octopus NET PVR for Kodi
|
||||
Digital Devices Octopus NET PVR for Kodi
|
||||
|
||||
Package: kodi-pvr-octonet-dbg
|
||||
Section: libs
|
||||
Architecture: any
|
||||
Depends: ${shlibs:Depends}, ${misc:Depends}
|
||||
Description: debug symbols for Digital Devices Octopus NET PVR for Kodi
|
||||
debug symbols for Digital Devices Octopus NET PVR for Kodi
|
||||
46
debian/copyright
vendored
Normal file
46
debian/copyright
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
Format: http://dep.debian.net/deps/dep5
|
||||
Upstream-Name: pvr.octonet
|
||||
Source: https://github.com/DigitalDevices/pvr.octonet
|
||||
|
||||
Files: *
|
||||
Copyright: 2015-2016 Julian Scheel
|
||||
2015-2016 jusst technologies GmbH
|
||||
2005-2013 Team XBMC
|
||||
License: GPL-2+
|
||||
This package is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
.
|
||||
This package is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
.
|
||||
On Debian systems, the complete text of the GNU General
|
||||
Public License version 2 can be found in "/usr/share/common-licenses/GPL-2".
|
||||
|
||||
Files: debian/*
|
||||
Copyright: 2016 Julian Scheel <julian@jusst.de>
|
||||
2015 Jean-Luc Barriere
|
||||
2015 wsnipex <wsnipex@a1.net>
|
||||
License: GPL-2+
|
||||
This package is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
.
|
||||
This package is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
.
|
||||
On Debian systems, the complete text of the GNU General
|
||||
Public License version 2 can be found in "/usr/share/common-licenses/GPL-2".
|
||||
|
||||
2
debian/kodi-pvr-octonet.install
vendored
Normal file
2
debian/kodi-pvr-octonet.install
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
usr/lib/
|
||||
usr/share/
|
||||
24
debian/rules
vendored
Executable file
24
debian/rules
vendored
Executable file
@@ -0,0 +1,24 @@
|
||||
#!/usr/bin/make -f
|
||||
# -*- makefile -*-
|
||||
# Sample debian/rules that uses debhelper.
|
||||
# This file was originally written by Joey Hess and Craig Small.
|
||||
# As a special exception, when this file is copied by dh-make into a
|
||||
# dh-make output file, you may use that output file without restriction.
|
||||
# This special exception was added by Craig Small in version 0.37 of dh-make.
|
||||
|
||||
# Uncomment this to turn on verbose mode.
|
||||
#export DH_VERBOSE=1
|
||||
|
||||
%:
|
||||
dh $@
|
||||
|
||||
override_dh_auto_configure:
|
||||
# USE_LTO breaks build
|
||||
dh_auto_configure -- -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=1
|
||||
|
||||
override_dh_strip:
|
||||
dh_strip -pkodi-pvr-octonet --dbg-package=kodi-pvr-octonet-dbg
|
||||
|
||||
override_dh_installdocs:
|
||||
dh_installdocs --link-doc=kodi-pvr-octonet
|
||||
|
||||
1
debian/source/format
vendored
Normal file
1
debian/source/format
vendored
Normal file
@@ -0,0 +1 @@
|
||||
3.0 (quilt)
|
||||
@@ -1,12 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<addon
|
||||
id="pvr.octonet"
|
||||
version="0.3"
|
||||
name="PVR DigitalDevices Octonet Client"
|
||||
version="0.3.7"
|
||||
name="Digital Devices Octopus NET Client"
|
||||
provider-name="digitaldevices">
|
||||
<requires>
|
||||
<c-pluff version="0.1" />
|
||||
<import addon="xbmc.pvr" version="5.2.0" />
|
||||
<import addon="xbmc.pvr" version="5.2.1" />
|
||||
</requires>
|
||||
<extension
|
||||
point="xbmc.pvrclient"
|
||||
@@ -16,8 +16,8 @@
|
||||
library_windx="pvr.octonet.dll"
|
||||
library_android="libpvr.octonet.so" />
|
||||
<extension point="xbmc.addon.metadata">
|
||||
<summary lang="de_DE">Kodi PVR Addon für DigitalDevices Octonet Streams</summary>
|
||||
<summary lang="en_US">Kodi PVR Addon for DigitalDevices Octonet Streams</summary>
|
||||
<summary lang="de_DE">Kodi PVR Addon für Digital Devices Octopus NET Streams</summary>
|
||||
<summary lang="en_US">Kodi PVR Addon for Digital Devices Octopus NET Streams</summary>
|
||||
<platform>all</platform>
|
||||
</extension>
|
||||
</addon>
|
||||
|
||||
@@ -19,3 +19,7 @@ msgstr ""
|
||||
msgctxt "#30000"
|
||||
msgid "Octonet Server Address"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "#30001"
|
||||
msgid "Could not load chanellist"
|
||||
msgstr ""
|
||||
|
||||
@@ -19,3 +19,7 @@ msgstr ""
|
||||
msgctxt "#30000"
|
||||
msgid "Octonet Server Address"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "#30001"
|
||||
msgid "Could not load chanellist"
|
||||
msgstr ""
|
||||
|
||||
@@ -41,8 +41,8 @@ OctonetData::OctonetData()
|
||||
groups.clear();
|
||||
lastEpgLoad = 0;
|
||||
|
||||
if (loadChannelList())
|
||||
kodi->QueueNotification(QUEUE_INFO, "%d channels loaded.", channels.size());
|
||||
if (!loadChannelList())
|
||||
kodi->QueueNotification(QUEUE_ERROR, kodi->GetLocalizedString(30001), channels.size());
|
||||
}
|
||||
|
||||
OctonetData::~OctonetData(void)
|
||||
@@ -53,14 +53,8 @@ OctonetData::~OctonetData(void)
|
||||
|
||||
int64_t OctonetData::parseID(std::string id)
|
||||
{
|
||||
int64_t nativeId;
|
||||
size_t strip;
|
||||
/* Strip colons from id */
|
||||
while ((strip = id.find(":")) != std::string::npos)
|
||||
id.erase(strip, 1);
|
||||
|
||||
std::stringstream ids(id);
|
||||
ids >> nativeId;
|
||||
std::hash<std::string> hash_fn;
|
||||
int64_t nativeId = hash_fn(id);
|
||||
|
||||
return nativeId;
|
||||
}
|
||||
@@ -125,7 +119,6 @@ OctonetChannel* OctonetData::findChannel(int64_t nativeId)
|
||||
time_t OctonetData::parseDateTime(std::string date)
|
||||
{
|
||||
struct tm timeinfo;
|
||||
time_t time;
|
||||
|
||||
memset(&timeinfo, 0, sizeof(timeinfo));
|
||||
|
||||
@@ -237,20 +230,23 @@ PVR_ERROR OctonetData::getChannels(ADDON_HANDLE handle, bool bRadio)
|
||||
|
||||
PVR_ERROR OctonetData::getEPG(ADDON_HANDLE handle, const PVR_CHANNEL &channel, time_t start, time_t end)
|
||||
{
|
||||
bool needs_reload = false;
|
||||
for (unsigned int i = 0; i < channels.size(); i++)
|
||||
{
|
||||
OctonetChannel &chan = channels.at(i);
|
||||
if (channel.iUniqueId != chan.id)
|
||||
continue;
|
||||
|
||||
if(chan.epg.empty()) {
|
||||
loadEPG();
|
||||
}
|
||||
|
||||
// FIXME: Check if reload is needed!?
|
||||
|
||||
std::vector<OctonetEpgEntry>::iterator it;
|
||||
time_t last_end = 0;
|
||||
for (it = chan.epg.begin(); it < chan.epg.end(); ++it) {
|
||||
if (end > last_end)
|
||||
last_end = end;
|
||||
for (it = chan.epg.begin(); it != chan.epg.end(); ++it) {
|
||||
if (it->end > last_end)
|
||||
last_end = it->end;
|
||||
|
||||
if (it->end < start || it->start > end) {
|
||||
continue;
|
||||
@@ -271,6 +267,24 @@ PVR_ERROR OctonetData::getEPG(ADDON_HANDLE handle, const PVR_CHANNEL &channel, t
|
||||
|
||||
if (last_end < end)
|
||||
loadEPG();
|
||||
|
||||
for (it = chan.epg.begin(); it != chan.epg.end(); ++it) {
|
||||
if (it->end < start || it->start > end) {
|
||||
continue;
|
||||
}
|
||||
|
||||
EPG_TAG entry;
|
||||
memset(&entry, 0, sizeof(EPG_TAG));
|
||||
|
||||
entry.iChannelNumber = i;
|
||||
entry.iUniqueBroadcastId = it->id;
|
||||
entry.strTitle = it->title.c_str();
|
||||
entry.strPlotOutline = it->subtitle.c_str();
|
||||
entry.startTime = it->start;
|
||||
entry.endTime = it->end;
|
||||
|
||||
pvr->TransferEpgEntry(handle, &entry);
|
||||
}
|
||||
}
|
||||
|
||||
return PVR_ERROR_NO_ERROR;
|
||||
@@ -286,6 +300,16 @@ const std::string& OctonetData::getUrl(int id) const {
|
||||
return channels[0].url;
|
||||
}
|
||||
|
||||
const std::string& OctonetData::getName(int id) const {
|
||||
for(std::vector<OctonetChannel>::const_iterator iter = channels.begin(); iter != channels.end(); ++iter) {
|
||||
if(iter->id == id) {
|
||||
return iter->name;
|
||||
}
|
||||
}
|
||||
|
||||
return channels[0].name;
|
||||
}
|
||||
|
||||
int OctonetData::getGroupCount(void)
|
||||
{
|
||||
return groups.size();
|
||||
|
||||
@@ -71,6 +71,7 @@ class OctonetData : public P8PLATFORM::CThread
|
||||
|
||||
virtual PVR_ERROR getEPG(ADDON_HANDLE handle, const PVR_CHANNEL &channel, time_t start, time_t end);
|
||||
const std::string& getUrl(int id) const;
|
||||
const std::string& getName(int id) const;
|
||||
|
||||
protected:
|
||||
virtual bool loadChannelList(void);
|
||||
|
||||
@@ -157,7 +157,7 @@ PVR_ERROR GetAddonCapabilities(PVR_ADDON_CAPABILITIES *pCapabilities)
|
||||
|
||||
const char* GetBackendName(void)
|
||||
{
|
||||
return "DigitalDevice Octonet PVR Addon";
|
||||
return "Digital Devices Octopus NET Client";
|
||||
}
|
||||
|
||||
const char* GetBackendVersion(void)
|
||||
@@ -249,7 +249,7 @@ PVR_ERROR UpdateTimer(const PVR_TIMER& timer) { return PVR_ERROR_NOT_IMPLEMENTED
|
||||
/* entirely unused, as we use standard RTSP+TS mux, which can be handlded by
|
||||
* Kodi core */
|
||||
bool OpenLiveStream(const PVR_CHANNEL& channel) {
|
||||
return rtsp_open(data->getUrl(channel.iUniqueId));
|
||||
return rtsp_open(data->getName(channel.iUniqueId), data->getUrl(channel.iUniqueId));
|
||||
}
|
||||
|
||||
int ReadLiveStream(unsigned char* pBuffer, unsigned int iBufferSize) {
|
||||
@@ -270,7 +270,12 @@ bool SwitchChannel(const PVR_CHANNEL& channel) {
|
||||
return OpenLiveStream(channel);
|
||||
}
|
||||
|
||||
PVR_ERROR SignalStatus(PVR_SIGNAL_STATUS& signalStatus) { return PVR_ERROR_NOT_IMPLEMENTED; }
|
||||
PVR_ERROR SignalStatus(PVR_SIGNAL_STATUS& signalStatus) {
|
||||
memset(&signalStatus, 0, sizeof(PVR_SIGNAL_STATUS));
|
||||
rtsp_fill_signal_status(signalStatus);
|
||||
return PVR_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
const char* GetLiveStreamURL(const PVR_CHANNEL& channel) { return NULL; }
|
||||
PVR_ERROR GetStreamProperties(PVR_STREAM_PROPERTIES* pProperties) { return PVR_ERROR_NOT_IMPLEMENTED; }
|
||||
|
||||
@@ -297,7 +302,7 @@ bool CanSeekStream() { return false; }
|
||||
|
||||
/* Callbacks */
|
||||
void PauseStream(bool bPaused) {}
|
||||
bool SeekTime(int time, bool backwards, double *startpts) { return false; }
|
||||
bool SeekTime(double time, bool backwards, double *startpts) { return false; }
|
||||
void SetSpeed(int speed) {}
|
||||
PVR_ERROR SetEPGTimeFrame(int) { return PVR_ERROR_NOT_IMPLEMENTED; }
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@ int asprintf(char **sptr, char *fmt, ...) {
|
||||
#define KEEPALIVE_INTERVAL 60
|
||||
#define KEEPALIVE_MARGIN 5
|
||||
#define UDP_ADDRESS_LEN 16
|
||||
#define RTCP_BUFFER_SIZE 1024
|
||||
|
||||
using namespace std;
|
||||
using namespace ADDON;
|
||||
@@ -66,12 +67,17 @@ struct rtsp_client {
|
||||
|
||||
Socket tcp_sock;
|
||||
Socket udp_sock;
|
||||
Socket rtcp_sock;
|
||||
|
||||
enum rtsp_state state;
|
||||
int cseq;
|
||||
|
||||
size_t fifo_size;
|
||||
uint16_t last_seq_nr;
|
||||
|
||||
string name;
|
||||
int level;
|
||||
int quality;
|
||||
};
|
||||
|
||||
struct url {
|
||||
@@ -81,6 +87,16 @@ struct url {
|
||||
string path;
|
||||
};
|
||||
|
||||
struct rtcp_app {
|
||||
uint8_t subtype;
|
||||
uint8_t pt;
|
||||
uint16_t len;
|
||||
uint32_t ssrc;
|
||||
char name[4];
|
||||
uint16_t identifier;
|
||||
uint16_t string_len;
|
||||
};
|
||||
|
||||
static rtsp_client *rtsp = NULL;
|
||||
|
||||
static url parse_url(const std::string& str) {
|
||||
@@ -109,6 +125,16 @@ static url parse_url(const std::string& str) {
|
||||
return result;
|
||||
}
|
||||
|
||||
void split_string(const string& s, char delim, vector<string>& elems) {
|
||||
stringstream ss;
|
||||
ss.str(s);
|
||||
|
||||
string item;
|
||||
while(getline(ss, item, delim)) {
|
||||
elems.push_back(item);
|
||||
}
|
||||
}
|
||||
|
||||
static int tcp_sock_read_line(string &line) {
|
||||
static string buf;
|
||||
|
||||
@@ -266,7 +292,7 @@ static enum rtsp_result rtsp_handle() {
|
||||
return (enum rtsp_result)rtsp_result;
|
||||
}
|
||||
|
||||
bool rtsp_open(const string& url_str)
|
||||
bool rtsp_open(const string& name, const string& url_str)
|
||||
{
|
||||
string setup_url_str;
|
||||
const char *psz_setup_url;
|
||||
@@ -279,6 +305,10 @@ bool rtsp_open(const string& url_str)
|
||||
if (rtsp == NULL)
|
||||
return false;
|
||||
|
||||
rtsp->name = name;
|
||||
rtsp->level = 0;
|
||||
rtsp->quality = 0;
|
||||
|
||||
kodi->Log(LOG_DEBUG, "try to open '%s'", url_str.c_str());
|
||||
|
||||
url dst = parse_url(url_str);
|
||||
@@ -342,6 +372,14 @@ bool rtsp_open(const string& url_str)
|
||||
goto error;
|
||||
}
|
||||
|
||||
rtsp->rtcp_sock = Socket(af_inet, pf_inet, sock_dgram, udp);
|
||||
if(!rtsp->rtcp_sock.bind(rtsp->udp_port + 1)) {
|
||||
goto error;
|
||||
}
|
||||
if(!rtsp->rtcp_sock.set_non_blocking(true)) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
error:
|
||||
@@ -349,11 +387,49 @@ error:
|
||||
return false;
|
||||
}
|
||||
|
||||
static void parse_rtcp(const char *buf, int size) {
|
||||
int offset = 0;
|
||||
while(size > 4) {
|
||||
const rtcp_app *app = reinterpret_cast<const rtcp_app *>(buf + offset);
|
||||
uint16_t len = 4 * (ntohs(app->len) + 1);
|
||||
|
||||
if((app->pt != 204) || (memcmp(app->name, "SES1", 4) != 0)) {
|
||||
size -= len;
|
||||
offset += len;
|
||||
continue;
|
||||
}
|
||||
|
||||
uint16_t string_len = ntohs(app->string_len);
|
||||
string app_data(&buf[offset + sizeof(rtcp_app)], string_len);
|
||||
|
||||
vector<string> elems;
|
||||
split_string(app_data, ';', elems);
|
||||
if(elems.size() != 4) {
|
||||
return;
|
||||
}
|
||||
|
||||
vector<string> tuner;
|
||||
split_string(elems[2], ',', tuner);
|
||||
if(tuner.size() < 4) {
|
||||
return;
|
||||
}
|
||||
|
||||
rtsp->level = atoi(tuner[1].c_str());
|
||||
rtsp->quality = atoi(tuner[3].c_str());
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int rtsp_read(void *buf, unsigned buf_size) {
|
||||
sockaddr addr;
|
||||
socklen_t addr_len = sizeof(addr);
|
||||
int ret = rtsp->udp_sock.recvfrom((char *)buf, buf_size, (sockaddr *)&addr, &addr_len);
|
||||
|
||||
char rtcp_buf[RTCP_BUFFER_SIZE];
|
||||
int rtcp_len = rtsp->rtcp_sock.recvfrom(rtcp_buf, RTCP_BUFFER_SIZE, (sockaddr *)&addr, &addr_len);
|
||||
parse_rtcp(rtcp_buf, rtcp_len);
|
||||
|
||||
// TODO: check ip
|
||||
|
||||
return ret;
|
||||
@@ -389,7 +465,16 @@ void rtsp_close()
|
||||
rtsp_teardown();
|
||||
rtsp->tcp_sock.close();
|
||||
rtsp->udp_sock.close();
|
||||
rtsp->rtcp_sock.close();
|
||||
delete rtsp;
|
||||
rtsp = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void rtsp_fill_signal_status(PVR_SIGNAL_STATUS& signal_status) {
|
||||
if(rtsp) {
|
||||
strncpy(signal_status.strServiceName, rtsp->name.c_str(), PVR_ADDON_NAME_STRING_LENGTH - 1);
|
||||
signal_status.iSNR = 0x1111 * rtsp->quality;
|
||||
signal_status.iSignal = 0x101 * rtsp->level;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,9 +2,11 @@
|
||||
#define _RTSP_CLIENT_HPP_
|
||||
|
||||
#include <string>
|
||||
#include <xbmc_pvr_types.h>
|
||||
|
||||
bool rtsp_open(const std::string& url_str);
|
||||
bool rtsp_open(const std::string& name, const std::string& url_str);
|
||||
void rtsp_close();
|
||||
int rtsp_read(void *buf, unsigned buf_size);
|
||||
void rtsp_fill_signal_status(PVR_SIGNAL_STATUS& signal_status);
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user