int eDVBCICAManagerSession::receivedAPDU(const unsigned char *tag, const void *data, int len)
{
    eDebugNoNewLine("[CI CA] SESSION(%d)/CA %02x %02x %02x: ", session_nb, tag[0], tag[1],tag[2]);
    for (int i=0; i<len; i++)
        eDebugNoNewLine("%02x ", ((const unsigned char*)data)[i]);
    eDebugNoNewLine("\n");

    if ((tag[0]==0x9f) && (tag[1]==0x80))
    {
        switch (tag[2])
        {
        case 0x31:
            eDebugNoNewLineStart("[CI CA]ca info:");
            for (int i=0; i<len; i+=2)
            {
                eDebugNoNewLine("%04x ", (((const unsigned char*)data)[i]<<8)|(((const unsigned char*)data)[i+1]));
                caids.push_back((((const unsigned char*)data)[i]<<8)|(((const unsigned char*)data)[i+1]));
            }
            std::sort(caids.begin(), caids.end());
            eDebugNoNewLine("\n");
            eDVBCIInterfaces::getInstance()->recheckPMTHandlers();
            break;
        default:
            eDebug("[CI CA] unknown APDU tag 9F 80 %02x", tag[2]);
            break;
        }
    }
    return 0;
}
示例#2
0
int eDVBCIResourceManagerSession::receivedAPDU(const unsigned char *tag,const void *data, int len)
{
#ifdef __sh__
	eDebug("eDVBCIResourceManagerSession::%s >", __func__);
	eDebugNoNewLine("SESSION(%d) %02x %02x %02x (len = %d): ", session_nb, tag[0], tag[1], tag[2], len);
#else
	eDebugNoNewLine("SESSION(%d) %02x %02x %02x: ", session_nb, tag[0], tag[1], tag[2]);
#endif
	for (int i=0; i<len; i++)
		eDebugNoNewLine("%02x ", ((const unsigned char*)data)[i]);
	eDebug("");
	if ((tag[0]==0x9f) && (tag[1]==0x80))
	{
		switch (tag[2])
		{
		case 0x10:  // profile enquiry
			eDebug("cam fragt was ich kann.");
			state=stateProfileEnquiry;
#ifdef __sh__
			eDebug("%s <", __func__);
#endif
			return 1;
			break;
		case 0x11: // Tprofile
			eDebugNoNewLine("mein cam kann: ");
			if (!len)
				eDebug("nichts");
			else
				for (int i=0; i<len; i++)
					eDebugNoNewLine("%02x ", ((const unsigned char*)data)[i]);

			if (state == stateFirstProfileEnquiry)
			{
#ifdef __sh__
				eDebug("%s <", __func__);
#endif
				// profile change
				return 1;
			}
			state=stateFinal;
			break;
		default:
			eDebug("unknown APDU tag 9F 80 %02x", tag[2]);
		}
	}
	
#ifdef __sh__
	eDebug("%s <", __func__);
#endif
	return 0;
}
示例#3
0
文件: font.cpp 项目: Anubisko/enigma2
std::string fontRenderClass::AddFont(const std::string &filename, const std::string &name, int scale, int renderflags)
{
	eDebugNoNewLine("[FONT] adding font %s...", filename.c_str());
	fflush(stdout);
	int error;
	fontListEntry *n=new fontListEntry;

	n->scale=scale;
	FT_Face face;
	singleLock s(ftlock);

	if ((error=FT_New_Face(library, filename.c_str(), 0, &face)))
		eFatal(" failed: %s", strerror(error));

	n->filename=filename;
	n->face=name;
	n->renderflags=renderflags;
	FT_Done_Face(face);

	n->next=font;
	eDebug("OK (%s)", n->face.c_str());
	font=n;

	return n->face;
}
示例#4
0
int eListboxServiceContent::setCurrentMarked(bool state)
{
	bool prev = m_current_marked;
	m_current_marked = state;

	if (state != prev && m_listbox)
	{
		m_listbox->entryChanged(cursorResolve(m_cursor_number));
		if (!state)
		{
			if (!m_lst)
				m_service_center->list(m_root, m_lst);
			if (m_lst)
			{
				ePtr<iMutableServiceList> list;
				if (m_lst->startEdit(list))
					eDebug("[eListboxServiceContent] no editable list");
				else
				{
					eServiceReference ref;
					getCurrent(ref);
					if(!ref)
						eDebug("[eListboxServiceContent] no valid service selected");
					else
					{
						int pos = cursorGet();
						eDebugNoNewLineStart("[eListboxServiceContent] move %s to %d ", ref.toString().c_str(), pos);
						if (list->moveService(ref, cursorGet()))
							eDebugNoNewLine("failed\n");
						else
							eDebugNoNewLine("ok\n");
					}
				}
			}
			else
				eDebug("[eListboxServiceContent] no list available!");
		}
	}

	return 0;
}
示例#5
0
int eDVBCIResourceManagerSession::receivedAPDU(const unsigned char *tag,const void *data, int len)
{
	eDebugNoNewLineStart("[CI RM] SESSION(%d) %02x %02x %02x: ", session_nb, tag[0], tag[1], tag[2]);
	for (int i=0; i<len; i++)
		eDebugNoNewLine("%02x ", ((const unsigned char*)data)[i]);
	eDebugNoNewLine("\n");
	if ((tag[0]==0x9f) && (tag[1]==0x80))
	{
		switch (tag[2])
		{
		case 0x10:  // profile enquiry
			eDebug("[CI RM] cam profile inquiry");
			state=stateProfileEnquiry;
			return 1;
			break;
		case 0x11: // Tprofile
			eDebugNoNewLineStart("[CI RM] can do: ");
			if (!len)
				eDebugNoNewLine("nothing");
			else
			{
				for (int i=0; i<len; i++)
					eDebugNoNewLine("%02x ", ((const unsigned char*)data)[i]);
				eDebugNoNewLine("\n");
			}
			if (state == stateFirstProfileEnquiry)
			{
				// profile change
				return 1;
			}
			state=stateFinal;
			break;
		default:
			eDebug("[CI RM] unknown APDU tag 9F 80 %02x", tag[2]);
		}
	}

	return 0;
}
示例#6
0
文件: bsod.cpp 项目: TitanNit/tdt
void oops(const mcontext_t &context, int dumpcode)
{
	eDebug("PC: %08lx", (unsigned long)context.pc);
	int i;
	for (i=0; i<32; ++i)
	{
		eDebugNoNewLine(" %08x", (int)context.gregs[i]);
		if ((i&3) == 3)
			eDebug("");
	}
		/* this is temporary debug stuff. */
	if (dumpcode && ((unsigned long)context.pc) > 0x10000) /* not a zero pointer */
	{
		eDebug("As a final action, i will try to dump a bit of code.");
		eDebug("I just hope that this won't crash.");
		int i;
		eDebugNoNewLine("%08lx:", (unsigned long)context.pc);
		for (i=0; i<0x20; ++i)
			eDebugNoNewLine(" %02x", ((unsigned char*)context.pc)[i]);
		eDebug(" (end)");
	}
}
示例#7
0
int eDVBCIMMISession::receivedAPDU(const unsigned char *tag, const void *data, int len)
{
	eDebugNoNewLineStart("SESSION(%d)/MMI %02x %02x %02x: ", session_nb, tag[0], tag[1],tag[2]);
	for (int i=0; i<len; i++)
		eDebugNoNewLine("%02x ", ((const unsigned char*)data)[i]);
	eDebugNoNewLineEnd("");

	if ((tag[0]==0x9f) && (tag[1]==0x88))
		if (eDVBCI_UI::getInstance()->processMMIData(slot->getSlotID(), tag, data, len) == 1)
		{
			state=stateDisplayReply;
			return 1;
		}

	return 0;
}
int eDVBCIDateTimeSession::receivedAPDU(const unsigned char *tag,const void *data, int len)
{
	eDebugNoNewLineStart("SESSION(%d)/DATETIME %02x %02x %02x: ", session_nb, tag[0],tag[1], tag[2]);
	for (int i=0; i<len; i++)
		eDebugNoNewLine("%02x ", ((const unsigned char*)data)[i]);
	eDebugEOL();

	if ((tag[0]==0x9f) && (tag[1]==0x84))
	{
		switch (tag[2])
		{
		case 0x40:
			state=stateSendDateTime;
			return 1;
			break;
		default:
			eDebug("unknown APDU tag 9F 84 %02x", tag[2]);
			break;
		}
	}
	return 0;
}
int eDVBCIApplicationManagerSession::receivedAPDU(const unsigned char *tag,const void *data, int len)
{
	eDebugNoNewLine("[CI AM] SESSION(%d)/APP %02x %02x %02x: ", session_nb, tag[0], tag[1], tag[2]);
	for (int i=0; i<len; i++)
		eDebugNoNewLine("%02x ", ((const unsigned char*)data)[i]);
	eDebugNoNewLine("\n");

	if ((tag[0]==0x9f) && (tag[1]==0x80))
	{
		switch (tag[2])
		{
		case 0x21:
		{
			int dl;
			eDebug("[CI AM] application info:");
			eDebug("[CI AM]   len: %d", len);
			eDebug("[CI AM]   application_type: %d", ((unsigned char*)data)[0]);
			eDebug("[CI AM]   application_manufacturer: %02x %02x", ((unsigned char*)data)[2], ((unsigned char*)data)[1]);
			eDebug("[CI AM]   manufacturer_code: %02x %02x", ((unsigned char*)data)[4],((unsigned char*)data)[3]);
			dl=((unsigned char*)data)[5];
			if ((dl + 6) > len)
			{
				eDebug("[CI AM] warning, invalid length (%d vs %d)", dl+6, len);
				dl=len-6;
			}
			char str[dl + 1];
			memcpy(str, ((char*)data) + 6, dl);
			str[dl] = '\0';
			eDebugNoNewLine("[CI AM]   menu string: ");
			for (int i = 0; i < dl; ++i)
				eDebugNoNewLine("%c", ((unsigned char*)data)[i+6]);
			eDebugNoNewLine("\n");

			eDVBCI_UI::getInstance()->setAppName(slot->getSlotID(), str);

			eDVBCI_UI::getInstance()->setState(slot->getSlotID(), 2);
			break;
		}
		default:
			eDebug("[CI AM] unknown APDU tag 9F 80 %02x", tag[2]);
			break;
		}
	}
	return 0;
}
示例#10
0
int eDVBServiceStream::doRecord()
{
	int err = doPrepare();
	if (err)
	{
		return err;
	}
	
	if (!m_tuned)
		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("start streaming...");

	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("STREAM: 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);
		eDebug(", and the text pid is %04x", 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);

			/* 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;
		}
	}

	return 0;
}
示例#11
0
void CAService::buildCAPMT( PMT *pmt )
{
    // std::cout << "[CAService] buildCAPMT" << std::endl;
    if ( !capmt )
        capmt = new unsigned char[1024];

    memcpy(capmt,"\x9f\x80\x32\x82\x00\x00", 6);

    capmt[6]=lastPMTVersion==-1 ? LIST_ONLY : LIST_UPDATE;
    capmt[7]=(unsigned char)((pmt->program_number>>8) & 0xff);			//prg-nr
    capmt[8]=(unsigned char)(pmt->program_number & 0xff);					//prg-nr

    capmt[9]=pmt->version;	//reserved - version - current/next
    capmt[10]=0x00;	//reserved - prg-info len
    capmt[11]=0x00;	//prg-info len

    capmt[12]=CMD_OK_DESCRAMBLING;  // ca pmt command id
    capmt[13]=0x81;  // private descr.. dvbnamespace
    capmt[14]=0x08;
    capmt[15]=me.getDVBNamespace().get()>>24;
    capmt[16]=(me.getDVBNamespace().get()>>16)&0xFF;
    capmt[17]=(me.getDVBNamespace().get()>>8)&0xFF;
    capmt[18]=me.getDVBNamespace().get()&0xFF;
    capmt[19]=me.getTransportStreamID().get()>>8;
    capmt[20]=me.getTransportStreamID().get()&0xFF;
    capmt[21]=me.getOriginalNetworkID().get()>>8;
    capmt[22]=me.getOriginalNetworkID().get()&0xFF;

    capmt[23]=0x82;  // demuxer kram..
    capmt[24]=0x02;

    switch(eSystemInfo::getInstance()->getHwType())
    {
    case eSystemInfo::DM7000:
    case eSystemInfo::DM7020:
        capmt[25]=0x03;  // descramble on demux0 and demux1
        capmt[26]=0x01;  // get section data from demux1
        break;
    case eSystemInfo::DM500PLUS: /* DM500 only has one demux */
    case eSystemInfo::DM600PVR: /* DM600 only has one demux */
        capmt[25]=0x01;  // descramble on demux0 // demux 1 is just a fake demux 0
        capmt[26]=0x01;  // get section data from demux1
        break;
    default:
        capmt[25]=0x01;  // only descramble on demux0
        capmt[26]=0x00;  // get section data from demux0
        break;
    }

    capmt[27]=0x84;  // pmt pid
    capmt[28]=0x02;
    capmt[29]=pmt->pid>>8;
    capmt[30]=pmt->pid&0xFF;

    lastPMTVersion=pmt->version;
    int lenpos=10;
    int len=19;
    int first=0;
    int wp=31;

    // program_info
    for (ePtrList<Descriptor>::const_iterator i(pmt->program_info);
            i != pmt->program_info.end(); ++i)
    {
        if (i->Tag()==9)	// CADescriptor
        {
            CADescriptor *ca=(CADescriptor*)*i;
            memcpy(capmt+wp, ca->data, ca->data[1]+2);
            wp+=ca->data[1]+2;
            len+=ca->data[1]+2;
        }
    }

    for (ePtrList<PMTEntry>::iterator i(pmt->streams); i != pmt->streams.end(); ++i)
    {
        PMTEntry *pe=*i;

        first=1;
        capmt[lenpos]=((len & 0xf00)>>8);
        capmt[lenpos+1]=(len & 0xff);
        len=0;
        lenpos=wp+3;
        first=1;
        capmt[wp++]=(pe->stream_type & 0xffff);
        capmt[wp++]=((pe->elementary_PID >> 8) & 0xff);
        capmt[wp++]=(pe->elementary_PID & 0xff);
        wp+=2;

        switch (pe->stream_type)
        {
        case 1: // ISO/IEC 11172 Video
        case 2: // ITU-T Rec. H.262 | ISO/IEC 13818-2 Video or ISO/IEC 11172-2 constrained parameter video stream
        case 3: // ISO/IEC 11172 Audio
        case 4: // ISO/IEC 13818-3 Audio
        case 0x80:
        case 0x81:
        case 0x82:
        case 0x83:
        case 6: // private stream ( ttx or AC3 or DTS )
            for (ePtrList<Descriptor>::const_iterator i(pe->ES_info);
                    i != pe->ES_info.end(); ++i)
            {
                if (i->Tag()==9)	// CADescriptor
                {
                    CADescriptor *ca=(CADescriptor*)*i;
                    if(first)
                    {
                        first=0;
                        capmt[wp++]=0x01;				//ca_pmt_command_id
                        len++;
                    }
                    memcpy(capmt+wp, ca->data, ca->data[1]+2);
                    wp+=ca->data[1]+2;
                    len+=ca->data[1]+2;
                }
            }
        default:
            break;
        }
    }
    capmt[lenpos]=((len & 0xf00)>>8);
    capmt[lenpos+1]=(len & 0xff);

    capmt[4]=((wp-6)>>8) & 0xff;
    capmt[5]=(wp-6) & 0xff;

#if 0
    for(int i=0; i<wp; i++)
        eDebugNoNewLine("%02x ",capmt[i]);
    eDebug("");
#endif
}
示例#12
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, 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
	{
		eDebug("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);
			eDebug(", 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);
				}
			}

				/* find out which pids are NEW and which pids are obsolete.. */
			std::set<int> new_pids, obsolete_pids;

			std::set_difference(pids_to_record.begin(), pids_to_record.end(), 
					m_pids_active.begin(), m_pids_active.end(),
					std::inserter(new_pids, new_pids.begin()));

			std::set_difference(
					m_pids_active.begin(), m_pids_active.end(),
					pids_to_record.begin(), pids_to_record.end(), 
					std::inserter(obsolete_pids, obsolete_pids.begin())
					);
			
			for (std::set<int>::iterator i(new_pids.begin()); i != new_pids.end(); ++i)
			{
				eDebug("ADD PID: %04x", *i);
				m_record->addPID(*i);
			}

			for (std::set<int>::iterator i(obsolete_pids.begin()); i != obsolete_pids.end(); ++i)
			{
				eDebug("REMOVED PID: %04x", *i);
				m_record->removePID(*i);
			}

			if (timing_pid != -1)
				m_record->setTimingPID(timing_pid, timing_pid_type, timing_stream_type);

			m_pids_active = pids_to_record;

			if (m_state != stateRecording)
			{
				m_record->start();
				m_state = stateRecording;
			}
		}
	}
	m_error = 0;
	m_event((iRecordableService*)this, evRecordRunning);
	return 0;
}
int 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;
}
示例#14
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;

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

            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;
            }
        }
    }
