Merge branch 'bug_672_removed_pvr_device'
authorghost <andreas.monzner@multimedia-labs.de>
Wed, 16 Feb 2011 13:36:53 +0000 (14:36 +0100)
committerghost <andreas.monzner@multimedia-labs.de>
Wed, 16 Feb 2011 13:36:53 +0000 (14:36 +0100)
Conflicts:
lib/dvb/dvb.cpp

1  2 
lib/dvb/decoder.cpp
lib/dvb/dvb.cpp
lib/dvb/idvb.h
lib/dvb/pmt.cpp
lib/dvb/pmt.h

diff --combined lib/dvb/decoder.cpp
index 8ed9f43f5fed4c56788547734b3da485fbe8b45a,45dde8b3de5c4b4eabf059414bf8fa102cb14f1b..df45063ad2dece66d3c22338d0ca7581828d1349
@@@ -203,9 -203,6 +203,9 @@@ int eDVBAudio::startPid(int pid, int ty
        case aLPCM:
                bypass = 6;
                break;
 +      case aDTSHD:
 +              bypass = 0x10;
 +              break;
        }
  
        eDebugNoNewLine("AUDIO_SET_BYPASS(%d) - ", bypass);
@@@ -1302,10 -1299,11 +1302,11 @@@ RESULT eTSMPEGDecoder::showSinglePic(co
                if (f >= 0)
                {
                        struct stat s;
+                       size_t written=0;
                        fstat(f, &s);
                        if (m_video_clip_fd == -1)
-                               m_video_clip_fd = open("/dev/dvb/adapter0/video0", O_WRONLY|O_NONBLOCK);
-                       if (m_video_clip_fd >= 0)
+                               m_video_clip_fd = open("/dev/dvb/adapter0/video0", O_WRONLY);
+                       while (m_video_clip_fd >= 0)
                        {
                                bool seq_end_avail = false;
                                size_t pos=0;
diff --combined lib/dvb/dvb.cpp
index c2ddb4099f35de7d73aa093f4b588a4ee9029b17,399e9f58b2593eaa06c3c2e1d52d8f4e8ab2ffa3..6f9a67fbd092002b4b6818805a6a75eb6c29b2b5
@@@ -98,8 -98,6 +98,8 @@@ eDVBResourceManager::eDVBResourceManage
                m_boxtype = DM500HD;
        else if (!strncmp(tmp, "dm800se\n", rd))
                m_boxtype = DM800SE;
 +      else if (!strncmp(tmp, "dm7020hd\n", rd))
 +              m_boxtype = DM7020HD;
        else {
                eDebug("boxtype detection via /proc/stb/info not possible... use fallback via demux count!\n");
                if (m_demux.size() == 3)
                        m_boxtype = DM8000;
        }
  
 -      eDebug("found %d adapter, %d frontends(%d sim) and %d demux, boxtype %d",
 +      eDebug("found %zd adapter, %zd frontends(%zd sim) and %zd demux, boxtype %d",
                m_adapter.size(), m_frontend.size(), m_simulate_frontend.size(), m_demux.size(), m_boxtype);
  
        eDVBCAService::registerChannelCallback(this);
@@@ -336,7 -334,7 +336,7 @@@ PyObject *eDVBResourceManager::setFront
        }
        if (assigned != m_frontend.size()) {
                char blasel[256];
 -              sprintf(blasel, "eDVBResourceManager::setFrontendSlotInformations .. assigned %d socket informations, but %d registered frontends!",
 +              sprintf(blasel, "eDVBResourceManager::setFrontendSlotInformations .. assigned %zd socket informations, but %d registered frontends!",
                        m_frontend.size(), assigned);
                PyErr_SetString(PyExc_StandardError, blasel);
                return NULL;
@@@ -466,7 -464,7 +466,7 @@@ RESULT eDVBResourceManager::allocateDem
  
        ePtr<eDVBRegisteredDemux> unused;
  
-       if (m_boxtype == DM800 || m_boxtype == DM500HD || m_boxtype == DM800SE) // dm800 / 500hd
+       if (m_boxtype == DM800) // dm800
        {
                cap |= capHoldDecodeReference; // this is checked in eDVBChannel::getDemux
                for (; i != m_demux.end(); ++i, ++n)
                        }
                }
        }
-       else if (m_boxtype == DM8000 || m_boxtype == DM7020HD)
 -      else if (m_boxtype == DM8000 || m_boxtype == DM500HD || m_boxtype == DM800SE)
++      else if (m_boxtype == DM8000 || m_boxtype == DM500HD || m_boxtype == DM800SE || m_boxtype == DM7020HD)
        {
                cap |= capHoldDecodeReference; // this is checked in eDVBChannel::getDemux
                for (; i != m_demux.end(); ++i, ++n)
@@@ -1490,7 -1488,7 +1490,7 @@@ void eDVBChannel::getNextSourceSpan(off
                                size = max;
                        else
                                size = aligned_end - current_offset;
 -                      eDebug("HIT, %lld < %lld < %lld, size: %d", i->first, current_offset, i->second, size);
 +                      eDebug("HIT, %lld < %lld < %lld, size: %zd", i->first, current_offset, i->second, size);
                        return;
                }
                if (current_offset < aligned_start)
                                        len = aligned_end - aligned_start;
  
                                start = aligned_end - len;
 -                              eDebug("skipping to %llx, %d", start, len);
 +                              eDebug("skipping to %llx, %zd", start, len);
                        }
  
 -                      eDebug("result: %llx, %x (%llx %llx)", start, size, aligned_start, aligned_end);
 +                      eDebug("result: %llx, %zx (%llx %llx)", start, size, aligned_start, aligned_end);
                        return;
                }
        }
        {
                start = current_offset;
                size = max;
 -              eDebug("NO CUESHEET. (%08llx, %d)", start, size);
 +              eDebug("NO CUESHEET. (%08llx, %zd)", start, size);
        } else
        {
                start = current_offset;
@@@ -1792,14 -1790,28 +1792,28 @@@ RESULT eDVBChannel::playSource(ePtr<iTs
                /* (this codepath needs to be improved anyway.) */
  #if HAVE_DVB_API_VERSION < 3
                m_pvr_fd_dst = open("/dev/pvr", O_WRONLY);
- #else
-               m_pvr_fd_dst = open("/dev/misc/pvr", O_WRONLY);
- #endif
                if (m_pvr_fd_dst < 0)
                {
-                       eDebug("can't open /dev/misc/pvr - you need to buy the new(!) $$$ box! (%m)"); // or wait for the driver to be improved.
+                       eDebug("can't open /dev/pvr - you need to buy the new(!) $$$ box! (%m)"); // or wait for the driver to be improved.
+                       return -ENODEV;
+               }
+ #else
+               ePtr<eDVBAllocatedDemux> &demux = m_demux ? m_demux : m_decoder_demux;
+               if (demux)
+               {
+                       m_pvr_fd_dst = demux->get().openDVR(O_WRONLY);
+                       if (m_pvr_fd_dst < 0)
+                       {
+                               eDebug("can't open /dev/dvb/adapterX/dvrX - you need to buy the new(!) $$$ box! (%m)"); // or wait for the driver to be improved.
+                               return -ENODEV;
+                       }
+               }
+               else
+               {
+                       eDebug("no demux allocated yet.. so its not possible to open the dvr device!!");
                        return -ENODEV;
                }
+ #endif
        }
  
        m_pvr_thread = new eDVBChannelFilePush();
diff --combined lib/dvb/idvb.h
index e56a2c7bb784afd35190e507dae1c22b383f377c,460b613a30000e1e26a3cd264d8ed9c645e412b6..86936f8dc36900b199f19fa1a690ac2f4b597afb
@@@ -636,6 -636,7 +636,7 @@@ public
        virtual RESULT getSTC(pts_t &pts, int num=0)=0;
        virtual RESULT getCADemuxID(uint8_t &id)=0;
        virtual RESULT flush()=0;
+       virtual int openDVR(int flags)=0;
  };
  
  #if HAVE_DVB_API_VERSION < 3 && !defined(VIDEO_EVENT_SIZE_CHANGED)
@@@ -650,7 -651,7 +651,7 @@@ public
                /** Set Displayed Video PID and type */
        virtual RESULT setVideoPID(int vpid, int type)=0;
  
 -      enum { af_MPEG, af_AC3, af_DTS, af_AAC };
 +      enum { af_MPEG, af_AC3, af_DTS, af_AAC, af_DTSHD };
                /** Set Displayed Audio PID and type */
        virtual RESULT setAudioPID(int apid, int type)=0;
  
diff --combined lib/dvb/pmt.cpp
index 4ad4e76f0a962e51a1c5b4b296756d430f46e7e6,dc2a88562fe0da5a29697cda04ffc3f72bf3870a..e5e633160c82458480b0e10d3b5f718359a43ad1
  #include <dvbsi++/registration_descriptor.h>
  
  eDVBServicePMTHandler::eDVBServicePMTHandler()
 -      :m_ca_servicePtr(0), m_dvb_scan(0), m_decode_demux_num(0xFF)
 +      :m_ca_servicePtr(0), m_dvb_scan(0), m_decode_demux_num(0xFF), m_no_pat_entry_delay(eTimer::create())
  {
        m_use_decode_demux = 0;
        m_pmt_pid = -1;
        eDVBResourceManager::getInstance(m_resourceManager);
        CONNECT(m_PMT.tableReady, eDVBServicePMTHandler::PMTready);
        CONNECT(m_PAT.tableReady, eDVBServicePMTHandler::PATready);
 +      CONNECT(m_no_pat_entry_delay->timeout, eDVBServicePMTHandler::sendEventNoPatEntry);
  }
  
  eDVBServicePMTHandler::~eDVBServicePMTHandler()
@@@ -44,8 -43,15 +44,15 @@@ void eDVBServicePMTHandler::channelStat
                && (state == iDVBChannel::state_ok) && (!m_demux))
        {
                if (m_channel)
-                       if (m_channel->getDemux(m_demux, (!m_use_decode_demux) ? 0 : iDVBChannel::capDecode))
+               {
+                       if (m_pvr_demux_tmp)
+                       {
+                               m_demux = m_pvr_demux_tmp;
+                               m_pvr_demux_tmp = NULL;
+                       }
+                       else if (m_channel->getDemux(m_demux, (!m_use_decode_demux) ? 0 : iDVBChannel::capDecode))
                                eDebug("Allocating %s-decoding a demux for now tuned-in channel failed.", m_use_decode_demux ? "" : "non-");
+               }
                
                serviceEvent(eventTuned);
                
@@@ -127,55 -133,25 +134,55 @@@ void eDVBServicePMTHandler::PMTready(in
        }
  }
  
 +void eDVBServicePMTHandler::sendEventNoPatEntry()
 +{
 +      serviceEvent(eventNoPATEntry);
 +}
 +
  void eDVBServicePMTHandler::PATready(int)
  {
 +      eDebug("PATready");
        ePtr<eTable<ProgramAssociationSection> > ptr;
        if (!m_PAT.getCurrent(ptr))
        {
 +              int service_id_single = -1;
 +              int pmtpid_single = -1;
                int pmtpid = -1;
 +              int cnt=0;
                std::vector<ProgramAssociationSection*>::const_iterator i;
                for (i = ptr->getSections().begin(); pmtpid == -1 && i != ptr->getSections().end(); ++i)
                {
                        const ProgramAssociationSection &pat = **i;
                        ProgramAssociationConstIterator program;
                        for (program = pat.getPrograms()->begin(); pmtpid == -1 && program != pat.getPrograms()->end(); ++program)
 +                      {
 +                              ++cnt;
                                if (eServiceID((*program)->getProgramNumber()) == m_reference.getServiceID())
                                        pmtpid = (*program)->getProgramMapPid();
 +                              if (++cnt == 1 && pmtpid_single == -1 && pmtpid == -1)
 +                              {
 +                                      pmtpid_single = (*program)->getProgramMapPid();
 +                                      service_id_single = (*program)->getProgramNumber();
 +                              }
 +                              else
 +                                      pmtpid_single = service_id_single = -1;
 +                      }
                }
 -              if (pmtpid == -1)
 -                      serviceEvent(eventNoPATEntry);
 -              else
 +              if (pmtpid_single != -1) // only one PAT entry .. and not valid pmtpid found
 +              {
 +                      eDebug("use single pat entry!");
 +                      m_reference.setServiceID(eServiceID(service_id_single));
 +                      pmtpid = pmtpid_single;
 +              }
 +              if (pmtpid == -1) {
 +                      eDebug("no PAT entry found.. start delay");
 +                      m_no_pat_entry_delay->start(1000, true);
 +              }
 +              else {
 +                      eDebug("use pmtpid %04x for service_id %04x", pmtpid, m_reference.getServiceID().get());
 +                      m_no_pat_entry_delay->stop();
                        m_PMT.begin(eApp, eDVBPMTSpec(pmtpid, m_reference.getServiceID().get()), m_demux);
 +              }
        } else
                serviceEvent(eventNoPAT);
  }
