Compare commits

...

43 Commits

Author SHA1 Message Date
Kai Sommerfeld
203f800eaa Merge pull request #22 from ksooo/jenkinsfile
Add Jenkinsfile to allow Kodi CI to build this addon.
2018-10-16 13:50:33 +02:00
Kai Sommerfeld
153dfeb3d5 Add Jenkinsfile to allow Kodi CI to build this addon. 2018-10-16 13:44:19 +02:00
Kai Sommerfeld
1e44819300 PVR API 5.10.0 2018-06-09 11:07:51 +02:00
René Bühlmann
54680a38bd PVR API 5.9.0 2018-04-11 14:42:04 +02:00
Kai Sommerfeld
689afbf4cd PVR API 5.8.0 2018-01-15 07:27:07 +01:00
Rechi
c4af00a4fe [depends] bump jsoncpp to 1.8.3 2017-11-15 12:41:33 +01:00
Anton Fedchin
f1f8d44b78 win10: fix linkage to deprecated wsock32 api. 2017-11-02 09:06:58 +01:00
Kai Sommerfeld
e9b4c05de5 Update to PVR API version 5.7.0 2017-09-26 14:17:23 +02:00
Kai Sommerfeld
a77cf111bb Added minimalistic support for PVR Addon API 5.3.0 2017-07-10 08:55:26 +02:00
Julian Scheel
020dd98e7b OctonetData: Use hash for channel nativeId
We previously assumed that the channelId provided by the Octonet would
only contain numbers and colons, which unfortunately is not true. The
satellite names could contain arbitrary characters, which then caused
the conversion to a numeric value to fail, stopping channels from being
distinguishable. This caused all EPG events to be mapped to the first
channel.

Signed-off-by: Julian Scheel <julian@jusst.de>
2017-07-06 14:32:14 +02:00
Julian Scheel
d7bb865329 AppVeyor: Provide built addon as artifact
Allow users to fetch the builds generated by AppVeyor.

Signed-off-by: Julian Scheel <julian@jusst.de>
2017-07-06 14:32:04 +02:00
Julian Scheel
9bbd7cf3c4 README: Update build path
Reflect relocation of cmake script in Kodi master.

Signed-off-by: Julian Scheel <julian@jusst.de>
2017-05-26 11:04:27 +02:00
Julian Scheel
7b9ec7d884 Travis: Update build instructions for Kodi master
The cmake build files for addons have been moved inside the kodi tree.
Update the Travis build script to reflect this.

Signed-off-by: Julian Scheel <julian@jusst.de>
2017-05-26 10:59:36 +02:00
Julian Scheel
37abebb540 AppVeyor: Update build instructions for Kodi master
The cmake build files for addons have been moved inside the kodi tree.
Update the AppVeyor build script to reflect this.

Signed-off-by: Julian Scheel <julian@jusst.de>
2017-05-26 10:58:35 +02:00
Alwin Esch
3494c4c470 Update on kodi to addon interface 2017-05-23 12:23:33 +02:00
Alwin Esch
ff41fc9acc update debian control 2017-05-18 12:04:46 +02:00
Alwin Esch
1ced6b3fa4 remove no more needed version functions 2017-05-18 12:04:46 +02:00
Alwin Esch
cd774b6edc change to automatic depends set on addon.xml 2017-05-18 12:04:46 +02:00
Alwin Esch
2a63777b6d libXBMC_codec.h removed and changed to libXBMC_pvr.h also fix compile fault after last request 2017-05-03 09:48:00 +02:00
Alwin Esch
e9f0d6bf76 Remove not used part 2017-05-03 09:47:39 +02:00
Dennis Hamester
8549a31c8d Bump version to 0.3.6 2016-11-28 15:09:54 +01:00
Dennis Hamester
0a7fb087ac Bump pvr api version to 5.2.1 2016-11-28 15:09:25 +01:00
Dennis Hamester
5c0f000a91 Bump version to 0.3.5 2016-11-28 14:14:57 +01:00
Dennis Hamester
2b020cec9c README: Rewrite build instructions 2016-11-28 14:00:01 +01:00
Dennis Hamester
96a19310ca Change time parameter of SeekTime from int to double
See xbmc/xbmc#10985
2016-11-28 10:40:36 +01:00
Dennis Hamester
3a6f4eb7b5 Bump version to 0.3.4 2016-11-18 10:28:37 +01:00
Dennis Hamester
2067aba378 OctonetData: Remove unused variable 2016-11-16 12:32:36 +01:00
Dennis Hamester
b52f50ef30 OctonetData: Fix missing EPG data for the first channel 2016-11-16 12:31:27 +01:00
Dennis Hamester
d1f9af2225 OctonetData: Fix computing last_end in getEPG() 2016-11-14 11:36:51 +01:00
Julian Scheel
880d313bef Unify Digital Devices naming
Always write Digital Devices with a blank in between.

