diff --git a/src/driver/streamts.cpp b/src/driver/streamts.cpp index 786837d20..38531d66b 100644 --- a/src/driver/streamts.cpp +++ b/src/driver/streamts.cpp @@ -70,7 +70,7 @@ #define DMX_BUFFER_SIZE (2048*TS_SIZE) #define IN_SIZE (250*TS_SIZE) -CStreamInstance::CStreamInstance(int clientfd, t_channel_id chid, stream_pids_t &_pids, bool _send_raw) +CStreamInstance::CStreamInstance(int clientfd, t_channel_id chid, stream_pids_t &_pids) { printf("CStreamInstance:: new channel %" PRIx64 " fd %d\n", chid, clientfd); fds.insert(clientfd); @@ -80,7 +80,7 @@ CStreamInstance::CStreamInstance(int clientfd, t_channel_id chid, stream_pids_t dmx = NULL; buf = NULL; frontend = NULL; - send_raw = _send_raw; + is_e2_stream = false; } CStreamInstance::~CStreamInstance() @@ -169,7 +169,7 @@ bool CStreamInstance::Open() if (!tmpchan) return false; - dmx = new cDemux(tmpchan->getRecordDemux());//FIXME + dmx = new cDemux(tmpchan->getStreamDemux());//FIXME if(!dmx) return false; return dmx->Open(DMX_TP_CHANNEL, NULL, DMX_BUFFER_SIZE); @@ -192,7 +192,7 @@ void CStreamInstance::run() dmx->Start(true); - if (!send_raw) + //if (!g_settings.stream_raw && is_e2_stream) CCamManager::getInstance()->Start(channel_id, CCamManager::STREAM); #if HAVE_ARM_HARDWARE || HAVE_MIPS_HARDWARE @@ -209,7 +209,7 @@ void CStreamInstance::run() Send(r); } - if (!send_raw) + //if (!g_settings.stream_raw && is_e2_stream) CCamManager::getInstance()->Stop(channel_id, CCamManager::STREAM); #if HAVE_ARM_HARDWARE || HAVE_MIPS_HARDWARE @@ -304,6 +304,7 @@ CFrontend * CStreamManager::FindFrontend(CZapitChannel * channel) { std::set frontends; CFrontend * frontend = NULL; + CFEManager::getInstance()->Open(); t_channel_id chid = channel->getChannelID(); if (CRecordManager::getInstance()->RecordingStatus(chid)) { @@ -311,8 +312,13 @@ CFrontend * CStreamManager::FindFrontend(CZapitChannel * channel) return frontend; } - t_channel_id live_channel_id = CZapit::getInstance()->GetCurrentChannelID(); - CFrontend *live_fe = CZapit::getInstance()->GetLiveFrontend(); + t_channel_id live_channel_id = 0; + CFrontend *live_fe = NULL; + + if (CNeutrinoApp::getInstance()->getMode() != NeutrinoModes::mode_standby) { + live_channel_id = CZapit::getInstance()->GetCurrentChannelID(); + live_fe = CZapit::getInstance()->GetLiveFrontend(); + } if (live_channel_id == chid) return live_fe; @@ -322,7 +328,8 @@ CFrontend * CStreamManager::FindFrontend(CZapitChannel * channel) bool unlock = false; if (!IS_WEBCHAN(live_channel_id)) { unlock = true; - CFEManager::getInstance()->lockFrontend(live_fe); + if (live_fe) + CFEManager::getInstance()->lockFrontend(live_fe); } OpenThreads::ScopedLock m_lock(mutex); @@ -336,14 +343,15 @@ CFrontend * CStreamManager::FindFrontend(CZapitChannel * channel) if (unlock && frontend == NULL) { unlock = false; - CFEManager::getInstance()->unlockFrontend(live_fe); + if (live_fe) + CFEManager::getInstance()->unlockFrontend(live_fe); frontend = CFEManager::getInstance()->allocateFE(channel, true); } CFEManager::getInstance()->Unlock(); if (frontend) { - bool found = (live_fe != frontend) || IS_WEBCHAN(live_channel_id) || SAME_TRANSPONDER(live_channel_id, chid); + bool found = (live_fe != NULL && live_fe != frontend) || IS_WEBCHAN(live_channel_id) || SAME_TRANSPONDER(live_channel_id, chid); bool ret = false; if (found) ret = zapit.zapTo_record(chid) > 0; @@ -354,7 +362,7 @@ CFrontend * CStreamManager::FindFrontend(CZapitChannel * channel) #if ENABLE_PIP /* FIXME until proper demux management */ t_channel_id pip_channel_id = CZapit::getInstance()->GetPipChannelID(); - if ((pip_channel_id == chid) && (channel->getRecordDemux() == channel->getPipDemux())) + if ((pip_channel_id == chid) && (channel->getStreamDemux() == channel->getPipDemux())) zapit.stopPip(); #endif } else { @@ -367,9 +375,9 @@ CFrontend * CStreamManager::FindFrontend(CZapitChannel * channel) CFEManager::getInstance()->unlockFrontend(*ft); #if HAVE_ARM_HARDWARE || HAVE_MIPS_HARDWARE - if (unlock && !frontend) + if (unlock && !frontend && live_fe) #else - if (unlock) + if (unlock && live_fe) #endif CFEManager::getInstance()->unlockFrontend(live_fe); @@ -377,7 +385,7 @@ CFrontend * CStreamManager::FindFrontend(CZapitChannel * channel) return frontend; } -bool CStreamManager::Parse(int fd, stream_pids_t &pids, t_channel_id &chid, CFrontend * &frontend, bool &send_raw) +bool CStreamManager::Parse(int fd, stream_pids_t &pids, t_channel_id &chid, CFrontend * &frontend, bool &is_e2) { char cbuf[512]; char *bp; @@ -418,49 +426,51 @@ bool CStreamManager::Parse(int fd, stream_pids_t &pids, t_channel_id &chid, CFro return false; } - chid = CZapit::getInstance()->GetCurrentChannelID(); - CZapitChannel * channel = CZapit::getInstance()->GetCurrentChannel(); + CFrontend *live_fe = NULL; + CZapitChannel * channel = NULL; + + if (CNeutrinoApp::getInstance()->getMode() != NeutrinoModes::mode_standby) { + chid = CZapit::getInstance()->GetCurrentChannelID(); + channel = CZapit::getInstance()->GetCurrentChannel(); + } t_channel_id tmpid = 0; + CZapitChannel *tmp_channel = NULL; bp = &cbuf[5]; - if (sscanf(bp, "id=%" SCNx64, &tmpid) == 1) { - channel = CServiceManager::getInstance()->FindChannel(tmpid); - chid = tmpid; - } - int tmpraw = 0; - bp = &cbuf[25]; - - if (sscanf(bp, "raw=%d", &tmpraw) == 1) + if (strstr(bp,"id=")) { - send_raw = (tmpraw > 0); + if (sscanf(bp, "id=%" SCNx64, &tmpid) == 1) { + tmp_channel = CServiceManager::getInstance()->FindChannel(tmpid); + if (tmp_channel) + { + printf("CStreamManager::Parse:N: channel_id %" PRIx64 " [%s] \n", tmp_channel->getChannelID(), tmp_channel->getName().c_str()); + channel = tmp_channel; + chid = tmp_channel->getChannelID(); + } + } } - - if (!tmpid) + else { - bp = &cbuf[5]; u_int service; u_int i1, i2, i3, i4, satpos; if (sscanf(bp, "%X:0:%X:%X:%X:%X:%X:0:0:0:", &service, &i1, &i2, &i3, &i4, &satpos) == 6) { - t_channel_id tmpchid = (((t_channel_id)i3) << 32) | (((t_channel_id)i4) << 16) | (t_channel_id)i2; - CZapitChannel *tmp_channel = CServiceManager::getInstance()->FindChannel48(tmpchid); - + tmpid = (((t_channel_id)i3) << 32) | (((t_channel_id)i4) << 16) | (t_channel_id)i2; + tmp_channel = CServiceManager::getInstance()->FindChannel48(tmpid); if (tmp_channel) { - printf("e2 -> n chid:%" SCNx64 "\n", tmp_channel->getChannelID()); + printf("CStreamManager::Parse:E: channel_id %" PRIx64 " [%s] \n", tmp_channel->getChannelID(), tmp_channel->getName().c_str()); channel = tmp_channel; chid = tmp_channel->getChannelID(); - send_raw = true; + is_e2 = true; } } } if (!channel) return false; - printf("CStreamManager::Parse: channel_id %" PRIx64 " [%s] send %s\n", chid, channel->getName().c_str(), send_raw ? "raw" : "decrypted"); - streammap_iterator_t it = streams.find(chid); if (it != streams.end()) { @@ -477,53 +487,54 @@ bool CStreamManager::Parse(int fd, stream_pids_t &pids, t_channel_id &chid, CFro return false; } - AddPids(fd, channel, pids, send_raw); + PreparePids(channel, pids); return !pids.empty(); } -void CStreamManager::AddPids(int fd, CZapitChannel *channel, stream_pids_t &pids, bool send_raw) +void CStreamManager::PreparePids(CZapitChannel *channel, stream_pids_t &pids) { - // avoid compiler warning - (void) fd; + pids.clear(); - if (pids.empty()) { - printf("CStreamManager::AddPids: searching channel %" PRIx64 " pids\n", channel->getChannelID()); - if (channel->getVideoPid()) - { - pids.insert(channel->getVideoPid()); - printf("CStreamManager::AddPids: vpid 0x%04x \n", channel->getVideoPid()); - } - for (int i = 0; i < channel->getAudioChannelCount(); i++) - { - pids.insert(channel->getAudioChannel(i)->pid); - printf("CStreamManager::AddPids: apid 0x%04x \n", channel->getAudioChannel(i)->pid); - } - if (!channel->capids.empty() && send_raw) - { - for(casys_pids_iterator_t it = channel->capids.begin(); it != channel->capids.end(); ++it) - { - pids.insert((*it)); //all ECM Pids - printf("CStreamManager::AddPids: capid 0x%04x \n", (*it)); - } - } - pids.insert(0); //PAT - printf("CStreamManager::AddPids: PATpid 0x%04x \n", 0); - pids.insert(channel->getPmtPid()); //PMT - printf("CStreamManager::AddPids: PMTpid 0x%04x \n", channel->getPmtPid()); - pids.insert(0x14); //TDT - printf("CStreamManager::AddPids: TDTpid 0x%04x \n", 0x14); + pids.insert(0); //PAT + printf("CStreamManager::PreparePids: PATpid 0x%04x \n", 0); + pids.insert(channel->getPmtPid()); //PMT + printf("CStreamManager::PreparePids: PMTpid 0x%04x \n", channel->getPmtPid()); + pids.insert(0x14); //TDT + printf("CStreamManager::PreparePids: TDTpid 0x%04x \n", 0x14); + + printf("CStreamManager::PreparePids: searching channel %" PRIx64 " pids\n", channel->getChannelID()); + if (channel->getVideoPid()) + { + pids.insert(channel->getVideoPid()); + printf("CStreamManager::PreparePids: vpid 0x%04x \n", channel->getVideoPid()); } + for (int i = 0; i < channel->getAudioChannelCount(); i++) + { + pids.insert(channel->getAudioChannel(i)->pid); + printf("CStreamManager::PreparePids: apid 0x%04x \n", channel->getAudioChannel(i)->pid); + } + +#if 0 + if (!channel->capids.empty() && g_settings.stream_raw && is_e2_stream) + { + for(casys_pids_iterator_t it = channel->capids.begin(); it != channel->capids.end(); ++it) + { + pids.insert((*it)); //all ECM Pids + printf("CStreamManager::PreparePids: capid 0x%04x \n", (*it)); + } + } +#endif //add pcr pid if (channel->getPcrPid() && (channel->getPcrPid() != channel->getVideoPid())) { pids.insert(channel->getPcrPid()); - printf("CStreamManager::AddPids: PCRpid 0x%04x \n", channel->getPcrPid()); + printf("CStreamManager::PreparePids: PCRpid 0x%04x \n", channel->getPcrPid()); } //add teletext pid if (channel->getTeletextPid() != 0) { pids.insert(channel->getTeletextPid()); - printf("CStreamManager::AddPids: Teletext pid 0x%04x \n", channel->getTeletextPid()); + printf("CStreamManager::PreparePids: Teletext pid 0x%04x \n", channel->getTeletextPid()); } //add dvb sub pid if ((int)channel->getSubtitleCount() > 0) { @@ -532,7 +543,7 @@ void CStreamManager::AddPids(int fd, CZapitChannel *channel, stream_pids_t &pids if (s->thisSubType == CZapitAbsSub::DVB) { CZapitDVBSub* sd = reinterpret_cast(s); pids.insert(sd->pId); - printf("CStreamManager::AddPids: Subtitle pid 0x%04x \n", sd->pId); + printf("CStreamManager::PreparePids: Subtitle pid 0x%04x \n", sd->pId); } } } @@ -542,13 +553,13 @@ void CStreamManager::AddPids(int fd, CZapitChannel *channel, stream_pids_t &pids bool CStreamManager::AddClient(int connfd) { stream_pids_t pids; - t_channel_id channel_id; - CFrontend *frontend; - bool send_raw; - - pids.clear(); // to catch and stream all pids later ! + pids.clear(); - if (Parse(connfd, pids, channel_id, frontend, send_raw)) { + t_channel_id channel_id = 0; + CFrontend *frontend = NULL; + bool is_e2 = false; + + if (Parse(connfd, pids, channel_id, frontend, is_e2)) { OpenThreads::ScopedLock m_lock(mutex); streammap_iterator_t it = streams.find(channel_id); if (it != streams.end()) { @@ -558,8 +569,9 @@ bool CStreamManager::AddClient(int connfd) if (IS_WEBCHAN(channel_id)) { stream = new CStreamStream(connfd, channel_id, pids); } else { - stream = new CStreamInstance(connfd, channel_id, pids, send_raw); + stream = new CStreamInstance(connfd, channel_id, pids); stream->frontend = frontend; + stream->is_e2_stream = is_e2; } int sendsize = 10*IN_SIZE; @@ -637,13 +649,12 @@ void CStreamManager::run() continue; } + g_RCInput->postMsg(NeutrinoMessages::EVT_STREAM_START, 0); if (!AddClient(connfd)) { close(connfd); g_RCInput->postMsg(NeutrinoMessages::EVT_STREAM_STOP, 0); } - else - g_RCInput->postMsg(NeutrinoMessages::EVT_STREAM_START, 0); poll_timeout = 1000; } else { if (pfd[i].revents & (POLLHUP | POLLRDHUP)) { @@ -761,7 +772,7 @@ _error: } CStreamStream::CStreamStream(int clientfd, t_channel_id chid, stream_pids_t &_pids) - : CStreamInstance(clientfd, chid, _pids, false) + : CStreamInstance(clientfd, chid, _pids) { ifcx = NULL; ofcx = NULL; diff --git a/src/driver/streamts.h b/src/driver/streamts.h index b28bae408..4fafd94e6 100644 --- a/src/driver/streamts.h +++ b/src/driver/streamts.h @@ -54,14 +54,13 @@ class CStreamInstance : public OpenThreads::Thread t_channel_id channel_id; stream_pids_t pids; stream_fds_t fds; - bool send_raw; virtual bool Send(ssize_t r, unsigned char * _buf = NULL); virtual void Close(); virtual void run(); friend class CStreamManager; public: - CStreamInstance(int clientfd, t_channel_id chid, stream_pids_t &pids, bool send_raw); + CStreamInstance(int clientfd, t_channel_id chid, stream_pids_t &pids); virtual ~CStreamInstance(); virtual bool Open(); virtual bool Start(); @@ -71,6 +70,7 @@ class CStreamInstance : public OpenThreads::Thread bool HasFd(int fd); stream_fds_t & GetFds() { return fds; } t_channel_id GetChannelId() { return channel_id; } + bool is_e2_stream; }; class CStreamStream : public CStreamInstance @@ -121,8 +121,8 @@ class CStreamManager : public OpenThreads::Thread streammap_t streams; bool Listen(); - bool Parse(int fd, stream_pids_t &pids, t_channel_id &chid, CFrontend * &frontend, bool &send_raw); - void AddPids(int fd, CZapitChannel * channel, stream_pids_t &pids, bool send_raw); + bool Parse(int fd, stream_pids_t &pids, t_channel_id &chid, CFrontend * &frontend, bool &is_e2); + void PreparePids(CZapitChannel * channel, stream_pids_t &pids); void CheckStandby(bool enter); CFrontend * FindFrontend(CZapitChannel * channel); bool StopAll(); diff --git a/src/zapit/include/zapit/channel.h b/src/zapit/include/zapit/channel.h index 7a8a4d379..7ca5f28fa 100644 --- a/src/zapit/include/zapit/channel.h +++ b/src/zapit/include/zapit/channel.h @@ -184,6 +184,7 @@ class CZapitChannel uint8_t record_demux; uint8_t pip_demux; + uint8_t stream_demux; void Init(); friend class CChannelList; @@ -303,8 +304,10 @@ class CZapitChannel void dumpBouquetXml(FILE * fd, bool bUser); void setRecordDemux(uint8_t num) { record_demux = num; }; void setPipDemux(uint8_t num) { pip_demux = num; }; + void setStreamDemux(uint8_t num) { stream_demux = num; }; int getRecordDemux() { return record_demux; }; int getPipDemux() { return pip_demux; }; + int getStreamDemux() { return stream_demux; }; static t_channel_id makeChannelId(t_satellite_position sat, freq_id_t freq, t_transport_stream_id tsid, t_original_network_id onid, t_service_id sid) { diff --git a/src/zapit/src/capmt.cpp b/src/zapit/src/capmt.cpp index 3ba3e776b..1a813a66b 100644 --- a/src/zapit/src/capmt.cpp +++ b/src/zapit/src/capmt.cpp @@ -257,9 +257,25 @@ bool CCamManager::SetMode(t_channel_id channel_id, enum runmode mode, bool start INFO("PLAY: fe_num %d dmx_src %d", source, demux); break; case STREAM: +#if HAVE_ARM_HARDWARE || HAVE_MIPS_HARDWARE +// INFO("STREAM(%d): fe_num %d stream_dmx %d", mode, frontend ? frontend->getNumber() : -1, channel->getStreamDemux()); +#ifdef DYNAMIC_DEMUX + source = channel->getStreamDemux(); + demux = channel->getStreamDemux(); +#else + if(frontend) + source = frontend->getNumber(); + demux = source; +#endif // DYNAMIC_DEMUX +#else + source = channel->getStreamDemux(); + demux = channel->getStreamDemux(); +#endif + INFO("STREAM(%d): fe_num %d stream_dmx %d", mode, source, demux); + break; case RECORD: #if HAVE_ARM_HARDWARE || HAVE_MIPS_HARDWARE -// INFO("RECORD/STREAM(%d): fe_num %d rec_dmx %d", mode, frontend ? frontend->getNumber() : -1, channel->getRecordDemux()); +// INFO("RECORD(%d): fe_num %d rec_dmx %d", mode, frontend ? frontend->getNumber() : -1, channel->getRecordDemux()); #ifdef DYNAMIC_DEMUX source = channel->getRecordDemux(); demux = channel->getRecordDemux(); @@ -272,7 +288,7 @@ bool CCamManager::SetMode(t_channel_id channel_id, enum runmode mode, bool start source = channel->getRecordDemux(); demux = channel->getRecordDemux(); #endif - INFO("RECORD/STREAM(%d): fe_num %d rec_dmx %d", mode, source, demux); + INFO("RECORD(%d): fe_num %d rec_dmx %d", mode, source, demux); break; case PIP: #if HAVE_ARM_HARDWARE || HAVE_MIPS_HARDWARE diff --git a/src/zapit/src/channel.cpp b/src/zapit/src/channel.cpp index 062ef4ccc..69b0c4960 100644 --- a/src/zapit/src/channel.cpp +++ b/src/zapit/src/channel.cpp @@ -106,6 +106,7 @@ void CZapitChannel::Init() has_bouquet = false; record_demux = 2; pip_demux = 2; + stream_demux = 2; polarization = 0; flags = 0; delsys = DVB_S; diff --git a/src/zapit/src/femanager.cpp b/src/zapit/src/femanager.cpp index c04c2109d..abf30355c 100644 --- a/src/zapit/src/femanager.cpp +++ b/src/zapit/src/femanager.cpp @@ -695,6 +695,8 @@ CFrontend * CFEManager::allocateFE(CZapitChannel * channel, bool forrecord) channel->setRecordDemux(dnum); INFO("pip dyn demux: %d", dnum); channel->setPipDemux(dnum); + INFO("pip stream demux: %d", dnum); + channel->setStreamDemux(dnum); if (forrecord && !dnum) { frontend = NULL; } else { @@ -703,6 +705,7 @@ CFrontend * CFEManager::allocateFE(CZapitChannel * channel, bool forrecord) #else channel->setRecordDemux(frontend->fenumber+1); channel->setPipDemux(frontend->fenumber+1); + channel->setStreamDemux(frontend->fenumber+1); #if HAVE_CST_HARDWARE /* I don't know if this check is necessary on cs, but it hurts on other hardware */ if(femap.size() > 1)