@@@ -261,29 -237,8 +268,29 @@@ int eDVBServicePMTHandler::getProgramIn
                        for (i = ptr->getSections().begin(); i != ptr->getSections().end(); ++i)
                        {
                                const ProgramMapSection &pmt = **i;
 +                              int is_hdmv = 0;
 +
                                program.pcrPid = pmt.getPcrPid();
  
 +                              for (DescriptorConstIterator desc = pmt.getDescriptors()->begin();
 +                                      desc != pmt.getDescriptors()->end(); ++desc)
 +                              {
 +                                      if ((*desc)->getTag() == CA_DESCRIPTOR)
 +                                      {
 +                                              CaDescriptor *descr = (CaDescriptor*)(*desc);
 +                                              program::capid_pair pair;
 +                                              pair.caid = descr->getCaSystemId();
 +                                              pair.capid = descr->getCaPid();
 +                                              program.caids.push_back(pair);
 +                                      }
 +                                      else if ((*desc)->getTag() == REGISTRATION_DESCRIPTOR)
 +                                      {
 +                                              RegistrationDescriptor *d = (RegistrationDescriptor*)(*desc);
 +                                              if (d->getFormatIdentifier() == 0x48444d56) // HDMV
 +                                                      is_hdmv = 1;
 +                                      }
 +                              }
 +
                                ElementaryStreamInfoConstIterator es;
                                for (es = pmt.getEsInfo()->begin(); es != pmt.getEsInfo()->end(); ++es)
                                {
                                                        audio.type = audioStream::atAACHE;
                                                        forced_audio = 1;
                                                }
 -                                      case 0x80: // user private ... but blueray LPCM
 -                                              if (!isvideo && !isaudio)
 +                                      case 0x80: // user private ... but bluray LPCM
 +                                      case 0xA0: // bluray secondary LPCM
 +                                              if (!isvideo && !isaudio && is_hdmv)
                                                {
                                                        isaudio = 1;
                                                        audio.type = audioStream::atLPCM;
                                                }
 -                                      case 0x81: // user private ... but blueray AC3
 -                                              if (!isvideo && !isaudio)
 +                                      case 0x81: // user private ... but bluray AC3
 +                                      case 0xA1: // bluray secondary AC3
 +                                              if (!isvideo && !isaudio && is_hdmv)
                                                {
                                                        isaudio = 1;
                                                        audio.type = audioStream::atAC3;
                                                }
 -                                      case 0x82: // Blueray DTS (dvb user private...)
 -                                      case 0xA2: // Blueray secondary DTS
 -                                              if (!isvideo && !isaudio)
 +                                      case 0x82: // bluray DTS (dvb user private...)
 +                                      case 0xA2: // bluray secondary DTS
 +                                              if (!isvideo && !isaudio && is_hdmv)
                                                {
                                                        isaudio = 1;
                                                        audio.type = audioStream::atDTS;
                                                }
 +                                      case 0x86: // bluray DTS-HD (dvb user private...)
 +                                      case 0xA6: // bluray secondary DTS-HD
 +                                              if (!isvideo && !isaudio && is_hdmv)
 +                                              {
 +                                                      isaudio = 1;
 +                                                      audio.type = audioStream::atDTSHD;
 +                                              }
                                        case 0x06: // PES Private
                                        case 0xEA: // TS_PSI_ST_SMPTE_VC1
                                        {
                                        default:
                                                break;
                                        }
 -                                      if (isteletext && (isaudio || isvideo)) 
 +                                      if (isteletext && (isaudio || isvideo))
                                        {
 -                                              eDebug("ambiguous streamtype for PID %04x detected.. forced as teletext!", (*es)->getPid());                                    
 +                                              eDebug("ambiguous streamtype for PID %04x detected.. forced as teletext!", (*es)->getPid());
                                                continue; // continue with next PID
                                        }
                                        else if (issubtitle && (isaudio || isvideo))
                                        else
                                                continue;
                                }
 -                              for (DescriptorConstIterator desc = pmt.getDescriptors()->begin();
 -                                      desc != pmt.getDescriptors()->end(); ++desc)
 -                              {
 -                                      if ((*desc)->getTag() == CA_DESCRIPTOR)
 -                                      {
 -                                              CaDescriptor *descr = (CaDescriptor*)(*desc);
 -                                              program::capid_pair pair;
 -                                              pair.caid = descr->getCaSystemId();
 -                                              pair.capid = descr->getCaPid();
 -                                              program.caids.push_back(pair);
 -                                      }
 -                              }
                        }
                        ret = 0;
  
