1 #include <lib/base/init_num.h>
2 #include <lib/base/init.h>
3 #include <lib/service/servicem2ts.h>
5 DEFINE_REF(eServiceFactoryM2TS)
7 class eM2TSFile: public iDataSource
9 DECLARE_REF(eM2TSFile);
12 eM2TSFile(const char *filename, bool cached=false);
16 off_t lseek(off_t offset, int whence);
17 ssize_t read(off_t offset, void *buf, size_t count);
21 int m_fd; /* for uncached */
22 FILE *m_file; /* for cached */
23 off_t m_current_offset, m_length;
25 off_t lseek_internal(off_t offset, int whence);
28 DEFINE_REF(eM2TSFile);
30 eM2TSFile::eM2TSFile(const char *filename, bool cached)
31 :m_lock(false), m_fd(-1), m_file(NULL), m_current_offset(0), m_length(0), m_cached(cached)
33 eDebug("eM2TSFile %p %s", this, filename);
35 m_fd = ::open(filename, O_RDONLY | O_LARGEFILE);
37 m_file = ::fopen64(filename, "rb");
39 m_current_offset = m_length = lseek_internal(0, SEEK_END);
42 eM2TSFile::~eM2TSFile()
44 eDebug("~eM2TSFile %p", this);
61 off_t eM2TSFile::lseek(off_t offset, int whence)
63 eSingleLocker l(m_lock);
65 offset = offset * 192 / 188;
66 ASSERT(!(offset % 192));
68 if (offset != m_current_offset)
69 m_current_offset = lseek_internal(offset, whence);
71 return m_current_offset;
74 off_t eM2TSFile::lseek_internal(off_t offset, int whence)
79 ret = ::lseek(m_fd, offset, whence);
82 if (::fseeko(m_file, offset, whence) < 0)
84 ret = ::ftello(m_file);
86 return ret <= 0 ? ret : ret*188/192;
89 ssize_t eM2TSFile::read(off_t offset, void *b, size_t count)
91 eSingleLocker l(m_lock);
92 unsigned char tmp[192];
93 unsigned char *buf = (unsigned char*)b;
96 offset = offset * 192 / 188;
97 ASSERT(!(offset % 192));
99 ASSERT(!(count % 188));
101 if (offset != m_current_offset)
103 m_current_offset = lseek_internal(offset, SEEK_SET);
104 if (m_current_offset < 0)
105 return m_current_offset;
111 ret = ::read(m_fd, tmp, 192);
113 ret = ::fread(tmp, 1, 192, m_file);
115 m_current_offset += ret;
116 if (ret < 0 || ret < 192)
117 return rd ? rd : ret;
118 memcpy(buf+rd, tmp+4, 188);
125 int eM2TSFile::valid()
133 off_t eM2TSFile::length()
138 eServiceFactoryM2TS::eServiceFactoryM2TS()
140 ePtr<eServiceCenter> sc;
141 eDebug("!!!!!!!!!!!!!!!!!!!eServiceFactoryM2TS");
142 eServiceCenter::getPrivInstance(sc);
145 std::list<std::string> extensions;
146 extensions.push_back("m2ts");
147 extensions.push_back("mts");
148 sc->addServiceFactory(eServiceFactoryM2TS::id, this, extensions);
152 eServiceFactoryM2TS::~eServiceFactoryM2TS()
154 ePtr<eServiceCenter> sc;
156 eServiceCenter::getPrivInstance(sc);
158 sc->removeServiceFactory(eServiceFactoryM2TS::id);
161 RESULT eServiceFactoryM2TS::play(const eServiceReference &ref, ePtr<iPlayableService> &ptr)
163 ptr = new eServiceM2TS(ref);
167 RESULT eServiceFactoryM2TS::record(const eServiceReference &ref, ePtr<iRecordableService> &ptr)
173 RESULT eServiceFactoryM2TS::list(const eServiceReference &ref, ePtr<iListableService> &ptr)
179 RESULT eServiceFactoryM2TS::info(const eServiceReference &ref, ePtr<iStaticServiceInformation> &ptr)
184 RESULT eServiceFactoryM2TS::offlineOperations(const eServiceReference &ref, ePtr<iServiceOfflineOperations> &ptr)
190 eServiceM2TS::eServiceM2TS(const eServiceReference &ref)
191 :eDVBServicePlay(ref, NULL)
193 eDebug("eServiceM2TS %p", this);
196 eServiceM2TS::~eServiceM2TS()
198 eDebug("~eServiceM2TS %p", this);
201 ePtr<iDataSource> eServiceM2TS::createDataSource(const eServiceReferenceDVB &ref)
203 ePtr<iDataSource> source = new eM2TSFile(ref.path.c_str());
207 eAutoInitPtr<eServiceFactoryM2TS> init_eServiceFactoryM2TS(eAutoInitNumbers::service+1, "eServiceFactoryM2TS");