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);
210 if ( info.pos_chapter != last_info.pos_chapter )
211 m_event(this, evUser+8); // chapterUpdated
212 if ( info.pos_title != last_info.pos_title )
213 m_event(this, evUser+9); // titleUpdated
214 memcpy(&last_info, &info, sizeof(struct ddvd_time));
217 case DDVD_SHOWOSD_TITLESTRING:
219 ddvd_get_title_string(m_ddvdconfig, m_ddvd_titlestring);
220 eDebug("DDVD_SHOWOSD_TITLESTRING: %s",m_ddvd_titlestring);
222 m_event(this, evStart);
225 case DDVD_MENU_OPENED:
226 eDebug("DVD_MENU_OPENED!");
228 m_event(this, evSeekableStatusChanged);
229 m_event(this, evUser+11);
231 case DDVD_MENU_CLOSED:
232 eDebug("DVD_MENU_CLOSED!");
234 m_event(this, evSeekableStatusChanged);
235 m_event(this, evUser+12);
242 eServiceDVD::~eServiceDVD()
244 eDebug("SERVICEDVD destruct!");
246 ddvd_close(m_ddvdconfig);
249 RESULT eServiceDVD::connectEvent(const Slot2<void,iPlayableService*,int> &event, ePtr<eConnection> &connection)
251 connection = new eConnection((iPlayableService*)this, m_event.connect(event));
255 RESULT eServiceDVD::start()
257 assert(m_state == stIdle);
259 eDebug("eServiceDVD starting");
261 // m_event(this, evStart);
265 RESULT eServiceDVD::stop()
267 assert(m_state != stIdle);
268 if (m_state == stStopped)
270 eDebug("DVD: stop %s", m_filename.c_str());
272 ddvd_send_key(m_ddvdconfig, DDVD_KEY_EXIT);
273 struct ddvd_time info;
274 ddvd_get_last_time(m_ddvdconfig, &info);
275 if ( info.pos_chapter < info.end_chapter )
278 pos = info.pos_hours * 3600;
279 pos += info.pos_minutes * 60;
280 pos += info.pos_seconds;
282 pos += info.pos_title * 256;
283 pos += info.pos_chapter;
285 eDebug("POS %llu\n", m_cue_pts);
291 RESULT eServiceDVD::setTarget(int target)
296 RESULT eServiceDVD::pause(ePtr<iPauseableService> &ptr)
302 RESULT eServiceDVD::seek(ePtr<iSeekableService> &ptr)
308 RESULT eServiceDVD::subtitle(ePtr<iSubtitleOutput> &ptr)
314 RESULT eServiceDVD::keys(ePtr<iServiceKeys> &ptr)
321 RESULT eServiceDVD::setSlowMotion(int ratio)
326 RESULT eServiceDVD::setFastForward(int trick)
328 eDebug("setTrickmode(%d)", trick);
329 while (m_current_trick > trick && m_current_trick != -64)
331 ddvd_send_key(m_ddvdconfig, DDVD_KEY_FBWD);
332 if (m_current_trick == 0)
333 m_current_trick = -2;
334 else if (m_current_trick > 0)
336 m_current_trick /= 2;
337 if (abs(m_current_trick) == 1)
341 m_current_trick *= 2;
343 while (m_current_trick < trick && m_current_trick != 64)
345 ddvd_send_key(m_ddvdconfig, DDVD_KEY_FFWD);
346 if (m_current_trick == 0)
348 else if (m_current_trick < 0)
350 m_current_trick /= 2;
351 if (abs(m_current_trick) == 1)
355 m_current_trick *= 2;
360 RESULT eServiceDVD::pause()
362 eDebug("set pause!\n");
363 ddvd_send_key(m_ddvdconfig, DDVD_KEY_PAUSE);
367 RESULT eServiceDVD::unpause()
369 eDebug("set unpause!\n");
370 ddvd_send_key(m_ddvdconfig, DDVD_KEY_PLAY);
374 void eServiceDVD::thread()
376 eDebug("eServiceDVD dvd thread started");
378 ddvd_run(m_ddvdconfig);
381 void eServiceDVD::thread_finished()
383 eDebug("eServiceDVD dvd thread finished");
384 m_pump.send(1); // inform main thread
387 RESULT eServiceDVD::info(ePtr<iServiceInformation>&i)
393 RESULT eServiceDVD::getName(std::string &name)
395 if ( m_ddvd_titlestring[0] != '\0' )
396 name = m_ddvd_titlestring;
402 int eServiceDVD::getInfo(int w)
409 return resIsPyObject; // then getInfoObject should be called
413 return resIsString; // then getInfoString should be called
416 struct ddvd_time info;
417 ddvd_get_last_time(m_ddvdconfig, &info);
418 return info.pos_chapter;
422 struct ddvd_time info;
423 ddvd_get_last_time(m_ddvdconfig, &info);
424 return info.end_chapter;
429 struct ddvd_time info;
430 ddvd_get_last_time(m_ddvdconfig, &info);
431 return info.pos_title;
435 struct ddvd_time info;
436 ddvd_get_last_time(m_ddvdconfig, &info);
437 return info.end_title;
440 case sTXTPID: // we abuse HAS_TELEXT icon in InfoBar to signalize subtitles status
444 ddvd_get_last_spu(m_ddvdconfig, &spu_id, &spu_lang);
452 std::string eServiceDVD::getInfoString(int w)
459 ddvd_get_last_spu(m_ddvdconfig, &spu_id, &spu_lang);
460 unsigned char spu_string[3]={spu_lang >> 8, spu_lang, 0};
465 sprintf(osd,"%d - %s",spu_id+1,spu_string);
471 int audio_id,audio_type;
473 ddvd_get_last_audio(m_ddvdconfig, &audio_id, &audio_lang, &audio_type);
474 char audio_string[3]={audio_lang >> 8, audio_lang, 0};
479 sprintf(audio_form,"MPEG");
482 sprintf(audio_form,"AC3");
485 sprintf(audio_form,"DTS");
488 sprintf(audio_form,"LPCM");
491 sprintf(audio_form,"-");
494 sprintf(osd,"%d - %s (%s)",audio_id+1,audio_string,audio_form);
498 eDebug("unhandled getInfoString(%d)", w);
503 PyObject *eServiceDVD::getInfoObject(int w)
508 eDebug("unhandled getInfoObject(%d)", w);
513 RESULT eServiceDVD::enableSubtitles(eWidget *parent, SWIG_PYOBJECT(ePyObject) entry)
515 if (m_subtitle_widget)
516 delete m_subtitle_widget;
517 m_subtitle_widget = new eSubtitleWidget(parent);
518 m_subtitle_widget->resize(parent->size());
519 m_subtitle_widget->setPixmap(m_pixmap, eRect(0, 0, 720, 576));
520 m_subtitle_widget->setZPosition(-1);
521 m_subtitle_widget->show();
525 RESULT eServiceDVD::disableSubtitles(eWidget *parent)
527 delete m_subtitle_widget;
528 m_subtitle_widget = 0;
532 PyObject *eServiceDVD::getSubtitleList()
534 eDebug("eServiceDVD::getSubtitleList nyi");
538 PyObject *eServiceDVD::getCachedSubtitle()
540 eDebug("eServiceDVD::getCachedSubtitle nyi");
544 RESULT eServiceDVD::getLength(pts_t &len)
546 // eDebug("eServiceDVD::getLength");
547 struct ddvd_time info;
548 ddvd_get_last_time(m_ddvdconfig, &info);
549 len = info.end_hours * 3600;
550 len += info.end_minutes * 60;
551 len += info.end_seconds;
556 RESULT eServiceDVD::seekTo(pts_t to)
558 struct ddvd_time info;
561 ddvd_get_last_time(m_ddvdconfig, &info);
562 cur = info.pos_hours * 3600;
563 cur += info.pos_minutes * 60;
564 cur += info.pos_seconds;
565 eDebug("seekTo %lld, cur %d, diff %lld", to, cur, to - cur);
566 ddvd_skip_seconds(m_ddvdconfig, to - cur);
570 RESULT eServiceDVD::seekRelative(int direction, pts_t to)
572 int seconds = to / 90000;
573 seconds *= direction;
574 eDebug("seekRelative %d %d", direction, seconds);
575 ddvd_skip_seconds(m_ddvdconfig, seconds);
579 RESULT eServiceDVD::getPlayPosition(pts_t &pos)
581 struct ddvd_time info;
582 ddvd_get_last_time(m_ddvdconfig, &info);
583 pos = info.pos_hours * 3600;
584 pos += info.pos_minutes * 60;
585 pos += info.pos_seconds;
586 // eDebug("getPlayPosition %lld", pos);
591 RESULT eServiceDVD::seekTitle(int title)
593 eDebug("setTitle %d", title);
594 ddvd_set_title(m_ddvdconfig, title);
598 RESULT eServiceDVD::seekChapter(int chapter)
600 eDebug("setChapter %d", chapter);
602 ddvd_set_chapter(m_ddvdconfig, chapter);
606 RESULT eServiceDVD::setTrickmode(int trick)
611 RESULT eServiceDVD::isCurrentlySeekable()
613 return m_state == stRunning;
616 RESULT eServiceDVD::keyPressed(int key)
620 case iServiceKeys::keyLeft:
621 ddvd_send_key(m_ddvdconfig, DDVD_KEY_LEFT);
623 case iServiceKeys::keyRight:
624 ddvd_send_key(m_ddvdconfig, DDVD_KEY_RIGHT);
626 case iServiceKeys::keyUp:
627 ddvd_send_key(m_ddvdconfig, DDVD_KEY_UP);
629 case iServiceKeys::keyDown:
630 ddvd_send_key(m_ddvdconfig, DDVD_KEY_DOWN);
632 case iServiceKeys::keyOk:
633 ddvd_send_key(m_ddvdconfig, DDVD_KEY_OK);
635 case iServiceKeys::keyUser:
636 ddvd_send_key(m_ddvdconfig, DDVD_KEY_AUDIO);
638 case iServiceKeys::keyUser+1:
639 ddvd_send_key(m_ddvdconfig, DDVD_KEY_SUBTITLE);
641 case iServiceKeys::keyUser+2:
642 ddvd_send_key(m_ddvdconfig, DDVD_KEY_AUDIOMENU);
644 case iServiceKeys::keyUser+3:
645 ddvd_send_key(m_ddvdconfig, DDVD_KEY_NEXT_CHAPTER);
647 case iServiceKeys::keyUser+4:
648 ddvd_send_key(m_ddvdconfig, DDVD_KEY_PREV_CHAPTER);
650 case iServiceKeys::keyUser+5:
651 ddvd_send_key(m_ddvdconfig, DDVD_KEY_NEXT_TITLE);
653 case iServiceKeys::keyUser+6:
654 ddvd_send_key(m_ddvdconfig, DDVD_KEY_PREV_TITLE);
656 case iServiceKeys::keyUser+7:
657 ddvd_send_key(m_ddvdconfig, DDVD_KEY_MENU);
665 RESULT eServiceDVD::cueSheet(ePtr<iCueSheet> &ptr)
676 PyObject *eServiceDVD::getCutList()
678 ePyObject list = PyList_New(1);
679 ePyObject tuple = PyTuple_New(2);
680 PyTuple_SetItem(tuple, 0, PyLong_FromLongLong(m_cue_pts));
681 PyTuple_SetItem(tuple, 1, PyInt_FromLong(3));
682 PyList_SetItem(list, 0, tuple);
686 void eServiceDVD::setCutList(ePyObject list)
690 void eServiceDVD::setCutListEnable(int enable)
694 void eServiceDVD::loadCuesheet()
696 eDebug("eServiceDVD::loadCuesheet()");
698 if ( m_ddvd_titlestring[0] != '\0' )
699 snprintf(filename, 128, "/home/root/dvd-%s.cuts", m_ddvd_titlestring);
701 eDebug("eServiceDVD::loadCuesheet() filename=%s",filename);
703 FILE *f = fopen(filename, "rb");
707 eDebug("loading cuts..");
708 unsigned long long where;
711 if (!fread(&where, sizeof(where), 1, f))
714 if (!fread(&what, sizeof(what), 1, f))
717 #if BYTE_ORDER == LITTLE_ENDIAN
718 where = bswap_64(where);
725 eDebug("cutfile not found!");
727 eDebug("eServiceDVD::loadCuesheet() pts=%lld",m_cue_pts);
730 m_event((iPlayableService*)this, evCuesheetChanged);
733 void eServiceDVD::saveCuesheet()
735 eDebug("eServiceDVD::saveCuesheet() pts=%lld",m_cue_pts);
737 if ( m_ddvd_titlestring[0] != '\0' )
738 snprintf(filename, 128, "/home/root/dvd-%s.cuts", m_ddvd_titlestring);
740 FILE *f = fopen(filename, "wb");
744 unsigned long long where;
748 #if BYTE_ORDER == BIG_ENDIAN
751 where = bswap_64(m_cue_pts);
754 fwrite(&where, sizeof(where), 1, f);
755 fwrite(&what, sizeof(what), 1, f);
761 eAutoInitPtr<eServiceFactoryDVD> init_eServiceFactoryDVD(eAutoInitNumbers::service+1, "eServiceFactoryDVD");
766 Py_InitModule("servicedvd", NULL);