int CEpgScan::handleMsg(const neutrino_msg_t msg, neutrino_msg_data_t data) { if (!g_settings.epg_scan || (!standby && (CFEManager::getInstance()->getEnabledCount() <= 1))) { if ((msg == NeutrinoMessages::EVT_EIT_COMPLETE) || (msg == NeutrinoMessages::EVT_BACK_ZAP_COMPLETE)) return messages_return::handled; return messages_return::unhandled; } CZapitChannel * newchan; if(msg == NeutrinoMessages::EVT_ZAP_COMPLETE) { AddTransponders(); INFO("EVT_ZAP_COMPLETE, scan map size: %d\n", scanmap.size()); return messages_return::handled; } else if (msg == NeutrinoMessages::EVT_EIT_COMPLETE) { t_channel_id chid = *(t_channel_id *)data; newchan = CServiceManager::getInstance()->FindChannel(chid); if (newchan) { scanned.insert(newchan->getTransponderId()); scanmap.erase(newchan->getTransponderId()); } INFO("EIT read complete [" PRINTF_CHANNEL_ID_TYPE "], scan map size: %d", chid, scanmap.size()); Next(); return messages_return::handled; } else if (msg == NeutrinoMessages::EVT_BACK_ZAP_COMPLETE) { t_channel_id chid = *(t_channel_id *)data; INFO("EVT_BACK_ZAP_COMPLETE [" PRINTF_CHANNEL_ID_TYPE "]", chid); if (next_chid) { newchan = CServiceManager::getInstance()->FindChannel(next_chid); if (newchan) { if(chid) { if (!CRecordManager::getInstance()->RecordingStatus()) { INFO("try to scan [%s]", newchan->getName().c_str()); if (standby && !g_Sectionsd->getIsScanningActive()) g_Sectionsd->setPauseScanning(false); g_Sectionsd->setServiceChanged(newchan->getChannelID(), false, newchan->getRecordDemux()); } } else { INFO("tune failed [%s]", newchan->getName().c_str()); scanmap.erase(newchan->getTransponderId()); Next(); } } } return messages_return::handled; } return messages_return::unhandled; }
void CStreamInstance::run() { printf("CStreamInstance::run: %llx\n", channel_id); #if 0 dmx = new cDemux(STREAM_DEMUX);//FIXME #endif CZapitChannel * tmpchan = CServiceManager::getInstance()->FindChannel(channel_id); if (!tmpchan) return; dmx = new cDemux(tmpchan->getRecordDemux());//FIXME dmx->Open(DMX_TP_CHANNEL, NULL, DMX_BUFFER_SIZE); /* pids here cannot be empty */ stream_pids_t::iterator it = pids.begin(); printf("CStreamInstance::run: add pid %x\n", *it); dmx->pesFilter(*it); ++it; for (; it != pids.end(); ++it) { printf("CStreamInstance::run: add pid %x\n", *it); dmx->addPid(*it); } #ifdef ENABLE_MULTI_CHANNEL dmx->Start();//FIXME #else dmx->Start(true);//FIXME #endif CCamManager::getInstance()->Start(channel_id, CCamManager::STREAM); while (running) { ssize_t r = dmx->Read(buf, IN_SIZE, 100); if(r > 0) Send(r); } CCamManager::getInstance()->Stop(channel_id, CCamManager::STREAM); printf("CStreamInstance::run: exiting %llx (%d fds)\n", channel_id, fds.size()); Close(); delete dmx; delete []buf; }
bool CStreamManager::Parse(int fd, stream_pids_t &pids, t_channel_id &chid) { char cbuf[512]; char *bp; FILE * fp = fdopen(fd, "r+"); if(fp == NULL) { perror("fdopen"); return false; } cbuf[0] = 0; bp = &cbuf[0]; /* read one line */ while (bp - &cbuf[0] < (int) sizeof(cbuf)) { unsigned char c; int res = read(fd, &c, 1); if(res < 0) { perror("read"); return false; } if ((*bp++ = c) == '\n') break; } *bp++ = 0; bp = &cbuf[0]; printf("CStreamManager::Parse: got %s\n", cbuf); /* send response to http client */ if (!strncmp(cbuf, "GET /", 5)) { fprintf(fp, "HTTP/1.1 200 OK\r\nServer: streamts (%s)\r\n\r\n", "ts" /*&argv[1][1]*/); fflush(fp); bp += 5; } else { printf("Received garbage\n"); return false; } #ifndef ENABLE_MULTI_CHANNEL /* parse stdin / url path, start dmx filters */ do { int pid; int res = sscanf(bp, "%x", &pid); if(res == 1) { printf("New pid: 0x%x\n", pid); pids.insert(pid); } } while ((bp = strchr(bp, ',')) && (bp++)); #endif chid = CZapit::getInstance()->GetCurrentChannelID(); CZapitChannel * channel = CZapit::getInstance()->GetCurrentChannel(); int mode = CNeutrinoApp::getInstance()->getMode(); if (mode == NeutrinoMessages::mode_standby && streams.empty()) { printf("CStreamManager::Parse: wakeup zapit..\n"); cpuFreq->SetCpuFreq(g_settings.cpufreq * 1000 * 1000); g_Zapit->setStandby(false); g_Zapit->getMode(); } if(pids.empty()) { #ifdef ENABLE_MULTI_CHANNEL t_channel_id tmpid; bp = &cbuf[5]; if (sscanf(bp, "id=%llx", &tmpid) == 1) { printf("############################# channel_id %llx\n", tmpid); CZapitChannel * tmpchan = CServiceManager::getInstance()->FindChannel(tmpid); if (tmpchan && (tmpid != chid) && SAME_TRANSPONDER(tmpid, chid)) { printf("############################# channel_id %llx -> zap\n", tmpid); bool ret = g_Zapit->zapTo_record(tmpid) > 0; if (ret) { channel = tmpchan; chid = tmpid; } } } if(CRecordManager::getInstance()->RecordingStatus(chid)) { printf("CStreamManager::Parse: channel %llx recorded, aborting..\n", chid); return false; } #ifdef ENABLE_PIP t_channel_id pip_channel_id = CZapit::getInstance()->GetPipChannelID(); if ((chid == pip_channel_id) && (channel->getRecordDemux() == channel->getPipDemux())) { printf("CStreamManager::Parse: channel %llx used for pip, aborting..\n", chid); return false; } #endif #endif printf("CStreamManager::Parse: no pids in url, using channel %llx pids\n", chid); if(!channel) return false; //pids.insert(0); //pids.insert(channel->getPmtPid()); pids.insert(channel->getVideoPid()); for (int i = 0; i < channel->getAudioChannelCount(); i++) pids.insert(channel->getAudioChannel(i)->pid); } CGenPsi psi; for (stream_pids_t::iterator it = pids.begin(); it != pids.end(); ++it) { if (*it == channel->getVideoPid()) { printf("CStreamManager::Parse: genpsi vpid %x (%d)\n", *it, channel->type); psi.addPid(*it, channel->type ? EN_TYPE_AVC : EN_TYPE_VIDEO, 0); } else { for (int i = 0; i < channel->getAudioChannelCount(); i++) { if (*it == channel->getAudioChannel(i)->pid) { CZapitAudioChannel::ZapitAudioChannelType atype = channel->getAudioChannel(i)->audioChannelType; printf("CStreamManager::Parse: genpsi apid %x (%d)\n", *it, atype); if(channel->getAudioChannel(i)->audioChannelType == CZapitAudioChannel::EAC3){ psi.addPid(*it, EN_TYPE_AUDIO_EAC3, atype, channel->getAudioChannel(i)->description.c_str()); }else{ psi.addPid(*it, EN_TYPE_AUDIO, atype, channel->getAudioChannel(i)->description.c_str()); } } } } } //add pcr pid if(channel->getPcrPid() != channel->getVideoPid()){ pids.insert(channel->getPcrPid()); psi.addPid(channel->getPcrPid(), EN_TYPE_PCR, 0); } //add teletext pid if (g_settings.recording_stream_vtxt_pid && channel->getTeletextPid() != 0){ pids.insert(channel->getTeletextPid()); psi.addPid(channel->getTeletextPid(), EN_TYPE_TELTEX, 0, channel->getTeletextLang()); } //add dvb sub pid if (g_settings.recording_stream_subtitle_pids){ for (int i = 0 ; i < (int)channel->getSubtitleCount() ; ++i) { CZapitAbsSub* s = channel->getChannelSub(i); if (s->thisSubType == CZapitAbsSub::DVB) { if(i>9)//max sub pids break; CZapitDVBSub* sd = reinterpret_cast<CZapitDVBSub*>(s); pids.insert(sd->pId); psi.addPid( sd->pId, EN_TYPE_DVBSUB, 0, sd->ISO639_language_code.c_str() ); } } } psi.genpsi(fd); return !pids.empty(); }
int CEpgScan::handleMsg(const neutrino_msg_t msg, neutrino_msg_data_t data) { if ((msg == NeutrinoMessages::EVT_TIMER) && (data == rescan_timer)) { INFO("rescan timer in %s mode, scanning %d", standby ? "standby" : "live", scan_in_progress); scanned.clear(); Clear(); g_RCInput->killTimer(rescan_timer); if (CheckMode()) { if (standby) CNeutrinoApp::getInstance()->wakeupFromStandby(); Start(standby); } else { AddTimer(); } return messages_return::handled; } if (!CheckMode()) { int ret = messages_return::handled; if (msg == NeutrinoMessages::EVT_EIT_COMPLETE) scan_in_progress = false; else if (msg == NeutrinoMessages::EVT_BACK_ZAP_COMPLETE) scan_in_progress = true; else ret = messages_return::unhandled; return ret; } CZapitChannel * newchan; if (msg == NeutrinoMessages::EVT_ZAP_COMPLETE) { /* live channel changed, block scan channel change by timer */ scan_in_progress = true; AddTransponders(); INFO("EVT_ZAP_COMPLETE, scan map size: %d\n", scanmap.size()); #if 0 t_channel_id chid = *(t_channel_id *)data; if (IS_WEBTV(chid)) Next(); #endif return messages_return::handled; } else if (msg == NeutrinoMessages::EVT_EIT_COMPLETE) { scan_in_progress = false; t_channel_id chid = *(t_channel_id *)data; newchan = CServiceManager::getInstance()->FindChannel(chid); if (newchan) { scanned.insert(newchan->getTransponderId()); scanmap.erase(newchan->getTransponderId()); } INFO("EIT read complete [" PRINTF_CHANNEL_ID_TYPE "], scan map size: %d", chid, scanmap.size()); Next(); return messages_return::handled; } else if (msg == NeutrinoMessages::EVT_BACK_ZAP_COMPLETE) { scan_in_progress = true; t_channel_id chid = *(t_channel_id *)data; INFO("EVT_BACK_ZAP_COMPLETE [" PRINTF_CHANNEL_ID_TYPE "]", chid); if (next_chid) { newchan = CServiceManager::getInstance()->FindChannel(next_chid); if (newchan) { if(chid) { if (!CRecordManager::getInstance()->RecordingStatus()) { INFO("try to scan [%s]", newchan->getName().c_str()); if (standby && !g_Sectionsd->getIsScanningActive()) g_Sectionsd->setPauseScanning(false); g_Sectionsd->setServiceChanged(newchan->getChannelID(), false, newchan->getRecordDemux()); } } else { INFO("tune failed [%s]", newchan->getName().c_str()); scanmap.erase(newchan->getTransponderId()); Next(); } } } return messages_return::handled; } return messages_return::unhandled; }
bool CCamManager::SetMode(t_channel_id channel_id, enum runmode mode, bool start, bool force_update) { CCam * cam; int oldmask, newmask; int demux = DEMUX_SOURCE_0; int source = DEMUX_SOURCE_0; CZapitChannel * channel = CServiceManager::getInstance()->FindChannel(channel_id); if(channel == NULL) { printf("CCamManager: channel %" PRIx64 " not found\n", channel_id); return false; } //INFO("channel %llx [%s] mode %d %s update %d", channel_id, channel->getName().c_str(), mode, start ? "START" : "STOP", force_update); mutex.lock(); cammap_iterator_t it = channel_map.find(channel_id); if(it != channel_map.end()) { cam = it->second; } else if(start) { cam = new CCam(); channel_map.insert(std::pair<t_channel_id, CCam*>(channel_id, cam)); } else { mutex.unlock(); return false; } /* FIXME until proper demux management */ switch(mode) { case PLAY: source = DEMUX_SOURCE_0; demux = LIVE_DEMUX; break; case STREAM: case RECORD: source = channel->getRecordDemux(); demux = channel->getRecordDemux(); break; #if 0 case STREAM: source = DEMUX_SOURCE_0; demux = STREAM_DEMUX; break; #endif case PIP: source = channel->getRecordDemux(); demux = channel->getPipDemux(); break; } oldmask = cam->getCaMask(); if(force_update) newmask = oldmask; else newmask = cam->makeMask(demux, start); if(cam->getSource() > 0) source = cam->getSource(); INFO("channel %" PRIx64 " [%s] mode %d %s src %d mask %d -> %d update %d", channel_id, channel->getName().c_str(), mode, start ? "START" : "STOP", source, oldmask, newmask, force_update); //INFO("source %d old mask %d new mask %d force update %s", source, oldmask, newmask, force_update ? "yes" : "no"); if((oldmask != newmask) || force_update) { cam->setCaMask(newmask); cam->setSource(source); if(newmask == 0) { cam->sendMessage(NULL, 0, false); cam->sendCaPmt(channel->getChannelID(), NULL, 0); } else { cam->makeCaPmt(channel, true); cam->setCaPmt(true); } } if(newmask == 0) { /* FIXME: back to live channel from playback dont parse pmt and call setCaPmt * (see CMD_SB_LOCK / UNLOCK PLAYBACK */ //channel->setRawPmt(NULL);//FIXME channel_map.erase(channel_id); delete cam; } CaIdVector caids; cCA::GetInstance()->GetCAIDS(caids); //uint8_t list = CCam::CAPMT_FIRST; uint8_t list = CCam::CAPMT_ONLY; if (channel_map.size() > 1) list = CCam::CAPMT_ADD; for (it = channel_map.begin(); it != channel_map.end(); /*++it*/) { cam = it->second; channel = CServiceManager::getInstance()->FindChannel(it->first); ++it; if(!channel) continue; #if 0 if (it == channel_map.end()) list |= CCam::CAPMT_LAST; // FIRST->ONLY or MORE->LAST #endif cam->makeCaPmt(channel, false, list, caids); int len; unsigned char * buffer = channel->getRawPmt(len); cam->sendCaPmt(channel->getChannelID(), buffer, len); //list = CCam::CAPMT_MORE; } mutex.unlock(); return true; }