Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

pvr: added a demo PVR add-on, that can e.g. be used by skinners to wo…

…rk on the PVR parts of their skin without access to a tuner
  • Loading branch information...
commit 2b363dc596d5f297407f9d6fb9ac2da8b11e04a6 1 parent 945c55e
@opdenkamp opdenkamp authored
View
4 Makefile.in
@@ -170,7 +170,8 @@ PVR_DIRS=\
xbmc/pvrclients/MediaPortal \
xbmc/pvrclients/mythtv \
xbmc/pvrclients/vdr-vnsi \
- xbmc/pvrclients/tvheadend
+ xbmc/pvrclients/tvheadend \
+ xbmc/pvrclients/pvr-demo
LIBADDON_DIRS=\
lib/addons/library.xbmc.addon \
@@ -274,6 +275,7 @@ pvrclients: exports
$(MAKE) -C xbmc/pvrclients/mythtv
$(MAKE) -C xbmc/pvrclients/vdr-vnsi
$(MAKE) -C xbmc/pvrclients/tvheadend
+ $(MAKE) -C xbmc/pvrclients/pvr-demo
libaddon: exports
$(MAKE) -C lib/addons/library.xbmc.addon
$(MAKE) -C lib/addons/library.xbmc.gui
View
19 addons/pvr.demo/addon.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<addon
+ id="pvr.demo"
+ version="1.0.0"
+ name="PVR Demo Client"
+ provider-name="Pulse-Eight Ltd.">
+ <requires>
+ <c-pluff version="0.1"/>
+ </requires>
+ <extension
+ point="xbmc.pvrclient"
+ library_linux="XBMC_demo.pvr" />
+ <extension point="xbmc.addon.metadata">
+ <summary>Pulse-Eight Demo PVR Client</summary>
+ <description>Pulse-Eight Demo PVR Client</description>
+ <disclaimer>Just contains stubs</disclaimer>
+ <platform>linux</platform>
+ </extension>
+</addon>
View
1  configure.in
@@ -1897,6 +1897,7 @@ OUTPUT_FILES="Makefile \
xbmc/pvrclients/Makefile.include \
xbmc/pvrclients/MediaPortal/Makefile \
xbmc/pvrclients/mythtv/Makefile \
+ xbmc/pvrclients/pvr-demo/Makefile \
xbmc/pvrclients/tvheadend/Makefile \
xbmc/pvrclients/vdr-vnsi/Makefile \
lib/addons/library.xbmc.addon/Makefile \
View
460 system/PVRDemoAddonSettings.xml
@@ -0,0 +1,460 @@
+<demo>
+ <channels>
+ <channel>
+ <name>Demo TV Channel 1</name>
+ <radio>0</radio>
+ <number>1</number>
+ <encryption>0</encryption>
+ <icon></icon>
+ <stream></stream>
+ </channel>
+ <channel>
+ <name>Demo TV Channel 2</name>
+ <radio>0</radio>
+ <number>2</number>
+ <encryption>0</encryption>
+ <icon></icon>
+ <stream></stream>
+ </channel>
+ <channel>
+ <name>Demo TV Channel 3</name>
+ <radio>0</radio>
+ <number>3</number>
+ <encryption>0</encryption>
+ <icon></icon>
+ <stream></stream>
+ </channel>
+ <channel>
+ <name>Demo TV Channel 4</name>
+ <radio>0</radio>
+ <number>4</number>
+ <encryption>0</encryption>
+ <icon></icon>
+ <stream></stream>
+ </channel>
+ <channel>
+ <name>Demo TV Channel 5</name>
+ <radio>0</radio>
+ <number>5</number>
+ <encryption>0</encryption>
+ <icon></icon>
+ <stream></stream>
+ </channel>
+ <channel>
+ <name>Demo TV Channel 10</name>
+ <radio>0</radio>
+ <number>10</number>
+ <encryption>0</encryption>
+ <icon></icon>
+ <stream></stream>
+ </channel>
+ <channel>
+ <name>Demo TV Channel 11</name>
+ <radio>0</radio>
+ <number>11</number>
+ <encryption>0</encryption>
+ <icon></icon>
+ <stream></stream>
+ </channel>
+ <channel>
+ <name>Demo TV Channel 12</name>
+ <radio>0</radio>
+ <number>12</number>
+ <encryption>0</encryption>
+ <icon></icon>
+ <stream></stream>
+ </channel>
+ <channel>
+ <name>Demo TV Channel 13</name>
+ <radio>0</radio>
+ <number>13</number>
+ <encryption>0</encryption>
+ <icon></icon>
+ <stream></stream>
+ </channel>
+ <channel>
+ <name>Demo TV Channel 14</name>
+ <radio>0</radio>
+ <number>14</number>
+ <encryption>0</encryption>
+ <icon></icon>
+ <stream></stream>
+ </channel>
+ <channel>
+ <name>Demo TV Channel 15</name>
+ <radio>0</radio>
+ <number>15</number>
+ <encryption>0</encryption>
+ <icon></icon>
+ <stream></stream>
+ </channel>
+
+ <channel>
+ <name>Demo Radio Channel #1</name>
+ <radio>1</radio>
+ <number>1</number>
+ <encryption>0</encryption>
+ <icon></icon>
+ <stream></stream>
+ </channel>
+ <channel>
+ <name>Demo Radio Channel #2</name>
+ <radio>1</radio>
+ <number>2</number>
+ <encryption>0</encryption>
+ <icon></icon>
+ <stream></stream>
+ </channel>
+ <channel>
+ <name>Demo Radio Channel #3</name>
+ <radio>1</radio>
+ <number>3</number>
+ <encryption>0</encryption>
+ <icon></icon>
+ <stream></stream>
+ </channel>
+ <channel>
+ <name>Demo Radio Channel #4</name>
+ <radio>1</radio>
+ <number>4</number>
+ <encryption>0</encryption>
+ <icon></icon>
+ <stream></stream>
+ </channel>
+ <channel>
+ <name>Demo Radio Channel #5</name>
+ <radio>1</radio>
+ <number>5</number>
+ <encryption>0</encryption>
+ <icon></icon>
+ <stream></stream>
+ </channel>
+ <channel>
+ <name>Demo Radio Channel #6</name>
+ <radio>1</radio>
+ <number>6</number>
+ <encryption>0</encryption>
+ <icon></icon>
+ <stream></stream>
+ </channel>
+ <channel>
+ <name>Demo Radio Channel #7</name>
+ <radio>1</radio>
+ <number>7</number>
+ <encryption>0</encryption>
+ <icon></icon>
+ <stream></stream>
+ </channel>
+ <channel>
+ <name>Demo Radio Channel #8</name>
+ <radio>1</radio>
+ <number>8</number>
+ <encryption>0</encryption>
+ <icon></icon>
+ <stream></stream>
+ </channel>
+ <channel>
+ <name>Demo Radio Channel #9</name>
+ <radio>1</radio>
+ <number>9</number>
+ <encryption>0</encryption>
+ <icon></icon>
+ <stream></stream>
+ </channel>
+ <channel>
+ <name>Demo Radio Channel #10</name>
+ <radio>1</radio>
+ <number>10</number>
+ <encryption>0</encryption>
+ <icon></icon>
+ <stream></stream>
+ </channel>
+ </channels>
+ <channelgroups>
+ <group>
+ <name>Demo Group #1</name>
+ <radio>0</radio>
+ <members>
+ <member>1</member>
+ <member>2</member>
+ <member>3</member>
+ <member>4</member>
+ <member>5</member>
+ <member>6</member>
+ <member>7</member>
+ <member>8</member>
+ <member>9</member>
+ <member>10</member>
+ <member>11</member>
+ </members>
+ </group>
+ <group>
+ <name>Demo Group #2</name>
+ <radio>0</radio>
+ <members>
+ <member>1</member>
+ <member>3</member>
+ <member>5</member>
+ <member>7</member>
+ <member>9</member>
+ <member>11</member>
+ </members>
+ </group>
+ </channelgroups>
+ <epg>
+ <entry>
+ <broadcastid>100</broadcastid>
+ <title>Demo EPG entry #1</title>
+ <channelid>1</channelid>
+ <start>0</start>
+ <end>7200</end>
+ <plotoutline>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam cursus consectetur ipsum, eu tincidunt dui aliquam ac. Sed scelerisque, augue eu lacinia ultrices, libero ante ullamcorper augue, vel malesuada justo risus ac nulla. Quisque ac libero libero. Sed tincidunt, orci eu condimentum laoreet, felis odio mattis est, et lacinia metus enim in leo. Fusce faucibus tristique risus in varius. Etiam sagittis venenatis ligula nec rutrum. Etiam gravida dictum hendrerit. Sed sodales felis in sapien rutrum non malesuada nisi lobortis. Mauris iaculis ante odio. Nunc gravida erat convallis purus dignissim et ultricies orci dapibus. Aliquam erat volutpat. Vestibulum mi felis, malesuada ac tincidunt sit amet, pulvinar nec dolor. Pellentesque vehicula est vulputate mi adipiscing euismod. Donec ac mauris nulla. Nullam suscipit felis eu quam sodales ac bibendum nisi interdum. Curabitur non lectus a ante venenatis semper eget id justo. Ut facilisis, ligula pretium dictum congue, lacus dolor commodo nibh, sit amet sodales sed. </plotoutline>
+ <plot>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam cursus consectetur ipsum, eu tincidunt dui aliquam ac. Sed scelerisque, augue eu lacinia ultrices, libero ante ullamcorper augue, vel malesuada justo risus ac nulla. Quisque ac libero libero. Sed tincidunt, orci eu condimentum laoreet, felis odio mattis est, et lacinia metus enim in leo. Fusce faucibus tristique risus in varius. Etiam sagittis venenatis ligula nec rutrum. Etiam gravida dictum hendrerit. Sed sodales felis in sapien rutrum non malesuada nisi lobortis. Mauris iaculis ante odio. Nunc gravida erat convallis purus dignissim et ultricies orci dapibus. Aliquam erat volutpat. Vestibulum mi felis, malesuada ac tincidunt sit amet, pulvinar nec dolor. Pellentesque vehicula est vulputate mi adipiscing euismod. Donec ac mauris nulla. Nullam suscipit felis eu quam sodales ac bibendum nisi interdum. Curabitur non lectus a ante venenatis semper eget id justo. Ut facilisis, ligula pretium dictum congue, lacus dolor commodo nibh, sit amet sodales sed. </plot>
+ <icon></icon>
+ <genretype>10</genretype>
+ <genresubtype>0</genresubtype>
+ </entry>
+ <entry>
+ <broadcastid>200</broadcastid>
+ <title>Demo EPG entry #2</title>
+ <channelid>2</channelid>
+ <start>0</start>
+ <end>7200</end>
+ <plotoutline>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam cursus consectetur ipsum, eu tincidunt dui aliquam ac. Sed scelerisque, augue eu lacinia ultrices, libero ante ullamcorper augue, vel malesuada justo risus ac nulla. Quisque ac libero libero. Sed tincidunt, orci eu condimentum laoreet, felis odio mattis est, et lacinia metus enim in leo. Fusce faucibus tristique risus in varius. Etiam sagittis venenatis ligula nec rutrum. Etiam gravida dictum hendrerit. Sed sodales felis in sapien rutrum non malesuada nisi lobortis. Mauris iaculis ante odio. Nunc gravida erat convallis purus dignissim et ultricies orci dapibus. Aliquam erat volutpat. Vestibulum mi felis, malesuada ac tincidunt sit amet, pulvinar nec dolor. Pellentesque vehicula est vulputate mi adipiscing euismod. Donec ac mauris nulla. Nullam suscipit felis eu quam sodales ac bibendum nisi interdum. Curabitur non lectus a ante venenatis semper eget id justo. Ut facilisis, ligula pretium dictum congue, lacus dolor commodo nibh, sit amet sodales sed. </plotoutline>
+ <plot>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam cursus consectetur ipsum, eu tincidunt dui aliquam ac. Sed scelerisque, augue eu lacinia ultrices, libero ante ullamcorper augue, vel malesuada justo risus ac nulla. Quisque ac libero libero. Sed tincidunt, orci eu condimentum laoreet, felis odio mattis est, et lacinia metus enim in leo. Fusce faucibus tristique risus in varius. Etiam sagittis venenatis ligula nec rutrum. Etiam gravida dictum hendrerit. Sed sodales felis in sapien rutrum non malesuada nisi lobortis. Mauris iaculis ante odio. Nunc gravida erat convallis purus dignissim et ultricies orci dapibus. Aliquam erat volutpat. Vestibulum mi felis, malesuada ac tincidunt sit amet, pulvinar nec dolor. Pellentesque vehicula est vulputate mi adipiscing euismod. Donec ac mauris nulla. Nullam suscipit felis eu quam sodales ac bibendum nisi interdum. Curabitur non lectus a ante venenatis semper eget id justo. Ut facilisis, ligula pretium dictum congue, lacus dolor commodo nibh, sit amet sodales sed. </plot>
+ <icon></icon>
+ <genretype>20</genretype>
+ <genresubtype>0</genresubtype>
+ </entry>
+ <entry>
+ <broadcastid>300</broadcastid>
+ <title>Demo EPG entry #3</title>
+ <channelid>3</channelid>
+ <start>0</start>
+ <end>7200</end>
+ <plotoutline>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam cursus consectetur ipsum, eu tincidunt dui aliquam ac. Sed scelerisque, augue eu lacinia ultrices, libero ante ullamcorper augue, vel malesuada justo risus ac nulla. Quisque ac libero libero. Sed tincidunt, orci eu condimentum laoreet, felis odio mattis est, et lacinia metus enim in leo. Fusce faucibus tristique risus in varius. Etiam sagittis venenatis ligula nec rutrum. Etiam gravida dictum hendrerit. Sed sodales felis in sapien rutrum non malesuada nisi lobortis. Mauris iaculis ante odio. Nunc gravida erat convallis purus dignissim et ultricies orci dapibus. Aliquam erat volutpat. Vestibulum mi felis, malesuada ac tincidunt sit amet, pulvinar nec dolor. Pellentesque vehicula est vulputate mi adipiscing euismod. Donec ac mauris nulla. Nullam suscipit felis eu quam sodales ac bibendum nisi interdum. Curabitur non lectus a ante venenatis semper eget id justo. Ut facilisis, ligula pretium dictum congue, lacus dolor commodo nibh, sit amet sodales sed.</plotoutline>
+ <plot>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam cursus consectetur ipsum, eu tincidunt dui aliquam ac. Sed scelerisque, augue eu lacinia ultrices, libero ante ullamcorper augue, vel malesuada justo risus ac nulla. Quisque ac libero libero. Sed tincidunt, orci eu condimentum laoreet, felis odio mattis est, et lacinia metus enim in leo. Fusce faucibus tristique risus in varius. Etiam sagittis venenatis ligula nec rutrum. Etiam gravida dictum hendrerit. Sed sodales felis in sapien rutrum non malesuada nisi lobortis. Mauris iaculis ante odio. Nunc gravida erat convallis purus dignissim et ultricies orci dapibus. Aliquam erat volutpat. Vestibulum mi felis, malesuada ac tincidunt sit amet, pulvinar nec dolor. Pellentesque vehicula est vulputate mi adipiscing euismod. Donec ac mauris nulla. Nullam suscipit felis eu quam sodales ac bibendum nisi interdum. Curabitur non lectus a ante venenatis semper eget id justo. Ut facilisis, ligula pretium dictum congue, lacus dolor commodo nibh, sit amet sodales sed.</plot>
+ <icon></icon>
+ <genretype></genretype>
+ <genresubtype>0</genresubtype>
+ </entry>
+ <entry>
+ <broadcastid>400</broadcastid>
+ <title>Demo EPG entry #4</title>
+ <channelid>4</channelid>
+ <start>0</start>
+ <end>7200</end>
+ <plotoutline>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam cursus consectetur ipsum, eu tincidunt dui aliquam ac. Sed scelerisque, augue eu lacinia ultrices, libero ante ullamcorper augue, vel malesuada justo risus ac nulla. Quisque ac libero libero. Sed tincidunt, orci eu condimentum laoreet, felis odio mattis est, et lacinia metus enim in leo. Fusce faucibus tristique risus in varius. Etiam sagittis venenatis ligula nec rutrum. Etiam gravida dictum hendrerit. Sed sodales felis in sapien rutrum non malesuada nisi lobortis. Mauris iaculis ante odio. Nunc gravida erat convallis purus dignissim et ultricies orci dapibus. Aliquam erat volutpat. Vestibulum mi felis, malesuada ac tincidunt sit amet, pulvinar nec dolor. Pellentesque vehicula est vulputate mi adipiscing euismod. Donec ac mauris nulla. Nullam suscipit felis eu quam sodales ac bibendum nisi interdum. Curabitur non lectus a ante venenatis semper eget id justo. Ut facilisis, ligula pretium dictum congue, lacus dolor commodo nibh, sit amet sodales sed.</plotoutline>
+ <plot>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam cursus consectetur ipsum, eu tincidunt dui aliquam ac. Sed scelerisque, augue eu lacinia ultrices, libero ante ullamcorper augue, vel malesuada justo risus ac nulla. Quisque ac libero libero. Sed tincidunt, orci eu condimentum laoreet, felis odio mattis est, et lacinia metus enim in leo. Fusce faucibus tristique risus in varius. Etiam sagittis venenatis ligula nec rutrum. Etiam gravida dictum hendrerit. Sed sodales felis in sapien rutrum non malesuada nisi lobortis. Mauris iaculis ante odio. Nunc gravida erat convallis purus dignissim et ultricies orci dapibus. Aliquam erat volutpat. Vestibulum mi felis, malesuada ac tincidunt sit amet, pulvinar nec dolor. Pellentesque vehicula est vulputate mi adipiscing euismod. Donec ac mauris nulla. Nullam suscipit felis eu quam sodales ac bibendum nisi interdum. Curabitur non lectus a ante venenatis semper eget id justo. Ut facilisis, ligula pretium dictum congue, lacus dolor commodo nibh, sit amet sodales sed.</plot>
+ <icon></icon>
+ <genretype>30</genretype>
+ <genresubtype>0</genresubtype>
+ </entry>
+ <entry>
+ <broadcastid>500</broadcastid>
+ <title>Demo EPG entry #5</title>
+ <channelid>5</channelid>
+ <start>0</start>
+ <end>7200</end>
+ <plotoutline>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam cursus consectetur ipsum, eu tincidunt dui aliquam ac. Sed scelerisque, augue eu lacinia ultrices, libero ante ullamcorper augue, vel malesuada justo risus ac nulla. Quisque ac libero libero. Sed tincidunt, orci eu condimentum laoreet, felis odio mattis est, et lacinia metus enim in leo. Fusce faucibus tristique risus in varius. Etiam sagittis venenatis ligula nec rutrum. Etiam gravida dictum hendrerit. Sed sodales felis in sapien rutrum non malesuada nisi lobortis. Mauris iaculis ante odio. Nunc gravida erat convallis purus dignissim et ultricies orci dapibus. Aliquam erat volutpat. Vestibulum mi felis, malesuada ac tincidunt sit amet, pulvinar nec dolor. Pellentesque vehicula est vulputate mi adipiscing euismod. Donec ac mauris nulla. Nullam suscipit felis eu quam sodales ac bibendum nisi interdum. Curabitur non lectus a ante venenatis semper eget id justo. Ut facilisis, ligula pretium dictum congue, lacus dolor commodo nibh, sit amet sodales sed.</plotoutline>
+ <plot>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam cursus consectetur ipsum, eu tincidunt dui aliquam ac. Sed scelerisque, augue eu lacinia ultrices, libero ante ullamcorper augue, vel malesuada justo risus ac nulla. Quisque ac libero libero. Sed tincidunt, orci eu condimentum laoreet, felis odio mattis est, et lacinia metus enim in leo. Fusce faucibus tristique risus in varius. Etiam sagittis venenatis ligula nec rutrum. Etiam gravida dictum hendrerit. Sed sodales felis in sapien rutrum non malesuada nisi lobortis. Mauris iaculis ante odio. Nunc gravida erat convallis purus dignissim et ultricies orci dapibus. Aliquam erat volutpat. Vestibulum mi felis, malesuada ac tincidunt sit amet, pulvinar nec dolor. Pellentesque vehicula est vulputate mi adipiscing euismod. Donec ac mauris nulla. Nullam suscipit felis eu quam sodales ac bibendum nisi interdum. Curabitur non lectus a ante venenatis semper eget id justo. Ut facilisis, ligula pretium dictum congue, lacus dolor commodo nibh, sit amet sodales sed.</plot>
+ <icon></icon>
+ <genretype></genretype>
+ <genresubtype>0</genresubtype>
+ </entry>
+ <entry>
+ <broadcastid>600</broadcastid>
+ <title>Demo EPG entry #6</title>
+ <channelid>6</channelid>
+ <start>0</start>
+ <end>7200</end>
+ <plotoutline>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam cursus consectetur ipsum, eu tincidunt dui aliquam ac. Sed scelerisque, augue eu lacinia ultrices, libero ante ullamcorper augue, vel malesuada justo risus ac nulla. Quisque ac libero libero. Sed tincidunt, orci eu condimentum laoreet, felis odio mattis est, et lacinia metus enim in leo. Fusce faucibus tristique risus in varius. Etiam sagittis venenatis ligula nec rutrum. Etiam gravida dictum hendrerit. Sed sodales felis in sapien rutrum non malesuada nisi lobortis. Mauris iaculis ante odio. Nunc gravida erat convallis purus dignissim et ultricies orci dapibus. Aliquam erat volutpat. Vestibulum mi felis, malesuada ac tincidunt sit amet, pulvinar nec dolor. Pellentesque vehicula est vulputate mi adipiscing euismod. Donec ac mauris nulla. Nullam suscipit felis eu quam sodales ac bibendum nisi interdum. Curabitur non lectus a ante venenatis semper eget id justo. Ut facilisis, ligula pretium dictum congue, lacus dolor commodo nibh, sit amet sodales sed.</plotoutline>
+ <plot>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam cursus consectetur ipsum, eu tincidunt dui aliquam ac. Sed scelerisque, augue eu lacinia ultrices, libero ante ullamcorper augue, vel malesuada justo risus ac nulla. Quisque ac libero libero. Sed tincidunt, orci eu condimentum laoreet, felis odio mattis est, et lacinia metus enim in leo. Fusce faucibus tristique risus in varius. Etiam sagittis venenatis ligula nec rutrum. Etiam gravida dictum hendrerit. Sed sodales felis in sapien rutrum non malesuada nisi lobortis. Mauris iaculis ante odio. Nunc gravida erat convallis purus dignissim et ultricies orci dapibus. Aliquam erat volutpat. Vestibulum mi felis, malesuada ac tincidunt sit amet, pulvinar nec dolor. Pellentesque vehicula est vulputate mi adipiscing euismod. Donec ac mauris nulla. Nullam suscipit felis eu quam sodales ac bibendum nisi interdum. Curabitur non lectus a ante venenatis semper eget id justo. Ut facilisis, ligula pretium dictum congue, lacus dolor commodo nibh, sit amet sodales sed.</plot>
+ <icon></icon>
+ <genretype>10</genretype>
+ <genresubtype>0</genresubtype>
+ </entry>
+ <entry>
+ <broadcastid>700</broadcastid>
+ <title>Demo EPG entry #7</title>
+ <channelid>7</channelid>
+ <start>0</start>
+ <end>7200</end>
+ <plotoutline>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam cursus consectetur ipsum, eu tincidunt dui aliquam ac. Sed scelerisque, augue eu lacinia ultrices, libero ante ullamcorper augue, vel malesuada justo risus ac nulla. Quisque ac libero libero. Sed tincidunt, orci eu condimentum laoreet, felis odio mattis est, et lacinia metus enim in leo. Fusce faucibus tristique risus in varius. Etiam sagittis venenatis ligula nec rutrum. Etiam gravida dictum hendrerit. Sed sodales felis in sapien rutrum non malesuada nisi lobortis. Mauris iaculis ante odio. Nunc gravida erat convallis purus dignissim et ultricies orci dapibus. Aliquam erat volutpat. Vestibulum mi felis, malesuada ac tincidunt sit amet, pulvinar nec dolor. Pellentesque vehicula est vulputate mi adipiscing euismod. Donec ac mauris nulla. Nullam suscipit felis eu quam sodales ac bibendum nisi interdum. Curabitur non lectus a ante venenatis semper eget id justo. Ut facilisis, ligula pretium dictum congue, lacus dolor commodo nibh, sit amet sodales sed.</plotoutline>
+ <plot>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam cursus consectetur ipsum, eu tincidunt dui aliquam ac. Sed scelerisque, augue eu lacinia ultrices, libero ante ullamcorper augue, vel malesuada justo risus ac nulla. Quisque ac libero libero. Sed tincidunt, orci eu condimentum laoreet, felis odio mattis est, et lacinia metus enim in leo. Fusce faucibus tristique risus in varius. Etiam sagittis venenatis ligula nec rutrum. Etiam gravida dictum hendrerit. Sed sodales felis in sapien rutrum non malesuada nisi lobortis. Mauris iaculis ante odio. Nunc gravida erat convallis purus dignissim et ultricies orci dapibus. Aliquam erat volutpat. Vestibulum mi felis, malesuada ac tincidunt sit amet, pulvinar nec dolor. Pellentesque vehicula est vulputate mi adipiscing euismod. Donec ac mauris nulla. Nullam suscipit felis eu quam sodales ac bibendum nisi interdum. Curabitur non lectus a ante venenatis semper eget id justo. Ut facilisis, ligula pretium dictum congue, lacus dolor commodo nibh, sit amet sodales sed.</plot>
+ <icon></icon>
+ <genretype>10</genretype>
+ <genresubtype>0</genresubtype>
+ </entry>
+ <entry>
+ <broadcastid>800</broadcastid>
+ <title>Demo EPG entry #8</title>
+ <channelid>8</channelid>
+ <start>0</start>
+ <end>7200</end>
+ <plotoutline>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam cursus consectetur ipsum, eu tincidunt dui aliquam ac. Sed scelerisque, augue eu lacinia ultrices, libero ante ullamcorper augue, vel malesuada justo risus ac nulla. Quisque ac libero libero. Sed tincidunt, orci eu condimentum laoreet, felis odio mattis est, et lacinia metus enim in leo. Fusce faucibus tristique risus in varius. Etiam sagittis venenatis ligula nec rutrum. Etiam gravida dictum hendrerit. Sed sodales felis in sapien rutrum non malesuada nisi lobortis. Mauris iaculis ante odio. Nunc gravida erat convallis purus dignissim et ultricies orci dapibus. Aliquam erat volutpat. Vestibulum mi felis, malesuada ac tincidunt sit amet, pulvinar nec dolor. Pellentesque vehicula est vulputate mi adipiscing euismod. Donec ac mauris nulla. Nullam suscipit felis eu quam sodales ac bibendum nisi interdum. Curabitur non lectus a ante venenatis semper eget id justo. Ut facilisis, ligula pretium dictum congue, lacus dolor commodo nibh, sit amet sodales sed.</plotoutline>
+ <plot>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam cursus consectetur ipsum, eu tincidunt dui aliquam ac. Sed scelerisque, augue eu lacinia ultrices, libero ante ullamcorper augue, vel malesuada justo risus ac nulla. Quisque ac libero libero. Sed tincidunt, orci eu condimentum laoreet, felis odio mattis est, et lacinia metus enim in leo. Fusce faucibus tristique risus in varius. Etiam sagittis venenatis ligula nec rutrum. Etiam gravida dictum hendrerit. Sed sodales felis in sapien rutrum non malesuada nisi lobortis. Mauris iaculis ante odio. Nunc gravida erat convallis purus dignissim et ultricies orci dapibus. Aliquam erat volutpat. Vestibulum mi felis, malesuada ac tincidunt sit amet, pulvinar nec dolor. Pellentesque vehicula est vulputate mi adipiscing euismod. Donec ac mauris nulla. Nullam suscipit felis eu quam sodales ac bibendum nisi interdum. Curabitur non lectus a ante venenatis semper eget id justo. Ut facilisis, ligula pretium dictum congue, lacus dolor commodo nibh, sit amet sodales sed.</plot>
+ <icon></icon>
+ <genretype>20</genretype>
+ <genresubtype>0</genresubtype>
+ </entry>
+ <entry>
+ <broadcastid>900</broadcastid>
+ <title>Demo EPG entry #9</title>
+ <channelid>9</channelid>
+ <start>0</start>
+ <end>7200</end>
+ <plotoutline>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam cursus consectetur ipsum, eu tincidunt dui aliquam ac. Sed scelerisque, augue eu lacinia ultrices, libero ante ullamcorper augue, vel malesuada justo risus ac nulla. Quisque ac libero libero. Sed tincidunt, orci eu condimentum laoreet, felis odio mattis est, et lacinia metus enim in leo. Fusce faucibus tristique risus in varius. Etiam sagittis venenatis ligula nec rutrum. Etiam gravida dictum hendrerit. Sed sodales felis in sapien rutrum non malesuada nisi lobortis. Mauris iaculis ante odio. Nunc gravida erat convallis purus dignissim et ultricies orci dapibus. Aliquam erat volutpat. Vestibulum mi felis, malesuada ac tincidunt sit amet, pulvinar nec dolor. Pellentesque vehicula est vulputate mi adipiscing euismod. Donec ac mauris nulla. Nullam suscipit felis eu quam sodales ac bibendum nisi interdum. Curabitur non lectus a ante venenatis semper eget id justo. Ut facilisis, ligula pretium dictum congue, lacus dolor commodo nibh, sit amet sodales sed.</plotoutline>
+ <plot>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam cursus consectetur ipsum, eu tincidunt dui aliquam ac. Sed scelerisque, augue eu lacinia ultrices, libero ante ullamcorper augue, vel malesuada justo risus ac nulla. Quisque ac libero libero. Sed tincidunt, orci eu condimentum laoreet, felis odio mattis est, et lacinia metus enim in leo. Fusce faucibus tristique risus in varius. Etiam sagittis venenatis ligula nec rutrum. Etiam gravida dictum hendrerit. Sed sodales felis in sapien rutrum non malesuada nisi lobortis. Mauris iaculis ante odio. Nunc gravida erat convallis purus dignissim et ultricies orci dapibus. Aliquam erat volutpat. Vestibulum mi felis, malesuada ac tincidunt sit amet, pulvinar nec dolor. Pellentesque vehicula est vulputate mi adipiscing euismod. Donec ac mauris nulla. Nullam suscipit felis eu quam sodales ac bibendum nisi interdum. Curabitur non lectus a ante venenatis semper eget id justo. Ut facilisis, ligula pretium dictum congue, lacus dolor commodo nibh, sit amet sodales sed.</plot>
+ <icon></icon>
+ <genretype>30</genretype>
+ <genresubtype>0</genresubtype>
+ </entry>
+ <entry>
+ <broadcastid>1000</broadcastid>
+ <title>Demo EPG entry #10</title>
+ <channelid>10</channelid>
+ <start>0</start>
+ <end>7200</end>
+ <plotoutline>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam cursus consectetur ipsum, eu tincidunt dui aliquam ac. Sed scelerisque, augue eu lacinia ultrices, libero ante ullamcorper augue, vel malesuada justo risus ac nulla. Quisque ac libero libero. Sed tincidunt, orci eu condimentum laoreet, felis odio mattis est, et lacinia metus enim in leo. Fusce faucibus tristique risus in varius. Etiam sagittis venenatis ligula nec rutrum. Etiam gravida dictum hendrerit. Sed sodales felis in sapien rutrum non malesuada nisi lobortis. Mauris iaculis ante odio. Nunc gravida erat convallis purus dignissim et ultricies orci dapibus. Aliquam erat volutpat. Vestibulum mi felis, malesuada ac tincidunt sit amet, pulvinar nec dolor. Pellentesque vehicula est vulputate mi adipiscing euismod. Donec ac mauris nulla. Nullam suscipit felis eu quam sodales ac bibendum nisi interdum. Curabitur non lectus a ante venenatis semper eget id justo. Ut facilisis, ligula pretium dictum congue, lacus dolor commodo nibh, sit amet sodales sed.</plotoutline>
+ <plot>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam cursus consectetur ipsum, eu tincidunt dui aliquam ac. Sed scelerisque, augue eu lacinia ultrices, libero ante ullamcorper augue, vel malesuada justo risus ac nulla. Quisque ac libero libero. Sed tincidunt, orci eu condimentum laoreet, felis odio mattis est, et lacinia metus enim in leo. Fusce faucibus tristique risus in varius. Etiam sagittis venenatis ligula nec rutrum. Etiam gravida dictum hendrerit. Sed sodales felis in sapien rutrum non malesuada nisi lobortis. Mauris iaculis ante odio. Nunc gravida erat convallis purus dignissim et ultricies orci dapibus. Aliquam erat volutpat. Vestibulum mi felis, malesuada ac tincidunt sit amet, pulvinar nec dolor. Pellentesque vehicula est vulputate mi adipiscing euismod. Donec ac mauris nulla. Nullam suscipit felis eu quam sodales ac bibendum nisi interdum. Curabitur non lectus a ante venenatis semper eget id justo. Ut facilisis, ligula pretium dictum congue, lacus dolor commodo nibh, sit amet sodales sed.</plot>
+ <icon></icon>
+ <genretype>10</genretype>
+ <genresubtype>0</genresubtype>
+ </entry>
+ <entry>
+ <broadcastid>1100</broadcastid>
+ <title>Demo EPG entry #11</title>
+ <channelid>11</channelid>
+ <start>0</start>
+ <end>7200</end>
+ <plotoutline>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam cursus consectetur ipsum, eu tincidunt dui aliquam ac. Sed scelerisque, augue eu lacinia ultrices, libero ante ullamcorper augue, vel malesuada justo risus ac nulla. Quisque ac libero libero. Sed tincidunt, orci eu condimentum laoreet, felis odio mattis est, et lacinia metus enim in leo. Fusce faucibus tristique risus in varius. Etiam sagittis venenatis ligula nec rutrum. Etiam gravida dictum hendrerit. Sed sodales felis in sapien rutrum non malesuada nisi lobortis. Mauris iaculis ante odio. Nunc gravida erat convallis purus dignissim et ultricies orci dapibus. Aliquam erat volutpat. Vestibulum mi felis, malesuada ac tincidunt sit amet, pulvinar nec dolor. Pellentesque vehicula est vulputate mi adipiscing euismod. Donec ac mauris nulla. Nullam suscipit felis eu quam sodales ac bibendum nisi interdum. Curabitur non lectus a ante venenatis semper eget id justo. Ut facilisis, ligula pretium dictum congue, lacus dolor commodo nibh, sit amet sodales sed.</plotoutline>
+ <plot>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam cursus consectetur ipsum, eu tincidunt dui aliquam ac. Sed scelerisque, augue eu lacinia ultrices, libero ante ullamcorper augue, vel malesuada justo risus ac nulla. Quisque ac libero libero. Sed tincidunt, orci eu condimentum laoreet, felis odio mattis est, et lacinia metus enim in leo. Fusce faucibus tristique risus in varius. Etiam sagittis venenatis ligula nec rutrum. Etiam gravida dictum hendrerit. Sed sodales felis in sapien rutrum non malesuada nisi lobortis. Mauris iaculis ante odio. Nunc gravida erat convallis purus dignissim et ultricies orci dapibus. Aliquam erat volutpat. Vestibulum mi felis, malesuada ac tincidunt sit amet, pulvinar nec dolor. Pellentesque vehicula est vulputate mi adipiscing euismod. Donec ac mauris nulla. Nullam suscipit felis eu quam sodales ac bibendum nisi interdum. Curabitur non lectus a ante venenatis semper eget id justo. Ut facilisis, ligula pretium dictum congue, lacus dolor commodo nibh, sit amet sodales sed.</plot>
+ <icon></icon>
+ <genretype>20</genretype>
+ <genresubtype>0</genresubtype>
+ </entry>
+
+ <entry>
+ <broadcastid>1200</broadcastid>
+ <title>Demo Radio EPG entry #1</title>
+ <channelid>12</channelid>
+ <start>0</start>
+ <end>7200</end>
+ <plotoutline>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam cursus consectetur ipsum, eu tincidunt dui aliquam ac. Sed scelerisque, augue eu lacinia ultrices, libero ante ullamcorper augue, vel malesuada justo risus ac nulla. Quisque ac libero libero. Sed tincidunt, orci eu condimentum laoreet, felis odio mattis est, et lacinia metus enim in leo. Fusce faucibus tristique risus in varius. Etiam sagittis venenatis ligula nec rutrum. Etiam gravida dictum hendrerit. Sed sodales felis in sapien rutrum non malesuada nisi lobortis. Mauris iaculis ante odio. Nunc gravida erat convallis purus dignissim et ultricies orci dapibus. Aliquam erat volutpat. Vestibulum mi felis, malesuada ac tincidunt sit amet, pulvinar nec dolor. Pellentesque vehicula est vulputate mi adipiscing euismod. Donec ac mauris nulla. Nullam suscipit felis eu quam sodales ac bibendum nisi interdum. Curabitur non lectus a ante venenatis semper eget id justo. Ut facilisis, ligula pretium dictum congue, lacus dolor commodo nibh, sit amet sodales sed.</plotoutline>
+ <plot>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam cursus consectetur ipsum, eu tincidunt dui aliquam ac. Sed scelerisque, augue eu lacinia ultrices, libero ante ullamcorper augue, vel malesuada justo risus ac nulla. Quisque ac libero libero. Sed tincidunt, orci eu condimentum laoreet, felis odio mattis est, et lacinia metus enim in leo. Fusce faucibus tristique risus in varius. Etiam sagittis venenatis ligula nec rutrum. Etiam gravida dictum hendrerit. Sed sodales felis in sapien rutrum non malesuada nisi lobortis. Mauris iaculis ante odio. Nunc gravida erat convallis purus dignissim et ultricies orci dapibus. Aliquam erat volutpat. Vestibulum mi felis, malesuada ac tincidunt sit amet, pulvinar nec dolor. Pellentesque vehicula est vulputate mi adipiscing euismod. Donec ac mauris nulla. Nullam suscipit felis eu quam sodales ac bibendum nisi interdum. Curabitur non lectus a ante venenatis semper eget id justo. Ut facilisis, ligula pretium dictum congue, lacus dolor commodo nibh, sit amet sodales sed.</plot>
+ <icon></icon>
+ <genretype>30</genretype>
+ <genresubtype>0</genresubtype>
+ </entry>
+ <entry>
+ <broadcastid>1300</broadcastid>
+ <title>Demo Radio EPG entry #2</title>
+ <channelid>13</channelid>
+ <start>0</start>
+ <end>7200</end>
+ <plotoutline>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam cursus consectetur ipsum, eu tincidunt dui aliquam ac. Sed scelerisque, augue eu lacinia ultrices, libero ante ullamcorper augue, vel malesuada justo risus ac nulla. Quisque ac libero libero. Sed tincidunt, orci eu condimentum laoreet, felis odio mattis est, et lacinia metus enim in leo. Fusce faucibus tristique risus in varius. Etiam sagittis venenatis ligula nec rutrum. Etiam gravida dictum hendrerit. Sed sodales felis in sapien rutrum non malesuada nisi lobortis. Mauris iaculis ante odio. Nunc gravida erat convallis purus dignissim et ultricies orci dapibus. Aliquam erat volutpat. Vestibulum mi felis, malesuada ac tincidunt sit amet, pulvinar nec dolor. Pellentesque vehicula est vulputate mi adipiscing euismod. Donec ac mauris nulla. Nullam suscipit felis eu quam sodales ac bibendum nisi interdum. Curabitur non lectus a ante venenatis semper eget id justo. Ut facilisis, ligula pretium dictum congue, lacus dolor commodo nibh, sit amet sodales sed.</plotoutline>
+ <plot>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam cursus consectetur ipsum, eu tincidunt dui aliquam ac. Sed scelerisque, augue eu lacinia ultrices, libero ante ullamcorper augue, vel malesuada justo risus ac nulla. Quisque ac libero libero. Sed tincidunt, orci eu condimentum laoreet, felis odio mattis est, et lacinia metus enim in leo. Fusce faucibus tristique risus in varius. Etiam sagittis venenatis ligula nec rutrum. Etiam gravida dictum hendrerit. Sed sodales felis in sapien rutrum non malesuada nisi lobortis. Mauris iaculis ante odio. Nunc gravida erat convallis purus dignissim et ultricies orci dapibus. Aliquam erat volutpat. Vestibulum mi felis, malesuada ac tincidunt sit amet, pulvinar nec dolor. Pellentesque vehicula est vulputate mi adipiscing euismod. Donec ac mauris nulla. Nullam suscipit felis eu quam sodales ac bibendum nisi interdum. Curabitur non lectus a ante venenatis semper eget id justo. Ut facilisis, ligula pretium dictum congue, lacus dolor commodo nibh, sit amet sodales sed.</plot>
+ <icon></icon>
+ <genretype>10</genretype>
+ <genresubtype>0</genresubtype>
+ </entry>
+ <entry>
+ <broadcastid>1400</broadcastid>
+ <title>Demo Radio EPG entry #3</title>
+ <channelid>14</channelid>
+ <start>0</start>
+ <end>7200</end>
+ <plotoutline>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam cursus consectetur ipsum, eu tincidunt dui aliquam ac. Sed scelerisque, augue eu lacinia ultrices, libero ante ullamcorper augue, vel malesuada justo risus ac nulla. Quisque ac libero libero. Sed tincidunt, orci eu condimentum laoreet, felis odio mattis est, et lacinia metus enim in leo. Fusce faucibus tristique risus in varius. Etiam sagittis venenatis ligula nec rutrum. Etiam gravida dictum hendrerit. Sed sodales felis in sapien rutrum non malesuada nisi lobortis. Mauris iaculis ante odio. Nunc gravida erat convallis purus dignissim et ultricies orci dapibus. Aliquam erat volutpat. Vestibulum mi felis, malesuada ac tincidunt sit amet, pulvinar nec dolor. Pellentesque vehicula est vulputate mi adipiscing euismod. Donec ac mauris nulla. Nullam suscipit felis eu quam sodales ac bibendum nisi interdum. Curabitur non lectus a ante venenatis semper eget id justo. Ut facilisis, ligula pretium dictum congue, lacus dolor commodo nibh, sit amet sodales sed.</plotoutline>
+ <plot>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam cursus consectetur ipsum, eu tincidunt dui aliquam ac. Sed scelerisque, augue eu lacinia ultrices, libero ante ullamcorper augue, vel malesuada justo risus ac nulla. Quisque ac libero libero. Sed tincidunt, orci eu condimentum laoreet, felis odio mattis est, et lacinia metus enim in leo. Fusce faucibus tristique risus in varius. Etiam sagittis venenatis ligula nec rutrum. Etiam gravida dictum hendrerit. Sed sodales felis in sapien rutrum non malesuada nisi lobortis. Mauris iaculis ante odio. Nunc gravida erat convallis purus dignissim et ultricies orci dapibus. Aliquam erat volutpat. Vestibulum mi felis, malesuada ac tincidunt sit amet, pulvinar nec dolor. Pellentesque vehicula est vulputate mi adipiscing euismod. Donec ac mauris nulla. Nullam suscipit felis eu quam sodales ac bibendum nisi interdum. Curabitur non lectus a ante venenatis semper eget id justo. Ut facilisis, ligula pretium dictum congue, lacus dolor commodo nibh, sit amet sodales sed.</plot>
+ <icon></icon>
+ <genretype>20</genretype>
+ <genresubtype>0</genresubtype>
+ </entry>
+ <entry>
+ <broadcastid>1500</broadcastid>
+ <title>Demo Radio EPG entry #4</title>
+ <channelid>15</channelid>
+ <start>0</start>
+ <end>7200</end>
+ <plotoutline>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam cursus consectetur ipsum, eu tincidunt dui aliquam ac. Sed scelerisque, augue eu lacinia ultrices, libero ante ullamcorper augue, vel malesuada justo risus ac nulla. Quisque ac libero libero. Sed tincidunt, orci eu condimentum laoreet, felis odio mattis est, et lacinia metus enim in leo. Fusce faucibus tristique risus in varius. Etiam sagittis venenatis ligula nec rutrum. Etiam gravida dictum hendrerit. Sed sodales felis in sapien rutrum non malesuada nisi lobortis. Mauris iaculis ante odio. Nunc gravida erat convallis purus dignissim et ultricies orci dapibus. Aliquam erat volutpat. Vestibulum mi felis, malesuada ac tincidunt sit amet, pulvinar nec dolor. Pellentesque vehicula est vulputate mi adipiscing euismod. Donec ac mauris nulla. Nullam suscipit felis eu quam sodales ac bibendum nisi interdum. Curabitur non lectus a ante venenatis semper eget id justo. Ut facilisis, ligula pretium dictum congue, lacus dolor commodo nibh, sit amet sodales sed.</plotoutline>
+ <plot>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam cursus consectetur ipsum, eu tincidunt dui aliquam ac. Sed scelerisque, augue eu lacinia ultrices, libero ante ullamcorper augue, vel malesuada justo risus ac nulla. Quisque ac libero libero. Sed tincidunt, orci eu condimentum laoreet, felis odio mattis est, et lacinia metus enim in leo. Fusce faucibus tristique risus in varius. Etiam sagittis venenatis ligula nec rutrum. Etiam gravida dictum hendrerit. Sed sodales felis in sapien rutrum non malesuada nisi lobortis. Mauris iaculis ante odio. Nunc gravida erat convallis purus dignissim et ultricies orci dapibus. Aliquam erat volutpat. Vestibulum mi felis, malesuada ac tincidunt sit amet, pulvinar nec dolor. Pellentesque vehicula est vulputate mi adipiscing euismod. Donec ac mauris nulla. Nullam suscipit felis eu quam sodales ac bibendum nisi interdum. Curabitur non lectus a ante venenatis semper eget id justo. Ut facilisis, ligula pretium dictum congue, lacus dolor commodo nibh, sit amet sodales sed.</plot>
+ <icon></icon>
+ <genretype>30</genretype>
+ <genresubtype>0</genresubtype>
+ </entry>
+ <entry>
+ <broadcastid>1600</broadcastid>
+ <title>Demo Radio EPG entry #5</title>
+ <channelid>16</channelid>
+ <start>0</start>
+ <end>7200</end>
+ <plotoutline>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam cursus consectetur ipsum, eu tincidunt dui aliquam ac. Sed scelerisque, augue eu lacinia ultrices, libero ante ullamcorper augue, vel malesuada justo risus ac nulla. Quisque ac libero libero. Sed tincidunt, orci eu condimentum laoreet, felis odio mattis est, et lacinia metus enim in leo. Fusce faucibus tristique risus in varius. Etiam sagittis venenatis ligula nec rutrum. Etiam gravida dictum hendrerit. Sed sodales felis in sapien rutrum non malesuada nisi lobortis. Mauris iaculis ante odio. Nunc gravida erat convallis purus dignissim et ultricies orci dapibus. Aliquam erat volutpat. Vestibulum mi felis, malesuada ac tincidunt sit amet, pulvinar nec dolor. Pellentesque vehicula est vulputate mi adipiscing euismod. Donec ac mauris nulla. Nullam suscipit felis eu quam sodales ac bibendum nisi interdum. Curabitur non lectus a ante venenatis semper eget id justo. Ut facilisis, ligula pretium dictum congue, lacus dolor commodo nibh, sit amet sodales sed.</plotoutline>
+ <plot>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam cursus consectetur ipsum, eu tincidunt dui aliquam ac. Sed scelerisque, augue eu lacinia ultrices, libero ante ullamcorper augue, vel malesuada justo risus ac nulla. Quisque ac libero libero. Sed tincidunt, orci eu condimentum laoreet, felis odio mattis est, et lacinia metus enim in leo. Fusce faucibus tristique risus in varius. Etiam sagittis venenatis ligula nec rutrum. Etiam gravida dictum hendrerit. Sed sodales felis in sapien rutrum non malesuada nisi lobortis. Mauris iaculis ante odio. Nunc gravida erat convallis purus dignissim et ultricies orci dapibus. Aliquam erat volutpat. Vestibulum mi felis, malesuada ac tincidunt sit amet, pulvinar nec dolor. Pellentesque vehicula est vulputate mi adipiscing euismod. Donec ac mauris nulla. Nullam suscipit felis eu quam sodales ac bibendum nisi interdum. Curabitur non lectus a ante venenatis semper eget id justo. Ut facilisis, ligula pretium dictum congue, lacus dolor commodo nibh, sit amet sodales sed.</plot>
+ <icon></icon>
+ <genretype>10</genretype>
+ <genresubtype>0</genresubtype>
+ </entry>
+ <entry>
+ <broadcastid>1700</broadcastid>
+ <title>Demo Radio EPG entry #6</title>
+ <channelid>17</channelid>
+ <start>0</start>
+ <end>7200</end>
+ <plotoutline>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam cursus consectetur ipsum, eu tincidunt dui aliquam ac. Sed scelerisque, augue eu lacinia ultrices, libero ante ullamcorper augue, vel malesuada justo risus ac nulla. Quisque ac libero libero. Sed tincidunt, orci eu condimentum laoreet, felis odio mattis est, et lacinia metus enim in leo. Fusce faucibus tristique risus in varius. Etiam sagittis venenatis ligula nec rutrum. Etiam gravida dictum hendrerit. Sed sodales felis in sapien rutrum non malesuada nisi lobortis. Mauris iaculis ante odio. Nunc gravida erat convallis purus dignissim et ultricies orci dapibus. Aliquam erat volutpat. Vestibulum mi felis, malesuada ac tincidunt sit amet, pulvinar nec dolor. Pellentesque vehicula est vulputate mi adipiscing euismod. Donec ac mauris nulla. Nullam suscipit felis eu quam sodales ac bibendum nisi interdum. Curabitur non lectus a ante venenatis semper eget id justo. Ut facilisis, ligula pretium dictum congue, lacus dolor commodo nibh, sit amet sodales sed.</plotoutline>
+ <plot>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam cursus consectetur ipsum, eu tincidunt dui aliquam ac. Sed scelerisque, augue eu lacinia ultrices, libero ante ullamcorper augue, vel malesuada justo risus ac nulla. Quisque ac libero libero. Sed tincidunt, orci eu condimentum laoreet, felis odio mattis est, et lacinia metus enim in leo. Fusce faucibus tristique risus in varius. Etiam sagittis venenatis ligula nec rutrum. Etiam gravida dictum hendrerit. Sed sodales felis in sapien rutrum non malesuada nisi lobortis. Mauris iaculis ante odio. Nunc gravida erat convallis purus dignissim et ultricies orci dapibus. Aliquam erat volutpat. Vestibulum mi felis, malesuada ac tincidunt sit amet, pulvinar nec dolor. Pellentesque vehicula est vulputate mi adipiscing euismod. Donec ac mauris nulla. Nullam suscipit felis eu quam sodales ac bibendum nisi interdum. Curabitur non lectus a ante venenatis semper eget id justo. Ut facilisis, ligula pretium dictum congue, lacus dolor commodo nibh, sit amet sodales sed.</plot>
+ <icon></icon>
+ <genretype>20</genretype>
+ <genresubtype>0</genresubtype>
+ </entry>
+ <entry>
+ <broadcastid>1800</broadcastid>
+ <title>Demo Radio EPG entry #7</title>
+ <channelid>18</channelid>
+ <start>0</start>
+ <end>7200</end>
+ <plotoutline>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam cursus consectetur ipsum, eu tincidunt dui aliquam ac. Sed scelerisque, augue eu lacinia ultrices, libero ante ullamcorper augue, vel malesuada justo risus ac nulla. Quisque ac libero libero. Sed tincidunt, orci eu condimentum laoreet, felis odio mattis est, et lacinia metus enim in leo. Fusce faucibus tristique risus in varius. Etiam sagittis venenatis ligula nec rutrum. Etiam gravida dictum hendrerit. Sed sodales felis in sapien rutrum non malesuada nisi lobortis. Mauris iaculis ante odio. Nunc gravida erat convallis purus dignissim et ultricies orci dapibus. Aliquam erat volutpat. Vestibulum mi felis, malesuada ac tincidunt sit amet, pulvinar nec dolor. Pellentesque vehicula est vulputate mi adipiscing euismod. Donec ac mauris nulla. Nullam suscipit felis eu quam sodales ac bibendum nisi interdum. Curabitur non lectus a ante venenatis semper eget id justo. Ut facilisis, ligula pretium dictum congue, lacus dolor commodo nibh, sit amet sodales sed.</plotoutline>
+ <plot>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam cursus consectetur ipsum, eu tincidunt dui aliquam ac. Sed scelerisque, augue eu lacinia ultrices, libero ante ullamcorper augue, vel malesuada justo risus ac nulla. Quisque ac libero libero. Sed tincidunt, orci eu condimentum laoreet, felis odio mattis est, et lacinia metus enim in leo. Fusce faucibus tristique risus in varius. Etiam sagittis venenatis ligula nec rutrum. Etiam gravida dictum hendrerit. Sed sodales felis in sapien rutrum non malesuada nisi lobortis. Mauris iaculis ante odio. Nunc gravida erat convallis purus dignissim et ultricies orci dapibus. Aliquam erat volutpat. Vestibulum mi felis, malesuada ac tincidunt sit amet, pulvinar nec dolor. Pellentesque vehicula est vulputate mi adipiscing euismod. Donec ac mauris nulla. Nullam suscipit felis eu quam sodales ac bibendum nisi interdum. Curabitur non lectus a ante venenatis semper eget id justo. Ut facilisis, ligula pretium dictum congue, lacus dolor commodo nibh, sit amet sodales sed.</plot>
+ <icon></icon>
+ <genretype>30</genretype>
+ <genresubtype>0</genresubtype>
+ </entry>
+ <entry>
+ <broadcastid>1900</broadcastid>
+ <title>Demo Radio EPG entry #8</title>
+ <channelid>19</channelid>
+ <start>0</start>
+ <end>7200</end>
+ <plotoutline>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam cursus consectetur ipsum, eu tincidunt dui aliquam ac. Sed scelerisque, augue eu lacinia ultrices, libero ante ullamcorper augue, vel malesuada justo risus ac nulla. Quisque ac libero libero. Sed tincidunt, orci eu condimentum laoreet, felis odio mattis est, et lacinia metus enim in leo. Fusce faucibus tristique risus in varius. Etiam sagittis venenatis ligula nec rutrum. Etiam gravida dictum hendrerit. Sed sodales felis in sapien rutrum non malesuada nisi lobortis. Mauris iaculis ante odio. Nunc gravida erat convallis purus dignissim et ultricies orci dapibus. Aliquam erat volutpat. Vestibulum mi felis, malesuada ac tincidunt sit amet, pulvinar nec dolor. Pellentesque vehicula est vulputate mi adipiscing euismod. Donec ac mauris nulla. Nullam suscipit felis eu quam sodales ac bibendum nisi interdum. Curabitur non lectus a ante venenatis semper eget id justo. Ut facilisis, ligula pretium dictum congue, lacus dolor commodo nibh, sit amet sodales sed.</plotoutline>
+ <plot>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam cursus consectetur ipsum, eu tincidunt dui aliquam ac. Sed scelerisque, augue eu lacinia ultrices, libero ante ullamcorper augue, vel malesuada justo risus ac nulla. Quisque ac libero libero. Sed tincidunt, orci eu condimentum laoreet, felis odio mattis est, et lacinia metus enim in leo. Fusce faucibus tristique risus in varius. Etiam sagittis venenatis ligula nec rutrum. Etiam gravida dictum hendrerit. Sed sodales felis in sapien rutrum non malesuada nisi lobortis. Mauris iaculis ante odio. Nunc gravida erat convallis purus dignissim et ultricies orci dapibus. Aliquam erat volutpat. Vestibulum mi felis, malesuada ac tincidunt sit amet, pulvinar nec dolor. Pellentesque vehicula est vulputate mi adipiscing euismod. Donec ac mauris nulla. Nullam suscipit felis eu quam sodales ac bibendum nisi interdum. Curabitur non lectus a ante venenatis semper eget id justo. Ut facilisis, ligula pretium dictum congue, lacus dolor commodo nibh, sit amet sodales sed.</plot>
+ <icon></icon>
+ <genretype>10</genretype>
+ <genresubtype>0</genresubtype>
+ </entry>
+ <entry>
+ <broadcastid>2000</broadcastid>
+ <title>Demo Radio EPG entry #9</title>
+ <channelid>20</channelid>
+ <start>0</start>
+ <end>7200</end>
+ <plotoutline>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam cursus consectetur ipsum, eu tincidunt dui aliquam ac. Sed scelerisque, augue eu lacinia ultrices, libero ante ullamcorper augue, vel malesuada justo risus ac nulla. Quisque ac libero libero. Sed tincidunt, orci eu condimentum laoreet, felis odio mattis est, et lacinia metus enim in leo. Fusce faucibus tristique risus in varius. Etiam sagittis venenatis ligula nec rutrum. Etiam gravida dictum hendrerit. Sed sodales felis in sapien rutrum non malesuada nisi lobortis. Mauris iaculis ante odio. Nunc gravida erat convallis purus dignissim et ultricies orci dapibus. Aliquam erat volutpat. Vestibulum mi felis, malesuada ac tincidunt sit amet, pulvinar nec dolor. Pellentesque vehicula est vulputate mi adipiscing euismod. Donec ac mauris nulla. Nullam suscipit felis eu quam sodales ac bibendum nisi interdum. Curabitur non lectus a ante venenatis semper eget id justo. Ut facilisis, ligula pretium dictum congue, lacus dolor commodo nibh, sit amet sodales sed.</plotoutline>
+ <plot>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam cursus consectetur ipsum, eu tincidunt dui aliquam ac. Sed scelerisque, augue eu lacinia ultrices, libero ante ullamcorper augue, vel malesuada justo risus ac nulla. Quisque ac libero libero. Sed tincidunt, orci eu condimentum laoreet, felis odio mattis est, et lacinia metus enim in leo. Fusce faucibus tristique risus in varius. Etiam sagittis venenatis ligula nec rutrum. Etiam gravida dictum hendrerit. Sed sodales felis in sapien rutrum non malesuada nisi lobortis. Mauris iaculis ante odio. Nunc gravida erat convallis purus dignissim et ultricies orci dapibus. Aliquam erat volutpat. Vestibulum mi felis, malesuada ac tincidunt sit amet, pulvinar nec dolor. Pellentesque vehicula est vulputate mi adipiscing euismod. Donec ac mauris nulla. Nullam suscipit felis eu quam sodales ac bibendum nisi interdum. Curabitur non lectus a ante venenatis semper eget id justo. Ut facilisis, ligula pretium dictum congue, lacus dolor commodo nibh, sit amet sodales sed.</plot>
+ <icon></icon>
+ <genretype>20</genretype>
+ <genresubtype>0</genresubtype>
+ </entry>
+ <entry>
+ <broadcastid>2100</broadcastid>
+ <title>Demo Radio EPG entry #10</title>
+ <channelid>21</channelid>
+ <start>0</start>
+ <end>7200</end>
+ <plotoutline>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam cursus consectetur ipsum, eu tincidunt dui aliquam ac. Sed scelerisque, augue eu lacinia ultrices, libero ante ullamcorper augue, vel malesuada justo risus ac nulla. Quisque ac libero libero. Sed tincidunt, orci eu condimentum laoreet, felis odio mattis est, et lacinia metus enim in leo. Fusce faucibus tristique risus in varius. Etiam sagittis venenatis ligula nec rutrum. Etiam gravida dictum hendrerit. Sed sodales felis in sapien rutrum non malesuada nisi lobortis. Mauris iaculis ante odio. Nunc gravida erat convallis purus dignissim et ultricies orci dapibus. Aliquam erat volutpat. Vestibulum mi felis, malesuada ac tincidunt sit amet, pulvinar nec dolor. Pellentesque vehicula est vulputate mi adipiscing euismod. Donec ac mauris nulla. Nullam suscipit felis eu quam sodales ac bibendum nisi interdum. Curabitur non lectus a ante venenatis semper eget id justo. Ut facilisis, ligula pretium dictum congue, lacus dolor commodo nibh, sit amet sodales sed.</plotoutline>
+ <plot>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam cursus consectetur ipsum, eu tincidunt dui aliquam ac. Sed scelerisque, augue eu lacinia ultrices, libero ante ullamcorper augue, vel malesuada justo risus ac nulla. Quisque ac libero libero. Sed tincidunt, orci eu condimentum laoreet, felis odio mattis est, et lacinia metus enim in leo. Fusce faucibus tristique risus in varius. Etiam sagittis venenatis ligula nec rutrum. Etiam gravida dictum hendrerit. Sed sodales felis in sapien rutrum non malesuada nisi lobortis. Mauris iaculis ante odio. Nunc gravida erat convallis purus dignissim et ultricies orci dapibus. Aliquam erat volutpat. Vestibulum mi felis, malesuada ac tincidunt sit amet, pulvinar nec dolor. Pellentesque vehicula est vulputate mi adipiscing euismod. Donec ac mauris nulla. Nullam suscipit felis eu quam sodales ac bibendum nisi interdum. Curabitur non lectus a ante venenatis semper eget id justo. Ut facilisis, ligula pretium dictum congue, lacus dolor commodo nibh, sit amet sodales sed.</plot>
+ <icon></icon>
+ <genretype>30</genretype>
+ <genresubtype>0</genresubtype>
+ </entry>
+
+ </epg>
+</demo>
View
27 xbmc/pvrclients/pvr-demo/Makefile.in
@@ -0,0 +1,27 @@
+#
+# Makefile for the XBMC PVR Demo add-on
+#
+# See the README for copyright information and
+# how to reach the author.
+#
+
+LIBS = @abs_top_srcdir@/lib/libTcpSocket/libTcpSocket.a @abs_top_srcdir@/lib/tinyXML/tinyxml.a -ldl
+LIBDIR = @abs_top_srcdir@/addons/pvr.demo
+LIB = @abs_top_srcdir@/addons/pvr.demo/XBMC_demo.pvr
+
+SRCS=client.cpp \
+ thread.cpp \
+ tools.cpp \
+ PVRDemoData.cpp
+
+include ../Makefile.include
+
+clean:
+ -rm -f $(OBJS) $(LIB) *.P *~
+ $(MAKE) -C @abs_top_srcdir@/lib/libTcpSocket clean
+ ${MAKE} -C @abs_top_srcdir@/lib/tinyXML clean
+
+$(LIB): $(OBJS)
+ ${MAKE} -C @abs_top_srcdir@/lib/libTcpSocket
+ ${MAKE} -C @abs_top_srcdir@/lib/tinyXML
+ $(CXX) $(CXXFLAGS) $(LDFLAGS) -shared -g $(OBJS) $(LIBS) $(LIBDIRS) $(SILIB) -o $(LIB)
View
360 xbmc/pvrclients/pvr-demo/PVRDemoData.cpp
@@ -0,0 +1,360 @@
+/*
+ * Copyright (C) 2011 Pulse-Eight
+ * http://www.pulse-eight.com/
+ *
+ * This Program 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, or (at your option)
+ * any later version.
+ *
+ * This Program 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 XBMC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "utils/XMLUtils.h"
+#include "PVRDemoData.h"
+/* hack hack */
+#include "filesystem/SpecialProtocol.h"
+
+using namespace std;
+using namespace ADDON;
+
+PVRDemoData::PVRDemoData(void)
+{
+ m_iEpgStart = -1;
+ m_strDefaultIcon = "http://www.royalty-free.tv/news/wp-content/uploads/2011/06/cc-logo1.jpg";
+ m_strDefaultMovie = "";
+
+ LoadDemoData();
+}
+
+PVRDemoData::~PVRDemoData(void)
+{
+ m_channels.clear();
+ m_groups.clear();
+}
+
+std::string PVRDemoData::GetSettingsFile() const
+{
+ return _P("special://xbmc/system/PVRDemoAddonSettings.xml");
+}
+
+bool PVRDemoData::LoadDemoData(void)
+{
+ TiXmlDocument xmlDoc;
+
+ if (!xmlDoc.LoadFile(GetSettingsFile()))
+ {
+ XBMC->Log(LOG_ERROR, "invalid demo data (no/invalid data file found)");
+ return false;
+ }
+
+ TiXmlElement *pRootElement = xmlDoc.RootElement();
+ if (strcmp(pRootElement->Value(), "demo") != 0)
+ {
+ XBMC->Log(LOG_ERROR, "invalid demo data (no <demo> tag found)");
+ return false;
+ }
+
+ /* load channels */
+ int iUniqueChannelId = 0;
+ TiXmlElement *pElement = pRootElement->FirstChildElement("channels");
+ if (pElement)
+ {
+ TiXmlNode *pChannelNode = NULL;
+ while ((pChannelNode = pElement->IterateChildren(pChannelNode)) != NULL)
+ {
+ CStdString strTmp;
+ PVRDemoChannel channel;
+ channel.iUniqueId = ++iUniqueChannelId;
+
+ /* channel name */
+ if (!XMLUtils::GetString(pChannelNode, "name", strTmp))
+ continue;
+ channel.strChannelName = strTmp;
+
+ /* radio/TV */
+ XMLUtils::GetBoolean(pChannelNode, "radio", channel.bRadio);
+
+ /* channel number */
+ if (!XMLUtils::GetInt(pChannelNode, "number", channel.iChannelNumber))
+ channel.iChannelNumber = iUniqueChannelId;
+
+ /* CAID */
+ if (!XMLUtils::GetInt(pChannelNode, "encryption", channel.iEncryptionSystem))
+ channel.iEncryptionSystem = 0;
+
+ /* icon path */
+ if (!XMLUtils::GetString(pChannelNode, "icon", strTmp))
+ channel.strIconPath = m_strDefaultIcon;
+ else
+ channel.strIconPath = strTmp;
+
+ /* stream url */
+ if (!XMLUtils::GetString(pChannelNode, "stream", strTmp))
+ channel.strStreamURL = m_strDefaultMovie;
+ else
+ channel.strStreamURL = strTmp;
+
+ m_channels.push_back(channel);
+ }
+ }
+
+ /* load channel groups */
+ int iUniqueGroupId = 0;
+ pElement = pRootElement->FirstChildElement("channelgroups");
+ if (pElement)
+ {
+ TiXmlNode *pGroupNode = NULL;
+ while ((pGroupNode = pElement->IterateChildren(pGroupNode)) != NULL)
+ {
+ CStdString strTmp;
+ PVRDemoChannelGroup group;
+ group.iGroupId = ++iUniqueGroupId;
+
+ /* group name */
+ if (!XMLUtils::GetString(pGroupNode, "name", strTmp))
+ continue;
+ group.strGroupName = strTmp;
+
+ /* radio/TV */
+ XMLUtils::GetBoolean(pGroupNode, "radio", group.bRadio);
+
+ /* members */
+ TiXmlNode* pMembers = pGroupNode->FirstChild("members");
+ TiXmlNode *pMemberNode = NULL;
+ while (pMembers != NULL && (pMemberNode = pMembers->IterateChildren(pMemberNode)) != NULL)
+ {
+ int iChannelId = atoi(pMemberNode->FirstChild()->Value());
+ if (iChannelId > -1)
+ group.members.push_back(iChannelId);
+ }
+
+ m_groups.push_back(group);
+ }
+ }
+
+ /* load EPG entries */
+ pElement = pRootElement->FirstChildElement("epg");
+ if (pElement)
+ {
+ TiXmlNode *pEpgNode = NULL;
+ while ((pEpgNode = pElement->IterateChildren(pEpgNode)) != NULL)
+ {
+ CStdString strTmp;
+ int iTmp;
+ PVRDemoEpgEntry entry;
+
+ /* broadcast id */
+ if (!XMLUtils::GetInt(pEpgNode, "broadcastid", entry.iBroadcastId))
+ continue;
+
+ /* channel id */
+ if (!XMLUtils::GetInt(pEpgNode, "channelid", iTmp))
+ continue;
+ PVRDemoChannel &channel = m_channels.at(iTmp - 1);
+ entry.iChannelId = channel.iUniqueId;
+
+ /* title */
+ if (!XMLUtils::GetString(pEpgNode, "title", strTmp))
+ continue;
+ entry.strTitle = strTmp;
+
+ /* start */
+ if (!XMLUtils::GetInt(pEpgNode, "start", iTmp))
+ continue;
+ entry.startTime = iTmp;
+
+ /* end */
+ if (!XMLUtils::GetInt(pEpgNode, "end", iTmp))
+ continue;
+ entry.endTime = iTmp;
+
+ /* plot */
+ if (XMLUtils::GetString(pEpgNode, "plot", strTmp))
+ entry.strPlot = strTmp;
+
+ /* plot outline */
+ if (XMLUtils::GetString(pEpgNode, "plotoutline", strTmp))
+ entry.strPlotOutline = strTmp;
+
+ /* icon path */
+ if (XMLUtils::GetString(pEpgNode, "icon", strTmp))
+ entry.strIconPath = strTmp;
+
+ /* genre type */
+ XMLUtils::GetInt(pEpgNode, "genretype", entry.iGenreType);
+
+ /* genre subtype */
+ XMLUtils::GetInt(pEpgNode, "genresubtype", entry.iGenreSubType);
+
+ XBMC->Log(LOG_DEBUG, "loaded EPG entry '%s' channel '%d' start '%d' end '%d'", entry.strTitle.c_str(), entry.iChannelId, entry.startTime, entry.endTime);
+ channel.epg.push_back(entry);
+ }
+ }
+
+ return true;
+}
+
+int PVRDemoData::GetChannelsAmount(void)
+{
+ return m_channels.size();
+}
+
+PVR_ERROR PVRDemoData::GetChannels(PVR_HANDLE handle, bool bRadio)
+{
+ for (unsigned int iChannelPtr = 0; iChannelPtr < m_channels.size(); iChannelPtr++)
+ {
+ PVRDemoChannel &channel = m_channels.at(iChannelPtr);
+ if (channel.bRadio == bRadio)
+ {
+ PVR_CHANNEL xbmcChannel;
+ memset(&xbmcChannel, 0, sizeof(PVR_CHANNEL));
+
+ xbmcChannel.iUniqueId = channel.iUniqueId;
+ xbmcChannel.bIsRadio = channel.bRadio;
+ xbmcChannel.iChannelNumber = channel.iChannelNumber;
+ xbmcChannel.strChannelName = channel.strChannelName.c_str();
+ xbmcChannel.strInputFormat = ""; // unused
+ xbmcChannel.strStreamURL = channel.strStreamURL.c_str();
+ xbmcChannel.iEncryptionSystem = channel.iEncryptionSystem;
+ xbmcChannel.strIconPath = channel.strIconPath.c_str();
+ xbmcChannel.bIsHidden = false;
+
+ PVR->TransferChannelEntry(handle, &xbmcChannel);
+ }
+ }
+
+ return PVR_ERROR_NO_ERROR;
+}
+
+bool PVRDemoData::GetChannel(const PVR_CHANNEL &channel, PVRDemoChannel &myChannel)
+{
+ for (unsigned int iChannelPtr = 0; iChannelPtr < m_channels.size(); iChannelPtr++)
+ {
+ PVRDemoChannel &thisChannel = m_channels.at(iChannelPtr);
+ if (thisChannel.iUniqueId == (int) channel.iUniqueId)
+ {
+ myChannel.iUniqueId = thisChannel.iUniqueId;
+ myChannel.bRadio = thisChannel.bRadio;
+ myChannel.iChannelNumber = thisChannel.iChannelNumber;
+ myChannel.iEncryptionSystem = thisChannel.iEncryptionSystem;
+ myChannel.strChannelName = thisChannel.strChannelName;
+ myChannel.strIconPath = thisChannel.strIconPath;
+ myChannel.strStreamURL = thisChannel.strStreamURL;
+
+ return true;
+ }
+ }
+
+ return false;
+}
+
+int PVRDemoData::GetChannelGroupsAmount(void)
+{
+ return m_groups.size();
+}
+
+PVR_ERROR PVRDemoData::GetChannelGroups(PVR_HANDLE handle, bool bRadio)
+{
+ for (unsigned int iGroupPtr = 0; iGroupPtr < m_groups.size(); iGroupPtr++)
+ {
+ PVRDemoChannelGroup &group = m_groups.at(iGroupPtr);
+ if (group.bRadio == bRadio)
+ {
+ PVR_CHANNEL_GROUP xbmcGroup;
+ memset(&xbmcGroup, 0, sizeof(PVR_CHANNEL_GROUP));
+
+ xbmcGroup.bIsRadio = bRadio;
+ xbmcGroup.strGroupName = group.strGroupName.c_str();
+
+ PVR->TransferChannelGroup(handle, &xbmcGroup);
+ }
+ }
+
+ return PVR_ERROR_NO_ERROR;
+}
+
+PVR_ERROR PVRDemoData::GetChannelGroupMembers(PVR_HANDLE handle, const PVR_CHANNEL_GROUP &group)
+{
+ for (unsigned int iGroupPtr = 0; iGroupPtr < m_groups.size(); iGroupPtr++)
+ {
+ PVRDemoChannelGroup &myGroup = m_groups.at(iGroupPtr);
+ if (myGroup.strGroupName == group.strGroupName)
+ {
+ for (unsigned int iChannelPtr = 0; iChannelPtr < myGroup.members.size(); iChannelPtr++)
+ {
+ int iId = myGroup.members.at(iChannelPtr) - 1;
+ if (iId < 0 || iId > (int)m_channels.size() - 1)
+ continue;
+ PVRDemoChannel &channel = m_channels.at(iId);
+ PVR_CHANNEL_GROUP_MEMBER xbmcGroupMember;
+ memset(&xbmcGroupMember, 0, sizeof(PVR_CHANNEL_GROUP_MEMBER));
+
+ xbmcGroupMember.strGroupName = group.strGroupName;
+ xbmcGroupMember.iChannelUniqueId = channel.iUniqueId;
+ xbmcGroupMember.iChannelNumber = channel.iChannelNumber;
+
+ PVR->TransferChannelGroupMember(handle, &xbmcGroupMember);
+ }
+ }
+ }
+
+ return PVR_ERROR_NO_ERROR;
+}
+
+PVR_ERROR PVRDemoData::GetEPGForChannel(PVR_HANDLE handle, const PVR_CHANNEL &channel, time_t iStart, time_t iEnd)
+{
+ if (m_iEpgStart == -1)
+ m_iEpgStart = iStart;
+
+ time_t iLastEndTime = m_iEpgStart + 1;
+ int iAddBroadcastId = 0;
+
+ for (unsigned int iChannelPtr = 0; iChannelPtr < m_channels.size(); iChannelPtr++)
+ {
+ PVRDemoChannel &myChannel = m_channels.at(iChannelPtr);
+ if (myChannel.iUniqueId != (int) channel.iUniqueId)
+ continue;
+
+ while (iLastEndTime < iEnd && myChannel.epg.size() > 0)
+ {
+ time_t iLastEndTimeTmp = 0;
+ for (unsigned int iEntryPtr = 0; iEntryPtr < myChannel.epg.size(); iEntryPtr++)
+ {
+ PVRDemoEpgEntry &myTag = myChannel.epg.at(iEntryPtr);
+
+ EPG_TAG tag;
+ memset(&tag, 0, sizeof(EPG_TAG));
+
+ tag.iUniqueBroadcastId = myTag.iBroadcastId + iAddBroadcastId;
+ tag.strTitle = myTag.strTitle.c_str();
+ tag.iChannelNumber = myTag.iChannelId;
+ tag.startTime = myTag.startTime + iLastEndTime;
+ tag.endTime = myTag.endTime + iLastEndTime;
+ tag.strPlotOutline = myTag.strPlotOutline.c_str();
+ tag.strPlot = myTag.strPlot.c_str();
+ tag.strIconPath = myTag.strIconPath.c_str();
+ tag.iGenreType = myTag.iGenreType;
+ tag.iGenreSubType = myTag.iGenreSubType;
+
+ iLastEndTimeTmp = tag.endTime;
+
+ PVR->TransferEpgEntry(handle, &tag);
+ }
+
+ iLastEndTime = iLastEndTimeTmp;
+ iAddBroadcastId += myChannel.epg.size();
+ }
+ }
+
+ return PVR_ERROR_NO_ERROR;
+}
View
94 xbmc/pvrclients/pvr-demo/PVRDemoData.h
@@ -0,0 +1,94 @@
+#pragma once
+/*
+ * Copyright (C) 2011 Pulse-Eight
+ * http://www.pulse-eight.com/
+ *
+ * This Program 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, or (at your option)
+ * any later version.
+ *
+ * This Program 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 XBMC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include <vector>
+#include "utils/StdString.h"
+#include "client.h"
+
+struct PVRDemoEpgEntry
+{
+ int iBroadcastId;
+ std::string strTitle;
+ int iChannelId;
+ time_t startTime;
+ time_t endTime;
+ std::string strPlotOutline;
+ std::string strPlot;
+ std::string strIconPath;
+ int iGenreType;
+ int iGenreSubType;
+// time_t firstAired;
+// int iParentalRating;
+// int iStarRating;
+// bool bNotify;
+// int iSeriesNumber;
+// int iEpisodeNumber;
+// int iEpisodePartNumber;
+// std::string strEpisodeName;
+};
+
+struct PVRDemoChannel
+{
+ bool bRadio;
+ int iUniqueId;
+ int iChannelNumber;
+ int iEncryptionSystem;
+ std::string strChannelName;
+ std::string strIconPath;
+ std::string strStreamURL;
+ std::vector<PVRDemoEpgEntry> epg;
+};
+
+struct PVRDemoChannelGroup
+{
+ bool bRadio;
+ int iGroupId;
+ std::string strGroupName;
+ std::vector<int> members;
+};
+
+class PVRDemoData
+{
+public:
+ PVRDemoData(void);
+ virtual ~PVRDemoData(void);
+
+ virtual int GetChannelsAmount(void);
+ virtual PVR_ERROR GetChannels(PVR_HANDLE handle, bool bRadio);
+ virtual bool GetChannel(const PVR_CHANNEL &channel, PVRDemoChannel &myChannel);
+
+ virtual int GetChannelGroupsAmount(void);
+ virtual PVR_ERROR GetChannelGroups(PVR_HANDLE handle, bool bRadio);
+ virtual PVR_ERROR GetChannelGroupMembers(PVR_HANDLE handle, const PVR_CHANNEL_GROUP &group);
+
+ virtual PVR_ERROR GetEPGForChannel(PVR_HANDLE handle, const PVR_CHANNEL &channel, time_t iStart, time_t iEnd);
+
+ virtual std::string GetSettingsFile() const;
+protected:
+ virtual bool LoadDemoData(void);
+private:
+ std::vector<PVRDemoChannelGroup> m_groups;
+ std::vector<PVRDemoChannel> m_channels;
+ time_t m_iEpgStart;
+ CStdString m_strDefaultIcon;
+ CStdString m_strDefaultMovie;
+};
View
291 xbmc/pvrclients/pvr-demo/client.cpp
@@ -0,0 +1,291 @@
+/*
+ * Copyright (C) 2011 Pulse-Eight
+ * http://www.pulse-eight.com/
+ *
+ * This Program 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, or (at your option)
+ * any later version.
+ *
+ * This Program 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 XBMC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "client.h"
+#include "xbmc_pvr_dll.h"
+#include "tools.h"
+#include "PVRDemoData.h"
+
+using namespace std;
+using namespace ADDON;
+
+bool m_bCreated = false;
+ADDON_STATUS m_CurStatus = ADDON_STATUS_UNKNOWN;
+int g_iClientId = -1;
+PVRDemoData *m_data = NULL;
+bool m_bIsPlaying = false;
+PVRDemoChannel m_currentChannel;
+
+/* User adjustable settings are saved here.
+ * Default values are defined inside client.h
+ * and exported to the other source files.
+ */
+std::string g_strUserPath = "";
+std::string g_strClientPath = "";
+
+CHelper_libXBMC_addon *XBMC = NULL;
+CHelper_libXBMC_pvr *PVR = NULL;
+
+extern "C" {
+
+void ADDON_ReadSettings(void)
+{
+ //STUB
+}
+
+ADDON_STATUS ADDON_Create(void* hdl, void* props)
+{
+ if (!hdl || !props)
+ return ADDON_STATUS_UNKNOWN;
+
+ PVR_PROPERTIES* pvrprops = (PVR_PROPERTIES*)props;
+
+ XBMC = new CHelper_libXBMC_addon;
+ if (!XBMC->RegisterMe(hdl))
+ return ADDON_STATUS_UNKNOWN;
+
+ PVR = new CHelper_libXBMC_pvr;
+ if (!PVR->RegisterMe(hdl))
+ return ADDON_STATUS_UNKNOWN;
+
+ XBMC->Log(LOG_DEBUG, "%s - Creating the PVR demo add-on", __FUNCTION__);
+
+ m_CurStatus = ADDON_STATUS_UNKNOWN;
+ g_iClientId = pvrprops->iClientId;
+ g_strUserPath = pvrprops->strUserPath;
+ g_strClientPath = pvrprops->strClientPath;
+
+ ADDON_ReadSettings();
+
+ m_data = new PVRDemoData;
+ m_CurStatus = ADDON_STATUS_OK;
+ m_bCreated = true;
+ return m_CurStatus;
+}
+
+ADDON_STATUS ADDON_GetStatus()
+{
+ return m_CurStatus;
+}
+
+void ADDON_Destroy()
+{
+ delete m_data;
+ m_bCreated = false;
+ m_CurStatus = ADDON_STATUS_UNKNOWN;
+}
+
+bool ADDON_HasSettings()
+{
+ return true;
+}
+
+unsigned int ADDON_GetSettings(ADDON_StructSetting ***sSet)
+{
+ return 0;
+}
+
+ADDON_STATUS ADDON_SetSetting(const char *settingName, const void *settingValue)
+{
+ return ADDON_STATUS_OK;
+}
+
+void ADDON_Stop()
+{
+}
+
+void ADDON_FreeSettings()
+{
+}
+
+/***********************************************************
+ * PVR Client AddOn specific public library functions
+ ***********************************************************/
+
+PVR_ERROR GetAddonCapabilities(PVR_ADDON_CAPABILITIES* pCapabilities)
+{
+ pCapabilities->bSupportsChannelSettings = false;
+ pCapabilities->bSupportsTimeshift = false;
+ pCapabilities->bSupportsEPG = true;
+ pCapabilities->bSupportsTV = true;
+ pCapabilities->bSupportsRadio = true;
+ pCapabilities->bSupportsRecordings = false;
+ pCapabilities->bSupportsTimers = false;
+ pCapabilities->bSupportsChannelGroups = true;
+ pCapabilities->bSupportsChannelScan = false;
+ pCapabilities->bHandlesInputStream = false;
+ pCapabilities->bHandlesDemuxing = false;
+
+ return PVR_ERROR_NO_ERROR;
+}
+
+const char *GetBackendName(void)
+{
+ static const char *strBackendName = "pulse-eight demo pvr add-on";
+ return strBackendName;
+}
+
+const char *GetBackendVersion(void)
+{
+ static CStdString strBackendVersion = "0.1";
+ return strBackendVersion.c_str();
+}
+
+const char *GetConnectionString(void)
+{
+ static CStdString strConnectionString = "connected";
+ return strConnectionString.c_str();
+}
+
+PVR_ERROR GetDriveSpace(long long *iTotal, long long *iUsed)
+{
+ *iTotal = 1024 * 1024 * 1024;
+ *iUsed = 0;
+ return PVR_ERROR_NO_ERROR;
+}
+
+PVR_ERROR GetEPGForChannel(PVR_HANDLE handle, const PVR_CHANNEL &channel, time_t iStart, time_t iEnd)
+{
+ if (m_data)
+ return m_data->GetEPGForChannel(handle, channel, iStart, iEnd);
+
+ return PVR_ERROR_SERVER_ERROR;
+}
+
+int GetChannelsAmount(void)
+{
+ if (m_data)
+ return m_data->GetChannelsAmount();
+
+ return -1;
+}
+
+PVR_ERROR GetChannels(PVR_HANDLE handle, bool bRadio)
+{
+ if (m_data)
+ return m_data->GetChannels(handle, bRadio);
+
+ return PVR_ERROR_SERVER_ERROR;
+}
+
+bool OpenLiveStream(const PVR_CHANNEL &channel)
+{
+ if (m_data)
+ {
+ CloseLiveStream();
+
+ if (m_data->GetChannel(channel, m_currentChannel))
+ {
+ m_bIsPlaying = true;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void CloseLiveStream(void)
+{
+ m_bIsPlaying = false;
+}
+
+int GetCurrentClientChannel(void)
+{
+ return m_currentChannel.iUniqueId;
+}
+
+bool SwitchChannel(const PVR_CHANNEL &channel)
+{
+ CloseLiveStream();
+
+ return OpenLiveStream(channel);
+}
+
+PVR_ERROR GetStreamProperties(PVR_STREAM_PROPERTIES* pProperties)
+{
+ return PVR_ERROR_NOT_IMPLEMENTED;
+}
+
+int GetChannelGroupsAmount(void)
+{
+ if (m_data)
+ return m_data->GetChannelGroupsAmount();
+
+ return -1;
+}
+
+PVR_ERROR GetChannelGroups(PVR_HANDLE handle, bool bRadio)
+{
+ if (m_data)
+ return m_data->GetChannelGroups(handle, bRadio);
+
+ return PVR_ERROR_SERVER_ERROR;
+}
+
+PVR_ERROR GetChannelGroupMembers(PVR_HANDLE handle, const PVR_CHANNEL_GROUP &group)
+{
+ if (m_data)
+ return m_data->GetChannelGroupMembers(handle, group);
+
+ return PVR_ERROR_SERVER_ERROR;
+}
+
+PVR_ERROR SignalStatus(PVR_SIGNAL_STATUS &signalStatus)
+{
+ snprintf(signalStatus.strAdapterName, sizeof(signalStatus.strAdapterName), "pvr demo adapter 1");
+ snprintf(signalStatus.strAdapterStatus, sizeof(signalStatus.strAdapterStatus), "OK");
+
+ return PVR_ERROR_NO_ERROR;
+}
+
+/** UNUSED API FUNCTIONS */
+PVR_ERROR DialogChannelScan(void) { return PVR_ERROR_NOT_IMPLEMENTED; }
+PVR_ERROR CallMenuHook(const PVR_MENUHOOK &menuhook) { return PVR_ERROR_NOT_IMPLEMENTED; }
+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 DialogChannelSettings(const PVR_CHANNEL &channel) { return PVR_ERROR_NOT_IMPLEMENTED; }
+PVR_ERROR DialogAddChannel(const PVR_CHANNEL &channel) { return PVR_ERROR_NOT_IMPLEMENTED; }
+bool OpenRecordedStream(const PVR_RECORDING &recording) { return false; }
+void CloseRecordedStream(void) {}
+int ReadRecordedStream(unsigned char *pBuffer, unsigned int iBufferSize) { return 0; }
+long long SeekRecordedStream(long long iPosition, int iWhence /* = SEEK_SET */) { return 0; }
+long long PositionRecordedStream(void) { return -1; }
+long long LengthRecordedStream(void) { return 0; }
+void DemuxReset(void) {}
+void DemuxFlush(void) {}
+int ReadLiveStream(unsigned char *pBuffer, unsigned int iBufferSize) { return 0; }
+long long SeekLiveStream(long long iPosition, int iWhence /* = SEEK_SET */) { return -1; }
+long long PositionLiveStream(void) { return -1; }
+long long LengthLiveStream(void) { return -1; }
+const char * GetLiveStreamURL(const PVR_CHANNEL &channel) { return ""; }
+int GetRecordingsAmount(void) { return -1; }
+PVR_ERROR GetRecordings(PVR_HANDLE handle) { return PVR_ERROR_NOT_IMPLEMENTED; }
+PVR_ERROR DeleteRecording(const PVR_RECORDING &recording) { return PVR_ERROR_NOT_IMPLEMENTED; }
+PVR_ERROR RenameRecording(const PVR_RECORDING &recording) { return PVR_ERROR_NOT_IMPLEMENTED; }
+int GetTimersAmount(void) { return -1; }
+PVR_ERROR GetTimers(PVR_HANDLE handle) { return PVR_ERROR_NOT_IMPLEMENTED; }
+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; }
+void DemuxAbort(void) {}
+DemuxPacket* DemuxRead(void) { return NULL; }
+}
View
30 xbmc/pvrclients/pvr-demo/client.h
@@ -0,0 +1,30 @@
+#pragma once
+/*
+ * Copyright (C) 2011 Pulse-Eight
+ * http://www.pulse-eight.com/
+ *
+ * This Program 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, or (at your option)
+ * any later version.
+ *
+ * This Program 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 XBMC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "../../../addons/library.xbmc.addon/libXBMC_addon.h"
+#include "../../../addons/library.xbmc.pvr/libXBMC_pvr.h"
+
+extern bool m_bCreated;
+extern std::string g_szUserPath;
+extern std::string g_szClientPath;
+extern ADDON::CHelper_libXBMC_addon *XBMC;
+extern CHelper_libXBMC_pvr *PVR;
View
418 xbmc/pvrclients/pvr-demo/thread.cpp
@@ -0,0 +1,418 @@
+/*
+ * Copyright (C) 2005-2009 Team XBMC
+ * http://www.xbmc.org
+ *
+ * This Program 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, or (at your option)
+ * any later version.
+ *
+ * This Program 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 XBMC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+/*
+ * Most of this code is taken from thread.c in the Video Disk Recorder ('VDR')
+ */
+
+#include "thread.h"
+#include <errno.h>
+#ifndef __APPLE__
+#include <malloc.h>
+#endif
+
+#if !defined(__WINDOWS__)
+#include <sys/signal.h>
+#endif
+
+#include <stdarg.h>
+#include <stdlib.h>
+
+using namespace ADDON;
+
+static bool GetAbsTime(struct timespec *Abstime, int MillisecondsFromNow)
+{
+ struct timeval now;
+ if (gettimeofday(&now, NULL) == 0) { // get current time
+ now.tv_sec += MillisecondsFromNow / 1000; // add full seconds
+ now.tv_usec += (MillisecondsFromNow % 1000) * 1000; // add microseconds
+ if (now.tv_usec >= 1000000) { // take care of an overflow
+ now.tv_sec++;
+ now.tv_usec -= 1000000;
+ }
+ Abstime->tv_sec = now.tv_sec; // seconds
+ Abstime->tv_nsec = now.tv_usec * 1000; // nano seconds
+ return true;
+ }
+ return false;
+}
+
+// --- cCondWait -------------------------------------------------------------
+
+cCondWait::cCondWait(void)
+{
+ signaled = false;
+ pthread_mutex_init(&mutex, NULL);
+ pthread_cond_init(&cond, NULL);
+}
+
+cCondWait::~cCondWait()
+{
+ pthread_cond_broadcast(&cond); // wake up any sleepers
+ pthread_cond_destroy(&cond);
+ pthread_mutex_destroy(&mutex);
+}
+
+void cCondWait::SleepMs(int TimeoutMs)
+{
+ cCondWait w;
+ w.Wait(max(TimeoutMs, 3)); // making sure the time is >2ms to avoid a possible busy wait
+}
+
+bool cCondWait::Wait(int TimeoutMs)
+{
+ pthread_mutex_lock(&mutex);
+ if (!signaled)
+ {
+ if (TimeoutMs)
+ {
+ struct timespec abstime;
+ if (GetAbsTime(&abstime, TimeoutMs))
+ {
+ while (!signaled)
+ {
+ int iResult = pthread_cond_timedwait(&cond, &mutex, &abstime);
+ if (iResult != 0)
+ break;
+ }
+ }
+ }
+ else
+ pthread_cond_wait(&cond, &mutex);
+ }
+ bool r = signaled;
+ signaled = false;
+ pthread_mutex_unlock(&mutex);
+ return r;
+}
+
+void cCondWait::Signal(void)
+{
+ pthread_mutex_lock(&mutex);
+ signaled = true;
+ pthread_cond_broadcast(&cond);
+ pthread_mutex_unlock(&mutex);
+}
+
+// --- cCondVar --------------------------------------------------------------
+
+cCondVar::cCondVar(void)
+{
+ pthread_cond_init(&cond, 0);
+}
+
+cCondVar::~cCondVar()
+{
+ pthread_cond_broadcast(&cond); // wake up any sleepers
+ pthread_cond_destroy(&cond);
+}
+
+void cCondVar::Wait(cMutex &Mutex)
+{
+ if (Mutex.locked) {
+ int locked = Mutex.locked;
+ Mutex.locked = 0; // have to clear the locked count here, as pthread_cond_wait
+ // does an implicit unlock of the mutex
+ pthread_cond_wait(&cond, &Mutex.mutex);
+ Mutex.locked = locked;
+ }
+}
+
+bool cCondVar::TimedWait(cMutex &Mutex, int TimeoutMs)
+{
+ bool r = true; // true = condition signaled, false = timeout
+
+ if (Mutex.locked) {
+ struct timespec abstime;
+ if (GetAbsTime(&abstime, TimeoutMs)) {
+ int locked = Mutex.locked;
+ Mutex.locked = 0; // have to clear the locked count here, as pthread_cond_timedwait
+ // does an implicit unlock of the mutex.
+ if (pthread_cond_timedwait(&cond, &Mutex.mutex, &abstime) == ETIMEDOUT)
+ r = false;
+ Mutex.locked = locked;
+ }
+ }
+ return r;
+}
+
+void cCondVar::Broadcast(void)
+{
+ pthread_cond_broadcast(&cond);
+}
+
+// --- cMutex ----------------------------------------------------------------
+
+cMutex::cMutex(void)
+{
+ locked = 0;
+ pthread_mutexattr_t attr;
+ pthread_mutexattr_init(&attr);
+#ifndef __APPLE__
+ pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK_NP);
+#else
+ pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
+#endif
+ pthread_mutex_init(&mutex, &attr);
+}
+
+cMutex::~cMutex()
+{
+ pthread_mutex_destroy(&mutex);
+}
+
+void cMutex::Lock(void)
+{
+ pthread_mutex_lock(&mutex);
+ locked++;
+}
+
+void cMutex::Unlock(void)
+{
+ if (!--locked)
+ pthread_mutex_unlock(&mutex);
+}
+
+// --- cThread ---------------------------------------------------------------
+
+tThreadId cThread::mainThreadId = 0;
+
+cThread::cThread(const char *Description)
+{
+ active = running = false;
+#if !defined(__WINDOWS__)
+ childTid = 0;
+#endif
+ childThreadId = 0;
+ description = NULL;
+ if (Description)
+ SetDescription("%s", Description);
+}
+
+cThread::~cThread()
+{
+ Cancel(); // just in case the derived class didn't call it
+ free(description);
+}
+
+void cThread::SetPriority(int Priority)
+{
+#if !defined(__WINDOWS__)
+ if (setpriority(PRIO_PROCESS, 0, Priority) < 0)
+ XBMC->Log(LOG_ERROR, "ERROR (%s,%d): %m", __FILE__, __LINE__);
+#endif
+}
+
+void cThread::SetIOPriority(int Priority)
+{
+#if !defined(__WINDOWS__)
+#ifdef HAVE_LINUXIOPRIO
+ if (syscall(SYS_ioprio_set, 1, 0, (Priority & 0xff) | (2 << 13)) < 0) // best effort class
+ XBMC->Log(LOG_ERROR, "ERROR (%s,%d): %m", __FILE__, __LINE__);
+#endif
+#endif
+}
+
+void cThread::SetDescription(const char *Description, ...)
+{
+ free(description);
+ description = NULL;
+ if (Description)
+ {
+ va_list ap;
+ va_start(ap, Description);
+ CStdString desc;
+ desc.FormatV(Description, ap);
+ description = strdup(desc.c_str());
+ va_end(ap);
+ }
+}
+
+void *cThread::StartThread(cThread *Thread)
+{
+ Thread->childThreadId = ThreadId();
+ if (Thread->description) {
+ XBMC->Log(LOG_DEBUG, "%s thread started (pid=%d, tid=%d)", Thread->description, getpid(), Thread->childThreadId);
+#ifdef PR_SET_NAME
+ if (prctl(PR_SET_NAME, Thread->description, 0, 0, 0) < 0)
+ XBMC->Log(LOG_ERROR, "%s thread naming failed (pid=%d, tid=%d)", Thread->description, getpid(), Thread->childThreadId);
+#endif
+ }
+ Thread->Action();
+ if (Thread->description)
+ XBMC->Log(LOG_DEBUG, "%s thread ended (pid=%d, tid=%d)", Thread->description, getpid(), Thread->childThreadId);
+ Thread->running = false;
+ Thread->active = false;
+ return NULL;
+}
+
+#define THREAD_STOP_TIMEOUT 3000 // ms to wait for a thread to stop before newly starting it
+#define THREAD_STOP_SLEEP 30 // ms to sleep while waiting for a thread to stop
+
+bool cThread::Start(void)
+{
+ if (!running) {
+ if (active) {
+ // Wait until the previous incarnation of this thread has completely ended
+ // before starting it newly:
+ cTimeMs RestartTimeout;
+ while (!running && active && RestartTimeout.Elapsed() < THREAD_STOP_TIMEOUT)
+ cCondWait::SleepMs(THREAD_STOP_SLEEP);
+ }
+ if (!active) {
+ active = running = true;
+ if (pthread_create(&childTid, NULL, (void *(*) (void *))&StartThread, (void *)this) == 0) {
+ pthread_detach(childTid); // auto-reap
+ }
+ else {
+ XBMC->Log(LOG_ERROR, "ERROR (%s,%d): %m", __FILE__, __LINE__);
+ active = running = false;
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+bool cThread::Active(void)
+{
+ if (active) {
+ //
+ // Single UNIX Spec v2 says:
+ //
+ // The pthread_kill() function is used to request
+ // that a signal be delivered to the specified thread.
+ //
+ // As in kill(), if sig is zero, error checking is
+ // performed but no signal is actually sent.
+ //
+ int err;
+ if ((err = pthread_kill(childTid, 0)) != 0) {
+ if (err != ESRCH)
+ XBMC->Log(LOG_ERROR, "ERROR (%s,%d): %m", __FILE__, __LINE__);
+#if !defined(__WINDOWS__)
+ childTid = 0;
+#endif
+ active = running = false;
+ }
+ else
+ return true;
+ }
+ return false;
+}
+
+void cThread::Cancel(int WaitSeconds)
+{
+ running = false;
+ if (active && WaitSeconds > -1)
+ {
+ if (WaitSeconds > 0)
+ {
+ for (time_t t0 = time(NULL) + WaitSeconds; time(NULL) < t0; )
+ {
+ if (!Active())
+ return;
+ cCondWait::SleepMs(10);
+ }
+ XBMC->Log(LOG_ERROR, "ERROR: %s thread %d won't end (waited %d seconds) - canceling it...", description ? description : "", childThreadId, WaitSeconds);
+ }
+ pthread_cancel(childTid);
+#if !defined(__WINDOWS__)
+ childTid = 0;
+#endif
+ active = false;
+ }
+}
+
+tThreadId cThread::ThreadId(void)
+{
+#ifdef __APPLE__
+ return (int)pthread_self();
+#else
+#ifdef __WINDOWS__
+ return GetCurrentThreadId();
+#else
+ return syscall(__NR_gettid);
+#endif
+#endif
+}
+
+void cThread::SetMainThreadId(void)
+{
+ if (mainThreadId == 0)
+ mainThreadId = ThreadId();
+ else
+ XBMC->Log(LOG_ERROR, "ERROR: attempt to set main thread id to %d while it already is %d", ThreadId(), mainThreadId);
+}
+
+// --- cMutexLock ------------------------------------------------------------
+
+cMutexLock::cMutexLock(cMutex *Mutex)
+{
+ mutex = NULL;
+ locked = false;
+ Lock(Mutex);
+}
+
+cMutexLock::~cMutexLock()
+{
+ if (mutex && locked)
+ mutex->Unlock();
+}
+
+bool cMutexLock::Lock(cMutex *Mutex)
+{
+ if (Mutex && !mutex)
+ {
+ mutex = Mutex;
+ Mutex->Lock();
+ locked = true;
+ return true;
+ }
+ return false;
+}
+
+// --- cThreadLock -----------------------------------------------------------
+
+cThreadLock::cThreadLock(cThread *Thread)
+{
+ thread = NULL;
+ locked = false;
+ Lock(Thread);
+}
+
+cThreadLock::~cThreadLock()
+{
+ if (thread && locked)
+ thread->Unlock();
+}
+
+bool cThreadLock::Lock(cThread *Thread)
+{
+ if (Thread && !thread)
+ {
+ thread = Thread;
+ Thread->Lock();
+ locked = true;
+ return true;
+ }
+ return false;
+}
View
168 xbmc/pvrclients/pvr-demo/thread.h
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2005-2009 Team XBMC
+ * http://www.xbmc.org
+ *
+ * This Program 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, or (at your option)
+ * any later version.
+ *
+ * This Program 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 XBMC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#ifndef __THREAD_H
+#define __THREAD_H
+
+#include <stdio.h>
+#include <sys/types.h>
+#include "tools.h"
+#include "utils/StdString.h"
+#include "libPlatform/os-dependent.h"
+
+class cCondWait {
+private:
+ pthread_mutex_t mutex;
+ pthread_cond_t cond;
+ bool signaled;
+public:
+ cCondWait(void);
+ ~cCondWait();
+ static void SleepMs(int TimeoutMs);
+ ///< Creates a cCondWait object and uses it to sleep for TimeoutMs
+ ///< milliseconds, immediately giving up the calling thread's time
+ ///< slice and thus avoiding a "busy wait".
+ ///< In order to avoid a possible busy wait, TimeoutMs will be automatically
+ ///< limited to values >2.
+ bool Wait(int TimeoutMs = 0);
+ ///< Waits at most TimeoutMs milliseconds for a call to Signal(), or
+ ///< forever if TimeoutMs is 0.
+ ///< \return Returns true if Signal() has been called, false it the given
+ ///< timeout has expired.
+ void Signal(void);
+ ///< Signals a caller of Wait() that the condition it is waiting for is met.
+ };
+
+class cMutex;
+
+class cCondVar {
+private:
+ pthread_cond_t cond;
+public:
+ cCondVar(void);
+ ~cCondVar();
+ void Wait(cMutex &Mutex);
+ bool TimedWait(cMutex &Mutex, int TimeoutMs);
+ void Broadcast(void);
+ };
+
+class cMutex {
+ friend class cCondVar;
+private:
+ pthread_mutex_t mutex;
+ int locked;
+public:
+ cMutex(void);
+ ~cMutex();
+ void Lock(void);
+ void Unlock(void);
+ };
+
+typedef pid_t tThreadId;
+
+class cThread {
+ friend class cThreadLock;
+private:
+ bool active;
+ bool running;
+ pthread_t childTid;
+ tThreadId childThreadId;
+ cMutex mutex;
+ char *description;
+ static tThreadId mainThreadId;
+ static void *StartThread(cThread *Thread);
+protected:
+ void SetPriority(int Priority);
+ void SetIOPriority(int Priority);
+ void Lock(void) { mutex.Lock(); }
+ void Unlock(void) { mutex.Unlock(); }
+ virtual void Action(void) = 0;
+ ///< A derived cThread class must implement the code it wants to
+ ///< execute as a separate thread in this function. If this is
+ ///< a loop, it must check Running() repeatedly to see whether
+ ///< it's time to stop.
+ bool Running(void) { return running; }
+ ///< Returns false if a derived cThread object shall leave its Action()
+ ///< function.
+ void Cancel(int WaitSeconds = 0);
+ ///< Cancels the thread by first setting 'running' to false, so that
+ ///< the Action() loop can finish in an orderly fashion and then waiting
+ ///< up to WaitSeconds seconds for the thread to actually end. If the
+ ///< thread doesn't end by itself, it is killed.
+ ///< If WaitSeconds is -1, only 'running' is set to false and Cancel()
+ ///< returns immediately, without killing the thread.
+public:
+ cThread(const char *Description = NULL);
+ ///< Creates a new thread.
+ ///< If Description is present, a log file entry will be made when
+ ///< the thread starts and stops. The Start() function must be called
+ ///< to actually start the thread.
+ virtual ~cThread();
+#ifdef __WINDOWS__
+ void SetDescription(const char *Description, ...);
+#else
+ void SetDescription(const char *Description, ...) __attribute__ ((format (printf, 2, 3)));
+#endif
+ bool Start(void);
+ ///< Actually starts the thread.
+ ///< If the thread is already running, nothing happens.
+ bool Active(void);
+ ///< Checks whether the thread is still alive.
+ static tThreadId ThreadId(void);
+ static tThreadId IsMainThread(void) { return ThreadId() == mainThreadId; }
+ static void SetMainThreadId(void);
+ };
+
+// cMutexLock can be used to easily set a lock on mutex and make absolutely
+// sure that it will be unlocked when the block will be left. Several locks can
+// be stacked, so a function that makes many calls to another function which uses
+// cMutexLock may itself use a cMutexLock to make one longer lock instead of many
+// short ones.
+
+class cMutexLock {
+private:
+ cMutex *mutex;
+ bool locked;
+public:
+ cMutexLock(cMutex *Mutex = NULL);
+ ~cMutexLock();
+ bool Lock(cMutex *Mutex);
+ };
+
+// cThreadLock can be used to easily set a lock in a thread and make absolutely
+// sure that it will be unlocked when the block will be left. Several locks can
+// be stacked, so a function that makes many calls to another function which uses
+// cThreadLock may itself use a cThreadLock to make one longer lock instead of many
+// short ones.
+
+class cThreadLock {
+private:
+ cThread *thread;
+ bool locked;
+public:
+ cThreadLock(cThread *Thread = NULL);
+ ~cThreadLock();
+ bool Lock(cThread *Thread);
+ };
+
+#define LOCK_THREAD cThreadLock ThreadLock(this)
+
+#endif //__THREAD_H
View
96 xbmc/pvrclients/pvr-demo/tools.cpp
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2005-2009 Team XBMC
+ * http://www.xbmc.org
+ *
+ * This Program 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, or (at your option)
+ * any later version.
+ *
+ * This Program 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 XBMC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+/*
+ * Most of this code is taken from tools.c in the Video Disk Recorder ('VDR')
+ */
+
+#include "tools.h"
+#include "libPlatform/os-dependent.h"
+
+using namespace ADDON;
+
+// --- cTimeMs ---------------------------------------------------------------
+
+cTimeMs::cTimeMs(int Ms)
+{
+ Set(Ms);
+}
+
+uint64_t cTimeMs::Now(void)
+{
+#if _POSIX_TIMERS > 0 && defined(_POSIX_MONOTONIC_CLOCK)
+#define MIN_RESOLUTION 5 // ms
+ static bool initialized = false;
+ static bool monotonic = false;
+ struct timespec tp;
+ if (!initialized) {
+ // check if monotonic timer is available and provides enough accurate resolution:
+ if (clock_getres(CLOCK_MONOTONIC, &tp) == 0) {
+ long Resolution = tp.tv_nsec;
+ // require a minimum resolution:
+ if (tp.tv_sec == 0 && tp.tv_nsec <= MIN_RESOLUTION * 1000000) {
+ if (clock_gettime(CLOCK_MONOTONIC, &tp) == 0) {
+ XBMC->Log(LOG_DEBUG, "cTimeMs: using monotonic clock (resolution is %ld ns)", Resolution);
+ monotonic = true;
+ }
+ else
+ XBMC->Log(LOG_ERROR, "cTimeMs: clock_gettime(CLOCK_MONOTONIC) failed");
+ }
+ else
+ XBMC->Log(LOG_DEBUG, "cTimeMs: not using monotonic clock - resolution is too bad (%ld s %ld ns)", tp.tv_sec, tp.tv_nsec);
+ }
+ else
+ XBMC->Log(LOG_ERROR, "cTimeMs: clock_getres(CLOCK_MONOTONIC) failed");
+ initialized = true;
+ }
+ if (monotonic) {
+ if (clock_gettime(CLOCK_MONOTONIC, &tp) == 0)
+ return (uint64_t(tp.tv_sec)) * 1000 + tp.tv_nsec / 1000000;
+ XBMC->Log(LOG_ERROR, "cTimeMs: clock_gettime(CLOCK_MONOTONIC) failed");
+ monotonic = false;
+ // fall back to gettimeofday()
+ }
+#else
+#if !defined(__WINDOWS__)
+# warning Posix monotonic clock not available
+#endif
+#endif
+ struct timeval t;
+ if (gettimeofday(&t, NULL) == 0)
+ return (uint64_t(t.tv_sec)) * 1000 + t.tv_usec / 1000;
+ return 0;
+}
+
+void cTimeMs::Set(int Ms)
+{
+ begin = Now() + Ms;
+}
+
+bool cTimeMs::TimedOut(void)
+{
+ return Now() >= begin;
+}
+
+uint64_t cTimeMs::Elapsed(void)
+{
+ return Now() - begin;
+}
View
63 xbmc/pvrclients/pvr-demo/tools.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2005-2009 Team XBMC
+ * http://www.xbmc.org
+ *
+ * This Program 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, or (at your option)
+ * any later version.
+ *
+ * This Program 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 XBMC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#ifndef __TOOLS_H
+#define __TOOLS_H
+
+#include "client.h"
+#include "utils/StdString.h"
+#include <errno.h>
+#include <fcntl.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#define ERRNUL(e) {errno=e;return 0;}
+#define ERRSYS(e) {errno=e;return -1;}
+
+#define SECSINDAY 86400
+
+#define KILOBYTE(n) ((n) * 1024)
+#define MEGABYTE(n) ((n) * 1024LL * 1024LL)
+
+#define MALLOC(type, size) (type *)malloc(sizeof(type) * (size))
+
+#define DELETENULL(p) (delete (p), p = NULL)
+//
+//#define CHECK(s) { if ((s) < 0) LOG_ERROR; } // used for 'ioctl()' calls
+#define FATALERRNO (errno && errno != EAGAIN && errno != EINTR)
+
+class cTimeMs
+{
+private:
+ uint64_t begin;
+public:
+ cTimeMs(int Ms = 0);
+ ///< Creates a timer with ms resolution and an initial timeout of Ms.
+ static uint64_t Now(void);
+ void Set(int Ms = 0);
+ bool TimedOut(void);
+ uint64_t Elapsed(void);
+};
+
+
+#endif //__TOOLS_H
Please sign in to comment.
Something went wrong with that request. Please try again.