uvgrtp-base/benchmarks/ffmpeg/receiver.cc

141 lines
3.8 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

extern "C" {
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavformat/avio.h>
#include <libswscale/swscale.h>
}
#include <atomic>
#include <cstdio>
#include <chrono>
#include <thread>
struct thread_info {
size_t pkts;
size_t bytes;
std::chrono::high_resolution_clock::time_point start;
} *thread_info;
std::atomic<int> nready(0);
void thread_func(int thread_num)
{
AVFormatContext *format_ctx = avformat_alloc_context();
AVCodecContext *codec_ctx = NULL;
int video_stream_index = 0;
/* register everything */
av_register_all();
avformat_network_init();
/* open rtsp */
AVDictionary *d = NULL;
av_dict_set(&d, "protocol_whitelist", "file,udp,rtp", 0);
char buf[256];
/* input buffer size */
snprintf(buf, sizeof(buf), "%d", 40 * 1024 * 1024);
av_dict_set(&d, "buffer_size", buf, 32);
/* avioflags flags (input/output)
*
* Possible values:
* direct
* Reduce buffering. */
snprintf(buf, sizeof(buf), "direct");
av_dict_set(&d, "avioflags", buf, 32);
/* Reduce the latency introduced by buffering during initial input streams analysis. */
av_dict_set(&d, "nobuffer", NULL, 32);
/* Set probing size in bytes, i.e. the size of the data to analyze to get stream information.
*
* A higher value will enable detecting more information in case it is dispersed into the stream,
* but will increase latency. Must be an integer not lesser than 32. It is 5000000 by default. */
snprintf(buf, sizeof(buf), "%d", 256);
av_dict_set(&d, "probesize", buf, 32);
/* Set number of frames used to probe fps. */
snprintf(buf, sizeof(buf), "%d", 2);
av_dict_set(&d, "fpsprobesize", buf, 32);
snprintf(buf, sizeof(buf), "ffmpeg/sdp/hevc_%d.sdp", thread_num / 2);
if (avformat_open_input(&format_ctx, buf, NULL, &d)) {
fprintf(stderr, "failed to open input file\n");
nready++;
return;
}
if (avformat_find_stream_info(format_ctx, NULL) < 0) {
fprintf(stderr, "failed to find stream info!\n");
nready++;
return;
}
for (size_t i = 0; i < format_ctx->nb_streams; i++) {
if (format_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO)
video_stream_index = i;
}
size_t pkts = 0;
size_t size = 0;
AVPacket packet;
av_init_packet(&packet);
auto start = std::chrono::high_resolution_clock::now();
/* start reading packets from stream */
av_read_play(format_ctx);
while (av_read_frame(format_ctx, &packet) >= 0) {
if (packet.stream_index == video_stream_index) {
size += packet.size;
} else {
fprintf(stderr, "unknown format!\n");
}
pkts++;
av_free_packet(&packet);
av_init_packet(&packet);
if (++pkts == 597)
break;
}
if (pkts == 597) {
fprintf(stderr, "%zu %zu\n", size,
std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::high_resolution_clock::now() - start
).count()
);
} else {
fprintf(stderr, "discard %zu %zu\n", size,
std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::high_resolution_clock::now() - start
).count()
);
}
av_read_pause(format_ctx);
nready++;
}
int main(int argc, char **argv)
{
if (argc != 2) {
fprintf(stderr, "usage: ./%s <number of threads>\n", __FILE__);
return -1;
}
int nthreads = atoi(argv[1]);
thread_info = (struct thread_info *)calloc(nthreads, sizeof(*thread_info));
for (int i = 0; i < nthreads; ++i)
new std::thread(thread_func, i * 2);
while (nready.load() != nthreads)
std::this_thread::sleep_for(std::chrono::milliseconds(20));
}