<Text Include="ReadMe.txt" />\r
</ItemGroup>\r
<ItemGroup>\r
- <ClInclude Include="..\src\mpeg2\ts\Analyzer.h" />\r
- <ClInclude Include="..\src\mpeg2\ts\const.h" />\r
+ <ClInclude Include="..\src\mpeg2\ts\Demultiplexer.h" />\r
<ClInclude Include="..\src\mpeg2\ts\EIT.h" />\r
<ClInclude Include="..\src\mpeg2\ts\Header.h" />\r
<ClInclude Include="..\src\mpeg2\ts\PAT.h" />\r
<ClInclude Include="..\src\Raym\URLResponse.h" />\r
<ClInclude Include="..\src\Raym\Workspace.h" />\r
<ClInclude Include="..\src\ry0\device\TunerFactory.h" />\r
+ <ClInclude Include="..\src\ry0\iPTd\Analyzer.h" />\r
<ClInclude Include="..\src\ry0\iPTd\CommandRunner.h" />\r
<ClInclude Include="..\src\ry0\iPTd\Controller.h" />\r
<ClInclude Include="..\src\ry0\iPTd\FFmpeg.h" />\r
<ClInclude Include="targetver.h" />\r
</ItemGroup>\r
<ItemGroup>\r
- <ClCompile Include="..\src\mpeg2\ts\Analyzer.cpp" />\r
+ <ClCompile Include="..\src\mpeg2\ts\Demultiplexer.cpp" />\r
<ClCompile Include="..\src\mpeg2\ts\EIT.cpp" />\r
<ClCompile Include="..\src\mpeg2\ts\Header.cpp" />\r
<ClCompile Include="..\src\mpeg2\ts\PAT.cpp" />\r
<ClCompile Include="..\src\Raym\URLResponse.cpp" />\r
<ClCompile Include="..\src\Raym\Workspace.cpp" />\r
<ClCompile Include="..\src\ry0\device\TunerFactory.cpp" />\r
+ <ClCompile Include="..\src\ry0\iPTd\Analyzer.cpp" />\r
<ClCompile Include="..\src\ry0\iPTd\CommandRunner.cpp" />\r
<ClCompile Include="..\src\ry0\iPTd\Controller.cpp" />\r
<ClCompile Include="..\src\ry0\iPTd\FFmpeg.cpp" />\r
<ClInclude Include="..\src\Raym\Stream.h">\r
<Filter>ソース ファイル\Raym</Filter>\r
</ClInclude>\r
- <ClInclude Include="..\src\mpeg2\ts\Analyzer.h">\r
- <Filter>ソース ファイル\mpeg2\ts</Filter>\r
- </ClInclude>\r
<ClInclude Include="..\src\mpeg2\ts\SDT.h">\r
<Filter>ソース ファイル\mpeg2\ts</Filter>\r
</ClInclude>\r
<ClInclude Include="..\src\mpeg2\ts\Header.h">\r
<Filter>ソース ファイル\mpeg2\ts</Filter>\r
</ClInclude>\r
- <ClInclude Include="..\src\mpeg2\ts\const.h">\r
- <Filter>ソース ファイル\mpeg2\ts</Filter>\r
- </ClInclude>\r
<ClInclude Include="..\src\ry0\device\TunerFactory.h">\r
<Filter>ソース ファイル\ry0\device</Filter>\r
</ClInclude>\r
<ClInclude Include="..\src\ry0\iPTd\HTTPLiveStreaming.h">\r
<Filter>ソース ファイル\ry0\iPTd</Filter>\r
</ClInclude>\r
+ <ClInclude Include="..\src\ry0\iPTd\Analyzer.h">\r
+ <Filter>ソース ファイル\ry0\iPTd</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="..\src\mpeg2\ts\Demultiplexer.h">\r
+ <Filter>ソース ファイル\mpeg2\ts</Filter>\r
+ </ClInclude>\r
</ItemGroup>\r
<ItemGroup>\r
<ClCompile Include="stdafx.cpp">\r
<ClCompile Include="..\src\Raym\Stream.cpp">\r
<Filter>ソース ファイル\Raym</Filter>\r
</ClCompile>\r
- <ClCompile Include="..\src\mpeg2\ts\Analyzer.cpp">\r
- <Filter>ソース ファイル\mpeg2\ts</Filter>\r
- </ClCompile>\r
<ClCompile Include="..\src\mpeg2\ts\SDT.cpp">\r
<Filter>ソース ファイル\mpeg2\ts</Filter>\r
</ClCompile>\r
<ClCompile Include="..\src\ry0\iPTd\HTTPLiveStreaming.cpp">\r
<Filter>ソース ファイル\ry0\iPTd</Filter>\r
</ClCompile>\r
+ <ClCompile Include="..\src\ry0\iPTd\Analyzer.cpp">\r
+ <Filter>ソース ファイル\ry0\iPTd</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\src\mpeg2\ts\Demultiplexer.cpp">\r
+ <Filter>ソース ファイル\mpeg2\ts</Filter>\r
+ </ClCompile>\r
</ItemGroup>\r
<ItemGroup>\r
<ResourceCompile Include="iPTd.rc">\r
\r
#pragma once\r
\r
+#ifdef _WIN32\r
#include <windows.h>\r
+#endif\r
\r
#include <Raym/Object.h>\r
\r
class Application : public Object\r
{\r
private:\r
+#ifdef _WIN32\r
HINSTANCE _instance; //\r
HWND _wnd; //\r
HMENU _menu;\r
UINT_PTR _timer;\r
UINT _counter;\r
+#endif\r
\r
bool addNotifyIcon();\r
void deleteNotifyIcon();\r
\r
public:\r
static Application *alloc();\r
+#ifdef _WIN32\r
virtual Application *init(HINSTANCE hInstance, int nCmdShow, LPCWSTR className);\r
+#endif\r
virtual int start();\r
\r
virtual void systemWillSuspend() = 0;\r
void suspend();\r
bool setWakeSchedule(int year, int month, int day, int hour, int min);\r
void resetWakeSchedule();\r
-\r
+#ifdef _WIN32\r
LRESULT WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);\r
+#endif\r
\r
// misc\r
static const char *GetHomeDirectory();\r
static const char *GetExecutePath();\r
static const char *GetPublicDirectory();\r
\r
+#ifdef _WIN32\r
// Win32 アプリケーションのエントリポイント\r
static int main(Application *(*allocator)(), LPCWSTR className, HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow);\r
+#endif\r
};\r
\r
} // Raym\r
class FileHandle : public Object\r
{\r
private:\r
+#ifdef _WIN32\r
HANDLE _handle;\r
+#endif\r
bool _pipe;\r
\r
protected:\r
~FileHandle();\r
\r
public:\r
+#ifdef _WIN32\r
static FileHandle *fileHandleWithHANDLE(HANDLE h);\r
HANDLE handle();\r
+#endif\r
bool isPipe();\r
\r
virtual const char *className();\r
{
long long len = atoll(val->cString());
char tmp[32];
+#ifdef _WIN32
sprintf_s(tmp, sizeof(tmp), "%lld", len);
+#else
+ sprintf(tmp, "%lld", len);
+#endif
if (strcmp(tmp, val->cString()) == 0)
{
content_length = len;
#ifndef __RAYM_LOG_H__\r
#define __RAYM_LOG_H__\r
\r
+#ifdef _WIN32\r
+#else\r
+#include <stdio.h>\r
+#include <stdarg.h>\r
+#endif\r
+\r
namespace Raym\r
{\r
\r
+#ifdef _WIN32\r
extern void Log(const char *format, ...);\r
+#else\r
+inline void Log(const char *format, ...)\r
+{\r
+ va_list ap;\r
+ va_start(ap, format);\r
+ vprintf(format, ap);\r
+ va_end(ap);\r
+}\r
+#endif\r
extern int LOG_NUM_MAX;\r
\r
} // Raym\r
DebugLog2("Object::Object()");
RAYM_LOCK_CREATE;
+ RAYM_COND_CREATE;
_retainCount = 1;
\r
#pragma once\r
\r
+#include "Raym/Log.h"\r
#define RAYM_MEMORY_CHECK\r
+//#define RAYM_MUTEX_CHECK\r
\r
#ifdef _WIN32\r
#include <windows.h>\r
\r
#define RAYM_LOCK_CREATE InitializeCriticalSection(&_cs)\r
#define RAYM_LOCK_DESTROY DeleteCriticalSection(&_cs)\r
+#define RAYM_COND_CREATE InitializeConditionVariable(&_cond)\r
+#define RAYM_COND_DESTROY pthread_cond_destroy(&_cond)\r
\r
#define DEFINE_STATIC_MUTEX(variable) \\r
class STATIC_MUTEX_variable \\r
pthread_mutex_init(&_lock, &attr); \\r
}\r
#define RAYM_LOCK_DESTROY pthread_mutex_destroy(&_lock)\r
-#define RAYM_LOCK pthread_mutex_lock(&_lock)\r
-#define RAYM_UNLOCK pthread_mutex_unlock(&_lock)\r
+#define RAYM_COND_CREATE pthread_cond_init(&_cond, NULL)\r
+#define RAYM_COND_DESTROY pthread_cond_destroy(&_cond)\r
\r
+#define DEFINE_STATIC_MUTEX(variable) \\r
+class STATIC_MUTEX_variable \\r
+{ \\r
+private: \\r
+ pthread_mutex_t _lock; \\r
+ \\r
+public: \\r
+ STATIC_MUTEX_variable() \\r
+ { \\r
+ pthread_mutexattr_t attr; \\r
+ pthread_mutexattr_init(&attr); \\r
+ pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); \\r
+ pthread_mutex_init(&_lock, &attr); \\r
+ } \\r
+ ~STATIC_MUTEX_variable() \\r
+ { \\r
+ pthread_mutex_destroy(&_lock); \\r
+ } \\r
+ void lock() \\r
+ { \\r
+ pthread_mutex_lock(&_lock); \\r
+ } \\r
+ void unlock() \\r
+ { \\r
+ pthread_mutex_unlock(&_lock); \\r
+ } \\r
+}; \\r
+static STATIC_MUTEX_variable variable;\r
#endif\r
\r
namespace Raym\r
Object();\r
virtual ~Object();\r
\r
+ int _retainCount;\r
+\r
+#ifdef RAYM_MUTEX_CHECK\r
+public:\r
+#endif\r
#ifdef _WIN32\r
CRITICAL_SECTION _cs;\r
+ CONDITION_VARIABLE _cond;\r
#else\r
pthread_mutex_t _lock;\r
+ pthread_cond_t _cond;\r
#endif\r
- int _retainCount;\r
\r
public:\r
//\r
\r
friend void RaymLock(Object *);\r
friend void RaymUnlock(Object *);\r
+ friend void RaymCondWait(Object *);\r
+ friend void RaymCondSignal(Object *);\r
+ friend void RaymCondBroadcast(Object *);\r
};\r
\r
+#ifndef RAYM_MUTEX_CHECK\r
inline void RaymLock(Object *obj)\r
{\r
#ifdef _WIN32\r
#else\r
#endif\r
}\r
+#else\r
+#ifdef _WIN32\r
+#define RaymLock(obj) \\r
+ DebugLog3("before lock: %s %d", __FILE__, __LINE__); \\r
+ EnterCriticalSection(&(obj->_cs)); \\r
+ DebugLog3("after lock: %s %d", __FILE__, __LINE__);\r
+#else\r
+#endif\r
+#endif\r
\r
+#ifndef RAYM_MUTEX_CHECK\r
inline void RaymUnlock(Object *obj)\r
{\r
#ifdef _WIN32\r
#else\r
#endif\r
}\r
+#else\r
+#ifdef _WIN32\r
+#define RaymUnlock(obj) \\r
+ DebugLog3("before unlock: %s %d", __FILE__, __LINE__); \\r
+ LeaveCriticalSection(&(obj->_cs)); \\r
+ DebugLog3("after unlock: %s %d", __FILE__, __LINE__);\r
+#else\r
+#endif\r
+#endif\r
+\r
+#ifndef RAYM_MUTEX_CHECK\r
+inline void RaymCondWait(Object *obj)\r
+{\r
+#ifdef _WIN32\r
+ SleepConditionVariableCS(&(obj->_cond), &(obj->_cs), INFINITE);\r
+#else\r
+#endif\r
+}\r
+#else\r
+#ifdef _WIN32\r
+#define RaymCondWait(obj) \\r
+ DebugLog3("before wait: %s %d", __FILE__, __LINE__); \\r
+ SleepConditionVariableCS(&(obj->_cond), &(obj->_cs), INFINITE); \\r
+ DebugLog3("after wait: %s %d", __FILE__, __LINE__);\r
+#else\r
+#endif\r
+#endif\r
+\r
+#ifndef RAYM_MUTEX_CHECK\r
+inline void RaymCondSignal(Object *obj)\r
+{\r
+#ifdef _WIN32\r
+ WakeConditionVariable(&(obj->_cond));\r
+#else\r
+#endif\r
+}\r
+#else\r
+#ifdef _WIN32\r
+#define RaymCondSignal(obj) \\r
+ DebugLog3("before signal: %s %d", __FILE__, __LINE__); \\r
+ WakeConditionVariable(&(obj->_cond)); \\r
+ DebugLog3("after signal: %s %d", __FILE__, __LINE__);\r
+#else\r
+#endif\r
+#endif\r
+\r
+inline void RaymCondBroadcast(Object *obj)\r
+{\r
+#ifdef _WIN32\r
+ WakeAllConditionVariable(&(obj->_cond));\r
+#else\r
+#endif\r
+}\r
+\r
\r
//#define RaymCriticalSection(OBJ, BLOCK) RaymLock(OBJ); BLOCK; RaymUnlock(OBJ);\r
\r
\r
#include <Raym/Object.h>\r
#include <Raym/Dictionary.h>\r
+#ifdef _WIN32\r
#include <windows.h>\r
#include <tlhelp32.h>\r
+#endif\r
\r
namespace Raym\r
{\r
#ifndef __RAYM_RUNTIME_H__
#define __RAYM_RUNTIME_H__
+#include <limits.h>
+
namespace Raym
{
#include <time.h>\r
#else\r
#include <sys/time.h>\r
+#include <iconv.h>\r
#endif\r
#include <errno.h>\r
\r
{\r
switch (encoding)\r
{\r
- case ShiftJISStringEncoding:\r
+ case UTF8StringEncoding:\r
+ _str = (char *)malloc(length + 1);\r
+ if (_str != NULL)\r
+ {\r
+ _length = length;\r
+ memcpy(_str, nullTerminatedCString, _length);\r
+ _str[_length] = '\0';\r
+ }\r
+ else\r
{\r
+ DebugLog3("error: %s(): malloc", __FUNCTION__);\r
+ release();\r
+ return NULL;\r
+ }\r
+ break;\r
+\r
+ case ShiftJISStringEncoding:\r
#ifdef _WIN32\r
+ {\r
int wlen = MultiByteToWideChar(CP_ACP, MB_ERR_INVALID_CHARS, nullTerminatedCString, (int)(strlen(nullTerminatedCString) + 1), NULL, 0);\r
if (wlen != 0)\r
{\r
release();\r
return NULL;\r
}\r
-#else\r
- DebugLog0("not implement.");\r
-#endif\r
}\r
break;\r
+#endif\r
\r
- case UTF8StringEncoding:\r
- _str = (char *)malloc(length + 1);\r
- if (_str != NULL)\r
- {\r
- _length = length;\r
- memcpy(_str, nullTerminatedCString, _length);\r
- _str[_length] = '\0';\r
- }\r
- else\r
+\r
+#ifndef _WIN32\r
{\r
- DebugLog3("error: %s(): malloc", __FUNCTION__);\r
- release();\r
- return NULL;\r
+ iconv_t cd;\r
+ const char *fromcode = NULL;\r
+ switch (encoding)\r
+ {\r
+ case JapaneseEUCStringEncoding:\r
+ fromcode = "EUC-JP";\r
+ break;\r
+ case ShiftJISStringEncoding:\r
+ fromcode = "SHIFT-JIS";\r
+ break;\r
+ default:\r
+ fromcode = "UTF-8";\r
+ break;\r
+ }\r
+ cd = iconv_open("UTF-8", fromcode);\r
+ if (cd != (iconv_t)-1)\r
+ {\r
+ size_t srclen = strlen(nullTerminatedCString);\r
+ _str = (char *)malloc(srclen * 3 + 1);\r
+ if (_str != NULL)\r
+ {\r
+ memset(_str, 0x00, srclen * 3 + 1);\r
+ size_t dstlen = srclen * 3 + 1;\r
+ char *dst = _str;\r
+ char *src = strdup(nullTerminatedCString);\r
+ char *src2 = src;\r
+ size_t ret = iconv(cd, &src, &srclen, &dst, &dstlen);\r
+ if (src2 != NULL)\r
+ {\r
+ free(src2);\r
+ }\r
+ if (ret == -1)\r
+ {\r
+ DebugLog0("nsstr: check 0: %d, %d\n", srclen, errno);\r
+ iconv_close(cd);\r
+ release();\r
+ return NULL;\r
+ }\r
+\r
+ iconv_close(cd);\r
+\r
+ char *p = (char *)realloc(_str, strlen(_str) + 1);\r
+ if (p == NULL)\r
+ {\r
+ DebugLog0("nsstr: check 1\n");\r
+ release();\r
+ return NULL;\r
+ }\r
+ _str = p;\r
+ _length = strlen(_str);\r
+// DebugLog0("_str = %s\n", _str);\r
+ }\r
+ else\r
+ {\r
+ DebugLog0("nsstr: check 2\n");\r
+ iconv_close(cd);\r
+ release();\r
+ return NULL;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ DebugLog0("nsstr: check 3\n");\r
+ }\r
}\r
break;\r
+#endif\r
\r
default:\r
DebugLog0("warning: Unknown String Encoding: 0x%08x", encoding);\r
char *buf = (char *)realloc(s1, strlen(s1) + strlen(s2) + 1);\r
if (buf != NULL)\r
{\r
+#ifdef _WIN32\r
strcat_s(buf, (strlen(s1) + strlen(s2) + 1), s2);\r
+#else\r
+ strcat(buf, s2);\r
+#endif\r
}\r
return buf;\r
}\r
release();\r
return NULL;\r
}\r
+#ifdef _WIN32\r
strcat_s(buf, (strlen(buf) + 3), "%%");\r
+#else\r
+ strcat(buf, "%%");\r
+#endif\r
}\r
else\r
{\r
String *String::stringByTrimming()\r
{\r
String *result = NULL;\r
+#ifdef _WIN32\r
char *buf = _strdup(_str);\r
+#else\r
+ char *buf = strdup(_str);\r
+#endif\r
if (buf != NULL)\r
{\r
char *st = buf;\r
Array *String::componentsSeparatedByString(const char *separator)\r
{\r
Array *result = Array::arrayWithCapacity(0);\r
+#ifdef _WIN32\r
char *tmp = _strdup(_str);\r
+#else\r
+ char *tmp = strdup(_str);\r
+#endif\r
char *p1 = tmp;\r
while (true)\r
{\r
String *result = NULL;\r
if (anIndex < _length)\r
{\r
+#ifdef _WIN32\r
char *tmp = _strdup(_str);\r
+#else\r
+ char *tmp = strdup(_str);\r
+#endif\r
if (tmp != NULL)\r
{\r
tmp[anIndex] = '\0';\r
FileHandle * _standardOutput;\r
FileHandle * _standardError;\r
\r
+#ifdef _WIN32\r
PROCESS_INFORMATION _pi;\r
+#endif\r
\r
protected:\r
Task();\r
int status_code = atoi(code);
char tmp[256];
+#ifdef _WIN32
sprintf_s(tmp, sizeof(tmp), "%d", status_code);
+#else
+ sprintf(tmp, "%d", status_code);
+#endif
if (strcmp(code, tmp) != 0)
{
DebugLog3("error: invalid format. (Status-Code) \"%s\"\n", statusLine);
+++ /dev/null
-//\r
-// Analyzer.cpp\r
-//\r
-\r
-#include "b25/aribstr.h"\r
-#include "mpeg2/ts/Analyzer.h"\r
-\r
-using namespace Raym;\r
-\r
-namespace MPEG2\r
-{\r
-namespace TS\r
-{\r
-\r
-Analyzer::Analyzer()\r
-{\r
- InitializeCriticalSection(&_cs);\r
-\r
- _pat = new PAT();\r
- _old_pat = NULL;\r
- _sdt = new SDT();\r
- _sdt_copy = NULL;\r
- _eit_0012 = new EIT();\r
- _eit_0012_copy = NULL;\r
- _eit_0026 = new EIT();\r
- _eit_0026_copy = NULL;\r
- _eit_0027 = new EIT();\r
- _eit_0027_copy = NULL;\r
- _pmt_list = NULL;\r
- _flag = 0;\r
-}\r
-\r
-Analyzer::~Analyzer()\r
-{\r
- delete _pat;\r
- if (_old_pat != NULL)\r
- {\r
- delete _old_pat;\r
- }\r
- delete _sdt;\r
- delete _eit_0012;\r
- delete _eit_0026;\r
- delete _eit_0027;\r
-\r
- if (_pmt_list != NULL)\r
- {\r
- delete _pmt_list;\r
- }\r
-\r
- DeleteCriticalSection(&_cs);\r
-}\r
-\r
-void Analyzer::setFlag(uint32_t flag)\r
-{\r
- EnterCriticalSection(&_cs);\r
- _flag = flag;\r
- LeaveCriticalSection(&_cs);\r
-}\r
-\r
-void Analyzer::put(uint8_t *buf, uint32_t size)\r
-{\r
- EnterCriticalSection(&_cs);\r
-\r
- uint32_t offset = 0;\r
- while (offset < size)\r
- {\r
- if (buf[offset] != SYNC_BYTE)\r
- {\r
- ++offset;\r
- continue;\r
- }\r
- uint16_t pid = ((buf[offset + 1] << 8) + buf[offset + 2]) & 0x1FFF;\r
- switch (pid)\r
- {\r
- case 0x0000: // PAT\r
- break;\r
-\r
- case 0x0011: // SDT\r
- if ((_flag & FLAG_SDT) == FLAG_SDT)\r
- {\r
- if (_sdt->decode(&buf[offset]))\r
- {\r
- detect(_sdt);\r
- }\r
- }\r
- break;\r
-\r
- case 0x0012: // EIT\r
- if ((_flag & FLAG_EIT) == FLAG_EIT)\r
- {\r
- if (_eit_0012->decode(&buf[offset]))\r
- {\r
- detect(_eit_0012);\r
- }\r
- }\r
- break;\r
-\r
- case 0x0026: // EIT\r
- if ((_flag & FLAG_EIT) == FLAG_EIT)\r
- {\r
- if (_eit_0026->decode(&buf[offset]))\r
- {\r
- detect(_eit_0026);\r
- }\r
- }\r
- break;\r
-\r
- case 0x0027: // EIT\r
- if ((_flag & FLAG_EIT) == FLAG_EIT)\r
- {\r
- if (_eit_0027->decode(&buf[offset]))\r
- {\r
- detect(_eit_0027);\r
- }\r
- }\r
- break;\r
-\r
- default:\r
- break;\r
- }\r
- offset += PACKET_SIZE;\r
- }\r
-\r
- LeaveCriticalSection(&_cs);\r
-}\r
-\r
-bool Analyzer::detect(PAT *pat)\r
-{\r
- return false;\r
-}\r
-\r
-void Analyzer::detect(PMT *pmt)\r
-{\r
-}\r
-\r
-void Analyzer::detect(SDT *sdt)\r
-{\r
- if (_sdt->_table_id == 0x42)\r
- {\r
- _sdt_copy = _sdt;\r
- _sdt = new SDT();\r
- }\r
-}\r
-\r
-void Analyzer::detect(EIT *eit)\r
-{\r
- if (eit == _eit_0012)\r
- {\r
- _eit_0012_copy = _eit_0012;\r
- _eit_0012 = new EIT();\r
- }\r
- if (eit == _eit_0026)\r
- {\r
- _eit_0026_copy = _eit_0026;\r
- _eit_0026 = new EIT();\r
- }\r
- if (eit == _eit_0027)\r
- {\r
- _eit_0027_copy = _eit_0027;\r
- _eit_0027 = new EIT();\r
- }\r
-}\r
-\r
-\r
-Dictionary *Analyzer::stationInfo()\r
-{\r
- Dictionary *result = NULL;\r
-\r
- EnterCriticalSection(&_cs);\r
-\r
- int count = 0;\r
- while ((_sdt_copy == NULL) && (count++ < 60))\r
- {\r
- LeaveCriticalSection(&_cs);\r
- ::Sleep(1);\r
- EnterCriticalSection(&_cs);\r
- }\r
-\r
- if (_sdt_copy != NULL)\r
- {\r
- result = Dictionary::dictionaryWithCapacity(0);\r
- Array *services = Array::arrayWithCapacity(0);\r
- result->setObject(services, KEY_SERVICES);\r
- for (uint32_t i = 0; i < _sdt_copy->_service_count; ++i)\r
- {\r
- Dictionary *service = Dictionary::dictionaryWithCapacity(0);\r
- services->addObject(service);\r
- char tmp[32];\r
- sprintf_s(tmp, "%d", _sdt_copy->_services[i]._service_id);\r
- service->setString(tmp, KEY_SERVICE_ID);\r
-// service->setInteger(_sdt_copy->_services[i]._service_id, KEY_SERVICE_ID);\r
- sprintf_s(tmp, "%d", _sdt_copy->_services[i]._desc->service_type);\r
- service->setString(tmp, KEY_SERVICE_TYPE);\r
-// service->setInteger(_sdt_copy->_services[i]._desc->service_type, KEY_TYPE);\r
- if (_sdt_copy->_services[i]._desc->service_name_length > 0)\r
- {\r
- String *name = String::stringWithCString(_sdt_copy->_services[i]._desc->service_name, ShiftJISStringEncoding);\r
- service->setString(name, KEY_NAME);\r
- if (i == 0)\r
- {\r
- result->setString(name, KEY_NAME);\r
- }\r
- }\r
- }\r
- delete _sdt_copy;\r
- _sdt_copy = NULL;\r
- }\r
- LeaveCriticalSection(&_cs);\r
-\r
- return result;\r
-}\r
-\r
-Array *Analyzer::eit2epgs(EIT *eit)\r
-{\r
- Array *result = NULL;\r
-\r
- if (eit != NULL)\r
- {\r
- while (true)\r
- {\r
- EIT::Event *event = eit->nextEvent();\r
- if (event == NULL)\r
- {\r
- break;\r
- }\r
-\r
- Dictionary *epg = Dictionary::dictionaryWithCapacity(0);\r
-\r
- char tmp[32];\r
- sprintf_s(tmp, "%d", eit->_service_id);\r
- epg->setString(tmp, KEY_EPG_SERVICE_ID);\r
-// epg->setInteger(eit->_service_id, KEY_EPG_SERVICE_ID);\r
- sprintf_s(tmp, "%d", event->_event_id);\r
- epg->setString(tmp, KEY_EPG_EVENT_ID);\r
-// epg->setInteger(event->_event_id, KEY_EPG_EVENT_ID);\r
-\r
- char date[16];\r
- sprintf_s(date, sizeof(date), "%02d/%02d/%02d", event->_st_year, event->_st_month, event->_st_day);\r
- epg->setString(date, KEY_EPG_DATE);\r
-\r
- char start[16];\r
- sprintf_s(start, sizeof(start), "%02d:%02d:%02d", event->_st_hour, event->_st_min, event->_st_sec);\r
- epg->setString(start, KEY_EPG_START);\r
-\r
- int hour = event->_st_hour + event->_dur_hour;\r
- int min = event->_st_min + event->_dur_min;\r
- int sec = event->_st_sec + event->_dur_sec;\r
- if (sec >= 60)\r
- {\r
- min += 1;\r
- sec -= 60;\r
- }\r
- if (min >= 60)\r
- {\r
- hour += 1;\r
- min -= 60;\r
- }\r
- char end[16];\r
- sprintf_s(end, sizeof(end), "%02d:%02d:%02d", hour, min, sec);\r
- epg->setString(end, KEY_EPG_END);\r
-\r
- Data *data = Data::dataWithCapacity(0);\r
-\r
- while (true)\r
- {\r
- Descriptor *desc = event->nextDescriptor();\r
- if (desc == NULL)\r
- {\r
- break;\r
- }\r
-\r
- switch (desc->descriptor_tag)\r
- {\r
- case TAG_BOUQUET_NAME_DESCRIPTOR:\r
- printf("TAG_BOUQUET_NAME_DESCRIPTOR\n");\r
- break;\r
-\r
- case TAG_SERVICE_DESCRIPTOR:\r
- printf("TAG_SERVICE_DESCRIPTOR\n");\r
- break;\r
-\r
- case TAG_SHORT_EVENT_DESCRIPTOR:\r
- if (desc->short_event.event_name_length > 0)\r
- {\r
- char *tmp = (char *)malloc(desc->short_event.event_name_length * 2 + 1);\r
- if (tmp)\r
- {\r
- AribToString(tmp, (const char *)desc->short_event.event_name, desc->short_event.event_name_length);\r
- String *event_name = String::stringWithCString(tmp, ShiftJISStringEncoding);\r
- if (event_name)\r
- {\r
- epg->setString(event_name, KEY_EPG_TITLE);\r
- }\r
- else\r
- {\r
- printf("stringWithCString() NG.\n");\r
- }\r
-\r
- free(tmp);\r
- }\r
- else\r
- {\r
- printf("malloc NG.\n");\r
- }\r
- }\r
- if (desc->short_event.text_length > 0)\r
- {\r
- char *tmp = (char *)malloc(desc->short_event.text_length * 2 + 1);\r
- if (tmp)\r
- {\r
- AribToString(tmp, (const char *)desc->short_event.text, desc->short_event.text_length);\r
- String *text = String::stringWithCString(tmp, ShiftJISStringEncoding);\r
- if (text)\r
- {\r
- epg->setString(text, KEY_EPG_DESCRIPTION);\r
- }\r
- else\r
- {\r
- printf("stringWithCString() NG.\n");\r
- }\r
-\r
- }\r
- else\r
- {\r
- printf("mallco NG.\n");\r
- }\r
- }\r
- break;\r
-\r
- case TAG_EXTENDED_EVENT_DESCRIPTOR:\r
- for (int i = 0; i < desc->extended_event.item_count; ++i)\r
- {\r
-\r
- // item_description と item を繋げてしまうと正しく読めない場合がある\r
- // 現状は item_description は捨てる\r
- // どうやって扱うか、今後の課題\r
- /*\r
- if (desc->extended_event.items[i].item_description_length > 0)\r
- {\r
- data->appendBytes(desc->extended_event.items[i].item_description, \r
- desc->extended_event.items[i].item_description_length);\r
- }\r
- */\r
-\r
- if (desc->extended_event.items[i].item_length > 0)\r
- {\r
- data->appendBytes(desc->extended_event.items[i].item,\r
- desc->extended_event.items[i].item_length);\r
- }\r
- }\r
- if (desc->extended_event.text_length > 0)\r
- {\r
- printf("TAG_EXTENDED_EVENT_DESCRIPTOR\n");\r
- printf(" text: %s\n", desc->extended_event.text);\r
- data->appendBytes(desc->extended_event.text, desc->extended_event.text_length);\r
- }\r
- break;\r
-\r
- case TAG_CONTENT_DESCRIPTOR:\r
- printf("TAG_CONTENT_DESCRIPTOR\n");\r
- break;\r
-\r
- case TAG_SERIES_DESCRIPTOR:\r
- printf("TAG_SERIES_DESCRIPTOR\n");\r
- break;\r
-\r
- default:\r
- printf("Unknow descriptor: 0x%02X\n", desc->descriptor_tag);\r
- break;\r
- }\r
- }\r
-\r
- if (data->length())\r
- {\r
- char *tmp = (char *)malloc(data->length() * 2);\r
- if (tmp)\r
- {\r
- AribToString(tmp, (const char *)data->bytes(), data->length());\r
- String *desc = String::stringWithCString(tmp, ShiftJISStringEncoding);\r
- if (desc)\r
- {\r
- epg->setString(desc, KEY_EPG_DESCRIPTION);\r
- }\r
- }\r
- }\r
-\r
- if (result == NULL)\r
- {\r
- result = Array::arrayWithCapacity(0);\r
- }\r
- result->addObject(epg);\r
- }\r
- }\r
-\r
- return result;\r
-}\r
-\r
-Array *Analyzer::epgInfos()\r
-{\r
- Array *result = NULL;\r
-\r
- EnterCriticalSection(&_cs);\r
- int count = 0;\r
- while ((_eit_0012_copy == NULL) && (_eit_0026_copy == NULL) &&\r
- (_eit_0027_copy == NULL) && (count++ < 60))\r
- {\r
- LeaveCriticalSection(&_cs);\r
- ::Sleep(1);\r
- EnterCriticalSection(&_cs);\r
- }\r
-\r
- result = Array::arrayWithCapacity(0);\r
- if (_eit_0012_copy != NULL)\r
- {\r
- Array *epgs = eit2epgs(_eit_0012_copy);\r
- if (epgs != NULL)\r
- {\r
- result->addObjectsFromArray(epgs);\r
- }\r
-\r
- delete _eit_0012_copy;\r
- _eit_0012_copy = NULL;\r
- }\r
- if (_eit_0026_copy != NULL)\r
- {\r
- Array *epgs = eit2epgs(_eit_0026_copy);\r
- if (epgs != NULL)\r
- {\r
- result->addObjectsFromArray(epgs);\r
- }\r
-\r
- delete _eit_0026_copy;\r
- _eit_0026_copy = NULL;\r
- }\r
- if (_eit_0027_copy != NULL)\r
- {\r
- Array *epgs = eit2epgs(_eit_0027_copy);\r
- if (epgs != NULL)\r
- {\r
- result->addObjectsFromArray(epgs);\r
- }\r
-\r
- delete _eit_0027_copy;\r
- _eit_0027_copy = NULL;\r
- }\r
-\r
- LeaveCriticalSection(&_cs);\r
-\r
- return result;\r
-}\r
-\r
-Analyzer::PMT_LIST::PMT_LIST(uint16_t program_number, uint16_t pid)\r
-{\r
- _program_number = program_number;\r
- _pid = pid;\r
- _pmt = new PMT();\r
- _prev = NULL;\r
- _next = NULL;\r
-}\r
-\r
-Analyzer::PMT_LIST::~PMT_LIST()\r
-{\r
- delete _pmt;\r
- if (_next != NULL)\r
- {\r
- delete _next;\r
- }\r
-}\r
-\r
-void Analyzer::PMT_LIST::add(uint16_t program_number, uint16_t pid)\r
-{\r
- if (_next == NULL)\r
- {\r
- _next = new PMT_LIST(program_number, pid);\r
- _next->_prev = this;\r
- }\r
- else\r
- {\r
- _next->add(program_number, pid);\r
- }\r
-}\r
-\r
-\r
-} // TS\r
-} // MPEG2\r
-\r
+++ /dev/null
-//\r
-// Analyzer.h\r
-//\r
-\r
-#pragma once\r
-\r
-//#include <stdint.h>\r
-//#include <windows.h>\r
-//#include <process.h>\r
-//#include <fcntl.h>\r
-//#include <io.h>\r
-//#include <stdio.h>\r
-\r
-#include "mpeg2/ts/const.h"\r
-#include "mpeg2/ts/Header.h"\r
-#include "mpeg2/ts/PAT.h"\r
-#include "mpeg2/ts/PMT.h"\r
-#include "mpeg2/ts/SDT.h"\r
-#include "mpeg2/ts/EIT.h"\r
-#include "ry0/device/Tuner.h"\r
-#include "Raym/Raym.h"\r
-\r
-namespace MPEG2\r
-{\r
-namespace TS\r
-{\r
-\r
-class Analyzer : public ry0::device::Tuner::Listener\r
-{\r
-public:\r
- enum \r
- {\r
- FLAG_PAT = 0x00000001,\r
- FLAG_SDT = 0x00000002,\r
- FLAG_EIT = 0x00000004\r
- };\r
-\r
-private:\r
- CRITICAL_SECTION _cs;\r
- bool _verbose;\r
- uint32_t _flag;\r
- PAT * _pat;\r
- PAT * _old_pat;\r
- SDT * _sdt;\r
- SDT * _sdt_copy;\r
- EIT * _eit_0012;\r
- EIT * _eit_0012_copy;\r
- EIT * _eit_0026;\r
- EIT * _eit_0026_copy;\r
- EIT * _eit_0027;\r
- EIT * _eit_0027_copy;\r
-\r
- class PMT_LIST\r
- {\r
- public:\r
- uint16_t _program_number;\r
- uint16_t _pid;\r
- PMT * _pmt;\r
- PMT_LIST * _prev;\r
- PMT_LIST * _next;\r
-\r
- PMT_LIST(uint16_t program_number, uint16_t pid);\r
- ~PMT_LIST();\r
- void add(uint16_t program_number, uint16_t pid);\r
- };\r
- PMT_LIST * _pmt_list;\r
-\r
- Raym::Array *eit2epgs(EIT *eit);\r
-\r
-public:\r
- Analyzer();\r
- virtual ~Analyzer();\r
- void setFlag(uint32_t flag);\r
- void put(uint8_t *buffer, uint32_t size);\r
-\r
- virtual bool detect(PAT *);\r
- virtual void detect(PMT *);\r
- virtual void detect(SDT *);\r
- virtual void detect(EIT *);\r
-\r
- Raym::Dictionary *stationInfo();\r
- Raym::Array *epgInfos();\r
-};\r
-\r
-} // ts\r
-} // mpeg2\r
-/*
- * EIT.cpp
- * PTxSystem
- *
- * Created by Ryosuke Mitachi on 11/08/24.
- * Copyright 2011 __MyCompanyName__. All rights reserved.
- *
- */
-
-#include "b25/aribstr.h"
-#include "mpeg2/ts/EIT.h"
-
-namespace MPEG2
-{
-namespace TS
-{
-
-EIT::EIT()
-{
- reset();
-}
-
-EIT::EIT(EIT &eit)
-{
-// printf("copy constructor.\n");
- _table_id = eit._table_id;
- _section_syntax_indicator = eit._section_syntax_indicator;
- _section_length = eit._section_length;
- _service_id = eit._service_id;
- _version_number = eit._version_number;
- _current_next_indicator = eit._current_next_indicator;
- _section_number = eit._section_number;
- _last_section_number = eit._last_section_number;
- _transport_stream_id = eit._transport_stream_id;
- _original_network_id = eit._original_network_id;
- _segment_last_section_number = eit._segment_last_section_number;
- _last_table_id = eit._last_table_id;
-
- _next_event_offset = eit._next_event_offset;
-
- _length = eit._length;
- memcpy(_section, eit._section, sizeof(_section));
-}
-
-EIT::~EIT()
-{
- reset();
-}
-
-bool EIT::decode_section()
-{
- bool result = false;
- _table_id = _section[0x00];
- if ((0x4E <= _table_id) && (_table_id <= 0x6F))
- {
- _section_syntax_indicator = (_section[0x01] & 0x80) >> 7;
- _section_length = ((_section[0x01] << 8) + _section[0x02]) & 0x0FFF;
- _service_id = (_section[0x03] << 8) + _section[0x04];
- _version_number = (_section[0x05] & 0x3E) >> 1;
- _current_next_indicator = _section[0x05] & 0x01;
- _section_number = _section[0x06];
- _last_section_number = _section[0x07];
- _transport_stream_id = (_section[0x08] << 8) + _section[0x09];
- _original_network_id = (_section[0x0a] << 8) + _section[0x0b];
- _segment_last_section_number = _section[0x0c];
- _last_table_id = _section[0x0d];
-
- if (_length == _section_length + 3)
- {
- _next_event_offset = 0x0e;
- result = true;
- }
- else
- {
- _next_event_offset = 0;
- }
- }
- else
- {
- printf("table id error. %d\n", _table_id);
- reset();
- }
- return result;
-}
-
-void EIT::reset()
-{
- _table_id = 0;
- _section_length = 0;
-}
-
-EIT::Event *EIT::nextEvent()
-{
-//printf("%s %d %d %d %d\n",__FUNCTION__, _table_id, _length, _section_length, _next_event_offset);
- if ((_table_id != 0) && (_length > 0) && (_length == _section_length + 3) && (_next_event_offset < (_length - 4)))
- {
- _event._event_id = (_section[_next_event_offset] << 8) + _section[_next_event_offset + 0x01];
-
- // start_time
- uint16_t mjd = (_section[_next_event_offset + 0x02] << 8) + _section[_next_event_offset + 0x03];
- _event._st_year = (uint16_t)((mjd - 15078.2) / 365.25);
- _event._st_month = (uint8_t)((mjd - 14956.1 - (uint16_t)(_event._st_year * 365.25)) / 30.6001);
- _event._st_day = mjd - 14956 - (uint16_t)(_event._st_year * 365.25) - (uint8_t)(_event._st_month * 30.6001);
- if ((_event._st_month == 14) || (_event._st_month == 15))
- {
- _event._st_year += 1901;
- _event._st_month -= 13;
- }
- else
- {
- _event._st_year += 1900;
- _event._st_month -= 1;
- }
- _event._st_hour = ((_section[_next_event_offset + 0x04] & 0xF0) >> 4) * 10 + (_section[_next_event_offset + 0x04] & 0x0F);
- _event._st_min = ((_section[_next_event_offset + 0x05] & 0xF0) >> 4) * 10 + (_section[_next_event_offset + 0x05] & 0x0F);
- _event._st_sec = ((_section[_next_event_offset + 0x06] & 0xF0) >> 4) * 10 + (_section[_next_event_offset + 0x06] & 0x0F);
-
- // duration
- _event._dur_hour = ((_section[_next_event_offset + 0x07] & 0xF0) >> 4) * 10 + (_section[_next_event_offset + 0x07] & 0x0F);
- _event._dur_min = ((_section[_next_event_offset + 0x08] & 0xF0) >> 4) * 10 + (_section[_next_event_offset + 0x08] & 0x0F);
- _event._dur_sec = ((_section[_next_event_offset + 0x09] & 0xF0) >> 4) * 10 + (_section[_next_event_offset + 0x09] & 0x0F);
-
- _event._running_status = (_section[_next_event_offset + 0x0a] & 0xE0) >> 5;
- _event._free_CA_mode = (_section[_next_event_offset + 0x0a] & 0x10) >> 4;
- _event._descriptors_loop_length = ((_section[_next_event_offset + 0x0a] & 0x0F) << 8) + _section[_next_event_offset + 0x0b];
-
- if (_next_event_offset + 0x0c + _event._descriptors_loop_length <= _length - 4)
- {
- _event._descriptor_ptr = &_section[_next_event_offset + 0x0c];
- _event._descriptor_offset = 0;
- _next_event_offset += (0x0c + _event._descriptors_loop_length);
- return &_event;
- }
- }
- _event._event_id = 0;
- _event._descriptors_loop_length = 0;
- return NULL;
-}
-
-Descriptor *EIT::Event::nextDescriptor()
-{
-//printf("%s\n", __FUNCTION__);
- uint16_t len = Table::parseDescriptor(&_descriptor_ptr[_descriptor_offset], _descriptors_loop_length, &_descriptor);
- if (len != 0)
- {
- _descriptor_offset += len;
- return &_descriptor;
- }
- return NULL;
-}
-
-} // TS
-} // MPEG2
+/*\r
+ * EIT.cpp\r
+ * PTxSystem\r
+ *\r
+ * Created by Ryosuke Mitachi on 11/08/24.\r
+ * Copyright 2011 __MyCompanyName__. All rights reserved.\r
+ *\r
+ */\r
+\r
+#include "b25/aribstr.h"\r
+#include "mpeg2/ts/EIT.h"\r
+\r
+namespace MPEG2\r
+{\r
+namespace TS\r
+{\r
+\r
+EIT::EIT()\r
+{\r
+ reset();\r
+}\r
+\r
+EIT::EIT(EIT &eit)\r
+{\r
+// printf("copy constructor.\n");\r
+ _table_id = eit._table_id;\r
+ _section_syntax_indicator = eit._section_syntax_indicator;\r
+ _section_length = eit._section_length;\r
+ _service_id = eit._service_id;\r
+ _version_number = eit._version_number;\r
+ _current_next_indicator = eit._current_next_indicator;\r
+ _section_number = eit._section_number;\r
+ _last_section_number = eit._last_section_number;\r
+ _transport_stream_id = eit._transport_stream_id;\r
+ _original_network_id = eit._original_network_id;\r
+ _segment_last_section_number = eit._segment_last_section_number;\r
+ _last_table_id = eit._last_table_id;\r
+\r
+ _event_offset = eit._event_offset;\r
+\r
+ _length = eit._length;\r
+ memcpy(_event_data, eit._event_data, sizeof(_event_data));\r
+}\r
+\r
+EIT::~EIT()\r
+{\r
+ reset();\r
+}\r
+\r
+bool EIT::decode_section()\r
+{\r
+ bool result = false;\r
+\r
+ /*\r
+ * 0x4E : EIT(自ストリームの現在と次の番組)\r
+ * 0x4F : EIT(他ストリームの現在と次の番組)\r
+ * 0x50 - 0x5F : EIT(自ストリーム、スケジュール)\r
+ * 0x60 - 0x6F : EIT(他ストリーム、スケジュール)\r
+ */\r
+ _table_id = _section[0x00];\r
+\r
+ if ((0x4E <= _table_id) && (_table_id <= 0x6F))\r
+ {\r
+ _section_syntax_indicator = (_section[0x01] & 0x80) >> 7;\r
+ _section_length = ((_section[0x01] << 8) + _section[0x02]) & 0x0FFF;\r
+ _service_id = (_section[0x03] << 8) + _section[0x04];\r
+ _version_number = (_section[0x05] & 0x3E) >> 1;\r
+ _current_next_indicator = _section[0x05] & 0x01;\r
+ _section_number = _section[0x06];\r
+ _last_section_number = _section[0x07];\r
+ _transport_stream_id = (_section[0x08] << 8) + _section[0x09];\r
+ _original_network_id = (_section[0x0a] << 8) + _section[0x0b];\r
+ _segment_last_section_number = _section[0x0c];\r
+ _last_table_id = _section[0x0d];\r
+\r
+ if (GetCrc32(_section, _section_length + 3) == 0)\r
+ {\r
+ memcpy(_event_data, &_section[0x0e], _section_length - 3 - 11);\r
+ _event_offset = 0;\r
+ result = true;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ printf("table id error. %d\n", _table_id);\r
+ reset();\r
+ }\r
+ return result;\r
+}\r
+\r
+void EIT::reset()\r
+{\r
+ printf("EIT::reset\n");\r
+ _table_id = 0;\r
+ _section_length = 0;\r
+ _event_offset = 0xFFFF;\r
+}\r
+\r
+EIT::Event *EIT::nextEvent()\r
+{\r
+printf("%s %d %d %d %d\n",__FUNCTION__, _table_id, _length, _section_length, _event_offset);\r
+// if ((_table_id != 0) && (_length > 0) && (_length == _section_length + 3) && (_event_offset < (_length - 4)))\r
+ if ((_event_offset >= 0x00) && (_event_offset + 0x0c < _section_length - 0x0e))\r
+ {\r
+ _event._event_id = (_event_data[_event_offset] << 8) + _event_data[_event_offset + 0x01];\r
+\r
+ // start_time\r
+ uint16_t mjd = (_event_data[_event_offset + 0x02] << 8) + _event_data[_event_offset + 0x03];\r
+ _event._st_year = (uint16_t)((mjd - 15078.2) / 365.25);\r
+ _event._st_month = (uint8_t)((mjd - 14956.1 - (uint16_t)(_event._st_year * 365.25)) / 30.6001);\r
+ _event._st_day = mjd - 14956 - (uint16_t)(_event._st_year * 365.25) - (uint8_t)(_event._st_month * 30.6001);\r
+ if ((_event._st_month == 14) || (_event._st_month == 15))\r
+ {\r
+ _event._st_year += 1901;\r
+ _event._st_month -= 13;\r
+ }\r
+ else\r
+ {\r
+ _event._st_year += 1900;\r
+ _event._st_month -= 1;\r
+ }\r
+ _event._st_hour = ((_event_data[_event_offset + 0x04] & 0xF0) >> 4) * 10 + (_event_data[_event_offset + 0x04] & 0x0F);\r
+ _event._st_min = ((_event_data[_event_offset + 0x05] & 0xF0) >> 4) * 10 + (_event_data[_event_offset + 0x05] & 0x0F);\r
+ _event._st_sec = ((_event_data[_event_offset + 0x06] & 0xF0) >> 4) * 10 + (_event_data[_event_offset + 0x06] & 0x0F);\r
+\r
+ // duration\r
+ _event._dur_hour = ((_event_data[_event_offset + 0x07] & 0xF0) >> 4) * 10 + (_event_data[_event_offset + 0x07] & 0x0F);\r
+ _event._dur_min = ((_event_data[_event_offset + 0x08] & 0xF0) >> 4) * 10 + (_event_data[_event_offset + 0x08] & 0x0F);\r
+ _event._dur_sec = ((_event_data[_event_offset + 0x09] & 0xF0) >> 4) * 10 + (_event_data[_event_offset + 0x09] & 0x0F);\r
+\r
+ _event._running_status = (_event_data[_event_offset + 0x0a] & 0xE0) >> 5;\r
+ _event._free_CA_mode = (_event_data[_event_offset + 0x0a] & 0x10) >> 4;\r
+ _event._descriptors_loop_length = ((_event_data[_event_offset + 0x0a] & 0x0F) << 8) + _event_data[_event_offset + 0x0b];\r
+\r
+printf("descriptors_loop_length = %d\n", _event._descriptors_loop_length);\r
+ if (_event_offset + 0x0c + _event._descriptors_loop_length <= _section_length)\r
+// if (_event_offset + 0x0c + _event._descriptors_loop_length <= _length - 4)\r
+ {\r
+ _event._descriptor_ptr = &_event_data[_event_offset + 0x0c];\r
+ _event._descriptor_offset = 0;\r
+ _event_offset += (0x0c + _event._descriptors_loop_length);\r
+printf("next event_offset = %d\n", _event_offset);\r
+ return &_event;\r
+ }\r
+ else\r
+ {\r
+printf("check 001\n");\r
+ }\r
+ }\r
+ else\r
+ {\r
+printf("check 002\n");\r
+ }\r
+ _event._event_id = 0;\r
+ _event._descriptors_loop_length = 0;\r
+ return NULL;\r
+}\r
+\r
+Descriptor *EIT::Event::nextDescriptor()\r
+{\r
+//printf("%s\n", __FUNCTION__);\r
+ if (_descriptors_loop_length >= 2)\r
+ {\r
+ uint16_t len = Table::parseDescriptor(&_descriptor_ptr[_descriptor_offset], _descriptors_loop_length, &_descriptor);\r
+ if (len != 0)\r
+ {\r
+ _descriptor_offset += len;\r
+ _descriptors_loop_length -= len;\r
+ return &_descriptor;\r
+ }\r
+ }\r
+ return NULL;\r
+}\r
+\r
+} // TS\r
+} // MPEG2\r
class Event
{
+
public:
uint16_t _event_id; // 16
// start_time 40
uint8_t * _descriptor_ptr;
uint16_t _descriptor_offset;
Descriptor _descriptor;
-
- public:
Descriptor *nextDescriptor();
};
+ uint8_t _event_data[MAX_SECT_LEN];
+ uint16_t _event_offset;
Event _event;
- uint16_t _next_event_offset;
public:
EIT();
~EIT();
void reset();
- EIT::Event *nextEvent();
+ Event *nextEvent();
};
/*
* Header.cpp
*/
+
#include "mpeg2/ts/Header.h"
namespace MPEG2
namespace TS
{
-const uint8_t SYNC_BYTE = 0x47;
-const uint8_t PACKET_SIZE = 188;
-
Header::Header(uint8_t *packet)
{
_sync_byte = packet[0x00];
_pid = ((packet[0x01] << 8) + packet[0x02]) & 0x1FFF;
_transport_scramble_control = (packet[0x03] & 0xc0) >> 6;
_adaptation_field_control = (packet[0x03] & 0x30) >> 4;
- _continuty_counter = packet[0x03] & 0x0F;
+ _continuity_counter = packet[0x03] & 0x0F;
}
} // TS
-} // MPEG2
\ No newline at end of file
+} // MPEG2
/*
* Header.h
*/
-#ifndef __MPEG2_TS_HEADER_H__
-#define __MPEG2_TS_HEADER_H__
+#pragma once
#include <stdint.h>
namespace TS
{
-extern const uint8_t SYNC_BYTE;
-extern const uint8_t PACKET_SIZE;
+enum
+{
+ SYNC_BYTE = 0x47,
+ PACKET_SIZE = 188,
+};
+
+enum
+{
+ PID_PAT = 0x0000,
+ PID_CAT = 0x0001,
+ PID_NIT = 0x0010,
+ PID_SDT_BAT = 0x0011,
+ PID_EIT_0012 = 0x0012,
+ PID_EIT_0026 = 0x0026,
+ PID_EIT_0027 = 0x0027,
+ PID_RST = 0x0013,
+ PID_TDT = 0x0014,
+};
class Header
{
uint16_t _pid; // 13
uint8_t _transport_scramble_control; // 2
uint8_t _adaptation_field_control; // 2
- uint8_t _continuty_counter; // 4
+ uint8_t _continuity_counter; // 4
Header(uint8_t *packet);
};
} // TS
} // MPEG2
-#endif
\ No newline at end of file
\r
Table::Table()\r
{\r
-// printf("Table()\n");\r
-// _section = NULL;\r
- _pid = 0x0FFF;\r
+ _pid = 0xFFFF;\r
_length = 0;\r
- _continuty_counter = 0;\r
}\r
\r
Table::~Table()\r
{\r
-// printf("~Table()\n");\r
-/*\r
- if (_section != NULL)\r
- {\r
- free(_section);\r
- }\r
-*/\r
}\r
\r
//\r
// CRC\r
//\r
-static int GetCrc32(\r
+int Table::GetCrc32(\r
unsigned char* data, // [in] CRC data\r
int len) // [in] CRC data length\r
{\r
\r
return crc;\r
}\r
-\r
+/*\r
bool Table::decode(uint8_t *packet)\r
{\r
bool result = false;\r
\r
Header header(packet);\r
- if (!header._transport_error)\r
+\r
+ if (header._transport_error)\r
+ {\r
+ printf("transport error.\n");\r
+ return false;\r
+ }\r
+\r
+ if (header._payload_unit_start)\r
{\r
+ _pid = header._pid;\r
+ _length = 0;\r
+ memset(_section, 0x00, sizeof(_section));\r
+ }\r
+\r
#if 0\r
- uint16_t length;\r
-// if (_section == NULL)\r
- if (header._payload_unit_start)\r
- {\r
- length = (((packet[0x06] << 8) + packet[0x07]) & 0x0FFF) + 3;\r
-// _section = (uint8_t *)malloc(length);\r
- memset(_section, 0x00, sizeof(_section));\r
- _length = (length < 183) ? length : 183;\r
- memcpy(_section, &packet[0x05], _length);\r
- }\r
- else\r
+ if ((_pid == header._pid) && (_continuity_counter == header._continuity_counter))\r
+ {\r
+ // adaptation_field_control\r
+ if (header._adaptation_field_control != 0x02)\r
{\r
- length = (((_section[0x01] << 8) + _section[0x02]) & 0x0FFF) + 3;\r
- uint16_t cpylen = ((length - _length) < 184) ? (length - _length) : 184;\r
- memcpy(&_section[_length], &packet[0x04], cpylen);\r
+ uint16_t length;\r
+ length = header._payload_unit_start ? ((((packet[0x06] << 8) + packet[0x07]) & 0x0FFF) + 3) : ((((_section[0x01] << 8) + _section[0x02]) & 0x0FFF) + 3);\r
+ uint8_t offset = 0x04;\r
+ if (header._adaptation_field_control == 0x03)\r
+ {\r
+ offset = offset + 1 + packet[0x04];\r
+ }\r
+ if (_length == 0)\r
+ {\r
+ // pointer_field\r
+ offset += 1;\r
+ }\r
+ uint16_t cpylen = ((length - _length) < (PACKET_SIZE - offset)) ? (length - _length) : (PACKET_SIZE - offset);\r
+\r
+ memcpy(&_section[_length], &packet[offset], cpylen);\r
_length += cpylen;\r
- }\r
+ _continuty_counter++;\r
\r
- if (_length == length)\r
- {\r
- // check CRC\r
-// if (true) // check CRC\r
- if (GetCrc32(_section, _length) == 0)\r
+ if (_length == length)\r
{\r
- // decode\r
-if (_length > 184)\r
-{\r
- printf("check %d\n", _length);\r
- abort();\r
-}\r
- result = decode_section();\r
+ if (GetCrc32(_section, _length) == 0)\r
+ {\r
+ // decode\r
+ result = decode_section();\r
+ }\r
}\r
-// free(_section);\r
-// _section = NULL;\r
}\r
-#else\r
+ }\r
+#endif\r
\r
- // check payload_unit_start\r
- if (header._payload_unit_start)\r
+ return result;\r
+}\r
+*/\r
+bool Table::decode(Header *header, uint8_t *packet)\r
+{\r
+ bool result = false;\r
+\r
+ if (header->_adaptation_field_control != 0x02)\r
+ {\r
+ uint16_t length;\r
+ length = header->_payload_unit_start ? ((((packet[0x06] << 8) + packet[0x07]) & 0x0FFF) + 3) : ((((_section[0x01] << 8) + _section[0x02]) & 0x0FFF) + 3);\r
+ uint8_t offset = 0x04;\r
+ if (header->_adaptation_field_control == 0x03)\r
{\r
- _pid = header._pid;\r
- _continuty_counter = header._continuty_counter;\r
- _length = 0;\r
- memset(_section, 0x00, sizeof(_section));\r
+ offset = offset + packet[0x04];\r
}\r
- if ((_pid == header._pid) && (_continuty_counter == header._continuty_counter))\r
+\r
+ if (header->_payload_unit_start)\r
{\r
- // adaptation_field_control\r
- if (header._adaptation_field_control != 0x02)\r
+ if (_length != 0)\r
{\r
- uint16_t length;\r
- length = header._payload_unit_start ? ((((packet[0x06] << 8) + packet[0x07]) & 0x0FFF) + 3) : ((((_section[0x01] << 8) + _section[0x02]) & 0x0FFF) + 3);\r
- uint8_t offset = 0x04;\r
- if (header._adaptation_field_control == 0x03)\r
- {\r
- offset = offset + 1 + packet[0x04];\r
- }\r
- if (_length == 0)\r
- {\r
- // pointer_field\r
- offset += 1;\r
- }\r
- uint16_t cpylen = ((length - _length) < (PACKET_SIZE - offset)) ? (length - _length) : (PACKET_SIZE - offset);\r
-\r
- memcpy(&_section[_length], &packet[offset], cpylen);\r
- _length += cpylen;\r
- _continuty_counter++;\r
-\r
- if (_length == length)\r
+ if (packet[offset] != 0)\r
{\r
- if (GetCrc32(_section, _length) == 0)\r
- {\r
- // decode\r
-/*\r
- if (_length > 184)\r
- {\r
- printf("check %d\n", _length);\r
- abort();\r
- }\r
-*/\r
- result = decode_section();\r
-// _length = 0;\r
- }\r
+ memcpy(&_section[_length], &packet[offset + 1], packet[offset]);\r
}\r
+ result = decode_section();\r
+ _length = 0;\r
}\r
- }\r
\r
-#endif\r
+ offset += (1 + packet[offset]);\r
+ }\r
\r
- }\r
- else\r
- {\r
-// printf("transport error.\n");\r
+ memcpy(&_section[_length], &packet[offset], PACKET_SIZE - offset);\r
+ _length += (PACKET_SIZE - offset);\r
}\r
\r
return result;\r
\r
void Table::reset()\r
{\r
+ printf("Table::reset\n");\r
+ _pid = 0xFFFF;\r
+ _length = 0;\r
+ memset(_section, 0x00, sizeof(_section));\r
}\r
\r
static int getBit(unsigned char *byte, int *pbit, int gbit)\r
result = parseContentDescriptor(buf, &descriptor->content);\r
break;\r
\r
+ case 0x50: // Component\r
+// result = parseComponentDescriptor(hoge);\r
+ result = descriptor->other.descriptor_length + 2;\r
+ break;\r
+\r
+ case 0xC4: // Audio Component \r
+// result = parseAudioComponentDescriptor(hoge);\r
+ result = descriptor->other.descriptor_length + 2;\r
+ break;\r
+\r
+\r
case 0xD5: // Series descriptor\r
+// result = parseSeriesDescriptor(hoge);\r
+ result = descriptor->other.descriptor_length + 2;\r
+ break;\r
+\r
default:\r
memcpy(&descriptor->other.descriptor[0], &buf[0x02], descriptor->other.descriptor_length);\r
+ result = descriptor->other.descriptor_length + 2;\r
break;\r
}\r
}\r
/*\r
* Table.h\r
*/\r
-#ifndef __MPEG2_TS_TABLE_H__\r
-#define __MPEG2_TS_TABLE_H__\r
+\r
+#pragma once\r
\r
#include <stdio.h>\r
#include <stdlib.h>\r
#include <stdint.h>\r
#include <string.h>\r
\r
+#include "mpeg2/ts/Header.h"\r
+\r
namespace MPEG2\r
{\r
namespace TS\r
static const int MAX_SECT_LEN = 4096;\r
static const int MAX_DESC_LEN = 255;\r
\r
+enum\r
+{\r
+ TABLE_ID_PAT = 0x00,\r
+ TABLE_ID_PMT = 0x02\r
+};\r
+\r
+enum\r
+{\r
+ TAG_BOUQUET_NAME_DESCRIPTOR = 0x47,\r
+ TAG_SERVICE_DESCRIPTOR = 0x48,\r
+ TAG_SHORT_EVENT_DESCRIPTOR = 0x4D,\r
+ TAG_EXTENDED_EVENT_DESCRIPTOR = 0x4E,\r
+ TAG_COMPONENT_DESCRIPTOR = 0x50,\r
+ TAG_CONTENT_DESCRIPTOR = 0x54,\r
+ TAG_SERIES_DESCRIPTOR = 0xD5,\r
+ TAG_EVENT_GROUP_DESCRIPTOR = 0xD6,\r
+ TAG_DIGITAL_COPY_CONTROL_DESCRIPTOR = 0xC1,\r
+ TAG_AUDIO_COMPONENT_DESCRIPTOR = 0xC4,\r
+};\r
+\r
// 6.2.1 Bouquet name descriptor\r
typedef struct _BouquetNameDescriptor\r
{\r
} Descriptor;\r
\r
\r
-enum\r
-{\r
- TABLE_ID_PAT = 0x00,\r
- TABLE_ID_PMT = 0x02\r
-};\r
-\r
-enum\r
-{\r
- TAG_BOUQUET_NAME_DESCRIPTOR = 0x47,\r
- TAG_SERVICE_DESCRIPTOR = 0x48,\r
- TAG_SHORT_EVENT_DESCRIPTOR = 0x4D,\r
- TAG_EXTENDED_EVENT_DESCRIPTOR = 0x4E,\r
- TAG_CONTENT_DESCRIPTOR = 0x54,\r
- TAG_SERIES_DESCRIPTOR = 0xD5,\r
-};\r
\r
class Table\r
{\r
protected:\r
uint16_t _pid;\r
- uint8_t _continuty_counter;\r
uint16_t _length;\r
uint8_t _section[MAX_SECT_LEN];\r
\r
virtual bool decode_section();\r
\r
-\r
public:\r
Table();\r
virtual ~Table();\r
- bool decode(uint8_t *packet);\r
- virtual void reset();\r
+// bool decode(uint8_t *packet);\r
+ bool decode(Header *header, uint8_t *packet);\r
+ void reset();\r
\r
static uint16_t parseDescriptor(uint8_t *buf, uint16_t length, Descriptor *descriptor);\r
+\r
+\r
+public:\r
+ static int GetCrc32(unsigned char* data, int length);\r
};\r
\r
} // TS\r
} // MPEG2\r
-#endif\r
-\r
+++ /dev/null
-//\r
-// const.h\r
-//\r
-\r
-#ifndef __MPEG2_TS_CONST_H__\r
-#define __MPEG2_TS_CONST_H__\r
-\r
-#include <stdint.h>\r
-\r
-namespace MPEG2\r
-{\r
-namespace TS\r
-{\r
-\r
-static const unsigned char SYNC_BYTE = 0x47;\r
-static const unsigned char PACKET_SIZE = 188;\r
-\r
-} // ts\r
-} // mpeg2\r
-\r
-#endif // __MPEG2_TS_CONST_H__
\ No newline at end of file
\r
#include "ry0/iPTd/Controller.h"\r
#include "ry0/iPTd/HTTPLiveStreaming.h"\r
-#include "mpeg2/ts/Analyzer.h"\r
+#include "ry0/iPTd/Analyzer.h"\r
\r
+#include "b25/aribstr.h"\r
#include "b25/arib_std_b25.h"\r
#include "b25/b_cas_card.h"\r
\r
//\r
static const TimeInterval DEF_COLLECT_EPG_DELAY = 1.0;\r
static const TimeInterval DEF_COLLECT_EPG_RETRY = 60.0;\r
-static const TimeInterval DEF_COLLECT_EPG_LIMIT_S = 10.5;\r
-static const TimeInterval DEF_COLLECT_EPG_LIMIT_T = 20.5;\r
+\r
+static const time_t DEF_COLLECT_EPG_LIMIT_S = 20;\r
+static const time_t DEF_COLLECT_EPG_LIMIT_T = 30;\r
\r
static const time_t OFFSET_OF_START_TIME = -2; // 録画開始時刻の補正(秒単位)\r
static const time_t OFFSET_OF_END_TIME = -3; // 録画停止時刻の補正(秒単位)\r
RaymUnlock(this);\r
}\r
\r
-void Controller::collectEPGsForTuner(int tuner, TimeInterval limit)\r
+void Controller::collectEPGsForTuner(int tuner, time_t limit)\r
{\r
DebugLog2("Controller::collectEPGsForTuner(%d) start.", tuner);\r
\r
return;\r
}\r
\r
- // \r
- Array *collected = Array::arrayWithCapacity(0);\r
-\r
- // 開始時刻取得\r
- Date *start = Date::date();\r
-\r
- // 取得開始\r
- bool done = false;\r
- while (!done)\r
- {\r
- AutoreleasePool *pool = AutoreleasePool::alloc()->init();\r
\r
- // EPG取得\r
- MPEG2::TS::Analyzer an;\r
- an.setFlag(MPEG2::TS::Analyzer::FLAG_EIT);\r
- _tuners[tuner]->setListener(&an);\r
- Array *epgs = an.epgInfos();\r
- _tuners[tuner]->setListener(NULL);\r
+ Analyzer *an = Analyzer::alloc()->init();\r
+ _tuners[tuner]->setListener(an);\r
\r
- if (epgs != NULL)\r
- {\r
- // 取得成功\r
- collected->addObjectsFromArray(epgs);\r
- }\r
+ Array *collected = an->collectEPGs(limit);\r
\r
- // リミットチェック\r
- if (Date::date()->timeIntervalSinceDate(start) >= limit)\r
- {\r
- done = true;\r
- }\r
-\r
- // キャンセル確認\r
- RaymLock(this);\r
- if (!done)\r
- {\r
- done = _cancel_epg_collect;\r
- }\r
- RaymUnlock(this);\r
-\r
- pool->release();\r
- }\r
+ _tuners[tuner]->setListener(NULL);\r
+ an->release();\r
\r
// lock\r
RaymLock(this);\r
\r
+ long add_cnt = 0;\r
+ long discard = 0;\r
+\r
for (uint j = 0; j < collected->count(); ++j)\r
{\r
Dictionary *epg1 = (Dictionary *)collected->objectAtIndex(j);\r
if (epg1->stringForKey(KEY_EPG_TITLE) == NULL)\r
{\r
// タイトルが無い場合は不要\r
+ ++discard;\r
+// DebugLog0("discard: %s", epg1->toString().c_str());\r
continue;\r
}\r
\r
key = epg1->stringForKey(KEY_EPG_EVENT_ID);\r
if (key != NULL)\r
{\r
+ ++add_cnt;\r
epgs_of_service->setObject(epg1, key);\r
}\r
}\r
}\r
+ DebugLog0("add: %d, discard: %d", add_cnt, discard);\r
\r
// ファイルへ書き出し\r
_epgs->writeToFile(_epgs_path, true);\r
// チャンネル設定\r
if (_tuners[tuner]->setChannel(ch))\r
{\r
+ DebugLog0(" %s: channel: %d", _tuners[tuner]->name(), ch);\r
+\r
// EPG取集\r
collectEPGsForTuner(tuner, ((type == Tuner::ISDB_S) ? DEF_COLLECT_EPG_LIMIT_S : DEF_COLLECT_EPG_LIMIT_T));\r
\r
channelInfo->setBool(true, KEY_ENABLED);\r
\r
// 局情報を取得\r
- MPEG2::TS::Analyzer an;\r
- an.setFlag(MPEG2::TS::Analyzer::FLAG_SDT);\r
- _tuners[tuner]->setListener(&an);\r
- uint32_t count = 0;\r
- while (count++ < 8)\r
- {\r
- Dictionary *stationInfo = an.stationInfo();\r
- if (stationInfo != NULL)\r
+ Analyzer *an = Analyzer::alloc()->init();\r
+ _tuners[tuner]->setListener(an);\r
+\r
+ Dictionary *stationInfo = an->stationInfo();\r
+ if (stationInfo != NULL)\r
+ {\r
+ if (stationInfo->stringForKey(KEY_NAME) != NULL)\r
{\r
- if (stationInfo->stringForKey(KEY_NAME) != NULL)\r
- {\r
- channelInfo->setString(stationInfo->stringForKey(KEY_NAME), KEY_NAME);\r
- }\r
- if (stationInfo->objectForKey(KEY_SERVICES) != NULL)\r
- {\r
- channelInfo->setObject(stationInfo->objectForKey(KEY_SERVICES), KEY_SERVICES);\r
- }\r
+ channelInfo->setString(stationInfo->stringForKey(KEY_NAME), KEY_NAME);\r
}\r
-\r
- if ((channelInfo->stringForKey(KEY_NAME) != NULL) && (channelInfo->objectForKey(KEY_SERVICES) != NULL))\r
+ if (stationInfo->objectForKey(KEY_SERVICES) != NULL)\r
{\r
- break;\r
+ channelInfo->setObject(stationInfo->objectForKey(KEY_SERVICES), KEY_SERVICES);\r
+ }\r
+ if (channelInfo->stringForKey(KEY_NAME) != NULL)\r
+ {\r
+ DebugLog0(" Name: %s", channelInfo->stringForKey(KEY_NAME)->cString());\r
}\r
}\r
\r
- if (channelInfo->stringForKey(KEY_NAME) != NULL)\r
- {\r
- DebugLog0(" Name: %s", channelInfo->stringForKey(KEY_NAME)->cString());\r
- }\r
_tuners[tuner]->setListener(NULL);\r
+ an->release();\r
\r
// 成功したチャンネルを保持\r
lastChannel = ch;\r
DebugLog0(" CH %s: NG", chkey);\r
}\r
\r
- // unlock\r
RaymUnlock(this);\r
}\r
\r
- // lock\r
RaymLock(this);\r
\r
// チューナを初期化済みに更新\r
{\r
// 初期化成功\r
DebugLog2("tuner initialize success.");\r
-\r
+#if 0\r
// EPG収集用タイマ起動(ISDB-S)\r
_timer_epg_s = Timer::alloc()->initWithTimeInterval(DEF_COLLECT_EPG_DELAY, this, (void *)CMD_COLLECT_EPG_ISDB_S, true);\r
if (_timer_epg_s != NULL)\r
{\r
_timer_epg_s->fire();\r
}\r
-\r
+#endif\r
+#if 1\r
// EPG収集用タイマ起動(ISDB-T)\r
_timer_epg_t = Timer::alloc()->initWithTimeInterval(DEF_COLLECT_EPG_DELAY, this, (void *)CMD_COLLECT_EPG_ISDB_T, true);\r
if (_timer_epg_t != NULL)\r
{\r
_timer_epg_t->fire();\r
}\r
+#endif\r
}\r
else\r
{\r
\r
#include "net/HTTPDaemon.h"\r
\r
-#define VERSION "0.02"\r
-#define REVISION 19\r
+#define VERSION "0.03"\r
+#define REVISION 20\r
\r
namespace ry0\r
{\r
static void getTimeWithEPG(Raym::Dictionary *epg, time_t *start, time_t *end);\r
\r
// EPG & 予約録画関連\r
- void collectEPGsForTuner(int tuner, Raym::TimeInterval limit);\r
+ void collectEPGsForTuner(int tuner, time_t limit);\r
bool collectEPGs(ry0::device::Tuner::Type type);\r
void removePastEPGs();\r
bool reserve(int service_id, int event_id);\r