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; }
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; }
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; }
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; }
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; }
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)"); } }
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; }
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; }
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 }
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; }
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; } } }
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; }
ssize_t eM2TSFile::read(off_t offset, void *b, size_t count) { eSingleLocker l(m_lock); unsigned char tmp[192*3]; unsigned char *buf = (unsigned char*)b; size_t rd=0; offset = (offset % 188) + (offset * 192) / 188; sync: if ((offset+m_sync_offset) != m_current_offset) { // eDebug("seekTo %lld", offset+m_sync_offset); m_current_offset = lseek_internal(offset+m_sync_offset, SEEK_SET); if (m_current_offset < 0) return m_current_offset; } while (rd < count) { size_t ret; ret = ::read(m_fd, tmp, 192); if (ret < 0 || ret < 192) return rd ? rd : ret; if (tmp[4] != 0x47) { if (rd > 0) { eDebug("short read at pos %lld async!!", m_current_offset); return rd; } else { int x=0; ret = ::read(m_fd, tmp+192, 384); #if 0 eDebugNoNewLine("m2ts out of sync at pos %lld, real %lld:", offset + m_sync_offset, m_current_offset); for (; x < 192; ++x) eDebugNoNewLine(" %02x", tmp[x]); eDebug(""); x=0; #else eDebug("m2ts out of sync at pos %lld, real %lld", offset + m_sync_offset, m_current_offset); #endif for (; x < 192; ++x) { if (tmp[x] == 0x47 && tmp[x+192] == 0x47) { int add_offs = (x - 4); eDebug("sync found at pos %d, sync_offset is now %d, old was %d", x, add_offs + m_sync_offset, m_sync_offset); m_sync_offset += add_offs; goto sync; } } } } memcpy(buf+rd, tmp+4, 188); rd += 188; m_current_offset += 188; } m_sync_offset %= 188; return rd; }
int 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); }