aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorghost <andreas.monzner@multimedia-labs.de>2009-04-23 13:01:04 +0200
committerghost <andreas.monzner@multimedia-labs.de>2009-04-23 13:01:04 +0200
commit556d6244747ea2b4b3590e682948e9f708b0a069 (patch)
treed978475519d4b075c5b13547547041ea12225fef
parent41c9e42e428c0216ef2e011985c060f79fcf8ebc (diff)
downloadenigma2-556d6244747ea2b4b3590e682948e9f708b0a069.tar.gz
enigma2-556d6244747ea2b4b3590e682948e9f708b0a069.zip
Add service flags and pid cache to recordings meta file. This adds possibility to playback services without pat/pmt, now also current selected audio pid, subtitles, pcm/ac3 delays are stored for ts playbacks
-rw-r--r--lib/dvb/db.cpp76
-rw-r--r--lib/dvb/db.h1
-rw-r--r--lib/dvb/metaparser.cpp5
-rw-r--r--lib/dvb/metaparser.h11
-rw-r--r--lib/service/servicedvb.cpp82
-rw-r--r--lib/service/servicedvbrecord.cpp104
6 files changed, 169 insertions, 110 deletions
diff --git a/lib/dvb/db.cpp b/lib/dvb/db.cpp
index 647afad4..ae30e360 100644
--- a/lib/dvb/db.cpp
+++ b/lib/dvb/db.cpp
@@ -265,6 +265,42 @@ void eDVBDB::reloadServicelist()
loadServicelist(CONFIGDIR"/enigma2/lamedb");
}
+void eDVBDB::parseServiceData(ePtr<eDVBService> s, std::string str)
+{
+ while ((!str.empty()) && str[1]==':') // new: p:, f:, c:%02d...
+ {
+ size_t c=str.find(',');
+ char p=str[0];
+ std::string v;
+ if (c == std::string::npos)
+ {
+ v=str.substr(2);
+ str="";
+ } else
+ {
+ v=str.substr(2, c-2);
+ str=str.substr(c+1);
+ }
+// eDebug("%c ... %s", p, v.c_str());
+ if (p == 'p')
+ s->m_provider_name=v;
+ else if (p == 'f')
+ {
+ sscanf(v.c_str(), "%x", &s->m_flags);
+ } else if (p == 'c')
+ {
+ int cid, val;
+ sscanf(v.c_str(), "%02d%x", &cid, &val);
+ s->setCacheEntry((eDVBService::cacheID)cid,val);
+ } else if (p == 'C')
+ {
+ int val;
+ sscanf(v.c_str(), "%04x", &val);
+ s->m_ca.push_front((uint16_t)val);
+ }
+ }
+}
+
/* THIS CODE IS BAD. it should be replaced by somethine better. */
void eDVBDB::loadServicelist(const char *file)
{
@@ -425,44 +461,10 @@ void eDVBDB::loadServicelist(const char *file)
fgets(line, 256, f);
if (strlen(line))
line[strlen(line)-1]=0;
- std::string str=line;
-
- if (str[1]!=':') // old ... (only service_provider)
- {
+ if (line[1]!=':') // old ... (only service_provider)
s->m_provider_name=line;
- } else
- while ((!str.empty()) && str[1]==':') // new: p:, f:, c:%02d...
- {
- size_t c=str.find(',');
- char p=str[0];
- std::string v;
- if (c == std::string::npos)
- {
- v=str.substr(2);
- str="";
- } else
- {
- v=str.substr(2, c-2);
- str=str.substr(c+1);
- }
-// eDebug("%c ... %s", p, v.c_str());
- if (p == 'p')
- s->m_provider_name=v;
- else if (p == 'f')
- {
- sscanf(v.c_str(), "%x", &s->m_flags);
- } else if (p == 'c')
- {
- int cid, val;
- sscanf(v.c_str(), "%02d%x", &cid, &val);
- s->setCacheEntry((eDVBService::cacheID)cid,val);
- } else if (p == 'C')
- {
- int val;
- sscanf(v.c_str(), "%04x", &val);
- s->m_ca.push_front((uint16_t)val);
- }
- }
+ else
+ parseServiceData(s, line);
addService(ref, s);
}
diff --git a/lib/dvb/db.h b/lib/dvb/db.h
index 11fb1ab1..098ee03e 100644
--- a/lib/dvb/db.h
+++ b/lib/dvb/db.h
@@ -70,6 +70,7 @@ public:
void saveServicelist();
void saveServicelist(const char *file);
void reloadBouquets();
+ void parseServiceData(ePtr<eDVBService> s, std::string str);
};
#ifndef SWIG
diff --git a/lib/dvb/metaparser.cpp b/lib/dvb/metaparser.cpp
index 175c7cdb..24a5ab67 100644
--- a/lib/dvb/metaparser.cpp
+++ b/lib/dvb/metaparser.cpp
@@ -67,6 +67,9 @@ int eDVBMetaParser::parseMeta(const std::string &tsname)
case 6:
m_filesize = atoll(line);
break;
+ case 7:
+ m_service_data = line;
+ break;
default:
break;
}
@@ -145,7 +148,7 @@ int eDVBMetaParser::updateMeta(const std::string &tsname)
FILE *f = fopen(filename.c_str(), "w");
if (!f)
return -ENOENT;
- fprintf(f, "%s\n%s\n%s\n%d\n%s\n%d\n%lld\n", ref.toString().c_str(), m_name.c_str(), m_description.c_str(), m_time_create, m_tags.c_str(), m_length, m_filesize );
+ fprintf(f, "%s\n%s\n%s\n%d\n%s\n%d\n%lld\n%s\n", ref.toString().c_str(), m_name.c_str(), m_description.c_str(), m_time_create, m_tags.c_str(), m_length, m_filesize, m_service_data.c_str() );
fclose(f);
return 0;
}
diff --git a/lib/dvb/metaparser.h b/lib/dvb/metaparser.h
index 2ca94d6d..38534d8f 100644
--- a/lib/dvb/metaparser.h
+++ b/lib/dvb/metaparser.h
@@ -9,19 +9,14 @@ class eDVBMetaParser
public:
eDVBMetaParser();
int parseFile(const std::string &basename);
-
int parseMeta(const std::string &filename);
int parseRecordings(const std::string &filename);
int updateMeta(const std::string &basename);
-
- int m_data_ok;
-
+
eServiceReferenceDVB m_ref;
- std::string m_name, m_description;
- int m_time_create, m_length;
+ int m_data_ok, m_time_create, m_length;
+ std::string m_name, m_description, m_tags, m_service_data;
long long m_filesize;
-
- std::string m_tags;
};
#endif
diff --git a/lib/service/servicedvb.cpp b/lib/service/servicedvb.cpp
index 0e6229c5..2cece3eb 100644
--- a/lib/service/servicedvb.cpp
+++ b/lib/service/servicedvb.cpp
@@ -860,30 +860,41 @@ RESULT eServiceFactoryDVB::offlineOperations(const eServiceReference &ref, ePtr<
RESULT eServiceFactoryDVB::lookupService(ePtr<eDVBService> &service, const eServiceReference &ref)
{
- // TODO: handle the listing itself
- // if (ref.... == -1) .. return "... bouquets ...";
- // could be also done in another serviceFactory (with seperate ID) to seperate actual services and lists
- // TODO: cache
- ePtr<iDVBChannelList> db;
- ePtr<eDVBResourceManager> res;
-
- int err;
- if ((err = eDVBResourceManager::getInstance(res)) != 0)
+ if (!ref.path.empty()) // playback
{
- eDebug("no resource manager");
- return err;
+ eDVBMetaParser parser;
+ int ret=parser.parseFile(ref.path);
+ service = new eDVBService;
+ if (!ret)
+ eDVBDB::getInstance()->parseServiceData(service, parser.m_service_data);
}
- if ((err = res->getChannelList(db)) != 0)
+ else
{
- eDebug("no channel list");
- return err;
- }
+ // TODO: handle the listing itself
+ // if (ref.... == -1) .. return "... bouquets ...";
+ // could be also done in another serviceFactory (with seperate ID) to seperate actual services and lists
+ // TODO: cache
+ ePtr<iDVBChannelList> db;
+ ePtr<eDVBResourceManager> res;
+
+ int err;
+ if ((err = eDVBResourceManager::getInstance(res)) != 0)
+ {
+ eDebug("no resource manager");
+ return err;
+ }
+ if ((err = res->getChannelList(db)) != 0)
+ {
+ eDebug("no channel list");
+ return err;
+ }
/* we are sure to have a ..DVB reference as the info() call was forwarded here according to it's ID. */
- if ((err = db->getService((eServiceReferenceDVB&)ref, service)) != 0)
- {
- eDebug("getService failed!");
- return err;
+ if ((err = db->getService((eServiceReferenceDVB&)ref, service)) != 0)
+ {
+ eDebug("getService failed!");
+ return err;
+ }
}
return 0;
@@ -916,6 +927,29 @@ eDVBServicePlay::eDVBServicePlay(const eServiceReference &ref, eDVBService *serv
eDVBServicePlay::~eDVBServicePlay()
{
+ if (m_is_pvr)
+ {
+ eDVBMetaParser meta;
+ int ret=meta.parseFile(m_reference.path);
+ if (!ret)
+ {
+ char tmp[255];
+ meta.m_service_data="";
+ sprintf(tmp, "f:%x", m_dvb_service->m_flags);
+ meta.m_service_data += tmp;
+ // cached pids
+ for (int x=0; x < eDVBService::cacheMax; ++x)
+ {
+ int entry = m_dvb_service->getCacheEntry((eDVBService::cacheID)x);
+ if (entry != -1)
+ {
+ sprintf(tmp, ",c:%02d%04x", x, entry);
+ meta.m_service_data += tmp;
+ }
+ }
+ meta.updateMeta(m_reference.path);
+ }
+ }
delete m_subtitle_widget;
}
@@ -1028,7 +1062,7 @@ RESULT eDVBServicePlay::start()
m_first_program_info = 1;
eServiceReferenceDVB &service = (eServiceReferenceDVB&)m_reference;
- r = m_service_handler.tune(service, m_is_pvr, m_cue);
+ r = m_service_handler.tune(service, m_is_pvr, m_cue, false, m_dvb_service);
/* inject EIT if there is a stored one */
if (m_is_pvr)
@@ -1425,7 +1459,7 @@ RESULT eDVBServicePlay::getName(std::string &name)
ePtr<iStaticServiceInformation> i = new eStaticServiceDVBPVRInformation(m_reference);
return i->getName(m_reference, name);
}
- if (m_dvb_service)
+ else if (m_dvb_service)
{
m_dvb_service->getName(m_reference, name);
if (name.empty())
@@ -1708,7 +1742,7 @@ int eDVBServicePlay::selectAudioStream(int i)
anything in the best case, or destroy the default setting in
case the real default is not yet available.)
*/
- if (m_dvb_service && !m_is_pvr && ((i != -1)
+ if (m_dvb_service && ((i != -1)
|| ((m_dvb_service->getCacheEntry(eDVBService::cAPID) == -1) && (m_dvb_service->getCacheEntry(eDVBService::cAC3PID)==-1))))
{
if (apidtype == eDVBAudio::aMPEG)
@@ -2271,7 +2305,7 @@ void eDVBServicePlay::updateDecoder()
ac3_delay = m_dvb_service->getCacheEntry(eDVBService::cAC3DELAY);
pcm_delay = m_dvb_service->getCacheEntry(eDVBService::cPCMDELAY);
}
- else // subservice or recording
+ else // subservice
{
eServiceReferenceDVB ref;
m_service_handler.getServiceReference(ref);
@@ -2340,7 +2374,7 @@ void eDVBServicePlay::updateDecoder()
m_decoder->setAudioChannel(achannel);
/* don't worry about non-existing services, nor pvr services */
- if (m_dvb_service && !m_is_pvr)
+ if (m_dvb_service)
{
/* (audio pid will be set in selectAudioTrack */
m_dvb_service->setCacheEntry(eDVBService::cVPID, vpid);
diff --git a/lib/service/servicedvbrecord.cpp b/lib/service/servicedvbrecord.cpp
index 1b83a4c4..294315e9 100644
--- a/lib/service/servicedvbrecord.cpp
+++ b/lib/service/servicedvbrecord.cpp
@@ -94,61 +94,85 @@ RESULT eDVBServiceRecord::prepare(const char *filename, time_t begTime, time_t e
int ret = doPrepare();
if (!ret)
{
- eEPGCache::getInstance()->Lock();
- const eit_event_struct *event = 0;
eServiceReferenceDVB ref = m_ref.getParentServiceReference();
+ ePtr<eDVBResourceManager> res_mgr;
+ eDVBMetaParser meta;
+ std::string service_data;
if (!ref.valid())
ref = m_ref;
- if ( eit_event_id != -1 )
- {
- eDebug("query epg event id %d", eit_event_id);
- eEPGCache::getInstance()->lookupEventId(ref, eit_event_id, event);
- }
- if ( !event && (begTime != -1 && endTime != -1) )
+ if (!eDVBResourceManager::getInstance(res_mgr))
{
- time_t queryTime = begTime + ((endTime-begTime)/2);
- tm beg, end, query;
- localtime_r(&begTime, &beg);
- localtime_r(&endTime, &end);
- localtime_r(&queryTime, &query);
- eDebug("query stime %d:%d:%d, etime %d:%d:%d, qtime %d:%d:%d",
- beg.tm_hour, beg.tm_min, beg.tm_sec,
- end.tm_hour, end.tm_min, end.tm_sec,
- query.tm_hour, query.tm_min, query.tm_sec);
- eEPGCache::getInstance()->lookupEventTime(ref, queryTime, event);
- }
- if ( event )
- {
- eDebug("found event.. store to disc");
- std::string fname = filename;
- fname.erase(fname.length()-2, 2);
- fname+="eit";
- int fd = open(fname.c_str(), O_CREAT|O_WRONLY, 0777);
- if (fd>-1)
+ ePtr<iDVBChannelList> db;
+ if (!res_mgr->getChannelList(db))
{
- int evLen=HILO(event->descriptors_loop_length)+12/*EIT_LOOP_SIZE*/;
- int wr = ::write( fd, (unsigned char*)event, evLen );
- if ( wr != evLen )
- eDebug("eit write error (%m)");
- ::close(fd);
+ ePtr<eDVBService> service;
+ if (!db->getService(ref, service))
+ {
+ char tmp[255];
+ sprintf(tmp, "f:%x", service->m_flags);
+ service_data += tmp;
+ // cached pids
+ for (int x=0; x < eDVBService::cacheMax; ++x)
+ {
+ int entry = service->getCacheEntry((eDVBService::cacheID)x);
+ if (entry != -1)
+ {
+ sprintf(tmp, ",c:%02d%04x", x, entry);
+ service_data += tmp;
+ }
+ }
+ }
}
}
- eEPGCache::getInstance()->Unlock();
-
- }
- if (ret)
- return ret;
- else
- {
- eDVBMetaParser meta;
meta.m_time_create = begTime;
meta.m_ref = m_ref;
meta.m_data_ok = 1;
+ meta.m_service_data = service_data;
if (name)
meta.m_name = name;
if (descr)
meta.m_description = descr;
ret = meta.updateMeta(filename) ? -255 : 0;
+ if (!ret)
+ {
+ const eit_event_struct *event = 0;
+ eEPGCache::getInstance()->Lock();
+ if ( eit_event_id != -1 )
+ {
+ eDebug("query epg event id %d", eit_event_id);
+ eEPGCache::getInstance()->lookupEventId(ref, eit_event_id, event);
+ }
+ if ( !event && (begTime != -1 && endTime != -1) )
+ {
+ time_t queryTime = begTime + ((endTime-begTime)/2);
+ tm beg, end, query;
+ localtime_r(&begTime, &beg);
+ localtime_r(&endTime, &end);
+ localtime_r(&queryTime, &query);
+ eDebug("query stime %d:%d:%d, etime %d:%d:%d, qtime %d:%d:%d",
+ beg.tm_hour, beg.tm_min, beg.tm_sec,
+ end.tm_hour, end.tm_min, end.tm_sec,
+ query.tm_hour, query.tm_min, query.tm_sec);
+ eEPGCache::getInstance()->lookupEventTime(ref, queryTime, event);
+ }
+ if ( event )
+ {
+ eDebug("found event.. store to disc");
+ std::string fname = filename;
+ fname.erase(fname.length()-2, 2);
+ fname+="eit";
+ int fd = open(fname.c_str(), O_CREAT|O_WRONLY, 0777);
+ if (fd>-1)
+ {
+ int evLen=HILO(event->descriptors_loop_length)+12/*EIT_LOOP_SIZE*/;
+ int wr = ::write( fd, (unsigned char*)event, evLen );
+ if ( wr != evLen )
+ eDebug("eit write error (%m)");
+ ::close(fd);
+ }
+ }
+ eEPGCache::getInstance()->Unlock();
+ }
}
return ret;
}