libtsfuncs is a library for mpeg PSI parsing and generation. https://georgi.unixsol.org/programs/libtsfuncs/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

nit_desc.c 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  1. /*
  2. * NIT descriptor generator
  3. * Copyright (C) 2010-2011 Unix Solutions Ltd.
  4. *
  5. * Released under MIT license.
  6. * See LICENSE-MIT.txt for license terms.
  7. */
  8. #include <stdio.h>
  9. #include <unistd.h>
  10. #include <netdb.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13. #include "tsfuncs.h"
  14. static void ts_nit_regenerate_packet_data(struct ts_nit *nit) {
  15. uint8_t *ts_packets;
  16. int num_packets;
  17. ts_nit_generate(nit, &ts_packets, &num_packets);
  18. memcpy(nit->section_header->packet_data, ts_packets, num_packets * TS_PACKET_SIZE);
  19. nit->section_header->num_packets = num_packets;
  20. free(ts_packets);
  21. }
  22. struct ts_nit *ts_nit_init(struct ts_nit *nit, uint16_t network_id) {
  23. nit->ts_header.pid = 0x10;
  24. nit->ts_header.pusi = 1;
  25. nit->ts_header.payload_field = 1;
  26. nit->ts_header.payload_offset = 4;
  27. nit->section_header->table_id = 0x40;
  28. nit->section_header->version_number = 1;
  29. nit->section_header->current_next_indicator = 1;
  30. nit->section_header->section_syntax_indicator = 1;
  31. nit->section_header->private_indicator = 1;
  32. nit->section_header->section_length = 9 + 4; // Empty section, +4 (16+16) for NIT table data
  33. nit->section_header->ts_id_number = network_id;
  34. nit->section_header->reserved1 = 3;
  35. nit->section_header->reserved2 = 3;
  36. nit->reserved1 = 0xf;
  37. nit->network_info_size = 0; // 16 bits
  38. nit->reserved2 = 0xf;
  39. nit->ts_loop_size = 0; // 16 bits
  40. nit->streams_num = 0;
  41. nit->initialized = 1;
  42. ts_nit_regenerate_packet_data(nit);
  43. return nit;
  44. }
  45. struct ts_nit *ts_nit_alloc_init(uint16_t network_id) {
  46. struct ts_nit *nit = ts_nit_alloc();
  47. if (!nit)
  48. return NULL;
  49. return ts_nit_init(nit, network_id);
  50. }
  51. int ts_nit_add_network_name_descriptor(struct ts_nit *nit, char *network_name) {
  52. if (!network_name || strlen(network_name) > 255)
  53. return 0;
  54. nit->network_info_size = strlen(network_name) + 2;
  55. uint8_t *descriptor = calloc(1, nit->network_info_size);
  56. int dpos = 0;
  57. descriptor[dpos + 0] = 0x40; // Network name descriptor
  58. descriptor[dpos + 1] = nit->network_info_size - 2; // -2 Because of two byte header
  59. dpos += 2;
  60. char *name = network_name;
  61. while (name[0]) {
  62. descriptor[dpos++] = name[0];
  63. name++;
  64. }
  65. nit->network_info = descriptor;
  66. nit->section_header->section_length += nit->network_info_size;
  67. ts_nit_regenerate_packet_data(nit);
  68. return 1;
  69. }
  70. static int ts_nit_add_stream(struct ts_nit *nit, uint16_t ts_id, uint16_t org_net_id, uint8_t *desc, uint8_t desc_size) {
  71. if (nit->streams_num == nit->streams_max - 1 || desc_size == 0) {
  72. FREE(desc);
  73. return 0;
  74. }
  75. int stream_len = 2 + 2 + 1 + 1 + desc_size;
  76. if (stream_len + nit->section_header->section_length > 4093) {
  77. ts_LOGf("NIT no space left, max 4093, current %d will become %d!\n",
  78. nit->section_header->section_length,
  79. stream_len + nit->section_header->section_length);
  80. free(desc);
  81. return 0;
  82. }
  83. nit->ts_loop_size += stream_len;
  84. nit->section_header->section_length += stream_len;
  85. struct ts_nit_stream *sinfo = calloc(1, sizeof(struct ts_nit_stream));
  86. sinfo->transport_stream_id = ts_id; // 2 bytes
  87. sinfo->original_network_id = org_net_id; // 2 bytes
  88. sinfo->reserved1 = 15; // 1 byte
  89. sinfo->descriptor_size = desc_size; // 1 byte
  90. sinfo->descriptor_data = desc; // desc_size bytes
  91. nit->streams[nit->streams_num] = sinfo;
  92. nit->streams_num++;
  93. ts_nit_regenerate_packet_data(nit);
  94. return 1;
  95. }
  96. // freq_type 0 == undefined
  97. // freq_type 1 == satellite
  98. // freq_type 2 == cable
  99. // freq_type 3 == terrestrial
  100. static int ts_nit_add_frequency_list_descriptor(struct ts_nit *nit, uint16_t ts_id, uint16_t org_net_id, uint8_t freq_type, uint32_t *freqs, uint8_t num_freqs) {
  101. uint8_t i;
  102. if (!num_freqs || num_freqs > 63)
  103. return 0;
  104. int desc_size = 2 + 1 + num_freqs * 4; // 2 for header desc header, 1 for coding type, 4 for each frequency
  105. uint8_t *desc = calloc(1, desc_size);
  106. int dpos = 0;
  107. desc[dpos + 0] = 0x62; // frequency_list_descriptor
  108. desc[dpos + 1] = desc_size - 2; // -2 Because of two byte header
  109. desc[dpos + 2] = 0xfc | freq_type; // 6 bits reserved, 2 bits freq_type
  110. dpos += 3;
  111. for(i=0;i<num_freqs;i++) {
  112. uint32_t freq = freqs[i];
  113. desc[dpos + 0] = ((freq &~ 0x00ffffff) >> 24);
  114. desc[dpos + 1] = ((freq &~ 0xff00ffff) >> 16);
  115. desc[dpos + 2] = ((freq &~ 0xffff00ff) >> 8);
  116. desc[dpos + 3] = (freq &~ 0xffffff00);
  117. dpos += 4;
  118. }
  119. return ts_nit_add_stream(nit, ts_id, org_net_id, desc, desc_size);
  120. }
  121. int ts_nit_add_frequency_list_descriptor_neutral(struct ts_nit *nit, uint16_t ts_id, uint16_t org_net_id, uint32_t *freqs, uint8_t num_freqs) {
  122. return ts_nit_add_frequency_list_descriptor(nit, ts_id, org_net_id, 0, freqs, num_freqs);
  123. }
  124. int ts_nit_add_frequency_list_descriptor_satellite(struct ts_nit *nit, uint16_t ts_id, uint16_t org_net_id, uint32_t *freqs, uint8_t num_freqs) {
  125. return ts_nit_add_frequency_list_descriptor(nit, ts_id, org_net_id, 1, freqs, num_freqs);
  126. }
  127. int ts_nit_add_frequency_list_descriptor_cable(struct ts_nit *nit, uint16_t ts_id, uint16_t org_net_id, uint32_t *freqs, uint8_t num_freqs) {
  128. return ts_nit_add_frequency_list_descriptor(nit, ts_id, org_net_id, 2, freqs, num_freqs);
  129. }
  130. int ts_nit_add_frequency_list_descriptor_terrestrial(struct ts_nit *nit, uint16_t ts_id, uint16_t org_net_id, uint32_t *freqs, uint8_t num_freqs) {
  131. return ts_nit_add_frequency_list_descriptor(nit, ts_id, org_net_id, 3, freqs, num_freqs);
  132. }
  133. int ts_nit_add_cable_delivery_descriptor(struct ts_nit *nit, uint16_t ts_id, uint16_t org_net_id, uint32_t freq, uint8_t modulation, uint32_t symbol_rate) {
  134. int desc_size = 13;
  135. uint8_t *desc = calloc(1, desc_size);
  136. desc[ 0] = 0x44; // cable_delivey_system_descriptor
  137. desc[ 1] = 11; // -2 Because of two byte header
  138. desc[ 2] = ((freq &~ 0x00ffffff) >> 24); // 32 bits, frequency
  139. desc[ 3] = ((freq &~ 0xff00ffff) >> 16);
  140. desc[ 4] = ((freq &~ 0xffff00ff) >> 8);
  141. desc[ 5] = (freq &~ 0xffffff00);
  142. desc[ 6] = 0xff; // 8 bits reserved
  143. desc[ 7] = 0xf0; // 4 bits reserved, 4 bits FEC_outer (0 == not defined)
  144. desc[ 8] = modulation; // 8 bits reserved
  145. desc[ 9] = (symbol_rate >> 20) &~ 0xffffff00; // 28 bits, symbol_rate
  146. desc[10] = (symbol_rate >> 12) &~ 0xffffff00;
  147. desc[11] = (symbol_rate >> 4 ) &~ 0xffffff00;
  148. desc[12] = (symbol_rate &~ 0xfffffff0) << 4; // 4 bits
  149. desc[12] |= 0; // 4 bits FEC_inner (0 == not defined)
  150. return ts_nit_add_stream(nit, ts_id, org_net_id, desc, desc_size);
  151. }
  152. int ts_nit_add_service_list_descriptor(struct ts_nit *nit, uint16_t ts_id, uint16_t org_net_id, uint32_t *services, uint8_t num_services) {
  153. uint8_t i;
  154. if (!num_services || num_services > 85) // 85 * 3 == 255
  155. return 0;
  156. int desc_size = 2 + num_services * 3; // 2 for header desc header, 3 for each service
  157. uint8_t *desc = calloc(1, desc_size);
  158. int dpos = 0;
  159. desc[dpos + 0] = 0x41; // service_list_descriptor
  160. desc[dpos + 1] = desc_size - 2; // -2 Because of two byte header
  161. dpos += 2;
  162. for(i=0;i<num_services;i++) {
  163. uint32_t srv = services[i];
  164. desc[dpos + 0] = (srv &~ 0xff00ffff) >> 16; // service_id (16 bits)
  165. desc[dpos + 1] = (srv &~ 0xffff00ff) >> 8;
  166. desc[dpos + 2] = (srv &~ 0xffffff00); // service_type (8 bits)
  167. dpos += 3;
  168. }
  169. return ts_nit_add_stream(nit, ts_id, org_net_id, desc, desc_size);
  170. }
  171. int ts_nit_add_nordig_specifier_descriptor(struct ts_nit *nit, uint16_t ts_id, uint16_t org_net_id) {
  172. int desc_size = 2 + 4; // 2 for header desc header, 3 for each service
  173. uint8_t *desc = calloc(1, desc_size);
  174. int dpos = 0;
  175. desc[dpos + 0] = 0x5f; // service_list_descriptor
  176. desc[dpos + 1] = desc_size - 2; // -2 Because of two byte header
  177. desc[dpos + 2] = 0x00; // -2 Because of two byte header
  178. desc[dpos + 3] = 0x00; // -2 Because of two byte header
  179. desc[dpos + 4] = 0x00; // -2 Because of two byte header
  180. desc[dpos + 5] = 0x29; // -2 Because of two byte header
  181. return ts_nit_add_stream(nit, ts_id, org_net_id, desc, desc_size);
  182. }
  183. int ts_nit_add_lcn_descriptor(struct ts_nit *nit, uint16_t ts_id, uint16_t org_net_id, uint32_t *services, uint8_t num_services) {
  184. uint8_t i;
  185. if (!num_services || num_services > 85) // 85 * 3 == 255
  186. return 0;
  187. int desc_size = 2 + num_services * 4; // 2 for header desc header, 4 for each service
  188. uint8_t *desc = calloc(1, desc_size);
  189. int dpos = 0;
  190. desc[dpos + 0] = 0x83; // service_lcn_descriptor
  191. desc[dpos + 1] = desc_size - 2; // -2 Because of two byte header
  192. dpos += 2;
  193. for(i=0;i<num_services;i++) {
  194. uint32_t srv = services[i];
  195. desc[dpos + 0] = (srv &~ 0x00ffffff) >> 24; // service_id (16 bits)
  196. desc[dpos + 1] = (srv &~ 0xff00ffff) >> 16; // service_id
  197. desc[dpos + 2] = (srv &~ 0xffff00ff) >> 8; // visible (1 bit), private (1 bit), first (6 bits) from lcn_number
  198. desc[dpos + 3] = (srv &~ 0xffffff00); // second (8 bits) lcn_number
  199. dpos += 4;
  200. }
  201. return ts_nit_add_stream(nit, ts_id, org_net_id, desc, desc_size);
  202. }
  203. int ts_nit_add_stream_descriptors(struct ts_nit *nit, uint16_t ts_id, uint16_t org_net_id, uint32_t freq, uint8_t modulation, uint32_t symbol_rate, uint32_t *lcn_services, uint32_t *svc_services, uint8_t num_services) {
  204. if (!num_services || num_services > 85) // 85 * 3 == 255
  205. return 0;
  206. int desc_size = 13 + 6 + 2 + 2 + num_services * 4 + num_services * 3; // 2 for header desc header, + ....
  207. uint8_t *desc = calloc(1, desc_size);
  208. desc[ 0] = 0x44; // cable_delivey_system_descriptor
  209. desc[ 1] = 11; // -2 Because of two byte header
  210. desc[ 2] = ((freq &~ 0x00ffffff) >> 24); // 32 bits, frequency
  211. desc[ 3] = ((freq &~ 0xff00ffff) >> 16);
  212. desc[ 4] = ((freq &~ 0xffff00ff) >> 8);
  213. desc[ 5] = (freq &~ 0xffffff00);
  214. desc[ 6] = 0xff; // 8 bits reserved
  215. desc[ 7] = 0xf0; // 4 bits reserved, 4 bits FEC_outer (0 == not defined)
  216. desc[ 8] = modulation; // 8 bits reserved
  217. desc[ 9] = (symbol_rate >> 20) &~ 0xffffff00; // 28 bits, symbol_rate
  218. desc[10] = (symbol_rate >> 12) &~ 0xffffff00;
  219. desc[11] = (symbol_rate >> 4 ) &~ 0xffffff00;
  220. desc[12] = (symbol_rate &~ 0xfffffff0) << 4; // 4 bits
  221. desc[12] |= 0; // 4 bits FEC_inner (0 == not defined)
  222. uint8_t i;
  223. int desc_svc_size = 2 + num_services * 3; // 2 for header desc header, 3 for each service
  224. int dpos = 13;
  225. desc[dpos + 0] = 0x41; // service_list_descriptor
  226. desc[dpos + 1] = desc_svc_size - 2; // -2 Because of two byte header
  227. dpos += 2;
  228. for(i=0;i<num_services;i++) {
  229. uint32_t srv = svc_services[i];
  230. desc[dpos + 0] = (srv &~ 0xff00ffff) >> 16; // service_id (16 bits)
  231. desc[dpos + 1] = (srv &~ 0xffff00ff) >> 8;
  232. desc[dpos + 2] = (srv &~ 0xffffff00); // service_type (8 bits)
  233. dpos += 3;
  234. }
  235. int desc_prv_size = 2 + 4; // 2 for header desc header, 3 for each service
  236. desc[dpos + 0] = 0x5f; // service_list_descriptor
  237. desc[dpos + 1] = desc_prv_size - 2; // -2 Because of two byte header
  238. desc[dpos + 2] = 0x00; // -2 Because of two byte header
  239. desc[dpos + 3] = 0x00; // -2 Because of two byte header
  240. desc[dpos + 4] = 0x00; // -2 Because of two byte header
  241. desc[dpos + 5] = 0x29; // -2 Because of two byte header
  242. dpos += 6;
  243. if (!num_services || num_services > 85) // 85 * 3 == 255
  244. return 0;
  245. int desc_lcn_size = 2 + num_services * 4; // 2 for header desc header, 4 for each service
  246. desc[dpos + 0] = 0x83; // service_lcn_descriptor
  247. desc[dpos + 1] = desc_lcn_size - 2; // -2 Because of two byte header
  248. dpos += 2;
  249. for(i=0;i<(num_services);i++) {
  250. uint32_t srv = lcn_services[i];
  251. desc[dpos + 0] = (srv &~ 0x00ffffff) >> 24; // service_id (16 bits)
  252. desc[dpos + 1] = (srv &~ 0xff00ffff) >> 16; // service_id
  253. desc[dpos + 2] = (srv &~ 0xffff00ff) >> 8; // visible (1 bit), private (1 bit), first (6 bits) from lcn_number
  254. desc[dpos + 3] = (srv &~ 0xffffff00); // second (8 bits) lcn_number
  255. dpos += 4;
  256. }
  257. return ts_nit_add_stream(nit, ts_id, org_net_id, desc, desc_size);
  258. }