static eServiceReferenceDVB getServiceByID(const char *id) { eTransponderList *tl=eDVB::getInstance()->settings->getTransponders(); if (!tl) return eServiceReferenceDVB(); int dvb_namespace, original_network_id, transport_stream_id, service_id, service_type; if (sscanf(id, "S:%x:%x:%x:%x:%x", &dvb_namespace, &original_network_id, &transport_stream_id, &service_id, &service_type)!=4) if (sscanf(id, "E:%x:%x:%x:%x:%x", &dvb_namespace, &original_network_id, &transport_stream_id, &service_id, &service_type)!=4) return eServiceReferenceDVB(); return eServiceReferenceDVB(eDVBNamespace(dvb_namespace), eTransportStreamID(transport_stream_id), eOriginalNetworkID(original_network_id), eServiceID(service_id), service_type); }
int eDVBMetaParser::parseMeta(const std::string &tsname) { /* if it's a PVR channel, recover service id. */ std::string filename = tsname + ".meta"; FILE *f = fopen(filename.c_str(), "r"); if (!f) return -ENOENT; int linecnt = 0; m_time_create = 0; while (1) { char line[1024]; if (!fgets(line, 1024, f)) break; if (*line && line[strlen(line)-1] == '\n') line[strlen(line)-1] = 0; if (*line && line[strlen(line)-1] == '\r') line[strlen(line)-1] = 0; switch (linecnt) { case 0: m_ref = eServiceReferenceDVB(line); break; case 1: m_name = line; break; case 2: m_description = line; break; case 3: m_time_create = atoi(line); break; case 4: m_tags = line; break; case 5: m_length = atoi(line); //movielength in pts break; case 6: m_filesize = atoll(line); break; case 7: m_service_data = line; break; default: break; } ++linecnt; } fclose(f); m_data_ok = 1; return 0; }
int eDVBMetaParser::parseRecordings(const std::string &filename) { std::string::size_type slash = filename.rfind('/'); if (slash == std::string::npos) return -1; std::string recordings = filename.substr(0, slash) + "/recordings.epl"; FILE *f = fopen(recordings.c_str(), "r"); if (!f) { // eDebug("no recordings.epl found: %s: %m", recordings.c_str()); return -1; } std::string description; eServiceReferenceDVB ref; // eDebug("parsing recordings.epl.."); while (1) { char line[1024]; if (!fgets(line, 1024, f)) break; size_t len = strlen(line); if (len < 2) // Lines with less than one char aren't meaningful continue; // Remove trailing \r\n --len; line[len] = 0; if (line[len-1] == '\r') line[len-1] = 0; if (strncmp(line, "#SERVICE: ", 10) == 0) ref = eServiceReferenceDVB(line + 10); else if (strncmp(line, "#DESCRIPTION: ", 14) == 0) description = line + 14; else if ((line[0] == '/') && (ref.path.substr(ref.path.find_last_of('/')) == filename.substr(filename.find_last_of('/')))) { // eDebug("hit! ref %s descr %s", m_ref.toString().c_str(), m_name.c_str()); m_ref = ref; m_name = description; m_description = ""; m_time_create = getctime(filename); m_length = 0; m_filesize = fileSize(filename); m_data_ok = 1; m_scrambled = 0; fclose(f); updateMeta(filename); return 0; } } fclose(f); return -1; }
int eDVBServiceStream::start(const char *serviceref, int fd) { if (m_state != stateIdle) return -1; m_ref = eServiceReferenceDVB(serviceref); if (doPrepare() < 0) return -1; m_target_fd = fd; m_want_record = 1; return doRecord(); }
int eDVBMetaParser::parseRecordings(const std::string &filename) { std::string::size_type slash = filename.rfind('/'); if (slash == std::string::npos) return -1; std::string recordings = filename.substr(0, slash) + "/recordings.epl"; FILE *f = fopen(recordings.c_str(), "r"); if (!f) { // eDebug("no recordings.epl found: %s: %m", recordings.c_str()); return -1; } std::string description; eServiceReferenceDVB ref; // eDebug("parsing recordings.epl.."); while (1) { char line[1024]; if (!fgets(line, 1024, f)) break; if (strlen(line)) line[strlen(line)-1] = 0; if (strlen(line) && line[strlen(line)-1] == '\r') line[strlen(line)-1] = 0; if (!strncmp(line, "#SERVICE: ", 10)) ref = eServiceReferenceDVB(line + 10); if (!strncmp(line, "#DESCRIPTION: ", 14)) description = line + 14; if ((line[0] == '/') && (ref.path.substr(ref.path.find_last_of('/')) == filename.substr(filename.find_last_of('/')))) { // eDebug("hit! ref %s descr %s", m_ref.toString().c_str(), m_name.c_str()); m_ref = ref; m_name = description; m_description = ""; m_time_create = 0; m_length = 0; m_filesize = fileSize(filename); m_data_ok = 1; fclose(f); updateMeta(filename.c_str()); return 0; } } fclose(f); return -1; }
int eServiceHandlerDVB::stop(int workaround) { eDVBServiceController *sapi=eDVB::getInstance()->getServiceAPI(); if (sapi) sapi->switchService(eServiceReferenceDVB()); #ifndef DISABLE_FILE if (!workaround) stopPlayback(); #endif return 0; }
RESULT eServiceMP3Record::prepare(const char *filename, time_t begTime, time_t endTime, int eit_event_id, const char *name, const char *descr, const char *tags, bool descramble, bool recordecm, int packetsize) { eDebug("[eMP3ServiceRecord] prepare filename %s", filename); m_filename = filename; if (m_state == stateIdle) { int ret = doPrepare(); if (!ret) { eDVBMetaParser meta; std::string service_data; meta.m_time_create = begTime; meta.m_ref = eServiceReferenceDVB(m_ref.toString()); meta.m_data_ok = 1; meta.m_service_data = service_data; if (name) meta.m_name = name; if (descr) meta.m_description = descr; if (tags) meta.m_tags = tags; meta.m_scrambled = recordecm; /* assume we will record scrambled data, when ecm will be included in the recording */ ret = meta.updateMeta(m_filename.c_str()) ? -255 : 0; if (!ret) { std::string fname = m_filename; fname.erase(fname.length()-6, 6); fname += "eit"; eEPGCache::getInstance()->saveEventToFile(fname.c_str(), m_ref, eit_event_id, begTime, endTime); } m_state = statePrepared; } return ret; } return -1; }
int eServiceHandlerDVB::serviceCommand(const eServiceCommand &cmd) { switch (cmd.type) { #ifndef DISABLE_FILE case eServiceCommand::cmdRecordOpen: { if (!recording) { permanentTimeshift.Stop(); playingPermanentTimeshift = 0; char *filename=reinterpret_cast<char*>(cmd.parm); current_filename=filename; eDVBServiceController *sapi=eDVB::getInstance()->getServiceAPI(); eDVB::getInstance()->recBegin(filename, sapi ? sapi->service : eServiceReferenceDVB()); delete[] (filename); recording=1; } else return -1; break; } case eServiceCommand::cmdRecordOpenPermanentTimeshift: { if (!recording) { permanentTimeshift.Start(); current_filename= permanentTimeshift.getTimeshiftPath(); playingPermanentTimeshift = 1; eDVBServiceController *sapi=eDVB::getInstance()->getServiceAPI(); eDVB::getInstance()->recBegin(current_filename.c_str(), sapi ? sapi->service : eServiceReferenceDVB()); recording=1; } else return -1; break; } case eServiceCommand::cmdRecordStart: if (recording == 1) { eDVB::getInstance()->recResume(); recording=2; } else return -1; break; case eServiceCommand::cmdRecordStop: if (recording == 2) { eDVB::getInstance()->recPause(); recording=1; } else return -1; break; case eServiceCommand::cmdRecordClose: if (recording) { permanentTimeshift.Stop(); playingPermanentTimeshift = 0; recording=0; eDVB::getInstance()->recEnd(); } else return -1; break; case eServiceCommand::cmdSetSpeed: { int parm=cmd.parm; if (!decoder && recording) { if ( parm == -1 ) // pause with must seek to begin { parm = 0; /* start paused playback */ startPlayback(current_filename, 2, true); } else startPlayback(current_filename, 1); } if ((state == statePlaying) || (state == statePause) || (state == stateStopped) || (state == stateSkipping)) { if (parm < 0 || !decoder) return -1; decoder->messages.send(eDVRPlayerThread::eDVRPlayerThreadMessage(eDVRPlayerThread::eDVRPlayerThreadMessage::setSpeed, parm)); if (parm == 0) state=statePause; else if (parm == 1 || parm == 2) state=statePlaying; else state=stateSkipping; } else return -2; break; } case eServiceCommand::cmdSkip: if (!decoder) { #ifdef TIMESHIFT if (recording && (cmd.parm < 0) ) startPlayback(current_filename, 1); else #endif return -1; } decoder->messages.send(eDVRPlayerThread::eDVRPlayerThreadMessage(eDVRPlayerThread::eDVRPlayerThreadMessage::skip, cmd.parm)); break; case eServiceCommand::cmdSeekAbsolute: if (!decoder) return -1; decoder->messages.send(eDVRPlayerThread::eDVRPlayerThreadMessage(eDVRPlayerThread::eDVRPlayerThreadMessage::seekreal, cmd.parm)); if ( cmd.parm == 0 && state == statePause ) state = stateStopped; break; case eServiceCommand::cmdSeekReal: if (!decoder) return -1; decoder->messages.send(eDVRPlayerThread::eDVRPlayerThreadMessage(eDVRPlayerThread::eDVRPlayerThreadMessage::seekreal, cmd.parm)); break; case eServiceCommand::cmdSeekBegin: if (!decoder) return -1; decoder->messages.send(eDVRPlayerThread::eDVRPlayerThreadMessage(eDVRPlayerThread::eDVRPlayerThreadMessage::seekmode, 1)); break; case eServiceCommand::cmdSeekEnd: if (!decoder) return -1; decoder->messages.send(eDVRPlayerThread::eDVRPlayerThreadMessage(eDVRPlayerThread::eDVRPlayerThreadMessage::seekmode, 0)); /* jumping to the current position after leaving seekmode avoids audio/video sync problems */ decoder->messages.send(eDVRPlayerThread::eDVRPlayerThreadMessage(eDVRPlayerThread::eDVRPlayerThreadMessage::seekreal, decoder->getPosition(1))); break; case eServiceCommand::cmdAddPermanentTimeshiftToRecording: if (recording) { permanentTimeshift.lock.lock(); int slices = permanentTimeshift.getRecordedMinutes(); eDVB::getInstance()->recSetSlice(slices); permanentTimeshift.renameAllSlices(current_filename.c_str()); if (decoder) { // currently playing timeshift file decoder->messages.send(eDVRPlayerThread::eDVRPlayerThreadMessage(eDVRPlayerThread::eDVRPlayerThreadMessage::addPermanentTimeshiftToRecording, slices)); } permanentTimeshift.lock.unlock(); } break; #endif // DISABLE_FILE default: return -1; } return 0; }
int eDVBMetaParser::parseMeta(const std::string &tsname) { /* if it's a PVR channel, recover service id. */ std::string filename = tsname + ".meta"; CFile f(filename.c_str(), "r"); if (!f) return -ENOENT; int linecnt = 0; m_time_create = 0; while (1) { char line[4096]; if (!fgets(line, 4096, f)) break; size_t len = strlen(line); if (len && line[len-1] == '\n') { --len; line[len] = 0; } if (len && line[len-1] == '\r') { --len; line[len] = 0; } switch (linecnt) { case 0: m_ref = eServiceReferenceDVB(line); break; case 1: m_name = line; break; case 2: m_description = line; break; case 3: m_time_create = atoi(line); if (m_time_create == 0) { m_time_create = getctime(tsname); } break; case 4: m_tags = line; break; case 5: m_length = atoi(line); //movielength in pts break; case 6: m_filesize = atoll(line); break; case 7: m_service_data = line; break; case 8: m_packet_size = atoi(line); if (m_packet_size <= 0) { /* invalid value, use default */ m_packet_size = 188; } break; case 9: m_scrambled = atoi(line); break; default: break; } ++linecnt; } m_data_ok = 1; return 0; }
int eDVBServiceController::switchService(const eServiceReferenceDVB &newservice) { if (newservice == service) { eDebug("is same service.."); return 0; } Decoder::Flush(1); #ifndef DISABLE_FILE eServiceReferenceDVB recRef = dvb.recorder && dvb.recorder->recRef ? dvb.recorder->recRef : eServiceReferenceDVB(); recRef.data[0] = service.getServiceType(); #endif if ( service #ifndef DISABLE_FILE // && !service.path && Decoder::locked != 2 // leave service for (timer) zap in Background && service != recRef #endif ) { // must replace faked service types.. for capmt handlers eServiceReferenceDVB ref=service; switch(ref.getServiceType()) { case 4: case 7: ref.data[0]=1; // TV break; } eDVBCaPMTClientHandler::distribute_leaveService(ref); // capmt handler call.. } /*emit*/ dvb.leaveService(service); // Linkage service handling.. if ( newservice.getServiceType()==7 && prevservice ) { parentservice = prevservice; prevservice = eServiceReferenceDVB(); } if ( !newservice ) { if ( service.getServiceType() != 7 ) prevservice=service; // save currentservice // when in 15 seconds no other dvb service is running disable frontend disableFrontendTimer.start(15*1000, true); } ///////////////////////////////// service=newservice; dvb.tEIT.start(0); // clear eit dvb.tPAT.start(0); // clear tables. dvb.tPMT.start(0); dvb.tSDT.start(0); if (service) { if ( service && !service.path ) eDVBCaPMTClientHandler::distribute_enterService(service); // capmt handler call.. dvb.event(eDVBServiceEvent(eDVBServiceEvent::eventServiceSwitch)); } switch(newservice.getServiceType()) { case 1: // tv service case 2: // radio service case 4: // nvod parent service case 7: // linkage service delete dvb.parentEIT; dvb.parentEIT = 0; break; case 5: // nvod ref service // send Parent EIT .. for osd text.. dvb.gotEIT(0,0); break; } return 1; }