Add multithreaded FFmpeg benchmark receive code
This commit is contained in:
parent
e8d44bf7d6
commit
4050ef0bcb
|
|
@ -16,8 +16,12 @@ ffmpeg_sender:
|
|||
$(CXX) $(CXXFLAGS) -o ffmpeg/sender ffmpeg/sender.cc util/util.cc -lkvazaar `pkg-config --libs libavformat` \
|
||||
-Wno-unused -Wno-deprecated-declarations -Wno-unused-result
|
||||
|
||||
ffmpeg_receiver:
|
||||
$(CXX) $(CXXFLAGS) -o ffmpeg/receiver ffmpeg/receiver.cc util/util.cc -lkvazaar `pkg-config --libs libavformat` \
|
||||
-Wno-unused -Wno-deprecated-declarations -Wno-unused-result
|
||||
|
||||
clean:
|
||||
rm -f kvzrtp/receiver kvzrtp/sender ffmpeg/sender
|
||||
rm -f kvzrtp/receiver kvzrtp/sender ffmpeg/sender ffmpeg/receiver
|
||||
|
||||
# jrtp:
|
||||
# $(CXX) $(CXXFLAGS) -o main_jrtp jrtp.cc ../util/util.cc -lkvazaar -ljrtp -lpthread
|
||||
|
|
|
|||
|
|
@ -1,6 +1,3 @@
|
|||
#include <stdio.h>
|
||||
#include <chrono>
|
||||
|
||||
extern "C" {
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <libavformat/avformat.h>
|
||||
|
|
@ -8,11 +5,24 @@ extern "C" {
|
|||
#include <libswscale/swscale.h>
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
#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;
|
||||
AVFormatContext *format_ctx = avformat_alloc_context();
|
||||
AVCodecContext *codec_ctx = NULL;
|
||||
int video_stream_index = 0;
|
||||
|
||||
/* register everything */
|
||||
av_register_all();
|
||||
|
|
@ -23,38 +33,108 @@ int main(int argc, char **argv)
|
|||
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, 0);
|
||||
av_dict_set(&d, "buffer_size", buf, 32);
|
||||
|
||||
if (avformat_open_input(&format_ctx, "../../examples/full/sdp/hevc.sdp", NULL, &d))
|
||||
return EXIT_FAILURE;
|
||||
/* avioflags flags (input/output)
|
||||
*
|
||||
* Possible values:
|
||||
* ‘direct’
|
||||
* Reduce buffering. */
|
||||
snprintf(buf, sizeof(buf), "direct");
|
||||
av_dict_set(&d, "avioflags", buf, 32);
|
||||
|
||||
if (avformat_find_stream_info(format_ctx, NULL) < 0)
|
||||
return EXIT_FAILURE;
|
||||
/* 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;
|
||||
}
|
||||
|
||||
//search video stream
|
||||
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 cnt = 0;
|
||||
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);
|
||||
return 0;
|
||||
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));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
v=0
|
||||
o=user 0 0 IN IP4 10.21.25.200
|
||||
s=No Name
|
||||
c=IN IP4 10.21.25.200
|
||||
t=0 0
|
||||
m=video 8888 RTP/AVP 96
|
||||
a=rtpmap:96 H265/90000
|
||||
a=recvonly
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
v=0
|
||||
o=user 0 0 IN IP4 10.21.25.200
|
||||
s=No Name
|
||||
c=IN IP4 10.21.25.200
|
||||
t=0 0
|
||||
m=video 8890 RTP/AVP 96
|
||||
a=rtpmap:96 H265/90000
|
||||
a=recvonly
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
v=0
|
||||
o=user 0 0 IN IP4 10.21.25.200
|
||||
s=No Name
|
||||
c=IN IP4 10.21.25.200
|
||||
t=0 0
|
||||
m=video 8892 RTP/AVP 96
|
||||
a=rtpmap:96 H265/90000
|
||||
a=recvonly
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
v=0
|
||||
o=user 0 0 IN IP4 10.21.25.200
|
||||
s=No Name
|
||||
c=IN IP4 10.21.25.200
|
||||
t=0 0
|
||||
m=video 8894 RTP/AVP 96
|
||||
a=rtpmap:96 H265/90000
|
||||
a=recvonly
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
v=0
|
||||
o=user 0 0 IN IP4 10.21.25.200
|
||||
s=No Name
|
||||
c=IN IP4 10.21.25.200
|
||||
t=0 0
|
||||
m=video 8896 RTP/AVP 96
|
||||
a=rtpmap:96 H265/90000
|
||||
a=recvonly
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
v=0
|
||||
o=user 0 0 IN IP4 10.21.25.200
|
||||
s=No Name
|
||||
c=IN IP4 10.21.25.200
|
||||
t=0 0
|
||||
m=video 8898 RTP/AVP 96
|
||||
a=rtpmap:96 H265/90000
|
||||
a=recvonly
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
v=0
|
||||
o=user 0 0 IN IP4 10.21.25.200
|
||||
s=No Name
|
||||
c=IN IP4 10.21.25.200
|
||||
t=0 0
|
||||
m=video 8900 RTP/AVP 96
|
||||
a=rtpmap:96 H265/90000
|
||||
a=recvonly
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
v=0
|
||||
o=user 0 0 IN IP4 10.21.25.200
|
||||
s=No Name
|
||||
c=IN IP4 10.21.25.200
|
||||
t=0 0
|
||||
m=video 8902 RTP/AVP 96
|
||||
a=rtpmap:96 H265/90000
|
||||
a=recvonly
|
||||
Loading…
Reference in New Issue