Beispiel #1
0
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);
		}
	}
}
Beispiel #2
0
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;
}
Beispiel #3
0
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;
}
Beispiel #5
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;
}
Beispiel #6
0
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;
}
Beispiel #7
0
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);
}
Beispiel #8
0
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);
				}
			}
		}
Beispiel #9
0
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 &region)
{
	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);
}
Beispiel #10
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();
}
Beispiel #11
0
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;
	}
Beispiel #13
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;
}
Beispiel #14
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;
}
Beispiel #16
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");
}
Beispiel #17
0
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;
}
Beispiel #18
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");
}
Beispiel #19
0
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
		}
	}
}
Beispiel #20
0
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;
}
Beispiel #22
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;
}
Beispiel #24
0
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;
}
Beispiel #25
0
void dump_malloc_stats(void)
{
	struct mallinfo mi = mallinfo();
	eDebug("MALLOC: %d total", mi.uordblks);
}
Beispiel #26
0
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");
}
Beispiel #27
0
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;
}
Beispiel #28
0
void eStreamThreadWeb::thread_finished() {
	if (m_srcfd >= 0)
		::close(m_srcfd);
	eDebug("eStreamThreadWeb closed");
	m_running = false;
}
Beispiel #29
0
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;
}
Beispiel #30
0
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;
}