friend void RaymLock(Object *);\r
friend void RaymUnlock(Object *);\r
friend void RaymCondWait(Object *);\r
+ friend void RaymCondTimedWait(Object *, int msec);\r
friend void RaymCondSignal(Object *);\r
friend void RaymCondBroadcast(Object *);\r
};\r
#endif\r
\r
#ifndef RAYM_MUTEX_CHECK\r
+inline void RaymCondTimedWait(Object *obj, int msec)\r
+{\r
+#ifdef _WIN32\r
+ SleepConditionVariableCS(&(obj->_cond), &(obj->_cs), (DWORD)msec);\r
+#else\r
+#endif\r
+}\r
+#else\r
+#ifdef _WIN32\r
+#define RaymCondTimedWait(obj, msec) \\r
+ DebugLog3("before wait: %s %d", __FILE__, __LINE__); \\r
+ SleepConditionVariableCS(&(obj->_cond), &(obj->_cs), (DWORD)msec); \\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
bool result = false;\r
if (string != NULL)\r
{\r
+ if (_str == NULL)\r
+ {\r
+ DebugLog0("String::isEqualToString() : _str == NULL");\r
+ }\r
+ if (string->_str == NULL)\r
+ {\r
+ DebugLog0("String::isEqualToString() : string->_str == NULL");\r
+ }\r
result = (strcmp(_str, string->_str) == 0);\r
}\r
return result;\r
#define KEY_EPG_DATE "Date"\r
#define KEY_EPG_START "Start"\r
#define KEY_EPG_END "End"\r
+#define KEY_EPG_DURATION "Duration"\r
#define KEY_EPG_TITLE "Title"\r
#define KEY_EPG_DESCRIPTION "Description"\r
#define KEY_EPG_CHANNEL "Channel"\r
#define KEY_EPG_REPEAT "Repeat"\r
#define KEY_EPG_KEYWORDS "Keywords"\r
#define KEY_EPG_RESERVED_BY_KEYWORDS "Reserved by keywords"\r
+#define KEY_EPG_EXT_ITEM_DESCRIPTION "Extended Item Description"\r
+#define KEY_EPG_EXT_ITEM "Extended Item"\r
+#define KEY_EPG_EXT_ITEMS "Extended Items"\r
\r
// ローカライズ用キー\r
#define KEY_I18N_Main_Menu "Main Menu"\r
-/*\r
- * EIT.cpp\r
- * PTxSystem\r
- *\r
- * Created by Ryosuke Mitachi on 11/08/24.\r
- * Copyright 2011 __MyCompanyName__. All rights reserved.\r
+/**\r
+ * @file EIT.cpp\r
*\r
*/\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
+ _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
+ _event_offset = eit._event_offset;\r
+ _length = eit._length;\r
memcpy(_event_data, eit._event_data, sizeof(_event_data));\r
}\r
\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
+ if ((TABLE_ID_SELF <= _table_id) && (_table_id <= TABLE_ID_OTHER_SCHEDULE_END))\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
+ _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
result = true;\r
}\r
}\r
- else\r
- {\r
- printf("table id error. %d\n", _table_id);\r
- reset();\r
- }\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
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
_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
+ _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._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
+\r
return &_event;\r
}\r
- else\r
- {\r
-printf("check 001\n");\r
- }\r
- }\r
- else\r
- {\r
-printf("check 002\n");\r
}\r
+\r
_event._event_id = 0;\r
_event._descriptors_loop_length = 0;\r
return NULL;\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
-//
-// EIT.h
-//
-
-#ifndef __MPEG2_TS_EIT_H__
-#define __MPEG2_TS_EIT_H__
-
-#include "mpeg2/ts/Table.h"
-
-namespace MPEG2
-{
-
-namespace TS
-{
-
-#define MAXSECLEN 4096
-
-typedef struct _EIThead {
- char table_id;
- int section_syntax_indicator;
- int reserved_future_use;
- int reserved1;
- int section_length;
- int service_id;
- int reserved2;
- int version_number;
- int current_next_indicator;
- int section_number;
- int last_section_number;
- int transport_stream_id;
- int original_network_id;
- int segment_last_section_number;
- int last_table_id;
-} EIThead;
-
-typedef struct _EITbody {
- int event_id;
- char start_time[5];
- char duration[3];
- int running_status;
- int free_CA_mode;
- int descriptors_loop_length;
-
- //
- int yy;
- int mm;
- int dd;
- int hh;
- int hm;
- int ss;
- int dhh;
- int dhm;
- int dss;
-} EITbody;
-
-typedef struct _SEVTdesc {
- int descriptor_tag;
- int descriptor_length;
- char ISO_639_language_code[3];
- int event_name_length;
- char event_name[MAXSECLEN];
- int text_length;
- char text[MAXSECLEN];
-} SEVTdesc;
-
-typedef struct _EEVTDhead {
- int descriptor_tag;
- int descriptor_length;
- int descriptor_number;
- int last_descriptor_number;
- char ISO_639_language_code[3];
- int length_of_items;
-} EEVTDhead;
-
-typedef struct _EEVTDitem {
- int item_description_length;
- char item_description[MAXSECLEN];
- int item_length;
- char item[MAXSECLEN];
-
- //
- int descriptor_number;
-} EEVTDitem;
-
-typedef struct _EEVTDtail {
- int text_length;
- char text[MAXSECLEN];
-} EEVTDtail;
-
-typedef struct _ContentDesc {
- int descriptor_tag;
- int descriptor_length;
- char content[MAXSECLEN];
-} ContentDesc;
-
-typedef struct _SeriesDesc {
- int descriptor_tag;
- int descriptor_length;
- int series_id;
- int repeat_label;
- int program_pattern;
- int expire_date_valid_flag;
- int expire_date;
- int episode_number;
- int last_episode_number;
- char series_name_char[MAXSECLEN];
-} SeriesDesc;
-
-class EIT : public Table
-{
-protected:
- bool decode_section();
-
-public:
- uint8_t _table_id; // 8
- uint8_t _section_syntax_indicator; // 1
- // 1 '1'
- // 2 '11'
- uint16_t _section_length; // 12
- uint16_t _service_id; // 16
- // 2 '11'
- uint8_t _version_number; // 5
- uint8_t _current_next_indicator; // 1
- uint8_t _section_number; // 8
- uint8_t _last_section_number; // 8
- uint16_t _transport_stream_id; // 16
- uint16_t _original_network_id; // 16
- uint8_t _segment_last_section_number; // 8
- uint8_t _last_table_id; // 8
-
- class Event
- {
-
- public:
- uint16_t _event_id; // 16
- // start_time 40
- uint16_t _st_year;
- uint8_t _st_month;
- uint8_t _st_day;
- uint8_t _st_hour;
- uint8_t _st_min;
- uint8_t _st_sec;
- // duration 24
- uint8_t _dur_hour;
- uint8_t _dur_min;
- uint8_t _dur_sec;
- uint8_t _running_status; // 3
- uint8_t _free_CA_mode; // 1
- uint16_t _descriptors_loop_length; // 12
-
- uint8_t * _descriptor_ptr;
- uint16_t _descriptor_offset;
- Descriptor _descriptor;
- Descriptor *nextDescriptor();
- };
-
- uint8_t _event_data[MAX_SECT_LEN];
- uint16_t _event_offset;
- Event _event;
-
-public:
- EIT();
- EIT(EIT &eit);
- ~EIT();
- void reset();
-
- Event *nextEvent();
-};
-
-
-} // TS
-} // MPEG2
-#endif
+/**\r
+ * @file EIT.h\r
+ *\r
+ */\r
+\r
+#pragma once\r
+\r
+#include "mpeg2/ts/Table.h"\r
+\r
+namespace MPEG2\r
+{\r
+\r
+namespace TS\r
+{\r
+\r
+class EIT : public Table\r
+{\r
+protected:\r
+ bool decode_section();\r
+\r
+public:\r
+ /*\r
+ * 0x4E : EIT(自ストリームの現在と次の番組)\r
+ * 0x4F : EIT(他ストリームの現在と次の番組)\r
+ * 0x50 - 0x5F : EIT(自ストリーム、スケジュール)\r
+ * 0x60 - 0x6F : EIT(他ストリーム、スケジュール)\r
+ */\r
+ enum\r
+ {\r
+ TABLE_ID_SELF = 0x4E,\r
+ TABLE_ID_OTHER = 0x4F,\r
+ TABLE_ID_SELF_SCHEDULE_BEGIN = 0x50,\r
+ TABLE_ID_SELF_SCHEDULE_END = 0x5F,\r
+ TABLE_ID_OTHER_SCHEDULE_BEGIN = 0x60,\r
+ TABLE_ID_OTHER_SCHEDULE_END = 0x6F\r
+ };\r
+\r
+ uint8_t _table_id; // 8\r
+ uint8_t _section_syntax_indicator; // 1\r
+ // 1 '1'\r
+ // 2 '11'\r
+ uint16_t _section_length; // 12\r
+ uint16_t _service_id; // 16\r
+ // 2 '11'\r
+ uint8_t _version_number; // 5\r
+ uint8_t _current_next_indicator; // 1\r
+ uint8_t _section_number; // 8\r
+ uint8_t _last_section_number; // 8\r
+ uint16_t _transport_stream_id; // 16\r
+ uint16_t _original_network_id; // 16\r
+ uint8_t _segment_last_section_number; // 8\r
+ uint8_t _last_table_id; // 8\r
+\r
+ class Event\r
+ {\r
+\r
+ public:\r
+ uint16_t _event_id; // 16\r
+ // start_time 40\r
+ uint16_t _st_year;\r
+ uint8_t _st_month;\r
+ uint8_t _st_day;\r
+ uint8_t _st_hour;\r
+ uint8_t _st_min;\r
+ uint8_t _st_sec;\r
+ // duration 24\r
+ uint8_t _dur_hour;\r
+ uint8_t _dur_min;\r
+ uint8_t _dur_sec;\r
+ uint8_t _running_status; // 3\r
+ uint8_t _free_CA_mode; // 1\r
+ uint16_t _descriptors_loop_length; // 12\r
+\r
+ uint8_t * _descriptor_ptr;\r
+ uint16_t _descriptor_offset;\r
+ Descriptor _descriptor;\r
+ Descriptor *nextDescriptor();\r
+ };\r
+\r
+ uint8_t _event_data[MAX_SECT_LEN];\r
+ uint16_t _event_offset;\r
+ Event _event;\r
+\r
+public:\r
+ EIT();\r
+ EIT(EIT &eit);\r
+ ~EIT();\r
+ void reset();\r
+\r
+ Event *nextEvent();\r
+};\r
+\r
+} // TS\r
+} // MPEG2\r
-/*
- * Header.cpp
+/**
+ * @file Header.cpp
+ *
*/
#include "mpeg2/ts/Header.h"
-/*
- * Header.h
+/**
+ * @file Header.h
+ *
*/
#pragma once
-/*
- * PAT.cpp
+/**
+ * @file PAT.cpp
+ *
*/
+
#include "mpeg2/ts/PAT.h"
namespace MPEG2
bool PAT::decode_section()
{
bool result = true;
- _table_id = _section[0x00];
+ _table_id = _section[0x00];
if (_table_id == TABLE_ID_PAT)
{
_section_syntax_indicator = (_section[0x01] & 0x80) >> 7;
}
} // TS
-} // MPEG2
\ No newline at end of file
+} // MPEG2
-/*
- * PAT.h
+/**
+ * @file PAT.h
+ *
*/
-#ifndef __MPEG2_TS_PAT_H__
-#define __MPEG2_TS_PAT_H__
+
+#pragma once
#include "mpeg2/ts/Table.h"
class PAT : public Table
{
public:
- uint8_t _table_id; // 8
- uint8_t _section_syntax_indicator; // 1
- // 1 '0'
- // 2 reserved
- uint16_t _section_length; // 12
- uint16_t _transport_stream_id; // 16
- // 2 reserved
- uint8_t _version_number; // 5
- uint8_t _current_next_indicator; // 1
- uint8_t _section_number; // 8
- uint8_t _last_section_number; // 8
- uint16_t _program_count;
- struct _program {
- uint16_t _program_number; // 16
- // 3 reserved
- uint16_t _pid; // 13
- } *_programs;
- // 32 CRC
+ uint8_t _table_id; // 8
+ uint8_t _section_syntax_indicator; // 1
+ // 1 '0'
+ // 2 reserved
+ uint16_t _section_length; // 12
+ uint16_t _transport_stream_id; // 16
+ // 2 reserved
+ uint8_t _version_number; // 5
+ uint8_t _current_next_indicator; // 1
+ uint8_t _section_number; // 8
+ uint8_t _last_section_number; // 8
+ uint16_t _program_count;
+ struct _program
+ {
+ uint16_t _program_number; // 16
+ // 3 reserved
+ uint16_t _pid; // 13
+ } * _programs;
+ // 32 CRC
protected:
bool decode_section();
} // TS
} // MPEG2
-#endif
\ No newline at end of file
-/*
- * PMT.cpp
+/**
+ * @file PMT.cpp
+ *
*/
#include "mpeg2/ts/PMT.h"
bool PMT::decode_section()
{
bool result = true;
- _table_id = _section[0x00];
+ _table_id = _section[0x00];
if (_table_id == TABLE_ID_PMT)
{
_section_syntax_indicator = (_section[0x01] & 0x80) >> 7;
{
free(_descriptor);
}
- _descriptor = (uint8_t *)malloc(_program_info_length);
+ _descriptor = (uint8_t *)malloc(_program_info_length);
memcpy(_descriptor, &_section[0x0c], _program_info_length);
if (_elements != NULL)
{
_elements = (struct _element *)realloc(_elements, sizeof(struct _element) * (_element_count + 1));
}
- _elements[_element_count]._stream_type = _section[offset];
+ _elements[_element_count]._stream_type = _section[offset];
_elements[_element_count]._elementary_PID = ((_section[offset + 1] << 8) + _section[offset + 2]) & 0x1FFF;
_elements[_element_count]._ES_info_length = ((_section[offset + 3] << 8) + _section[offset + 4]) & 0x0FFF;
- _elements[_element_count]._descriptor = (uint8_t *)malloc(_elements[_element_count]._ES_info_length);
+ _elements[_element_count]._descriptor = (uint8_t *)malloc(_elements[_element_count]._ES_info_length);
memcpy(_elements[_element_count]._descriptor, &_section[offset + 5], _elements[_element_count]._ES_info_length);
offset += (5 + _elements[_element_count]._ES_info_length);
_element_count++;
void PMT::reset()
{
+ _table_id = 0;
_section_syntax_indicator = 0;
_section_length = 0;
_program_number = 0;
}
} // TS
-} // MPEG2
\ No newline at end of file
+} // MPEG2
-/*
- * PMT.h
+/**
+ * @file PMT.h
+ *
*/
-#ifndef __MPEG2_TS_PMT_H__
-#define __MPEG2_TS_PMT_H__
+
+#pragma once
#include "mpeg2/ts/Table.h"
class PMT : public Table
{
public:
- uint8_t _table_id; // 8
- uint8_t _section_syntax_indicator; // 1
- // 1 '0'
- // 2 reserved
- uint16_t _section_length; // 12
- uint16_t _program_number; // 16
- // 2 reserved
- uint8_t _version_number; // 5
- uint8_t _current_next_indicator; // 1
- uint8_t _section_number; // 8
- uint8_t _last_section_number; // 8
- // 3 reserved
- uint16_t _PCR_PID; // 13
- // 4 reserved
- uint16_t _program_info_length; // 12
- uint8_t * _descriptor; // N
- uint16_t _element_count;
+ uint8_t _table_id; // 8
+ uint8_t _section_syntax_indicator; // 1
+ // 1 '0'
+ // 2 reserved
+ uint16_t _section_length; // 12
+ uint16_t _program_number; // 16
+ // 2 reserved
+ uint8_t _version_number; // 5
+ uint8_t _current_next_indicator; // 1
+ uint8_t _section_number; // 8
+ uint8_t _last_section_number; // 8
+ // 3 reserved
+ uint16_t _PCR_PID; // 13
+ // 4 reserved
+ uint16_t _program_info_length; // 12
+ uint8_t * _descriptor; // N
+ uint16_t _element_count;
struct _element
{
- uint8_t _stream_type; // 8
- // 3 reserved
- uint16_t _elementary_PID; // 13
- // 4 reserved
- uint16_t _ES_info_length; // 12
- uint8_t * _descriptor; // N
- } *_elements;
- // 32 CRC
+ uint8_t _stream_type; // 8
+ // 3 reserved
+ uint16_t _elementary_PID; // 13
+ // 4 reserved
+ uint16_t _ES_info_length; // 12
+ uint8_t * _descriptor; // N
+ } * _elements;
+ // 32 CRC
protected:
bool decode_section();
} // TS
} // MPEG2
-#endif
\ No newline at end of file
-/*\r
- * SDT.cpp\r
+/**\r
+ * @file SDT.cpp\r
+ *\r
*/\r
\r
#include "b25/aribstr.h"\r
-//
-// SDT.h
-//
-#ifndef __MPEG2_TS_SDT_H__
-#define __MPEG2_TS_SDT_H__
+/**
+ * @file SDT.h
+ *
+ */
+
+#pragma once
#include "mpeg2/ts/Table.h"
} // TS
} // MPEG2
-#endif
-
-
\r
return crc;\r
}\r
-/*\r
-bool Table::decode(uint8_t *packet)\r
-{\r
- bool result = false;\r
-\r
- Header header(packet);\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
- if ((_pid == header._pid) && (_continuity_counter == header._continuity_counter))\r
- {\r
- // adaptation_field_control\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
- 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
- {\r
- if (GetCrc32(_section, _length) == 0)\r
- {\r
- // decode\r
- result = decode_section();\r
- }\r
- }\r
- }\r
- }\r
-#endif\r
-\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
if (packet[offset] != 0)\r
{\r
memcpy(&_section[_length], &packet[offset + 1], packet[offset]);\r
+ _length += packet[offset];\r
}\r
result = decode_section();\r
_length = 0;\r
return result;\r
}\r
\r
-bool Table::decode_section()\r
-{\r
- return false;\r
-}\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
+static uint16_t parseServiceDescriptor(uint8_t *buf, ServiceDescriptor *service)\r
{\r
- int pbyte = *pbit / 8;\r
- unsigned char *fbyte = byte + pbyte;\r
-\r
- int cutbit = *pbit - (pbyte * 8);\r
- int lcutbit = 32 - (cutbit + gbit);\r
-\r
- unsigned char tbuf[4]; //\r
- unsigned int tnum;\r
-\r
- memcpy(tbuf, fbyte, sizeof(unsigned char) * 4);\r
-\r
- //\r
- tbuf[0] = tbuf[0] << cutbit;\r
- tbuf[0] = tbuf[0] >> cutbit;\r
-\r
- //\r
- tnum = tbuf[0] << 24 | tbuf[1] << 16 | tbuf[2] << 8 | tbuf[3];\r
-\r
- //\r
- tnum = tnum >> lcutbit;\r
-\r
- *pbit += gbit;\r
-\r
- return tnum;\r
-}\r
-\r
-#define MAXSECLEN 4096\r
-\r
-static void getStr(char *tostr, unsigned char *byte, int *pbit, int len)\r
-{\r
- char str[MAXSECLEN];\r
- int pbyte = *pbit / 8;\r
- unsigned char *fbyte = byte + pbyte;\r
-\r
- memset(str, 0, sizeof(char) * MAXSECLEN);\r
- memcpy(str, fbyte, len);\r
-\r
- *pbit += (len * 8);\r
-\r
- AribToString(tostr, str, len);\r
-}\r
-\r
-static void getStr(char *tostr, unsigned char *byte, int len)\r
-{\r
- char str[MAXSECLEN];\r
-\r
- memset(str, 0, sizeof(char) * MAXSECLEN);\r
- memcpy(str, byte, len);\r
-\r
- AribToString(tostr, str, len);\r
-}\r
-\r
-static uint16_t parseContentDescriptor(uint8_t *buf, ContentDescriptor *content)\r
-{\r
-// printf("%s\n", __FUNCTION__);\r
- for (int i = 0; i < (content->descriptor_length / 2); ++i)\r
+ service->_descriptor_tag = buf[0];\r
+ service->_descriptor_length = buf[1];\r
+ service->_service_type = buf[2];\r
+ service->_service_provider_name_length = buf[3];\r
+ if (service->_service_provider_name_length > 0)\r
{\r
- content->contents[i].content_nibble_level_1 = (buf[i * 2 + 0x02] & 0xF0) >> 4;\r
- content->contents[i].content_nibble_level_2 = buf[i * 2 + 0x02] & 0x0F;\r
- content->contents[i].user_nibble_1 = (buf[i * 2 + 0x03] & 0xF0) >> 4;\r
- content->contents[i].user_nibble_2 = buf[i * 2 + 0x03] & 0x0F;\r
+ memcpy(service->_service_provider_name, &buf[4], service->_service_provider_name_length);\r
}\r
- return content->descriptor_length + 2;\r
+ service->_service_name_length = buf[4 + service->_service_provider_name_length];\r
+ if (service->_service_name_length > 0)\r
+ {\r
+ memcpy(service->_service_name, &buf[5 + service->_service_provider_name_length], service->_service_name_length);\r
+ }\r
+ return service->_descriptor_length + 2;\r
}\r
\r
static uint16_t parseShortEventDescriptor(uint8_t *buf, ShortEventDescriptor *short_event)\r
{\r
-// printf("%s\n", __FUNCTION__);\r
- uint16_t result = short_event->descriptor_length + 2;\r
-#if 0\r
- memcpy(&short_event->ISO_639_language_code[0], &buf[0x02], 3);\r
- short_event->event_name_length = buf[0x05];\r
- if ((short_event->event_name_length + 5) <= short_event->descriptor_length)\r
+ short_event->_descriptor_tag = buf[0];\r
+ short_event->_descriptor_length = buf[1];\r
+ memcpy(short_event->_ISO_639_language_code, &buf[2], 3);\r
+ short_event->_event_name_length = buf[5];\r
+ if (short_event->_event_name_length > 0)\r
{\r
-// memcpy(&short_event->event_name[0], &buf[0x06], short_event->event_name_length);\r
- getStr((char *)short_event->event_name, &buf[0x06], short_event->event_name_length);\r
- short_event->text_length = buf[short_event->event_name_length + 6];\r
- if ((short_event->text_length + short_event->event_name_length + 5) == short_event->descriptor_length)\r
- {\r
-// memcpy(&short_event->text[0], &buf[short_event->event_name_length + 6], short_event->text_length);\r
- getStr((char *)short_event->text, &buf[short_event->event_name_length + 6], short_event->text_length);\r
-// printf("%s() success.\n", __FUNCTION__);\r
- }\r
- else\r
- {\r
- printf("%s() event_name_length = %d\n", __FUNCTION__, short_event->event_name_length);\r
- printf("%s() text_length error. %d\n", __FUNCTION__, short_event->text_length);\r
- result = 0;\r
- }\r
+ memcpy(short_event->_event_name, &buf[6], short_event->_event_name_length);\r
}\r
- else\r
+ short_event->_text_length = buf[6 + short_event->_event_name_length];\r
+ if (short_event->_text_length > 0)\r
{\r
- printf("%s() descriptor_length = %d\n", __FUNCTION__, short_event->descriptor_length);\r
- printf("%s() event_name_length error. %d\n", __FUNCTION__, short_event->event_name_length);\r
- result = 0;\r
+ memcpy(short_event->_text, &buf[7 + short_event->_event_name_length], short_event->_text_length);\r
}\r
-#else\r
- int boff = 0;\r
-\r
- memset(short_event, 0, sizeof(ShortEventDescriptor));\r
-\r
- short_event->descriptor_tag = getBit(buf, &boff, 8);\r
- if ((short_event->descriptor_tag & 0xFF) == 0x4D)\r
- {\r
- short_event->descriptor_length = getBit(buf, &boff, 8);\r
- memcpy(short_event->ISO_639_language_code, buf + boff / 8, 3);\r
- /* desc->ISO_639_language_code = getBit(data, &boff, 24); */\r
- boff += 24;\r
-\r
- short_event->event_name_length = getBit(buf, &boff, 8);\r
-// memset((char *)short_event->event_name, 0x00, MAX_DESC_LEN);\r
-// getStr((char *)short_event->event_name, buf, &boff, short_event->event_name_length);\r
- memcpy((char *)short_event->event_name, buf + boff / 8, short_event->event_name_length);\r
- boff += short_event->event_name_length * 8;\r
-\r
- short_event->text_length = getBit(buf, &boff, 8);\r
-// memset((char *)short_event->text, 0x00, MAX_DESC_LEN);\r
-// getStr((char *)short_event->text, buf, &boff, short_event->text_length);\r
- memcpy((char *)short_event->text, buf + boff / 8, short_event->text_length);\r
- }\r
- else\r
- {\r
- result = false;\r
- }\r
-#endif\r
- return result;\r
+ return short_event->_descriptor_length + 2;\r
}\r
\r
static uint16_t parseExtendedEventDescriptor(uint8_t *buf, ExtendedEventDescriptor *extended)\r
{\r
-// printf("%s\n", __FUNCTION__);\r
- uint16_t result = extended->descriptor_length + 2;\r
-#if 1\r
- extended->descriptor_number = (buf[0x02] & 0xF0) >> 4;\r
- extended->last_descriptor_number = buf[0x02] & 0x0F;\r
- memcpy(&extended->ISO_639_language_code[0], &buf[0x03], 3);\r
- extended->length_of_items = buf[0x06];\r
- extended->item_count = 0;\r
- if ((extended->length_of_items + 6) <= extended->descriptor_length)\r
+ extended->_descriptor_tag = buf[0x00];\r
+ extended->_descriptor_length = buf[0x01];\r
+ extended->_descriptor_number = (buf[0x02] & 0xF0) >> 4;\r
+ extended->_last_descriptor_number = buf[0x02] & 0x0F;\r
+ memcpy(&extended->_ISO_639_language_code[0], &buf[0x03], 3);\r
+ extended->_length_of_items = buf[0x06];\r
+ extended->_item_count = 0;\r
+ if ((extended->_length_of_items + 6) <= extended->_descriptor_length)\r
{\r
- extended->text_length = 0;\r
- extended->text_length = buf[extended->length_of_items + 7];\r
- if ((extended->text_length + extended->length_of_items + 6) == extended->descriptor_length)\r
+ extended->_text_length = buf[extended->_length_of_items + 7];\r
+ if ((extended->_text_length + extended->_length_of_items + 6) == extended->_descriptor_length)\r
{\r
- memcpy(&extended->text[0], &buf[extended->length_of_items + 7], extended->text_length);\r
-// memset((char *)extended->text, 0x00, MAX_DESC_LEN);\r
-// getStr((char *)extended->text, &buf[extended->length_of_items + 7], extended->text_length);\r
+ memcpy(&extended->_text[0], &buf[extended->_length_of_items + 7], extended->_text_length);\r
\r
- int item_remain = extended->length_of_items;\r
+ int item_remain = extended->_length_of_items;\r
int item_offset = 0x07;\r
while (item_remain >= 2)\r
{\r
- extended->items[extended->item_count].item_description_length = buf[item_offset++];\r
- if (extended->items[extended->item_count].item_description_length > 0)\r
+ extended->_items[extended->_item_count]._item_description_length = buf[item_offset++];\r
+ if (extended->_items[extended->_item_count]._item_description_length > 0)\r
{\r
- memcpy(&extended->items[extended->item_count].item_description[0], &buf[item_offset],\r
- extended->items[extended->item_count].item_description_length);\r
-// memset((char *)&extended->items[extended->item_count].item_description[0], 0x00, MAX_DESC_LEN);\r
-// getStr((char *)&extended->items[extended->item_count].item_description[0], &buf[item_offset],\r
-// extended->items[extended->item_count].item_description_length);\r
- item_offset += extended->items[extended->item_count].item_description_length;\r
+ memcpy(&extended->_items[extended->_item_count]._item_description[0], &buf[item_offset],\r
+ extended->_items[extended->_item_count]._item_description_length);\r
+ item_offset += extended->_items[extended->_item_count]._item_description_length;\r
}\r
- item_remain -= (1 + extended->items[extended->item_count].item_description_length);\r
+ item_remain -= (1 + extended->_items[extended->_item_count]._item_description_length);\r
if (item_remain < 1)\r
{\r
printf("%s item desc len error.\n", __FUNCTION__);\r
- result = 0;\r
break;\r
}\r
\r
- extended->items[extended->item_count].item_length = buf[item_offset++];\r
- if (extended->items[extended->item_count].item_length > 0)\r
+ extended->_items[extended->_item_count]._item_length = buf[item_offset++];\r
+ if (extended->_items[extended->_item_count]._item_length > 0)\r
{\r
- memcpy(&extended->items[extended->item_count].item[0], &buf[item_offset],\r
- extended->items[extended->item_count].item_length);\r
-// memset((char *)&extended->items[extended->item_count].item[0], 0x00, MAX_DESC_LEN);\r
-// getStr((char *)&extended->items[extended->item_count].item[0], &buf[item_offset],\r
-// extended->items[extended->item_count].item_length);\r
- item_offset += extended->items[extended->item_count].item_length;\r
+ memcpy(&extended->_items[extended->_item_count]._item[0], &buf[item_offset],\r
+ extended->_items[extended->_item_count]._item_length);\r
+ item_offset += extended->_items[extended->_item_count]._item_length;\r
}\r
- item_remain -= (1 + extended->items[extended->item_count].item_length);\r
+ item_remain -= (1 + extended->_items[extended->_item_count]._item_length);\r
if ((item_remain < 0) || (item_remain == 1))\r
{\r
printf("%s item len error. %d\n", __FUNCTION__, item_remain);\r
- result = 0;\r
break;\r
}\r
- else {\r
-// printf("eevt success.\n");\r
- }\r
\r
- ++extended->item_count;\r
+ ++extended->_item_count;\r
}\r
}\r
- else\r
- {\r
- printf("%s() length_of_items = %d\n", __FUNCTION__, extended->length_of_items);\r
- printf("%s() text_length error. %d\n", __FUNCTION__, extended->text_length);\r
- result = 0;\r
- }\r
}\r
- else\r
+\r
+ return extended->_descriptor_length + 2;\r
+}\r
+\r
+static uint16_t parseComponentDescriptor(uint8_t *buf, ComponentDescriptor *component)\r
+{\r
+ component->_descriptor_tag = buf[0];\r
+ component->_descriptor_length = buf[1];\r
+\r
+ return component->_descriptor_length + 2;\r
+}\r
+\r
+static uint16_t parseContentDescriptor(uint8_t *buf, ContentDescriptor *content)\r
+{\r
+ content->_descriptor_tag = buf[0];\r
+ content->_descriptor_length = buf[1];\r
+ for (int i = 0; i < (content->_descriptor_length / 2); ++i)\r
{\r
- printf("%s() descriptor_length = %d\n", __FUNCTION__, extended->descriptor_length);\r
- printf("%s() length_of_items error. %d\n", __FUNCTION__, extended->length_of_items);\r
- result = 0;\r
+ content->_contents[i]._content_nibble_level_1 = (buf[i * 2 + 0x02] & 0xF0) >> 4;\r
+ content->_contents[i]._content_nibble_level_2 = buf[i * 2 + 0x02] & 0x0F;\r
+ content->_contents[i]._user_nibble_1 = (buf[i * 2 + 0x03] & 0xF0) >> 4;\r
+ content->_contents[i]._user_nibble_2 = buf[i * 2 + 0x03] & 0x0F;\r
}\r
-#else\r
-#endif\r
- return result;\r
+ return content->_descriptor_length + 2;\r
+}\r
+\r
+static uint16_t parseDigitalCopyControlDescriptor(uint8_t *buf, DigitalCopyControlDescriptor *digital_copy_control)\r
+{\r
+ digital_copy_control->_descriptor_tag = buf[0];\r
+ digital_copy_control->_descriptor_length = buf[1];\r
+\r
+ return digital_copy_control->_descriptor_length + 2;\r
+}\r
+\r
+static uint16_t parseAudioComponentDescriptor(uint8_t *buf, AudioComponentDescriptor *audio_component)\r
+{\r
+ audio_component->_descriptor_tag = buf[0];\r
+ audio_component->_descriptor_length = buf[1];\r
+ audio_component->_stream_content = buf[2] & 0x0F;\r
+ audio_component->_component_type = buf[3];\r
+ audio_component->_component_tag = buf[4];\r
+ audio_component->_stream_type = buf[5];\r
+ audio_component->_simulcast_group_tag = buf[6];\r
+ audio_component->_ES_multi_lingual_flag = buf[7] >> 7;\r
+ audio_component->_main_component_flag = (buf[7] >> 6) & 0x01;\r
+ audio_component->_quality_indicator = (buf[7] >> 4) & 0x03;\r
+ audio_component->_sampling_rate = (buf[7] >> 1) & 0x07;\r
+ memcpy(audio_component->_ISO_639_language_code, &buf[8], 3);\r
+ if (audio_component->_ES_multi_lingual_flag == 1)\r
+ {\r
+ memcpy(audio_component->_ISO_639_language_code_2, &buf[11], 3);\r
+ }\r
+ uint8_t cpylen = audio_component->_descriptor_length - (9 + audio_component->_ES_multi_lingual_flag * 3);\r
+ memcpy(audio_component->_text_char, &buf[11 + audio_component->_ES_multi_lingual_flag * 3], cpylen);\r
+ return audio_component->_descriptor_length + 2;\r
+}\r
+\r
+static uint16_t parseSeriesDescriptor(uint8_t *buf, SeriesDescriptor *series)\r
+{\r
+ series->_descriptor_tag = buf[0];\r
+ series->_descriptor_length = buf[1];\r
+\r
+ return series->_descriptor_length + 2;\r
}\r
\r
uint16_t Table::parseDescriptor(uint8_t *buf, uint16_t length, Descriptor *descriptor)\r
{\r
uint16_t result = 0;\r
\r
- descriptor->other.descriptor_tag = buf[0x00];\r
- descriptor->other.descriptor_length = buf[0x01];\r
+ descriptor->_other._descriptor_tag = buf[0x00];\r
+ descriptor->_other._descriptor_length = buf[0x01];\r
\r
// length check\r
- if ((descriptor->other.descriptor_length + 2) <= length)\r
+ if ((descriptor->_other._descriptor_length + 2) <= length)\r
{\r
- switch (descriptor->other.descriptor_tag)\r
+ switch (descriptor->_other._descriptor_tag)\r
{\r
- case 0x4D: // Short event descriptor\r
- result = parseShortEventDescriptor(buf, &descriptor->short_event);\r
+ case TAG_SERVICE_DESCRIPTOR:\r
+ result = parseServiceDescriptor(buf, &descriptor->_service);\r
break;\r
\r
- case 0x4E: // Extended event descriptor\r
- result = parseExtendedEventDescriptor(buf, &descriptor->extended_event);\r
+ case TAG_SHORT_EVENT_DESCRIPTOR:\r
+ result = parseShortEventDescriptor(buf, &descriptor->_short_event);\r
break;\r
\r
- case 0x54: // Content descriptor\r
- result = parseContentDescriptor(buf, &descriptor->content);\r
+ case TAG_EXTENDED_EVENT_DESCRIPTOR:\r
+ result = parseExtendedEventDescriptor(buf, &descriptor->_extended_event);\r
break;\r
\r
- case 0x50: // Component\r
-// result = parseComponentDescriptor(hoge);\r
- result = descriptor->other.descriptor_length + 2;\r
+ case TAG_COMPONENT_DESCRIPTOR:\r
+ result = parseComponentDescriptor(buf, &descriptor->_component);\r
break;\r
\r
- case 0xC4: // Audio Component \r
-// result = parseAudioComponentDescriptor(hoge);\r
- result = descriptor->other.descriptor_length + 2;\r
+ case TAG_CONTENT_DESCRIPTOR:\r
+ result = parseContentDescriptor(buf, &descriptor->_content);\r
break;\r
\r
+ case TAG_DIGITAL_COPY_CONTROL_DESCRIPTOR:\r
+ result = parseDigitalCopyControlDescriptor(buf, &descriptor->_digital_copy_control);\r
+ break;\r
+\r
+ case TAG_AUDIO_COMPONENT_DESCRIPTOR:\r
+ result = parseAudioComponentDescriptor(buf, &descriptor->_audio_component);\r
+ break;\r
\r
- case 0xD5: // Series descriptor\r
-// result = parseSeriesDescriptor(hoge);\r
- result = descriptor->other.descriptor_length + 2;\r
+ case TAG_SERIES_DESCRIPTOR:\r
+ result = parseSeriesDescriptor(buf, &descriptor->_series);\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
+ memcpy(&descriptor->_other._descriptor[0], &buf[0x02], descriptor->_other._descriptor_length);\r
+ result = descriptor->_other._descriptor_length + 2;\r
break;\r
}\r
}\r
else\r
{\r
printf("%s() length = %d\n", __FUNCTION__, length);\r
- printf("%s() descriptor_tag = %d\n", __FUNCTION__, descriptor->other.descriptor_tag);\r
- printf("%s() descriptor_length error. %d\n", __FUNCTION__, descriptor->other.descriptor_length);\r
+ printf("%s() descriptor_tag = %d\n", __FUNCTION__, descriptor->_other._descriptor_tag);\r
+ printf("%s() descriptor_length error. %d\n", __FUNCTION__, descriptor->_other._descriptor_length);\r
result = 0;\r
// abort();\r
}\r
}\r
\r
} // TS\r
-} // MPEG2
\ No newline at end of file
+} // MPEG2\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_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_EVENT_GROUP_DESCRIPTOR = 0xD6,\r
TAG_DIGITAL_COPY_CONTROL_DESCRIPTOR = 0xC1,\r
TAG_AUDIO_COMPONENT_DESCRIPTOR = 0xC4,\r
+ TAG_DATA_CONTENT_DESCRIPTOR = 0xC7,\r
+ TAG_SERIES_DESCRIPTOR = 0xD5\r
};\r
\r
// 6.2.1 Bouquet name descriptor\r
typedef struct _BouquetNameDescriptor\r
{\r
- uint8_t descriptor_tag; // 8\r
- uint8_t descriptor_length; // 8\r
- uint8_t descriptor[MAX_DESC_LEN]; // 8 x N\r
+ uint8_t _descriptor_tag; // 8\r
+ uint8_t _descriptor_length; // 8\r
+ uint8_t _descriptor[MAX_DESC_LEN]; // 8 x N\r
} BouquetNameDescriptor;\r
\r
+// 6.2.3 Component descriptor\r
+typedef struct _ComponentDescriptor\r
+{\r
+ uint8_t _descriptor_tag; // 8\r
+ uint8_t _descriptor_length; // 8\r
+ uint8_t _reserved_future_use; // 4\r
+ uint8_t _stream_content; // 4\r
+ uint8_t _component_type; // 8\r
+ uint8_t _component_tag; // 8\r
+ uint8_t _ISO_639_language_code[3]; // 24\r
+ uint8_t _text_char[MAX_DESC_LEN]; // 8 x N\r
+} ComponentDescriptor;\r
+\r
// 6.2.4 Content descriptor\r
typedef struct _ContentDescriptor\r
{\r
- uint8_t descriptor_tag; // 8\r
- uint8_t descriptor_length; // 8\r
+ uint8_t _descriptor_tag; // 8\r
+ uint8_t _descriptor_length; // 8\r
struct\r
{\r
- uint8_t content_nibble_level_1; // 4\r
- uint8_t content_nibble_level_2; // 4\r
- uint8_t user_nibble_1; // 4\r
- uint8_t user_nibble_2; // 4\r
- } contents[MAX_DESC_LEN/2]; // 16 x N\r
+ uint8_t _content_nibble_level_1; // 4\r
+ uint8_t _content_nibble_level_2; // 4\r
+ uint8_t _user_nibble_1; // 4\r
+ uint8_t _user_nibble_2; // 4\r
+ } _contents[MAX_DESC_LEN/2]; // 16 x N\r
} ContentDescriptor;\r
\r
// 6.2.7 Extended event descriptor\r
typedef struct _ExtendedEventDescriptor\r
{\r
- uint8_t descriptor_tag; // 8\r
- uint8_t descriptor_length; // 8\r
- uint8_t descriptor_number; // 4\r
- uint8_t last_descriptor_number; // 4\r
- uint8_t ISO_639_language_code[3]; // 24\r
- uint8_t length_of_items; // 8\r
- uint8_t item_count;\r
+ uint8_t _descriptor_tag; // 8\r
+ uint8_t _descriptor_length; // 8\r
+ uint8_t _descriptor_number; // 4\r
+ uint8_t _last_descriptor_number; // 4\r
+ uint8_t _ISO_639_language_code[3]; // 24\r
+ uint8_t _length_of_items; // 8\r
+ uint8_t _item_count;\r
struct\r
{\r
- uint8_t item_description_length; // 8\r
- uint8_t item_description[MAX_DESC_LEN]; // 8 x N\r
- uint8_t item_length; // 8\r
- uint8_t item[MAX_DESC_LEN]; // 8 x N\r
- } items[MAX_DESC_LEN/2];\r
- uint8_t text_length; // 8\r
- uint8_t text[MAX_DESC_LEN]; // 8 x N\r
+ uint8_t _item_description_length; // 8\r
+ uint8_t _item_description[MAX_DESC_LEN]; // 8 x N\r
+ uint8_t _item_length; // 8\r
+ uint8_t _item[MAX_DESC_LEN]; // 8 x N\r
+ } _items[MAX_DESC_LEN/2];\r
+ uint8_t _text_length; // 8\r
+ uint8_t _text[MAX_DESC_LEN]; // 8 x N\r
} ExtendedEventDescriptor;\r
\r
// 6.2.13 Service descriptor\r
typedef struct _ServiceDescriptor\r
{\r
- uint8_t descriptor_tag; // 8\r
- uint8_t descriptor_length; // 8\r
- uint8_t service_type; // 8\r
- uint8_t service_provider_name_length; // 8\r
- uint8_t service_provider_name[MAX_DESC_LEN]; // 8 x N\r
- uint8_t service_name_length; // 8\r
- uint8_t service_name[MAX_DESC_LEN]; // 8 x N\r
+ uint8_t _descriptor_tag; // 8\r
+ uint8_t _descriptor_length; // 8\r
+ uint8_t _service_type; // 8\r
+ uint8_t _service_provider_name_length; // 8\r
+ uint8_t _service_provider_name[MAX_DESC_LEN]; // 8 x N\r
+ uint8_t _service_name_length; // 8\r
+ uint8_t _service_name[MAX_DESC_LEN]; // 8 x N\r
} ServiceDescriptor;\r
\r
// 6.2.15 Short event descriptor\r
typedef struct _ShortEventDescriptor\r
{\r
- uint8_t descriptor_tag; // 8\r
- uint8_t descriptor_length; // 8\r
- uint8_t ISO_639_language_code[3]; // 24\r
- uint8_t event_name_length; // 8\r
- uint8_t event_name[MAX_DESC_LEN]; // 8 x N\r
- uint8_t text_length; // 8\r
- uint8_t text[MAX_DESC_LEN]; // 8 x N\r
+ uint8_t _descriptor_tag; // 8\r
+ uint8_t _descriptor_length; // 8\r
+ uint8_t _ISO_639_language_code[3]; // 24\r
+ uint8_t _event_name_length; // 8\r
+ uint8_t _event_name[MAX_DESC_LEN]; // 8 x N\r
+ uint8_t _text_length; // 8\r
+ uint8_t _text[MAX_DESC_LEN]; // 8 x N\r
} ShortEventDescriptor;\r
\r
+// 6.2.23 Digital copy control descriptor\r
+typedef struct _DigitalCopyControlDescriptor\r
+{\r
+ uint8_t _descriptor_tag; // 8\r
+ uint8_t _descriptor_length; // 8\r
+\r
+} DigitalCopyControlDescriptor;\r
+\r
+// 6.2.26 Audio compoenent descriptor\r
+typedef struct _AudioComponentDescriptor\r
+{\r
+ uint8_t _descriptor_tag; // 8\r
+ uint8_t _descriptor_length; // 8\r
+ uint8_t _reserved_future_use; // 4\r
+ uint8_t _stream_content; // 4\r
+ uint8_t _component_type; // 8\r
+ uint8_t _component_tag; // 8\r
+ uint8_t _stream_type; // 8\r
+ uint8_t _simulcast_group_tag; // 8\r
+ uint8_t _ES_multi_lingual_flag; // 1\r
+ uint8_t _main_component_flag; // 1\r
+ uint8_t _quality_indicator; // 2\r
+ uint8_t _sampling_rate; // 3\r
+ uint8_t _reserved_future_use_2; // 1\r
+ uint8_t _ISO_639_language_code[3]; // 24\r
+ uint8_t _ISO_639_language_code_2[3]; // 24 if (ES_multi_lingual_flag == 1)\r
+ uint8_t _text_char[MAX_DESC_LEN]; // 8 x N\r
+} AudioComponentDescriptor;\r
+\r
// 6.2.33 Series descriptor\r
typedef struct _SeriesDescriptor\r
{\r
- uint8_t descriptor_tag; // 8\r
- uint8_t descriptor_length; // 8\r
- uint16_t series_id; // 16\r
- uint8_t repeat_label; // 4\r
- uint8_t program_pattern; // 3\r
- uint8_t expire_date_valid_flag; // 1\r
- uint16_t expire_date; // 16\r
- uint16_t episode_number; // 12\r
- uint16_t last_episode_number; // 12\r
- uint8_t series_name[MAX_DESC_LEN]; // 8 x N\r
+ uint8_t _descriptor_tag; // 8\r
+ uint8_t _descriptor_length; // 8\r
+ uint16_t _series_id; // 16\r
+ uint8_t _repeat_label; // 4\r
+ uint8_t _program_pattern; // 3\r
+ uint8_t _expire_date_valid_flag; // 1\r
+ uint16_t _expire_date; // 16\r
+ uint16_t _episode_number; // 12\r
+ uint16_t _last_episode_number; // 12\r
+ uint8_t _series_name[MAX_DESC_LEN]; // 8 x N\r
} SeriesDescriptor;\r
\r
\r
typedef struct _OtherDescriptor\r
{\r
- uint8_t descriptor_tag; // 8\r
- uint8_t descriptor_length; // 8\r
- uint8_t descriptor[MAX_DESC_LEN]; // 8 x N\r
+ uint8_t _descriptor_tag; // 8\r
+ uint8_t _descriptor_length; // 8\r
+ uint8_t _descriptor[MAX_DESC_LEN]; // 8 x N\r
} OtherDescriptor;\r
\r
typedef union _Descriptor\r
{\r
- uint8_t descriptor_tag;\r
- BouquetNameDescriptor bouquet_name;\r
- ServiceDescriptor service;\r
- ShortEventDescriptor short_event;\r
- ExtendedEventDescriptor extended_event;\r
- ContentDescriptor content;\r
- SeriesDescriptor series;\r
- OtherDescriptor other;\r
+ uint8_t _descriptor_tag;\r
+ BouquetNameDescriptor _bouquet_name;\r
+ ComponentDescriptor _component;\r
+ ContentDescriptor _content;\r
+ ExtendedEventDescriptor _extended_event;\r
+ ServiceDescriptor _service;\r
+ ShortEventDescriptor _short_event;\r
+ DigitalCopyControlDescriptor _digital_copy_control;\r
+ AudioComponentDescriptor _audio_component;\r
+ SeriesDescriptor _series;\r
+ OtherDescriptor _other;\r
} Descriptor;\r
\r
-\r
-\r
class Table\r
{\r
protected:\r
uint16_t _length;\r
uint8_t _section[MAX_SECT_LEN];\r
\r
- virtual bool decode_section();\r
+ virtual bool decode_section() = 0;\r
\r
public:\r
Table();\r
virtual ~Table();\r
-// bool decode(uint8_t *packet);\r
bool decode(Header *header, uint8_t *packet);\r
void reset();\r
\r
\r
#include <time.h>\r
\r
+#define DBG_LEVEL 0\r
+#include "Raym/Log.h"\r
+\r
#include "Raym/Raym.h"\r
#include "b25/aribstr.h"\r
#include "ry0/iPTd/Analyzer.h"\r
return result;\r
}\r
\r
-static Array *eit2epgs(MPEG2::TS::EIT *eit)\r
+Array *Analyzer::collectEPGs(time_t limit)\r
{\r
- Array *result = Array::arrayWithCapacity(0);\r
+ _demux.setFlag(MPEG2::TS::Demultiplexer::FLG_EIT, true);\r
\r
-printf(" | 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F\n");\r
-printf("----+------------------------------------------------\n");\r
-for (int ii = 0; ii < eit->_section_length - 0x0e; ++ii)\r
-{\r
- if (ii % 16 == 0)\r
- {\r
- printf("%04x: ", ii);\r
- }\r
- printf("%02x ", eit->_event_data[ii]);\r
- if (ii % 16 == 15)\r
- {\r
- printf("\n");\r
- }\r
-}\r
-printf("\n");\r
+ std::vector<MPEG2::TS::EIT *> eits;\r
+\r
+ RaymLock(this);\r
+\r
+ time_t start = time(NULL);\r
while (true)\r
{\r
- MPEG2::TS::EIT::Event *event = eit->nextEvent();\r
- if (event == NULL)\r
+ while ((_eit == NULL) && (time(NULL) < start + limit))\r
{\r
- DebugLog0("event is null\n");\r
- break;\r
+ RaymCondTimedWait(this, 1000);\r
}\r
\r
- DebugLog0("eit -> epg: start\n");\r
-\r
- Dictionary *epg = Dictionary::dictionaryWithCapacity(0);\r
-\r
- char tmp[32];\r
-#ifdef _WIN32\r
- sprintf_s(tmp, "%d", eit->_service_id);\r
-#else\r
- sprintf(tmp, "%d", eit->_service_id);\r
-#endif\r
- epg->setString(tmp, KEY_EPG_SERVICE_ID);\r
-\r
-#ifdef _WIN32\r
- sprintf_s(tmp, "%d", event->_event_id);\r
-#else\r
- sprintf(tmp, "%d", event->_event_id);\r
-#endif\r
- epg->setString(tmp, KEY_EPG_EVENT_ID);\r
-\r
- char date[16];\r
-#ifdef _WIN32\r
- sprintf_s(date, sizeof(date), "%02d/%02d/%02d", event->_st_year, event->_st_month, event->_st_day);\r
-#else\r
- sprintf(date, "%02d/%02d/%02d", event->_st_year, event->_st_month, event->_st_day);\r
-#endif\r
- epg->setString(date, KEY_EPG_DATE);\r
-\r
- char start[16];\r
-#ifdef _WIN32\r
- sprintf_s(start, sizeof(start), "%02d:%02d:%02d", event->_st_hour, event->_st_min, event->_st_sec);\r
-#else\r
- sprintf(start, "%02d:%02d:%02d", event->_st_hour, event->_st_min, event->_st_sec);\r
-#endif\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
+ if (_eit != NULL)\r
{\r
- min += 1;\r
- sec -= 60;\r
+ eits.push_back(_eit);\r
+ _eit = NULL;\r
}\r
- if (min >= 60)\r
+ else\r
{\r
- hour += 1;\r
- min -= 60;\r
+ break;\r
}\r
- char end[16];\r
-#ifdef _WIN32\r
- sprintf_s(end, sizeof(end), "%02d:%02d:%02d", hour, min, sec);\r
-#else\r
- sprintf(end, "%02d:%02d:%02d", hour, min, sec);\r
-#endif\r
- epg->setString(end, KEY_EPG_END);\r
-\r
- Data *data = Data::dataWithCapacity(0);\r
-\r
- DebugLog0("eit -> epg: check 000\n");\r
- while (true)\r
+ }\r
+\r
+ RaymUnlock(this);\r
+\r
+ _demux.setFlag(MPEG2::TS::Demultiplexer::FLG_EIT, false);\r
+\r
+ Array *result = Array::arrayWithCapacity(0);\r
+\r
+ std::vector<MPEG2::TS::EIT *>::iterator it;\r
+ for (it = eits.begin(); it != eits.end(); ++it)\r
+ {\r
+ MPEG2::TS::EIT *eit = (*it);\r
+ if ((eit->_table_id == MPEG2::TS::EIT::TABLE_ID_SELF) ||\r
+ ((MPEG2::TS::EIT::TABLE_ID_SELF_SCHEDULE_BEGIN <= eit->_table_id) && (eit->_table_id <= MPEG2::TS::EIT::TABLE_ID_SELF_SCHEDULE_END)))\r
{\r
- MPEG2::TS::Descriptor *desc = event->nextDescriptor();\r
- if (desc == NULL)\r
+ MPEG2::TS::EIT::Event *event;\r
+ while ((event = eit->nextEvent()) != NULL)\r
{\r
- DebugLog0("eit -> epg: check 001\n");\r
- break;\r
- }\r
- DebugLog0("eit -> epg: check 002\n");\r
+ char service_id[32];\r
+ sprintf_s(service_id, "%d", eit->_service_id);\r
\r
- switch (desc->descriptor_tag)\r
- {\r
- case MPEG2::TS::TAG_BOUQUET_NAME_DESCRIPTOR:\r
- DebugLog0("TAG_BOUQUET_NAME_DESCRIPTOR\n");\r
- break;\r
+ char event_id[32];\r
+ sprintf_s(event_id, "%d", event->_event_id);\r
\r
- case MPEG2::TS::TAG_SERVICE_DESCRIPTOR:\r
- DebugLog0("TAG_SERVICE_DESCRIPTOR\n");\r
- break;\r
+ Dictionary *epg = NULL;\r
\r
- case MPEG2::TS::TAG_SHORT_EVENT_DESCRIPTOR:\r
- DebugLog0("TAG_SHORT_EVENT_DESCRIPTOR\n");\r
- if (desc->short_event.event_name_length > 0)\r
+ for (uint32_t i = 0; i < result->count(); ++i)\r
{\r
-DebugLog0("event_name_length: %d\n", desc->short_event.event_name_length);\r
- char *tmp = (char *)malloc(desc->short_event.event_name_length * 2 + 1);\r
- if (tmp)\r
+ epg = (Dictionary *)result->objectAtIndex(i);\r
+ if (epg->stringForKey(KEY_EPG_SERVICE_ID)->isEqualToString(service_id) &&\r
+ epg->stringForKey(KEY_EPG_EVENT_ID)->isEqualToString(event_id))\r
{\r
- AribToString(tmp, (const char *)desc->short_event.event_name, desc->short_event.event_name_length);\r
-DebugLog0("event_name: %s\n", tmp);\r
- String *event_name = String::stringWithCString(tmp, ShiftJISStringEncoding);\r
- if (event_name)\r
- {\r
-DebugLog0("event_name: %s\n", event_name->cString());\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
+ break;\r
}\r
+ epg = NULL;\r
}\r
- else\r
- {\r
-DebugLog0("event_name_length ng: %d\n", desc->short_event.event_name_length);\r
- }\r
- if (desc->short_event.text_length > 0)\r
+\r
+ if (epg == NULL)\r
{\r
-DebugLog0("text_length: %d\n", desc->short_event.text_length);\r
- char *tmp = (char *)malloc(desc->short_event.text_length * 2 + 1);\r
- if (tmp)\r
+ epg = Dictionary::dictionaryWithCapacity(0);\r
+ epg->setString(service_id, KEY_EPG_SERVICE_ID);\r
+ epg->setString(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
- 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
- free(tmp);\r
+ min += 1;\r
+ sec -= 60;\r
}\r
- else\r
+ if (min >= 60)\r
{\r
- printf("mallco NG.\n");\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
+ char duration[8];\r
+ sprintf_s(duration, sizeof(duration), "%d", event->_dur_hour * 3600 + event->_dur_min * 60 + event->_dur_sec);\r
+ epg->setString(duration, KEY_EPG_DURATION);\r
+\r
+ result->addObject(epg);\r
}\r
- else\r
- {\r
-DebugLog0("text_length ng: %d\n", desc->short_event.text_length);\r
- }\r
- break;\r
\r
- case MPEG2::TS::TAG_EXTENDED_EVENT_DESCRIPTOR:\r
- printf("TAG_EXTENDED_EVENT_DESCRIPTOR\n");\r
- for (int i = 0; i < desc->extended_event.item_count; ++i)\r
+ Array *ext_items = NULL;\r
+ String *ext_item_desc = NULL;\r
+ Data *ext_item = NULL;\r
+ Data *ext_text = NULL;\r
+\r
+ MPEG2::TS::Descriptor *desc;\r
+ while ((desc = event->nextDescriptor()) != NULL)\r
{\r
+ switch (desc->_descriptor_tag)\r
+ {\r
+ case MPEG2::TS::TAG_BOUQUET_NAME_DESCRIPTOR:\r
+ DebugLog3("TAG_BOUQUET_NAME_DESCRIPTOR\n");\r
+ break;\r
\r
- // item_description と item を繋げてしまうと正しく読めない場合がある\r
- // 現状は item_description は捨てる\r
- // どうやって扱うか、今後の課題\r
+ case MPEG2::TS::TAG_SERVICE_DESCRIPTOR:\r
+ DebugLog3("TAG_SERVICE_DESCRIPTOR\n");\r
+ break;\r
\r
- if (desc->extended_event.items[i].item_description_length > 0)\r
- {\r
- char *tmp = (char *)malloc(desc->extended_event.items[i].item_description_length * 2 + 1);\r
- if (tmp)\r
+ case MPEG2::TS::TAG_SHORT_EVENT_DESCRIPTOR:\r
+ DebugLog3("TAG_SHORT_EVENT_DESCRIPTOR\n");\r
+ if (desc->_short_event._event_name_length > 0)\r
{\r
- AribToString(tmp, (const char *)desc->extended_event.items[i].item_description, desc->extended_event.items[i].item_description_length);\r
- String *item_description = String::stringWithCString(tmp, ShiftJISStringEncoding);\r
- if (item_description)\r
+ char *tmp = (char *)malloc(desc->_short_event._event_name_length * 3);\r
+ if (tmp != NULL)\r
{\r
- DebugLog0("item_description: %s\n", item_description->cString());\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 != NULL)\r
+ {\r
+ epg->setString(event_name, KEY_EPG_TITLE);\r
+ }\r
+ free(tmp);\r
}\r
- free(tmp);\r
}\r
-// data->appendBytes(desc->extended_event.items[i].item_description, \r
-// desc->extended_event.items[i].item_description_length);\r
- }\r
+ if (desc->_short_event._text_length > 0)\r
+ {\r
+ char *tmp = (char *)malloc(desc->_short_event._text_length * 3);\r
+ if (tmp != NULL)\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 != NULL)\r
+ {\r
+ epg->setString(text, KEY_EPG_DESCRIPTION);\r
+ }\r
+ free(tmp);\r
+ }\r
+ }\r
+ break;\r
\r
+ case MPEG2::TS::TAG_EXTENDED_EVENT_DESCRIPTOR:\r
+ DebugLog3("TAG_EXTENDED_EVENT_DESCRIPTOR\n");\r
+ {\r
+ for (int i = 0; i < desc->_extended_event._item_count; ++i)\r
+ {\r
+ if (ext_items == NULL)\r
+ {\r
+ ext_items = Array::arrayWithCapacity(0);\r
+ epg->setObject(ext_items, KEY_EPG_EXT_ITEMS);\r
+ }\r
+\r
+ if (desc->_extended_event._items[i]._item_description_length > 0)\r
+ {\r
+ if (ext_item != NULL)\r
+ {\r
+ char *tmp = (char *)malloc(ext_item->length() * 3);\r
+ if (tmp != NULL)\r
+ {\r
+ AribToString(tmp, (const char *)ext_item->bytes(), ext_item->length());\r
+ String *desc = String::stringWithCString(tmp, ShiftJISStringEncoding);\r
+ if (desc != NULL)\r
+ {\r
+ Dictionary *dict = Dictionary::dictionaryWithCapacity(0);\r
+ if (ext_item_desc != NULL)\r
+ {\r
+ dict->setString(ext_item_desc, KEY_EPG_EXT_ITEM_DESCRIPTION);\r
+ ext_item_desc = NULL;\r
+ }\r
+ dict->setString(desc, KEY_EPG_EXT_ITEM);\r
+ ext_items->addObject(dict);\r
+ }\r
+ free(tmp);\r
+ }\r
+ ext_item = NULL;\r
+ }\r
+\r
+ char *tmp = (char *)malloc(desc->_extended_event._items[i]._item_description_length * 3);\r
+ if (tmp != NULL)\r
+ {\r
+ AribToString(tmp, (const char *)desc->_extended_event._items[i]._item_description,\r
+ desc->_extended_event._items[i]._item_description_length);\r
+ ext_item_desc = String::stringWithCString(tmp, ShiftJISStringEncoding);\r
+ free(tmp);\r
+ }\r
+ else\r
+ {\r
+ ext_item_desc = NULL;\r
+ }\r
+ }\r
+\r
+ if (desc->_extended_event._items[i]._item_length > 0)\r
+ {\r
+ if (ext_item == NULL)\r
+ {\r
+ ext_item = Data::dataWithCapacity(0);\r
+ }\r
+ ext_item->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
+ if (ext_text == NULL)\r
+ {\r
+ ext_text = Data::dataWithCapacity(0);\r
+ }\r
+ ext_text->appendBytes(desc->_extended_event._text, desc->_extended_event._text_length);\r
+ }\r
+ }\r
+ break;\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
- DebugLog0("TAG_EXTENDED_EVENT_DESCRIPTOR\n");\r
- DebugLog0(" text: %s\n", desc->extended_event.text);\r
- data->appendBytes(desc->extended_event.text, desc->extended_event.text_length);\r
- }\r
- break;\r
+ case MPEG2::TS::TAG_CONTENT_DESCRIPTOR:\r
+ DebugLog3("TAG_CONTENT_DESCRIPTOR\n");\r
+ break;\r
\r
- case MPEG2::TS::TAG_CONTENT_DESCRIPTOR:\r
- DebugLog0("TAG_CONTENT_DESCRIPTOR\n");\r
- break;\r
+ case MPEG2::TS::TAG_SERIES_DESCRIPTOR:\r
+ DebugLog3("TAG_SERIES_DESCRIPTOR\n");\r
+ break;\r
\r
- case MPEG2::TS::TAG_SERIES_DESCRIPTOR:\r
- DebugLog0("TAG_SERIES_DESCRIPTOR\n");\r
- break;\r
+ case MPEG2::TS::TAG_EVENT_GROUP_DESCRIPTOR:\r
+ DebugLog3("TAG_EVENT_GROUP_DESCRIPTOR\n");\r
+ break;\r
\r
- case MPEG2::TS::TAG_EVENT_GROUP_DESCRIPTOR:\r
- DebugLog0("TAG_EVENT_GROUP_DESCRIPTOR\n");\r
- break;\r
+ case MPEG2::TS::TAG_COMPONENT_DESCRIPTOR:\r
+ DebugLog3("TAG_COMPONENT_DESCRIPTOR\n");\r
+ break;\r
\r
- case MPEG2::TS::TAG_COMPONENT_DESCRIPTOR:\r
- DebugLog0("TAG_COMPONENT_DESCRIPTOR\n");\r
- break;\r
+ case MPEG2::TS::TAG_DIGITAL_COPY_CONTROL_DESCRIPTOR:\r
+ DebugLog3("TAG_DIGITAL_COPY_CONTROL_DESCRIPTOR\n");\r
+ break;\r
\r
- case MPEG2::TS::TAG_DIGITAL_COPY_CONTROL_DESCRIPTOR:\r
- DebugLog0("TAG_DIGITAL_COPY_CONTROL_DESCRIPTOR\n");\r
- break;\r
+ case MPEG2::TS::TAG_AUDIO_COMPONENT_DESCRIPTOR:\r
+ DebugLog3("TAG_AUDIO_COMPONENT_DESCRIPTOR\n");\r
+ break;\r
\r
- case MPEG2::TS::TAG_AUDIO_COMPONENT_DESCRIPTOR:\r
- DebugLog0("TAG_AUDIO_COMPONENT_DESCRIPTOR\n");\r
- break;\r
+ case MPEG2::TS::TAG_DATA_CONTENT_DESCRIPTOR:\r
+ DebugLog3("TAG_AUDIO_COMPONENT_DESCRIPTOR\n");\r
+ break;\r
\r
-// case MPEG2::TS::TAG_17: // 不明\r
+ default:\r
+ DebugLog3("Unknown descriptor: 0x%02X\n", desc->_descriptor_tag);\r
+ break;\r
+ }\r
+ }\r
\r
- default:\r
- DebugLog0("Unknown descriptor: 0x%02X\n", desc->descriptor_tag);\r
- break;\r
- }\r
- }\r
+ if (ext_item != NULL)\r
+ {\r
+ char *tmp = (char *)malloc(ext_item->length() * 3);\r
+ if (tmp != NULL)\r
+ {\r
+ AribToString(tmp, (const char *)ext_item->bytes(), ext_item->length());\r
+ String *desc = String::stringWithCString(tmp, ShiftJISStringEncoding);\r
+ if (desc != NULL)\r
+ {\r
+ Dictionary *dict = Dictionary::dictionaryWithCapacity(0);\r
+ if (ext_item_desc != NULL)\r
+ {\r
+ dict->setString(ext_item_desc, KEY_EPG_EXT_ITEM_DESCRIPTION);\r
+ ext_item_desc = NULL;\r
+ }\r
+ dict->setString(desc, KEY_EPG_EXT_ITEM);\r
+ ext_items->addObject(dict);\r
+ }\r
+ free(tmp);\r
+ }\r
+ ext_item = NULL;\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
+ if (ext_text != NULL)\r
{\r
- epg->setString(desc, KEY_EPG_DESCRIPTION);\r
+ char *tmp = (char *)malloc(ext_text->length() * 3);\r
+ if (tmp != NULL)\r
+ {\r
+ AribToString(tmp, (const char *)ext_text->bytes(), ext_text->length());\r
+ String *desc = String::stringWithCString(tmp, ShiftJISStringEncoding);\r
+ if (desc != NULL)\r
+ {\r
+ Dictionary *dict = Dictionary::dictionaryWithCapacity(0);\r
+ dict->setString("no desc", KEY_EPG_EXT_ITEM_DESCRIPTION);\r
+ dict->setString(desc, KEY_EPG_EXT_ITEM);\r
+ ext_items->addObject(dict);\r
+ }\r
+ free(tmp);\r
+ }\r
+ ext_text = NULL;\r
}\r
- free(tmp);\r
}\r
}\r
\r
- result->addObject(epg);\r
-\r
- DebugLog0("eit -> epg: done\n");\r
- DebugLog0("%s\n", epg->toString().c_str());\r
- }\r
-\r
-\r
- DebugLog0("eit2epg done.\n");\r
- return result;\r
-}\r
-\r
-Array *Analyzer::collectEPGs(time_t limit)\r
-{\r
- _demux.setFlag(MPEG2::TS::Demultiplexer::FLG_EIT, true);\r
-\r
- std::vector<MPEG2::TS::EIT *> eits;\r
-\r
- DebugLog0("b lock\n");\r
- RaymLock(this);\r
- DebugLog0("a lock\n");\r
-\r
- time_t start = time(NULL);\r
- while (time(NULL) < start + limit)\r
- {\r
- while (_eit == NULL)\r
- {\r
- DebugLog0("b wait\n");\r
- RaymCondWait(this);\r
- DebugLog0("a wait\n");\r
- }\r
-\r
- eits.push_back(_eit);\r
- _eit = NULL;\r
- }\r
-\r
- DebugLog0("b unlock\n");\r
- RaymUnlock(this);\r
- DebugLog0("a unlock\n");\r
-\r
- _demux.setFlag(MPEG2::TS::Demultiplexer::FLG_EIT, false);\r
-\r
- Array *result = Array::arrayWithCapacity(0);\r
-\r
- std::vector<MPEG2::TS::EIT *>::iterator it;\r
- for (it = eits.begin(); it != eits.end(); ++it)\r
- {\r
- result->addObjectsFromArray(eit2epgs(*it));\r
delete *it;\r
}\r
\r
\r
void Analyzer::detect(MPEG2::TS::EIT *eit)\r
{\r
- DebugLog0("b lock: detect\n");\r
RaymLock(this);\r
- DebugLog0("a lock: detect\n");\r
if (_eit != NULL)\r
{\r
delete _eit;\r
}\r
_eit = new MPEG2::TS::EIT(*eit);\r
RaymCondSignal(this);\r
- DebugLog0("b unlock: detect\n");\r
RaymUnlock(this);\r
- DebugLog0("a unlock: detect\n");\r
}\r
\r
} // iPTd\r
static const TimeInterval DEF_COLLECT_EPG_DELAY = 1.0;\r
static const TimeInterval DEF_COLLECT_EPG_RETRY = 60.0;\r
\r
-static const time_t DEF_COLLECT_EPG_LIMIT_S = 20;\r
-static const time_t DEF_COLLECT_EPG_LIMIT_T = 30;\r
+static const time_t DEF_COLLECT_EPG_LIMIT_S = 30;\r
+static const time_t DEF_COLLECT_EPG_LIMIT_T = 75;\r
\r
static const time_t OFFSET_OF_START_TIME = -2; // 録画開始時刻の補正(秒単位)\r
static const time_t OFFSET_OF_END_TIME = -3; // 録画停止時刻の補正(秒単位)\r
return result;\r
}\r
\r
+// epgの開始時刻でソートする為の比較関数\r
+Integer compareFunction(Object *obj1, Object *obj2, void *context)\r
+{\r
+ if (isKindOfClass(Dictionary, obj1) && isKindOfClass(Dictionary, obj2))\r
+ {\r
+ time_t st1;\r
+ time_t ed1;\r
+ Controller::getTimeWithEPG((Dictionary *)obj1, &st1, &ed1);\r
+\r
+ time_t st2;\r
+ time_t ed2;\r
+ Controller::getTimeWithEPG((Dictionary *)obj2, &st2, &ed2);\r
+\r
+ if (st1 < st2)\r
+ {\r
+ return OrderedAscending;\r
+ }\r
+ else if (st1 > st2)\r
+ {\r
+ return OrderedDescending;\r
+ }\r
+ else\r
+ {\r
+ if (ed1 < ed2)\r
+ {\r
+ return OrderedAscending;\r
+ }\r
+ else if (ed1 > ed2)\r
+ {\r
+ return OrderedDescending;\r
+ }\r
+ }\r
+ }\r
+ return OrderedSame;\r
+}\r
+\r
#ifndef _WIN32\r
#pragma mark '\r
#pragma mark ------- EPG関連 -------\r
time_t now = time(NULL);\r
\r
// lock\r
- RaymLock(this);\r
+ RaymLock(_epgs);\r
+\r
+ Array *epg_list = Array::arrayWithCapacity(0);\r
\r
// サービスIDでループ\r
Array *keys1 = _epgs->allKeys();\r
// 削除する\r
events->removeObjectForKey(key);\r
}\r
+ else\r
+ {\r
+ epg_list->addObject(epg);\r
+ }\r
}\r
}\r
}\r
}\r
\r
+ epg_list = epg_list->sortedArrayUsingFunction(compareFunction, this);\r
+ std::string xmltv_programs;\r
+ for (uint i = 0; i < epg_list->count(); ++i)\r
+ {\r
+ Dictionary *epg = (Dictionary *)epg_list->objectAtIndex(i);\r
+\r
+ std::string epg_date = epg->stringForKey(KEY_EPG_DATE)->stringByReplacingOccurrencesOfString("/", "")->cString();\r
+ std::string epg_start = epg->stringForKey(KEY_EPG_START)->stringByReplacingOccurrencesOfString(":", "")->cString();\r
+ std::string epg_end = epg->stringForKey(KEY_EPG_END)->stringByReplacingOccurrencesOfString(":", "")->cString();\r
+ std::string epg_event_id = epg->stringForKey(KEY_EPG_EVENT_ID)->cString();\r
+ std::string epg_duration = epg->stringForKey(KEY_EPG_DURATION)->cString();\r
+ std::string epg_title = epg->stringForKey(KEY_EPG_TITLE)->cString();\r
+\r
+ Array *ch_list = _service_to_channels->arrayForKey(epg->stringForKey(KEY_EPG_SERVICE_ID));\r
+ for (uint ch_idx = 0; (ch_list != NULL) && (ch_idx < ch_list->count()); ++ch_idx)\r
+ {\r
+ xmltv_programs += " <programme start=\"" + epg_date + epg_start + " +0900\" stop=\"";\r
+ xmltv_programs += epg_date + epg_end + " +0900\" channel=\"";\r
+ xmltv_programs += ((String *)ch_list->objectAtIndex(ch_idx))->cString();\r
+ xmltv_programs += "\" event_id=\"" + epg_event_id + "\" duration=\"" + epg_duration + "\">\r\n";\r
+\r
+ xmltv_programs += " <title lang=\"ja_JP\">" + epg_title + "</title>\r\n";\r
+\r
+ xmltv_programs += " </programme>\r\n";\r
+ }\r
+ }\r
+\r
// unlock\r
+ RaymUnlock(_epgs);\r
+\r
+ std::string str_xmltv_xml;\r
+ str_xmltv_xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n";\r
+ str_xmltv_xml += "<!DOCTYPE tv SYSTEM \"xmltv.dtd\">\r\n";\r
+ str_xmltv_xml += "<tv generator-info-name=\"iPTd_R2\" generator-info-url=\"http://localhost/\">\r\n";\r
+ str_xmltv_xml += _xmltv_channels;\r
+ str_xmltv_xml += xmltv_programs;\r
+ str_xmltv_xml += "</tv>\r\n";\r
+\r
+ RaymLock(this);\r
+ RELEASE(_xmltv_xml);\r
+ _xmltv_xml = String::alloc()->initWithUTF8String(str_xmltv_xml.c_str());\r
RaymUnlock(this);\r
}\r
\r
an->release();\r
\r
// lock\r
- RaymLock(this);\r
-\r
- long add_cnt = 0;\r
- long discard = 0;\r
+ RaymLock(_epgs);\r
\r
for (uint j = 0; j < collected->count(); ++j)\r
{\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
// unlock\r
- RaymUnlock(this);\r
+ RaymUnlock(_epgs);\r
\r
DebugLog2("Controller::collectEPGsForTuner(%d) end.", tuner);\r
}\r
{\r
DebugLog0("collect EPG of \"%s\" was finished.", _tuners[tuner]->name());\r
\r
- // 過去のEPGを削除\r
- removePastEPGs();\r
}\r
\r
+ // 過去のEPGを削除\r
+ removePastEPGs();\r
+\r
DebugLog2("Controller::collectEPGs(%s) end.", type == Tuner::ISDB_S ? "ISDB-S" : "ISDB-T");\r
\r
return true;\r
HTTPResponse *Controller::responseForPlaylist(HTTPRequest *request, SOCKADDR_IN *client)\r
{\r
HTTPResponse *result = NULL;\r
- // http://bit.ly/iptv_feb2015\r
-\r
-#if 0\r
-\r
-#EXTM3U\r
-\r
-#EXTINF:-1, [COLOR yellow]Updated 15/04/2015 @ 03:45 [/COLOR] \r
-plugin://plugin.video.youtube/?action=play_video&videoid=eMduu81gNgM\r
-#EXTINF:-1, [COLOR green] --Uk Live Tv--[/COLOR] \r
-plugin://plugin.video.youtube/?action=play_video&videoid=eMduu81gNgM\r
-#EXTINF:-1, [COLOR green] --Free Collection of IPTV sports links--[/COLOR] \r
-plugin://plugin.video.youtube/?action=play_video&videoid=eMduu81gNgM\r
-#EXTINF:-1, [COLOR red] --Links will go down. Please note that it will take time to update--[/COLOR]\r
-plugin://plugin.video.youtube/?action=play_video&videoid=eMduu81gNgM\r
-#EXTINF:-1, [COLOR red] --Please contact me at the husham.com website--[/COLOR]\r
-plugin://plugin.video.youtube/?action=play_video&videoid=eMduu81gNgM\r
-\r
-#EXTINF:-1, Sky sports news\r
-rtmp://89.248.172.159:443/liverepeater playpath=35 swfUrl=http://popeoftheplayers.eu/atdedead.swf pageUrl=http://popeoftheplayers.eu/crichd.php?id=35&width=600&height=450 token=#atd%#$ZH\r
-#EXTINF:-1,Bt sports 1\r
-rtmp://80.82.78.87:443/liverepeater/starsp pageUrl=http://xxxxxxxxxxxxxxxx.xx/rtmpe://strm.dcast.tv:1935/live/asdfadfaa/pageUrl=http://xxxxx.xx/rtmp://80.82.64.90:443/liverepeater/79/pageUrl=http://filotv.pw/rtmpe://strm.ukcast.tv:1935/redirect/FUNKTSN/pageUrl=http://ukcast.tv/rtmp://173.192.81.176:443/liverepeater/stream1/token%ZZri(nKa@#Z/pageUrl=http://hdcast.org/cdn.kingofplayers.com/rtmpe://46.246.29.152:1935/redirect/HDMNBC playpath=41?18?49?33?48?38?11 pageUrl=http://popeoftheplayers.eu/hdcast.org/rtmp://31.220.0.134:1935/live/tsn2/pageUrl=http://www.eucast.tv/rtmp://195.154.236.152:80/liverepeater/141449/pageUrl=http://goodcast.pw/rtmp://77.81.98.134/tv/bt1h28qn?v=pageUrl=http://castok.com/rtmp://89.46.102.70:443/liveedge/bt1pageUrl=http://hqstreams.tv/rtmpe://play.finecast.tv/live/hqbt1page/playpath=42?finecast.tv/rtmpe://cdn.hdcast.org:1935/redirect/swfUrl=http://www.hdcast.org/aplayer/jwplayer.flash.swfpageUrl=http://www.hdcast.org/token=Fo5_n0w?U.rA6l3-70w47ch@#8x12pX@ token=#atd%#$ZH\r
\r
-#endif\r
-\r
-\r
- std::string contents;\r
- contents = "#EXTM3U\r\n";\r
- contents += "\r\n";\r
-\r
- Dictionary *tuner_channel_to_udp = _streaming_ctrls->dictionaryForKey(KEY_MAPPING_TUNER_CHANNEL_TO_UDP);\r
- if (tuner_channel_to_udp != NULL)\r
+ if (_iptv_m3u8 != NULL)\r
{\r
- Tuner::Type types[] = {Tuner::ISDB_T, Tuner::ISDB_S};\r
- for (int t = 0; t < sizeof(types) / sizeof(Tuner::Type); ++t)\r
- {\r
- for (int i = 0; i < _tunerCount; ++i)\r
- {\r
- if (isTunerInitialized(i) && (_tuners[i]->type() == types[t]))\r
- {\r
- uint ch_max = ((types[t] == Tuner::ISDB_T) ? Tuner::MAX_CHANNELS_ISDB_T : Tuner::MAX_CHANNELS_ISDB_S);\r
- for (uint ch = 0; ch <= ch_max; ++ch)\r
- {\r
- if (isChannelEnabled(i, ch))\r
- {\r
- char tuner_and_channel[10];\r
- sprintf_s(tuner_and_channel, "%d,%d", i, ch);\r
- char *chstr = strchr(tuner_and_channel, ',');\r
- if (chstr != NULL)\r
- {\r
- ++chstr;\r
- }\r
+ result = responseWithUTF8Text(request, _iptv_m3u8);\r
+ }\r
\r
- String *udp_str = tuner_channel_to_udp->stringForKey(tuner_and_channel);\r
- if (udp_str != NULL)\r
- {\r
- contents += "#EXTINF:-1 tvg-id=\"";\r
- contents += tuner_and_channel;\r
- contents += "\" tvg-logo=\"";\r
- contents += ((types[t] == Tuner::ISDB_T) ? "t_" : "s_");\r
- if (chstr != NULL)\r
- {\r
- contents += chstr;\r
- }\r
- else\r
- {\r
- contents += "ffff";\r
- }\r
- contents += "\" group-title=\"";\r
- contents += _tuners[i]->name();\r
- contents += "\", ";\r
- String *station_name = stationName(types[t], ch);\r
- if (station_name != NULL)\r
- {\r
- contents += station_name->cString();\r
- }\r
- else\r
- {\r
- contents += tuner_and_channel;\r
- }\r
- contents += "\r\n";\r
- contents += "udp://0.0.0.0:";\r
- contents += udp_str->cString();\r
- contents += "\r\n";\r
- }\r
- }\r
- }\r
- }\r
- }\r
- }\r
+ return result;\r
+}\r
\r
- }\r
+HTTPResponse *Controller::responseForXmltv(HTTPRequest *request, SOCKADDR_IN *client)\r
+{\r
+ HTTPResponse *result = NULL;\r
\r
- String *text = String::stringWithUTF8String(contents.c_str());\r
- if (text != NULL)\r
+ if (_xmltv_xml != NULL)\r
{\r
- result = responseWithUTF8Text(request, text);\r
+ result = responseWithUTF8Text(request, _xmltv_xml);\r
}\r
\r
return result;\r
{\r
return responseForPlaylist(request, client);\r
}\r
+ else if (uri->isMatch("^/xmltv.xml$"))\r
+ {\r
+ return responseForXmltv(request, client);\r
+ }\r
\r
//\r
else if (uri->isMatch("^/iptd.log$"))\r
return result;\r
}\r
\r
-// epgの開始時刻でソートする為の比較関数\r
-Integer compareFunction(Object *obj1, Object *obj2, void *context)\r
-{\r
- if (isKindOfClass(Dictionary, obj1) && isKindOfClass(Dictionary, obj2))\r
- {\r
- time_t st1;\r
- time_t ed1;\r
- Controller::getTimeWithEPG((Dictionary *)obj1, &st1, &ed1);\r
-\r
- time_t st2;\r
- time_t ed2;\r
- Controller::getTimeWithEPG((Dictionary *)obj2, &st2, &ed2);\r
-\r
- if (st1 < st2)\r
- {\r
- return OrderedAscending;\r
- }\r
- else if (st1 > st2)\r
- {\r
- return OrderedDescending;\r
- }\r
- else\r
- {\r
- if (ed1 < ed2)\r
- {\r
- return OrderedAscending;\r
- }\r
- else if (ed1 > ed2)\r
- {\r
- return OrderedDescending;\r
- }\r
- }\r
- }\r
- return OrderedSame;\r
-}\r
-\r
Array *Controller::programsForServices(Array *services)\r
{\r
DebugLog2("Controller::programsForServices()");\r
{\r
// 初期化成功\r
DebugLog2("tuner initialize success.");\r
-#if 0\r
+#if 1\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
}\r
\r
+ RELEASE(_service_to_channels);\r
+ _service_to_channels = Dictionary::alloc()->initWithCapacity(0);\r
+\r
+ _xmltv_channels = "";\r
+ std::string str_iptv_m3u8;\r
+ str_iptv_m3u8 = "#EXTM3U\r\n";\r
+ str_iptv_m3u8 += "\r\n";\r
+\r
+ Dictionary *tunerInfos = _props->dictionaryForKey(KEY_TUNERS);\r
+ int idx_isdb_t = 0;\r
+ int idx_isdb_s = 0;\r
+ Tuner::Type type = Tuner::Type::ISDB_T;\r
+ while ((idx_isdb_t < _tunerCount) || (idx_isdb_s < _tunerCount))\r
+ {\r
+ int *idx = (type == Tuner::Type::ISDB_T) ? &idx_isdb_t : &idx_isdb_s;\r
+ while (*idx < _tunerCount)\r
+ {\r
+ if (_tuners[*idx]->type() == type)\r
+ {\r
+ Dictionary *tunerInfo = tunerInfos->dictionaryForKey(_tuners[*idx]->name());\r
+ if (tunerInfo->boolForKey(KEY_ENABLED))\r
+ {\r
+ int ch_max = (type == Tuner::Type::ISDB_T) ? Tuner::MAX_CHANNELS_ISDB_T : Tuner::MAX_CHANNELS_ISDB_S;\r
+ for (int ch = 0; ch < ch_max; ++ch)\r
+ {\r
+ char key[8];\r
+ sprintf_s(key, "%03d", ch);\r
+ Dictionary *channelInfo = tunerInfo->dictionaryForKey(KEY_CHANNELS)->dictionaryForKey(key);\r
+ if ((channelInfo != NULL) && channelInfo->boolForKey(KEY_ENABLED))\r
+ {\r
+ Array *services = channelInfo->arrayForKey(KEY_SERVICES);\r
+ for (uint service_idx = 0; service_idx < services->count(); ++service_idx)\r
+ {\r
+ Dictionary *service = (Dictionary *)services->objectAtIndex(service_idx);\r
+ char channel_name[32];\r
+ sprintf_s(channel_name, "%03d_%s", *idx, service->stringForKey(KEY_SERVICE_ID)->cString());\r
+\r
+ Array *ch_list = _service_to_channels->arrayForKey(service->stringForKey(KEY_SERVICE_ID));\r
+ if (ch_list == NULL)\r
+ {\r
+ ch_list = Array::arrayWithCapacity(0);\r
+ _service_to_channels->setObject(ch_list, service->stringForKey(KEY_SERVICE_ID));\r
+ }\r
+ ch_list->addObject(String::stringWithUTF8String(channel_name));\r
+\r
+ _xmltv_channels += " <channel id=\"";\r
+ _xmltv_channels += channel_name;\r
+ _xmltv_channels += "\"";\r
+ // transport_stream_id\r
+ // original_network_id\r
+ _xmltv_channels += " service_id=\"";\r
+ _xmltv_channels += service->stringForKey(KEY_SERVICE_ID)->cString();\r
+ _xmltv_channels += "\">\r\n";\r
+\r
+ _xmltv_channels += " <display-name lang=\"ja_JP\">";\r
+ _xmltv_channels += service->stringForKey(KEY_NAME)->cString();\r
+ _xmltv_channels += "</display-name>\r\n";\r
+\r
+ _xmltv_channels += " </channel>\r\n";\r
+\r
+ str_iptv_m3u8 += "#EXTINF:-1 tvg-id=\"";\r
+ str_iptv_m3u8 += channel_name;\r
+ str_iptv_m3u8 += "\" tvg-logo=\"logo_";\r
+ str_iptv_m3u8 += channel_name;\r
+ str_iptv_m3u8 += "\" group-title=\"";\r
+ str_iptv_m3u8 += _tuners[*idx]->name();\r
+ str_iptv_m3u8 += "\", ";\r
+ str_iptv_m3u8 += service->stringForKey(KEY_NAME)->cString();\r
+ str_iptv_m3u8 += "\r\n";\r
+ str_iptv_m3u8 += "http://0.0.0.0:50080/";\r
+ str_iptv_m3u8 += channel_name;\r
+ str_iptv_m3u8 += "/streaming.m3u8\r\n";\r
+ }\r
+ }\r
+ }\r
+ }\r
+ break;\r
+ }\r
+ ++(*idx);\r
+ }\r
+ ++(*idx);\r
+ type = (type == Tuner::Type::ISDB_T) ? Tuner::Type::ISDB_S : Tuner::Type::ISDB_T;\r
+ }\r
+\r
+ _iptv_m3u8 = String::alloc()->initWithUTF8String(str_iptv_m3u8.c_str());\r
+\r
+\r
// 周期タイマ起動\r
_timer_periodic = Timer::alloc()->initWithTimeInterval(1.0, this, (void *)CMD_PERIODIC, true);\r
_timer_periodic->fire();\r
// 設定以前にログ出力しないこと\r
Raym::LOG_NUM_MAX = 8;\r
\r
+#if 0\r
+ AutoreleasePool *epg_pool = AutoreleasePool::alloc()->init();\r
+\r
+ class EPGTest : public Raym::TimerDelegate\r
+ {\r
+ public:\r
+ Analyzer * _an;\r
+ Timer * _timer;\r
+\r
+ EPGTest(Analyzer *an)\r
+ {\r
+ _an = an;\r
+\r
+ _timer = Timer::alloc()->initWithTimeInterval(3.0, this, NULL, false);\r
+ _timer->fire();\r
+ }\r
+\r
+ ~EPGTest()\r
+ {\r
+ RELEASE(_timer);\r
+ }\r
+\r
+ void timerExpired(Raym::Timer *timer, void *userInfo)\r
+ {\r
+ AutoreleasePool *pool = AutoreleasePool::alloc()->init();\r
+ Data *data = Data::dataWithContentsOfFile("./mini.ts");\r
+ if (data != NULL)\r
+ {\r
+ DebugLog0("open ok");\r
+ _an->put((uint8_t *)data->bytes(), data->length());\r
+ }\r
+ else\r
+ {\r
+ DebugLog0("open ng");\r
+ }\r
+ pool->release();\r
+ }\r
+ };\r
+\r
+ Analyzer *an = Analyzer::alloc()->init();\r
+ EPGTest test(an);\r
+\r
+ Array *collected = an->collectEPGs(60);\r
+ if (collected != NULL)\r
+ {\r
+ DebugLog0("collected: %d", collected->count());\r
+\r
+ Dictionary *dict = Dictionary::dictionaryWithCapacity(0);\r
+ dict->setObject(collected, "Array");\r
+ if (dict->writeToFile("./hoge.plist", false))\r
+ {\r
+ DebugLog0("write ng.");\r
+ }\r
+\r
+ for (uint i = 0; i < collected->count(); ++i)\r
+ {\r
+ Dictionary *epg = (Dictionary *)collected->objectAtIndex(i);\r
+ DebugLog0("EPG: %s", epg->toString().c_str());\r
+ }\r
+ }\r
+\r
+ an->release();\r
+ epg_pool->release();\r
+ return 0;\r
+#endif\r
+\r
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId());\r
if (hProcess != NULL)\r
{\r
_reservation_seq_id = 0;\r
_cancel_epg_collect = false;\r
\r
+ _iptv_m3u8 = NULL;\r
+ _xmltv_xml = NULL;\r
+ _service_to_channels = NULL;\r
+\r
_tunerCount = 0;\r
for (int i = 0; i < ry0::device::MAX_TUNERS; ++i)\r
{\r
RELEASE(_store_path);\r
RELEASE(_reservations_path);\r
RELEASE(_reservations);\r
+ RELEASE(_iptv_m3u8);\r
+ RELEASE(_xmltv_xml);\r
+ RELEASE(_service_to_channels);\r
\r
if (_multi2_dll != NULL)\r
{\r
#include "net/HTTPDaemon.h"\r
\r
#define VERSION "0.03"\r
-#define REVISION 20\r
+#define REVISION 30\r
\r
namespace ry0\r
{\r
public NET::HTTPDaemonDelegate\r
{\r
private:\r
-// CRITICAL_SECTION _cs;\r
\r
Raym::String * _system_path; // システムパス(実行ファイルが配置されているディレクトリ)\r
Raym::String * _props_path; // プロパティファイルのパス\r
Raym::String * _store_path; // 録画データ格納先\r
Raym::Dictionary * _reservations; // 予約情報\r
Raym::String * _reservations_path; // 予約情報ファイルのパス\r
- int _reservation_seq_id; // 予約情報シーケンスID\r
- int _idle_count; // アイドルカウンタ\r
+ int _reservation_seq_id; // 予約情報シーケンスID\r
+ int _idle_count; // アイドルカウンタ\r
\r
- bool _initialized; // 初期化済み\r
- HMODULE _multi2_dll;\r
- bool _cancel_epg_collect; // EPG収集キャンセル\r
+ bool _initialized; // 初期化済み\r
+ HMODULE _multi2_dll;\r
+ bool _cancel_epg_collect; // EPG収集キャンセル\r
\r
- NET::HTTPDaemon * _httpd;\r
+ NET::HTTPDaemon * _httpd;\r
\r
Raym::Dictionary * _streaming_ctrls; // ストリーミング制御情報格納用\r
\r
Raym::Timer * _timer_epg_s; // EPG(ISDB-S)収集用\r
Raym::Timer * _timer_epg_t; // EPG(ISDB-T)収集用\r
\r
+ Raym::String * _iptv_m3u8;\r
+ Raym::String * _xmltv_xml;\r
+ std::string _xmltv_channels;\r
+ Raym::Dictionary * _service_to_channels;\r
+\r
void scanChannel(int tuner);\r
void periodic();\r
void periodic_2();\r
NET::HTTPResponse *responseForModKeywordsCGI(NET::HTTPRequest *request, SOCKADDR_IN *client);\r
NET::HTTPResponse *responseForReloadURI(NET::HTTPRequest *request, SOCKADDR_IN *client, const char *uri, int sec = 0);\r
NET::HTTPResponse *responseForPlaylist(NET::HTTPRequest *request, SOCKADDR_IN *client);\r
+ NET::HTTPResponse *responseForXmltv(NET::HTTPRequest *request, SOCKADDR_IN *client);\r
NET::HTTPResponse *responseForHLSControl(NET::HTTPRequest *request, SOCKADDR_IN *client, int tuner, int channel, Raym::String *preset);\r
NET::HTTPResponse *requestTunerControl(NET::HTTPRequest *request, SOCKADDR_IN *client, int tuner);\r
NET::HTTPResponse *request(NET::HTTPRequest *request, SOCKADDR_IN *client);\r