2 * @file Extractor.cpp
\r
9 #include "Raym/Log.h"
\r
11 #include "Raym/Raym.h"
\r
12 #include "b25/aribstr.h"
\r
13 #include "ry0/iPTd/Extractor.h"
\r
15 using namespace Raym;
\r
22 Extractor::Extractor()
\r
26 _analyzer.setListener(this);
\r
29 Extractor::~Extractor()
\r
37 Extractor *Extractor::alloc()
\r
39 return new Extractor();
\r
42 Extractor *Extractor::init()
\r
47 Dictionary *Extractor::stationInfo()
\r
49 Dictionary *result = NULL;
\r
51 _analyzer.setFlag(MPEG2::TS::Analyzer::FLG_SDT, true);
\r
56 while ((result == NULL) && (count++ < 32))
\r
58 while (_sdt == NULL)
\r
63 if (_sdt->_table_id == 0x42)
\r
65 result = Dictionary::dictionaryWithCapacity(0);
\r
66 Array *services = Array::arrayWithCapacity(0);
\r
67 result->setObject(services, KEY_SERVICES);
\r
68 for (uint32_t i = 0; i < _sdt->_service_count; ++i)
\r
70 Dictionary *service = Dictionary::dictionaryWithCapacity(0);
\r
71 services->addObject(service);
\r
73 sprintf_s(tmp, "%d", _sdt->_services[i]._service_id);
\r
74 service->setString(tmp, KEY_SERVICE_ID);
\r
75 sprintf_s(tmp, "%d", _sdt->_services[i]._desc->service_type);
\r
76 service->setString(tmp, KEY_SERVICE_TYPE);
\r
77 service->setBool(false, KEY_IPTV_ENABLED);
\r
78 if (_sdt->_services[i]._desc->service_name_length > 0)
\r
80 String *name = String::stringWithCString(_sdt->_services[i]._desc->service_name, ShiftJISStringEncoding);
\r
81 service->setString(name, KEY_NAME);
\r
84 result->setString(name, KEY_NAME);
\r
96 _analyzer.setFlag(MPEG2::TS::Analyzer::FLG_SDT, false);
\r
101 Array *Extractor::collectEPGs(time_t limit)
\r
103 _analyzer.setFlag(MPEG2::TS::Analyzer::FLG_EIT, true);
\r
105 std::vector<MPEG2::TS::EIT *> eits;
\r
109 time_t start = time(NULL);
\r
112 while ((_eit == NULL) && (time(NULL) < start + limit))
\r
114 RaymCondTimedWait(this, 1000);
\r
119 eits.push_back(_eit);
\r
130 _analyzer.setFlag(MPEG2::TS::Analyzer::FLG_EIT, false);
\r
132 Array *result = Array::arrayWithCapacity(0);
\r
134 std::vector<MPEG2::TS::EIT *>::iterator it;
\r
135 for (it = eits.begin(); it != eits.end(); ++it)
\r
137 MPEG2::TS::EIT *eit = (*it);
\r
138 if ((eit->_table_id == MPEG2::TS::EIT::TABLE_ID_SELF) ||
\r
139 ((MPEG2::TS::EIT::TABLE_ID_SELF_SCHEDULE_BEGIN <= eit->_table_id) && (eit->_table_id <= MPEG2::TS::EIT::TABLE_ID_SELF_SCHEDULE_END)))
\r
141 MPEG2::TS::EIT::Event *event;
\r
142 while ((event = eit->nextEvent()) != NULL)
\r
144 char service_id[32];
\r
145 sprintf_s(service_id, "%d", eit->_service_id);
\r
148 sprintf_s(event_id, "%d", event->_event_id);
\r
150 Dictionary *epg = NULL;
\r
152 for (uint32_t i = 0; i < result->count(); ++i)
\r
154 epg = (Dictionary *)result->objectAtIndex(i);
\r
155 if (epg->stringForKey(KEY_EPG_SERVICE_ID)->isEqualToString(service_id) &&
\r
156 epg->stringForKey(KEY_EPG_EVENT_ID)->isEqualToString(event_id))
\r
165 epg = Dictionary::dictionaryWithCapacity(0);
\r
166 epg->setString(service_id, KEY_EPG_SERVICE_ID);
\r
167 epg->setString(event_id, KEY_EPG_EVENT_ID);
\r
170 sprintf_s(date, sizeof(date), "%02d/%02d/%02d", event->_st_year, event->_st_month, event->_st_day);
\r
171 epg->setString(date, KEY_EPG_DATE);
\r
174 sprintf_s(start, sizeof(start), "%02d:%02d:%02d", event->_st_hour, event->_st_min, event->_st_sec);
\r
175 epg->setString(start, KEY_EPG_START);
\r
177 int hour = event->_st_hour + event->_dur_hour;
\r
178 int min = event->_st_min + event->_dur_min;
\r
179 int sec = event->_st_sec + event->_dur_sec;
\r
191 sprintf_s(end, sizeof(end), "%02d:%02d:%02d", hour, min, sec);
\r
192 epg->setString(end, KEY_EPG_END);
\r
195 sprintf_s(duration, sizeof(duration), "%d", event->_dur_hour * 3600 + event->_dur_min * 60 + event->_dur_sec);
\r
196 epg->setString(duration, KEY_EPG_DURATION);
\r
198 result->addObject(epg);
\r
201 Array *ext_items = NULL;
\r
202 String *ext_item_desc = NULL;
\r
203 Data *ext_item = NULL;
\r
204 Data *ext_text = NULL;
\r
206 MPEG2::TS::Descriptor *desc;
\r
207 while ((desc = event->nextDescriptor()) != NULL)
\r
209 switch (desc->_descriptor_tag)
\r
211 case MPEG2::TS::TAG_BOUQUET_NAME_DESCRIPTOR:
\r
212 DebugLog3("TAG_BOUQUET_NAME_DESCRIPTOR\n");
\r
215 case MPEG2::TS::TAG_SERVICE_DESCRIPTOR:
\r
216 DebugLog3("TAG_SERVICE_DESCRIPTOR\n");
\r
219 case MPEG2::TS::TAG_SHORT_EVENT_DESCRIPTOR:
\r
220 DebugLog3("TAG_SHORT_EVENT_DESCRIPTOR\n");
\r
221 if (desc->_short_event._event_name_length > 0)
\r
223 char *tmp = (char *)malloc(desc->_short_event._event_name_length * 3);
\r
226 AribToString(tmp, (const char *)desc->_short_event._event_name, desc->_short_event._event_name_length);
\r
227 String *event_name = String::stringWithCString(tmp, ShiftJISStringEncoding);
\r
228 if (event_name != NULL)
\r
230 epg->setString(event_name, KEY_EPG_TITLE);
\r
235 if (desc->_short_event._text_length > 0)
\r
237 char *tmp = (char *)malloc(desc->_short_event._text_length * 3);
\r
240 AribToString(tmp, (const char *)desc->_short_event._text, desc->_short_event._text_length);
\r
241 String *text = String::stringWithCString(tmp, ShiftJISStringEncoding);
\r
244 epg->setString(text, KEY_EPG_DESCRIPTION);
\r
251 case MPEG2::TS::TAG_EXTENDED_EVENT_DESCRIPTOR:
\r
252 DebugLog3("TAG_EXTENDED_EVENT_DESCRIPTOR\n");
\r
254 for (int i = 0; i < desc->_extended_event._item_count; ++i)
\r
256 if (ext_items == NULL)
\r
258 ext_items = Array::arrayWithCapacity(0);
\r
259 epg->setObject(ext_items, KEY_EPG_EXT_ITEMS);
\r
262 if (desc->_extended_event._items[i]._item_description_length > 0)
\r
264 if (ext_item != NULL)
\r
266 char *tmp = (char *)malloc(ext_item->length() * 3);
\r
269 AribToString(tmp, (const char *)ext_item->bytes(), ext_item->length());
\r
270 String *desc = String::stringWithCString(tmp, ShiftJISStringEncoding);
\r
273 Dictionary *dict = Dictionary::dictionaryWithCapacity(0);
\r
274 if (ext_item_desc != NULL)
\r
276 dict->setString(ext_item_desc, KEY_EPG_EXT_ITEM_DESCRIPTION);
\r
277 ext_item_desc = NULL;
\r
279 dict->setString(desc, KEY_EPG_EXT_ITEM);
\r
280 ext_items->addObject(dict);
\r
287 char *tmp = (char *)malloc(desc->_extended_event._items[i]._item_description_length * 3);
\r
290 AribToString(tmp, (const char *)desc->_extended_event._items[i]._item_description,
\r
291 desc->_extended_event._items[i]._item_description_length);
\r
292 ext_item_desc = String::stringWithCString(tmp, ShiftJISStringEncoding);
\r
297 ext_item_desc = NULL;
\r
301 if (desc->_extended_event._items[i]._item_length > 0)
\r
303 if (ext_item == NULL)
\r
305 ext_item = Data::dataWithCapacity(0);
\r
307 ext_item->appendBytes(desc->_extended_event._items[i]._item,
\r
308 desc->_extended_event._items[i]._item_length);
\r
311 if (desc->_extended_event._text_length > 0)
\r
313 if (ext_text == NULL)
\r
315 ext_text = Data::dataWithCapacity(0);
\r
317 ext_text->appendBytes(desc->_extended_event._text, desc->_extended_event._text_length);
\r
322 case MPEG2::TS::TAG_CONTENT_DESCRIPTOR:
\r
323 DebugLog3("TAG_CONTENT_DESCRIPTOR\n");
\r
326 case MPEG2::TS::TAG_SERIES_DESCRIPTOR:
\r
327 DebugLog3("TAG_SERIES_DESCRIPTOR\n");
\r
330 case MPEG2::TS::TAG_EVENT_GROUP_DESCRIPTOR:
\r
331 DebugLog3("TAG_EVENT_GROUP_DESCRIPTOR\n");
\r
334 case MPEG2::TS::TAG_COMPONENT_DESCRIPTOR:
\r
335 DebugLog3("TAG_COMPONENT_DESCRIPTOR\n");
\r
338 case MPEG2::TS::TAG_DIGITAL_COPY_CONTROL_DESCRIPTOR:
\r
339 DebugLog3("TAG_DIGITAL_COPY_CONTROL_DESCRIPTOR\n");
\r
342 case MPEG2::TS::TAG_AUDIO_COMPONENT_DESCRIPTOR:
\r
343 DebugLog3("TAG_AUDIO_COMPONENT_DESCRIPTOR\n");
\r
346 case MPEG2::TS::TAG_DATA_CONTENT_DESCRIPTOR:
\r
347 DebugLog3("TAG_AUDIO_COMPONENT_DESCRIPTOR\n");
\r
351 DebugLog3("Unknown descriptor: 0x%02X\n", desc->_descriptor_tag);
\r
356 if (ext_item != NULL)
\r
358 char *tmp = (char *)malloc(ext_item->length() * 3);
\r
361 AribToString(tmp, (const char *)ext_item->bytes(), ext_item->length());
\r
362 String *desc = String::stringWithCString(tmp, ShiftJISStringEncoding);
\r
365 Dictionary *dict = Dictionary::dictionaryWithCapacity(0);
\r
366 if (ext_item_desc != NULL)
\r
368 dict->setString(ext_item_desc, KEY_EPG_EXT_ITEM_DESCRIPTION);
\r
369 ext_item_desc = NULL;
\r
371 dict->setString(desc, KEY_EPG_EXT_ITEM);
\r
372 ext_items->addObject(dict);
\r
379 if (ext_text != NULL)
\r
381 char *tmp = (char *)malloc(ext_text->length() * 3);
\r
384 AribToString(tmp, (const char *)ext_text->bytes(), ext_text->length());
\r
385 String *desc = String::stringWithCString(tmp, ShiftJISStringEncoding);
\r
388 Dictionary *dict = Dictionary::dictionaryWithCapacity(0);
\r
389 dict->setString("no desc", KEY_EPG_EXT_ITEM_DESCRIPTION);
\r
390 dict->setString(desc, KEY_EPG_EXT_ITEM);
\r
391 ext_items->addObject(dict);
\r
406 void Extractor::put(uint8_t *buffer, uint32_t size)
\r
408 _analyzer.put(buffer, size);
\r
411 void Extractor::detect(MPEG2::TS::PAT *pat)
\r
415 void Extractor::detect(MPEG2::TS::SDT *sdt)
\r
423 _sdt = new MPEG2::TS::SDT(*sdt);
\r
424 RaymCondSignal(this);
\r
428 void Extractor::detect(MPEG2::TS::EIT *eit)
\r
436 _eit = new MPEG2::TS::EIT(*eit);
\r
437 RaymCondSignal(this);
\r