void eSocket::notifier(int what) { if ((what & eSocketNotifier::Read) && (mystate == Connection)) { int bytesavail=256; if (issocket) if (ioctl(getDescriptor(), FIONREAD, &bytesavail)<0) eDebug("FIONREAD failed.\n"); { if (issocket) { if (!bytesavail) // does the REMOTE END has closed the connection? (no Hungup here!) { writebuffer.clear(); close(); return; } } else // when operating on terminals, check for break { serial_icounter_struct icount; memset(&icount, 0, sizeof(icount)); if (!ioctl(getDescriptor(), TIOCGICOUNT, &icount)) { if (last_break == -1) last_break = icount.brk; else if (last_break != icount.brk) { last_break = icount.brk; readbuffer.fromfile(getDescriptor(), bytesavail); readbuffer.clear(); writebuffer.clear(); rsn->setRequested(rsn->getRequested()&~eSocketNotifier::Write); write(getDescriptor(), "BREAK!", 6); hangup(); return; } } else eDebug("TIOCGICOUNT failed(%m)"); } int r; if ((r=readbuffer.fromfile(getDescriptor(), bytesavail)) != bytesavail) if (issocket) eDebug("fromfile failed!"); readyRead_(); } } else if (what & eSocketNotifier::Write) { if ((mystate == Connection) || (mystate == Closing)) { if (!writebuffer.empty()) { bytesWritten_(writebuffer.tofile(getDescriptor(), 65536)); if (writebuffer.empty()) { rsn->setRequested(rsn->getRequested()&~eSocketNotifier::Write); if (mystate == Closing) { close(); // warning, we might get destroyed after close. return; } } } else eDebug("got ready to write, but nothin in buffer. strange."); if (mystate == Closing) close(); } else if (mystate == Connecting) { mystate=Connection; rsn->setRequested(rsn->getRequested()&~eSocketNotifier::Write); int res; socklen_t size=sizeof(res); ::getsockopt(getDescriptor(), SOL_SOCKET, SO_ERROR, &res, &size); if (!res) connected_(); else { close(); error_(res); } } } else if (what & eSocketNotifier::Hungup) { if (mystate == Connection || (mystate == Closing && issocket) ) { writebuffer.clear(); close(); } else if (mystate == Connecting) { int res; socklen_t size=sizeof(res); ::getsockopt(getDescriptor(), SOL_SOCKET, SO_ERROR, &res, &size); close(); error_(res); } } }
RESULT eDVBResourceManager::allocateDemux(eDVBRegisteredFrontend *fe, ePtr<eDVBAllocatedDemux> &demux, int &cap) { /* find first unused demux which is on same adapter as frontend (or any, if PVR) never use the first one unless we need a decoding demux. */ eDebug("allocate demux"); eSmartPtrList<eDVBRegisteredDemux>::iterator i(m_demux.begin()); if (i == m_demux.end()) return -1; ePtr<eDVBRegisteredDemux> unused; if (m_boxtype == DM7025) // ATI { /* FIXME: hardware demux policy */ int n=0; if (!(cap & iDVBChannel::capDecode)) { if (m_demux.size() > 2) /* assumed to be true, otherwise we have lost anyway */ { ++i, ++n; ++i, ++n; } } for (; i != m_demux.end(); ++i, ++n) { int is_decode = n < 2; int in_use = is_decode ? (i->m_demux->getRefCount() != 2) : i->m_inuse; if ((!in_use) && ((!fe) || (i->m_adapter == fe->m_adapter))) { if ((cap & iDVBChannel::capDecode) && !is_decode) continue; unused = i; break; } } } else { iDVBAdapter *adapter = fe ? fe->m_adapter : m_adapter.begin(); /* look for a demux on the same adapter as the frontend, or the first adapter for dvr playback */ int source = fe ? fe->m_frontend->getDVBID() : -1; cap |= capHoldDecodeReference; // this is checked in eDVBChannel::getDemux if (!fe) { /* * For pvr playback, start with the last demux. * On some hardware, we have less ca devices than demuxes, * so we should try to leave the first demuxes for live tv, * and start with the last for pvr playback */ i = m_demux.end(); --i; } while (i != m_demux.end()) { if (i->m_adapter == adapter) { if (!i->m_inuse) { /* mark the first unused demux, we'll use that when we do not find a better match */ if (!unused) unused = i; } else { /* demux is in use, see if we can share it */ if (i->m_demux->getSource() == source) { /* * TODO: when allocating a dvr demux, we cannot share a used demux. * We should probably always pick a free demux, to start a new pvr playback. * Each demux is fed by its own dvr device, so each has a different memory source */ demux = new eDVBAllocatedDemux(i); return 0; } } } if (fe) { ++i; } else { --i; } } } if (unused) { demux = new eDVBAllocatedDemux(unused); if (fe) demux->get().setSourceFrontend(fe->m_frontend->getDVBID()); else demux->get().setSourcePVR(0); return 0; } eDebug("demux not found"); return -1; }
void eDVBResourceManager::releaseCachedChannel() { eDebug("release cached channel (timer timeout)"); m_cached_channel=0; }
int eDVBServiceRecord::doRecord() { int err = doPrepare(); if (err) { m_error = errTuneFailed; m_event((iRecordableService*)this, evRecordFailed); return err; } if (!m_tuned) return 0; /* try it again when we are tuned in */ if (!m_record && m_tuned && !m_streaming && !m_simulate) { eDebug("Recording to %s...", m_filename.c_str()); ::remove(m_filename.c_str()); int fd = ::open(m_filename.c_str(), O_WRONLY | O_CREAT | O_LARGEFILE | O_CLOEXEC, 0666); if (fd == -1) { eDebug("eDVBServiceRecord - can't open recording file!"); m_error = errOpenRecordFile; m_event((iRecordableService*)this, evRecordFailed); return errOpenRecordFile; } ePtr<iDVBDemux> demux; if (m_service_handler.getDataDemux(demux)) { eDebug("eDVBServiceRecord - NO DEMUX available!"); m_error = errNoDemuxAvailable; m_event((iRecordableService*)this, evRecordFailed); return errNoDemuxAvailable; } demux->createTSRecorder(m_record); if (!m_record) { eDebug("eDVBServiceRecord - no ts recorder available."); m_error = errNoTsRecorderAvailable; m_event((iRecordableService*)this, evRecordFailed); return errNoTsRecorderAvailable; } m_record->setTargetFD(fd); m_record->setTargetFilename(m_filename); m_record->connectEvent(slot(*this, &eDVBServiceRecord::recordEvent), m_con_record_event); m_target_fd = fd; } if (m_streaming) { m_state = stateRecording; eDebug("start streaming..."); } else { eDebugNoNewLineStart("start recording..."); eDVBServicePMTHandler::program program; if (m_service_handler.getProgramInfo(program)) eDebug("getting program info failed."); else { std::set<int> pids_to_record; pids_to_record.insert(0); // PAT if (program.pmtPid != -1) pids_to_record.insert(program.pmtPid); // PMT int timing_pid = -1, timing_stream_type = -1; iDVBTSRecorder::timing_pid_type timing_pid_type = iDVBTSRecorder::none; eDebugNoNewLine("RECORD: have %zd video stream(s)", program.videoStreams.size()); if (!program.videoStreams.empty()) { eDebugNoNewLine(" ("); for (std::vector<eDVBServicePMTHandler::videoStream>::const_iterator i(program.videoStreams.begin()); i != program.videoStreams.end(); ++i) { pids_to_record.insert(i->pid); if (timing_pid == -1) { timing_pid = i->pid; timing_stream_type = i->type; timing_pid_type = iDVBTSRecorder::video_pid; } if (i != program.videoStreams.begin()) eDebugNoNewLine(", "); eDebugNoNewLine("%04x", i->pid); } eDebugNoNewLine(")"); } eDebugNoNewLine(", and %zd audio stream(s)", program.audioStreams.size()); if (!program.audioStreams.empty()) { eDebugNoNewLine(" ("); for (std::vector<eDVBServicePMTHandler::audioStream>::const_iterator i(program.audioStreams.begin()); i != program.audioStreams.end(); ++i) { pids_to_record.insert(i->pid); if (timing_pid == -1) { timing_pid = i->pid; timing_stream_type = i->type; timing_pid_type = iDVBTSRecorder::audio_pid; } if (i != program.audioStreams.begin()) eDebugNoNewLine(", "); eDebugNoNewLine("%04x", i->pid); } eDebugNoNewLine(")"); } if (!program.subtitleStreams.empty()) { eDebugNoNewLine(" ("); for (std::vector<eDVBServicePMTHandler::subtitleStream>::const_iterator i(program.subtitleStreams.begin()); i != program.subtitleStreams.end(); ++i) { pids_to_record.insert(i->pid); if (i != program.subtitleStreams.begin()) eDebugNoNewLine(", "); eDebugNoNewLine("%04x", i->pid); } eDebugNoNewLine(")"); } eDebugNoNewLine(", and the pcr pid is %04x", program.pcrPid); if (program.pcrPid >= 0 && program.pcrPid < 0x1fff) pids_to_record.insert(program.pcrPid); eDebugNoNewLineEnd(", and the text pid is %04x", program.textPid); if (program.textPid != -1) pids_to_record.insert(program.textPid); // Videotext if (m_record_ecm) { for (std::list<eDVBServicePMTHandler::program::capid_pair>::const_iterator i(program.caids.begin()); i != program.caids.end(); ++i) { if (i->capid >= 0) pids_to_record.insert(i->capid); } } bool include_ait = eConfigManager::getConfigBoolValue("config.recording.include_ait"); if (include_ait) { /* add AIT pid (if any) */ if (program.aitPid >= 0) pids_to_record.insert(program.aitPid); } /* find out which pids are NEW and which pids are obsolete.. */ std::set<int> new_pids, obsolete_pids; std::set_difference(pids_to_record.begin(), pids_to_record.end(), m_pids_active.begin(), m_pids_active.end(), std::inserter(new_pids, new_pids.begin())); std::set_difference( m_pids_active.begin(), m_pids_active.end(), pids_to_record.begin(), pids_to_record.end(), std::inserter(obsolete_pids, obsolete_pids.begin()) ); for (std::set<int>::iterator i(new_pids.begin()); i != new_pids.end(); ++i) { eDebug("ADD PID: %04x", *i); m_record->addPID(*i); } for (std::set<int>::iterator i(obsolete_pids.begin()); i != obsolete_pids.end(); ++i) { eDebug("REMOVED PID: %04x", *i); m_record->removePID(*i); } if (timing_pid != -1) m_record->setTimingPID(timing_pid, timing_pid_type, timing_stream_type); m_pids_active = pids_to_record; if (m_state != stateRecording) { m_record->start(); m_state = stateRecording; } } } m_error = 0; m_event((iRecordableService*)this, evRecordRunning); return 0; }
int main(int argc, char **argv) { #if TMTWIN|1 MiniFTP_Thread *miniftp; miniftp=new MiniFTP_Thread(); eSystemInfo *systeminfo; systeminfo = new eSystemInfo(); #endif #ifdef MEMLEAK_CHECK atexit(DumpUnfreed); #endif #ifdef OBJECT_DEBUG atexit(object_dump); #endif gst_init(&argc, &argv); // set pythonpath if unset setenv("PYTHONPATH", eEnv::resolve("${libdir}/enigma2/python").c_str(), 0); printf("PYTHONPATH: %s\n", getenv("PYTHONPATH")); bsodLogInit(); ePython python; eMain main; #if 1 ePtr<gMainDC> my_dc; gMainDC::getInstance(my_dc); //int double_buffer = my_dc->haveDoubleBuffering(); ePtr<gLCDDC> my_lcd_dc; gLCDDC::getInstance(my_lcd_dc); /* ok, this is currently hardcoded for arabic. */ /* some characters are wrong in the regular font, force them to use the replacement font */ for (int i = 0x60c; i <= 0x66d; ++i) eTextPara::forceReplacementGlyph(i); eTextPara::forceReplacementGlyph(0xfdf2); for (int i = 0xfe80; i < 0xff00; ++i) eTextPara::forceReplacementGlyph(i); eWidgetDesktop dsk(my_dc->size()); eWidgetDesktop dsk_lcd(my_lcd_dc->size()); dsk.setStyleID(0); dsk_lcd.setStyleID(my_lcd_dc->size().width() == 96 ? 2 : 1); /* if (double_buffer) { eDebug(" - double buffering found, enable buffered graphics mode."); dsk.setCompositionMode(eWidgetDesktop::cmBuffered); } */ wdsk = &dsk; lcddsk = &dsk_lcd; dsk.setDC(my_dc); dsk_lcd.setDC(my_lcd_dc); dsk.setBackgroundColor(gRGB(0,0,0,0xFF)); #endif /* redrawing is done in an idle-timer, so we have to set the context */ dsk.setRedrawTask(main); dsk_lcd.setRedrawTask(main); eDebug("Loading spinners..."); { int i; #define MAX_SPINNER 64 ePtr<gPixmap> wait[MAX_SPINNER]; for (i=0; i<MAX_SPINNER; ++i) { char filename[64]; std::string rfilename; snprintf(filename, sizeof(filename), "${datadir}/enigma2/skin_default/spinner/wait%d.png", i + 1); rfilename = eEnv::resolve(filename); loadPNG(wait[i], rfilename.c_str()); if (!wait[i]) { if (!i) eDebug("failed to load %s! (%m)", rfilename.c_str()); else eDebug("found %d spinner!\n", i); break; } } if (i) my_dc->setSpinner(eRect(ePoint(100, 100), wait[0]->size()), wait, i); else my_dc->setSpinner(eRect(100, 100, 0, 0), wait, 1); } gRC::getInstance()->setSpinnerDC(my_dc); eRCInput::getInstance()->keyEvent.connect(slot(keyEvent)); printf("executing main\n"); bsodCatchSignals(); setIoPrio(IOPRIO_CLASS_BE, 3); /* start at full size */ eVideoWidget::setFullsize(true); // python.execute("mytest", "__main__"); python.execFile(eEnv::resolve("${libdir}/enigma2/python/mytest.py").c_str()); /* restore both decoders to full size */ eVideoWidget::setFullsize(true); if (exit_code == 5) /* python crash */ { eDebug("(exit code 5)"); bsodFatal(0); } dsk.paint(); dsk_lcd.paint(); { gPainter p(my_lcd_dc); p.resetClip(eRect(ePoint(0, 0), my_lcd_dc->size())); p.clear(); p.flush(); } return exit_code; }
fbClass::fbClass(const char *fb) { m_manual_blit=-1; instance=this; locked=0; lfb = 0; available=0; cmap.start=0; cmap.len=256; cmap.red=red; cmap.green=green; cmap.blue=blue; cmap.transp=trans; fbFd=open(fb, O_RDWR); if (fbFd<0) { perror(fb); goto nolfb; } #if not defined(__sh__) if (ioctl(fbFd, FBIOGET_VSCREENINFO, &screeninfo)<0) { perror("FBIOGET_VSCREENINFO"); goto nolfb; } #endif fb_fix_screeninfo fix; if (ioctl(fbFd, FBIOGET_FSCREENINFO, &fix)<0) { perror("FBIOGET_FSCREENINFO"); goto nolfb; } available=fix.smem_len; m_phys_mem = fix.smem_start; eDebug("%dk total video mem", available/1024); #if defined(__sh__) // The first 1920x1080x4 bytes are reserved // After that we can take 1280x720x4 bytes for our virtual framebuffer available -= 1920*1080*4; eDebug("%dk usable video mem", available/1024); lfb=(unsigned char*)mmap(0, available, PROT_WRITE|PROT_READ, MAP_SHARED, fbFd, 1920*1080*4); #else eDebug("%dk video mem", available/1024); lfb=(unsigned char*)mmap(0, available, PROT_WRITE|PROT_READ, MAP_SHARED, fbFd, 0); #endif if (!lfb) { perror("mmap"); goto nolfb; } #if not defined(__sh__) showConsole(0); enableManualBlit(); #endif return; nolfb: if (fbFd >= 0) { ::close(fbFd); fbFd = -1; } printf("framebuffer not available.\n"); return; }
void gFBDC::setResolution(int xres, int yres, int bpp) { #if defined(__sh__) /* if xres and yres are negative call SetMode with the lates xres and yres * we need that to read the new screen dimesnions after a resolution change * without changing the frambuffer dimensions */ int m_xres; int m_yres; int m_bpp; fb->getMode(m_xres, m_yres, m_bpp); if (xres<0 && yres<0 ) { fb->SetMode(m_xres, m_yres, bpp); return; } #else if (m_pixmap && (surface.x == xres) && (surface.y == yres) && (surface.bpp == bpp)) return; #endif if (gAccel::getInstance()) gAccel::getInstance()->releaseAccelMemorySpace(); fb->SetMode(xres, yres, bpp); #if defined(__sh__) for (int y = 0; y<yres; y++) { // make whole screen transparent memset(fb->lfb+y*fb->Stride(), 0x00, fb->Stride()); } #endif surface.x = xres; surface.y = yres; surface.bpp = bpp; surface.bypp = bpp / 8; surface.stride = fb->Stride(); surface.data = fb->lfb; surface.data_phys = fb->getPhysAddr(); int fb_size = surface.stride * surface.y; if (fb->getNumPages() > 1) { surface_back = surface; surface_back.data = fb->lfb + fb_size; surface_back.data_phys = surface.data_phys + fb_size; fb_size *= 2; } else { surface_back.data = 0; surface_back.data_phys = 0; } eDebug("[gFBDC] resolution: %dx%dx%d stride=%d, %dkB available for acceleration surfaces.", surface.x, surface.y, surface.bpp, fb->Stride(), (fb->Available() - fb_size)/1024); if (gAccel::getInstance()) gAccel::getInstance()->setAccelMemorySpace(fb->lfb + fb_size, surface.data_phys + fb_size, fb->Available() - fb_size); if (!surface.clut.data) { surface.clut.colors = 256; surface.clut.data = new gRGB[surface.clut.colors]; memset(surface.clut.data, 0, sizeof(*surface.clut.data)*surface.clut.colors); } surface_back.clut = surface.clut; m_pixmap = new gPixmap(&surface); }
int eDVBServiceStream::doRecord() { int err = doPrepare(); if (err) { eDebug("[eDVBServiceStream] doPrerare err %d", err); return err; } if (!m_tuned) { eDebug("[eDVBServiceStream] try it again when we are tuned in"); return 0; /* try it again when we are tuned in */ } if (!m_record && m_tuned) { ePtr<iDVBDemux> demux; if (m_service_handler.getDataDemux(demux)) { eDebug("eDVBServiceStream - NO DEMUX available"); return -1; } demux->createTSRecorder(m_record, /*packetsize*/ 188, /*streaming*/ true); if (!m_record) { eDebug("eDVBServiceStream - no ts recorder available."); return -1; } m_record->setTargetFD(m_target_fd); m_record->connectEvent(sigc::mem_fun(*this, &eDVBServiceStream::recordEvent), m_con_record_event); } eDebug("start streaming..."); if (recordCachedPids()) { eDebug("[eDVBServiceStream] streaming pids from cache."); return 0; } eDVBServicePMTHandler::program program; if (m_service_handler.getProgramInfo(program)) { eDebug("getting program info failed."); } else if(m_record_no_pids == 0) { std::set<int> pids_to_record; eServiceReferenceDVB ref = m_ref.getParentServiceReference(); ePtr<eDVBService> service; if (!ref.valid()) ref = m_ref; if(!eDVBDB::getInstance()->getService(ref, service)) { // cached pids for (int x = 0; x < eDVBService::cacheMax; ++x) { if (x == 5) { x += 3; // ignore cVTYPE, cACHANNEL, cAC3DELAY, cPCMDELAY continue; } int entry = service->getCacheEntry((eDVBService::cacheID)x); if (entry != -1) { if (eDVBService::cSUBTITLE == (eDVBService::cacheID)x) { entry = (entry&0xFFFF0000)>>16; } pids_to_record.insert(entry); } } }
void *gRC::thread() { int need_notify = 0; #ifndef SYNC_PAINT while (1) { #else while (rp != wp) { #endif #ifndef SYNC_PAINT pthread_mutex_lock(&mutex); #endif if ( rp != wp ) { /* make sure the spinner is not displayed when we something is painted */ disableSpinner(); gOpcode o(queue[rp++]); if ( rp == MAXSIZE ) rp=0; #ifndef SYNC_PAINT pthread_mutex_unlock(&mutex); #endif if (o.opcode==gOpcode::shutdown) break; else if (o.opcode==gOpcode::notify) need_notify = 1; else if (o.opcode==gOpcode::setCompositing) { m_compositing = o.parm.setCompositing; m_compositing->Release(); } else if(o.dc) { o.dc->exec(&o); // o.dc is a gDC* filled with grabref... so we must release it here o.dc->Release(); } } else { if (need_notify) { need_notify = 0; m_notify_pump.send(1); } #ifndef SYNC_PAINT while(rp == wp) { /* when the main thread is non-idle for a too long time without any display output, we want to display a spinner. */ struct timespec timeout; clock_gettime(CLOCK_REALTIME, &timeout); if (m_spinner_enabled) { timeout.tv_nsec += 100*1000*1000; /* yes, this is required. */ if (timeout.tv_nsec > 1000*1000*1000) { timeout.tv_nsec -= 1000*1000*1000; timeout.tv_sec++; } } else timeout.tv_sec += 2; int idle = 1; if (pthread_cond_timedwait(&cond, &mutex, &timeout) == ETIMEDOUT) { if (eApp && !eApp->isIdle()) { int idle_count = eApp->idleCount(); if (idle_count == m_prev_idle_count) idle = 0; else m_prev_idle_count = idle_count; } } if (!idle) { if (!m_spinner_enabled) eDebug("main thread is non-idle! display spinner!"); enableSpinner(); } else disableSpinner(); } pthread_mutex_unlock(&mutex); #endif } } #ifndef SYNC_PAINT pthread_exit(0); #endif return 0; } void gRC::recv_notify(const int &i) { notify(); } gRC *gRC::getInstance() { return instance; } void gRC::enableSpinner() { if (!m_spinner_dc) { eDebug("no spinner DC!"); return; } gOpcode o; o.opcode = m_spinner_enabled ? gOpcode::incrementSpinner : gOpcode::enableSpinner; m_spinner_dc->exec(&o); m_spinner_enabled = 1; o.opcode = gOpcode::flush; m_spinner_dc->exec(&o); } void gRC::disableSpinner() { if (!m_spinner_enabled) return; if (!m_spinner_dc) { eDebug("no spinner DC!"); return; } m_spinner_enabled = 0; gOpcode o; o.opcode = gOpcode::disableSpinner; m_spinner_dc->exec(&o); o.opcode = gOpcode::flush; m_spinner_dc->exec(&o); } static int gPainter_instances; gPainter::gPainter(gDC *dc, eRect rect): m_dc(dc), m_rc(gRC::getInstance()) { // ASSERT(!gPainter_instances); gPainter_instances++; // begin(rect); } gPainter::~gPainter() { end(); gPainter_instances--; } void gPainter::setBackgroundColor(const gColor &color) { if ( m_dc->islocked() ) return; gOpcode o; o.opcode = gOpcode::setBackgroundColor; o.dc = m_dc.grabRef(); o.parm.setColor = new gOpcode::para::psetColor; o.parm.setColor->color = color; m_rc->submit(o); } void gPainter::setForegroundColor(const gColor &color) { if ( m_dc->islocked() ) return; gOpcode o; o.opcode = gOpcode::setForegroundColor; o.dc = m_dc.grabRef(); o.parm.setColor = new gOpcode::para::psetColor; o.parm.setColor->color = color; m_rc->submit(o); } void gPainter::setBackgroundColor(const gRGB &color) { if ( m_dc->islocked() ) return; gOpcode o; o.opcode = gOpcode::setBackgroundColorRGB; o.dc = m_dc.grabRef(); o.parm.setColorRGB = new gOpcode::para::psetColorRGB; o.parm.setColorRGB->color = color; m_rc->submit(o); } void gPainter::setForegroundColor(const gRGB &color) { if ( m_dc->islocked() ) return; gOpcode o; o.opcode = gOpcode::setForegroundColorRGB; o.dc = m_dc.grabRef(); o.parm.setColorRGB = new gOpcode::para::psetColorRGB; o.parm.setColorRGB->color = color; m_rc->submit(o); } void gPainter::setFont(gFont *font) { if ( m_dc->islocked() ) return; gOpcode o; o.opcode = gOpcode::setFont; o.dc = m_dc.grabRef(); font->AddRef(); o.parm.setFont = new gOpcode::para::psetFont; o.parm.setFont->font = font; m_rc->submit(o); } void gPainter::renderText(const eRect &pos, const std::string &string, int flags) { if ( m_dc->islocked() ) return; gOpcode o; o.opcode=gOpcode::renderText; o.dc = m_dc.grabRef(); o.parm.renderText = new gOpcode::para::prenderText; o.parm.renderText->area = pos; o.parm.renderText->text = string.empty()?0:strdup(string.c_str()); o.parm.renderText->flags = flags; m_rc->submit(o); } void gPainter::renderPara(eTextPara *para, ePoint offset) { if ( m_dc->islocked() ) return; ASSERT(para); gOpcode o; o.opcode=gOpcode::renderPara; o.dc = m_dc.grabRef(); o.parm.renderPara = new gOpcode::para::prenderPara; o.parm.renderPara->offset = offset; para->AddRef(); o.parm.renderPara->textpara = para; m_rc->submit(o); } void gPainter::fill(const eRect &area) { if ( m_dc->islocked() ) return; gOpcode o; o.opcode=gOpcode::fill; o.dc = m_dc.grabRef(); o.parm.fill = new gOpcode::para::pfillRect; o.parm.fill->area = area; m_rc->submit(o); } void gPainter::fill(const gRegion ®ion) { if ( m_dc->islocked() ) return; gOpcode o; o.opcode=gOpcode::fillRegion; o.dc = m_dc.grabRef(); o.parm.fillRegion = new gOpcode::para::pfillRegion; o.parm.fillRegion->region = region; m_rc->submit(o); } void gPainter::clear() { if ( m_dc->islocked() ) return; gOpcode o; o.opcode=gOpcode::clear; o.dc = m_dc.grabRef(); o.parm.fill = new gOpcode::para::pfillRect; o.parm.fill->area = eRect(); m_rc->submit(o); } void gPainter::blit(gPixmap *pixmap, ePoint pos, const eRect &clip, int flags) { blitScale(pixmap, eRect(pos, eSize()), clip, flags, 0); }
void eDVBServicePMTHandler::AITready(int error) { eDebug("AITready"); ePtr<eTable<ApplicationInformationSection> > ptr; if (!m_AIT.getCurrent(ptr)) { m_HBBTVUrl = ""; for (std::vector<ApplicationInformationSection*>::const_iterator it = ptr->getSections().begin(); it != ptr->getSections().end(); ++it) { for (std::list<ApplicationInformation *>::const_iterator i = (*it)->getApplicationInformation()->begin(); i != (*it)->getApplicationInformation()->end(); ++i) { if ((*i)->getApplicationControlCode() == 0x01) /* AUTOSTART */ { for (DescriptorConstIterator desc = (*i)->getDescriptors()->begin(); desc != (*i)->getDescriptors()->end(); ++desc) { switch ((*desc)->getTag()) { case APPLICATION_DESCRIPTOR: break; case APPLICATION_NAME_DESCRIPTOR: break; case TRANSPORT_PROTOCOL_DESCRIPTOR: { TransportProtocolDescriptor *transport = (TransportProtocolDescriptor*)(*desc); switch (transport->getProtocolId()) { case 1: /* object carousel */ if (m_dsmcc_pid >= 0) { m_OC.begin(eApp, eDVBDSMCCDLDataSpec(m_dsmcc_pid), m_demux); } break; case 2: /* ip */ break; case 3: /* interaction */ for (InterActionTransportConstIterator interactionit = transport->getInteractionTransports()->begin(); interactionit != transport->getInteractionTransports()->end(); ++interactionit) { m_HBBTVUrl = (*interactionit)->getUrlBase()->getUrl(); break; } break; } break; } case GRAPHICS_CONSTRAINTS_DESCRIPTOR: break; case SIMPLE_APPLICATION_LOCATION_DESCRIPTOR: { SimpleApplicationLocationDescriptor *applicationlocation = (SimpleApplicationLocationDescriptor*)(*desc); m_HBBTVUrl += applicationlocation->getInitialPath(); break; } case APPLICATION_USAGE_DESCRIPTOR: break; case SIMPLE_APPLICATION_BOUNDARY_DESCRIPTOR: break; } } } } } if (!m_HBBTVUrl.empty()) { serviceEvent(eventHBBTVInfo); } } /* for now, do not keep listening for table updates */ m_AIT.stop(); }
int eDVBServicePMTHandler::getProgramInfo(program &program) { ePtr<eTable<ProgramMapSection> > ptr; int cached_apid_ac3 = -1; int cached_apid_mpeg = -1; int cached_vpid = -1; int cached_tpid = -1; int ret = -1; program.videoStreams.clear(); program.audioStreams.clear(); program.pcrPid = -1; program.pmtPid = -1; program.textPid = -1; int first_ac3 = -1; int audio_cached = -1; int autoaudio_mpeg = -1; int autoaudio_ac3 = -1; int autoaudio_level = 4; std::string configvalue; std::vector<std::string> autoaudio_languages; if (!ePythonConfigQuery::getConfigValue("config.autolanguage.audio_autoselect1", configvalue) && configvalue != "None") autoaudio_languages.push_back(configvalue); if (!ePythonConfigQuery::getConfigValue("config.autolanguage.audio_autoselect2", configvalue) && configvalue != "None") autoaudio_languages.push_back(configvalue); if (!ePythonConfigQuery::getConfigValue("config.autolanguage.audio_autoselect3", configvalue) && configvalue != "None") autoaudio_languages.push_back(configvalue); if (!ePythonConfigQuery::getConfigValue("config.autolanguage.audio_autoselect4", configvalue) && configvalue != "None") autoaudio_languages.push_back(configvalue); program.defaultAudioStream = 0; audioStream *prev_audio = 0; int autosub_txt_normal = -1; int autosub_txt_hearing = -1; int autosub_dvb_normal = -1; int autosub_dvb_hearing = -1; int autosub_level =4; std::vector<std::string> autosub_languages; if (!ePythonConfigQuery::getConfigValue("config.autolanguage.subtitle_autoselect1", configvalue) && configvalue != "None") autosub_languages.push_back(configvalue); if (!ePythonConfigQuery::getConfigValue("config.autolanguage.subtitle_autoselect2", configvalue) && configvalue != "None") autosub_languages.push_back(configvalue); if (!ePythonConfigQuery::getConfigValue("config.autolanguage.subtitle_autoselect3", configvalue) && configvalue != "None") autosub_languages.push_back(configvalue); if (!ePythonConfigQuery::getConfigValue("config.autolanguage.subtitle_autoselect4", configvalue) && configvalue != "None") autosub_languages.push_back(configvalue); program.defaultSubtitleStream = -1; if ( m_service && !m_service->cacheEmpty() ) { cached_vpid = m_service->getCacheEntry(eDVBService::cVPID); cached_apid_mpeg = m_service->getCacheEntry(eDVBService::cAPID); cached_apid_ac3 = m_service->getCacheEntry(eDVBService::cAC3PID); cached_tpid = m_service->getCacheEntry(eDVBService::cTPID); } if ( ((m_service && m_service->usePMT()) || !m_service) && !m_PMT.getCurrent(ptr)) { if (m_have_cached_program) { program = m_cached_program; ret = 0; } else { eDVBTableSpec table_spec; ptr->getSpec(table_spec); program.pmtPid = table_spec.pid < 0x1fff ? table_spec.pid : -1; std::vector<ProgramMapSection*>::const_iterator i; 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) { int isaudio = 0, isvideo = 0, issubtitle = 0, forced_video = 0, forced_audio = 0, isteletext = 0; int streamtype = (*es)->getType(); videoStream video; audioStream audio; audio.component_tag=video.component_tag=-1; video.type = videoStream::vtMPEG2; audio.type = audioStream::atMPEG; audio.rdsPid = -1; switch (streamtype) { case 0x1b: // AVC Video Stream (MPEG4 H264) video.type = videoStream::vtMPEG4_H264; isvideo = 1; //break; fall through !!! case 0x10: // MPEG 4 Part 2 if (!isvideo) { video.type = videoStream::vtMPEG4_Part2; isvideo = 1; } //break; fall through !!! case 0x01: // MPEG 1 video if (!isvideo) video.type = videoStream::vtMPEG1; //break; fall through !!! case 0x02: // MPEG 2 video isvideo = 1; forced_video = 1; //break; fall through !!! case 0x03: // MPEG 1 audio case 0x04: // MPEG 2 audio: if (!isvideo) { isaudio = 1; forced_audio = 1; } //break; fall through !!! case 0x0f: // MPEG 2 AAC if (!isvideo && !isaudio) { isaudio = 1; audio.type = audioStream::atAAC; forced_audio = 1; } //break; fall through !!! case 0x11: // MPEG 4 AAC if (!isvideo && !isaudio) { isaudio = 1; audio.type = audioStream::atAACHE; forced_audio = 1; } 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 bluray AC3 case 0xA1: // bluray secondary AC3 if (!isvideo && !isaudio) { isaudio = 1; audio.type = audioStream::atAC3; } 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 { int num_descriptors = 0; for (DescriptorConstIterator desc = (*es)->getDescriptors()->begin(); desc != (*es)->getDescriptors()->end(); ++desc) { uint8_t tag = (*desc)->getTag(); /* check descriptors to get the exakt stream type. */ ++num_descriptors; if (!forced_video && !forced_audio) { switch (tag) { case AUDIO_STREAM_DESCRIPTOR: isaudio = 1; break; case VIDEO_STREAM_DESCRIPTOR: { isvideo = 1; VideoStreamDescriptor *d = (VideoStreamDescriptor*)(*desc); if (d->getMpeg1OnlyFlag()) video.type = videoStream::vtMPEG1; break; } case SUBTITLING_DESCRIPTOR: { SubtitlingDescriptor *d = (SubtitlingDescriptor*)(*desc); const SubtitlingList *list = d->getSubtitlings(); subtitleStream s; s.pid = (*es)->getPid(); for (SubtitlingConstIterator it(list->begin()); it != list->end(); ++it) { s.subtitling_type = (*it)->getSubtitlingType(); switch(s.subtitling_type) { case 0x10 ... 0x13: // dvb subtitles normal case 0x20 ... 0x23: // dvb subtitles hearing impaired break; default: eDebug("dvb subtitle %s PID %04x with wrong subtitling type (%02x)... force 0x10!!", s.language_code.c_str(), s.pid, s.subtitling_type); s.subtitling_type = 0x10; break; } s.composition_page_id = (*it)->getCompositionPageId(); s.ancillary_page_id = (*it)->getAncillaryPageId(); std::string language = (*it)->getIso639LanguageCode(); s.language_code = language; // eDebug("add dvb subtitle %s PID %04x, type %d, composition page %d, ancillary_page %d", s.language_code.c_str(), s.pid, s.subtitling_type, s.composition_page_id, s.ancillary_page_id); if (!language.empty()) { int x = 1; for (std::vector<std::string>::iterator it2 = autosub_languages.begin();x <= autosub_level && it2 != autosub_languages.end();x++,it2++) { if ( (*it2).find(language) != -1 ) { autosub_level = x; if (s.subtitling_type >= 0x20) autosub_dvb_hearing = program.subtitleStreams.size(); else autosub_dvb_normal = program.subtitleStreams.size(); break; } } } issubtitle = 1; program.subtitleStreams.push_back(s); } break; } case TELETEXT_DESCRIPTOR: if ( program.textPid == -1 || (*es)->getPid() == cached_tpid ) { subtitleStream s; s.subtitling_type = 0x01; // EBU TELETEXT SUBTITLES s.pid = program.textPid = (*es)->getPid(); TeletextDescriptor *d = (TeletextDescriptor*)(*desc); isteletext = 1; const VbiTeletextList *list = d->getVbiTeletexts(); std::string language; for (VbiTeletextConstIterator it(list->begin()); it != list->end(); ++it) { switch((*it)->getTeletextType()) { case 0x02: // Teletext subtitle page case 0x05: // Teletext subtitle page for hearing impaired pepople language = (*it)->getIso639LanguageCode(); s.language_code = language; s.teletext_page_number = (*it)->getTeletextPageNumber(); s.teletext_magazine_number = (*it)->getTeletextMagazineNumber(); // eDebug("add teletext subtitle %s PID %04x, page number %d, magazine number %d", s.language_code.c_str(), s.pid, s.teletext_page_number, s.teletext_magazine_number); if (!language.empty()) { int x = 1; for (std::vector<std::string>::iterator it2 = autosub_languages.begin();x <= autosub_level && it2 != autosub_languages.end();x++,it2++) { if ( (*it2).find(language) != -1 ) { autosub_level = x; if (s.subtitling_type == 0x05) autosub_txt_hearing = program.subtitleStreams.size(); else autosub_txt_normal = program.subtitleStreams.size(); break; } } } program.subtitleStreams.push_back(s); issubtitle=1; default: break; } } } break; case DTS_DESCRIPTOR: isaudio = 1; audio.type = audioStream::atDTS; break; case 0x2B: // TS_PSI_DT_MPEG2_AAC isaudio = 1; audio.type = audioStream::atAAC; // MPEG2-AAC break; case 0x1C: // TS_PSI_DT_MPEG4_Audio case AAC_DESCRIPTOR: isaudio = 1; audio.type = audioStream::atAACHE; // MPEG4-AAC break; case AC3_DESCRIPTOR: isaudio = 1; audio.type = audioStream::atAC3; break; case ENHANCED_AC3_DESCRIPTOR: isaudio = 1; audio.type = audioStream::atDDP; break; case REGISTRATION_DESCRIPTOR: /* some services don't have a separate AC3 descriptor */ { RegistrationDescriptor *d = (RegistrationDescriptor*)(*desc); switch (d->getFormatIdentifier()) { case 0x44545331 ... 0x44545333: // DTS1/DTS2/DTS3 isaudio = 1; audio.type = audioStream::atDTS; break; case 0x41432d33: // == 'AC-3' isaudio = 1; audio.type = audioStream::atAC3; break; case 0x42535344: // == 'BSSD' (LPCM) isaudio = 1; audio.type = audioStream::atLPCM; break; case 0x56432d31: // == 'VC-1' { const AdditionalIdentificationInfoVector *vec = d->getAdditionalIdentificationInfo(); if (vec->size() > 1 && (*vec)[0] == 0x01) // subdescriptor tag { if ((*vec)[1] >= 0x90) // profile_level video.type = videoStream::vtVC1; // advanced profile else video.type = videoStream::vtVC1_SM; // simple main isvideo = 1; } } default: break; } break; } case 0x28: // TS_PSI_DT_AVC isvideo = 1; video.type = videoStream::vtMPEG4_H264; break; case 0x1B: // TS_PSI_DT_MPEG4_Video isvideo = 1; video.type = videoStream::vtMPEG4_Part2; break; default: break; } } switch (tag) { case ISO_639_LANGUAGE_DESCRIPTOR: if (!isvideo) { const Iso639LanguageList *languages = ((Iso639LanguageDescriptor*)*desc)->getIso639Languages(); /* use last language code */ int cnt=0; for (Iso639LanguageConstIterator i=languages->begin(); i != languages->end(); ++i) { std::string language=(*i)->getIso639LanguageCode(); if ( cnt==0 ) audio.language_code = language; else audio.language_code += "/" + language; cnt++; if (!language.empty()) { int x = 1; for (std::vector<std::string>::iterator it = autoaudio_languages.begin();x <= autoaudio_level && it != autoaudio_languages.end();x++,it++) { if ( (*it).find(language) != -1 ) { if (audio.type == audioStream::atMPEG && (autoaudio_level > x || autoaudio_mpeg == -1)) autoaudio_mpeg = program.audioStreams.size(); else if (audio.type != audioStream::atMPEG && (autoaudio_level > x || autoaudio_ac3 == -1)) autoaudio_ac3 = program.audioStreams.size(); autoaudio_level = x; break; } } } } } break; case STREAM_IDENTIFIER_DESCRIPTOR: audio.component_tag = video.component_tag = ((StreamIdentifierDescriptor*)*desc)->getComponentTag(); break; case CA_DESCRIPTOR: { CaDescriptor *descr = (CaDescriptor*)(*desc); program::capid_pair pair; pair.caid = descr->getCaSystemId(); pair.capid = descr->getCaPid(); program.caids.push_back(pair); break; } default: break; } } if (!num_descriptors && streamtype == 0x06 && prev_audio) { prev_audio->rdsPid = (*es)->getPid(); eDebug("Rds PID %04x detected ? ! ?", prev_audio->rdsPid); } prev_audio = 0; break; } case 0x05: /* ITU-T Rec. H.222.0 | ISO/IEC 13818-1 private sections */ { for (DescriptorConstIterator desc = (*es)->getDescriptors()->begin(); desc != (*es)->getDescriptors()->end(); ++desc) { switch ((*desc)->getTag()) { case APPLICATION_SIGNALLING_DESCRIPTOR: m_AIT.begin(eApp, eDVBAITSpec((*es)->getPid()), m_demux); break; } } break; } case 0x0b: /* ISO/IEC 13818-6 DSM-CC U-N Messages */ { for (DescriptorConstIterator desc = (*es)->getDescriptors()->begin(); desc != (*es)->getDescriptors()->end(); ++desc) { switch ((*desc)->getTag()) { case CAROUSEL_IDENTIFIER_DESCRIPTOR: m_dsmcc_pid = (*es)->getPid(); break; case STREAM_IDENTIFIER_DESCRIPTOR: break; } } break; } default: break; } if (isteletext && (isaudio || isvideo)) { eDebug("ambiguous streamtype for PID %04x detected.. forced as teletext!", (*es)->getPid()); continue; // continue with next PID } else if (issubtitle && (isaudio || isvideo)) eDebug("ambiguous streamtype for PID %04x detected.. forced as subtitle!", (*es)->getPid()); else if (isaudio && isvideo) eDebug("ambiguous streamtype for PID %04x detected.. forced as video!", (*es)->getPid()); if (issubtitle) // continue with next PID continue; else if (isvideo) { video.pid = (*es)->getPid(); if ( !program.videoStreams.empty() && video.pid == cached_vpid ) { program.videoStreams.push_back(program.videoStreams[0]); program.videoStreams[0] = video; } else program.videoStreams.push_back(video); } else if (isaudio) { audio.pid = (*es)->getPid(); /* if we find the cached pids, this will be our default stream */ if (audio.pid == cached_apid_ac3 || audio.pid == cached_apid_mpeg) audio_cached = program.audioStreams.size(); /* also, we need to know the first non-mpeg (i.e. "ac3"/dts/...) stream */ if ((audio.type != audioStream::atMPEG) && ((first_ac3 == -1) || (audio.pid == cached_apid_ac3))) first_ac3 = program.audioStreams.size(); program.audioStreams.push_back(audio); prev_audio = &program.audioStreams.back(); } else continue; } } ret = 0; bool defaultac3 = false; bool useaudio_cache = false; if (!ePythonConfigQuery::getConfigValue("config.autolanguage.audio_defaultac3", configvalue)) defaultac3 = configvalue == "True"; if (!ePythonConfigQuery::getConfigValue("config.autolanguage.audio_usecache", configvalue)) useaudio_cache = configvalue == "True"; if (useaudio_cache && audio_cached != -1) program.defaultAudioStream = audio_cached; else if ( defaultac3 ) { if ( autoaudio_ac3 != -1 ) program.defaultAudioStream = autoaudio_ac3; else if ( autoaudio_mpeg != -1 ) program.defaultAudioStream = autoaudio_mpeg; else if ( first_ac3 != -1 ) program.defaultAudioStream = first_ac3; } else { if ( autoaudio_mpeg != -1 ) program.defaultAudioStream = autoaudio_mpeg; else if ( autoaudio_ac3 != -1 ) program.defaultAudioStream = autoaudio_ac3; } bool allow_hearingimpaired = false; bool default_hearingimpaired = false; bool defaultdvb = false; int equallanguagemask = false; if (!ePythonConfigQuery::getConfigValue("config.autolanguage.subtitle_hearingimpaired", configvalue)) allow_hearingimpaired = configvalue == "True"; if (!ePythonConfigQuery::getConfigValue("config.autolanguage.subtitle_defaultimpaired", configvalue)) default_hearingimpaired = configvalue == "True"; if (!ePythonConfigQuery::getConfigValue("config.autolanguage.subtitle_defaultdvb", configvalue)) defaultdvb = configvalue == "True"; if (!ePythonConfigQuery::getConfigValue("config.autolanguage.equal_languages", configvalue)) equallanguagemask = atoi(configvalue.c_str()); if (defaultdvb) { if (allow_hearingimpaired && default_hearingimpaired && autosub_dvb_hearing != -1) program.defaultSubtitleStream = autosub_dvb_hearing; else if (autosub_dvb_normal != -1) program.defaultSubtitleStream = autosub_dvb_normal; else if (allow_hearingimpaired && autosub_dvb_hearing != -1) program.defaultSubtitleStream = autosub_dvb_hearing; else if (allow_hearingimpaired && default_hearingimpaired && autosub_txt_hearing != -1) program.defaultSubtitleStream = autosub_txt_hearing; else if (autosub_txt_normal != -1) program.defaultSubtitleStream = autosub_txt_normal; else if (allow_hearingimpaired && autosub_dvb_hearing != -1) program.defaultSubtitleStream = autosub_txt_hearing; } else { if (allow_hearingimpaired && default_hearingimpaired && autosub_txt_hearing != -1) program.defaultSubtitleStream = autosub_txt_hearing; else if (autosub_txt_normal != -1) program.defaultSubtitleStream = autosub_txt_normal; else if (allow_hearingimpaired && autosub_txt_hearing != -1) program.defaultSubtitleStream = autosub_txt_hearing; else if (allow_hearingimpaired && default_hearingimpaired && autosub_dvb_hearing != -1) program.defaultSubtitleStream = autosub_dvb_hearing; else if (autosub_dvb_normal != -1) program.defaultSubtitleStream = autosub_dvb_normal; else if (allow_hearingimpaired && autosub_dvb_hearing != -1) program.defaultSubtitleStream = autosub_dvb_hearing; } if (program.defaultSubtitleStream != -1 && (equallanguagemask & (1<<(autosub_level-1))) == 0 && program.subtitleStreams[program.defaultSubtitleStream].language_code.compare(program.audioStreams[program.defaultAudioStream].language_code) == 0 ) program.defaultSubtitleStream = -1; m_cached_program = program; m_have_cached_program = true; } } else if ( m_service && !m_service->cacheEmpty() )
int eDVBPMTParser::getProgramInfo(program &program) { ePtr<eTable<ProgramMapSection> > ptr; int ret = -1; clearProgramInfo(program); if (!m_PMT.getCurrent(ptr)) { audioStream *prev_audio = 0; eDVBTableSpec table_spec; ptr->getSpec(table_spec); program.pmtPid = table_spec.pid < 0x1fff ? table_spec.pid : -1; std::vector<ProgramMapSection*>::const_iterator i; for (i = ptr->getSections().begin(); i != ptr->getSections().end(); ++i) { const ProgramMapSection &pmt = **i; int is_hdmv = 0; program.serviceId = pmt.getProgramNumber(); 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) { int isaudio = 0, isvideo = 0, issubtitle = 0, forced_video = 0, forced_audio = 0, isteletext = 0; int streamtype = (*es)->getType(); videoStream video; audioStream audio; audio.component_tag=video.component_tag=-1; video.type = videoStream::vtMPEG2; audio.type = audioStream::atMPEG; audio.rdsPid = -1; switch (streamtype) { case 0x1b: // AVC Video Stream (MPEG4 H264) video.type = videoStream::vtMPEG4_H264; isvideo = 1; //break; fall through !!! case 0x10: // MPEG 4 Part 2 if (!isvideo) { video.type = videoStream::vtMPEG4_Part2; isvideo = 1; } //break; fall through !!! case 0x01: // MPEG 1 video if (!isvideo) video.type = videoStream::vtMPEG1; //break; fall through !!! case 0x02: // MPEG 2 video isvideo = 1; forced_video = 1; //break; fall through !!! case 0x03: // MPEG 1 audio case 0x04: // MPEG 2 audio: if (!isvideo) { isaudio = 1; forced_audio = 1; } //break; fall through !!! case 0x0f: // MPEG 2 AAC if (!isvideo && !isaudio) { isaudio = 1; audio.type = audioStream::atAAC; forced_audio = 1; } //break; fall through !!! case 0x11: // MPEG 4 AAC if (!isvideo && !isaudio) { isaudio = 1; audio.type = audioStream::atAACHE; forced_audio = 1; } 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 bluray AC3 case 0xA1: // bluray secondary AC3 if (!isvideo && !isaudio) { isaudio = 1; audio.type = audioStream::atAC3; } case 0x82: // bluray DTS (dvb user private...) case 0xA2: // bluray secondary DTS if (!isvideo && !isaudio && is_hdmv) { isaudio = 1; audio.type = audioStream::atDTS; } case 0x85: // bluray DTS-HD HRA(dvb user private...) case 0x86: // bluray DTS-HD MA(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 { int num_descriptors = 0; for (DescriptorConstIterator desc = (*es)->getDescriptors()->begin(); desc != (*es)->getDescriptors()->end(); ++desc) { uint8_t tag = (*desc)->getTag(); /* check descriptors to get the exakt stream type. */ ++num_descriptors; if (!forced_video && !forced_audio) { switch (tag) { case AUDIO_STREAM_DESCRIPTOR: isaudio = 1; break; case VIDEO_STREAM_DESCRIPTOR: { isvideo = 1; VideoStreamDescriptor *d = (VideoStreamDescriptor*)(*desc); if (d->getMpeg1OnlyFlag()) video.type = videoStream::vtMPEG1; break; } case SUBTITLING_DESCRIPTOR: { SubtitlingDescriptor *d = (SubtitlingDescriptor*)(*desc); const SubtitlingList *list = d->getSubtitlings(); subtitleStream s; s.pid = (*es)->getPid(); for (SubtitlingConstIterator it(list->begin()); it != list->end(); ++it) { s.subtitling_type = (*it)->getSubtitlingType(); switch(s.subtitling_type) { case 0x10 ... 0x13: // dvb subtitles normal case 0x20 ... 0x23: // dvb subtitles hearing impaired break; default: eDebug("[eDVBPMTParser] dvb subtitle %s PID %04x with wrong subtitling type (%02x)... force 0x10!!", s.language_code.c_str(), s.pid, s.subtitling_type); s.subtitling_type = 0x10; break; } s.composition_page_id = (*it)->getCompositionPageId(); s.ancillary_page_id = (*it)->getAncillaryPageId(); std::string language = (*it)->getIso639LanguageCode(); s.language_code = language; // eDebug("[eDVBPMTParser] add dvb subtitle %s PID %04x, type %d, composition page %d, ancillary_page %d", s.language_code.c_str(), s.pid, s.subtitling_type, s.composition_page_id, s.ancillary_page_id); issubtitle = 1; program.subtitleStreams.push_back(s); } break; } case TELETEXT_DESCRIPTOR: if (program.textPid == -1) { subtitleStream s; s.subtitling_type = 0x01; // EBU TELETEXT SUBTITLES s.pid = program.textPid = (*es)->getPid(); TeletextDescriptor *d = (TeletextDescriptor*)(*desc); isteletext = 1; const VbiTeletextList *list = d->getVbiTeletexts(); std::string language; for (VbiTeletextConstIterator it(list->begin()); it != list->end(); ++it) { switch((*it)->getTeletextType()) { case 0x02: // Teletext subtitle page case 0x05: // Teletext subtitle page for hearing impaired pepople language = (*it)->getIso639LanguageCode(); s.language_code = language; s.teletext_page_number = (*it)->getTeletextPageNumber(); s.teletext_magazine_number = (*it)->getTeletextMagazineNumber(); // eDebug("[eDVBPMTParser] add teletext subtitle %s PID %04x, page number %d, magazine number %d", s.language_code.c_str(), s.pid, s.teletext_page_number, s.teletext_magazine_number); program.subtitleStreams.push_back(s); issubtitle=1; default: break; } } } break; case DTS_DESCRIPTOR: isaudio = 1; audio.type = audioStream::atDTS; break; case 0x2B: // TS_PSI_DT_MPEG2_AAC isaudio = 1; audio.type = audioStream::atAAC; // MPEG2-AAC break; case 0x1C: // TS_PSI_DT_MPEG4_Audio case AAC_DESCRIPTOR: isaudio = 1; audio.type = audioStream::atAACHE; // MPEG4-AAC break; case AC3_DESCRIPTOR: isaudio = 1; audio.type = audioStream::atAC3; break; case ENHANCED_AC3_DESCRIPTOR: isaudio = 1; audio.type = audioStream::atDDP; break; case REGISTRATION_DESCRIPTOR: /* some services don't have a separate AC3 descriptor */ { RegistrationDescriptor *d = (RegistrationDescriptor*)(*desc); switch (d->getFormatIdentifier()) { case 0x44545331 ... 0x44545333: // DTS1/DTS2/DTS3 isaudio = 1; audio.type = audioStream::atDTS; break; case 0x41432d33: // == 'AC-3' isaudio = 1; audio.type = audioStream::atAC3; break; case 0x42535344: // == 'BSSD' (LPCM) isaudio = 1; audio.type = audioStream::atLPCM; break; case 0x56432d31: // == 'VC-1' { const AdditionalIdentificationInfoVector *vec = d->getAdditionalIdentificationInfo(); if (vec->size() > 1 && (*vec)[0] == 0x01) // subdescriptor tag { if ((*vec)[1] >= 0x90) // profile_level video.type = videoStream::vtVC1; // advanced profile else video.type = videoStream::vtVC1_SM; // simple main isvideo = 1; } } default: break; } break; } case 0x28: // TS_PSI_DT_AVC isvideo = 1; video.type = videoStream::vtMPEG4_H264; break; case 0x1B: // TS_PSI_DT_MPEG4_Video isvideo = 1; video.type = videoStream::vtMPEG4_Part2; break; default: break; } } switch (tag) { case ISO_639_LANGUAGE_DESCRIPTOR: if (!isvideo) { const Iso639LanguageList *languages = ((Iso639LanguageDescriptor*)*desc)->getIso639Languages(); /* use last language code */ int cnt=0; for (Iso639LanguageConstIterator i=languages->begin(); i != languages->end(); ++i) { std::string language=(*i)->getIso639LanguageCode(); if ( cnt==0 ) audio.language_code = language; else audio.language_code += "/" + language; cnt++; } } break; case STREAM_IDENTIFIER_DESCRIPTOR: audio.component_tag = video.component_tag = ((StreamIdentifierDescriptor*)*desc)->getComponentTag(); break; case CA_DESCRIPTOR: { CaDescriptor *descr = (CaDescriptor*)(*desc); program::capid_pair pair; pair.caid = descr->getCaSystemId(); pair.capid = descr->getCaPid(); program.caids.push_back(pair); break; } default: break; } } if (!num_descriptors && streamtype == 0x06 && prev_audio) { prev_audio->rdsPid = (*es)->getPid(); eDebug("[eDVBPMTParser] Rds PID %04x detected ? ! ?", prev_audio->rdsPid); } prev_audio = 0; break; } case 0x05: /* ITU-T Rec. H.222.0 | ISO/IEC 13818-1 private sections */ { for (DescriptorConstIterator desc = (*es)->getDescriptors()->begin(); desc != (*es)->getDescriptors()->end(); ++desc) { switch ((*desc)->getTag()) { case APPLICATION_SIGNALLING_DESCRIPTOR: program.aitPid = (*es)->getPid(); break; } } break; } case 0x0b: /* ISO/IEC 13818-6 DSM-CC U-N Messages */ { for (DescriptorConstIterator desc = (*es)->getDescriptors()->begin(); desc != (*es)->getDescriptors()->end(); ++desc) { switch ((*desc)->getTag()) { case CAROUSEL_IDENTIFIER_DESCRIPTOR: program.dsmccPid = (*es)->getPid(); break; case STREAM_IDENTIFIER_DESCRIPTOR: break; } } break; } default: break; } if (isteletext && (isaudio || isvideo)) { eDebug("[eDVBPMTParser] ambiguous streamtype for PID %04x detected.. forced as teletext!", (*es)->getPid()); continue; // continue with next PID } else if (issubtitle && (isaudio || isvideo)) eDebug("[eDVBPMTParser] ambiguous streamtype for PID %04x detected.. forced as subtitle!", (*es)->getPid()); else if (isaudio && isvideo) eDebug("[eDVBPMTParser] ambiguous streamtype for PID %04x detected.. forced as video!", (*es)->getPid()); if (issubtitle) // continue with next PID continue; else if (isvideo) { video.pid = (*es)->getPid(); program.videoStreams.push_back(video); } else if (isaudio) { audio.pid = (*es)->getPid(); program.audioStreams.push_back(audio); prev_audio = &program.audioStreams.back(); } else continue; } } ret = 0; }
int eMMI_UI::processMMIData(int slot_id, const unsigned char *tag, const void *data, int len) { switch (tag[2]) { case 0x00: //Tmmi_close { unsigned char *d=(unsigned char*)data; int timeout=0; if (d[0] == 1) { if (len > 1) timeout = d[1]; else { eDebug("mmi close tag incorrect.. no timeout given.. assume 5 seconds"); timeout = 5; } } else if (d[0] > 1) eDebug("mmi close tag incorrect.. byte 4 should be 0 or 1"); mmiScreenClose(slot_id, timeout); break; } case 0x01: eDebug("MMI display control"); if (((unsigned char*)data)[0] != 1) eDebug("kann ich nicht. aber das sag ich dem modul nicht."); return 1; case 0x07: //Tmenu_enq { unsigned char *d=(unsigned char*)data; unsigned char *max=((unsigned char*)d) + len; int textlen = len - 2; eDebug("in enq"); if ((d+2) > max) break; int blind = *d++ & 1; int alen = *d++; eDebug("%d bytes text", textlen); if ((d+textlen) > max) break; char str[textlen + 1]; memcpy(str, ((char*)d), textlen); str[textlen] = '\0'; eDebug("enq-text: %s",str); mmiScreenEnq(slot_id, blind, alen, (char*)convertDVBUTF8(str).c_str()); break; } case 0x09: //Tmenu_last case 0x0c: //Tlist_last { unsigned char *d=(unsigned char*)data; unsigned char *max=((unsigned char*)d) + len; int pos = 0; eDebug("Tmenu_last"); if (d > max) break; int n=*d++; if(tag[2] == 0x09) //menu mmiScreenBegin(slot_id, 0); else //list mmiScreenBegin(slot_id, 1); if (n == 0xFF) n=0; else n++; eDebug("%d texts", n); for (int i=0; i < (n+3); ++i) { int textlen; if ((d+3) > max) break; eDebug("text tag: %02x %02x %02x", d[0], d[1], d[2]); d+=3; d+=eDVBCISession::parseLengthField(d, textlen); eDebug("%d bytes text", textlen); if ((d+textlen) > max) break; char str[textlen + 1]; memcpy(str, ((char*)d), textlen); str[textlen] = '\0'; mmiScreenAddText(slot_id, pos++, (char*)convertDVBUTF8(str).c_str()); eDebug("[eMMI_UI] %s", str); d += textlen; } mmiScreenFinish(slot_id); break; } default: eDebug("unknown APDU tag 9F 88 %02x", tag[2]); break; } return 0; }
void gFBDC::exec(const gOpcode *o) { switch (o->opcode) { case gOpcode::setPalette: { gDC::exec(o); setPalette(); break; } case gOpcode::flip: { if (surface_back.data_phys) { gUnmanagedSurface s(surface); surface = surface_back; surface_back = s; if (surface.data_phys > surface_back.data_phys) fb->setOffset(surface_back.y); else fb->setOffset(0); } break; } case gOpcode::waitVSync: { static timeval l; static int t; timeval now; if (t == 1000) { gettimeofday(&now, 0); int diff = (now.tv_sec - l.tv_sec) * 1000 + (now.tv_usec - l.tv_usec) / 1000; eDebug("[gFBDC] %d ms latency (%d fps)", diff, t * 1000 / (diff ? diff : 1)); l = now; t = 0; } ++t; fb->blit(); fb->waitVSync(); break; } case gOpcode::flush: #ifdef USE_LIBVUGLES2 if (gles_is_animation()) gles_do_animation(); else fb->blit(); #else fb->blit(); #endif break; case gOpcode::sendShow: { #ifdef HAVE_OSDANIMATION CFile::writeIntHex("/proc/stb/fb/animation_mode", 0x01); #endif #ifdef USE_LIBVUGLES2 gles_set_buffer((unsigned int *)surface.data); gles_set_animation(1, o->parm.setShowHideInfo->point.x(), o->parm.setShowHideInfo->point.y(), o->parm.setShowHideInfo->size.width(), o->parm.setShowHideInfo->size.height()); #endif break; } case gOpcode::sendHide: { #ifdef HAVE_OSDANIMATION CFile::writeIntHex("/proc/stb/fb/animation_mode", 0x10); #endif #ifdef USE_LIBVUGLES2 gles_set_buffer((unsigned int *)surface.data); gles_set_animation(0, o->parm.setShowHideInfo->point.x(), o->parm.setShowHideInfo->point.y(), o->parm.setShowHideInfo->size.width(), o->parm.setShowHideInfo->size.height()); #endif break; } #ifdef USE_LIBVUGLES2 case gOpcode::setView: { gles_viewport(o->parm.setViewInfo->size.width(), o->parm.setViewInfo->size.height(), fb->Stride()); break; } #endif default: gDC::exec(o); break; } }
int eDVBServiceStream::doRecord() { int err = doPrepare(); if (err) { eDebug("[eDVBServiceStream] doPrerare err %d", err); return err; } if (!m_tuned) { eDebug("[eDVBServiceStream] try it again when we are tuned in"); return 0; /* try it again when we are tuned in */ } if (!m_record && m_tuned) { ePtr<iDVBDemux> demux; if (m_service_handler.getDataDemux(demux)) { eDebug("[eDVBServiceStream] NO DEMUX available"); return -1; } demux->createTSRecorder(m_record, /*packetsize*/ 188, /*streaming*/ true); if (!m_record) { eDebug("[eDVBServiceStream] no ts recorder available."); return -1; } m_record->setTargetFD(m_target_fd); m_record->connectEvent(slot(*this, &eDVBServiceStream::recordEvent), m_con_record_event); } eDebug("[eDVBServiceStream] start streaming..."); if (recordCachedPids()) { eDebug("[eDVBServiceStream] streaming pids from cache."); return 0; } eDVBServicePMTHandler::program program; if (m_service_handler.getProgramInfo(program)) { eDebug("[eDVBServiceStream] getting program info failed."); } else { std::set<int> pids_to_record; pids_to_record.insert(0); // PAT if (program.pmtPid != -1) pids_to_record.insert(program.pmtPid); // PMT int timing_pid = -1, timing_stream_type = -1; iDVBTSRecorder::timing_pid_type timing_pid_type = iDVBTSRecorder::none; eDebugNoNewLineStart("[eDVBServiceStream] have %zd video stream(s)", program.videoStreams.size()); if (!program.videoStreams.empty()) { eDebugNoNewLine(" ("); for (std::vector<eDVBServicePMTHandler::videoStream>::const_iterator i(program.videoStreams.begin()); i != program.videoStreams.end(); ++i) { pids_to_record.insert(i->pid); if (timing_pid == -1) { timing_pid = i->pid; timing_stream_type = i->type; timing_pid_type = iDVBTSRecorder::video_pid; } if (i != program.videoStreams.begin()) eDebugNoNewLine(", "); eDebugNoNewLine("%04x", i->pid); } eDebugNoNewLine(")"); } eDebugNoNewLine(", and %zd audio stream(s)", program.audioStreams.size()); if (!program.audioStreams.empty()) { eDebugNoNewLine(" ("); for (std::vector<eDVBServicePMTHandler::audioStream>::const_iterator i(program.audioStreams.begin()); i != program.audioStreams.end(); ++i) { pids_to_record.insert(i->pid); if (timing_pid == -1) { timing_pid = i->pid; timing_stream_type = i->type; timing_pid_type = iDVBTSRecorder::audio_pid; } if (i != program.audioStreams.begin()) eDebugNoNewLine(", "); eDebugNoNewLine("%04x", i->pid); } eDebugNoNewLine(")"); } if (!program.subtitleStreams.empty()) { eDebugNoNewLine(" ("); for (std::vector<eDVBServicePMTHandler::subtitleStream>::const_iterator i(program.subtitleStreams.begin()); i != program.subtitleStreams.end(); ++i) { pids_to_record.insert(i->pid); if (i != program.subtitleStreams.begin()) eDebugNoNewLine(", "); eDebugNoNewLine("%04x", i->pid); } eDebugNoNewLine(")"); } eDebugNoNewLine(", and the pcr pid is %04x", program.pcrPid); if (program.pcrPid >= 0 && program.pcrPid < 0x1fff) pids_to_record.insert(program.pcrPid); eDebugNoNewLine(", and the text pid is %04x\n", program.textPid); if (program.textPid != -1) pids_to_record.insert(program.textPid); // Videotext if (m_stream_ecm) { for (std::list<eDVBServicePMTHandler::program::capid_pair>::const_iterator i(program.caids.begin()); i != program.caids.end(); ++i) { if (i->capid >= 0) pids_to_record.insert(i->capid); } } if (m_stream_ait) { if (program.aitPid >= 0) pids_to_record.insert(program.aitPid); } if (m_stream_eit) { pids_to_record.insert(0x12); } /* include TDT pid, really low bandwidth, should not hurt anyone */ pids_to_record.insert(0x14); recordPids(pids_to_record, timing_pid, timing_stream_type, timing_pid_type); } return 0; }
void eStreamClient::set_socket_option(int fd, int optid, int option) { if(::setsockopt(fd, SOL_SOCKET, optid, &option, sizeof(option))) eDebug("Failed to set socket option: %m"); }
int fbClass::SetMode(int nxRes, int nyRes, int nbpp) { #if defined(__sh__) xRes=nxRes; yRes=nyRes; bpp=32; m_number_of_pages = 1; topDiff=bottomDiff=leftDiff=rightDiff = 0; #else screeninfo.xres_virtual=screeninfo.xres=nxRes; screeninfo.yres_virtual=(screeninfo.yres=nyRes)*2; screeninfo.height=0; screeninfo.width=0; screeninfo.xoffset=screeninfo.yoffset=0; screeninfo.bits_per_pixel=nbpp; switch (nbpp) { case 16: // ARGB 1555 screeninfo.transp.offset = 15; screeninfo.transp.length = 1; screeninfo.red.offset = 10; screeninfo.red.length = 5; screeninfo.green.offset = 5; screeninfo.green.length = 5; screeninfo.blue.offset = 0; screeninfo.blue.length = 5; break; case 32: // ARGB 8888 screeninfo.transp.offset = 24; screeninfo.transp.length = 8; screeninfo.red.offset = 16; screeninfo.red.length = 8; screeninfo.green.offset = 8; screeninfo.green.length = 8; screeninfo.blue.offset = 0; screeninfo.blue.length = 8; break; } if (ioctl(fbFd, FBIOPUT_VSCREENINFO, &screeninfo)<0) { // try single buffering screeninfo.yres_virtual=screeninfo.yres=nyRes; if (ioctl(fbFd, FBIOPUT_VSCREENINFO, &screeninfo)<0) { perror("FBIOPUT_VSCREENINFO"); printf("fb failed\n"); return -1; } eDebug(" - double buffering not available."); } else eDebug(" - double buffering available!"); m_number_of_pages = screeninfo.yres_virtual / nyRes; #endif ioctl(fbFd, FBIOGET_VSCREENINFO, &screeninfo); #if defined(__sh__) xResSc=screeninfo.xres; yResSc=screeninfo.yres; stride=xRes*4; #else if ((screeninfo.xres!=nxRes) || (screeninfo.yres!=nyRes) || (screeninfo.bits_per_pixel!=nbpp)) { eDebug("SetMode failed: wanted: %dx%dx%d, got %dx%dx%d", nxRes, nyRes, nbpp, screeninfo.xres, screeninfo.yres, screeninfo.bits_per_pixel); } xRes=screeninfo.xres; yRes=screeninfo.yres; bpp=screeninfo.bits_per_pixel; fb_fix_screeninfo fix; if (ioctl(fbFd, FBIOGET_FSCREENINFO, &fix)<0) { perror("FBIOGET_FSCREENINFO"); printf("fb failed\n"); } stride=fix.line_length; memset(lfb, 0, stride*yRes); #endif blit(); return 0; }
void eStreamClient::set_tcp_option(int fd, int optid, int option) { if(::setsockopt(fd, SOL_TCP, optid, &option, sizeof(option))) eDebug("Failed to set TCP parameter: %m"); }
void eDVBLocalTimeHandler::updateTime( time_t tp_time, eDVBChannel *chan, int update_count ) { int time_difference; bool restart_tdt = false; if (!tp_time) restart_tdt = true; else if (tp_time == -1) { restart_tdt = true; /*if ( eSystemInfo::getInstance()->getHwType() == eSystemInfo::DM7020 || ( eSystemInfo::getInstance()->getHwType() == eSystemInfo::DM7000 && eSystemInfo::getInstance()->hasStandbyWakeupTimer() ) ) TODO !!!!!!! */ { eDebug("[eDVBLocalTimerHandler] no transponder tuned... or no TDT/TOT avail .. try to use RTC :)"); time_t rtc_time = getRTC(); if ( rtc_time ) // RTC Ready? { tm now; localtime_r(&rtc_time, &now); eDebug("[eDVBLocalTimerHandler] RTC time is %02d:%02d:%02d", now.tm_hour, now.tm_min, now.tm_sec); time_t linuxTime=time(0); localtime_r(&linuxTime, &now); eDebug("[eDVBLocalTimerHandler] Receiver time is %02d:%02d:%02d", now.tm_hour, now.tm_min, now.tm_sec); time_difference = rtc_time - linuxTime; eDebug("[eDVBLocalTimerHandler] RTC to Receiver time difference is %ld seconds", linuxTime - rtc_time ); if ( time_difference ) { eDebug("[eDVBLocalTimerHandler] set Linux Time to RTC Time"); timeval tnow; gettimeofday(&tnow,0); tnow.tv_sec=rtc_time; settimeofday(&tnow,0); } else if ( !time_difference ) eDebug("[eDVBLocalTimerHandler] no change needed"); else eDebug("[eDVBLocalTimerHandler] set to RTC time"); /*emit*/ m_timeUpdated(); } else eDebug("[eDVBLocalTimerHandler] getRTC returned time=0. RTC problem?"); } } else { std::map< eDVBChannelID, int >::iterator it( m_timeOffsetMap.find( chan->getChannelID() ) ); // current linux time time_t linuxTime = time(0); #ifdef DEBUG // current transponder time tm tp_now; localtime_r(&tp_time, &tp_now); eDebug("[eDVBLocalTimerHandler] Transponder time is %02d.%02d.%04d %02d:%02d:%02d", tp_now.tm_mday, tp_now.tm_mon + 1, tp_now.tm_year + 1900, tp_now.tm_hour, tp_now.tm_min, tp_now.tm_sec); #endif // difference between current enigma time and transponder time int enigma_diff = tp_time-linuxTime; int new_diff=0; bool updated = m_time_ready; if ( m_time_ready ) // ref time ready? { // difference between reference time (current enigma time) // and the transponder time eDebug("[eDVBLocalTimerHandler] diff is %d", enigma_diff); if ( abs(enigma_diff) < 120 ) { eDebug("[eDVBLocalTimerHandler] diff < 120 .. use Transponder Time"); m_timeOffsetMap[chan->getChannelID()] = 0; new_diff = enigma_diff; } else if ( it != m_timeOffsetMap.end() ) // correction saved? { eDebug("[eDVBLocalTimerHandler] we have correction %d", it->second); time_t CorrectedTpTime = tp_time+it->second; int ddiff = CorrectedTpTime-linuxTime; eDebug("[eDVBLocalTimerHandler] diff after add correction is %d", ddiff); if ( abs(it->second) < 300 ) // stored correction < 5 min { eDebug("[eDVBLocalTimerHandler] use stored correction(<5 min)"); new_diff = ddiff; } else if ( getRTC() ) { time_t rtc=getRTC(); m_timeOffsetMap[chan->getChannelID()] = rtc-tp_time; new_diff = rtc-linuxTime; // set enigma time to rtc eDebug("[eDVBLocalTimerHandler] update stored correction to %ld (calced against RTC time)", rtc-tp_time ); } else if ( abs(ddiff) <= 120 ) { // with stored correction calced time difference is lower 2 min // this don't help when a transponder have a clock running to slow or to fast // then its better to have a DM7020 with always running RTC eDebug("[eDVBLocalTimerHandler] use stored correction(corr < 2 min)"); new_diff = ddiff; } else // big change in calced correction.. hold current time and update correction { eDebug("[eDVBLocalTimerHandler] update stored correction to %d", -enigma_diff); m_timeOffsetMap[chan->getChannelID()] = -enigma_diff; } } else { eDebug("[eDVBLocalTimerHandler] no correction found... store calced correction(%d)",-enigma_diff); m_timeOffsetMap[chan->getChannelID()] = -enigma_diff; } } else // no time setted yet { if ( it != m_timeOffsetMap.end() ) { enigma_diff += it->second; eDebug("[eDVBLocalTimerHandler] we have correction (%d)... use", it->second ); } else eDebug("[eDVBLocalTimerHandler] dont have correction.. set Transponder Diff"); new_diff=enigma_diff; m_time_ready=true; } time_t t = linuxTime+new_diff; m_last_tp_time_difference=tp_time-t; if (!new_diff && updated) // overrride this check on first received TDT { eDebug("[eDVBLocalTimerHandler] not changed"); return; } if ( !update_count ) { // set rtc to calced transponder time when the first tdt is received on this // transponder setRTC(t); eDebug("[eDVBLocalTimerHandler] update RTC"); } else if (getRTC()) { if (abs(getRTC() - t) > 60) { eDebug("[eDVBLocalTimerHandler] difference between new linux time and RTC time is > 60 sec... transponder time looks not ok... use rtc time"); t = getRTC(); } else eDebug("[eDVBLocalTimerHandler] difference between linux time and RTC time is < 60 sec... so the transponder time looks ok"); } else eDebug("[eDVBLocalTimerHandler] no RTC available :("); tm now; localtime_r(&t, &now); eDebug("[eDVBLocalTimerHandler] time update to %02d:%02d:%02d", now.tm_hour, now.tm_min, now.tm_sec); time_difference = t - linuxTime; // calc our new linux_time -> enigma_time correction eDebug("[eDVBLocalTimerHandler] m_time_difference is %d", time_difference ); if ( time_difference ) { eDebug("[eDVBLocalTimerHandler] set Linux Time"); timeval tnow; gettimeofday(&tnow,0); tnow.tv_sec=t; settimeofday(&tnow,0); #ifdef DEBUG linuxTime=time(0); localtime_r(&linuxTime, &now); eDebug("[eDVBLocalTimerHandler] time after update is %02d:%02d:%02d", now.tm_hour, now.tm_min, now.tm_sec); #endif } /*emit*/ m_timeUpdated(); } if ( restart_tdt ) { std::map<iDVBChannel*, channel_data>::iterator it = m_knownChannels.find(chan); if ( it != m_knownChannels.end() ) { int updateCount = it->second.tdt->getUpdateCount(); it->second.tdt = 0; it->second.tdt = new TDT(chan, updateCount); it->second.tdt->startTimer(TIME_UPDATE_INTERVAL); // restart TDT for this transponder in 30min } } }
void eStreamClient::notifier(int what) { if (!(what & eSocketNotifier::Read)) return; ePtr<eStreamClient> ref = this; char buf[512]; int len; if ((len = singleRead(streamFd, buf, sizeof(buf))) <= 0) { rsn->stop(); stop(); parent->connectionLost(this); return; } request.append(buf, len); if (running || (request.find('\n') == std::string::npos)) return; if (request.substr(0, 5) == "GET /") { size_t pos; size_t posdur; if (eConfigManager::getConfigBoolValue("config.streaming.authentication")) { bool authenticated = false; if ((pos = request.find("Authorization: Basic ")) != std::string::npos) { std::string authentication, username, password; std::string hash = request.substr(pos + 21); pos = hash.find('\r'); hash = hash.substr(0, pos); authentication = base64decode(hash); pos = authentication.find(':'); if (pos != std::string::npos) { char *buffer = (char*)malloc(4096); if (buffer) { struct passwd pwd; struct passwd *pwdresult = NULL; std::string crypt; username = authentication.substr(0, pos); password = authentication.substr(pos + 1); getpwnam_r(username.c_str(), &pwd, buffer, 4096, &pwdresult); if (pwdresult) { struct crypt_data cryptdata; char *cryptresult = NULL; cryptdata.initialized = 0; crypt = pwd.pw_passwd; if (crypt == "*" || crypt == "x") { struct spwd spwd; struct spwd *spwdresult = NULL; getspnam_r(username.c_str(), &spwd, buffer, 4096, &spwdresult); if (spwdresult) { crypt = spwd.sp_pwdp; } } cryptresult = crypt_r(password.c_str(), crypt.c_str(), &cryptdata); authenticated = cryptresult && cryptresult == crypt; } free(buffer); } } } if (!authenticated) { const char *reply = "HTTP/1.0 401 Authorization Required\r\nWWW-Authenticate: Basic realm=\"streamserver\"\r\n\r\n"; writeAll(streamFd, reply, strlen(reply)); rsn->stop(); parent->connectionLost(this); return; } } pos = request.find(' ', 5); if (pos != std::string::npos) { std::string serviceref = urlDecode(request.substr(5, pos - 5)); if (!serviceref.empty()) { const char *reply = "HTTP/1.0 200 OK\r\nConnection: Close\r\nContent-Type: video/mpeg\r\nServer: streamserver\r\n\r\n"; writeAll(streamFd, reply, strlen(reply)); /* We don't expect any incoming data, so set a tiny buffer */ set_socket_option(streamFd, SO_RCVBUF, 1 * 1024); /* We like 188k packets, so set the TCP window size to that */ set_socket_option(streamFd, SO_SNDBUF, 188 * 1024); /* activate keepalive */ set_socket_option(streamFd, SO_KEEPALIVE, 1); /* configure keepalive */ set_tcp_option(streamFd, TCP_KEEPINTVL, 10); // every 10 seconds set_tcp_option(streamFd, TCP_KEEPIDLE, 1); // after 1 second of idle set_tcp_option(streamFd, TCP_KEEPCNT, 2); // drop connection after second miss /* also set 10 seconds data push timeout */ set_tcp_option(streamFd, TCP_USER_TIMEOUT, 10 * 1000); if (serviceref.substr(0, 10) == "file?file=") /* convert openwebif stream reqeust back to serviceref */ serviceref = "1:0:1:0:0:0:0:0:0:0:" + serviceref.substr(10); pos = serviceref.find('?'); if (pos == std::string::npos) { eDebug("[eDVBServiceStream] stream ref: %s", serviceref.c_str()); if (eDVBServiceStream::start(serviceref.c_str(), streamFd) >= 0) { running = true; m_serviceref = serviceref; m_useencoder = false; } } else { request = serviceref.substr(pos); serviceref = serviceref.substr(0, pos); /* BC support for ? instead of & as URL argument seperator */ while((pos = request.find('?')) != std::string::npos) { request.replace(pos, 1, "&"); } pos = request.find("&bitrate="); posdur = request.find("&duration="); eDebug("[eDVBServiceStream] stream ref: %s", serviceref.c_str()); if (posdur != std::string::npos) { if (eDVBServiceStream::start(serviceref.c_str(), streamFd) >= 0) { running = true; m_serviceref = serviceref; m_useencoder = false; } int timeout = 0; sscanf(request.substr(posdur).c_str(), "&duration=%d", &timeout); eDebug("[eDVBServiceStream] duration: %d seconds", timeout); if (timeout) { m_timeout->startLongTimer(timeout); } } else if (pos != std::string::npos) { /* we need to stream transcoded data */ int bitrate = 1024 * 1024; int width = 720; int height = 576; int framerate = 25000; int interlaced = 0; int aspectratio = 0; std::string vcodec, acodec; sscanf(request.substr(pos).c_str(), "&bitrate=%d", &bitrate); pos = request.find("&width="); if (pos != std::string::npos) sscanf(request.substr(pos).c_str(), "&width=%d", &width); pos = request.find("&height="); if (pos != std::string::npos) sscanf(request.substr(pos).c_str(), "&height=%d", &height); pos = request.find("&framerate="); if (pos != std::string::npos) sscanf(request.substr(pos).c_str(), "&framerate=%d", &framerate); pos = request.find("&interlaced="); if (pos != std::string::npos) sscanf(request.substr(pos).c_str(), "&interlaced=%d", &interlaced); pos = request.find("&aspectratio="); if (pos != std::string::npos) sscanf(request.substr(pos).c_str(), "&aspectratio=%d", &aspectratio); pos = request.find("&vcodec="); if (pos != std::string::npos) { vcodec = request.substr(pos + 8); pos = vcodec.find('&'); if (pos != std::string::npos) { vcodec = vcodec.substr(0, pos); } } pos = request.find("&acodec="); if (pos != std::string::npos) { acodec = request.substr(pos + 8); pos = acodec.find('&'); if (pos != std::string::npos) { acodec = acodec.substr(0, pos); } } encoderFd = -1; if (eEncoder::getInstance()) encoderFd = eEncoder::getInstance()->allocateEncoder(serviceref, bitrate, width, height, framerate, !!interlaced, aspectratio, vcodec, acodec); if (encoderFd >= 0) { running = true; streamThread = new eDVBRecordStreamThread(188); if (streamThread) { streamThread->setTargetFD(streamFd); streamThread->start(encoderFd); } m_serviceref = serviceref; m_useencoder = true; } } } } } } if (!running) { const char *reply = "HTTP/1.0 400 Bad Request\r\n\r\n"; writeAll(streamFd, reply, strlen(reply)); rsn->stop(); parent->connectionLost(this); return; } request.clear(); }
int eDVBServiceRecord::doPrepare() { /* allocate a ts recorder if we don't already have one. */ if (m_state == stateIdle) { eDVBServicePMTHandler::serviceType servicetype; if(tryFallbackTuner(/*REF*/m_ref, /*REF*/m_is_stream_client, m_is_pvr, m_simulate)) eDebug("ServiceRecord: fallback tuner selected"); if (m_streaming) { servicetype = m_record_ecm ? eDVBServicePMTHandler::scrambled_streamserver : eDVBServicePMTHandler::streamserver; } else { servicetype = m_record_ecm ? eDVBServicePMTHandler::scrambled_recording : eDVBServicePMTHandler::recording; } m_pids_active.clear(); m_state = statePrepared; ePtr<iTsSource> source; /* * NOTE: we do not have to create a source for simulated recordings, * we will not get to the point where the source is going to be used */ if (!m_simulate && !m_ref.path.empty()) { if (m_is_stream_client) { /* * streams are considered to be descrambled by default; * user can indicate a stream is scrambled, by using servicetype id + 0x100 */ m_descramble = (m_ref.type == eServiceFactoryDVB::id + 0x100); m_record_ecm = false; servicetype = eDVBServicePMTHandler::streamclient; eHttpStream *f = new eHttpStream(); f->open(m_ref.path.c_str()); source = ePtr<iTsSource>(f); } else { /* re-record a recording */ int packetsize = 188; eDVBMetaParser meta; if (!meta.parseFile(m_ref.path)) { std::string path = m_ref.path; m_ref = meta.m_ref; m_ref.path = path; packetsize = meta.m_packet_size; m_descramble = meta.m_scrambled; } servicetype = eDVBServicePMTHandler::offline; eRawFile *f = new eRawFile(packetsize); f->open(m_ref.path.c_str()); source = ePtr<iTsSource>(f); } } return m_service_handler.tuneExt(m_ref, source, m_ref.path.c_str(), 0, m_simulate, NULL, servicetype, m_descramble); } return 0; }
eServiceWebTS::~eServiceWebTS() { eDebug("ServiceWebTS destruct!"); stop(); }
ssize_t eM2TSFile::read(off_t offset, void *b, size_t count) { eSingleLocker l(m_lock); unsigned char tmp[192*3]; unsigned char *buf = (unsigned char*)b; size_t rd=0; offset = (offset % 188) + (offset * 192) / 188; sync: if ((offset+m_sync_offset) != m_current_offset) { // eDebug("seekTo %lld", offset+m_sync_offset); m_current_offset = lseek_internal(offset+m_sync_offset, SEEK_SET); if (m_current_offset < 0) return m_current_offset; } while (rd < count) { size_t ret; ret = ::read(m_fd, tmp, 192); if (ret < 0 || ret < 192) return rd ? rd : ret; if (tmp[4] != 0x47) { if (rd > 0) { eDebug("short read at pos %lld async!!", m_current_offset); return rd; } else { int x=0; ret = ::read(m_fd, tmp+192, 384); #if 0 eDebugNoNewLine("m2ts out of sync at pos %lld, real %lld:", offset + m_sync_offset, m_current_offset); for (; x < 192; ++x) eDebugNoNewLine(" %02x", tmp[x]); eDebug(""); x=0; #else eDebug("m2ts out of sync at pos %lld, real %lld", offset + m_sync_offset, m_current_offset); #endif for (; x < 192; ++x) { if (tmp[x] == 0x47 && tmp[x+192] == 0x47) { int add_offs = (x - 4); eDebug("sync found at pos %d, sync_offset is now %d, old was %d", x, add_offs + m_sync_offset, m_sync_offset); m_sync_offset += add_offs; goto sync; } } } } memcpy(buf+rd, tmp+4, 188); rd += 188; m_current_offset += 188; } m_sync_offset %= 188; return rd; }
int eServiceWebTS::openHttpConnection(std::string url) { std::string host; int port = 80; std::string uri; int slash = url.find("/", 7); if (slash > 0) { host = url.substr(7, slash-7); uri = url.substr(slash, url.length()-slash); } else { host = url.substr(7, url.length()-7); uri = ""; } int dp = host.find(":"); if (dp == 0) { port = atoi(host.substr(1, host.length()-1).c_str()); host = "localhost"; } else if (dp > 0) { port = atoi(host.substr(dp+1, host.length()-dp-1).c_str()); host = host.substr(0, dp); } struct hostent* h = gethostbyname(host.c_str()); if (h == NULL || h->h_addr_list == NULL) return -1; int fd = socket(PF_INET, SOCK_STREAM, 0); if (fd == -1) return -1; struct sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_addr.s_addr = *((in_addr_t*)h->h_addr_list[0]); addr.sin_port = htons(port); eDebug("connecting to %s", url.c_str()); if (connect(fd, (sockaddr*)&addr, sizeof(addr)) == -1) { std::string msg = "connect failed for: " + url; eDebug("[eServiceWebTS] %s", msg.c_str()); return -1; } std::string request = "GET "; request.append(uri).append(" HTTP/1.1\r\n"); request.append("Host: ").append(host).append("\r\n"); request.append("Accept: */*\r\n"); request.append("Connection: close\r\n"); request.append("\r\n"); //eDebug(request.c_str()); write(fd, request.c_str(), request.length()); int rc; size_t buflen = 1000; char* linebuf = (char*)malloc(1000); rc = getline(&linebuf, &buflen, fd); //eDebug("RECV(%d): %s", rc, linebuf); if (rc <= 0) { close(fd); free(linebuf); return -1; } char proto[100]; int statuscode = 0; char statusmsg[100]; rc = sscanf(linebuf, "%99s %d %99s", proto, &statuscode, statusmsg); if (rc != 3 || statuscode != 200) { eDebug("wrong response: \"200 OK\" expected.\n %d --- %d",rc,statuscode); free(linebuf); close(fd); return -1; } eDebug("proto=%s, code=%d, msg=%s", proto, statuscode, statusmsg); while (rc > 0) { rc = getline(&linebuf, &buflen, fd); //eDebug("RECV(%d): %s", rc, linebuf); } free(linebuf); return fd; }
void dump_malloc_stats(void) { struct mallinfo mi = mallinfo(); eDebug("MALLOC: %d total", mi.uordblks); }
void eStreamThreadWeb::thread() { const int bufsize = 40000; unsigned char buf[bufsize]; bool eof = false; fd_set rfds; fd_set wfds; struct timeval timeout; int rc,r,w,maxfd; time_t next_scantime = 0; bool sosSend = false; m_running = true; r = w = 0; hasStarted(); eDebug("eStreamThreadWeb started"); while (!m_stop) { pthread_testcancel(); FD_ZERO(&rfds); FD_ZERO(&wfds); maxfd = 0; timeout.tv_sec = 1; timeout.tv_usec = 0; if (r < bufsize) { FD_SET(m_srcfd, &rfds); maxfd = MAX(maxfd, m_srcfd); } if (w < r) { FD_SET(m_destfd, &wfds); maxfd = MAX(maxfd, m_destfd); } rc = select(maxfd+1, &rfds, &wfds, NULL, &timeout); if (rc == 0) { eDebug("eStreamThreadWeb::thread: timeout!"); continue; } if (rc < 0) { eDebug("eStreamThreadWeb::thread: error in select (%d)", errno); break; } if (FD_ISSET(m_srcfd, &rfds)) { rc = ::read(m_srcfd, buf+r, bufsize - r); if (rc < 0) { eDebug("eStreamThreadWeb::thread: error in read (%d)", errno); m_messagepump.send(evtReadError); break; } else if (rc == 0) { eof = true; } else { if (!sosSend) { sosSend = true; m_messagepump.send(evtSOS); } r += rc; if (r == bufsize) eDebug("eStreamThreadWeb::thread: buffer full"); } } if (FD_ISSET(m_destfd, &wfds) && (w < r) && ((r > bufsize/4) || eof)) { rc = ::write(m_destfd, buf+w, r-w); if (rc < 0) { eDebug("eStreamThreadWeb::thread: error in write (%d)", errno); m_messagepump.send(evtWriteError); break; } w += rc; //eDebug("eStreamThreadWeb::thread: buffer r=%d w=%d",r,w); if (w == r) { if (time(0) >= next_scantime) { if (scanAudioInfo(buf, r)) { m_messagepump.send(evtStreamInfo); next_scantime = time(0) + 1; } } w = r = 0; } } if (eof && (r==w)) { m_messagepump.send(evtEOS); break; } } eDebug("eStreamThreadWeb end"); }
RESULT eDVBResourceManager::allocateChannel(const eDVBChannelID &channelid, eUsePtr<iDVBChannel> &channel, bool simulate) { /* first, check if a channel is already existing. */ std::list<active_channel> &active_channels = simulate ? m_active_simulate_channels : m_active_channels; if (!simulate && m_cached_channel) { eDVBChannel *cache_chan = (eDVBChannel*)&(*m_cached_channel); if(channelid==cache_chan->getChannelID()) { eDebug("use cached_channel"); channel = m_cached_channel; return 0; } m_cached_channel_state_changed_conn.disconnect(); m_cached_channel=0; m_releaseCachedChannelTimer->stop(); } eDebugNoSimulate("allocate channel.. %04x:%04x", channelid.transport_stream_id.get(), channelid.original_network_id.get()); for (std::list<active_channel>::iterator i(active_channels.begin()); i != active_channels.end(); ++i) { eDebugNoSimulate("available channel.. %04x:%04x", i->m_channel_id.transport_stream_id.get(), i->m_channel_id.original_network_id.get()); if (i->m_channel_id == channelid) { eDebugNoSimulate("found shared channel.."); channel = i->m_channel; return 0; } } /* no currently available channel is tuned to this channelid. create a new one, if possible. */ if (!m_list) { eDebugNoSimulate("no channel list set!"); return errNoChannelList; } ePtr<iDVBFrontendParameters> feparm; if (m_list->getChannelFrontendData(channelid, feparm)) { eDebugNoSimulate("channel not found!"); return errChannelNotInList; } /* allocate a frontend. */ ePtr<eDVBAllocatedFrontend> fe; int err = allocateFrontend(fe, feparm, simulate); if (err) return err; RESULT res; ePtr<eDVBChannel> ch = new eDVBChannel(this, fe); res = ch->setChannel(channelid, feparm); if (res) { channel = 0; return errChidNotFound; } if (simulate) channel = ch; else { m_cached_channel = channel = ch; m_cached_channel_state_changed_conn = CONNECT(ch->m_stateChanged,eDVBResourceManager::DVBChannelStateChanged); } return 0; }
void eStreamThreadWeb::thread_finished() { if (m_srcfd >= 0) ::close(m_srcfd); eDebug("eStreamThreadWeb closed"); m_running = false; }
int eDVBResourceManager::canAllocateChannel(const eDVBChannelID &channelid, const eDVBChannelID& ignore, bool simulate) { std::list<active_channel> &active_channels = simulate ? m_active_simulate_channels : m_active_channels; int ret=0; if (!simulate && m_cached_channel) { eDVBChannel *cache_chan = (eDVBChannel*)&(*m_cached_channel); if(channelid==cache_chan->getChannelID()) return tuner_type_channel_default(m_list, channelid); } /* first, check if a channel is already existing. */ // eDebug("allocate channel.. %04x:%04x", channelid.transport_stream_id.get(), channelid.original_network_id.get()); for (std::list<active_channel>::iterator i(active_channels.begin()); i != active_channels.end(); ++i) { // eDebug("available channel.. %04x:%04x", i->m_channel_id.transport_stream_id.get(), i->m_channel_id.original_network_id.get()); if (i->m_channel_id == channelid) { // eDebug("found shared channel.."); return tuner_type_channel_default(m_list, channelid); } } int *decremented_cached_channel_fe_usecount=NULL, *decremented_fe_usecount=NULL; for (std::list<active_channel>::iterator i(active_channels.begin()); i != active_channels.end(); ++i) { eSmartPtrList<eDVBRegisteredFrontend> &frontends = simulate ? m_simulate_frontend : m_frontend; // eDebug("available channel.. %04x:%04x", i->m_channel_id.transport_stream_id.get(), i->m_channel_id.original_network_id.get()); if (i->m_channel_id == ignore) { eDVBChannel *channel = (eDVBChannel*) &(*i->m_channel); // one eUsePtr<iDVBChannel> is used in eDVBServicePMTHandler // another on eUsePtr<iDVBChannel> is used in the eDVBScan instance used in eDVBServicePMTHandler (for SDT scan) // so we must check here if usecount is 3 (when the channel is equal to the cached channel) // or 2 when the cached channel is not equal to the compared channel if (channel == &(*m_cached_channel) ? channel->getUseCount() == 3 : channel->getUseCount() == 2) // channel only used once.. { ePtr<iDVBFrontend> fe; if (!i->m_channel->getFrontend(fe)) { for (eSmartPtrList<eDVBRegisteredFrontend>::iterator ii(frontends.begin()); ii != frontends.end(); ++ii) { if ( &(*fe) == &(*ii->m_frontend) ) { --ii->m_inuse; decremented_fe_usecount = &ii->m_inuse; if (channel == &(*m_cached_channel)) decremented_cached_channel_fe_usecount = decremented_fe_usecount; break; } } } } break; } } if (!decremented_cached_channel_fe_usecount) { if (m_cached_channel) { eDVBChannel *channel = (eDVBChannel*) &(*m_cached_channel); if (channel->getUseCount() == 1) { ePtr<iDVBFrontend> fe; if (!channel->getFrontend(fe)) { eSmartPtrList<eDVBRegisteredFrontend> &frontends = simulate ? m_simulate_frontend : m_frontend; for (eSmartPtrList<eDVBRegisteredFrontend>::iterator ii(frontends.begin()); ii != frontends.end(); ++ii) { if ( &(*fe) == &(*ii->m_frontend) ) { --ii->m_inuse; decremented_cached_channel_fe_usecount = &ii->m_inuse; break; } } } } } } else decremented_cached_channel_fe_usecount=NULL; ePtr<iDVBFrontendParameters> feparm; if (!m_list) { eDebug("no channel list set!"); goto error; } if (m_list->getChannelFrontendData(channelid, feparm)) { eDebug("channel not found!"); goto error; } ret = canAllocateFrontend(feparm, simulate); error: if (decremented_fe_usecount) ++(*decremented_fe_usecount); if (decremented_cached_channel_fe_usecount) ++(*decremented_cached_channel_fe_usecount); return ret; }
int loadPNG(ePtr<gPixmap> &result, const char *filename) { __u8 header[8]; FILE *fp=fopen(filename, "rb"); if (!fp) { // eDebug("couldn't open %s", filename ); return 0; } if (!fread(header, 8, 1, fp)) { eDebug("couldn't read"); fclose(fp); return 0; } if (png_sig_cmp(header, 0, 8)) { fclose(fp); return 0; } png_structp png_ptr=png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0); if (!png_ptr) { eDebug("no pngptr"); fclose(fp); return 0; } png_infop info_ptr=png_create_info_struct(png_ptr); if (!info_ptr) { eDebug("no info ptr"); png_destroy_read_struct(&png_ptr, (png_infopp)0, (png_infopp)0); fclose(fp); return 0; } png_infop end_info = png_create_info_struct(png_ptr); if (!end_info) { eDebug("no end"); png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); fclose(fp); return 0; } if (setjmp(png_ptr->jmpbuf)) { eDebug("das war wohl nix"); png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); fclose(fp); result = 0; return 0; } png_init_io(png_ptr, fp); png_set_sig_bytes(png_ptr, 8); png_set_invert_alpha(png_ptr); png_read_info(png_ptr, info_ptr); png_uint_32 width, height; int bit_depth; int color_type; png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, 0, 0, 0); if (color_type == PNG_COLOR_TYPE_GRAY || color_type & PNG_COLOR_MASK_PALETTE) { result=new gPixmap(eSize(width, height), bit_depth); gSurface *surface = result->surface; png_bytep *rowptr=new png_bytep[height]; for (unsigned int i=0; i<height; i++) rowptr[i]=((png_byte*)(surface->data))+i*surface->stride; png_read_rows(png_ptr, rowptr, 0, height); delete [] rowptr; if (png_get_valid(png_ptr, info_ptr, PNG_INFO_PLTE)) { png_color *palette; int num_palette; png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette); if (num_palette) surface->clut.data=new gRGB[num_palette]; else surface->clut.data=0; surface->clut.colors=num_palette; for (int i=0; i<num_palette; i++) { surface->clut.data[i].a=0; surface->clut.data[i].r=palette[i].red; surface->clut.data[i].g=palette[i].green; surface->clut.data[i].b=palette[i].blue; } if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) { png_byte *trans; png_get_tRNS(png_ptr, info_ptr, &trans, &num_palette, 0); for (int i=0; i<num_palette; i++) surface->clut.data[i].a=255-trans[i]; } } else { surface->clut.data=0; surface->clut.colors=0; } surface->clut.start=0; png_read_end(png_ptr, end_info); } else { result=0; eDebug("%s: %dx%dx%d png, %d", filename, (int)width, (int)height, (int)bit_depth, color_type); } png_destroy_read_struct(&png_ptr, &info_ptr,&end_info); fclose(fp); return 0; }