OSDN Git Service

commit local dev ver
[rec10/rec10-git.git] / epgdump / sdtt.c
1 // -*- tab-width:4 -*-
2
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6
7 #include "sdtt.h"
8 #include "ts_ctl.h"
9 #include "clt2png.h"
10
11 // STD-B21 p130 (144)
12 int parseSDTThead(unsigned char *data, SDTThead *h) {
13         int boff = 0;
14
15         memset(h, 0, sizeof(SDTThead));
16
17         h->table_id = getBit(data, &boff, 8);
18         h->section_syntax_indicator = getBit(data, &boff, 1);
19         h->reserved_future_use1 = getBit(data, &boff, 1);
20         h->reserved1 = getBit(data, &boff, 2);
21         h->section_length = getBit(data, &boff, 12);
22         h->maker_id = getBit(data, &boff, 8);
23         h->model_id = getBit(data, &boff, 8);
24         // boff -= 16;
25         // h->table_id_ext = getBit(data, &boff, 16);
26         h->reserved2 = getBit(data, &boff, 2);
27         h->version_number = getBit(data, &boff, 5);
28         h->current_next_indicator = getBit(data, &boff, 1);
29         h->section_number = getBit(data, &boff, 8);
30         h->last_section_number = getBit(data, &boff, 8);
31         h->transport_stream_id = getBit(data, &boff, 16);
32         h->original_network_id = getBit(data, &boff, 16);
33         h->service_id = getBit(data, &boff, 16);
34         h->num_of_contents = getBit(data, &boff, 8);
35
36         return 15;
37 }
38
39 // STD-B21 p130 (144)
40 int parseSDTTcont(unsigned char *data, SDTTcont *sdtc) {
41         int boff = 0;
42
43         memset(sdtc, 0, sizeof(SDTTcont));
44         sdtc->group = getBit(data, &boff, 4);
45         sdtc->target_version = getBit(data, &boff, 12);
46         sdtc->new_version = getBit(data, &boff, 12);
47         sdtc->download_level = getBit(data, &boff, 2);
48         sdtc->version_indicator = getBit(data, &boff, 2);
49         sdtc->content_description_length = getBit(data, &boff, 12);
50         sdtc->reserved1 = getBit(data, &boff, 4);
51         sdtc->schedule_description_length = getBit(data, &boff, 12);
52         sdtc->schedule_timeshift_information = getBit(data, &boff, 4);  
53         /*
54         for (i=0; i<sdtc->schedule_description_length / 8; i++) {
55                 sdtc->start_time = getBit(data, &boff, 40);
56                 sdtc->duration = getBit(data, &boff, 24);
57         }
58         */
59
60         return sdtc->schedule_description_length + 8;
61         //return sdtc->content_description_length + 8;
62 }
63
64 // STD-B21 p132 (146)
65 int parseSDTTdesc(unsigned char *data, SDTTdesc *sdts) {
66 // 0xC9(201)
67         int boff = 0;
68         int i = 0;
69         SDTTdescModule *module;
70
71         memset(sdts, 0, sizeof(SDTTdesc));
72         sdts->descriptor_tag = getBit(data, &boff, 8);
73         sdts->descriptor_length = getBit(data, &boff, 8);
74         sdts->reboot = getBit(data, &boff, 1);
75         sdts->add_on = getBit(data, &boff, 1);
76         sdts->compatibility_flag = getBit(data, &boff, 1);
77         sdts->module_info_flag = getBit(data, &boff, 1);
78         sdts->text_info_flag = getBit(data, &boff, 1);
79         sdts->reserved1 = getBit(data, &boff, 3);
80         sdts->component_size = getBit(data, &boff, 32);
81         sdts->download_id = getBit(data, &boff, 32);
82         sdts->time_out_value_DII = getBit(data, &boff, 32);
83         sdts->leak_rate = getBit(data, &boff, 22);
84         sdts->reserved2 = getBit(data, &boff,2);
85         sdts->component_tag = getBit(data, &boff, 8);
86
87         if ( sdts->compatibility_flag == 1) {
88                 sdts->compatibility_length = getBit(data, &boff, 16);
89                 boff += sdts->compatibility_length * 8;
90         }
91         if ( sdts->module_info_flag == 1) {
92                 sdts->num_of_modules = getBit(data, &boff, 16);
93
94                 if ( sdts->num_of_modules > 0 ) 
95                         sdts->modules = calloc(1, sizeof(SDTTdescModule) * ( sdts->num_of_modules + 1 ));
96
97                 for (i=0; i<sdts->num_of_modules; i++) {
98                         module = sdts->modules + sizeof(SDTTdescModule) * i;// &sdts->modules[i];
99                         module->module_id = getBit(data, &boff, 16);
100                         module->module_size = getBit(data, &boff, 32);
101                         module->module_info_length = getBit(data, &boff, 8);
102                         if ( *(data + boff / 8) == 0x01 ) {
103                                 /* Type 記述子 モジュールの型(MIME 形式等) */
104                                 module->descriptor_tag = getBit(data, &boff, 8);
105                                 module->descriptor_length = getBit(data, &boff, 8);
106                                 module->Type = allocCopy(data, &boff, module->descriptor_length);
107                                 module->Type[module->descriptor_length] = '\0';
108                                 // +1 byte for null-terminated
109                         }
110                         else if ( *(data + boff / 8) == 0x02 ) {
111                                 /* Name 記述子 モジュール名(ファイル名) */
112                                 module->descriptor_tag = getBit(data, &boff, 8);
113                                 module->descriptor_length = getBit(data, &boff, 8);
114                                 module->Name = allocCopy(data, &boff, module->descriptor_length);
115                                 module->Name[module->descriptor_length] = '\0';
116                         }
117                         else if ( *(data + boff / 8) == 0x03 ) {
118                                 /* Info 記述子 モジュール情報(文字型) */
119                                 module->descriptor_tag = getBit(data, &boff, 8);
120                                 module->descriptor_length = getBit(data, &boff, 8);
121                                 boff += 24; // ISO_639_language_code
122                                 module->Info = allocCopy(data, &boff, module->descriptor_length - 3);
123                                 module->Info[module->descriptor_length] = '\0';
124                         }
125                         else {
126                                 module->module_info_byte = allocCopy(data, &boff, module->module_info_length);
127                         }
128                 }
129         }
130         sdts->private_data_length = getBit(data, &boff, 8);
131         sdts->private_data_byte = allocCopy(data, &boff, sdts->private_data_length);
132         if ( sdts->text_info_flag == 1) {
133                 sdts->ISO_639_language_code = getBit(data, &boff, 24);
134                 sdts->text_length = getBit(data, &boff, 8);
135                 getStr(sdts->text_char, data, &boff, sdts->text_length);
136                 //sdts->text_char = allocCopy(data, &boff, sdts->text_length);
137         }
138
139         return boff / 8;
140 }
141
142 // STD-B21 p193 (209)
143 int parseSDTTdata(unsigned char *data, SDTTdata *cdtd) {
144         int boff = 0, i, j;
145         SDTTdataLoop *loop;
146         SDTTdataService *service;
147
148         memset(cdtd, 0, sizeof(SDTTdata));
149
150         cdtd->logo_type = getBit(data, &boff, 8);
151         cdtd->number_of_loop = getBit(data, &boff, 16);
152         cdtd->loop = calloc(1, sizeof(SDTTdataLoop) * cdtd->number_of_loop);
153
154         for (i=0; i<cdtd->number_of_loop; i++) {
155                 loop = cdtd->loop + sizeof(SDTTdataLoop) * i;
156
157                 loop->reserved_future_use1 = getBit(data, &boff, 7);
158                 loop->logo_id = getBit(data, &boff, 9);
159                 loop->number_of_services = getBit(data, &boff, 8);
160                 loop->services = calloc(1, sizeof(SDTTdataService) * loop->number_of_services);
161
162                 for (j=0; j<loop->number_of_services; j++) {
163                         service = loop->services + sizeof(SDTTdataService) * j;
164                         service->original_network_id = getBit(data, &boff, 16);
165                         service->transport_stream_id = getBit(data, &boff, 16);
166                         service->service_id = getBit(data, &boff, 16);
167                 }
168                 loop->data_size = getBit(data, &boff, 16);
169                 loop->data = allocCopy(data, &boff, loop->data_size);
170         }
171
172         return boff / 8;
173 }
174
175 void dumpSDTT(unsigned char *ptr, STATION *station, int station_count)
176 {
177         SDTThead  sdth;
178         SDTTcont  sdtc;
179         SDTTdesc  sdts;
180         SDTTdata  sdtd;
181         SDTTdescModule *module;
182
183         int len = 0;
184         int loop_len = 0;
185         int desc_len = 0;
186         int i, j;
187
188         /* SDTT */
189         len = parseSDTThead(ptr, &sdth);
190         ptr += len;
191         loop_len = sdth.section_length - (len - 3 + 4); // 3は共通ヘッダ長 4はCRC
192
193         /*
194         printf("SDTT=(%d:%d:%d:%d:%d:%d:%d:%d:%d:%d)\n",
195                 sdth.table_id, sdth.section_number, sdth.version_number, 
196                 sdth.maker_id, sdth.model_id, 
197                 sdth.transport_stream_id, sdth.original_network_id, 
198                 sdth.service_id, sdth.num_of_contents, sdth.section_length);
199         */
200
201         if ( sdth.maker_id == 0xff && sdth.model_id == 0xfe )
202                 printf("BS FOUND\n");
203
204         if ( sdth.maker_id == 0xff && sdth.model_id == 0xfc )
205                 printf("BS/広帯域 CS FOUND\n");
206
207         if ( ! ( sdth.maker_id == 0xff && ( sdth.model_id == 0xfc || sdth.model_id == 0xfe ) ) )
208                 return;
209
210         while(loop_len > 0) {
211                 /*
212                 logo_type
213                 0x00 24x48 864  SD4:3 スモール 
214                 0x01 24x36 648  SD16:9 スモール
215                 0x02 27x48 972  HD スモール 
216                 0x03 36x72 1296 SD4:3 ラージ 
217                 0x04 36x54 972  SD16:9 ラージ 
218                 0x05 36x64 1152 HD ラージ 
219                 */
220
221                 for (i=0; i<sdth.num_of_contents; i++) {
222                         len = parseSDTTcont(ptr, &sdtc);
223                         ptr += len;
224                         loop_len -= len;
225
226                         desc_len = sdtc.content_description_length - sdtc.schedule_description_length;
227                         loop_len -= desc_len;
228
229                         while(desc_len > 0) {
230                                 if ( *ptr != 0xC9 ) {
231                                         len = parseOTHERdesc(ptr);
232                                         ptr += len;
233                                         desc_len -= len;
234                                         continue;
235                                 }
236
237                                 len = parseSDTTdesc(ptr, &sdts);
238                                 ptr += len;
239                                 desc_len -= len;
240 #if 1
241                                 printf("SDTTdesc %d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%s\n",
242                                         sdts.descriptor_tag, sdts.descriptor_length, 
243                                         sdts.reboot, sdts.add_on, 
244                                         sdts.compatibility_flag, sdts.module_info_flag, sdts.text_info_flag, 
245                                         sdts.component_size, sdts.download_id, sdts.time_out_value_DII, 
246                                         sdts.leak_rate, sdts.component_tag, 
247                                         sdts.text_info_flag ? sdts.text_char : "");
248 #endif
249                                 for (i=0; i<sdts.num_of_modules; i++) {
250                                         module = sdts.modules + sizeof(SDTTdescModule) * i;
251                                         if ( module->descriptor_tag == 0x01 ) {
252                                                 printf("sdts.Type %s id:%d\n", module->Type, sdts.download_id);
253                                         }
254                                         else if ( module->descriptor_tag == 0x02 ) {
255                                                 printf("sdts.Name %s id:%d\n", module->Name, sdts.download_id);
256
257                                                 if ( strstr( module->Name, "CS_LOGO" ) ) {
258                                                         station[0].logo_download_data_id = sdts.download_id;
259                                                 }
260                                                 else if ( strstr( module->Name, "LOGO" ) ) {
261                                                         station[0].logo_download_data_id = sdts.download_id;
262                                                 }
263                                         }
264                                         else if ( module->descriptor_tag == 0x03 ) {
265                                                 printf("sdts.Info %s id:%d\n", module->Info, sdts.download_id);
266                                         }
267                                         else {
268                                                 printf("MIB: %s\n", module->module_info_byte);
269                                         }
270                                 }
271 /*
272                                 len = parseSDTTdata(ptr, &sdtd);
273                                 ptr += len;
274                                 desc_len -= len;
275 */
276 #if 0
277                         printf("SDTT=(%d:%d:%d:%d:%d:%dbyte:desc%dbyte)%d,%d,%d,%d\n",
278                                 cdth.table_id, cdth.download_data_id, cdth.version_number, 
279                                 cdth.original_network_id, cdth.data_type, 
280                                 cdth.section_length, cdth.descriptors_loop_length, 
281
282                                 cdtdte.logo_type, cdtdte.logo_id, cdtdte.logo_version,
283                                 cdtdte.data_size);
284 #endif
285                         }
286                 }
287         }
288         return;
289 }
290