Signed-off-by: Julian Scheel <julian@jusst.de>
2016-11-11 20:49:27 +01:00
Julian Scheel
94eb166783 README: Add AppVeyor badge
Add a badge for AppVeyor (Windows) build status.

Signed-off-by: Julian Scheel <julian@jusst.de>
2016-11-10 17:54:14 +01:00
Dennis Hamester
ba7e50e79c client: Clear incoming signalStatus before filling it 2016-11-10 17:23:47 +01:00
Julian Scheel
5fc6fc2ebc README: Add build status
Signed-off-by: Julian Scheel <julian@jusst.de>
2016-11-10 17:20:24 +01:00
Julian Scheel
8778ebe422 Increment version to 0.3.1
Signed-off-by: Julian Scheel <julian@jusst.de>
2016-11-10 14:05:46 +01:00
Dennis Hamester
0adb1ade91 Pass channel name to rtsp_client 2016-11-10 11:33:56 +01:00
Dennis Hamester
844a5c3cd4 OctonetData: Add getter for channel name 2016-11-10 11:27:31 +01:00
Dennis Hamester
838c0094b7 Pass signal quality and snr to Kodi core 2016-11-10 10:52:33 +01:00
Dennis Hamester
c5b90f130b rtsp_client: Parse RTCP APP packets 2016-11-09 15:40:40 +01:00
Dennis Hamester
415d2c98ac rtsp_client: Open and close rtcp socket as well 2016-11-09 15:32:39 +01:00
Julian Scheel
2aa320ee2d Add debian package build files
Signed-off-by: Julian Scheel <julian@jusst.de>
2016-11-09 10:24:25 +01:00
Julian Scheel
de0bf9c847 Increment version to 0.3.1
Signed-off-by: Julian Scheel <julian@jusst.de>
2016-11-08 11:15:45 +01:00
Julian Scheel
9abe9180b6 Notify on channel load error not success
Do not queue a notification when loading channels was successful, but
only when it failed. While at it make the message string translatable.

Signed-off-by: Julian Scheel <julian@jusst.de>
2016-11-08 11:14:24 +01:00
Julian Scheel
4665b282a2 Unify naming and fix typo
Use same addon names in client.cpp and addon.xml.

Signed-off-by: Julian Scheel <julian@jusst.de>
2016-11-08 08:35:48 +01:00
26 changed files with 379 additions and 158 deletions

1
.gitignore vendored
View File

@@ -1 +1,2 @@
/build
pvr.octonet/addon.xml

View File

@@ -37,9 +37,9 @@ before_install:
before_script:
- cd $TRAVIS_BUILD_DIR/..
- git clone --depth=1 https://github.com/xbmc/xbmc.git
- 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
- mkdir -p xbmc/cmake/addons/addons/pvr.octonet
- echo "pvr.octonet https://github.com/DigitalDevices/pvr.octonet master" > xbmc/cmake/addons/addons/pvr.octonet/pvr.octonet.txt
- cd $TRAVIS_BUILD_DIR && mkdir build && cd build
- cmake -DADDONS_TO_BUILD=pvr.octonet -DADDON_SRC_PREFIX=$TRAVIS_BUILD_DIR/.. -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$TRAVIS_BUILD_DIR/../xbmc/addons -DPACKAGE_ZIP=1 $TRAVIS_BUILD_DIR/../xbmc/project/cmake/addons
- cmake -DADDONS_TO_BUILD=pvr.octonet -DADDON_SRC_PREFIX=$TRAVIS_BUILD_DIR/.. -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$TRAVIS_BUILD_DIR/../xbmc/addons -DPACKAGE_ZIP=1 $TRAVIS_BUILD_DIR/../xbmc/cmake/addons
script: make

View File

