std::string fontRenderClass::AddFont(const std::string &filename, const std::string &name, int scale, int renderflags) { eDebugNoNewLineStart("[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))) eDebugNoNewLineEnd(" failed: %s", strerror(error)); n->filename=filename; n->face=name; n->renderflags=renderflags; FT_Done_Face(face); n->next=font; eDebugNoNewLineEnd("OK (%s)", n->face.c_str()); font=n; return n->face; }
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__); eDebugNoNewLineStart("SESSION(%d) %02x %02x %02x (len = %d): ", session_nb, tag[0], tag[1], tag[2], len); #else eDebugNoNewLineStart("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]); eDebugNoNewLineEnd(""); if ((tag[0]==0x9f) && (tag[1]==0x80)) { switch (tag[2]) { case 0x10: // profile enquiry eDebug("cam fragt was ich kann."); state=stateProfileEnquiry; return 1; break; case 0x11: // Tprofile eDebugNoNewLineStart("mein cam kann: "); if (!len) eDebugNoNewLineEnd("nichts"); else { for (int i=0; i<len; i++) eDebugNoNewLine("%02x ", ((const unsigned char*)data)[i]); eDebugNoNewLineEnd(""); } if (state == stateFirstProfileEnquiry) { // profile change return 1; } state=stateFinal; break; default: eDebug("unknown APDU tag 9F 80 %02x", tag[2]); } } 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; }
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 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("no editable list"); else { eServiceReference ref; getCurrent(ref); if(!ref) eDebug("no valid service selected"); else { int pos = cursorGet(); eDebugNoNewLineStart("move %s to %d ", ref.toString().c_str(), pos); if (list->moveService(ref, cursorGet())) eDebugNoNewLineEnd("failed"); else eDebugNoNewLineEnd("ok"); } } } else eDebug("no list available!"); } } 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 eDVBServiceRecord::doRecord() { int err = doPrepare(); if (err) { m_error = errTuneFailed; m_event((iRecordableService*)this, evRecordFailed); return err; } if (!m_tuned) return 0; /* try it again when we are tuned in */ if (!m_record && m_tuned && !m_streaming && !m_simulate) { eDebug("Recording to %s...", m_filename.c_str()); ::remove(m_filename.c_str()); int fd = ::open(m_filename.c_str(), O_WRONLY | O_CREAT | O_LARGEFILE | O_CLOEXEC, 0666); if (fd == -1) { eDebug("eDVBServiceRecord - can't open recording file!"); m_error = errOpenRecordFile; m_event((iRecordableService*)this, evRecordFailed); return errOpenRecordFile; } ePtr<iDVBDemux> demux; if (m_service_handler.getDataDemux(demux)) { eDebug("eDVBServiceRecord - NO DEMUX available!"); m_error = errNoDemuxAvailable; m_event((iRecordableService*)this, evRecordFailed); return errNoDemuxAvailable; } demux->createTSRecorder(m_record); if (!m_record) { eDebug("eDVBServiceRecord - no ts recorder available."); m_error = errNoTsRecorderAvailable; m_event((iRecordableService*)this, evRecordFailed); return errNoTsRecorderAvailable; } m_record->setTargetFD(fd); m_record->setTargetFilename(m_filename); m_record->connectEvent(slot(*this, &eDVBServiceRecord::recordEvent), m_con_record_event); m_target_fd = fd; } if (m_streaming) { m_state = stateRecording; eDebug("start streaming..."); } else { eDebugNoNewLineStart("start recording..."); eDVBServicePMTHandler::program program; if (m_service_handler.getProgramInfo(program)) eDebug("getting program info failed."); else { std::set<int> pids_to_record; pids_to_record.insert(0); // PAT if (program.pmtPid != -1) pids_to_record.insert(program.pmtPid); // PMT int timing_pid = -1, timing_stream_type = -1; iDVBTSRecorder::timing_pid_type timing_pid_type = iDVBTSRecorder::none; eDebugNoNewLine("RECORD: have %zd video stream(s)", program.videoStreams.size()); if (!program.videoStreams.empty()) { eDebugNoNewLine(" ("); for (std::vector<eDVBServicePMTHandler::videoStream>::const_iterator i(program.videoStreams.begin()); i != program.videoStreams.end(); ++i) { pids_to_record.insert(i->pid); if (timing_pid == -1) { timing_pid = i->pid; timing_stream_type = i->type; timing_pid_type = iDVBTSRecorder::video_pid; } if (i != program.videoStreams.begin()) eDebugNoNewLine(", "); eDebugNoNewLine("%04x", i->pid); } eDebugNoNewLine(")"); } eDebugNoNewLine(", and %zd audio stream(s)", program.audioStreams.size()); if (!program.audioStreams.empty()) { eDebugNoNewLine(" ("); for (std::vector<eDVBServicePMTHandler::audioStream>::const_iterator i(program.audioStreams.begin()); i != program.audioStreams.end(); ++i) { pids_to_record.insert(i->pid); if (timing_pid == -1) { timing_pid = i->pid; timing_stream_type = i->type; timing_pid_type = iDVBTSRecorder::audio_pid; } if (i != program.audioStreams.begin()) eDebugNoNewLine(", "); eDebugNoNewLine("%04x", i->pid); } eDebugNoNewLine(")"); } if (!program.subtitleStreams.empty()) { eDebugNoNewLine(" ("); for (std::vector<eDVBServicePMTHandler::subtitleStream>::const_iterator i(program.subtitleStreams.begin()); i != program.subtitleStreams.end(); ++i) { pids_to_record.insert(i->pid); if (i != program.subtitleStreams.begin()) eDebugNoNewLine(", "); eDebugNoNewLine("%04x", i->pid); } eDebugNoNewLine(")"); } eDebugNoNewLine(", and the pcr pid is %04x", program.pcrPid); if (program.pcrPid >= 0 && program.pcrPid < 0x1fff) pids_to_record.insert(program.pcrPid); eDebugNoNewLineEnd(", and the text pid is %04x", program.textPid); if (program.textPid != -1) pids_to_record.insert(program.textPid); // Videotext if (m_record_ecm) { for (std::list<eDVBServicePMTHandler::program::capid_pair>::const_iterator i(program.caids.begin()); i != program.caids.end(); ++i) { if (i->capid >= 0) pids_to_record.insert(i->capid); } } bool include_ait = eConfigManager::getConfigBoolValue("config.recording.include_ait"); if (include_ait) { /* add AIT pid (if any) */ if (program.aitPid >= 0) pids_to_record.insert(program.aitPid); } /* find out which pids are NEW and which pids are obsolete.. */ std::set<int> new_pids, obsolete_pids; std::set_difference(pids_to_record.begin(), pids_to_record.end(), m_pids_active.begin(), m_pids_active.end(), std::inserter(new_pids, new_pids.begin())); std::set_difference( m_pids_active.begin(), m_pids_active.end(), pids_to_record.begin(), pids_to_record.end(), std::inserter(obsolete_pids, obsolete_pids.begin()) ); for (std::set<int>::iterator i(new_pids.begin()); i != new_pids.end(); ++i) { eDebug("ADD PID: %04x", *i); m_record->addPID(*i); } for (std::set<int>::iterator i(obsolete_pids.begin()); i != obsolete_pids.end(); ++i) { eDebug("REMOVED PID: %04x", *i); m_record->removePID(*i); } if (timing_pid != -1) m_record->setTimingPID(timing_pid, timing_pid_type, timing_stream_type); m_pids_active = pids_to_record; if (m_state != stateRecording) { m_record->start(); m_state = stateRecording; } } } m_error = 0; m_event((iRecordableService*)this, evRecordRunning); return 0; }
int 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); }
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("[eDVBServiceRecord] 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"); 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); ::close(fd); return errNoDemuxAvailable; } demux->createTSRecorder(m_record); if (!m_record) { eDebug("[eDVBServiceRecord] no ts recorder available."); m_error = errNoTsRecorderAvailable; m_event((iRecordableService*)this, evRecordFailed); ::close(fd); 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("[eDVBServiceRecord] start streaming..."); } else { eDebug("[eDVBServiceRecord] start recording..."); eDVBServicePMTHandler::program program; if (m_service_handler.getProgramInfo(program)) eDebug("[eDVBServiceRecord] 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("[eDVBServiceRecord] 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); eDebugNoNewLine(", and the text pid is %04x\n", 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("[eDVBServiceRecord] ADD PID: %04x", *i); m_record->addPID(*i); } for (std::set<int>::iterator i(obsolete_pids.begin()); i != obsolete_pids.end(); ++i) { eDebug("[eDVBServiceRecord] 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 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; }
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("[eM2TSFile] 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 < 192) return rd ? rd : ret; if (tmp[4] != 0x47) { if (rd > 0) { eDebug("[eM2TSFile] short read at pos %lld async!!", m_current_offset); return rd; } else { int x=0; ret = ::read(m_fd, tmp+192, 384); #if 0 eDebugNoNewLineStart("[eM2TSFile] m2ts out of sync at pos %lld, real %lld:", offset + m_sync_offset, m_current_offset); for (; x < 192; ++x) eDebugNoNewLine(" %02x", tmp[x]); eDebugNoNewLine("\n"); x=0; #else eDebug("[eM2TSFile] 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("[eM2TSFile] 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; }