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(); }
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; }