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.

mpeg-packet.c 6.5KB

10 月之前
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. #include "mpeg-pes-internal.h"
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <assert.h>
  5. #include <errno.h>
  6. #define MPEG_PACKET_PAYLOAD_MAX_SIZE (10 * 1024 * 1024)
  7. typedef int (*h2645_find_new_access)(const uint8_t* p, size_t bytes, int* vcl);
  8. static int mpeg_packet_append(struct packet_t* pkt, const void* data, size_t size)
  9. {
  10. void* ptr;
  11. // fix: pkt->size + size bits wrap
  12. if (pkt->size + size > MPEG_PACKET_PAYLOAD_MAX_SIZE || pkt->size + size < pkt->size)
  13. return -EINVAL;
  14. if (pkt->capacity < pkt->size + size)
  15. {
  16. ptr = realloc(pkt->data, pkt->size + size + 2048);
  17. if (NULL == ptr) return -ENOMEM;
  18. pkt->data = (uint8_t*)ptr;
  19. pkt->capacity = pkt->size + size + 2048;
  20. }
  21. // append new data
  22. memcpy(pkt->data + pkt->size, data, size);
  23. pkt->size += size;
  24. return 0;
  25. }
  26. static int mpeg_packet_h264_h265_filter(uint16_t program, uint16_t stream, struct packet_t* pkt, const uint8_t* data, size_t size, pes_packet_handler handler, void* param)
  27. {
  28. int i;
  29. size_t off;
  30. size_t leading;
  31. //assert(0 == pes->len || pes->payload.len == pes->len);
  32. // skip AUD
  33. for (off = i = 0; off < size; off += i + 1)
  34. {
  35. i = mpeg_h264_find_nalu(data + off, size - off, &leading);
  36. if (i < 0)
  37. {
  38. assert(0);
  39. return -1;
  40. }
  41. //assert(0 == i - leading);
  42. if (PSI_STREAM_H264 == pkt->codecid ? 9 == (data[off + i] & 0x1f) : 35 == ((data[off + i] >> 1) & 0x3f))
  43. continue;
  44. i -= (int)leading; // rewind to 0x00 00 00 01
  45. break;
  46. }
  47. // TODO: check size > 0 ???
  48. return handler(param, program, stream, pkt->codecid, pkt->flags, pkt->pts, pkt->dts, data + off + i, size - off - i);
  49. }
  50. static int mpeg_packet_h264_h265(struct packet_t* pkt, const struct pes_t* pes, size_t size, pes_packet_handler handler, void* param)
  51. {
  52. int r, n;
  53. const uint8_t* p, *end, *data;
  54. h2645_find_new_access find;
  55. n = PSI_STREAM_H264 == pes->codecid ? 4 : 5;
  56. data = pkt->data;
  57. end = pkt->data + pkt->size;
  58. p = pkt->size - size < n ? pkt->data : end - size - n; // start from trailing nalu
  59. find = PSI_STREAM_H264 == pes->codecid ? mpeg_h264_find_new_access_unit : mpeg_h265_find_new_access_unit;
  60. // TODO: The first frame maybe not a valid frame, filter it
  61. if (0 == pkt->codecid)
  62. {
  63. pkt->pts = pes->pts;
  64. pkt->dts = pes->dts;
  65. pkt->sid = pes->sid;
  66. pkt->codecid = pes->codecid;
  67. pkt->flags = pes->flags;
  68. }
  69. // PES contain multiple packet
  70. n = find(p, end - p, &pkt->vcl);
  71. while (n >= 0)
  72. {
  73. assert(pkt->vcl > 0);
  74. p += n;
  75. pkt->flags = (pkt->flags ^ MPEG_FLAG_IDR_FRAME) | (1 == pkt->vcl ? MPEG_FLAG_IDR_FRAME : 0); // update key frame flags
  76. r = mpeg_packet_h264_h265_filter(pes->pn, pes->pid, pkt, data, p - data, handler, param);
  77. if (0 != r)
  78. return r;
  79. data = p;
  80. pkt->vcl = 0; // next frame
  81. n = find(p, end - p, &pkt->vcl);
  82. }
  83. // save pts/dts
  84. pkt->pts = pes->pts;
  85. pkt->dts = pes->dts;
  86. pkt->sid = pes->sid;
  87. pkt->codecid = pes->codecid;
  88. pkt->flags = pes->flags;
  89. // assert(0 == find(p, end - p)); // start with AUD
  90. // remain data
  91. if (data != pkt->data)
  92. {
  93. memmove(pkt->data, data, end - data);
  94. pkt->size = end - data;
  95. }
  96. return 0;
  97. }
  98. static void pes_packet_codec_verify(struct pes_t* pes, const struct packet_t* pkt)
  99. {
  100. int r;
  101. size_t i, n;
  102. #if defined(MPEG_GUESS_STREAM) || defined(MPEG_H26X_VERIFY)
  103. if (pes->codecid == PSI_STREAM_RESERVED && 0 == mpeg_h26x_verify(pkt->data, pkt->size, &r))
  104. {
  105. // modify codecid
  106. static const uint8_t sc_codecid[] = { PSI_STREAM_RESERVED, PSI_STREAM_H264, PSI_STREAM_H265, PSI_STREAM_MPEG4, };
  107. pes->codecid = sc_codecid[(r < 0 || r >= sizeof(sc_codecid) / sizeof(sc_codecid[0])) ? PSI_STREAM_RESERVED : r];
  108. }
  109. #endif
  110. #if defined(MPEG_DAHUA_AAC_FROM_G711)
  111. if ((pes->codecid == PSI_STREAM_AUDIO_G711A || pes->codecid == PSI_STREAM_AUDIO_G711U)
  112. && pkt->size > 7 && 0xFF == pkt->data[0] && 0xF0 == (pkt->data[1] & 0xF0))
  113. {
  114. n = 7;
  115. // calc mpeg4_aac_adts_frame_length
  116. for (i = 0; i + 7 < pkt->size && n >= 7; i += n)
  117. {
  118. // fix n == 0
  119. n = ((size_t)(pkt->data[i + 3] & 0x03) << 11) | ((size_t)pkt->data[i + 4] << 3) | ((size_t)(pkt->data[i + 5] >> 5) & 0x07);
  120. }
  121. pes->codecid = i == pkt->size ? PSI_STREAM_AAC : pes->codecid; // fix it
  122. }
  123. #endif
  124. }
  125. int pes_packet(struct packet_t* pkt, struct pes_t* pes, const void* data, size_t size, int start, pes_packet_handler handler, void* param)
  126. {
  127. int r;
  128. // use timestamp to split packet
  129. assert(PTS_NO_VALUE != pes->dts);
  130. if (pkt->size > 0 && (pkt->dts != pes->dts || start))
  131. {
  132. pes_packet_codec_verify(pes, pkt); // verify on packet complete
  133. if (PSI_STREAM_H264 != pes->codecid && PSI_STREAM_H265 != pes->codecid)
  134. {
  135. assert(PTS_NO_VALUE != pkt->dts);
  136. r = handler(param, pes->pn, pes->pid, pkt->codecid, pkt->flags, pkt->pts, pkt->dts, pkt->data, pkt->size);
  137. pkt->size = 0; // new packet start
  138. if (0 != r)
  139. return r;
  140. }
  141. }
  142. // merge buffer
  143. r = mpeg_packet_append(pkt, data, size);
  144. if (0 != r)
  145. return r;
  146. if (PSI_STREAM_H264 == pes->codecid || PSI_STREAM_H265 == pes->codecid)
  147. {
  148. return mpeg_packet_h264_h265(pkt, pes, size, handler, param);
  149. }
  150. else
  151. {
  152. // save pts/dts
  153. pkt->pts = pes->pts;
  154. pkt->dts = pes->dts;
  155. pkt->sid = pes->sid;
  156. pkt->codecid = pes->codecid;
  157. pkt->flags = pes->flags;
  158. // for audio packet only, H.264/H.265 pes->len maybe incorrect
  159. assert(PSI_STREAM_H264 != pes->codecid && PSI_STREAM_H265 != pes->codecid);
  160. #if !defined(MPEG_LIVING_VIDEO_FRAME_DEMUX)
  161. if (PES_SID_VIDEO != pes->sid)
  162. #endif
  163. if (pes->len > 0 && pes->pkt.size >= pes->len)
  164. {
  165. pes_packet_codec_verify(pes, pkt); // verify on packet complete
  166. if (PSI_STREAM_H264 == pes->codecid || PSI_STREAM_H265 == pes->codecid)
  167. return mpeg_packet_h264_h265(pkt, pes, size, handler, param);
  168. assert(pes->pkt.size == pes->len || (pkt->flags & MPEG_FLAG_PACKET_CORRUPT)); // packet lost
  169. r = handler(param, pes->pn, pes->pid, pkt->codecid, pkt->flags, pkt->pts, pkt->dts, pes->pkt.data, pes->len);
  170. pkt->size = 0; // new packet start
  171. }
  172. }
  173. return r;
  174. }