Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

181 Zeilen
5.8KB

  1. // ETSI EN 300 468 V1.15.1 (2016-03)
  2. // Digital Video Broadcasting (DVB); Specification for Service Information (SI) in DVB systems
  3. // 5.2.3 Service Description Table (SDT) (p27)
  4. #include "mpeg-ts-internal.h"
  5. #include "mpeg-element-descriptor.h"
  6. #include "mpeg-util.h"
  7. #include <string.h>
  8. #include <assert.h>
  9. #define SERVICE_ENCODER "encoder"
  10. /*
  11. service_description_section(){
  12. table_id 8 uimsbf
  13. section_syntax_indicator 1 bslbf
  14. reserved_future_use 1 bslbf
  15. reserved 2 bslbf
  16. section_length 12 uimsbf
  17. transport_stream_id 16 uimsbf
  18. reserved 2 bslbf
  19. version_number 5 uimsbf
  20. current_next_indicator 1 bslbf
  21. section_number 8 uimsbf
  22. last_section_number 8 uimsbf
  23. original_network_id 16 uimsbf
  24. reserved_future_use 8 bslbf
  25. for (i=0;i<N;i++){
  26. service_id 16 uimsbf
  27. reserved_future_use 6 bslbf
  28. EIT_schedule_flag 1 bslbf
  29. EIT_present_following_flag 1 bslbf
  30. running_status 3 uimsbf
  31. free_CA_mode 1 bslbf
  32. descriptors_loop_length 12 uimsbf
  33. for (j=0;j<N;j++){
  34. descriptor()
  35. }
  36. }
  37. CRC_32 32 rpchof
  38. }
  39. */
  40. size_t sdt_read(struct pat_t *pat, const uint8_t* data, size_t bytes)
  41. {
  42. struct pmt_t* pmt;
  43. uint16_t sid;
  44. uint32_t i, k, n, section_length;
  45. uint8_t tagid, taglen, tagn1, tagn2;
  46. if (bytes < 11)
  47. return 0;
  48. // printf("SDT: %0x %0x %0x %0x %0x %0x %0x %0x, %0x, %0x, %0x\n", (unsigned int)data[0], (unsigned int)data[1], (unsigned int)data[2], (unsigned int)data[3], (unsigned int)data[4], (unsigned int)data[5], (unsigned int)data[6],(unsigned int)data[7],(unsigned int)data[8],(unsigned int)data[9],(unsigned int)data[10]);
  49. // uint32_t table_id = data[0];
  50. // uint32_t section_syntax_indicator = (data[1] >> 7) & 0x01;
  51. // uint32_t zero = (data[1] >> 6) & 0x01;
  52. // uint32_t reserved = (data[1] >> 4) & 0x03;
  53. section_length = ((data[1] & 0x0F) << 8) | data[2];
  54. // uint32_t transport_stream_id = (data[3] << 8) | data[4];
  55. // uint32_t reserved2 = (data[5] >> 6) & 0x03;
  56. // uint32_t version_number = (data[5] >> 1) & 0x1F;
  57. // uint32_t current_next_indicator = data[5] & 0x01;
  58. // uint32_t sector_number = data[6];
  59. // uint32_t last_sector_number = data[7];
  60. // uint32_t original_network_id = (data[8] << 8) | data[9];
  61. // uint32_t reserved4 = data[10];
  62. if(PAT_TID_SDT != data[0] || section_length + 3 > bytes)
  63. return 0;
  64. // TODO: version_number change, reload SDT
  65. assert(bytes >= section_length + 3); // PMT = section_length + 3
  66. for (i = 11; i + 5 <= section_length + 3 - 4/*CRC32*/ && section_length + 3 <= bytes; i += 5 + n) // 9: follow section_length item
  67. {
  68. sid = (data[i] << 8) | data[i + 1];
  69. n = ((data[i+3] & 0x0F) << 8) | data[i+4];
  70. // skip reserved/EIT data[i+2]
  71. if(i + 5 + n > section_length + 3 - 4)
  72. continue;
  73. pmt = pat_find(pat, sid);
  74. if(NULL == pmt)
  75. continue; // pmt not found
  76. for(k = i + 5; k + 2 <= i + 5 + n; k += 2 + taglen)
  77. {
  78. // 6.1 Descriptor identification and location
  79. tagid = data[k];
  80. taglen = data[k + 1];
  81. // 6.2.33 Service descriptor (p77)
  82. if(0x48 != tagid || k + taglen > i + 5 + n)
  83. continue;
  84. //service_type = data[k + 2];
  85. tagn1 = data[k + 3];
  86. if(tagn1 >= sizeof(pmt->provider) || k + 3 + tagn1 > i + 5 + n)
  87. continue;
  88. memcpy(pmt->provider, &data[k+4], tagn1);
  89. pmt->provider[tagn1] = 0;
  90. tagn2 = data[k + 4 + tagn1];
  91. if(tagn2 >= sizeof(pmt->name) || k + 5 + tagn1 + tagn2 > i + 5 + n)
  92. continue;
  93. memcpy(pmt->name, &data[k+5+tagn1], tagn2);
  94. pmt->name[tagn2] = 0;
  95. }
  96. }
  97. //assert(j+4 == bytes);
  98. //crc = (data[j] << 24) | (data[j+1] << 16) | (data[j+2] << 8) | data[j+3];
  99. // assert(0 == mpeg_crc32(0xffffffff, data, section_length+3));
  100. return section_length + 3;
  101. }
  102. size_t sdt_write(const struct pat_t* pat, uint8_t* data)
  103. {
  104. size_t i, j;
  105. size_t len, s1, n1, v1;
  106. uint32_t crc = 0;
  107. n1 = strlen(SERVICE_ENCODER);
  108. v1 = strlen(SERVICE_NAME);
  109. s1 = 3 /*tag*/ + 1 + n1 + 1 + v1;
  110. len = 3 /*nid*/ + s1 + 5 /*service head*/ + 5 + 4; // 5 bytes remain header and 4 bytes crc32
  111. // shall not exceed 1021 (0x3FD).
  112. assert(len <= 1021);
  113. assert(len <= TS_PACKET_SIZE - 7);
  114. data[0] = PAT_TID_SDT; // service_description_section
  115. // section_syntax_indicator = '1'
  116. // '0'
  117. // reserved '11'
  118. nbo_w16(data + 1, (uint16_t)(0xf000 | len));
  119. // transport_stream_id
  120. nbo_w16(data + 3, (uint16_t)pat->tsid);
  121. // reserved '11'
  122. // version_number 'xxxxx'
  123. // current_next_indicator '1'
  124. data[5] = (uint8_t)(0xC1 | (pat->ver << 1));
  125. // section_number/last_section_number
  126. data[6] = 0x00;
  127. data[7] = 0x00;
  128. // original_network_id
  129. nbo_w16(data + 8, (uint16_t)pat->tsid);
  130. data[10] = 0xFF; // reserved
  131. j = 11;
  132. // only one
  133. for (i = 0; i < 1; i++)
  134. {
  135. nbo_w16(data + j, (uint16_t)pat->tsid);
  136. data[j + 2] = 0xfc | 0x00; // no EIT
  137. assert(n1 < 255 && v1 < 255 && len < 255);
  138. nbo_w16(data + j + 3, (uint16_t)(0x8000 | s1));
  139. data[j + 5] = 0x48; // tag id
  140. data[j + 6] = (uint8_t)(3 + n1 + v1); // tag len
  141. data[j + 7] = 1; // service type
  142. data[j + 8] = (uint8_t)n1;
  143. memcpy(data + j + 9, SERVICE_NAME, n1);
  144. data[j + 9 + n1] = (uint8_t)v1;
  145. memcpy(data + j + 10 + n1, SERVICE_NAME, v1);
  146. j += 10 + v1 + n1;
  147. }
  148. // crc32
  149. crc = mpeg_crc32(0xffffffff, data, (uint32_t)j);
  150. data[j + 3] = (uint8_t)((crc >> 24) & 0xFF);
  151. data[j + 2] = (uint8_t)((crc >> 16) & 0xFF);
  152. data[j + 1] = (uint8_t)((crc >> 8) & 0xFF);
  153. data[j + 0] = (uint8_t)(crc & 0xFF);
  154. return j + 4;
  155. }