示例#15
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)
	{
#if defined(__sh__) 
		int flags = O_WRONLY|O_CREAT|O_LARGEFILE;
		struct statfs sbuf;
#endif
		eDebug("Recording to %s...", m_filename.c_str());
		::remove(m_filename.c_str());
#if defined(__sh__)
		//nit2005, we must creat a file for statfs
 		int fd = ::open(m_filename.c_str(), O_WRONLY|O_CREAT|O_LARGEFILE, 0644);
		::close(fd);
		if (statfs(m_filename.c_str(), &sbuf) < 0) 
		{ 
			eDebug("eDVBServiceRecord - can't get fs type assuming none NFS!"); 
		} else 
		{ 
			if (sbuf.f_type == EXT3_SUPER_MAGIC) 
				eDebug("eDVBServiceRecord - Ext2/3/4 Filesystem\n"); 
			else 
			if (sbuf.f_type == NFS_SUPER_MAGIC) 
			{ 
				eDebug("eDVBServiceRecord - NFS Filesystem; add O_DIRECT to flags\n"); 
				flags |= O_DIRECT; 
			} 
			else 
			if (sbuf.f_type == USBDEVICE_SUPER_MAGIC) 
				eDebug("eDVBServiceRecord - USB Device\n"); 
			else 
			if (sbuf.f_type == SMB_SUPER_MAGIC) 
				eDebug("eDVBServiceRecord - SMBs Device\n"); 
			else 
			if (sbuf.f_type == MSDOS_SUPER_MAGIC) 
				eDebug("eDVBServiceRecord - MSDOS Device\n"); 
		} 

		fd = ::open(m_filename.c_str(), flags, 0644); 
#else
		int fd = ::open(m_filename.c_str(), O_WRONLY|O_CREAT|O_LARGEFILE, 0644);
#endif
		if (fd == -1)
		{
			eDebug("eDVBServiceRecord - can't open recording file!");
			m_error = errOpenRecordFile;
			m_event((iRecordableService*)this, evRecordFailed);
			return errOpenRecordFile;
		}

			/* turn off kernel caching strategies */
		posix_fadvise(fd, 0, 0, POSIX_FADV_RANDOM);

		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.c_str());
		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
	{
		eDebug("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_pid_type = -1;

			eDebugNoNewLine("RECORD: have %d 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_pid_type = i->type;
					}
					
					if (i != program.videoStreams.begin())
							eDebugNoNewLine(", ");
					eDebugNoNewLine("%04x", i->pid);
				}
				eDebugNoNewLine(")");
			}
			eDebugNoNewLine(", and %d 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_pid_type = -1;
					}
				
					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 != 0x1fff)
				pids_to_record.insert(program.pcrPid);
			eDebug(", and the text pid is %04x", program.textPid);
			if (program.textPid != -1)
				pids_to_record.insert(program.textPid); // Videotext

				/* 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);

			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;
}
示例#16
0
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;
}
示例#17
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
	{
		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);
				}
			}
		}

		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("STREAM: 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_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);
	}