@@@ -759,8 -717,8 +766,8 @@@ int eDVBServicePMTHandler::tuneExt(eSer
  {
        RESULT res=0;
        m_reference = ref;
 -      
        m_use_decode_demux = use_decode_demux;
 +      m_no_pat_entry_delay->stop();
  
                /* use given service as backup. This is used for timeshift where we want to clone the live stream using the cache, but in fact have a PVR channel */
        m_service = service;
        {
                if (!ref.getServiceID().get() /* incorrect sid in meta file or recordings.epl*/ )
                {
 -                      eWarning("no .meta file found, trying to find PMT pid");
                        eDVBTSTools tstools;
 +                      bool b = source || !tstools.openFile(ref.path.c_str(), 1);
 +                      eWarning("no .meta file found, trying to find PMT pid");
                        if (source)
 -                              tstools.setSource(source, streaminfo_file ? streaminfo_file : ref.path.c_str());
 -                      else if (tstools.openFile(ref.path.c_str()))
 -                              eWarning("failed to open file");
 -                      else
 +                              tstools.setSource(source, NULL);
 +                      if (b)
                        {
                                int service_id, pmt_pid;
                                if (!tstools.findPMT(pmt_pid, service_id))
                                        m_pmt_pid = pmt_pid;
                                }
                        }
 +                      else
 +                              eWarning("no valid source to find PMT pid!");
                }
                eDebug("alloc PVR");
                        /* allocate PVR */
                if (m_pvr_channel)
                {
                        m_pvr_channel->setCueSheet(cue);
-                       if (source)
+                       if (m_pvr_channel->getDemux(m_pvr_demux_tmp, (!m_use_decode_demux) ? 0 : iDVBChannel::capDecode))
+                               eDebug("Allocating %s-decoding a demux for PVR channel failed.", m_use_decode_demux ? "" : "non-");
+                       else if (source)
                                m_pvr_channel->playSource(source, streaminfo_file);
                        else
                                m_pvr_channel->playFile(ref.path.c_str());
diff --combined lib/dvb/pmt.h
index 1888e05417fcd3e2ba9458d3d5e9b6fe80d176b3,6b20d7146d4daba8e222ee7ab008908e265926e6..0c44f35a7ea682549ed18c4970febaf36943bcf1
@@@ -86,8 -86,8 +86,8 @@@ class eDVBServicePMTHandler: public Obj
        eUsePtr<iDVBChannel> m_channel;
        eUsePtr<iDVBPVRChannel> m_pvr_channel;
        ePtr<eDVBResourceManager> m_resourceManager;
-       ePtr<iDVBDemux> m_demux;
-       
+       ePtr<iDVBDemux> m_demux, m_pvr_demux_tmp;
        void channelStateChanged(iDVBChannel *);
        ePtr<eConnection> m_channelStateChanged_connection;
        void channelEvent(iDVBChannel *, int event);
        
        int m_use_decode_demux;
        uint8_t m_decode_demux_num;
 +      ePtr<eTimer> m_no_pat_entry_delay;
  public:
        eDVBServicePMTHandler();
        ~eDVBServicePMTHandler();
@@@ -145,7 -144,7 +145,7 @@@ public
        {
                int pid,
                    rdsPid; // hack for some radio services which transmit radiotext on different pid (i.e. harmony fm, HIT RADIO FFH, ...)
 -              enum { atMPEG, atAC3, atDTS, atAAC, atAACHE, atLPCM };
 +              enum { atMPEG, atAC3, atDTS, atAAC, atAACHE, atLPCM, atDTSHD };
                int type; // mpeg2, ac3, dts, ...
                
                int component_tag;
        int getPMT(ePtr<eTable<ProgramMapSection> > &ptr) { return m_PMT.getCurrent(ptr); }
        int getChannel(eUsePtr<iDVBChannel> &channel);
        void resetCachedProgram() { m_have_cached_program = false; }
 +      void sendEventNoPatEntry();
  
        /* deprecated interface */
        int tune(eServiceReferenceDVB &ref, int use_decode_demux, eCueSheet *sg=0, bool simulate=false, eDVBService *service = 0);