2 #include "servicedvd.h"
3 #include <lib/base/eerror.h>
4 #include <lib/base/object.h>
5 #include <lib/base/ebase.h>
7 #include <lib/service/service.h>
8 #include <lib/base/init_num.h>
9 #include <lib/base/init.h>
10 #include <lib/gui/esubtitle.h>
11 #include <lib/gdi/gpixmap.h>
14 #include <netinet/in.h>
16 #error no byte order defined!
20 #include <dreamdvd/ddvdlib.h>
25 eServiceFactoryDVD::eServiceFactoryDVD()
27 ePtr<eServiceCenter> sc;
29 eServiceCenter::getPrivInstance(sc);
32 std::list<std::string> extensions;
33 extensions.push_back("iso");
34 sc->addServiceFactory(eServiceFactoryDVD::id, this, extensions);
38 eServiceFactoryDVD::~eServiceFactoryDVD()
40 ePtr<eServiceCenter> sc;
42 eServiceCenter::getPrivInstance(sc);
44 sc->removeServiceFactory(eServiceFactoryDVD::id);
47 DEFINE_REF(eServiceFactoryDVD)
50 RESULT eServiceFactoryDVD::play(const eServiceReference &ref, ePtr<iPlayableService> &ptr)
53 ptr = new eServiceDVD(ref.path.c_str());
57 RESULT eServiceFactoryDVD::record(const eServiceReference &ref, ePtr<iRecordableService> &ptr)
63 RESULT eServiceFactoryDVD::list(const eServiceReference &, ePtr<iListableService> &ptr)
70 RESULT eServiceFactoryDVD::info(const eServiceReference &ref, ePtr<iStaticServiceInformation> &ptr)
76 RESULT eServiceFactoryDVD::offlineOperations(const eServiceReference &, ePtr<iServiceOfflineOperations> &ptr)
84 DEFINE_REF(eServiceDVD);
86 eServiceDVD::eServiceDVD(const char *filename):
88 m_ddvdconfig(ddvd_create()),
89 m_pixmap(new gPixmap(eSize(720, 576), 32)),
93 m_sn(eApp, ddvd_get_messagepipe_fd(m_ddvdconfig), eSocketNotifier::Read|eSocketNotifier::Priority|eSocketNotifier::Error|eSocketNotifier::Hungup),
96 eDebug("SERVICEDVD construct!");
98 ddvd_set_dvd_path(m_ddvdconfig, filename);
99 ddvd_set_ac3thru(m_ddvdconfig, 0);
100 ddvd_set_language(m_ddvdconfig, "de");
101 ddvd_set_video(m_ddvdconfig, DDVD_16_9, DDVD_PAL);
102 ddvd_set_lfb(m_ddvdconfig, (unsigned char *)m_pixmap->surface->data, 720, 576, 4, 720*4);
103 CONNECT(m_sn.activated, eServiceDVD::gotMessage);
104 CONNECT(m_pump.recv_msg, eServiceDVD::gotThreadMessage);
105 strcpy(m_ddvd_titlestring,"");
109 void eServiceDVD::gotThreadMessage(const int &msg)
113 case 1: // thread stopped
115 m_event(this, evStopped);
120 void eServiceDVD::gotMessage(int what)
122 switch(ddvd_get_next_message(m_ddvdconfig,1))
124 case DDVD_COLORTABLE_UPDATE:
127 struct ddvd_color ctmp[4];
128 ddvd_get_last_colortable(ddvdconfig, ctmp);
132 rd1[252+i]=ctmp[i].red;
133 bl1[252+i]=ctmp[i].blue;
134 gn1[252+i]=ctmp[i].green;
135 tr1[252+i]=ctmp[i].trans;
138 if(ioctl(fb, FBIOPUTCMAP, &colormap) == -1)
140 printf("Framebuffer: <FBIOPUTCMAP failed>\n");
144 eDebug("no support for 8bpp framebuffer in dvdplayer yet!");
147 case DDVD_SCREEN_UPDATE:
148 eDebug("DVD_SCREEN_UPDATE!");
149 if (m_subtitle_widget)
150 m_subtitle_widget->setPixmap(m_pixmap, eRect(0, 0, 720, 576));
152 case DDVD_SHOWOSD_STATE_PLAY:
154 eDebug("DVD_SHOWOSD_STATE_PLAY!");
156 m_event(this, evUser+1);
159 case DDVD_SHOWOSD_STATE_PAUSE:
161 eDebug("DVD_SHOWOSD_STATE_PAUSE!");
162 m_event(this, evUser+2);
165 case DDVD_SHOWOSD_STATE_FFWD:
167 eDebug("DVD_SHOWOSD_STATE_FFWD!");
168 m_event(this, evUser+3);
171 case DDVD_SHOWOSD_STATE_FBWD:
173 eDebug("DVD_SHOWOSD_STATE_FBWD!");
174 m_event(this, evUser+4);
177 case DDVD_SHOWOSD_STRING:
179 eDebug("DVD_SHOWOSD_STRING!");
180 m_event(this, evUser+5);
183 case DDVD_SHOWOSD_AUDIO:
185 eDebug("DVD_SHOWOSD_STRING!");
186 m_event(this, evUser+6);
189 case DDVD_SHOWOSD_SUBTITLE:
191 eDebug("DVD_SHOWOSD_SUBTITLE!");
192 m_event((iPlayableService*)this, evUpdatedInfo);
193 m_event(this, evUser+7);
196 case DDVD_EOF_REACHED:
197 eDebug("DVD_EOF_REACHED!");
198 m_event(this, evEOF);
200 case DDVD_SOF_REACHED:
201 eDebug("DVD_SOF_REACHED!");
202 m_event(this, evSOF);
204 case DDVD_SHOWOSD_TIME:
206 static struct ddvd_time last_info;
207 struct ddvd_time info;
208 eDebug("DVD_SHOWOSD_TIME!");
209 ddvd_get_last_time(m_ddvdconfig, &info);
212 ddvd_get_last_spu(m_ddvdconfig, &spu_id, &spu_lang);
213 if ( info.pos_chapter != last_info.pos_chapter )
215 m_event(this, evUser+8); // chapterUpdated
217 if ( info.pos_title != last_info.pos_title )
219 m_event(this, evUser+9); // titleUpdated
221 ddvd_get_last_time(m_ddvdconfig, &last_info);
224 case DDVD_SHOWOSD_TITLESTRING:
226 ddvd_get_title_string(m_ddvdconfig, m_ddvd_titlestring);
227 eDebug("DDVD_SHOWOSD_TITLESTRING: %s",m_ddvd_titlestring);
229 m_event(this, evStart);
232 case DDVD_MENU_OPENED:
233 eDebug("DVD_MENU_OPENED!");
235 m_event(this, evSeekableStatusChanged);
236 m_event(this, evUser+11);
238 case DDVD_MENU_CLOSED:
239 eDebug("DVD_MENU_CLOSED!");
241 m_event(this, evSeekableStatusChanged);
242 m_event(this, evUser+12);
249 eServiceDVD::~eServiceDVD()
251 eDebug("SERVICEDVD destruct!");
253 ddvd_close(m_ddvdconfig);
256 RESULT eServiceDVD::connectEvent(const Slot2<void,iPlayableService*,int> &event, ePtr<eConnection> &connection)
258 connection = new eConnection((iPlayableService*)this, m_event.connect(event));
262 RESULT eServiceDVD::start()
264 assert(m_state == stIdle);
266 eDebug("eServiceDVD starting");
268 // m_event(this, evStart);
272 RESULT eServiceDVD::stop()
274 assert(m_state != stIdle);
275 if (m_state == stStopped)
277 eDebug("DVD: stop %s", m_filename.c_str());
279 ddvd_send_key(m_ddvdconfig, DDVD_KEY_EXIT);
280 struct ddvd_time info;
281 ddvd_get_last_time(m_ddvdconfig, &info);
282 if ( info.pos_chapter < info.end_chapter )
285 pos = info.pos_hours * 3600;
286 pos += info.pos_minutes * 60;
287 pos += info.pos_seconds;
295 RESULT eServiceDVD::setTarget(int target)
300 RESULT eServiceDVD::pause(ePtr<iPauseableService> &ptr)
306 RESULT eServiceDVD::seek(ePtr<iSeekableService> &ptr)
312 RESULT eServiceDVD::subtitle(ePtr<iSubtitleOutput> &ptr)
318 RESULT eServiceDVD::keys(ePtr<iServiceKeys> &ptr)
325 RESULT eServiceDVD::setSlowMotion(int ratio)
330 RESULT eServiceDVD::setFastForward(int trick)
332 eDebug("setTrickmode(%d)", trick);
333 while (m_current_trick > trick && m_current_trick != -64)
335 ddvd_send_key(m_ddvdconfig, DDVD_KEY_FBWD);
336 if (m_current_trick == 0)
337 m_current_trick = -2;
338 else if (m_current_trick > 0)
340 m_current_trick /= 2;
341 if (abs(m_current_trick) == 1)
345 m_current_trick *= 2;
347 while (m_current_trick < trick && m_current_trick != 64)
349 ddvd_send_key(m_ddvdconfig, DDVD_KEY_FFWD);
350 if (m_current_trick == 0)
352 else if (m_current_trick < 0)
354 m_current_trick /= 2;
355 if (abs(m_current_trick) == 1)
359 m_current_trick *= 2;
364 RESULT eServiceDVD::pause()
366 eDebug("set pause!\n");
367 ddvd_send_key(m_ddvdconfig, DDVD_KEY_PAUSE);
371 RESULT eServiceDVD::unpause()
373 eDebug("set unpause!\n");
374 ddvd_send_key(m_ddvdconfig, DDVD_KEY_PLAY);
378 void eServiceDVD::thread()
380 eDebug("eServiceDVD dvd thread started");
382 ddvd_run(m_ddvdconfig);
385 void eServiceDVD::thread_finished()
387 eDebug("eServiceDVD dvd thread finished");
388 m_pump.send(1); // inform main thread
391 RESULT eServiceDVD::info(ePtr<iServiceInformation>&i)
397 RESULT eServiceDVD::getName(std::string &name)
399 if ( m_ddvd_titlestring[0] != '\0' )
400 name = m_ddvd_titlestring;
406 int eServiceDVD::getInfo(int w)
413 return resIsPyObject; // then getInfoObject should be called
417 return resIsString; // then getInfoString should be called
420 struct ddvd_time info;
421 ddvd_get_last_time(m_ddvdconfig, &info);
422 return info.pos_chapter;
426 struct ddvd_time info;
427 ddvd_get_last_time(m_ddvdconfig, &info);
428 return info.end_chapter;
433 struct ddvd_time info;
434 ddvd_get_last_time(m_ddvdconfig, &info);
435 return info.pos_title;
439 struct ddvd_time info;
440 ddvd_get_last_time(m_ddvdconfig, &info);
441 return info.end_title;
444 case sTXTPID: // we abuse HAS_TELEXT icon in InfoBar to signalize subtitles status
448 ddvd_get_last_spu(m_ddvdconfig, &spu_id, &spu_lang);
456 std::string eServiceDVD::getInfoString(int w)
463 ddvd_get_last_spu(m_ddvdconfig, &spu_id, &spu_lang);
464 unsigned char spu_string[3]={spu_lang >> 8, spu_lang, 0};
469 sprintf(osd,"%d - %s",spu_id+1,spu_string);
475 int audio_id,audio_type;
477 ddvd_get_last_audio(m_ddvdconfig, &audio_id, &audio_lang, &audio_type);
478 char audio_string[3]={audio_lang >> 8, audio_lang, 0};
483 sprintf(audio_form,"MPEG");
486 sprintf(audio_form,"AC3");
489 sprintf(audio_form,"DTS");
492 sprintf(audio_form,"LPCM");
495 sprintf(audio_form,"-");
498 sprintf(osd,"%d - %s (%s)",audio_id+1,audio_string,audio_form);
502 eDebug("unhandled getInfoString(%d)", w);
507 PyObject *eServiceDVD::getInfoObject(int w)
512 eDebug("unhandled getInfoObject(%d)", w);
517 RESULT eServiceDVD::enableSubtitles(eWidget *parent, SWIG_PYOBJECT(ePyObject) entry)
519 if (m_subtitle_widget)
520 delete m_subtitle_widget;
521 m_subtitle_widget = new eSubtitleWidget(parent);
522 m_subtitle_widget->resize(parent->size());
523 m_subtitle_widget->setPixmap(m_pixmap, eRect(0, 0, 720, 576));
524 m_subtitle_widget->setZPosition(-1);
525 m_subtitle_widget->show();
529 RESULT eServiceDVD::disableSubtitles(eWidget *parent)
531 delete m_subtitle_widget;
532 m_subtitle_widget = 0;
536 PyObject *eServiceDVD::getSubtitleList()
538 eDebug("eServiceDVD::getSubtitleList nyi");
542 PyObject *eServiceDVD::getCachedSubtitle()
544 eDebug("eServiceDVD::getCachedSubtitle nyi");
548 RESULT eServiceDVD::getLength(pts_t &len)
550 // eDebug("eServiceDVD::getLength");
551 struct ddvd_time info;
552 ddvd_get_last_time(m_ddvdconfig, &info);
553 len = info.end_hours * 3600;
554 len += info.end_minutes * 60;
555 len += info.end_seconds;
560 RESULT eServiceDVD::seekTo(pts_t to)
562 struct ddvd_time info;
565 ddvd_get_last_time(m_ddvdconfig, &info);
566 cur = info.pos_hours * 3600;
567 cur += info.pos_minutes * 60;
568 cur += info.pos_seconds;
569 eDebug("seekTo %lld, cur %d, diff %lld", to, cur, cur - to);
570 ddvd_skip_seconds(m_ddvdconfig, cur - to);
574 RESULT eServiceDVD::seekRelative(int direction, pts_t to)
576 int seconds = to / 90000;
577 seconds *= direction;
578 eDebug("seekRelative %d %d", direction, seconds);
579 ddvd_skip_seconds(m_ddvdconfig, seconds);
583 RESULT eServiceDVD::getPlayPosition(pts_t &pos)
585 struct ddvd_time info;
586 ddvd_get_last_time(m_ddvdconfig, &info);
587 pos = info.pos_hours * 3600;
588 pos += info.pos_minutes * 60;
589 pos += info.pos_seconds;
590 // eDebug("getPlayPosition %lld", pos);
595 RESULT eServiceDVD::seekTitle(int title)
597 eDebug("setTitle %d", title);
598 ddvd_set_title(m_ddvdconfig, title);
602 RESULT eServiceDVD::seekChapter(int chapter)
604 eDebug("setChapter %d", chapter);
606 ddvd_set_chapter(m_ddvdconfig, chapter);
610 RESULT eServiceDVD::setTrickmode(int trick)
615 RESULT eServiceDVD::isCurrentlySeekable()
617 return m_state == stRunning;
620 RESULT eServiceDVD::keyPressed(int key)
624 case iServiceKeys::keyLeft:
625 ddvd_send_key(m_ddvdconfig, DDVD_KEY_LEFT);
627 case iServiceKeys::keyRight:
628 ddvd_send_key(m_ddvdconfig, DDVD_KEY_RIGHT);
630 case iServiceKeys::keyUp:
631 ddvd_send_key(m_ddvdconfig, DDVD_KEY_UP);
633 case iServiceKeys::keyDown:
634 ddvd_send_key(m_ddvdconfig, DDVD_KEY_DOWN);
636 case iServiceKeys::keyOk:
637 ddvd_send_key(m_ddvdconfig, DDVD_KEY_OK);
639 case iServiceKeys::keyUser:
640 ddvd_send_key(m_ddvdconfig, DDVD_KEY_AUDIO);
642 case iServiceKeys::keyUser+1:
643 ddvd_send_key(m_ddvdconfig, DDVD_KEY_SUBTITLE);
645 case iServiceKeys::keyUser+2:
646 ddvd_send_key(m_ddvdconfig, DDVD_KEY_AUDIOMENU);
648 case iServiceKeys::keyUser+3:
649 ddvd_send_key(m_ddvdconfig, DDVD_KEY_NEXT_CHAPTER);
651 case iServiceKeys::keyUser+4:
652 ddvd_send_key(m_ddvdconfig, DDVD_KEY_PREV_CHAPTER);
654 case iServiceKeys::keyUser+5:
655 ddvd_send_key(m_ddvdconfig, DDVD_KEY_NEXT_TITLE);
657 case iServiceKeys::keyUser+6:
658 ddvd_send_key(m_ddvdconfig, DDVD_KEY_PREV_TITLE);
660 case iServiceKeys::keyUser+7:
661 ddvd_send_key(m_ddvdconfig, DDVD_KEY_MENU);
669 RESULT eServiceDVD::cueSheet(ePtr<iCueSheet> &ptr)
680 PyObject *eServiceDVD::getCutList()
682 ePyObject list = PyList_New(1);
683 ePyObject tuple = PyTuple_New(2);
684 PyTuple_SetItem(tuple, 0, PyLong_FromLongLong(m_cue_pts));
685 PyTuple_SetItem(tuple, 1, PyInt_FromLong(3));
686 PyList_SetItem(list, 0, tuple);
690 void eServiceDVD::setCutList(ePyObject list)
694 void eServiceDVD::setCutListEnable(int enable)
698 void eServiceDVD::loadCuesheet()
700 eDebug("eServiceDVD::loadCuesheet()");
702 if ( m_ddvd_titlestring[0] != '\0' )
703 snprintf(filename, 128, "/home/root/dvd-%s.cuts", m_ddvd_titlestring);
705 eDebug("eServiceDVD::loadCuesheet() filename=%s",filename);
707 FILE *f = fopen(filename, "rb");
711 eDebug("loading cuts..");
712 unsigned long long where;
715 if (!fread(&where, sizeof(where), 1, f))
718 if (!fread(&what, sizeof(what), 1, f))
721 #if BYTE_ORDER == LITTLE_ENDIAN
722 where = bswap_64(where);
729 eDebug("cutfile not found!");
731 eDebug("eServiceDVD::loadCuesheet() pts=%lld",m_cue_pts);
734 m_event((iPlayableService*)this, evCuesheetChanged);
737 void eServiceDVD::saveCuesheet()
739 eDebug("eServiceDVD::saveCuesheet() pts=%lld",m_cue_pts);
741 if ( m_ddvd_titlestring[0] != '\0' )
742 snprintf(filename, 128, "/home/root/dvd-%s.cuts", m_ddvd_titlestring);
744 FILE *f = fopen(filename, "wb");
748 unsigned long long where;
752 #if BYTE_ORDER == BIG_ENDIAN
755 where = bswap_64(m_cue_pts);
758 fwrite(&where, sizeof(where), 1, f);
759 fwrite(&what, sizeof(what), 1, f);
765 eAutoInitPtr<eServiceFactoryDVD> init_eServiceFactoryDVD(eAutoInitNumbers::service+1, "eServiceFactoryDVD");
770 Py_InitModule("servicedvd", NULL);