Permalink
Browse files

[mythtv-cmyth] Release 0.5

  • Loading branch information...
1 parent d7a2fa1 commit 86d018859302d1c40b44844c44549f4e75bad250 @fetzerch fetzerch committed Nov 5, 2012
Showing with 1,184 additions and 701 deletions.
  1. +2 −2 addons/pvr.mythtv.cmyth/addon/addon.xml
  2. +14 −1 addons/pvr.mythtv.cmyth/addon/changelog.txt
  3. +9 −27 addons/pvr.mythtv.cmyth/src/cppmyth/MythConnection.cpp
  4. +1 −2 addons/pvr.mythtv.cmyth/src/cppmyth/MythConnection.h
  5. +36 −5 addons/pvr.mythtv.cmyth/src/cppmyth/MythEventHandler.cpp
  6. +6 −21 addons/pvr.mythtv.cmyth/src/cppmyth/MythFile.cpp
  7. +10 −3 addons/pvr.mythtv.cmyth/src/cppmyth/MythProgramInfo.cpp
  8. +2 −1 addons/pvr.mythtv.cmyth/src/cppmyth/MythProgramInfo.h
  9. +80 −75 addons/pvr.mythtv.cmyth/src/cppmyth/MythRecorder.cpp
  10. +3 −0 addons/pvr.mythtv.cmyth/src/cppmyth/MythRecorder.h
  11. +1 −3 addons/pvr.mythtv.cmyth/src/fileOps.cpp
  12. +57 −48 addons/pvr.mythtv.cmyth/src/pvrclient-mythtv.cpp
  13. +33 −7 lib/cmyth/include/cmyth/cmyth.h
  14. +78 −22 lib/cmyth/include/refmem/atomic.h
  15. +32 −0 lib/cmyth/include/refmem/refmem.h
  16. +5 −14 lib/cmyth/libcmyth/bookmark.c
  17. +15 −5 lib/cmyth/libcmyth/cmyth_local.h
  18. +2 −2 lib/cmyth/libcmyth/commbreak.c
  19. +104 −14 lib/cmyth/libcmyth/connection.c
  20. +78 −43 lib/cmyth/libcmyth/file.c
  21. +128 −144 lib/cmyth/libcmyth/livetv.c
  22. +11 −3 lib/cmyth/libcmyth/mysql_query.c
  23. +287 −189 lib/cmyth/libcmyth/mythtv_mysql.c
  24. +0 −2 lib/cmyth/libcmyth/proginfo.c
  25. +1 −1 lib/cmyth/libcmyth/proglist.c
  26. +9 −9 lib/cmyth/libcmyth/recorder.c
  27. +87 −21 lib/cmyth/libcmyth/socket.c
  28. +2 −11 lib/cmyth/libcmyth/timestamp.c
  29. +72 −12 lib/cmyth/librefmem/alloc.c
  30. +19 −14 lib/cmyth/librefmem/refmem_local.h
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<addon
id="pvr.mythtv.cmyth"
- version="0.4.0"
+ version="0.5.0"
name="MythTV cmyth PVR Client"
provider-name="Christian Fetzer, Jean-Luc Barrière, Tonny Petersen">
<requires>
@@ -15,7 +15,7 @@
library_windx="XBMC_MythTV_cmyth_win32.pvr"/>
<extension point="xbmc.addon.metadata">
<summary>XBMC frontend for MythTV (using libcmyth)</summary>
- <description>MythTV frontend (up to MythTV 0.25). Supports streaming of Live TV &amp; Recordings, listening to Radio channels, EPG and Timers.</description>
+ <description>MythTV frontend (up to MythTV 0.26). Supports streaming of Live TV &amp; Recordings, listening to Radio channels, EPG and Timers.</description>
<disclaimer>This is unstable software! The authors are in no way responsible for failed recordings, incorrect timers, wasted hours, or any other undesirable effects.</disclaimer>
<platform>all</platform>
</extension>
@@ -1,8 +1,21 @@
+v0.5.0
+- Support MythTV 0.26 backends
+- Allow Timer Deletion
+- Support reconnecting to backend
+- Reworked LiveTV (no more stops at show end, fixed USB tuner support)
+- Performance improvements (adapted socket buffer sizes, removed unnecessary locks)
+- Stability improvements
+ - Fixed crash on SetRecordingPlayCount and SetRecordingLastPlayedPosition
+ - Fixed crash when addon was restarted
+ - Fixed crash when backend connection was lost
+ - Fixed memory leaks in libcmyth
+- Show correct start/end time in recordings- and timer view
+
v0.4.0
- OSX support
v0.3.0
-- Transifex localizations (https://www.transifex.com/projects/p/pvrmythtvcmyth)
+- Transifex localizations
- Support for recording images (icon, thumbnail, fanart)
- Fixed: Preview images of new recordings were not cached
@@ -67,7 +67,6 @@ MythConnection::MythConnection()
: m_conn_t(new MythPointerThreadSafe<cmyth_conn_t>())
, m_server("")
, m_port(0)
- , m_retryCount(0)
, m_pEventHandler(NULL)
{
}
@@ -76,7 +75,6 @@ MythConnection::MythConnection(const CStdString &server, unsigned short port)
: m_conn_t(new MythPointerThreadSafe<cmyth_conn_t>)
, m_server(server)
, m_port(port)
- , m_retryCount(0)
, m_pEventHandler(NULL)
{
cmyth_conn_t connection = cmyth_conn_connect_ctrl(const_cast<char*>(server.c_str()), port, 64 * 1024, 16 * 1024);
@@ -130,25 +128,11 @@ bool MythConnection::IsConnected()
bool MythConnection::TryReconnect()
{
int retval = false;
- if (m_retryCount < 10)
- {
- m_retryCount++;
-
- Lock();
- retval = cmyth_conn_reconnect_ctrl(*m_conn_t);
- Unlock();
-
- if (retval == 1)
- {
- m_retryCount = 0;
- if (m_pEventHandler && !m_pEventHandler->TryReconnect())
- {
- XBMC->Log(LOG_ERROR, "%s - Unable to reconnect event handler", __FUNCTION__);
- }
- }
- }
- if (g_bExtraDebug && retval == 0)
- XBMC->Log(LOG_DEBUG, "%s - Unable to reconnect (retry count: %d)", __FUNCTION__, m_retryCount);
+ Lock();
+ retval = cmyth_conn_reconnect_ctrl(*m_conn_t);
+ Unlock();
+ if (retval == 0)
+ XBMC->Log(LOG_DEBUG, "%s - Unable to reconnect", __FUNCTION__);
return retval == 1;
}
@@ -298,10 +282,8 @@ ProgramInfoMap MythConnection::GetScheduledPrograms()
bool MythConnection::UpdateSchedules(int id)
{
- CStdString cmd;
- cmd.Format("RESCHEDULE_RECORDINGS %i", id);
int retval = 0;
- CMYTH_CONN_CALL(retval, retval < 0, cmyth_schedule_recording(*m_conn_t, cmd.Buffer()));
+ CMYTH_CONN_CALL(retval, retval < 0, cmyth_conn_reschedule_recordings(*m_conn_t, id));
return retval >= 0;
}
@@ -354,15 +336,15 @@ MythFile MythConnection::ConnectFile(MythProgramInfo &recording)
MythFile MythConnection::ConnectPath(const CStdString &filename, const CStdString &storageGroup)
{
cmyth_file_t file = NULL;
- CMYTH_CONN_CALL_REF(file, file == NULL, cmyth_conn_connect_path(const_cast<char*>(filename.c_str()), *m_conn_t, 64 * 1024, 16 * 1024, const_cast<char*>(storageGroup.c_str())));
+ CMYTH_CONN_CALL_REF(file, file == NULL, cmyth_conn_connect_path(const_cast<char*>(filename.c_str()), *m_conn_t, 64 * 1024, 64 * 1024, const_cast<char*>(storageGroup.c_str())));
return MythFile(file, *this);
}
-int MythConnection::SetBookmark(MythProgramInfo &recording, long long bookmark)
+bool MythConnection::SetBookmark(MythProgramInfo &recording, long long bookmark)
{
int retval;
CMYTH_CONN_CALL(retval, retval < 0, cmyth_set_bookmark(*m_conn_t, *recording.m_proginfo_t, bookmark));
- return retval;
+ return retval >= 0;
}
long long MythConnection::GetBookmark(MythProgramInfo &recording)
@@ -86,13 +86,12 @@ class MythConnection
// Bookmarks
long long GetBookmark(MythProgramInfo &recording);
- int SetBookmark(MythProgramInfo &recording, long long bookmark);
+ bool SetBookmark(MythProgramInfo &recording, long long bookmark);
private:
boost::shared_ptr<MythPointerThreadSafe<cmyth_conn_t> > m_conn_t;
CStdString m_server;
unsigned short m_port;
- int m_retryCount;
MythEventHandler *m_pEventHandler;
};
@@ -67,6 +67,8 @@ class MythEventHandler::MythEventHandlerPrivate : public CThread, public CMutex
void SetRecordingEventListener(const CStdString &recordid, const MythFile &file);
void HandleUpdateFileSize(const CStdString &buffer);
+ void RetryConnect();
+
// Data
CStdString m_server;
unsigned short m_port;
@@ -159,7 +161,7 @@ void *MythEventHandler::MythEventHandlerPrivate::Process()
{
bool retval = m_recorder.LiveTVChainUpdate(databuf);
if (g_bExtraDebug)
- XBMC->Log(LOG_NOTICE, "%s - Event chain update: %i", __FUNCTION__, retval);
+ XBMC->Log(LOG_NOTICE, "%s - Event chain update: %s", __FUNCTION__, (retval ? "true" : "false"));
}
else
if (g_bExtraDebug)
@@ -227,17 +229,27 @@ void *MythEventHandler::MythEventHandlerPrivate::Process()
PVR->TriggerRecordingUpdate();
}
- if (myth_event == CMYTH_EVENT_CLOSE ||
- myth_event == CMYTH_EVENT_UNKNOWN)
+ if (myth_event == CMYTH_EVENT_UNKNOWN)
+ {
+ XBMC->Log(LOG_NOTICE, "%s - Event unknown, databuf: %s", __FUNCTION__, databuf);
+ }
+
+ if (myth_event == CMYTH_EVENT_CLOSE)
{
XBMC->Log(LOG_NOTICE, "%s - Event client connection closed", __FUNCTION__);
+ RetryConnect();
}
databuf[0] = 0;
}
- else if (select < 0 || cmyth_conn_hung(*m_conn_t))
+ else if (select < 0)
{
- XBMC->Log( LOG_NOTICE, "%s - Select returned error; reconnect event client connection", __FUNCTION__);
+ XBMC->Log(LOG_ERROR, "%s Event client connection error", __FUNCTION__);
+ RetryConnect();
+ }
+ else if (select = 0 && cmyth_conn_hung(*m_conn_t))
+ {
+ XBMC->Log(LOG_NOTICE, "%s - Connection hung - reconnect event client connection", __FUNCTION__);
if (!m_conn_t)
break;
@@ -313,6 +325,25 @@ void MythEventHandler::MythEventHandlerPrivate::HandleUpdateFileSize(const CStdS
}
}
+void MythEventHandler::MythEventHandlerPrivate::RetryConnect()
+{
+ while (!IsStopped())
+ {
+ usleep(999999);
+ ref_release(*m_conn_t);
+ *m_conn_t = NULL;
+ *m_conn_t = cmyth_conn_connect_event(const_cast<char*>(m_server.c_str()), m_port, 64 * 1024, 16 * 1024);
+
+ if (*m_conn_t == NULL)
+ XBMC->Log(LOG_NOTICE, "%s - Could not connect client to event socket", __FUNCTION__);
+ else
+ {
+ XBMC->Log(LOG_NOTICE, "%s - Connected client to event socket", __FUNCTION__);
+ break;
+ }
+ }
+}
+
MythEventHandler::MythEventHandler()
: m_imp()
{
@@ -21,22 +21,6 @@
#include "MythFile.h"
#include "MythPointer.h"
-/* Call 'call', then if 'cond' condition is true see if we're still
- * connected to the control socket and try to re-connect if not.
- * If reconnection is ok, call 'call' again. */
-#define CMYTH_FILE_CALL(var, cond, call) m_conn.Lock(); \
- var = call; \
- m_conn.Unlock(); \
- if (cond) \
- { \
- if (!m_conn.IsConnected() && m_conn.TryReconnect()) \
- { \
- m_conn.Lock(); \
- var = call; \
- m_conn.Unlock(); \
- } \
- } \
-
MythFile::MythFile()
: m_file_t(new MythPointer<cmyth_file_t>())
, m_conn(MythConnection())
@@ -60,33 +44,34 @@ bool MythFile::IsNull() const
unsigned long long MythFile::Length()
{
unsigned long long retval = 0;
- CMYTH_FILE_CALL(retval, (long long)retval < 0, cmyth_file_length(*m_file_t));
+ retval = cmyth_file_length(*m_file_t);
return retval;
}
void MythFile::UpdateLength(unsigned long long length)
{
int retval = 0;
- CMYTH_FILE_CALL(retval, retval < 0, cmyth_update_file_length(*m_file_t, length));
+ retval = cmyth_update_file_length(*m_file_t, length);
+ (void)retval;
}
int MythFile::Read(void *buffer, unsigned long length)
{
int bytesRead;
- CMYTH_FILE_CALL(bytesRead, bytesRead < 0, cmyth_file_read(*m_file_t, static_cast< char * >(buffer), length));
+ bytesRead = cmyth_file_read(*m_file_t, static_cast< char * >(buffer), length);
return bytesRead;
}
long long MythFile::Seek(long long offset, int whence)
{
long long retval = 0;
- CMYTH_FILE_CALL(retval, retval < 0, cmyth_file_seek(*m_file_t, offset, whence));
+ retval = cmyth_file_seek(*m_file_t, offset, whence);
return retval;
}
unsigned long long MythFile::Position()
{
unsigned long long retval = 0;
- CMYTH_FILE_CALL( retval, (long long)retval < 0, cmyth_file_position(*m_file_t));
+ retval = cmyth_file_position(*m_file_t);
return retval;
}
@@ -45,14 +45,14 @@ CStdString MythProgramInfo::StrUID()
// Creates unique IDs from ChannelID, RecordID and StartTime like "100_200_2011-12-10T12:00:00"
char buf[40] = "";
sprintf(buf, "%d_%ld_", ChannelID(), RecordID());
- time_t starttime = StartTime();
+ time_t starttime = RecordingStartTime();
strftime(buf + strlen(buf), 20, "%Y-%m-%dT%H:%M:%S", localtime(&starttime));
return CStdString(buf);
}
long long MythProgramInfo::UID()
{
- long long retval = RecStart();
+ long long retval = RecordingStartTime();
retval <<= 32;
retval += ChannelID();
if (retval > 0)
@@ -180,13 +180,20 @@ unsigned long MythProgramInfo::RecordID()
return cmyth_proginfo_recordid(*m_proginfo_t);
}
-time_t MythProgramInfo::RecStart()
+time_t MythProgramInfo::RecordingStartTime()
{
MythTimestamp time = cmyth_proginfo_rec_start(*m_proginfo_t);
time_t retval(time.UnixTime());
return retval;
}
+time_t MythProgramInfo::RecordingEndTime()
+{
+ MythTimestamp time = cmyth_proginfo_rec_end(*m_proginfo_t);
+ time_t retval(time.UnixTime());
+ return retval;
+}
+
int MythProgramInfo::Priority()
{
return cmyth_proginfo_priority(*m_proginfo_t); // Might want to use recpriority2 instead
@@ -61,7 +61,8 @@ class MythProgramInfo
RecordStatus Status();
CStdString RecordingGroup();
unsigned long RecordID();
- time_t RecStart();
+ time_t RecordingStartTime();
+ time_t RecordingEndTime();
int Priority();
private:
Oops, something went wrong.

0 comments on commit 86d0188

Please sign in to comment.