1f21efdded1e66c13d646725881f1352cf4fdf57
[openblackhole/openblackhole-enigma2.git] / lib / service / servicemp3.h
1 #ifndef __servicemp3_h
2 #define __servicemp3_h
3
4 #include <lib/base/message.h>
5 #include <lib/service/iservice.h>
6 #include <lib/dvb/pmt.h>
7 #include <lib/dvb/subtitle.h>
8 #include <lib/dvb/teletext.h>
9 #include <gst/gst.h>
10 /* for subtitles */
11 #include <lib/gui/esubtitle.h>
12
13 class eStaticServiceMP3Info;
14
15 class eServiceFactoryMP3: public iServiceHandler
16 {
17         DECLARE_REF(eServiceFactoryMP3);
18 public:
19         eServiceFactoryMP3();
20         virtual ~eServiceFactoryMP3();
21         enum { id = 0x1001 };
22
23                 // iServiceHandler
24         RESULT play(const eServiceReference &, ePtr<iPlayableService> &ptr);
25         RESULT record(const eServiceReference &, ePtr<iRecordableService> &ptr);
26         RESULT list(const eServiceReference &, ePtr<iListableService> &ptr);
27         RESULT info(const eServiceReference &, ePtr<iStaticServiceInformation> &ptr);
28         RESULT offlineOperations(const eServiceReference &, ePtr<iServiceOfflineOperations> &ptr);
29 private:
30         ePtr<eStaticServiceMP3Info> m_service_info;
31 };
32
33 class eStaticServiceMP3Info: public iStaticServiceInformation
34 {
35         DECLARE_REF(eStaticServiceMP3Info);
36         friend class eServiceFactoryMP3;
37         eStaticServiceMP3Info();
38 public:
39         RESULT getName(const eServiceReference &ref, std::string &name);
40         int getLength(const eServiceReference &ref);
41         int getInfo(const eServiceReference &ref, int w);
42         int isPlayable(const eServiceReference &ref, const eServiceReference &ignore, bool simulate) { return 1; }
43         long long getFileSize(const eServiceReference &ref);
44         RESULT getEvent(const eServiceReference &ref, ePtr<eServiceEvent> &ptr, time_t start_time);
45 };
46
47 class eStreamBufferInfo: public iStreamBufferInfo
48 {
49         DECLARE_REF(eStreamBufferInfo);
50         int bufferPercentage;
51         int inputRate;
52         int outputRate;
53         int bufferSpace;
54         int bufferSize;
55
56 public:
57         eStreamBufferInfo(int percentage, int inputrate, int outputrate, int space, int size);
58
59         int getBufferPercentage() const;
60         int getAverageInputRate() const;
61         int getAverageOutputRate() const;
62         int getBufferSpace() const;
63         int getBufferSize() const;
64 };
65
66 class eServiceMP3InfoContainer: public iServiceInfoContainer
67 {
68         DECLARE_REF(eServiceMP3InfoContainer);
69
70         double doubleValue;
71         GstBuffer *bufferValue;
72
73         unsigned char *bufferData;
74         unsigned int bufferSize;
75 #if GST_VERSION_MAJOR >= 1
76         GstMapInfo map;
77 #endif
78
79 public:
80         eServiceMP3InfoContainer();
81         ~eServiceMP3InfoContainer();
82
83         double getDouble(unsigned int index) const;
84         unsigned char *getBuffer(unsigned int &size) const;
85         void setDouble(double value);
86         void setBuffer(GstBuffer *buffer);
87 };
88
89 class GstMessageContainer: public iObject
90 {
91         DECLARE_REF(GstMessageContainer);
92         GstMessage *messagePointer;
93         GstPad *messagePad;
94         GstBuffer *messageBuffer;
95         int messageType;
96
97 public:
98         GstMessageContainer(int type, GstMessage *msg, GstPad *pad, GstBuffer *buffer)
99         {
100                 messagePointer = msg;
101                 messagePad = pad;
102                 messageBuffer = buffer;
103                 messageType = type;
104         }
105         ~GstMessageContainer()
106         {
107                 if (messagePointer) gst_message_unref(messagePointer);
108                 if (messagePad) gst_object_unref(messagePad);
109                 if (messageBuffer) gst_buffer_unref(messageBuffer);
110         }
111         int getType() { return messageType; }
112         operator GstMessage *() { return messagePointer; }
113         operator GstPad *() { return messagePad; }
114         operator GstBuffer *() { return messageBuffer; }
115 };
116
117 typedef struct _GstElement GstElement;
118
119 typedef enum { atUnknown, atMPEG, atMP3, atAC3, atDTS, atAAC, atPCM, atOGG, atFLAC, atWMA } audiotype_t;
120 typedef enum { stUnknown, stPlainText, stSSA, stASS, stSRT, stVOB, stPGS } subtype_t;
121 typedef enum { ctNone, ctMPEGTS, ctMPEGPS, ctMKV, ctAVI, ctMP4, ctVCD, ctCDA, ctASF, ctOGG } containertype_t;
122
123 class eServiceMP3: public iPlayableService, public iPauseableService,
124         public iServiceInformation, public iSeekableService, public iAudioTrackSelection, public iAudioChannelSelection,
125         public iSubtitleOutput, public iStreamedService, public iAudioDelay, public Object, public iCueSheet
126 {
127         DECLARE_REF(eServiceMP3);
128 public:
129         virtual ~eServiceMP3();
130
131                 // iPlayableService
132         RESULT connectEvent(const Slot2<void,iPlayableService*,int> &event, ePtr<eConnection> &connection);
133         RESULT start();
134         RESULT stop();
135         RESULT setTarget(int target);
136
137         RESULT pause(ePtr<iPauseableService> &ptr);
138         RESULT setSlowMotion(int ratio);
139         RESULT setFastForward(int ratio);
140
141         RESULT seek(ePtr<iSeekableService> &ptr);
142         RESULT audioTracks(ePtr<iAudioTrackSelection> &ptr);
143         RESULT audioChannel(ePtr<iAudioChannelSelection> &ptr);
144         RESULT subtitle(ePtr<iSubtitleOutput> &ptr);
145         RESULT audioDelay(ePtr<iAudioDelay> &ptr);
146         RESULT cueSheet(ePtr<iCueSheet> &ptr);
147
148                 // not implemented (yet)
149         RESULT frontendInfo(ePtr<iFrontendInformation> &ptr) { ptr = 0; return -1; }
150         RESULT subServices(ePtr<iSubserviceList> &ptr) { ptr = 0; return -1; }
151         RESULT timeshift(ePtr<iTimeshiftService> &ptr) { ptr = 0; return -1; }
152 //      RESULT cueSheet(ePtr<iCueSheet> &ptr) { ptr = 0; return -1; }
153
154                 // iCueSheet
155         PyObject *getCutList();
156         void setCutList(SWIG_PYOBJECT(ePyObject));
157         void setCutListEnable(int enable);
158
159         RESULT rdsDecoder(ePtr<iRdsDecoder> &ptr) { ptr = 0; return -1; }
160         RESULT keys(ePtr<iServiceKeys> &ptr) { ptr = 0; return -1; }
161         RESULT stream(ePtr<iStreamableService> &ptr) { ptr = 0; return -1; }
162
163                 // iPausableService
164         RESULT pause();
165         RESULT unpause();
166
167         RESULT info(ePtr<iServiceInformation>&);
168
169                 // iSeekableService
170         RESULT getLength(pts_t &SWIG_OUTPUT);
171         RESULT seekTo(pts_t to);
172         RESULT seekRelative(int direction, pts_t to);
173         RESULT getPlayPosition(pts_t &SWIG_OUTPUT);
174         RESULT setTrickmode(int trick);
175         RESULT isCurrentlySeekable();
176
177                 // iServiceInformation
178         RESULT getName(std::string &name);
179         RESULT getEvent(ePtr<eServiceEvent> &evt, int nownext);
180         int getInfo(int w);
181         std::string getInfoString(int w);
182         ePtr<iServiceInfoContainer> getInfoObject(int w);
183
184                 // iAudioTrackSelection
185         int getNumberOfTracks();
186         RESULT selectTrack(unsigned int i);
187         RESULT getTrackInfo(struct iAudioTrackInfo &, unsigned int n);
188         int getCurrentTrack();
189
190                 // iAudioChannelSelection
191         int getCurrentChannel();
192         RESULT selectChannel(int i);
193
194                 // iSubtitleOutput
195         RESULT enableSubtitles(iSubtitleUser *user, SubtitleTrack &track);
196         RESULT disableSubtitles();
197         RESULT getSubtitleList(std::vector<SubtitleTrack> &sublist);
198         RESULT getCachedSubtitle(SubtitleTrack &track);
199
200                 // iStreamedService
201         RESULT streamed(ePtr<iStreamedService> &ptr);
202         ePtr<iStreamBufferInfo> getBufferCharge();
203         int setBufferSize(int size);
204
205                 // iAudioDelay
206         int getAC3Delay();
207         int getPCMDelay();
208         void setAC3Delay(int);
209         void setPCMDelay(int);
210
211         struct audioStream
212         {
213                 GstPad* pad;
214                 audiotype_t type;
215                 std::string language_code; /* iso-639, if available. */
216                 std::string codec; /* clear text codec description */
217                 audioStream()
218                         :pad(0), type(atUnknown)
219                 {
220                 }
221         };
222         struct subtitleStream
223         {
224                 GstPad* pad;
225                 subtype_t type;
226                 std::string language_code; /* iso-639, if available. */
227                 subtitleStream()
228                         :pad(0)
229                 {
230                 }
231         };
232         struct sourceStream
233         {
234                 audiotype_t audiotype;
235                 containertype_t containertype;
236                 bool is_video;
237                 bool is_streaming;
238                 sourceStream()
239                         :audiotype(atUnknown), containertype(ctNone), is_video(FALSE), is_streaming(FALSE)
240                 {
241                 }
242         };
243         struct bufferInfo
244         {
245                 gint bufferPercent;
246                 gint avgInRate;
247                 gint avgOutRate;
248                 gint64 bufferingLeft;
249                 bufferInfo()
250                         :bufferPercent(0), avgInRate(0), avgOutRate(0), bufferingLeft(-1)
251                 {
252                 }
253         };
254         struct errorInfo
255         {
256                 std::string error_message;
257                 std::string missing_codec;
258         };
259
260 protected:
261         ePtr<eTimer> m_nownext_timer;
262         ePtr<eServiceEvent> m_event_now, m_event_next;
263         void updateEpgCacheNowNext();
264
265                 /* cuesheet */
266         struct cueEntry
267         {
268                 pts_t where;
269                 unsigned int what;
270
271                 bool operator < (const struct cueEntry &o) const
272                 {
273                         return where < o.where;
274                 }
275                 cueEntry(const pts_t &where, unsigned int what) :
276                         where(where), what(what)
277                 {
278                 }
279         };
280
281         std::multiset<cueEntry> m_cue_entries;
282         int m_cuesheet_changed, m_cutlist_enabled;
283         void loadCuesheet();
284         void saveCuesheet();
285 private:
286         static int pcm_delay;
287         static int ac3_delay;
288         int m_currentAudioStream;
289         int m_currentSubtitleStream;
290         int m_cachedSubtitleStream;
291         int selectAudioStream(int i);
292         std::vector<audioStream> m_audioStreams;
293         std::vector<subtitleStream> m_subtitleStreams;
294         iSubtitleUser *m_subtitle_widget;
295         gdouble m_currentTrickRatio;
296         friend class eServiceFactoryMP3;
297         eServiceReference m_ref;
298         int m_buffer_size;
299         int m_ignore_buffering_messages;
300         bool m_is_live;
301         bool m_use_prefillbuffer;
302         bool m_paused;
303         bool m_seek_paused;
304         /* cuesheet load check */
305         bool m_cuesheet_loaded;
306         /* servicemMP3 chapter TOC support CVR */
307 #if GST_VERSION_MAJOR >= 1
308         bool m_use_chapter_entries;
309         /* last used seek position gst-1 only */
310         gint64 m_last_seek_pos;
311 #endif
312         bufferInfo m_bufferInfo;
313         errorInfo m_errorInfo;
314         std::string m_download_buffer_path;
315         eServiceMP3(eServiceReference ref);
316         Signal2<void,iPlayableService*,int> m_event;
317         enum
318         {
319                 stIdle, stRunning, stStopped,
320         };
321         int m_state;
322         GstElement *m_gst_playbin, *audioSink, *videoSink;
323         GstTagList *m_stream_tags;
324         guint m_bitrate;
325
326         eFixedMessagePump<ePtr<GstMessageContainer> > m_pump;
327
328         audiotype_t gstCheckAudioPad(GstStructure* structure);
329         void gstBusCall(GstMessage *msg);
330         void handleMessage(GstMessage *msg);
331         static GstBusSyncReply gstBusSyncHandler(GstBus *bus, GstMessage *message, gpointer user_data);
332         static void gstTextpadHasCAPS(GstPad *pad, GParamSpec * unused, gpointer user_data);
333         void gstTextpadHasCAPS_synced(GstPad *pad);
334         static void gstCBsubtitleAvail(GstElement *element, GstBuffer *buffer, gpointer user_data);
335         GstPad* gstCreateSubtitleSink(eServiceMP3* _this, subtype_t type);
336         void gstPoll(ePtr<GstMessageContainer> const &);
337         static void playbinNotifySource(GObject *object, GParamSpec *unused, gpointer user_data);
338 #if GST_VERSION_MAJOR < 1
339         static gint match_sinktype(GstElement *element, gpointer type);
340 #else
341 /* TOC processing CVR */
342         void HandleTocEntry(GstMessage *msg);
343         static gint match_sinktype(const GValue *velement, const gchar *type);
344 #endif
345         static void handleElementAdded(GstBin *bin, GstElement *element, gpointer user_data);
346
347         struct subtitle_page_t
348         {
349                 uint32_t start_ms;
350                 uint32_t end_ms;
351                 std::string text;
352
353                 subtitle_page_t(uint32_t start_ms_in, uint32_t end_ms_in, const std::string& text_in)
354                         : start_ms(start_ms_in), end_ms(end_ms_in), text(text_in)
355                 {
356                 }
357         };
358
359         typedef std::map<uint32_t, subtitle_page_t> subtitle_pages_map_t;
360         typedef std::pair<uint32_t, subtitle_page_t> subtitle_pages_map_pair_t;
361         subtitle_pages_map_t m_subtitle_pages;
362         ePtr<eTimer> m_subtitle_sync_timer;
363
364         ePtr<eTimer> m_streamingsrc_timeout;
365         pts_t m_prev_decoder_time;
366         int m_decoder_time_valid_state;
367
368         void pushSubtitles();
369         void pullSubtitle(GstBuffer *buffer);
370         void sourceTimeout();
371         sourceStream m_sourceinfo;
372         gulong m_subs_to_pull_handler_id;
373
374         RESULT seekToImpl(pts_t to);
375
376         gint m_aspect, m_width, m_height, m_framerate, m_progressive;
377         std::string m_useragent;
378         std::string m_extra_headers;
379         RESULT trickSeek(gdouble ratio);
380 };
381
382 #endif