Skip to content

Commit 5256b2f

Browse files
committed
fftools/ffmpeg_mux: print latency information in -debug_ts muxing output
1 parent 9d7000b commit 5256b2f

File tree

2 files changed

+79
-11
lines changed

2 files changed

+79
-11
lines changed

doc/ffmpeg.texi

+1-1
Original file line numberDiff line numberDiff line change
@@ -830,7 +830,7 @@ be achieved with @code{ffmpeg ... < /dev/null} but it requires a
830830
shell.
831831

832832
@item -debug_ts (@emph{global})
833-
Print timestamp information. It is off by default. This option is
833+
Print timestamp/latency information. It is off by default. This option is
834834
mostly useful for testing and debugging purposes, and the output
835835
format may change from one version to another, so it should not be
836836
employed by portable scripts.

fftools/ffmpeg_mux.c

+78-10
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,12 @@
2525
#include "ffmpeg_utils.h"
2626
#include "sync_queue.h"
2727

28+
#include "libavutil/avstring.h"
2829
#include "libavutil/fifo.h"
2930
#include "libavutil/intreadwrite.h"
3031
#include "libavutil/log.h"
3132
#include "libavutil/mem.h"
33+
#include "libavutil/time.h"
3234
#include "libavutil/timestamp.h"
3335

3436
#include "libavcodec/packet.h"
@@ -59,6 +61,80 @@ static int64_t filesize(AVIOContext *pb)
5961
return ret;
6062
}
6163

64+
static void mux_log_debug_ts(OutputStream *ost, const AVPacket *pkt)
65+
{
66+
static const char *desc[] = {
67+
[LATENCY_PROBE_DEMUX] = "demux",
68+
[LATENCY_PROBE_DEC_PRE] = "decode",
69+
[LATENCY_PROBE_DEC_POST] = "decode",
70+
[LATENCY_PROBE_FILTER_PRE] = "filter",
71+
[LATENCY_PROBE_FILTER_POST] = "filter",
72+
[LATENCY_PROBE_ENC_PRE] = "encode",
73+
[LATENCY_PROBE_ENC_POST] = "encode",
74+
[LATENCY_PROBE_NB] = "mux",
75+
};
76+
77+
char latency[512];
78+
79+
*latency = 0;
80+
if (pkt->opaque_ref) {
81+
const FrameData *fd = (FrameData*)pkt->opaque_ref->data;
82+
int64_t now = av_gettime_relative();
83+
int64_t total = INT64_MIN;
84+
85+
int next;
86+
87+
for (unsigned i = 0; i < FF_ARRAY_ELEMS(fd->wallclock); i = next) {
88+
int64_t val = fd->wallclock[i];
89+
90+
next = i + 1;
91+
92+
if (val == INT64_MIN)
93+
continue;
94+
95+
if (total == INT64_MIN) {
96+
total = now - val;
97+
snprintf(latency, sizeof(latency), "total:%gms", total / 1e3);
98+
}
99+
100+
// find the next valid entry
101+
for (; next <= FF_ARRAY_ELEMS(fd->wallclock); next++) {
102+
int64_t val_next = (next == FF_ARRAY_ELEMS(fd->wallclock)) ?
103+
now : fd->wallclock[next];
104+
int64_t diff;
105+
106+
if (val_next == INT64_MIN)
107+
continue;
108+
diff = val_next - val;
109+
110+
// print those stages that take at least 5% of total
111+
if (100. * diff > 5. * total) {
112+
av_strlcat(latency, ", ", sizeof(latency));
113+
114+
if (!strcmp(desc[i], desc[next]))
115+
av_strlcat(latency, desc[i], sizeof(latency));
116+
else
117+
av_strlcatf(latency, sizeof(latency), "%s-%s:",
118+
desc[i], desc[next]);
119+
120+
av_strlcatf(latency, sizeof(latency), " %gms/%d%%",
121+
diff / 1e3, (int)(100. * diff / total));
122+
}
123+
124+
break;
125+
}
126+
127+
}
128+
}
129+
130+
av_log(ost, AV_LOG_INFO, "muxer <- pts:%s pts_time:%s dts:%s dts_time:%s "
131+
"duration:%s duration_time:%s size:%d latency(%s)\n",
132+
av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, &ost->st->time_base),
133+
av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, &ost->st->time_base),
134+
av_ts2str(pkt->duration), av_ts2timestr(pkt->duration, &ost->st->time_base),
135+
pkt->size, *latency ? latency : "N/A");
136+
}
137+
62138
static int write_packet(Muxer *mux, OutputStream *ost, AVPacket *pkt)
63139
{
64140
MuxStream *ms = ms_from_ost(ost);
@@ -140,16 +216,8 @@ static int write_packet(Muxer *mux, OutputStream *ost, AVPacket *pkt)
140216

141217
pkt->stream_index = ost->index;
142218

143-
if (debug_ts) {
144-
av_log(ost, AV_LOG_INFO, "muxer <- type:%s "
145-
"pkt_pts:%s pkt_pts_time:%s pkt_dts:%s pkt_dts_time:%s duration:%s duration_time:%s size:%d\n",
146-
av_get_media_type_string(ost->type),
147-
av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, &ost->st->time_base),
148-
av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, &ost->st->time_base),
149-
av_ts2str(pkt->duration), av_ts2timestr(pkt->duration, &ost->st->time_base),
150-
pkt->size
151-
);
152-
}
219+
if (debug_ts)
220+
mux_log_debug_ts(ost, pkt);
153221

154222
if (ms->stats.io)
155223
enc_stats_write(ost, &ms->stats, NULL, pkt, frame_num);

0 commit comments

Comments
 (0)