Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

138 lignes
4.9KB

  1. #include "mpeg-ps-internal.h"
  2. #include <assert.h>
  3. // 2.5.3.3 Pack layer of program stream (p78)
  4. // Table 2-38 - Program stream pack
  5. // Table 2-39 - Program stream pack header
  6. #if 1
  7. int pack_header_read(struct ps_pack_header_t* h, struct mpeg_bits_t* reader)
  8. {
  9. uint8_t v8;
  10. uint64_t v64;
  11. uint8_t stuffing_length;
  12. size_t header_length;
  13. v8 = mpeg_bits_read8(reader); // data[4]
  14. if (0 == (0xC0 & v8))
  15. {
  16. // MPEG-1
  17. // ISO/IEC 11172-1
  18. /*
  19. pack() {
  20. pack_start_code 32 bslbf
  21. '0010' 4 bslbf
  22. system_clock_reference [32..30] 3 bslbf
  23. marker_bit 1 bslbf
  24. system_clock_reference [29..15] 15 bslbf
  25. marker_bit 1 bslbf
  26. system_clock_reference [14..0] 15 bslbf
  27. marker_bit 1 bslbf
  28. marker_bit 1 bslbf
  29. mux_rate 22 uimsbf
  30. marker_bit 1 bslbf
  31. if (nextbits() == system_header_start_code)
  32. system_header ()
  33. while (nextbits() == packet_start_code)
  34. packet()
  35. }
  36. */
  37. h->mpeg2 = 0;
  38. //assert(0x20 == (0xF0 & v8));
  39. h->system_clock_reference_base = (((uint64_t)(v8 >> 1) & 0x07) << 30) | mpeg_bits_read30(reader);
  40. h->system_clock_reference_extension = 1;
  41. h->program_mux_rate = (mpeg_bits_read8(reader) & 0x7F) << 15;
  42. h->program_mux_rate |= mpeg_bits_read15(reader);
  43. return mpeg_bits_error(reader) ? MPEG_ERROR_NEED_MORE_DATA : MPEG_ERROR_OK;
  44. }
  45. else
  46. {
  47. h->mpeg2 = 1;
  48. v64 = mpeg_bits_read64(reader); // data[5-12]
  49. //assert((0x44 & data[4]) == 0x44); // '01xxx1xx'
  50. //assert((0x04 & data[6]) == 0x04); // 'xxxxx1xx'
  51. //assert((0x04 & data[8]) == 0x04); // 'xxxxx1xx'
  52. //assert((0x01 & data[9]) == 0x01); // 'xxxxxxx1'
  53. h->system_clock_reference_base = (((v8 >> 3) & 0x07) << 30) | ((v8 & 0x03) << 28) | (((v64 >> 51) & 0x1FFF) << 15) | ((v64 >> 35) & 0x7FFF);
  54. h->system_clock_reference_extension = (uint32_t)((v64 >> 25) & 0x1F);
  55. //assert((0x03 & v64) == 0x03); // 'xxxxxx11'
  56. h->program_mux_rate = (uint32_t)((v64 >> 2) & 0x3FFFFF);
  57. //assert((0xF8 & data[13]) == 0x00); // '00000xxx'
  58. stuffing_length = mpeg_bits_read8(reader) & 0x07; // stuffing
  59. header_length = 14 + stuffing_length;
  60. mpeg_bits_skip(reader, stuffing_length);
  61. return mpeg_bits_error(reader) ? MPEG_ERROR_NEED_MORE_DATA : MPEG_ERROR_OK;
  62. }
  63. }
  64. #else
  65. size_t pack_header_read(struct ps_pack_header_t *h, const uint8_t* data, size_t bytes)
  66. {
  67. uint8_t stuffing_length;
  68. size_t header_length;
  69. if (bytes < 14) return 0;
  70. assert(0x00 == data[0] && 0x00 == data[1] && 0x01 == data[2] && PES_SID_START == data[3]);
  71. if (0 == (0xC0 & data[4]))
  72. {
  73. // MPEG-1
  74. h->mpeg2 = 0;
  75. assert(0x20 == (0xF0 & data[4]));
  76. h->system_clock_reference_base = (((uint64_t)(data[4] >> 1) & 0x07) << 30) | ((uint64_t)data[5] << 22) | (((uint64_t)data[6] >> 1) << 15) | ((uint64_t)data[7] << 7) | (data[8] >> 1);
  77. h->system_clock_reference_extension = 1;
  78. h->program_mux_rate = ((data[9] >> 1) << 15) | (data[10] << 7) | (data[11] >> 1);
  79. return 12;
  80. }
  81. else
  82. {
  83. h->mpeg2 = 1;
  84. assert((0x44 & data[4]) == 0x44); // '01xxx1xx'
  85. assert((0x04 & data[6]) == 0x04); // 'xxxxx1xx'
  86. assert((0x04 & data[8]) == 0x04); // 'xxxxx1xx'
  87. assert((0x01 & data[9]) == 0x01); // 'xxxxxxx1'
  88. h->system_clock_reference_base = (((uint64_t)(data[4] >> 3) & 0x07) << 30) | (((uint64_t)data[4] & 0x3) << 28) | ((uint64_t)data[5] << 20) | ((((uint64_t)data[6] >> 3) & 0x1F) << 15) | (((uint64_t)data[6] & 0x3) << 13) | ((uint64_t)data[7] << 5) | ((data[8] >> 3) & 0x1F);
  89. h->system_clock_reference_extension = ((data[8] & 0x3) << 7) | ((data[9] >> 1) & 0x7F);
  90. assert((0x03 & data[12]) == 0x03); // 'xxxxxx11'
  91. h->program_mux_rate = (data[10] << 14) | (data[11] << 6) | ((data[12] >> 2) & 0x3F);
  92. //assert((0xF8 & data[13]) == 0x00); // '00000xxx'
  93. stuffing_length = data[13] & 0x07; // stuffing
  94. header_length = 14 + stuffing_length;
  95. if (header_length > bytes)
  96. return 0;
  97. return header_length;
  98. }
  99. }
  100. #endif
  101. size_t pack_header_write(const struct ps_pack_header_t *h, uint8_t *data)
  102. {
  103. // pack_start_code
  104. nbo_w32(data, 0x000001BA);
  105. // 33-system_clock_reference_base + 9-system_clock_reference_extension
  106. // '01xxx1xx xxxxxxxx xxxxx1xx xxxxxxxx xxxxx1xx xxxxxxx1'
  107. data[4] = 0x44 | (((h->system_clock_reference_base >> 30) & 0x07) << 3) | ((h->system_clock_reference_base >> 28) & 0x03);
  108. data[5] = ((h->system_clock_reference_base >> 20) & 0xFF);
  109. data[6] = 0x04 | (((h->system_clock_reference_base >> 15) & 0x1F) << 3) | ((h->system_clock_reference_base >> 13) & 0x03);
  110. data[7] = ((h->system_clock_reference_base >> 5) & 0xFF);
  111. data[8] = 0x04 | ((h->system_clock_reference_base & 0x1F) << 3) | ((h->system_clock_reference_extension >> 7) & 0x03);
  112. data[9] = 0x01 | ((h->system_clock_reference_extension & 0x7F) << 1);
  113. // program_mux_rate
  114. // 'xxxxxxxx xxxxxxxx xxxxxx11'
  115. data[10] = (uint8_t)(h->program_mux_rate >> 14);
  116. data[11] = (uint8_t)(h->program_mux_rate >> 6);
  117. data[12] = (uint8_t)(0x03 | ((h->program_mux_rate & 0x3F) << 2));
  118. // stuffing length
  119. // '00000xxx'
  120. data[13] = 0xF8;
  121. return 14;
  122. }