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.

rtp-vp8-pack.c 3.1KB

6 miesięcy temu
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. // RFC7741 RTP Payload Format for VP8 Video
  2. //
  3. #include "rtp-packet.h"
  4. #include "rtp-profile.h"
  5. #include "rtp-payload-internal.h"
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #include <assert.h>
  9. #include <errno.h>
  10. // Timestamp: The granularity of the clock is 90 kHz
  11. #define KHz 90 // 90000Hz
  12. #define N_VP8_HEADER 1
  13. struct rtp_encode_vp8_t
  14. {
  15. struct rtp_packet_t pkt;
  16. struct rtp_payload_t handler;
  17. void* cbparam;
  18. int size;
  19. };
  20. static void* rtp_vp8_pack_create(int size, uint8_t pt, uint16_t seq, uint32_t ssrc, struct rtp_payload_t *handler, void* cbparam)
  21. {
  22. struct rtp_encode_vp8_t *packer;
  23. packer = (struct rtp_encode_vp8_t *)calloc(1, sizeof(*packer));
  24. if (!packer) return NULL;
  25. memcpy(&packer->handler, handler, sizeof(packer->handler));
  26. packer->cbparam = cbparam;
  27. packer->size = size;
  28. packer->pkt.rtp.v = RTP_VERSION;
  29. packer->pkt.rtp.pt = pt;
  30. packer->pkt.rtp.seq = seq;
  31. packer->pkt.rtp.ssrc = ssrc;
  32. return packer;
  33. }
  34. static void rtp_vp8_pack_destroy(void* pack)
  35. {
  36. struct rtp_encode_vp8_t *packer;
  37. packer = (struct rtp_encode_vp8_t *)pack;
  38. #if defined(_DEBUG) || defined(DEBUG)
  39. memset(packer, 0xCC, sizeof(*packer));
  40. #endif
  41. free(packer);
  42. }
  43. static void rtp_vp8_pack_get_info(void* pack, uint16_t* seq, uint32_t* timestamp)
  44. {
  45. struct rtp_encode_vp8_t *packer;
  46. packer = (struct rtp_encode_vp8_t *)pack;
  47. *seq = (uint16_t)packer->pkt.rtp.seq;
  48. *timestamp = packer->pkt.rtp.timestamp;
  49. }
  50. static int rtp_vp8_pack_input(void* pack, const void* data, int bytes, uint32_t timestamp)
  51. {
  52. int r, n;
  53. uint8_t *rtp;
  54. uint8_t vp8_payload_descriptor[1];
  55. const uint8_t *ptr;
  56. struct rtp_encode_vp8_t *packer;
  57. packer = (struct rtp_encode_vp8_t *)pack;
  58. packer->pkt.rtp.timestamp = timestamp; //(uint32_t)(time * KHz);
  59. r = 0;
  60. ptr = (const uint8_t *)data;
  61. for (vp8_payload_descriptor[0] = 0x10 /*start of partition*/; 0 == r && bytes > 0; ++packer->pkt.rtp.seq)
  62. {
  63. packer->pkt.payload = ptr;
  64. packer->pkt.payloadlen = (bytes + N_VP8_HEADER + RTP_FIXED_HEADER) <= packer->size ? bytes : (packer->size - N_VP8_HEADER - RTP_FIXED_HEADER);
  65. ptr += packer->pkt.payloadlen;
  66. bytes -= packer->pkt.payloadlen;
  67. n = RTP_FIXED_HEADER + N_VP8_HEADER + packer->pkt.payloadlen;
  68. rtp = (uint8_t*)packer->handler.alloc(packer->cbparam, n);
  69. if (!rtp) return -ENOMEM;
  70. // Marker bit (M): MUST be set for the very last packet of each encoded
  71. // frame in line with the normal use of the M bit in video formats.
  72. packer->pkt.rtp.m = (0 == bytes) ? 1 : 0;
  73. n = rtp_packet_serialize_header(&packer->pkt, rtp, n);
  74. if (n != RTP_FIXED_HEADER)
  75. {
  76. assert(0);
  77. return -1;
  78. }
  79. memcpy(rtp + n, vp8_payload_descriptor, N_VP8_HEADER);
  80. memcpy(rtp + n + N_VP8_HEADER, packer->pkt.payload, packer->pkt.payloadlen);
  81. r = packer->handler.packet(packer->cbparam, rtp, n + N_VP8_HEADER + packer->pkt.payloadlen, packer->pkt.rtp.timestamp, 0);
  82. packer->handler.free(packer->cbparam, rtp);
  83. vp8_payload_descriptor[0] = 0x00;
  84. }
  85. return r;
  86. }
  87. struct rtp_payload_encode_t *rtp_vp8_encode()
  88. {
  89. static struct rtp_payload_encode_t encode = {
  90. rtp_vp8_pack_create,
  91. rtp_vp8_pack_destroy,
  92. rtp_vp8_pack_get_info,
  93. rtp_vp8_pack_input,
  94. };
  95. return &encode;
  96. }