OSDN Git Service

EPG収集
[iptd/iPTd.git] / src / mpeg2 / ts / SDT.cpp
1 /**\r
2  * @file SDT.cpp\r
3  *\r
4  */\r
5 \r
6 #include "b25/aribstr.h"\r
7 #include "mpeg2/ts/SDT.h"\r
8 \r
9 namespace MPEG2\r
10 {\r
11 namespace TS\r
12 {\r
13 \r
14 static int getBit(unsigned char *byte, int *pbit, int gbit)\r
15 {\r
16         int pbyte = *pbit / 8;\r
17         unsigned char *fbyte = byte + pbyte;\r
18 \r
19         int cutbit = *pbit - (pbyte * 8);\r
20         int lcutbit = 32 - (cutbit + gbit);\r
21 \r
22         unsigned char tbuf[4]; //\r
23         unsigned int tnum;\r
24 \r
25         memcpy(tbuf, fbyte, sizeof(unsigned char) * 4);\r
26 \r
27         //\r
28         tbuf[0] = tbuf[0] << cutbit;\r
29         tbuf[0] = tbuf[0] >> cutbit;\r
30 \r
31         //\r
32         tnum = tbuf[0] << 24 | tbuf[1] << 16 | tbuf[2] << 8 | tbuf[3];\r
33 \r
34         //\r
35         tnum = tnum >> lcutbit;\r
36 \r
37         *pbit += gbit;\r
38 \r
39         return tnum;\r
40   \r
41 }\r
42 \r
43 static int parseSDThead(unsigned char *data, SDThead *h)\r
44 {\r
45         int boff = 0;\r
46 \r
47         memset(h, 0, sizeof(SDThead));\r
48 \r
49         boff = 0;\r
50         h->table_id = getBit(data, &boff, 8);\r
51         h->section_syntax_indicator = getBit(data, &boff, 1);\r
52         h->reserved_future_use1 = getBit(data, &boff, 1);\r
53         h->reserved1 = getBit(data, &boff, 2);\r
54         h->section_length = getBit(data, &boff, 12);\r
55         h->transport_stream_id = getBit(data, &boff, 16);\r
56         h->reserved2 = getBit(data, &boff, 2);\r
57         h->version_number = getBit(data, &boff, 5);\r
58         h->current_next_indicator = getBit(data, &boff, 1);\r
59         h->section_number = getBit(data, &boff, 8);\r
60         h->last_section_number = getBit(data, &boff, 8);\r
61         h->original_network_id = getBit(data, &boff, 16);\r
62         h->reserved_future_use2 = getBit(data, &boff, 8);\r
63 \r
64         return 11;\r
65 }\r
66 \r
67 static int parseSDTbody(unsigned char *data, SDTbody *b)\r
68 {\r
69         int boff = 0;\r
70 \r
71         memset(b, 0, sizeof(SDTbody));\r
72 \r
73         b->service_id = getBit(data, &boff, 16);\r
74         b->reserved_future_use1 = getBit(data, &boff, 3);\r
75         b->EIT_user_defined_flags = getBit(data, &boff, 3);\r
76         b->EIT_schedule_flag = getBit(data, &boff, 1);\r
77         b->EIT_present_following_flag = getBit(data, &boff, 1);\r
78         b->running_status = getBit(data, &boff, 3);\r
79         b->free_CA_mode = getBit(data, &boff, 1);\r
80         b->descriptors_loop_length = getBit(data, &boff, 12);\r
81 \r
82         return 5;\r
83 }\r
84 \r
85 static void getStr(char *tostr, unsigned char *byte, int *pbit, int len)\r
86 {\r
87     char str[MAXSECLEN];\r
88     int pbyte = *pbit / 8;\r
89     unsigned char *fbyte = byte + pbyte;\r
90 \r
91     memset(str, 0, sizeof(char) * MAXSECLEN);\r
92     memcpy(str, fbyte, len);\r
93 \r
94     *pbit += (len * 8);\r
95 \r
96     AribToString(tostr, str, len);\r
97 }\r
98 \r
99 static int parseSVCdesc(unsigned char *data, SVCdesc *desc)\r
100 {\r
101         int boff = 0;\r
102   \r
103         memset(desc, 0, sizeof(SVCdesc));\r
104 \r
105         desc->descriptor_tag = getBit(data, &boff, 8);\r
106         desc->descriptor_length = getBit(data, &boff, 8);\r
107         desc->service_type = getBit(data, &boff, 8);\r
108         desc->service_provider_name_length = getBit(data, &boff, 8);\r
109         getStr(desc->service_provider_name, data, &boff, desc->service_provider_name_length);\r
110         desc->service_name_length = getBit(data, &boff, 8);\r
111         getStr(desc->service_name, data, &boff, desc->service_name_length);\r
112 \r
113         return desc->descriptor_length + 2;\r
114 }\r
115 \r
116 SDT::SDT()\r
117 {\r
118 //    printf("SDT::SDT()\n");\r
119     _service_count = 0;\r
120     _services = NULL;\r
121 }\r
122 SDT::SDT(SDT &sdt)\r
123 {\r
124 //    printf("SDT::SDT(SDT &)\n");\r
125     _table_id                   = sdt._table_id;\r
126     _section_syntax_indicator   = sdt._section_syntax_indicator;\r
127     _section_length             = sdt._section_length;\r
128     _transport_stream_id        = sdt._transport_stream_id;\r
129     _version_number             = sdt._version_number;\r
130     _current_next_indicator     = sdt._current_next_indicator;\r
131     _section_number             = sdt._section_number;\r
132     _last_section_number        = sdt._last_section_number;\r
133     _original_network_id        = sdt._original_network_id;\r
134     _service_count              = sdt._service_count;\r
135     _services                   = (struct _service *)malloc(sizeof(struct _service) * _service_count);\r
136     for (int i = 0; i < _service_count; ++i)\r
137     {\r
138         _services[i]._service_id                    = sdt._services[i]._service_id;\r
139         _services[i]._EIT_user_defined_flags        = sdt._services[i]._EIT_user_defined_flags;\r
140         _services[i]._EIT_schedule_flag             = sdt._services[i]._EIT_schedule_flag;\r
141         _services[i]._EIT_present_following_flag    = sdt._services[i]._EIT_present_following_flag;\r
142         _services[i]._running_status                = sdt._services[i]._running_status;\r
143         _services[i]._free_CA_mode                  = sdt._services[i]._free_CA_mode;\r
144         _services[i]._descriptors_loop_length       = sdt._services[i]._descriptors_loop_length;\r
145         _services[i]._descriptor = NULL;\r
146         if (sdt._services[i]._descriptor != NULL)\r
147         {\r
148             _services[i]._descriptor = (uint8_t *)malloc(_services[i]._descriptors_loop_length);\r
149             memcpy(_services[i]._descriptor, _services[i]._descriptor, _services[i]._descriptors_loop_length);\r
150         }\r
151         _services[i]._desc = NULL;\r
152         if (sdt._services[i]._desc != NULL)\r
153         {\r
154             _services[i]._desc = (SVCdesc *)malloc(sizeof(SVCdesc));\r
155             memcpy(_services[i]._desc, sdt._services[i]._desc, sizeof(SVCdesc));\r
156         }\r
157     }\r
158 }\r
159 \r
160 SDT::~SDT()\r
161 {\r
162 //    printf("SDT::~SDT()\n");\r
163     reset();\r
164 }\r
165 \r
166 bool SDT::decode_section()\r
167 {\r
168 //    printf("SDT::%s\n", __FUNCTION__);\r
169 \r
170         int len = 0;\r
171         int loop_len = 0;\r
172         SDThead  sdth;\r
173         SDTbody  sdtb;\r
174 //      SVCdesc  desc;\r
175 \r
176     uint8_t *ptr = &_section[0];\r
177 \r
178         /* SDT */\r
179         len = parseSDThead(ptr, &sdth);\r
180     if ((sdth.table_id != 0x42) && (sdth.table_id != 0x46))\r
181     {\r
182         return false;\r
183     }\r
184 \r
185     _table_id = sdth.table_id;\r
186 \r
187 #if 0\r
188     if (_services != NULL)\r
189     {\r
190         for (int i = 0; i < _service_count; ++i)\r
191         {\r
192             if (_services[i]._descriptor != NULL)\r
193             {\r
194                 free(_services[i]._descriptor);\r
195                 _services[i]._descriptor = NULL;\r
196             }\r
197             if (_services[i]._desc != NULL)\r
198             {\r
199                 free(_services[i]._desc);\r
200                 _services[i]._desc = NULL;\r
201             }\r
202         }\r
203         free(_services);\r
204         _services = NULL;\r
205     }\r
206     _service_count = 0;\r
207 #else\r
208     reset();\r
209 #endif\r
210         ptr += len;\r
211         loop_len = sdth.section_length - (len - 3 + 4); // 3: common header, 4:CRC\r
212         while (loop_len > 0)\r
213     {\r
214                 len = parseSDTbody(ptr, &sdtb);\r
215                 ptr += len;\r
216                 loop_len -= len;\r
217 \r
218         if (_services == NULL)\r
219         {\r
220             _services = (struct _service *)malloc(sizeof(struct _service));\r
221         }\r
222         else\r
223         {\r
224             _services = (struct _service *)realloc(_services, sizeof(struct _service) * (_service_count + 1));\r
225         }\r
226 \r
227         _services[_service_count]._service_id = sdtb.service_id;\r
228         _services[_service_count]._descriptors_loop_length = 0;\r
229         _services[_service_count]._descriptor = NULL;\r
230         _services[_service_count]._desc = (SVCdesc *)malloc(sizeof(SVCdesc));\r
231 \r
232         parseSVCdesc(ptr, _services[_service_count]._desc);\r
233 \r
234         ++_service_count;\r
235 \r
236                 ptr += sdtb.descriptors_loop_length;\r
237                 loop_len -= sdtb.descriptors_loop_length;\r
238         }\r
239 \r
240     return true;\r
241 }\r
242 \r
243 void SDT::reset()\r
244 {\r
245     if (_services != NULL)\r
246     {\r
247         for (int i = 0; i < _service_count; ++i)\r
248         {\r
249             if (_services[i]._descriptor != NULL)\r
250             {\r
251                 free(_services[i]._descriptor);\r
252                 _services[i]._descriptor = NULL;\r
253             }\r
254             if (_services[i]._desc != NULL)\r
255             {\r
256                 free(_services[i]._desc);\r
257                 _services[i]._desc = NULL;\r
258             }\r
259         }\r
260         free(_services);\r
261         _services = NULL;\r
262     }\r
263     _service_count = 0;\r
264 }\r
265 \r
266 } // TS\r
267 } // MPEG2\r