#include "rtmp-server.h" #include "sys/thread.h" #include "sys/system.h" #include "sys/path.h" #include #include #include #define N 5000 #define M 8 struct rtmp_server_publish_benchmark_t { rtmp_server_t* rtmp; size_t i; }; struct rtmp_raw_packet_t { const uint8_t* data; uint32_t size; uint32_t timestamp; }; static uint32_t s_clock; static std::vector s_pkts; static rtmp_server_publish_benchmark_t s_servers[N]; static void load_file(const char* filename, void** p, int64_t* n) { *n = path_filesize(filename); *p = malloc(*n); FILE* fp = fopen(filename, "rb"); fread(*p, 1, *n, fp); fclose(fp); } static void init_packets(const char* filename) { // TODO: free(p) int64_t n; uint8_t* p; load_file(filename, (void**)&p, &n); for (int64_t i = 0; i < n; i += 8) { struct rtmp_raw_packet_t pkt; pkt.size = *(uint32_t*)(p + i); pkt.timestamp = *(uint32_t*)(p + i + 4); pkt.data = p + i + 8; i += pkt.size; s_pkts.push_back(pkt); } } static void rtmp_server_publish_input(rtmp_server_publish_benchmark_t* rtmp, uint32_t now) { if (rtmp->i >= s_pkts.size()) return; for(int i = 0; 1; i++) { rtmp_raw_packet_t& pkt = s_pkts[rtmp->i]; if ((int)(s_clock + pkt.timestamp - now) > 0) { if (i > 50) printf("cycle %d\n", i); return; } rtmp_server_input(rtmp->rtmp, pkt.data, pkt.size); ++rtmp->i; } } static int STDCALL rtmp_server_onthread(void* param) { int idx = (int)(intptr_t)param; while (1) { uint32_t now = system_clock(); for (int i = idx; i < N; i += M) { rtmp_server_publish_input(s_servers + i, now); } system_sleep(10); } return 0; } static int rtmp_server_send(void* param, const void* header, size_t len, const void* data, size_t bytes) { return len + bytes; } static int rtmp_server_onpublish(void* param, const char* app, const char* stream, const char* type) { return 0; } static int rtmp_server_onscript(void* param, const void* script, size_t bytes, uint32_t timestamp) { return 0; } static int rtmp_server_onvideo(void* param, const void* data, size_t bytes, uint32_t timestamp) { return 0; } static int rtmp_server_onaudio(void* param, const void* data, size_t bytes, uint32_t timestamp) { return 0; } void rtmp_server_publish_benchmark_test(const char* bin) { init_packets(bin); for (int i = 0; i < N; i++) { struct rtmp_server_handler_t handler; memset(&handler, 0, sizeof(handler)); handler.send = rtmp_server_send; handler.onpublish = rtmp_server_onpublish; handler.onscript = rtmp_server_onscript; handler.onvideo = rtmp_server_onvideo; handler.onaudio = rtmp_server_onaudio; s_servers[i].rtmp = rtmp_server_create(NULL, &handler); s_servers[i].i = 0; } s_clock = system_clock(); for (int i = 0; i < M; i++) { // TODO destroy thread pthread_t thread; thread_create(&thread, rtmp_server_onthread, (void*)i); } assert(s_pkts.size() > 0); uint32_t duration = s_pkts.rbegin()->timestamp; system_sleep(duration + 100); for (int i = 0; i < N; i++) { rtmp_server_destroy(s_servers[i].rtmp); } }