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;
428 struct ddvd_time info;
429 ddvd_get_last_time(m_ddvdconfig, &info);
430 return info.pos_title;
434 struct ddvd_time info;
435 ddvd_get_last_time(m_ddvdconfig, &info);
436 return info.end_title;
438 case sTXTPID: // we abuse HAS_TELEXT icon in InfoBar to signalize subtitles status
442 ddvd_get_last_spu(m_ddvdconfig, &spu_id, &spu_lang);
450 std::string eServiceDVD::getInfoString(int w)
457 ddvd_get_last_spu(m_ddvdconfig, &spu_id, &spu_lang);
458 unsigned char spu_string[3]={spu_lang >> 8, spu_lang, 0};
463 sprintf(osd,"%d - %s",spu_id+1,spu_string);
469 int audio_id,audio_type;
471 ddvd_get_last_audio(m_ddvdconfig, &audio_id, &audio_lang, &audio_type);
472 char audio_string[3]={audio_lang >> 8, audio_lang, 0};
477 sprintf(audio_form,"MPEG");
480 sprintf(audio_form,"AC3");
483 sprintf(audio_form,"DTS");
486 sprintf(audio_form,"LPCM");
489 sprintf(audio_form,"-");
492 sprintf(osd,"%d - %s (%s)",audio_id+1,audio_string,audio_form);
496 eDebug("unhandled getInfoString(%d)", w);
501 PyObject *eServiceDVD::getInfoObject(int w)
506 eDebug("unhandled getInfoObject(%d)", w);
511 RESULT eServiceDVD::enableSubtitles(eWidget *parent, SWIG_PYOBJECT(ePyObject) entry)
513 if (m_subtitle_widget)
514 delete m_subtitle_widget;
515 m_subtitle_widget = new eSubtitleWidget(parent);
516 m_subtitle_widget->resize(parent->size());
517 m_subtitle_widget->setPixmap(m_pixmap, eRect(0, 0, 720, 576));
518 m_subtitle_widget->setZPosition(-1);
519 m_subtitle_widget->show();
523 RESULT eServiceDVD::disableSubtitles(eWidget *parent)
525 delete m_subtitle_widget;
526 m_subtitle_widget = 0;
530 PyObject *eServiceDVD::getSubtitleList()
532 eDebug("eServiceDVD::getSubtitleList nyi");
536 PyObject *eServiceDVD::getCachedSubtitle()
538 eDebug("eServiceDVD::getCachedSubtitle nyi");
542 RESULT eServiceDVD::getLength(pts_t &len)
544 // eDebug("eServiceDVD::getLength");
545 struct ddvd_time info;
546 ddvd_get_last_time(m_ddvdconfig, &info);
547 len = info.end_hours * 3600;
548 len += info.end_minutes * 60;
549 len += info.end_seconds;
554 RESULT eServiceDVD::seekTo(pts_t to)
556 struct ddvd_time info;
559 ddvd_get_last_time(m_ddvdconfig, &info);
560 cur = info.pos_hours * 3600;
561 cur += info.pos_minutes * 60;
562 cur += info.pos_seconds;
563 eDebug("seekTo %lld, cur %d, diff %lld", to, cur, to - cur);
564 ddvd_skip_seconds(m_ddvdconfig, to - cur);
568 RESULT eServiceDVD::seekRelative(int direction, pts_t to)
570 int seconds = to / 90000;
571 seconds *= direction;
572 eDebug("seekRelative %d %d", direction, seconds);
573 ddvd_skip_seconds(m_ddvdconfig, seconds);
577 RESULT eServiceDVD::getPlayPosition(pts_t &pos)
579 struct ddvd_time info;
580 ddvd_get_last_time(m_ddvdconfig, &info);
581 pos = info.pos_hours * 3600;
582 pos += info.pos_minutes * 60;
583 pos += info.pos_seconds;
584 // eDebug("getPlayPosition %lld", pos);
589 RESULT eServiceDVD::seekTitle(int title)
591 eDebug("setTitle %d", title);
592 ddvd_set_title(m_ddvdconfig, title);
596 RESULT eServiceDVD::seekChapter(int chapter)
598 eDebug("setChapter %d", chapter);
600 ddvd_set_chapter(m_ddvdconfig, chapter);
604 RESULT eServiceDVD::setTrickmode(int trick)
609 RESULT eServiceDVD::isCurrentlySeekable()
611 return m_state == stRunning;
614 RESULT eServiceDVD::keyPressed(int key)
618 case iServiceKeys::keyLeft:
619 ddvd_send_key(m_ddvdconfig, DDVD_KEY_LEFT);
621 case iServiceKeys::keyRight:
622 ddvd_send_key(m_ddvdconfig, DDVD_KEY_RIGHT);
624 case iServiceKeys::keyUp:
625 ddvd_send_key(m_ddvdconfig, DDVD_KEY_UP);
627 case iServiceKeys::keyDown:
628 ddvd_send_key(m_ddvdconfig, DDVD_KEY_DOWN);
630 case iServiceKeys::keyOk:
631 ddvd_send_key(m_ddvdconfig, DDVD_KEY_OK);
633 case iServiceKeys::keyUser:
634 ddvd_send_key(m_ddvdconfig, DDVD_KEY_AUDIO);
636 case iServiceKeys::keyUser+1:
637 ddvd_send_key(m_ddvdconfig, DDVD_KEY_SUBTITLE);
639 case iServiceKeys::keyUser+2:
640 ddvd_send_key(m_ddvdconfig, DDVD_KEY_AUDIOMENU);
642 case iServiceKeys::keyUser+3:
643 ddvd_send_key(m_ddvdconfig, DDVD_KEY_NEXT_CHAPTER);
645 case iServiceKeys::keyUser+4:
646 ddvd_send_key(m_ddvdconfig, DDVD_KEY_PREV_CHAPTER);
648 case iServiceKeys::keyUser+5:
649 ddvd_send_key(m_ddvdconfig, DDVD_KEY_NEXT_TITLE);
651 case iServiceKeys::keyUser+6:
652 ddvd_send_key(m_ddvdconfig, DDVD_KEY_PREV_TITLE);
654 case iServiceKeys::keyUser+7:
655 ddvd_send_key(m_ddvdconfig, DDVD_KEY_MENU);
663 RESULT eServiceDVD::cueSheet(ePtr<iCueSheet> &ptr)
674 PyObject *eServiceDVD::getCutList()
676 ePyObject list = PyList_New(1);
677 ePyObject tuple = PyTuple_New(2);
678 PyTuple_SetItem(tuple, 0, PyLong_FromLongLong(m_cue_pts));
679 PyTuple_SetItem(tuple, 1, PyInt_FromLong(3));
680 PyList_SetItem(list, 0, tuple);
684 void eServiceDVD::setCutList(ePyObject list)
688 void eServiceDVD::setCutListEnable(int enable)
692 void eServiceDVD::loadCuesheet()
694 eDebug("eServiceDVD::loadCuesheet()");
696 if ( m_ddvd_titlestring[0] != '\0' )
697 snprintf(filename, 128, "/home/root/dvd-%s.cuts", m_ddvd_titlestring);
699 eDebug("eServiceDVD::loadCuesheet() filename=%s",filename);
701 FILE *f = fopen(filename, "rb");
705 eDebug("loading cuts..");
706 unsigned long long where;
709 if (!fread(&where, sizeof(where), 1, f))
712 if (!fread(&what, sizeof(what), 1, f))
715 #if BYTE_ORDER == LITTLE_ENDIAN
716 where = bswap_64(where);
723 eDebug("cutfile not found!");
725 eDebug("eServiceDVD::loadCuesheet() pts=%lld",m_cue_pts);
728 m_event((iPlayableService*)this, evCuesheetChanged);
731 void eServiceDVD::saveCuesheet()
733 eDebug("eServiceDVD::saveCuesheet() pts=%lld",m_cue_pts);
735 if ( m_ddvd_titlestring[0] != '\0' )
736 snprintf(filename, 128, "/home/root/dvd-%s.cuts", m_ddvd_titlestring);
738 FILE *f = fopen(filename, "wb");
742 unsigned long long where;
746 #if BYTE_ORDER == BIG_ENDIAN
749 where = bswap_64(m_cue_pts);
752 fwrite(&where, sizeof(where), 1, f);
753 fwrite(&what, sizeof(what), 1, f);
759 eAutoInitPtr<eServiceFactoryDVD> init_eServiceFactoryDVD(eAutoInitNumbers::service+1, "eServiceFactoryDVD");
764 Py_InitModule("servicedvd", NULL);