@@ -26,10 +26,19 @@ set(OCTONET_SOURCES
src/Socket.cpp
src/rtsp_client.cpp)
set(OCTONET_HEADERS
src/client.h
src/OctonetData.h
src/Socket.h)
build_addon(pvr.octonet OCTONET DEPLIBS)
if(WIN32)
target_link_libraries(pvr.octonet wsock32 ws2_32)
if(NOT CMAKE_SYSTEM_NAME STREQUAL WindowsStore)
target_link_libraries(pvr.octonet wsock32 ws2_32)
else()
target_link_libraries(pvr.octonet ws2_32)
endif()
endif()
include(CPack)

1
Jenkinsfile vendored Normal file
View File

@@ -0,0 +1 @@
buildPlugin()

View File

@@ -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) | [![Build Status](https://travis-ci.org/julianscheel/pvr.octonet.svg?branch=master)](https://travis-ci.org/julianscheel/pvr.octonet) |
| Windows (AppVeyor) | [![Build status](https://ci.appveyor.com/api/projects/status/m7dhmpmuf5coir5h?svg=true)](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/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.

View File

@@ -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
- 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
- mkdir xbmc\cmake\addons\addons\pvr.octonet
- echo pvr.octonet https://github.com/DigitalDevices/pvr.octonet master > xbmc\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\cmake\addons
- cmake --build . --config %CONFIG%

7
debian/changelog.in vendored Normal file
View 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
View File

@@ -0,0 +1 @@
9

22
debian/control vendored Normal file
View 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,
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
View 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
View File

@@ -0,0 +1,2 @@
usr/lib/
usr/share/

24
debian/rules vendored Executable file
View 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
View File

@@ -0,0 +1 @@
3.0 (quilt)

View File

@@ -1,7 +1,10 @@
project(jsoncpp)
cmake_minimum_required(VERSION 2.6)
cmake_minimum_required(VERSION 3.1)
enable_language(CXX)
SET(CMAKE_CXX_STANDARD 11)
SET(CMAKE_CXX_STANDARD_REQUIRED ON)
SET(CMAKE_CXX_EXTENSIONS OFF)
set(SOURCES src/lib_json/json_reader.cpp
src/lib_json/json_value.cpp

View File

@@ -1 +1 @@
jsoncpp http://mirrors.kodi.tv/build-deps/sources/jsoncpp-src-0.5.0.tar.gz
jsoncpp http://mirrors.kodi.tv/build-deps/sources/jsoncpp-1.8.3.tar.gz

View File

@@ -1,23 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<addon
id="pvr.octonet"
version="0.3"
name="PVR DigitalDevices Octonet Client"
provider-name="digitaldevices">
<requires>
<c-pluff version="0.1" />
<import addon="xbmc.pvr" version="5.2.0" />
</requires>
<extension
point="xbmc.pvrclient"
library_linux="pvr.octonet.so"
library_osx="pvr.octonet.dylib"
library_freebsd="pvr.octonet.so"
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>
<platform>all</platform>
</extension>
</addon>

16
pvr.octonet/addon.xml.in Normal file
View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<addon
id="pvr.octonet"
version="0.7.0"
name="Digital Devices Octopus NET Client"
provider-name="digitaldevices">
<requires>@ADDON_DEPENDS@</requires>
<extension
point="xbmc.pvrclient"
library_@PLATFORM@="@LIBRARY_FILENAME@"/>
<extension point="xbmc.addon.metadata">
<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>@PLATFORM@</platform>
</extension>
</addon>

View File

@@ -19,3 +19,7 @@ msgstr ""
msgctxt "#30000"
msgid "Octonet Server Address"
msgstr ""
msgctxt "#30001"
msgid "Could not load chanellist"
msgstr ""

View File

@@ -19,3 +19,7 @@ msgstr ""
msgctxt "#30000"
msgid "Octonet Server Address"
msgstr ""
msgctxt "#30001"
msgid "Could not load chanellist"
msgstr ""

View File

@@ -41,8 +41,8 @@ OctonetData::OctonetData()
groups.clear();
lastEpgLoad = 0;
if (loadChannelList())
kodi->QueueNotification(QUEUE_INFO, "%d channels loaded.", channels.size());
if (!loadChannelList())
libKodi->QueueNotification(QUEUE_ERROR, libKodi->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;
}
@@ -68,15 +62,15 @@ int64_t OctonetData::parseID(std::string id)
bool OctonetData::loadChannelList()
{
std::string jsonContent;
void *f = kodi->OpenFile(("http://" + serverAddress + "/channellist.lua?select=json").c_str(), 0);
void *f = libKodi->OpenFile(("http://" + serverAddress + "/channellist.lua?select=json").c_str(), 0);
if (!f)
return false;
char buf[1024];
while (int read = kodi->ReadFile(f, buf, 1024))
while (int read = libKodi->ReadFile(f, buf, 1024))
jsonContent.append(buf, read);
kodi->CloseFile(f);
libKodi->CloseFile(f);
Json::Value root;
Json::Reader reader;
@@ -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));
@@ -154,15 +147,15 @@ bool OctonetData::loadEPG(void)
return false;
std::string jsonContent;
void *f = kodi->OpenFile(("http://" + serverAddress + "/epg.lua?;#|encoding=gzip").c_str(), 0);
void *f = libKodi->OpenFile(("http://" + serverAddress + "/epg.lua?;#|encoding=gzip").c_str(), 0);
if (!f)
return false;
char buf[1024];
while (int read = kodi->ReadFile(f, buf, 1024))
while (int read = libKodi->ReadFile(f, buf, 1024))
jsonContent.append(buf, read);
kodi->CloseFile(f);
libKodi->CloseFile(f);
Json::Value root;
Json::Reader reader;
@@ -191,7 +184,7 @@ bool OctonetData::loadEPG(void)
channel = findChannel(entry.channelId);
if (channel == NULL) {
kodi->Log(LOG_ERROR, "EPG for unknown channel.");
libKodi->Log(LOG_ERROR, "EPG for unknown channel.");
continue;
}
@@ -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;
@@ -259,7 +255,7 @@ PVR_ERROR OctonetData::getEPG(ADDON_HANDLE handle, const PVR_CHANNEL &channel, t
EPG_TAG entry;
memset(&entry, 0, sizeof(EPG_TAG));
entry.iChannelNumber = i;
entry.iUniqueChannelId = chan.id;
entry.iUniqueBroadcastId = it->id;
entry.strTitle = it->title.c_str();
entry.strPlotOutline = it->subtitle.c_str();
@@ -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.iUniqueChannelId = chan.id;
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();

View File

@@ -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);

View File

@@ -196,13 +196,13 @@ int Socket::send ( const char* data, const unsigned int len )
if (result < 0)
{
kodi->Log(LOG_ERROR, "Socket::send - select failed");
libKodi->Log(LOG_ERROR, "Socket::send - select failed");
close();
return 0;
}
if (FD_ISSET(_sd, &set_w))
{
kodi->Log(LOG_ERROR, "Socket::send - failed to send data");
libKodi->Log(LOG_ERROR, "Socket::send - failed to send data");
close();
return 0;
}
@@ -212,7 +212,7 @@ int Socket::send ( const char* data, const unsigned int len )
if (status == -1)
{
errormessage( getLastError(), "Socket::send");
kodi->Log(LOG_ERROR, "Socket::send - failed to send data");
libKodi->Log(LOG_ERROR, "Socket::send - failed to send data");
close();
return 0;
}
@@ -296,7 +296,7 @@ bool Socket::ReadLine (string& line)
if (result < 0)
{
kodi->Log(LOG_DEBUG, "%s: select failed", __FUNCTION__);
libKodi->Log(LOG_DEBUG, "%s: select failed", __FUNCTION__);
errormessage(getLastError(), __FUNCTION__);
close();
return false;
@@ -306,11 +306,11 @@ bool Socket::ReadLine (string& line)
{
if (retries != 0)
{
kodi->Log(LOG_DEBUG, "%s: timeout waiting for response, retrying... (%i)", __FUNCTION__, retries);
libKodi->Log(LOG_DEBUG, "%s: timeout waiting for response, retrying... (%i)", __FUNCTION__, retries);
retries--;
continue;
} else {
kodi->Log(LOG_DEBUG, "%s: timeout waiting for response. Aborting after 10 retries.", __FUNCTION__);
libKodi->Log(LOG_DEBUG, "%s: timeout waiting for response. Aborting after 10 retries.", __FUNCTION__);
return false;
}
}
@@ -318,7 +318,7 @@ bool Socket::ReadLine (string& line)
result = recv(_sd, buffer, sizeof(buffer) - 1, 0);
if (result < 0)
{
kodi->Log(LOG_DEBUG, "%s: recv failed", __FUNCTION__);
libKodi->Log(LOG_DEBUG, "%s: recv failed", __FUNCTION__);
errormessage(getLastError(), __FUNCTION__);
close();
return false;
@@ -389,7 +389,7 @@ bool Socket::connect ( const std::string& host, const unsigned short port )
if ( !setHostname( host ) )
{
kodi->Log(LOG_ERROR, "Socket::setHostname(%s) failed.\n", host.c_str());
libKodi->Log(LOG_ERROR, "Socket::setHostname(%s) failed.\n", host.c_str());
return false;
}
_port = port;
@@ -438,7 +438,7 @@ bool Socket::connect ( const std::string& host, const unsigned short port )
if (address == NULL)
{
kodi->Log(LOG_ERROR, "Socket::connect %s:%u\n", host.c_str(), port);
libKodi->Log(LOG_ERROR, "Socket::connect %s:%u\n", host.c_str(), port);
errormessage(getLastError(), "Socket::connect");
close();
return false;
@@ -474,7 +474,7 @@ bool Socket::set_non_blocking ( const bool b )
if (ioctlsocket(_sd, FIONBIO, &iMode) == -1)
{
kodi->Log(LOG_ERROR, "Socket::set_non_blocking - Can't set socket condition to: %i", iMode);
libKodi->Log(LOG_ERROR, "Socket::set_non_blocking - Can't set socket condition to: %i", iMode);
return false;
}
@@ -565,7 +565,7 @@ void Socket::errormessage( int errnum, const char* functionname) const
default:
errmsg = "WSA Error";
}
kodi->Log(LOG_ERROR, "%s: (Winsock error=%i) %s\n", functionname, errnum, errmsg);
libKodi->Log(LOG_ERROR, "%s: (Winsock error=%i) %s\n", functionname, errnum, errmsg);
}
int Socket::getLastError() const
@@ -623,7 +623,7 @@ bool Socket::set_non_blocking ( const bool b )
if(fcntl (_sd , F_SETFL, opts) == -1)
{
kodi->Log(LOG_ERROR, "Socket::set_non_blocking - Can't set socket flags to: %i", opts);
libKodi->Log(LOG_ERROR, "Socket::set_non_blocking - Can't set socket flags to: %i", opts);
return false;
}
return true;
@@ -699,7 +699,7 @@ void Socket::errormessage( int errnum, const char* functionname) const
break;
}
kodi->Log(LOG_ERROR, "%s: (errno=%i) %s\n", functionname, errnum, errmsg);
libKodi->Log(LOG_ERROR, "%s: (errno=%i) %s\n", functionname, errnum, errmsg);
}
int Socket::getLastError() const

View File

@@ -36,7 +36,7 @@ std::string octonetAddress = "";
/* internal state variables */
ADDON_STATUS addonStatus = ADDON_STATUS_UNKNOWN;
CHelper_libXBMC_addon *kodi = NULL;
CHelper_libXBMC_addon *libKodi = NULL;
CHelper_libXBMC_pvr *pvr = NULL;
OctonetData *data = NULL;
@@ -49,7 +49,7 @@ extern "C" {
void ADDON_ReadSettings(void)
{
char buffer[2048];
if (kodi->GetSetting("octonetAddress", &buffer))
if (libKodi->GetSetting("octonetAddress", &buffer))
octonetAddress = buffer;
}
@@ -59,22 +59,22 @@ ADDON_STATUS ADDON_Create(void *callbacks, void* props)
return ADDON_STATUS_UNKNOWN;
PVR_PROPERTIES *pvrprops = (PVR_PROPERTIES*)props;
kodi = new CHelper_libXBMC_addon;
if (!kodi->RegisterMe(callbacks)) {
kodi->Log(LOG_ERROR, "%s: Failed to register octonet addon", __func__);
SAFE_DELETE(kodi);
libKodi = new CHelper_libXBMC_addon;
if (!libKodi->RegisterMe(callbacks)) {
libKodi->Log(LOG_ERROR, "%s: Failed to register octonet addon", __func__);
SAFE_DELETE(libKodi);
return ADDON_STATUS_PERMANENT_FAILURE;
}
pvr = new CHelper_libXBMC_pvr;
if (!pvr->RegisterMe(callbacks)) {
kodi->Log(LOG_ERROR, "%s: Failed to register octonet pvr addon", __func__);
libKodi->Log(LOG_ERROR, "%s: Failed to register octonet pvr addon", __func__);
SAFE_DELETE(pvr);
SAFE_DELETE(kodi);
SAFE_DELETE(libKodi);
return ADDON_STATUS_PERMANENT_FAILURE;
}
kodi->Log(LOG_DEBUG, "%s: Creating octonet pvr addon", __func__);
libKodi->Log(LOG_DEBUG, "%s: Creating octonet pvr addon", __func__);
ADDON_ReadSettings();
data = new OctonetData;
@@ -83,12 +83,10 @@ ADDON_STATUS ADDON_Create(void *callbacks, void* props)
return addonStatus;
}
void ADDON_Stop() {} /* no-op */
void ADDON_Destroy()
{
delete pvr;
delete kodi;
delete libKodi;
addonStatus = ADDON_STATUS_UNKNOWN;
}
@@ -97,16 +95,6 @@ ADDON_STATUS ADDON_GetStatus()
return addonStatus;
}
bool ADDON_HasSettings()
{
return true;
}
unsigned int ADDON_GetSettings(ADDON_StructSetting ***sSet)
{
return 0;
}
ADDON_STATUS ADDON_SetSetting(const char *settingName, const void *settingValue)
{
/* For simplicity do a full addon restart whenever settings are
@@ -114,9 +102,6 @@ ADDON_STATUS ADDON_SetSetting(const char *settingName, const void *settingValue)
return ADDON_STATUS_NEED_RESTART;
}
void ADDON_FreeSettings() {} /* no-op */
void ADDON_Announce(const char *flag, const char *sender, const char *message, const void *data) {} /* no-op */
}
@@ -125,44 +110,28 @@ void ADDON_Announce(const char *flag, const char *sender, const char *message, c
extern "C"
{
const char* GetPVRAPIVersion(void)
{
return XBMC_PVR_API_VERSION;
}
const char* GetMininumPVRAPIVersion(void)
{
return XBMC_PVR_MIN_API_VERSION;
}
const char* GetGUIAPIVersion(void)
{
return KODI_GUILIB_API_VERSION;
}
const char* GetMininumGUIAPIVersion(void)
{
return KODI_GUILIB_MIN_API_VERSION;
}
PVR_ERROR GetAddonCapabilities(PVR_ADDON_CAPABILITIES *pCapabilities)
{
pCapabilities->bSupportsTV = true;
pCapabilities->bSupportsRadio = true;
pCapabilities->bSupportsChannelGroups = true;
pCapabilities->bSupportsEPG = true;
pCapabilities->bSupportsRecordings = false;
pCapabilities->bSupportsRecordingsRename = false;
pCapabilities->bSupportsRecordingsLifetimeChange = false;
pCapabilities->bSupportsDescrambleInfo = false;
return PVR_ERROR_NO_ERROR;
}
const char* GetBackendName(void)
{
return "DigitalDevice Octonet PVR Addon";
return "Digital Devices Octopus NET Client";
}
const char* GetBackendVersion(void)
{
return XBMC_PVR_API_VERSION;
return STR(OCTONET_VERSION);
}
const char* GetConnectionString(void)
@@ -174,12 +143,12 @@ PVR_ERROR GetDriveSpace(long long* iTotal, long long* iUsed) { return PVR_ERROR_
PVR_ERROR CallMenuHook(const PVR_MENUHOOK& menuhook, const PVR_MENUHOOK_DATA &item) { return PVR_ERROR_NOT_IMPLEMENTED; }
void OnSystemSleep() {
kodi->Log(LOG_INFO, "Received event: %s", __FUNCTION__);
libKodi->Log(LOG_INFO, "Received event: %s", __FUNCTION__);
// FIXME: Disconnect?
}
void OnSystemWake() {
kodi->Log(LOG_INFO, "Received event: %s", __FUNCTION__);
libKodi->Log(LOG_INFO, "Received event: %s", __FUNCTION__);
// FIXME:Reconnect?
}
@@ -192,6 +161,9 @@ PVR_ERROR GetEPGForChannel(ADDON_HANDLE handle, const PVR_CHANNEL& channel, time
return data->getEPG(handle, channel, iStart, iEnd);
}
PVR_ERROR IsEPGTagRecordable(const EPG_TAG*, bool*) { return PVR_ERROR_NOT_IMPLEMENTED; }
PVR_ERROR IsEPGTagPlayable(const EPG_TAG*, bool*) { return PVR_ERROR_NOT_IMPLEMENTED; }
/* Channel groups */
int GetChannelGroupsAmount(void)
{
@@ -223,7 +195,6 @@ PVR_ERROR GetChannels(ADDON_HANDLE handle, bool bRadio)
PVR_ERROR DeleteChannel(const PVR_CHANNEL& channel) { return PVR_ERROR_NOT_IMPLEMENTED; }
PVR_ERROR RenameChannel(const PVR_CHANNEL& channel) { return PVR_ERROR_NOT_IMPLEMENTED; }
PVR_ERROR MoveChannel(const PVR_CHANNEL& channel) { return PVR_ERROR_NOT_IMPLEMENTED; }
PVR_ERROR OpenDialogChannelSettings(const PVR_CHANNEL& channel) { return PVR_ERROR_NOT_IMPLEMENTED; }
PVR_ERROR OpenDialogChannelAdd(const PVR_CHANNEL& channel) { return PVR_ERROR_NOT_IMPLEMENTED; }
@@ -234,6 +205,7 @@ PVR_ERROR DeleteRecording(const PVR_RECORDING& recording) { return PVR_ERROR_NOT
PVR_ERROR UndeleteRecording(const PVR_RECORDING& recording) { return PVR_ERROR_NOT_IMPLEMENTED; }
PVR_ERROR DeleteAllRecordingsFromTrash() { return PVR_ERROR_NOT_IMPLEMENTED; }
PVR_ERROR RenameRecording(const PVR_RECORDING& recording) { return PVR_ERROR_NOT_IMPLEMENTED; }
PVR_ERROR SetRecordingLifetime(const PVR_RECORDING*) { return PVR_ERROR_NOT_IMPLEMENTED; }
PVR_ERROR SetRecordingPlayCount(const PVR_RECORDING& recording, int count) { return PVR_ERROR_NOT_IMPLEMENTED; }
PVR_ERROR SetRecordingLastPlayedPosition(const PVR_RECORDING& recording, int lastplayedposition) { return PVR_ERROR_NOT_IMPLEMENTED; }
int GetRecordingLastPlayedPosition(const PVR_RECORDING& recording) { return PVR_ERROR_NOT_IMPLEMENTED; }
@@ -245,11 +217,18 @@ PVR_ERROR AddTimer(const PVR_TIMER& timer) { return PVR_ERROR_NOT_IMPLEMENTED; }
PVR_ERROR DeleteTimer(const PVR_TIMER& timer, bool bForceDelete) { return PVR_ERROR_NOT_IMPLEMENTED; }
PVR_ERROR UpdateTimer(const PVR_TIMER& timer) { return PVR_ERROR_NOT_IMPLEMENTED; }
/* PVR stream properties handling */
PVR_ERROR GetStreamReadChunkSize(int* chunksize) { return PVR_ERROR_NOT_IMPLEMENTED; }
PVR_ERROR GetChannelStreamProperties(const PVR_CHANNEL*, PVR_NAMED_VALUE*, unsigned int*) { return PVR_ERROR_NOT_IMPLEMENTED; }
PVR_ERROR GetRecordingStreamProperties(const PVR_RECORDING*, PVR_NAMED_VALUE*, unsigned int*) { return PVR_ERROR_NOT_IMPLEMENTED; }
PVR_ERROR GetEPGTagStreamProperties(const EPG_TAG*, PVR_NAMED_VALUE*, unsigned int*) { return PVR_ERROR_NOT_IMPLEMENTED; }
PVR_ERROR GetEPGTagEdl(const EPG_TAG* epgTag, PVR_EDL_ENTRY edl[], int *size) { return PVR_ERROR_NOT_IMPLEMENTED; }
/* PVR stream handling */
/* 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) {
@@ -261,25 +240,24 @@ void CloseLiveStream(void) {
}
long long SeekLiveStream(long long iPosition, int iWhence) { return -1; }
long long PositionLiveStream(void) { return -1; }
long long LengthLiveStream(void) { return -1; }
bool IsRealTimeStream(void) { return true; }
bool SwitchChannel(const PVR_CHANNEL& channel) {
CloseLiveStream();
return OpenLiveStream(channel);
PVR_ERROR SignalStatus(PVR_SIGNAL_STATUS& signalStatus) {
memset(&signalStatus, 0, sizeof(PVR_SIGNAL_STATUS));
rtsp_fill_signal_status(signalStatus);
return PVR_ERROR_NO_ERROR;
}
PVR_ERROR SignalStatus(PVR_SIGNAL_STATUS& signalStatus) { return PVR_ERROR_NOT_IMPLEMENTED; }
const char* GetLiveStreamURL(const PVR_CHANNEL& channel) { return NULL; }
PVR_ERROR GetStreamTimes(PVR_STREAM_TIMES *times) { return PVR_ERROR_NOT_IMPLEMENTED; }
PVR_ERROR GetStreamProperties(PVR_STREAM_PROPERTIES* pProperties) { return PVR_ERROR_NOT_IMPLEMENTED; }
PVR_ERROR GetDescrambleInfo(PVR_DESCRAMBLE_INFO*) { return PVR_ERROR_NOT_IMPLEMENTED; }
/* Recording stream handling */
bool OpenRecordedStream(const PVR_RECORDING& recording) { return false; }
void CloseRecordedStream(void) {}
int ReadRecordedStream(unsigned char* pBuffer, unsigned int iBufferSize) { return -1; }
long long SeekRecordedStream(long long iPosition, int iWhence) { return -1; }
long long PositionRecordedStream(void) { return -1; }
long long LengthRecordedStream(void) { return -1; }
/* PVR demuxer */
@@ -290,21 +268,16 @@ void DemuxFlush(void) {}
DemuxPacket* DemuxRead(void) { return NULL; }
/* Various helper functions */
unsigned int GetChannelSwitchDelay(void) { return 0; }
bool IsTimeshifting(void) { return false; }
bool CanPauseStream() { return false; }
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; }
time_t GetPlayingTime() { return 0; }
time_t GetBufferTimeStart() { return 0; }
time_t GetBufferTimeEnd() { return 0; }
const char* GetBackendHostname()
{
return octonetAddress.c_str();

View File

@@ -28,7 +28,7 @@
#define __func__ __FUNCTION__
#endif
extern ADDON::CHelper_libXBMC_addon *kodi;
extern ADDON::CHelper_libXBMC_addon *libKodi;
extern CHelper_libXBMC_pvr *pvr;
/* IP or hostname of the octonet to be connected to */

View File

@@ -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,13 +305,17 @@ bool rtsp_open(const string& url_str)
if (rtsp == NULL)
return false;
kodi->Log(LOG_DEBUG, "try to open '%s'", url_str.c_str());
rtsp->name = name;
rtsp->level = 0;
rtsp->quality = 0;
libKodi->Log(LOG_DEBUG, "try to open '%s'", url_str.c_str());
url dst = parse_url(url_str);
kodi->Log(LOG_DEBUG, "connect to host '%s'", dst.host.c_str());
libKodi->Log(LOG_DEBUG, "connect to host '%s'", dst.host.c_str());
if(!rtsp->tcp_sock.connect(dst.host, dst.port)) {
kodi->Log(LOG_ERROR, "Failed to connect to RTSP server %s:%d", dst.host.c_str(), dst.port);
libKodi->Log(LOG_ERROR, "Failed to connect to RTSP server %s:%d", dst.host.c_str(), dst.port);
goto error;
}
@@ -323,7 +353,7 @@ bool rtsp_open(const string& url_str)
rtsp->tcp_sock.send(setup_ss.str());
if (rtsp_handle() != RTSP_RESULT_OK) {
kodi->Log(LOG_ERROR, "Failed to setup RTSP session");
libKodi->Log(LOG_ERROR, "Failed to setup RTSP session");
goto error;
}
@@ -338,7 +368,15 @@ bool rtsp_open(const string& url_str)
rtsp->tcp_sock.send(play_ss.str());
if (rtsp_handle() != RTSP_RESULT_OK) {
kodi->Log(LOG_ERROR, "Failed to play RTSP session");
libKodi->Log(LOG_ERROR, "Failed to play RTSP session");
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;
}
@@ -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;
@@ -377,7 +453,7 @@ static void rtsp_teardown() {
rtsp->tcp_sock.send(ss.str());
if (rtsp_handle() != RTSP_RESULT_OK) {
kodi->Log(LOG_ERROR, "Failed to teardown RTSP session");
libKodi->Log(LOG_ERROR, "Failed to teardown RTSP session");
return;
}
}
@@ -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;
}
}

View File

@@ -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