From: Andreas Monzner Date: Wed, 13 Dec 2006 13:26:48 +0000 (+0000) Subject: use aspect ratio information from mpeg sequence header instead of eit (needs X-Git-Tag: 2.6.0~2595 X-Git-Url: https://git.cweiske.de/enigma2.git/commitdiff_plain/b5b839edc91a6902966079ec0b0bb5026df9df57 use aspect ratio information from mpeg sequence header instead of eit (needs new drivers) --- diff --git a/lib/dvb/decoder.cpp b/lib/dvb/decoder.cpp index 50934c71..b9acabad 100644 --- a/lib/dvb/decoder.cpp +++ b/lib/dvb/decoder.cpp @@ -1,3 +1,4 @@ +#include #include #include #if HAVE_DVB_API_VERSION < 3 @@ -178,7 +179,11 @@ eDVBVideo::eDVBVideo(eDVBDemux *demux, int dev): m_demux(demux), m_dev(dev) m_fd = ::open(filename, O_RDWR); if (m_fd < 0) eWarning("%s: %m", filename); - + else + { + m_sn = new eSocketNotifier(eApp, m_fd, eSocketNotifier::Priority); + CONNECT(m_sn->activated, eDVBVideo::video_event); + } eDebug("Video Device: %s", filename); #if HAVE_DVB_API_VERSION < 3 sprintf(filename, "/dev/dvb/card%d/demux%d", demux->adapter, demux->demux); @@ -281,6 +286,8 @@ int eDVBVideo::getPTS(pts_t &now) eDVBVideo::~eDVBVideo() { + if (m_sn) + delete m_sn; if (m_is_slow_motion) setSlowMotion(0); if (m_is_fast_forward) @@ -291,6 +298,37 @@ eDVBVideo::~eDVBVideo() ::close(m_fd_demux); } +void eDVBVideo::video_event(int) +{ +#if HAVE_DVB_API_VERSION >= 3 + struct video_event evt; + if (::ioctl(m_fd, VIDEO_GET_EVENT, &evt) < 0) + eDebug("VIDEO_GET_EVENT failed(%m)"); + else + { + if (evt.type == VIDEO_EVENT_SIZE_CHANGED) + { + struct iTSMPEGDecoder::videoEvent event; + event.type = iTSMPEGDecoder::videoEvent::eventSizeChanged; + event.aspect = evt.u.size.aspect_ratio; + event.height = evt.u.size.h; + event.width = evt.u.size.w; + /* emit */ m_event(event); + } + else + eDebug("unhandled DVBAPI Video Event %d", evt.type); + } +#else +#warning "FIXMEE!! Video Events not implemented for old api" +#endif +} + +RESULT eDVBVideo::connectEvent(const Slot1 &event, ePtr &conn) +{ + conn = new eConnection(this, m_event.connect(event)); + return 0; +} + DEFINE_REF(eDVBPCR); eDVBPCR::eDVBPCR(eDVBDemux *demux): m_demux(demux) @@ -442,6 +480,7 @@ int eTSMPEGDecoder::setState() if (m_changed & changeVideo) { m_video = new eDVBVideo(m_demux, m_decoder); + m_video->connectEvent(slot(*this, &eTSMPEGDecoder::video_event), m_video_event_conn); if (m_video->startPid(m_vpid)) { eWarning("video: startpid failed!"); @@ -489,6 +528,7 @@ int eTSMPEGDecoder::setState() { eDebug("new video"); m_video = new eDVBVideo(m_demux, m_decoder); + m_video->connectEvent(slot(*this, &eTSMPEGDecoder::video_event), m_video_event_conn); if (m_video->startPid(m_vpid, m_vtype)) { eWarning("video: startpid failed!"); @@ -549,8 +589,10 @@ RESULT eTSMPEGDecoder::setPCMDelay(int delay) fprintf(fp, "%x", delay*90); fclose(fp); m_pcm_delay = delay; + return 0; } } + return -1; } RESULT eTSMPEGDecoder::setAC3Delay(int delay) @@ -563,13 +605,15 @@ RESULT eTSMPEGDecoder::setAC3Delay(int delay) fprintf(fp, "%x", delay*90); fclose(fp); m_ac3_delay = delay; + return 0; } } + return -1; } eTSMPEGDecoder::eTSMPEGDecoder(eDVBDemux *demux, int decoder): m_demux(demux), m_changed(0), m_decoder(decoder) { - demux->connectEvent(slot(*this, &eTSMPEGDecoder::demux_event), m_demux_event); + demux->connectEvent(slot(*this, &eTSMPEGDecoder::demux_event), m_demux_event_conn); m_is_ff = m_is_sm = m_is_trickmode = 0; } @@ -772,6 +816,7 @@ RESULT eTSMPEGDecoder::getPTS(int what, pts_t &pts) RESULT eTSMPEGDecoder::setRadioPic(const std::string &filename) { m_radio_pic = filename; + return 0; } RESULT eTSMPEGDecoder::showSinglePic(const char *filename) @@ -845,3 +890,15 @@ RESULT eTSMPEGDecoder::showSinglePic(const char *filename) } return 0; } + +RESULT eTSMPEGDecoder::connectVideoEvent(const Slot1 &event, ePtr &conn) +{ + conn = new eConnection(this, m_video_event.connect(event)); + return 0; +} + +void eTSMPEGDecoder::video_event(struct videoEvent event) +{ + /* emit */ m_video_event(event); +} + diff --git a/lib/dvb/decoder.h b/lib/dvb/decoder.h index 8e8f65ad..c864c095 100644 --- a/lib/dvb/decoder.h +++ b/lib/dvb/decoder.h @@ -4,6 +4,8 @@ #include #include +class eSocketNotifier; + class eDVBAudio: public iObject { DECLARE_REF(eDVBAudio); @@ -28,7 +30,7 @@ public: virtual ~eDVBAudio(); }; -class eDVBVideo: public iObject +class eDVBVideo: public iObject, public Object { DECLARE_REF(eDVBVideo); private: @@ -36,6 +38,9 @@ private: int m_fd, m_fd_demux, m_dev; int m_is_slow_motion, m_is_fast_forward; + eSocketNotifier *m_sn; + void video_event(int what); + Signal1 m_event; public: enum { MPEG2, MPEG4_H264 }; eDVBVideo(eDVBDemux *demux, int dev); @@ -52,6 +57,7 @@ public: void unfreeze(); int getPTS(pts_t &now); virtual ~eDVBVideo(); + RESULT connectEvent(const Slot1 &event, ePtr &conn); }; class eDVBPCR: public iObject @@ -104,9 +110,12 @@ private: int m_changed, m_decoder; int m_is_ff, m_is_sm, m_is_trickmode; int setState(); - ePtr m_demux_event; + ePtr m_demux_event_conn; + ePtr m_video_event_conn; void demux_event(int event); + void video_event(struct videoEvent); + Signal1 m_video_event; public: enum { pidNone = -1 }; eTSMPEGDecoder(eDVBDemux *demux, int decoder); @@ -136,6 +145,7 @@ public: RESULT setRadioPic(const std::string &filename); /* what 0=auto, 1=video, 2=audio. */ RESULT getPTS(int what, pts_t &pts); + RESULT connectVideoEvent(const Slot1 &event, ePtr &connection); }; #endif diff --git a/lib/dvb/idvb.h b/lib/dvb/idvb.h index 997b2a88..7ee50e8d 100644 --- a/lib/dvb/idvb.h +++ b/lib/dvb/idvb.h @@ -8,6 +8,7 @@ #define FRONTENDPARAMETERS FrontendParameters #else #include +#include #define FRONTENDPARAMETERS struct dvb_frontend_parameters #endif #include @@ -646,6 +647,16 @@ public: virtual RESULT showSinglePic(const char *filename) = 0; virtual RESULT setRadioPic(const std::string &filename) = 0; + + struct videoEvent + { + enum { eventUnknown = 0, eventSizeChanged = VIDEO_EVENT_SIZE_CHANGED } type; + unsigned char aspect; + unsigned short height; + unsigned short width; + }; + + virtual RESULT connectVideoEvent(const Slot1 &event, ePtr &connection) = 0; }; #endif //SWIG diff --git a/lib/python/Components/Converter/ServiceInfo.py b/lib/python/Components/Converter/ServiceInfo.py index c581ed73..e2d3fc52 100644 --- a/lib/python/Components/Converter/ServiceInfo.py +++ b/lib/python/Components/Converter/ServiceInfo.py @@ -23,7 +23,7 @@ class ServiceInfo(Converter, object): self.HAS_TELETEXT: [iPlayableService.evUpdatedInfo], self.IS_MULTICHANNEL: [iPlayableService.evUpdatedInfo], self.IS_CRYPTED: [iPlayableService.evUpdatedInfo], - self.IS_WIDESCREEN: [iPlayableService.evUpdatedEventInfo], + self.IS_WIDESCREEN: [iPlayableService.evVideoSizeChanged], self.SUBSERVICES_AVAILABLE: [iPlayableService.evUpdatedEventInfo] }[self.type] diff --git a/lib/python/Components/Sources/CurrentService.py b/lib/python/Components/Sources/CurrentService.py index f49f0323..8e582d55 100644 --- a/lib/python/Components/Sources/CurrentService.py +++ b/lib/python/Components/Sources/CurrentService.py @@ -16,7 +16,8 @@ class CurrentService(PerServiceBase, Source): # which is not always provided. iPlayableService.evUpdatedInfo: self.serviceEvent, iPlayableService.evUpdatedEventInfo: self.serviceEvent, - iPlayableService.evCuesheetChanged: self.serviceEvent + iPlayableService.evCuesheetChanged: self.serviceEvent, + iPlayableService.evVideoSizeChanged: self.serviceEvent }, with_event=True) self.navcore = navcore diff --git a/lib/service/iservice.h b/lib/service/iservice.h index 2ada9095..85ac6fd3 100644 --- a/lib/service/iservice.h +++ b/lib/service/iservice.h @@ -301,6 +301,9 @@ public: sTags, /* space seperated list of tags */ sDVBState, /* states as defined in pmt handler (as events there) */ + + sVideoHeight, + sVideoWidth }; enum { resNA = -1, resIsString = -2, resIsPyObject = -3 }; @@ -529,7 +532,9 @@ public: /* only when cueSheet is implemented */ evCuesheetChanged, - evUpdatedRadioText + evUpdatedRadioText, + + evVideoSizeChanged }; #ifndef SWIG virtual RESULT connectEvent(const Slot2 &event, ePtr &connection)=0; diff --git a/lib/service/servicedvb.cpp b/lib/service/servicedvb.cpp index 85961550..24a91966 100644 --- a/lib/service/servicedvb.cpp +++ b/lib/service/servicedvb.cpp @@ -714,6 +714,7 @@ RESULT eServiceFactoryDVB::lookupService(ePtr &service, const eServ eDVBServicePlay::eDVBServicePlay(const eServiceReference &ref, eDVBService *service): m_reference(ref), m_dvb_service(service), m_have_video_pid(0), m_is_paused(0) { + memset(&m_videoEventData, 0, sizeof(struct iTSMPEGDecoder::videoEvent)); m_is_primary = 1; m_is_pvr = !m_reference.path.empty(); @@ -1230,9 +1231,29 @@ int eDVBServicePlay::getInfo(int w) switch (w) { +#if HAVE_DVB_API_VERSION >= 3 + case sVideoHeight: + if (m_videoEventData.type != iTSMPEGDecoder::videoEvent::eventUnknown) + return m_videoEventData.height; + return -1; + case sVideoWidth: + if (m_videoEventData.type != iTSMPEGDecoder::videoEvent::eventUnknown) + return m_videoEventData.width; + return -1; +#else +#warning "FIXMEE implement sVideoHeight, sVideoWidth for old DVB API" +#endif case sAspect: - if (no_program_info) return -1; - if (!program.videoStreams.empty() && program.videoStreams[0].component_tag != -1) +#if HAVE_DVB_API_VERSION >= 3 + if (m_videoEventData.type != iTSMPEGDecoder::videoEvent::eventUnknown) + return m_videoEventData.aspect == VIDEO_FORMAT_4_3 ? 1 : 3; + else +#else +#warning "FIXMEE implement sAspect for old DVB API" +#endif + if (no_program_info) + return -1; + else if (!program.videoStreams.empty() && program.videoStreams[0].component_tag != -1) { ePtr evt; if (!m_event_handler.getEvent(evt, 0)) @@ -1828,7 +1849,11 @@ void eDVBServicePlay::updateDecoder() { h.getDecodeDemux(m_decode_demux); if (m_decode_demux) + { m_decode_demux->getMPEGDecoder(m_decoder, m_is_primary); + if (m_decoder) + m_decoder->connectVideoEvent(slot(*this, &eDVBServicePlay::video_event), m_video_event_connection); + } if (m_cue) m_cue->setDecodingDemux(m_decode_demux, m_decoder); m_teletext_parser = new eDVBTeletextParser(m_decode_demux); @@ -2408,6 +2433,13 @@ void eDVBServicePlay::setPCMDelay(int delay) m_decoder->setPCMDelay(delay); } +void eDVBServicePlay::video_event(struct iTSMPEGDecoder::videoEvent event) +{ + eDebug("!!!!!!!!!! Video Event type %d, aspect %d, %dx%d", event.type, event.aspect, event.width, event.height); + memcpy(&m_videoEventData, &event, sizeof(iTSMPEGDecoder::videoEvent)); + m_event((iPlayableService*)this, evVideoSizeChanged); +} + DEFINE_REF(eDVBServicePlay) eAutoInitPtr init_eServiceFactoryDVB(eAutoInitNumbers::service+1, "eServiceFactoryDVB"); diff --git a/lib/service/servicedvb.h b/lib/service/servicedvb.h index b40341f7..c765e0e3 100644 --- a/lib/service/servicedvb.h +++ b/lib/service/servicedvb.h @@ -267,6 +267,10 @@ private: ePtr m_radiotext_parser; ePtr m_radiotext_updated_connection; void radioTextUpdated(); + + ePtr m_video_event_connection; + void video_event(struct iTSMPEGDecoder::videoEvent); + struct iTSMPEGDecoder::videoEvent m_videoEventData; }; class eStaticServiceDVBBouquetInformation: public iStaticServiceInformation