Skip to content

Commit

Permalink
Merge remote-tracking branch 'my/recording-stability'
Browse files Browse the repository at this point in the history
  • Loading branch information
andrey-utkin committed Oct 21, 2024
2 parents 2a1bb9c + 21a31fd commit 1865a97
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 32 deletions.
48 changes: 23 additions & 25 deletions server/media_writer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ static void bc_avlog(int val, const char *msg)
// S.K. >> Implementation of separated media writer
///////////////////////////////////////////////////////////////

media_writer::media_writer()
media_writer::media_writer():
last_mux_dts{0, 0}
{
}

Expand Down Expand Up @@ -74,31 +75,24 @@ bool media_writer::write_packet(const stream_packet &pkt)
opkt.stream_index = stream->index;

/* Fix non-increasing timestamps */
if (pkt.type == AVMEDIA_TYPE_AUDIO)
{
if (opkt.pts < last_audio_pts || opkt.dts < last_audio_dts)
{
opkt.pts = last_audio_pts + 1;
opkt.dts = last_audio_dts + 1;
bc_log(Debug, "fixing timestamps in audio packet");
}

last_audio_pts = opkt.pts;
last_audio_dts = opkt.dts;
}

if (pkt.type == AVMEDIA_TYPE_VIDEO)
{
if (opkt.pts < last_video_pts || opkt.dts < last_video_dts)
{
opkt.pts = last_video_pts + 1;
opkt.dts = last_video_dts + 1;
bc_log(Debug, "fixing timestamps in video packet");
}

last_video_pts = opkt.pts;
last_video_dts = opkt.dts;
static_assert(AVMEDIA_TYPE_VIDEO == 0);
static_assert(AVMEDIA_TYPE_AUDIO == 1);
int64_t &last_mux_dts = this->last_mux_dts[pkt.type];
if (opkt.dts == AV_NOPTS_VALUE) {
// Do nothing.
// In ffmpeg, ffmpeg_mux.c:write_packet() does nothing and
// lavf/mux.c:compute_muxer_pkt_fields() deals with it for now
bc_log(Info, "Got bad dts=NOPTS on stream %d, passing to libavformat to handle", opkt.stream_index);
} else if (last_mux_dts < opkt.dts) {
// Do nothing. This is normal.
} else {
// In this clause we're dealing with incorrect timestamp received from the source.
assert(last_mux_dts >= opkt.dts);
assert(last_mux_dts != AV_NOPTS_VALUE);
bc_log(Info, "Got bad dts=%" PRId64 " while last was %" PRId64 " on stream %d, setting to last+1", opkt.dts, last_mux_dts, opkt.stream_index);
opkt.dts = last_mux_dts + 1;
}
last_mux_dts = opkt.dts;

bc_log(Debug, "av_interleaved_write_frame: dts=%" PRId64 " pts=%" PRId64 " tb=%d/%d s_i=%d k=%d",
opkt.dts, opkt.pts, out_ctx->streams[opkt.stream_index]->time_base.num,
Expand All @@ -109,6 +103,10 @@ bool media_writer::write_packet(const stream_packet &pkt)
if (re < 0)
{
bc_avlog(re, "Error writing frame to recording");
if (re == AVERROR(EINVAL)) {
bc_log(Error, "Error writing frame to recording. Likely timestamping problem. Ignoring.");
return true;
}
return false;
}

Expand Down
9 changes: 2 additions & 7 deletions server/media_writer.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,8 @@ class media_writer
AVStream *audio_st = NULL;
std::string recording_path;

/* Base PTS value for the start of the recording. This assumes that all streams
* share a time_base of AV_TIME_BASE, and 0 represents the same instant across all
* streams. This is set automatically by the first written packet. */
int64_t last_video_pts = 0;
int64_t last_video_dts = 0;
int64_t last_audio_pts = 0;
int64_t last_audio_dts = 0;
/* Control monotonicity of timestamps we feed to muxer, the same way as in ffmpeg_mux.c in ffmpeg.*/
int64_t last_mux_dts[2] = {0, 0};
};

class snapshot_writer
Expand Down

0 comments on commit 1865a97

Please sign in to comment.