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.

147 lines
3.5KB

  1. #include "aom-av1.h"
  2. #include "rtp-payload.h"
  3. #include "rtp-profile.h"
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include <assert.h>
  8. enum
  9. {
  10. OBU_SEQUENCE_HEADER = 1,
  11. OBU_TEMPORAL_DELIMITER = 2,
  12. OBU_FRAME = 6,
  13. };
  14. struct av1_rtp_test_t
  15. {
  16. struct aom_av1_t av1;
  17. void* encoder;
  18. void* decoder;
  19. uint32_t pts, dts;
  20. uint8_t* ptr;
  21. int bytes;
  22. int vcl;
  23. int keyframe;
  24. FILE* wfp;
  25. };
  26. static uint8_t* file_read(const char* file, long* size)
  27. {
  28. FILE* fp = fopen(file, "rb");
  29. if (fp)
  30. {
  31. fseek(fp, 0, SEEK_END);
  32. *size = ftell(fp);
  33. fseek(fp, 0, SEEK_SET);
  34. uint8_t* ptr = (uint8_t*)malloc(*size);
  35. fread(ptr, 1, *size, fp);
  36. fclose(fp);
  37. return ptr;
  38. }
  39. return NULL;
  40. }
  41. static void* rtp_alloc(void* /*param*/, int bytes)
  42. {
  43. static uint8_t buffer[2 * 1024 * 1024 + 4] = { 0, 0, 0, 1, };
  44. assert(bytes <= sizeof(buffer) - 4);
  45. return buffer + 4;
  46. }
  47. static void rtp_free(void* /*param*/, void* /*packet*/)
  48. {
  49. }
  50. static int rtp_encode_packet(void* param, const void* packet, int bytes, uint32_t timestamp, int /*flags*/)
  51. {
  52. struct av1_rtp_test_t* ctx = (struct av1_rtp_test_t*)param;
  53. //int x = rand();
  54. //if( (x % 100) < RTP_LOST_PERCENT )
  55. //{
  56. // printf("======== discard [%s] timestamp: %u ==============\n", ctx->av ? "V" : "A", (unsigned int)timestamp);
  57. // return 0;
  58. //}
  59. int r = rtp_payload_decode_input(ctx->decoder, packet, bytes);
  60. return r >= 0 ? 0 : r;
  61. }
  62. static int rtp_decode_packet(void* param, const void* packet, int bytes, uint32_t timestamp, int flags)
  63. {
  64. struct av1_rtp_test_t* ctx = (struct av1_rtp_test_t*)param;
  65. printf("RTP Decode: timestamp: %u, bytes: %d\n", (unsigned int)timestamp, bytes);
  66. static const uint8_t av1_temporal_delimiter[] = { 0x12, 0x00 };
  67. assert(sizeof(av1_temporal_delimiter) == fwrite(av1_temporal_delimiter, 1, sizeof(av1_temporal_delimiter), ctx->wfp));
  68. assert(bytes == fwrite(packet, 1, bytes, ctx->wfp));
  69. return 0;
  70. }
  71. static int av1_handler(void* param, const uint8_t* obu, size_t bytes)
  72. {
  73. struct av1_rtp_test_t* ctx = (struct av1_rtp_test_t*)param;
  74. uint8_t obu_type = (obu[0] >> 3) & 0x0F;
  75. if (ctx->vcl > 0 && OBU_TEMPORAL_DELIMITER == obu_type)
  76. {
  77. printf("av1 frame: %u, bytes: %d\n", (unsigned int)ctx->dts, ctx->bytes);
  78. assert(0 == rtp_payload_encode_input(ctx->encoder, ctx->ptr, ctx->bytes, (unsigned int)ctx->dts));
  79. ctx->dts += 40; // fps 25
  80. ctx->bytes = 0;
  81. ctx->vcl = 0;
  82. ctx->keyframe = 0;
  83. }
  84. if (OBU_TEMPORAL_DELIMITER == obu_type)
  85. return 0; // ignore
  86. if (OBU_SEQUENCE_HEADER == obu_type)
  87. ctx->keyframe = 1;
  88. if (OBU_FRAME == obu_type)
  89. ++ctx->vcl;
  90. memcpy(ctx->ptr + ctx->bytes, obu, bytes);
  91. ctx->bytes += bytes;
  92. return 0;
  93. }
  94. void av1_rtp_test(const char* low_overhead_bitstream_format_obu)
  95. {
  96. struct av1_rtp_test_t ctx;
  97. memset(&ctx, 0, sizeof(ctx));
  98. static uint8_t s_buffer[2 * 1024 * 1024];
  99. snprintf((char*)s_buffer, sizeof(s_buffer), "%s.obu", low_overhead_bitstream_format_obu);
  100. ctx.wfp = fopen((const char*)s_buffer, "wb");
  101. ctx.ptr = s_buffer;
  102. struct rtp_payload_t handler1;
  103. handler1.alloc = rtp_alloc;
  104. handler1.free = rtp_free;
  105. handler1.packet = rtp_decode_packet;
  106. ctx.decoder = rtp_payload_decode_create(97, "AV1", &handler1, &ctx);
  107. struct rtp_payload_t handler2;
  108. handler2.alloc = rtp_alloc;
  109. handler2.free = rtp_free;
  110. handler2.packet = rtp_encode_packet;
  111. ctx.encoder = rtp_payload_encode_create(97, "AV1", 0, 0, &handler2, &ctx);
  112. long bytes = 0;
  113. uint8_t* ptr = file_read(low_overhead_bitstream_format_obu, &bytes);
  114. if (NULL == ptr) return;
  115. aom_av1_obu_split(ptr, bytes, av1_handler, &ctx);
  116. free(ptr);
  117. fclose(ctx.wfp);
  118. }