2 #include "servicedvd.h"
3 #include <lib/base/eerror.h>
4 #include <lib/base/object.h>
5 #include <lib/base/ebase.h>
6 #include <lib/base/nconfig.h>
8 #include <lib/service/service.h>
9 #include <lib/base/init_num.h>
10 #include <lib/base/init.h>
11 #include <lib/gui/esubtitle.h>
12 #include <lib/gdi/gpixmap.h>
15 #include <netinet/in.h>
17 #error no byte order defined!
21 #include <dreamdvd/ddvdlib.h>
26 eServiceFactoryDVD::eServiceFactoryDVD()
28 ePtr<eServiceCenter> sc;
30 eServiceCenter::getPrivInstance(sc);
33 std::list<std::string> extensions;
34 extensions.push_back("iso");
35 sc->addServiceFactory(eServiceFactoryDVD::id, this, extensions);
39 eServiceFactoryDVD::~eServiceFactoryDVD()
41 ePtr<eServiceCenter> sc;
43 eServiceCenter::getPrivInstance(sc);
45 sc->removeServiceFactory(eServiceFactoryDVD::id);
48 DEFINE_REF(eServiceFactoryDVD)
51 RESULT eServiceFactoryDVD::play(const eServiceReference &ref, ePtr<iPlayableService> &ptr)
54 ptr = new eServiceDVD(ref.path.c_str());
58 RESULT eServiceFactoryDVD::record(const eServiceReference &/*ref*/, ePtr<iRecordableService> &ptr)
64 RESULT eServiceFactoryDVD::list(const eServiceReference &, ePtr<iListableService> &ptr)
71 RESULT eServiceFactoryDVD::info(const eServiceReference &/*ref*/, ePtr<iStaticServiceInformation> &ptr)
77 RESULT eServiceFactoryDVD::offlineOperations(const eServiceReference &, ePtr<iServiceOfflineOperations> &ptr)
85 DEFINE_REF(eServiceDVD);
87 eServiceDVD::eServiceDVD(const char *filename):
89 m_ddvdconfig(ddvd_create()),
90 m_pixmap(new gPixmap(eSize(720, 576), 32)),
94 m_sn(eApp, ddvd_get_messagepipe_fd(m_ddvdconfig), eSocketNotifier::Read|eSocketNotifier::Priority|eSocketNotifier::Error|eSocketNotifier::Hungup),
98 eDebug("SERVICEDVD construct!");
100 ddvd_set_dvd_path(m_ddvdconfig, filename);
101 ddvd_set_ac3thru(m_ddvdconfig, 0);
102 ddvd_set_language(m_ddvdconfig, "de");
104 if (ePythonConfigQuery::getConfigValue("config.av.aspect", aspect) != 0)
106 if (aspect == "4_3_letterbox")
107 ddvd_set_video(m_ddvdconfig, DDVD_4_3_LETTERBOX, DDVD_PAL);
108 else if (aspect == "4_3_panscan")
109 ddvd_set_video(m_ddvdconfig, DDVD_4_3_PAN_SCAN, DDVD_PAL);
111 ddvd_set_video(m_ddvdconfig, DDVD_16_9, DDVD_PAL);
113 ddvd_set_lfb(m_ddvdconfig, (unsigned char *)m_pixmap->surface->data, 720, 576, 4, 720*4);
114 CONNECT(m_sn.activated, eServiceDVD::gotMessage);
115 CONNECT(m_pump.recv_msg, eServiceDVD::gotThreadMessage);
116 strcpy(m_ddvd_titlestring,"");
120 void eServiceDVD::gotThreadMessage(const int &msg)
124 case 1: // thread stopped
126 m_event(this, evStopped);
131 void eServiceDVD::gotMessage(int /*what*/)
133 switch(ddvd_get_next_message(m_ddvdconfig,1))
135 case DDVD_COLORTABLE_UPDATE:
138 struct ddvd_color ctmp[4];
139 ddvd_get_last_colortable(ddvdconfig, ctmp);
143 rd1[252+i]=ctmp[i].red;
144 bl1[252+i]=ctmp[i].blue;
145 gn1[252+i]=ctmp[i].green;
146 tr1[252+i]=ctmp[i].trans;
149 if(ioctl(fb, FBIOPUTCMAP, &colormap) == -1)
151 printf("Framebuffer: <FBIOPUTCMAP failed>\n");
155 eDebug("no support for 8bpp framebuffer in dvdplayer yet!");
158 case DDVD_SCREEN_UPDATE:
159 eDebug("DVD_SCREEN_UPDATE!");
160 if (m_subtitle_widget)
161 m_subtitle_widget->setPixmap(m_pixmap, eRect(0, 0, 720, 576));
163 case DDVD_SHOWOSD_STATE_PLAY:
165 eDebug("DVD_SHOWOSD_STATE_PLAY!");
167 m_event(this, evUser+1);
170 case DDVD_SHOWOSD_STATE_PAUSE:
172 eDebug("DVD_SHOWOSD_STATE_PAUSE!");
173 m_event(this, evUser+2);
176 case DDVD_SHOWOSD_STATE_FFWD:
178 eDebug("DVD_SHOWOSD_STATE_FFWD!");
179 m_event(this, evUser+3);
182 case DDVD_SHOWOSD_STATE_FBWD:
184 eDebug("DVD_SHOWOSD_STATE_FBWD!");
185 m_event(this, evUser+4);
188 case DDVD_SHOWOSD_STRING:
190 eDebug("DVD_SHOWOSD_STRING!");
191 m_event(this, evUser+5);
194 case DDVD_SHOWOSD_AUDIO:
196 eDebug("DVD_SHOWOSD_STRING!");
197 m_event(this, evUser+6);
200 case DDVD_SHOWOSD_SUBTITLE:
202 eDebug("DVD_SHOWOSD_SUBTITLE!");
203 m_event((iPlayableService*)this, evUpdatedInfo);
204 m_event(this, evUser+7);
207 case DDVD_EOF_REACHED:
208 eDebug("DVD_EOF_REACHED!");
209 m_event(this, evEOF);
211 case DDVD_SOF_REACHED:
212 eDebug("DVD_SOF_REACHED!");
213 m_event(this, evSOF);
215 case DDVD_SHOWOSD_TIME:
217 static struct ddvd_time last_info;
218 struct ddvd_time info;
219 // eDebug("DVD_SHOWOSD_TIME!");
220 ddvd_get_last_time(m_ddvdconfig, &info);
221 if ( info.pos_chapter != last_info.pos_chapter )
222 m_event(this, evUser+8); // chapterUpdated
223 if ( info.pos_title != last_info.pos_title )
224 m_event(this, evUser+9); // titleUpdated
225 memcpy(&last_info, &info, sizeof(struct ddvd_time));
228 case DDVD_SHOWOSD_TITLESTRING:
230 ddvd_get_title_string(m_ddvdconfig, m_ddvd_titlestring);
231 eDebug("DDVD_SHOWOSD_TITLESTRING: %s",m_ddvd_titlestring);
233 m_event(this, evStart);
236 case DDVD_MENU_OPENED:
237 eDebug("DVD_MENU_OPENED!");
239 m_event(this, evSeekableStatusChanged);
240 m_event(this, evUser+11);
242 case DDVD_MENU_CLOSED:
243 eDebug("DVD_MENU_CLOSED!");
245 m_event(this, evSeekableStatusChanged);
246 m_event(this, evUser+12);
253 eServiceDVD::~eServiceDVD()
255 eDebug("SERVICEDVD destruct!");
257 ddvd_close(m_ddvdconfig);
260 RESULT eServiceDVD::connectEvent(const Slot2<void,iPlayableService*,int> &event, ePtr<eConnection> &connection)
262 connection = new eConnection((iPlayableService*)this, m_event.connect(event));
266 RESULT eServiceDVD::start()
268 assert(m_state == stIdle);
270 eDebug("eServiceDVD starting");
272 // m_event(this, evStart);
276 RESULT eServiceDVD::stop()
278 assert(m_state != stIdle);
279 if (m_state == stStopped)
281 eDebug("DVD: stop %s", m_filename.c_str());
283 ddvd_send_key(m_ddvdconfig, DDVD_KEY_EXIT);
284 struct ddvd_time info;
285 ddvd_get_last_time(m_ddvdconfig, &info);
286 if ( info.pos_chapter < info.end_chapter )
289 pos = info.pos_hours * 3600;
290 pos += info.pos_minutes * 60;
291 pos += info.pos_seconds;
293 pos += info.pos_title * 256;
294 pos += info.pos_chapter;
296 eDebug("POS %llu\n", m_cue_pts);
302 RESULT eServiceDVD::setTarget(int /*target*/)
307 RESULT eServiceDVD::pause(ePtr<iPauseableService> &ptr)
313 RESULT eServiceDVD::seek(ePtr<iSeekableService> &ptr)
319 RESULT eServiceDVD::subtitle(ePtr<iSubtitleOutput> &ptr)
325 RESULT eServiceDVD::keys(ePtr<iServiceKeys> &ptr)
332 RESULT eServiceDVD::setSlowMotion(int /*ratio*/)
337 RESULT eServiceDVD::setFastForward(int trick)
339 eDebug("setTrickmode(%d)", trick);
340 while (m_current_trick > trick && m_current_trick != -64)
342 ddvd_send_key(m_ddvdconfig, DDVD_KEY_FBWD);
343 if (m_current_trick == 0)
344 m_current_trick = -2;
345 else if (m_current_trick > 0)
347 m_current_trick /= 2;
348 if (abs(m_current_trick) == 1)
352 m_current_trick *= 2;
354 while (m_current_trick < trick && m_current_trick != 64)
356 ddvd_send_key(m_ddvdconfig, DDVD_KEY_FFWD);
357 if (m_current_trick == 0)
359 else if (m_current_trick < 0)
361 m_current_trick /= 2;
362 if (abs(m_current_trick) == 1)
366 m_current_trick *= 2;
371 RESULT eServiceDVD::pause()
373 eDebug("set pause!\n");
374 ddvd_send_key(m_ddvdconfig, DDVD_KEY_PAUSE);
378 RESULT eServiceDVD::unpause()
380 eDebug("set unpause!\n");
381 ddvd_send_key(m_ddvdconfig, DDVD_KEY_PLAY);
385 void eServiceDVD::thread()
387 eDebug("eServiceDVD dvd thread started");
389 ddvd_run(m_ddvdconfig);
392 void eServiceDVD::thread_finished()
394 eDebug("eServiceDVD dvd thread finished");
395 m_pump.send(1); // inform main thread
398 RESULT eServiceDVD::info(ePtr<iServiceInformation>&i)
404 RESULT eServiceDVD::getName(std::string &name)
406 if ( m_ddvd_titlestring[0] != '\0' )
407 name = m_ddvd_titlestring;
413 int eServiceDVD::getInfo(int w)
420 return resIsPyObject; // then getInfoObject should be called
424 return resIsString; // then getInfoString should be called
427 struct ddvd_time info;
428 ddvd_get_last_time(m_ddvdconfig, &info);
429 return info.pos_chapter;
433 struct ddvd_time info;
434 ddvd_get_last_time(m_ddvdconfig, &info);
435 return info.end_chapter;
439 struct ddvd_time info;
440 ddvd_get_last_time(m_ddvdconfig, &info);
441 return info.pos_title;
445 struct ddvd_time info;
446 ddvd_get_last_time(m_ddvdconfig, &info);
447 return info.end_title;
449 case sTXTPID: // we abuse HAS_TELEXT icon in InfoBar to signalize subtitles status
453 ddvd_get_last_spu(m_ddvdconfig, &spu_id, &spu_lang);
461 std::string eServiceDVD::getInfoString(int w)
468 ddvd_get_last_spu(m_ddvdconfig, &spu_id, &spu_lang);
469 unsigned char spu_string[3]={spu_lang >> 8, spu_lang, 0};
474 sprintf(osd,"%d - %s",spu_id+1,spu_string);
480 int audio_id,audio_type;
482 ddvd_get_last_audio(m_ddvdconfig, &audio_id, &audio_lang, &audio_type);
483 char audio_string[3]={audio_lang >> 8, audio_lang, 0};
488 sprintf(audio_form,"MPEG");
491 sprintf(audio_form,"AC3");
494 sprintf(audio_form,"DTS");
497 sprintf(audio_form,"LPCM");
500 sprintf(audio_form,"-");
503 sprintf(osd,"%d - %s (%s)",audio_id+1,audio_string,audio_form);
507 eDebug("unhandled getInfoString(%d)", w);
512 PyObject *eServiceDVD::getInfoObject(int w)
517 eDebug("unhandled getInfoObject(%d)", w);
522 RESULT eServiceDVD::enableSubtitles(eWidget *parent, SWIG_PYOBJECT(ePyObject) /*entry*/)
524 if (m_subtitle_widget)
525 delete m_subtitle_widget;
526 m_subtitle_widget = new eSubtitleWidget(parent);
527 m_subtitle_widget->resize(parent->size());
528 m_subtitle_widget->setPixmap(m_pixmap, eRect(0, 0, 720, 576));
529 m_subtitle_widget->setZPosition(-1);
530 m_subtitle_widget->show();
534 RESULT eServiceDVD::disableSubtitles(eWidget */*parent*/)
536 delete m_subtitle_widget;
537 m_subtitle_widget = 0;
541 PyObject *eServiceDVD::getSubtitleList()
543 eDebug("eServiceDVD::getSubtitleList nyi");
547 PyObject *eServiceDVD::getCachedSubtitle()
549 eDebug("eServiceDVD::getCachedSubtitle nyi");
553 RESULT eServiceDVD::getLength(pts_t &len)
555 // eDebug("eServiceDVD::getLength");
556 struct ddvd_time info;
557 ddvd_get_last_time(m_ddvdconfig, &info);
558 len = info.end_hours * 3600;
559 len += info.end_minutes * 60;
560 len += info.end_seconds;
565 RESULT eServiceDVD::seekTo(pts_t to)
567 struct ddvd_time info;
570 ddvd_get_last_time(m_ddvdconfig, &info);
571 cur = info.pos_hours * 3600;
572 cur += info.pos_minutes * 60;
573 cur += info.pos_seconds;
574 eDebug("seekTo %lld, cur %d, diff %lld", to, cur, to - cur);
575 ddvd_skip_seconds(m_ddvdconfig, to - cur);
579 RESULT eServiceDVD::seekRelative(int direction, pts_t to)
581 int seconds = to / 90000;
582 seconds *= direction;
583 eDebug("seekRelative %d %d", direction, seconds);
584 ddvd_skip_seconds(m_ddvdconfig, seconds);
588 RESULT eServiceDVD::getPlayPosition(pts_t &pos)
590 struct ddvd_time info;
591 ddvd_get_last_time(m_ddvdconfig, &info);
592 pos = info.pos_hours * 3600;
593 pos += info.pos_minutes * 60;
594 pos += info.pos_seconds;
595 // eDebug("getPlayPosition %lld", pos);
600 RESULT eServiceDVD::seekTitle(int title)
602 eDebug("setTitle %d", title);
603 ddvd_set_title(m_ddvdconfig, title);
607 RESULT eServiceDVD::seekChapter(int chapter)
609 eDebug("setChapter %d", chapter);
611 ddvd_set_chapter(m_ddvdconfig, chapter);
615 RESULT eServiceDVD::setTrickmode(int /*trick*/)
620 RESULT eServiceDVD::isCurrentlySeekable()
622 return m_state == stRunning;
625 RESULT eServiceDVD::keyPressed(int key)
629 case iServiceKeys::keyLeft:
630 ddvd_send_key(m_ddvdconfig, DDVD_KEY_LEFT);
632 case iServiceKeys::keyRight:
633 ddvd_send_key(m_ddvdconfig, DDVD_KEY_RIGHT);
635 case iServiceKeys::keyUp:
636 ddvd_send_key(m_ddvdconfig, DDVD_KEY_UP);
638 case iServiceKeys::keyDown:
639 ddvd_send_key(m_ddvdconfig, DDVD_KEY_DOWN);
641 case iServiceKeys::keyOk:
642 ddvd_send_key(m_ddvdconfig, DDVD_KEY_OK);
644 case iServiceKeys::keyUser:
645 ddvd_send_key(m_ddvdconfig, DDVD_KEY_AUDIO);
647 case iServiceKeys::keyUser+1:
648 ddvd_send_key(m_ddvdconfig, DDVD_KEY_SUBTITLE);
650 case iServiceKeys::keyUser+2:
651 ddvd_send_key(m_ddvdconfig, DDVD_KEY_AUDIOMENU);
653 case iServiceKeys::keyUser+3:
654 ddvd_send_key(m_ddvdconfig, DDVD_KEY_NEXT_CHAPTER);
656 case iServiceKeys::keyUser+4:
657 ddvd_send_key(m_ddvdconfig, DDVD_KEY_PREV_CHAPTER);
659 case iServiceKeys::keyUser+5:
660 ddvd_send_key(m_ddvdconfig, DDVD_KEY_NEXT_TITLE);
662 case iServiceKeys::keyUser+6:
663 ddvd_send_key(m_ddvdconfig, DDVD_KEY_PREV_TITLE);
665 case iServiceKeys::keyUser+7:
666 ddvd_send_key(m_ddvdconfig, DDVD_KEY_MENU);
674 RESULT eServiceDVD::cueSheet(ePtr<iCueSheet> &ptr)
685 PyObject *eServiceDVD::getCutList()
687 ePyObject list = PyList_New(1);
688 ePyObject tuple = PyTuple_New(2);
689 PyTuple_SetItem(tuple, 0, PyLong_FromLongLong(m_cue_pts));
690 PyTuple_SetItem(tuple, 1, PyInt_FromLong(3));
691 PyList_SetItem(list, 0, tuple);
695 void eServiceDVD::setCutList(ePyObject /*list*/)
699 void eServiceDVD::setCutListEnable(int /*enable*/)
703 void eServiceDVD::loadCuesheet()
705 eDebug("eServiceDVD::loadCuesheet()");
707 if ( m_ddvd_titlestring[0] != '\0' )
708 snprintf(filename, 128, "/home/root/dvd-%s.cuts", m_ddvd_titlestring);
710 eDebug("eServiceDVD::loadCuesheet() filename=%s",filename);
712 FILE *f = fopen(filename, "rb");
716 eDebug("loading cuts..");
717 unsigned long long where;
720 if (!fread(&where, sizeof(where), 1, f))
723 if (!fread(&what, sizeof(what), 1, f))
726 #if BYTE_ORDER == LITTLE_ENDIAN
727 where = bswap_64(where);
734 eDebug("cutfile not found!");
736 eDebug("eServiceDVD::loadCuesheet() pts=%lld",m_cue_pts);
739 m_event((iPlayableService*)this, evCuesheetChanged);
742 void eServiceDVD::saveCuesheet()
744 eDebug("eServiceDVD::saveCuesheet() pts=%lld",m_cue_pts);
746 if ( m_ddvd_titlestring[0] != '\0' )
747 snprintf(filename, 128, "/home/root/dvd-%s.cuts", m_ddvd_titlestring);
749 FILE *f = fopen(filename, "wb");
753 unsigned long long where;
757 #if BYTE_ORDER == BIG_ENDIAN
760 where = bswap_64(m_cue_pts);
763 fwrite(&where, sizeof(where), 1, f);
764 fwrite(&what, sizeof(what), 1, f);
770 eAutoInitPtr<eServiceFactoryDVD> init_eServiceFactoryDVD(eAutoInitNumbers::service+1, "eServiceFactoryDVD");
775 Py_InitModule("servicedvd", NULL);