From 2aa38f5ceb6991e26df20dc0f463aa64466f09ed Mon Sep 17 00:00:00 2001 From: Fraxinas Date: Wed, 3 Jun 2009 13:28:31 +0200 Subject: [PATCH] introduce new iStreamedService interface (e.g. controlling buffer for streaming media) --- .../Plugins/Extensions/DVDPlayer/src/servicedvd.h | 1 + lib/service/iservice.h | 16 ++++++++++ lib/service/servicedvb.h | 4 ++- lib/service/servicedvbrecord.h | 2 +- lib/service/servicemp3.cpp | 36 ++++++++++++++++++++++ lib/service/servicemp3.h | 22 +++++++++++-- 6 files changed, 77 insertions(+), 4 deletions(-) diff --git a/lib/python/Plugins/Extensions/DVDPlayer/src/servicedvd.h b/lib/python/Plugins/Extensions/DVDPlayer/src/servicedvd.h index 12e21d2..94843a4 100644 --- a/lib/python/Plugins/Extensions/DVDPlayer/src/servicedvd.h +++ b/lib/python/Plugins/Extensions/DVDPlayer/src/servicedvd.h @@ -42,6 +42,7 @@ public: RESULT audioDelay(ePtr &ptr) { ptr = 0; return -1; } RESULT rdsDecoder(ePtr &ptr) { ptr = 0; return -1; } RESULT stream(ePtr &ptr) { ptr = 0; return -1; } + RESULT streamed(ePtr &ptr) { ptr = 0; return -1; } RESULT cueSheet(ePtr &ptr); // iPlayableService diff --git a/lib/service/iservice.h b/lib/service/iservice.h index 22ffde6..373f24c 100644 --- a/lib/service/iservice.h +++ b/lib/service/iservice.h @@ -742,6 +742,19 @@ public: }; SWIG_TEMPLATE_TYPEDEF(ePtr, iStreamableServicePtr); +SWIG_IGNORE(iStreamedService); +class iStreamedService: public iObject +{ +#ifdef SWIG + iStreamedService(); + ~iStreamedService(); +#endif +public: + virtual PyObject *getBufferCharge()=0; + virtual int setBufferSize(int size)=0; +}; +SWIG_TEMPLATE_TYPEDEF(ePtr, iStreamedServicePtr); + class iServiceKeys_ENUMS { #ifdef SWIG @@ -812,6 +825,8 @@ public: evVideoFramerateChanged, evVideoProgressiveChanged, + evBuffering, + evStopped, evUser = 0x100 @@ -847,6 +862,7 @@ public: virtual SWIG_VOID(RESULT) audioDelay(ePtr &SWIG_OUTPUT)=0; virtual SWIG_VOID(RESULT) rdsDecoder(ePtr &SWIG_OUTPUT)=0; virtual SWIG_VOID(RESULT) stream(ePtr &SWIG_OUTPUT)=0; + virtual SWIG_VOID(RESULT) streamed(ePtr &SWIG_OUTPUT)=0; virtual SWIG_VOID(RESULT) keys(ePtr &SWIG_OUTPUT)=0; }; SWIG_TEMPLATE_TYPEDEF(ePtr, iPlayableServicePtr); diff --git a/lib/service/servicedvb.h b/lib/service/servicedvb.h index 43e4690..6eba506 100644 --- a/lib/service/servicedvb.h +++ b/lib/service/servicedvb.h @@ -114,13 +114,14 @@ public: RESULT audioDelay(ePtr &ptr); RESULT rdsDecoder(ePtr &ptr); RESULT keys(ePtr &ptr) { ptr = 0; return -1; } + RESULT streamed(ePtr &ptr) { ptr = 0; return -1; } // iPauseableService RESULT pause(); RESULT unpause(); RESULT setSlowMotion(int ratio); RESULT setFastForward(int ratio); - + // iSeekableService RESULT getLength(pts_t &len); RESULT seekTo(pts_t to); @@ -182,6 +183,7 @@ public: // iStreamableService RESULT stream(ePtr &ptr); PyObject *getStreamingData(); + private: friend class eServiceFactoryDVB; eServiceReference m_reference; diff --git a/lib/service/servicedvbrecord.h b/lib/service/servicedvbrecord.h index 319fbb7..0535f02 100644 --- a/lib/service/servicedvbrecord.h +++ b/lib/service/servicedvbrecord.h @@ -28,7 +28,7 @@ public: RESULT frontendInfo(ePtr &ptr); RESULT subServices(ePtr &ptr); - /* streamable service */ + // iStreamableService PyObject *getStreamingData(); // iSubserviceList diff --git a/lib/service/servicemp3.cpp b/lib/service/servicemp3.cpp index fd3587a..2ddfe92 100644 --- a/lib/service/servicemp3.cpp +++ b/lib/service/servicemp3.cpp @@ -196,6 +196,7 @@ eServiceMP3::eServiceMP3(const char *filename, const char *title): m_filename(fi m_currentSubtitleStream = 0; m_subtitle_widget = 0; m_currentTrickRatio = 0; + m_buffer_size = 1*1024*1024; CONNECT(m_seekTimeout->timeout, eServiceMP3::seekTimeoutCB); CONNECT(m_subtitle_sync_timer->timeout, eServiceMP3::pushSubtitles); CONNECT(m_pump.recv_msg, eServiceMP3::gstPoll); @@ -332,6 +333,7 @@ eServiceMP3::eServiceMP3(const char *filename, const char *title): m_filename(fi } gst_element_set_state (m_gst_playbin, GST_STATE_PLAYING); + setBufferSize(m_buffer_size); } eServiceMP3::~eServiceMP3() @@ -1214,6 +1216,14 @@ eDebug("AUDIO STRUCT=%s", g_type); g_free(eventname); } } + break; + } + case GST_MESSAGE_BUFFERING: + { + GstBufferingMode mode; + gst_message_parse_buffering(msg, &(m_bufferInfo.bufferPercent)); + gst_message_parse_buffering_stats(msg, &mode, &(m_bufferInfo.avgInRate), &(m_bufferInfo.avgOutRate), &(m_bufferInfo.bufferingLeft)); + m_event((iPlayableService*)this, evBuffering); } default: break; @@ -1401,6 +1411,7 @@ RESULT eServiceMP3::disableSubtitles(eWidget *parent) PyObject *eServiceMP3::getCachedSubtitle() { +// eDebug("eServiceMP3::getCachedSubtitle"); Py_RETURN_NONE; } @@ -1429,6 +1440,31 @@ PyObject *eServiceMP3::getSubtitleList() return l; } +RESULT eServiceMP3::streamed(ePtr &ptr) +{ + ptr = this; + return 0; +} + +PyObject *eServiceMP3::getBufferCharge() +{ + ePyObject tuple = PyTuple_New(5); + PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(m_bufferInfo.bufferPercent)); + PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong(m_bufferInfo.avgInRate)); + PyTuple_SET_ITEM(tuple, 2, PyInt_FromLong(m_bufferInfo.avgOutRate)); + PyTuple_SET_ITEM(tuple, 3, PyInt_FromLong(m_bufferInfo.bufferingLeft)); + PyTuple_SET_ITEM(tuple, 4, PyInt_FromLong(m_buffer_size)); + return tuple; +} + +int eServiceMP3::setBufferSize(int size) +{ + m_buffer_size = size; + g_object_set (G_OBJECT (m_gst_playbin), "buffer-size", m_buffer_size, NULL); + return 0; +} + + #else #warning gstreamer not available, not building media player #endif diff --git a/lib/service/servicemp3.h b/lib/service/servicemp3.h index f4d657c..1d77483 100644 --- a/lib/service/servicemp3.h +++ b/lib/service/servicemp3.h @@ -50,7 +50,7 @@ typedef enum { stPlainText, stSSA, stSRT } subtype_t; typedef enum { ctNone, ctMPEGTS, ctMPEGPS, ctMKV, ctAVI, ctMP4, ctVCD, ctCDA } containertype_t; class eServiceMP3: public iPlayableService, public iPauseableService, - public iServiceInformation, public iSeekableService, public iAudioTrackSelection, public iAudioChannelSelection, public iSubtitleOutput, public Object + public iServiceInformation, public iSeekableService, public iAudioTrackSelection, public iAudioChannelSelection, public iSubtitleOutput, public iStreamedService, public Object { DECLARE_REF(eServiceMP3); public: @@ -78,8 +78,8 @@ public: RESULT cueSheet(ePtr &ptr) { ptr = 0; return -1; } RESULT audioDelay(ePtr &ptr) { ptr = 0; return -1; } RESULT rdsDecoder(ePtr &ptr) { ptr = 0; return -1; } - RESULT stream(ePtr &ptr) { ptr = 0; return -1; } RESULT keys(ePtr &ptr) { ptr = 0; return -1; } + RESULT stream(ePtr &ptr) { ptr = 0; return -1; } // iPausableService RESULT pause(); @@ -117,6 +117,11 @@ public: PyObject *getSubtitleList(); PyObject *getCachedSubtitle(); + // iStreamedService + RESULT streamed(ePtr &ptr); + PyObject *getBufferCharge(); + int setBufferSize(int size); + struct audioStream { GstPad* pad; @@ -149,6 +154,17 @@ public: { } }; + struct bufferInfo + { + int bufferPercent; + int avgInRate; + int avgOutRate; + long long bufferingLeft; + bufferInfo() + :bufferPercent(0), avgInRate(0), avgOutRate(0), bufferingLeft(-1) + { + } + }; private: int m_currentAudioStream; int m_currentSubtitleStream; @@ -162,6 +178,8 @@ private: friend class eServiceFactoryMP3; std::string m_filename; std::string m_title; + int m_buffer_size; + bufferInfo m_bufferInfo; eServiceMP3(const char *filename, const char *title); Signal2 m_event; enum -- 2.7.4