Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

186 rindas
5.0KB

  1. // ITU-T H.222.0(10/2014)
  2. // Information technology - Generic coding of moving pictures and associated audio information: Systems
  3. // 2.4.4.3 Program association table(p65)
  4. #include "mpeg-ts-internal.h"
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include <assert.h>
  8. struct pmt_t* pat_alloc_pmt(struct pat_t* pat)
  9. {
  10. void* ptr;
  11. unsigned int n;
  12. if (NULL == pat->pmts)
  13. {
  14. assert(0 == pat->pmt_count);
  15. assert(0 == pat->pmt_capacity);
  16. pat->pmts = pat->pmt_default;
  17. pat->pmt_capacity = sizeof(pat->pmt_default) / sizeof(pat->pmt_default[0]);
  18. }
  19. if (pat->pmt_count >= pat->pmt_capacity)
  20. {
  21. if (pat->pmt_count + 1 > 65535)
  22. {
  23. assert(0);
  24. return NULL;
  25. }
  26. n = pat->pmt_capacity + pat->pmt_capacity / 4 + 4;
  27. ptr = realloc(pat->pmts == pat->pmt_default ? NULL : pat->pmts, sizeof(pat->pmts[0]) * n);
  28. if (!ptr)
  29. return NULL;
  30. if (pat->pmts == pat->pmt_default)
  31. memmove(ptr, pat->pmt_default, sizeof(pat->pmt_default));
  32. pat->pmts = (struct pmt_t*)ptr;
  33. pat->pmt_capacity = n;
  34. }
  35. // new pmt
  36. memset(&pat->pmts[pat->pmt_count], 0, sizeof(pat->pmts[0]));
  37. return &pat->pmts[pat->pmt_count];
  38. }
  39. static struct pmt_t* pat_fetch(struct pat_t* pat, uint16_t pid)
  40. {
  41. unsigned int i;
  42. struct pmt_t* pmt;
  43. for(i = 0; i < pat->pmt_count; i++)
  44. {
  45. if(pat->pmts[i].pid == pid)
  46. return &pat->pmts[i];
  47. }
  48. // new pmt
  49. pmt = pat_alloc_pmt(pat);
  50. pat->pmt_count++;
  51. return pmt;
  52. }
  53. size_t pat_read(struct pat_t *pat, const uint8_t* data, size_t bytes)
  54. {
  55. // Table 2-30 Program association section(p65)
  56. struct pmt_t* pmt;
  57. uint32_t i = 0;
  58. uint16_t pn, pid;
  59. // uint32_t crc = 0;
  60. uint32_t section_length, transport_stream_id, version_number;
  61. if(bytes < 8)
  62. return 0; // invalid data length
  63. // printf("PAT: %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]);
  64. assert(PAT_TID_PAS == data[0]); // table_id
  65. assert(1 == ((data[1] >> 7) & 0x01)); // section_syntax_indicator
  66. // uint32_t zero = (data[1] >> 6) & 0x01;
  67. // uint32_t reserved = (data[1] >> 4) & 0x03;
  68. section_length = ((data[1] & 0x0F) << 8) | data[2];
  69. transport_stream_id = (data[3] << 8) | data[4];
  70. // uint32_t reserved2 = (data[5] >> 6) & 0x03;
  71. version_number = (data[5] >> 1) & 0x1F;
  72. // uint32_t current_next_indicator = data[5] & 0x01;
  73. // uint32_t sector_number = data[6];
  74. // uint32_t last_sector_number = data[7];
  75. if (PAT_TID_PAS != data[0] || section_length + 3 < 8 + 4 /*crc32*/ || section_length + 3 > bytes)
  76. {
  77. assert(0);
  78. return 0; // invalid data length
  79. }
  80. assert(bytes >= section_length + 3); // PMT = section_length + 3
  81. if(pat->ver != version_number)
  82. pat->pmt_count = 0; // clear all pmts
  83. pat->tsid = transport_stream_id;
  84. pat->ver = version_number;
  85. // TODO: version_number change, reload pmts
  86. // 4:CRC, 5:follow section_length item
  87. for(i = 8; i + 4 <= section_length + 8 - 5 - 4/*CRC32*/ && section_length + 3 <= bytes; i += 4)
  88. {
  89. pn = (data[i] << 8) | data[i+1];
  90. pid = ((data[i+2] & 0x1F) << 8) | data[i+3];
  91. // printf("PAT: pn: %0x, pid: %0x\n", (unsigned int)pn, (unsigned int)pid);
  92. if(0 == pn)
  93. continue; // ignore NIT info
  94. pmt = pat_fetch(pat, pid);
  95. if(NULL == pmt)
  96. continue;
  97. pmt->pn = pn;
  98. pmt->pid = pid;
  99. }
  100. //assert(i+4 == bytes);
  101. //crc = (data[i] << 24) | (data[i+1] << 16) | (data[i+2] << 8) | data[i+3];
  102. //crc = mpeg_crc32(-1, data, bytes-4);
  103. // assert(0 == mpeg_crc32(0xffffffff, data, section_length+3));
  104. return section_length + 3;
  105. }
  106. size_t pat_write(const struct pat_t *pat, uint8_t *data)
  107. {
  108. // Table 2-30 Program association section(p65)
  109. uint32_t i = 0;
  110. uint32_t len = 0;
  111. uint32_t crc = 0;
  112. len = pat->pmt_count * 4 + 5 + 4; // 5 bytes remain header and 4 bytes crc32
  113. // shall not exceed 1021 (0x3FD).
  114. assert(len <= 1021);
  115. assert(len <= TS_PACKET_SIZE - 7);
  116. data[0] = PAT_TID_PAS; // program association table
  117. // section_syntax_indicator = '1'
  118. // '0'
  119. // reserved '11'
  120. nbo_w16(data + 1, (uint16_t)(0xb000 | len));
  121. // transport_stream_id
  122. nbo_w16(data + 3, (uint16_t)pat->tsid);
  123. // reserved '11'
  124. // version_number 'xxxxx'
  125. // current_next_indicator '1'
  126. data[5] = (uint8_t)(0xC1 | (pat->ver << 1));
  127. // section_number/last_section_number
  128. data[6] = 0x00;
  129. data[7] = 0x00;
  130. for(i = 0; i < pat->pmt_count; i++)
  131. {
  132. nbo_w16(data + 8 + i * 4 + 0, (uint16_t)pat->pmts[i].pn);
  133. nbo_w16(data + 8 + i * 4 + 2, (uint16_t)(0xE000 | pat->pmts[i].pid));
  134. }
  135. // crc32
  136. crc = mpeg_crc32(0xffffffff, data, len-1);
  137. //put32(data + section_length - 1, crc);
  138. data[len - 1 + 3] = (crc >> 24) & 0xFF;
  139. data[len - 1 + 2] = (crc >> 16) & 0xFF;
  140. data[len - 1 + 1] = (crc >> 8) & 0xFF;
  141. data[len - 1 + 0] = crc & 0xFF;
  142. return len + 3; // total length
  143. }
  144. struct pmt_t* pat_find(struct pat_t* pat, uint16_t pn)
  145. {
  146. unsigned int i;
  147. for(i = 0; i < pat->pmt_count; i++)
  148. {
  149. if(pat->pmts[i].pn == pn)
  150. return &pat->pmts[i];
  151. }
  152. return NULL;
  153. }