ts.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. /**********************************************************************************************/
  2. /* The MIT License */
  3. /* */
  4. /* Copyright 2016-2016 Twitch Interactive, Inc. or its affiliates. All Rights Reserved. */
  5. /* */
  6. /* Permission is hereby granted, free of charge, to any person obtaining a copy */
  7. /* of this software and associated documentation files (the "Software"), to deal */
  8. /* in the Software without restriction, including without limitation the rights */
  9. /* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell */
  10. /* copies of the Software, and to permit persons to whom the Software is */
  11. /* furnished to do so, subject to the following conditions: */
  12. /* */
  13. /* The above copyright notice and this permission notice shall be included in */
  14. /* all copies or substantial portions of the Software. */
  15. /* */
  16. /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR */
  17. /* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, */
  18. /* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE */
  19. /* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER */
  20. /* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, */
  21. /* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN */
  22. /* THE SOFTWARE. */
  23. /**********************************************************************************************/
  24. #include "ts.h"
  25. #include <string.h>
  26. void ts_init (ts_t* ts)
  27. {
  28. memset (ts,0,sizeof (ts_t));
  29. }
  30. static int64_t ts_parse_pts (const uint8_t* data)
  31. {
  32. // 0000 1110 1111 1111 1111 1110 1111 1111 1111 1110
  33. uint64_t pts = 0;
  34. pts |= (uint64_t) (data[0] & 0x0E) << 29;
  35. pts |= (uint64_t) (data[1] & 0xFF) << 22;
  36. pts |= (uint64_t) (data[2] & 0xFE) << 14;
  37. pts |= (uint64_t) (data[3] & 0xFF) << 7;
  38. pts |= (uint64_t) (data[4] & 0xFE) >> 1;
  39. return pts;
  40. }
  41. int ts_parse_packet (ts_t* ts, const uint8_t* data)
  42. {
  43. size_t i = 0;
  44. int pusi = !! (data[i + 1] & 0x40); // Payload Unit Start Indicator
  45. int16_t pid = ( (data[i + 1] & 0x1F) << 8) | data[i + 2]; // PID
  46. int adaption_present = !! (data[i + 3] & 0x20); // Adaptation field exist
  47. int payload_present = !! (data[i + 3] & 0x10); // Contains payload
  48. i += 4;
  49. ts->data = 0;
  50. ts->size = 0;
  51. if (adaption_present) {
  52. uint8_t adaption_length = data[i + 0]; // adaption field length
  53. i += 1 + adaption_length;
  54. }
  55. if (pid == 0) {
  56. if (payload_present) {
  57. // Skip the payload.
  58. i += data[i] + 1;
  59. }
  60. ts->pmtpid = ( (data[i + 10] & 0x1F) << 8) | data[i + 11];
  61. } else if (pid == ts->pmtpid) {
  62. // PMT
  63. if (payload_present) {
  64. // Skip the payload.
  65. i += data[i] + 1;
  66. }
  67. uint16_t section_length = ( (data[i + 1] & 0x0F) << 8) | data[i + 2];
  68. int current = data[i + 5] & 0x01;
  69. int16_t program_info_length = ( (data[i + 10] & 0x0F) << 8) | data[i + 11];
  70. int16_t descriptor_loop_length = section_length - (9 + program_info_length + 4); // 4 for the crc
  71. i += 12 + program_info_length;
  72. if (current) {
  73. while (descriptor_loop_length >= 5) {
  74. uint8_t stream_type = data[i];
  75. int16_t elementary_pid = ( (data[i + 1] & 0x1F) << 8) | data[i + 2];
  76. int16_t esinfo_length = ( (data[i + 3] & 0x0F) << 8) | data[i + 4];
  77. if (0x1B == stream_type) {
  78. ts->avcpid = elementary_pid;
  79. }
  80. i += 5 + esinfo_length;
  81. descriptor_loop_length -= 5 + esinfo_length;
  82. }
  83. }
  84. } else if (payload_present && pid == ts->avcpid) {
  85. if (pusi) {
  86. // int data_alignment = !! (data[i + 6] & 0x04);
  87. int has_pts = !! (data[i + 7] & 0x80);
  88. int has_dts = !! (data[i + 7] & 0x40);
  89. uint8_t header_length = data[i + 8];
  90. if (has_pts) {
  91. ts->pts = ts_parse_pts (&data[i + 9]);
  92. ts->dts = has_dts ? ts_parse_pts (&data[i + 14]) : ts->pts;
  93. }
  94. i += 9 + header_length;
  95. }
  96. ts->data = &data[i];
  97. ts->size = TS_PACKET_SIZE-i;
  98. return LIBCAPTION_READY;
  99. }
  100. return LIBCAPTION_OK;
  101. }