Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.

92 wiersze
2.4KB

  1. // RFC7798 RTP Payload Format for High Efficiency Video Coding (HEVC)
  2. #include "mpeg4-hevc.h"
  3. #include "sdp-payload.h"
  4. #include "base64.h"
  5. #include <stdio.h>
  6. #include <stdint.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include <assert.h>
  10. #include <errno.h>
  11. int sdp_h265(uint8_t *data, int bytes, const char* proto, unsigned short port, int payload, int frequence, const void* extra, int extra_size)
  12. {
  13. static const char* pattern =
  14. "m=video %hu %s %d\n"
  15. "a=rtpmap:%d H265/90000\n"
  16. "a=fmtp:%d";
  17. const uint8_t nalu[] = { 32/*vps*/, 33/*sps*/, 34/*pps*/ };
  18. const char* sprop[] = { "sprop-vps", "sprop-sps", "sprop-pps" };
  19. int r, n;
  20. int i, j, k;
  21. struct mpeg4_hevc_t hevc;
  22. assert(90000 == frequence);
  23. r = mpeg4_hevc_decoder_configuration_record_load((const uint8_t*)extra, extra_size, &hevc);
  24. if (r < 0)
  25. return r;
  26. n = snprintf((char*)data, bytes, pattern, port, proto && *proto ? proto : "RTP/AVP", payload, payload, payload);
  27. for (i = 0; i < sizeof(nalu) / sizeof(nalu[0]); i++)
  28. {
  29. if (i > 0 && n < bytes) data[n++] = ';';
  30. n += snprintf((char*)data + n, bytes - n, " %s=", sprop[i]);
  31. for (k = j = 0; j < hevc.numOfArrays; j++)
  32. {
  33. assert(hevc.nalu[j].type == ((hevc.nalu[j].data[0] >> 1) & 0x3F));
  34. if (nalu[i] != hevc.nalu[j].type)
  35. continue;
  36. if (n + 1 + hevc.nalu[j].bytes * 2 > bytes)
  37. return -ENOMEM; // don't have enough memory
  38. if (k++ > 0 && n < bytes) data[n++] = ',';
  39. n += (int)base64_encode((char*)data + n, hevc.nalu[j].data, hevc.nalu[j].bytes);
  40. }
  41. }
  42. if(n < bytes)
  43. data[n++] = '\n';
  44. return n;
  45. }
  46. int sdp_h265_load(uint8_t* data, int bytes, const char* vps, const char* sps, const char* pps, const char* sei)
  47. {
  48. int i, n, len, off;
  49. const char* p, * next;
  50. const char* sprops[4];
  51. const uint8_t startcode[] = { 0x00, 0x00, 0x00, 0x01 };
  52. off = 0;
  53. sprops[0] = vps;
  54. sprops[1] = sps;
  55. sprops[2] = pps;
  56. sprops[3] = sei;
  57. for (i = 0; i < sizeof(sprops) / sizeof(sprops[0]); i++)
  58. {
  59. p = sprops[i];
  60. while (p)
  61. {
  62. next = strchr(p, ',');
  63. len = next ? (int)(next - p) : (int)strlen(p);
  64. if (off + (len + 3) / 4 * 3 + (int)sizeof(startcode) > bytes)
  65. return -ENOMEM; // don't have enough space
  66. memcpy(data + off, startcode, sizeof(startcode));
  67. n = (int)base64_decode(data + off + sizeof(startcode), p, len);
  68. assert(n <= (len + 3) / 4 * 3);
  69. off += n + sizeof(startcode);
  70. off += n;
  71. p = next ? next + 1 : NULL;
  72. }
  73. }
  74. return 0;
  75. }