X-Git-Url: https://git.cweiske.de/enigma2.git/blobdiff_plain/17be24380f07656d14b88baf5af0d9ef3d8eddfd..b643641e2c6288eff61d0346a3dda82bd820b3b7:/lib/python/Plugins/Extensions/DVDPlayer/src/servicedvd.cpp diff --git a/lib/python/Plugins/Extensions/DVDPlayer/src/servicedvd.cpp b/lib/python/Plugins/Extensions/DVDPlayer/src/servicedvd.cpp index 016e16a1..0372c497 100644 --- a/lib/python/Plugins/Extensions/DVDPlayer/src/servicedvd.cpp +++ b/lib/python/Plugins/Extensions/DVDPlayer/src/servicedvd.cpp @@ -1,8 +1,8 @@ /* yes, it's dvd */ -#include "servicedvd.h" #include #include #include +#include #include #include #include @@ -10,17 +10,16 @@ #include #include -#ifdef cue #include #include #ifndef BYTE_ORDER #error no byte order defined! #endif -#endif //cue extern "C" { #include } +#include "servicedvd.h" // eServiceFactoryDVD @@ -52,11 +51,11 @@ DEFINE_REF(eServiceFactoryDVD) RESULT eServiceFactoryDVD::play(const eServiceReference &ref, ePtr &ptr) { // check resources... - ptr = new eServiceDVD(ref.path.c_str()); + ptr = new eServiceDVD(ref); return 0; } -RESULT eServiceFactoryDVD::record(const eServiceReference &ref, ePtr &ptr) +RESULT eServiceFactoryDVD::record(const eServiceReference &/*ref*/, ePtr &ptr) { ptr=0; return -1; @@ -69,7 +68,7 @@ RESULT eServiceFactoryDVD::list(const eServiceReference &, ePtr &ptr) +RESULT eServiceFactoryDVD::info(const eServiceReference &/*ref*/, ePtr &ptr) { ptr=0; return -1; @@ -85,31 +84,75 @@ RESULT eServiceFactoryDVD::offlineOperations(const eServiceReference &, ePtrsurface->data, 720, 576, 4, 720*4); - CONNECT(m_sn.activated, eServiceDVD::gotMessage); + + std::string ddvd_language; + if (!ePythonConfigQuery::getConfigValue("config.osd.language", ddvd_language)) + ddvd_set_language(m_ddvdconfig, (ddvd_language.substr(0,2)).c_str()); + + int fd = open("/proc/stb/video/aspect", O_RDONLY); + if (fd > -1) + { + rd = read(fd, tmp, 255); + if (rd > 2 && !strncmp(tmp, "4:3", 3)) + aspect = DDVD_4_3; + else if (rd > 4 && !strncmp(tmp, "16:10", 5)) + aspect = DDVD_16_10; + close(fd); + } + + fd = open("/proc/stb/video/policy", O_RDONLY); + if (fd > -1) + { + rd = read(fd, tmp, 255); + if (rd > 6 && !strncmp(tmp, "bestfit", 7)) + policy = DDVD_JUSTSCALE; + else if (rd > 8 && !strncmp(tmp, "letterbox", 9)) + policy = DDVD_LETTERBOX; + close(fd); + } + +#ifdef DDVD_SUPPORTS_16_10_SCALING + fd = open("/proc/stb/video/policy2", O_RDONLY); + if (fd > -1) + { + rd = read(fd, tmp, 255); + if (rd > 6 && !strncmp(tmp, "bestfit", 7)) + policy2 = DDVD_JUSTSCALE; + else if (rd > 8 && !strncmp(tmp, "letterbox", 9)) + policy2 = DDVD_LETTERBOX; + close(fd); + } + ddvd_set_video_ex(m_ddvdconfig, aspect, policy, policy2, DDVD_PAL /*unused*/); +#else + ddvd_set_video(m_ddvdconfig, aspect, policy, DDVD_PAL /*unused*/); +#warning please update libdreamdvd for 16:10 scaling support! +#endif + + CONNECT(m_sn->activated, eServiceDVD::gotMessage); CONNECT(m_pump.recv_msg, eServiceDVD::gotThreadMessage); strcpy(m_ddvd_titlestring,""); - m_doSeekTo = 0; - m_seekTitle = 0; -#ifdef cue m_cue_pts = 0; -#endif + pause(); } void eServiceDVD::gotThreadMessage(const int &msg) @@ -123,7 +166,7 @@ void eServiceDVD::gotThreadMessage(const int &msg) } } -void eServiceDVD::gotMessage(int what) +void eServiceDVD::gotMessage(int /*what*/) { switch(ddvd_get_next_message(m_ddvdconfig,1)) { @@ -152,8 +195,24 @@ void eServiceDVD::gotMessage(int what) } case DDVD_SCREEN_UPDATE: eDebug("DVD_SCREEN_UPDATE!"); - if (m_subtitle_widget) - m_subtitle_widget->setPixmap(m_pixmap, eRect(0, 0, 720, 576)); + if (m_subtitle_widget) { + int x1,x2,y1,y2; + ddvd_get_last_blit_area(m_ddvdconfig, &x1, &x2, &y1, &y2); + + int x_offset = 0, y_offset = 0, width = 720, height = 576; + +#ifdef DDVD_SUPPORTS_GET_BLIT_DESTINATION + ddvd_get_blit_destination(m_ddvdconfig, &x_offset, &y_offset, &width, &height); + eDebug("values got from ddvd: %d %d %d %d", x_offset, y_offset, width, height); + y_offset = -y_offset; + width -= x_offset * 2; + height -= y_offset * 2; +#endif + eRect dest(x_offset, y_offset, width, height); + + if (dest.width() && dest.height()) + m_subtitle_widget->setPixmap(m_pixmap, eRect(x1, y1, (x2-x1)+1, (y2-y1)+1), dest); + } break; case DDVD_SHOWOSD_STATE_PLAY: { @@ -203,35 +262,29 @@ void eServiceDVD::gotMessage(int what) eDebug("DVD_EOF_REACHED!"); m_event(this, evEOF); break; - case DDVD_SOF_REACHED: eDebug("DVD_SOF_REACHED!"); m_event(this, evSOF); break; + case DDVD_SHOWOSD_ANGLE: + { + int current, num; + ddvd_get_angle_info(m_ddvdconfig, ¤t, &num); + eDebug("DVD_ANGLE_INFO: %d / %d", current, num); + m_event(this, evUser+13); + break; + } case DDVD_SHOWOSD_TIME: { static struct ddvd_time last_info; struct ddvd_time info; +// eDebug("DVD_SHOWOSD_TIME!"); ddvd_get_last_time(m_ddvdconfig, &info); - int spu_id; - uint16_t spu_lang; - ddvd_get_last_spu(m_ddvdconfig, &spu_id, &spu_lang); if ( info.pos_chapter != last_info.pos_chapter ) - { - eDebug("DVD_SHOWOSD_TIME!"); m_event(this, evUser+8); // chapterUpdated - } - if ( info.pos_title != last_info.pos_title ) - { + if ( info.pos_title != last_info.pos_title ) m_event(this, evUser+9); // titleUpdated - } - if ( info.pos_title == m_seekTitle && m_doSeekTo ) - { - seekRelative( +1, m_doSeekTo ); - m_doSeekTo = 0; - m_seekTitle = 0; - } - ddvd_get_last_time(m_ddvdconfig, &last_info); + memcpy(&last_info, &info, sizeof(struct ddvd_time)); break; } case DDVD_SHOWOSD_TITLESTRING: @@ -239,17 +292,21 @@ void eServiceDVD::gotMessage(int what) ddvd_get_title_string(m_ddvdconfig, m_ddvd_titlestring); eDebug("DDVD_SHOWOSD_TITLESTRING: %s",m_ddvd_titlestring); loadCuesheet(); + if (!m_cue_pts) + unpause(); m_event(this, evStart); -// m_event((iPlayableService*)this, evUpdatedEventInfo); -// m_event(this, evUser+10); break; } case DDVD_MENU_OPENED: eDebug("DVD_MENU_OPENED!"); + m_state = stMenu; + m_event(this, evSeekableStatusChanged); m_event(this, evUser+11); break; case DDVD_MENU_CLOSED: eDebug("DVD_MENU_CLOSED!"); + m_state = stRunning; + m_event(this, evSeekableStatusChanged); m_event(this, evUser+12); break; default: @@ -261,7 +318,9 @@ eServiceDVD::~eServiceDVD() { eDebug("SERVICEDVD destruct!"); kill(); + saveCuesheet(); ddvd_close(m_ddvdconfig); + disableSubtitles(0); } RESULT eServiceDVD::connectEvent(const Slot2 &event, ePtr &connection) @@ -272,42 +331,26 @@ RESULT eServiceDVD::connectEvent(const Slot2 &event, RESULT eServiceDVD::start() { - assert(m_state == stIdle); + ASSERT(m_state == stIdle); m_state = stRunning; eDebug("eServiceDVD starting"); - run(); // m_event(this, evStart); return 0; } RESULT eServiceDVD::stop() { - assert(m_state != stIdle); + ASSERT(m_state != stIdle); if (m_state == stStopped) return -1; - eDebug("DVD: stop %s", m_filename.c_str()); + eDebug("DVD: stop %s", m_ref.path.c_str()); m_state = stStopped; ddvd_send_key(m_ddvdconfig, DDVD_KEY_EXIT); -#ifdef cue - struct ddvd_time info; - ddvd_get_last_time(m_ddvdconfig, &info); - if ( info.pos_chapter < info.end_chapter ) - { - pts_t pos; - pos = info.pos_hours * 3600; - pos += info.pos_minutes * 60; - pos += info.pos_seconds; - pos *= 90000; - m_cue_pts = pos; - } - else // last chapter - usually credits, don't save cue - m_cue_pts = 0; - saveCuesheet(); -#endif + return 0; } -RESULT eServiceDVD::setTarget(int target) +RESULT eServiceDVD::setTarget(int /*target*/) { return -1; } @@ -337,7 +380,7 @@ RESULT eServiceDVD::keys(ePtr &ptr) } // iPausableService -RESULT eServiceDVD::setSlowMotion(int ratio) +RESULT eServiceDVD::setSlowMotion(int /*ratio*/) { return -1; } @@ -378,12 +421,14 @@ RESULT eServiceDVD::setFastForward(int trick) RESULT eServiceDVD::pause() { + eDebug("set pause!\n"); ddvd_send_key(m_ddvdconfig, DDVD_KEY_PAUSE); return 0; } RESULT eServiceDVD::unpause() { + eDebug("set unpause!\n"); ddvd_send_key(m_ddvdconfig, DDVD_KEY_PLAY); return 0; } @@ -412,48 +457,38 @@ RESULT eServiceDVD::getName(std::string &name) if ( m_ddvd_titlestring[0] != '\0' ) name = m_ddvd_titlestring; else - name = m_filename; + name = m_ref.path; return 0; } int eServiceDVD::getInfo(int w) { switch (w) - { - case sUser: - case sArtist: - case sAlbum: - return resIsPyObject; // then getInfoObject should be called - case sComment: - case sTracknumber: - case sGenre: - return resIsString; // then getInfoString should be called - case evUser+8: + { + case sCurrentChapter: { struct ddvd_time info; ddvd_get_last_time(m_ddvdconfig, &info); return info.pos_chapter; } - case evUser+80: + case sTotalChapters: { struct ddvd_time info; ddvd_get_last_time(m_ddvdconfig, &info); return info.end_chapter; } - - case evUser+9: + case sCurrentTitle: { struct ddvd_time info; ddvd_get_last_time(m_ddvdconfig, &info); return info.pos_title; } - case evUser+90: + case sTotalTitles: { struct ddvd_time info; ddvd_get_last_time(m_ddvdconfig, &info); return info.end_title; } - case sTXTPID: // we abuse HAS_TELEXT icon in InfoBar to signalize subtitles status { int spu_id; @@ -461,6 +496,10 @@ int eServiceDVD::getInfo(int w) ddvd_get_last_spu(m_ddvdconfig, &spu_id, &spu_lang); return spu_id; } + case sUser+6: + case sUser+7: + case sUser+8: + return resIsPyObject; default: return resNA; } @@ -470,76 +509,109 @@ std::string eServiceDVD::getInfoString(int w) { switch(w) { - case evUser+7: { - int spu_id; - uint16_t spu_lang; - ddvd_get_last_spu(m_ddvdconfig, &spu_id, &spu_lang); - unsigned char spu_string[3]={spu_lang >> 8, spu_lang, 0}; - char osd[100]; - if (spu_id == -1) - sprintf(osd,""); - else - sprintf(osd,"%d - %s",spu_id+1,spu_string); -// lbo_changed=1; - return osd; - } - case evUser+6: - { + case sServiceref: + return m_ref.toString(); + default: + eDebug("unhandled getInfoString(%d)", w); + } + return ""; +} + +PyObject *eServiceDVD::getInfoObject(int w) +{ + switch(w) + { + case sUser+6: + { + ePyObject tuple = PyTuple_New(3); int audio_id,audio_type; uint16_t audio_lang; ddvd_get_last_audio(m_ddvdconfig, &audio_id, &audio_lang, &audio_type); char audio_string[3]={audio_lang >> 8, audio_lang, 0}; - char audio_form[5]; + PyTuple_SetItem(tuple, 0, PyInt_FromLong(audio_id+1)); + PyTuple_SetItem(tuple, 1, PyString_FromString(audio_string)); switch(audio_type) { case DDVD_MPEG: - sprintf(audio_form,"MPEG"); + PyTuple_SetItem(tuple, 2, PyString_FromString("MPEG")); break; case DDVD_AC3: - sprintf(audio_form,"AC3"); + PyTuple_SetItem(tuple, 2, PyString_FromString("AC3")); break; case DDVD_DTS: - sprintf(audio_form,"DTS"); + PyTuple_SetItem(tuple, 2, PyString_FromString("DTS")); break; case DDVD_LPCM: - sprintf(audio_form,"LPCM"); + PyTuple_SetItem(tuple, 2, PyString_FromString("LPCM")); break; default: - sprintf(audio_form,"-"); + PyTuple_SetItem(tuple, 2, PyString_FromString("")); } - char osd[100]; - sprintf(osd,"%d - %s (%s)",audio_id+1,audio_string,audio_form); - return osd; + return tuple; + } + case sUser+7: + { + ePyObject tuple = PyTuple_New(2); + int spu_id; + uint16_t spu_lang; + ddvd_get_last_spu(m_ddvdconfig, &spu_id, &spu_lang); + char spu_string[3]={spu_lang >> 8, spu_lang, 0}; + if (spu_id == -1) + { + PyTuple_SetItem(tuple, 0, PyInt_FromLong(0)); + PyTuple_SetItem(tuple, 1, PyString_FromString("")); } - default: - eDebug("unhandled getInfoString(%d)", w); - } - return ""; -} + else + { + PyTuple_SetItem(tuple, 0, PyInt_FromLong(spu_id+1)); + PyTuple_SetItem(tuple, 1, PyString_FromString(spu_string)); + } + return tuple; + } + case sUser+8: + { + ePyObject tuple = PyTuple_New(2); + int current, num; + ddvd_get_angle_info(m_ddvdconfig, ¤t, &num); + PyTuple_SetItem(tuple, 0, PyInt_FromLong(current)); + PyTuple_SetItem(tuple, 1, PyInt_FromLong(num)); -PyObject *eServiceDVD::getInfoObject(int w) -{ - switch(w) - { + return tuple; + } default: eDebug("unhandled getInfoObject(%d)", w); } Py_RETURN_NONE; } -RESULT eServiceDVD::enableSubtitles(eWidget *parent, SWIG_PYOBJECT(ePyObject) entry) +RESULT eServiceDVD::enableSubtitles(eWidget *parent, SWIG_PYOBJECT(ePyObject) /*entry*/) { - if (m_subtitle_widget) - delete m_subtitle_widget; + delete m_subtitle_widget; + m_subtitle_widget = new eSubtitleWidget(parent); m_subtitle_widget->resize(parent->size()); - m_subtitle_widget->setPixmap(m_pixmap, eRect(0, 0, 720, 576)); + + eSize size = eSize(720, 576); + + if (!m_pixmap) + { + m_pixmap = new gPixmap(size, 32, 1); /* allocate accel surface (if possible) */ +#ifdef DDVD_SUPPORTS_GET_BLIT_DESTINATION + ddvd_set_lfb_ex(m_ddvdconfig, (unsigned char *)m_pixmap->surface->data, size.width(), size.height(), 4, size.width()*4, 1); +#else + ddvd_set_lfb(m_ddvdconfig, (unsigned char *)m_pixmap->surface->data, size.width(), size.height(), 4, size.width()*4); +#warning please update libdreamdvd for fast scaling +#endif + run(); // start the thread + } + m_subtitle_widget->setZPosition(-1); m_subtitle_widget->show(); + return 0; } -RESULT eServiceDVD::disableSubtitles(eWidget *parent) +RESULT eServiceDVD::disableSubtitles(eWidget */*parent*/) { delete m_subtitle_widget; m_subtitle_widget = 0; @@ -570,26 +642,14 @@ RESULT eServiceDVD::getLength(pts_t &len) return 0; } -// RESULT eServiceDVD::seekTo(pts_t to) -// { -// struct ddvd_time info; -// to /= 90000; -// int cur; -// ddvd_get_last_time(m_ddvdconfig, &info); -// cur = info.pos_hours * 3600; -// cur += info.pos_minutes * 60; -// cur += info.pos_seconds; -// eDebug("seekTo %lld, cur %d, diff %lld", to, cur, cur - to); -// ddvd_skip_seconds(m_ddvdconfig, cur - to); -// return 0; -// } - RESULT eServiceDVD::seekTo(pts_t to) { - m_seekTitle = 1; - eDebug("seekTo %lld", to); - ddvd_set_title(m_ddvdconfig, m_seekTitle); - m_doSeekTo = to; + eDebug("eServiceDVD::seekTo(%lld)",to); + if ( to > 0 ) + { + eDebug("set_resume_pos: resume_info.title=%d, chapter=%d, block=%lu, audio_id=%d, audio_lock=%d, spu_id=%d, spu_lock=%d",m_resume_info.title,m_resume_info.chapter,m_resume_info.block,m_resume_info.audio_id, m_resume_info.audio_lock, m_resume_info.spu_id, m_resume_info.spu_lock); + ddvd_set_resume_pos(m_ddvdconfig, m_resume_info); + } return 0; } @@ -614,6 +674,13 @@ RESULT eServiceDVD::getPlayPosition(pts_t &pos) return 0; } +RESULT eServiceDVD::seekTitle(int title) +{ + eDebug("setTitle %d", title); + ddvd_set_title(m_ddvdconfig, title); + return 0; +} + RESULT eServiceDVD::seekChapter(int chapter) { eDebug("setChapter %d", chapter); @@ -622,14 +689,14 @@ RESULT eServiceDVD::seekChapter(int chapter) return 0; } -RESULT eServiceDVD::setTrickmode(int trick) +RESULT eServiceDVD::setTrickmode(int /*trick*/) { return -1; } RESULT eServiceDVD::isCurrentlySeekable() { - return 1; + return m_state == stRunning ? 3 : 0; } RESULT eServiceDVD::keyPressed(int key) @@ -675,13 +742,15 @@ RESULT eServiceDVD::keyPressed(int key) case iServiceKeys::keyUser+7: ddvd_send_key(m_ddvdconfig, DDVD_KEY_MENU); break; + case iServiceKeys::keyUser+8: + ddvd_send_key(m_ddvdconfig, DDVD_KEY_ANGLE); + break; default: return -1; } return 0; } -#ifdef cue RESULT eServiceDVD::cueSheet(ePtr &ptr) { if (m_cue_pts) @@ -695,130 +764,100 @@ RESULT eServiceDVD::cueSheet(ePtr &ptr) PyObject *eServiceDVD::getCutList() { - ePyObject list = PyList_New(0); - -// for (std::multiset::iterator i(m_cue_entries.begin()); i != m_cue_entries.end(); ++i) -// { - ePyObject tuple = PyTuple_New(2); -// PyTuple_SetItem(tuple, 0, PyLong_FromLongLong(i->where)); - PyTuple_SetItem(tuple, 0, PyLong_FromLongLong(m_cue_pts)); -// PyTuple_SetItem(tuple, 1, PyInt_FromLong(i->what)); - PyTuple_SetItem(tuple, 1, PyInt_FromLong(3)); - PyList_Append(list, tuple); - Py_DECREF(tuple); -// } - -// eDebug("eServiceDVD::getCutList() pts=%lld",m_cue_pts); - + ePyObject list = PyList_New(1); + ePyObject tuple = PyTuple_New(2); + PyTuple_SetItem(tuple, 0, PyLong_FromLongLong(m_cue_pts)); + PyTuple_SetItem(tuple, 1, PyInt_FromLong(3)); + PyList_SetItem(list, 0, tuple); return list; } -void eServiceDVD::setCutList(ePyObject list) +void eServiceDVD::setCutList(ePyObject /*list*/) { - eDebug("eServiceDVD::setCutList()"); - - if (!PyList_Check(list)) - return; - int size = PyList_Size(list); - int i; - -// m_cue_entries.clear(); - - for (i=0; i 3) -// break; - - m_cue_pts = where; - -// m_cue_entries.insert(cueEntry(where, what)); - } + what = ntohl(what); + + if (!fread(&m_resume_info, sizeof(struct ddvd_resume), 1, f)) + return; + if (!fread(&what, sizeof(what), 1, f)) + return; + + what = ntohl(what); + if (what != 4 ) + return; + + m_cue_pts = where; + fclose(f); -// eDebug("%d entries", m_cue_entries.size()); } else eDebug("cutfile not found!"); - - m_cuesheet_changed = 0; -// cutlistToCuesheet(); - eDebug("eServiceDVD::loadCuesheet() pts=%lld",m_cue_pts); if (m_cue_pts) + { m_event((iPlayableService*)this, evCuesheetChanged); + eDebug("eServiceDVD::loadCuesheet() pts=%lld",m_cue_pts); + } } void eServiceDVD::saveCuesheet() { - eDebug("eServiceDVD::saveCuesheet() pts=%lld",m_cue_pts); + eDebug("eServiceDVD::saveCuesheet()"); + + struct ddvd_resume resume_info; + ddvd_get_resume_pos(m_ddvdconfig, &resume_info); + + if (resume_info.title) + { + struct ddvd_time info; + ddvd_get_last_time(m_ddvdconfig, &info); + pts_t pos; + pos = info.pos_hours * 3600; + pos += info.pos_minutes * 60; + pos += info.pos_seconds; + pos *= 90000; + m_cue_pts = pos; + eDebug("ddvd_get_resume_pos resume_info.title=%d, chapter=%d, block=%lu, audio_id=%d, audio_lock=%d, spu_id=%d, spu_lock=%d (pts=%llu)",resume_info.title,resume_info.chapter,resume_info.block,resume_info.audio_id, resume_info.audio_lock, resume_info.spu_id, resume_info.spu_lock,m_cue_pts); + } + else + { + eDebug("we're in a menu or somewhere else funny. so save cuesheet with pts=0"); + m_cue_pts = 0; + } + char filename[128]; if ( m_ddvd_titlestring[0] != '\0' ) snprintf(filename, 128, "/home/root/dvd-%s.cuts", m_ddvd_titlestring); + else + snprintf(filename, 128, "%s/dvd.cuts", m_ref.path.c_str()); FILE *f = fopen(filename, "wb"); @@ -827,27 +866,22 @@ void eServiceDVD::saveCuesheet() unsigned long long where; int what; -// for (std::multiset::iterator i(m_cue_entries.begin()); i != m_cue_entries.end(); ++i) - { #if BYTE_ORDER == BIG_ENDIAN - where = m_cue_pts; -// where = i->where; + where = m_cue_pts; #else -// where = bswap_64(i->where); - where = bswap_64(m_cue_pts); + where = bswap_64(m_cue_pts); #endif -// what = htonl(i->what); - what = 3; - fwrite(&where, sizeof(where), 1, f); - fwrite(&what, sizeof(what), 1, f); - - } + what = htonl(3); + fwrite(&where, sizeof(where), 1, f); + fwrite(&what, sizeof(what), 1, f); + + what = htonl(4); + fwrite(&resume_info, sizeof(struct ddvd_resume), 1, f); + fwrite(&what, sizeof(what), 1, f); + fclose(f); } - - m_cuesheet_changed = 0; } -#endif eAutoInitPtr init_eServiceFactoryDVD(eAutoInitNumbers::service+1, "eServiceFactoryDVD");