recording: improve pts accuracy and consistency

Also clean up some logging
This commit is contained in:
Megamouse 2023-11-15 23:58:21 +01:00
parent 90846013c2
commit 49f910a56b
3 changed files with 25 additions and 24 deletions

View file

@ -821,12 +821,7 @@ void rec_info::stop_video_provider(bool flush)
const usz audio_start_offset = audio_ring_block_count < audio_ringbuffer.size() ? 0 : audio_ring_block_count; const usz audio_start_offset = audio_ring_block_count < audio_ringbuffer.size() ? 0 : audio_ring_block_count;
const s64 audio_start_pts = audio_ringbuffer.empty() ? 0 : audio_ringbuffer[audio_start_offset % audio_ringbuffer.size()].pts; const s64 audio_start_pts = audio_ringbuffer.empty() ? 0 : audio_ringbuffer[audio_start_offset % audio_ringbuffer.size()].pts;
cellRec.error("Flushing video ringbuffer: frame_count=%d, video_ringbuffer.size=%d", frame_count, video_ringbuffer.size());
cellRec.error("Flushing video ringbuffer: block_count=%d, audio_ringbuffer.size=%d", block_count, audio_ringbuffer.size());
cellRec.error("Flushing video ringbuffer: video_start_pts=%d, audio_start_pts=%d", video_start_pts, audio_start_pts);
// Try to add the frames and samples in proper order // Try to add the frames and samples in proper order
s64 last_pts = -1;
for (usz sync_timestamp_us = 0, frame = 0, block = 0; frame < frame_count || block < block_count; frame++) for (usz sync_timestamp_us = 0, frame = 0, block = 0; frame < frame_count || block < block_count; frame++)
{ {
// Add one frame // Add one frame
@ -854,13 +849,6 @@ void rec_info::stop_video_provider(bool flush)
break; break;
} }
if (sample_block.pts <= last_pts)
{
cellRec.error("Flushing video ringbuffer: last_pts=%d, sample_block.pts=%d", last_pts, sample_block.pts);
}
last_pts = sample_block.pts;
encoder->add_audio_samples(sample_block.block.data(), CELL_REC_AUDIO_BLOCK_SAMPLES, channels, timestamp_us); encoder->add_audio_samples(sample_block.block.data(), CELL_REC_AUDIO_BLOCK_SAMPLES, channels, timestamp_us);
block++; block++;
} }

View file

@ -767,6 +767,11 @@ namespace utils
av_log_set_callback([](void* avcl, int level, const char* fmt, va_list vl) -> void av_log_set_callback([](void* avcl, int level, const char* fmt, va_list vl) -> void
{ {
if (level > av_log_get_level())
{
return;
}
constexpr int line_size = 1024; constexpr int line_size = 1024;
char line[line_size]{}; char line[line_size]{};
int print_prefix = 1; int print_prefix = 1;
@ -777,9 +782,17 @@ namespace utils
return; return;
} }
media_log.error("av_log: %s", line); // TODO: decrease log level std::string msg = line;
fmt::trim_back(msg, "\n\r\t ");
if (level <= AV_LOG_ERROR)
media_log.error("av_log: %s", msg);
else if (level <= AV_LOG_WARNING)
media_log.warning("av_log: %s", msg);
else
media_log.notice("av_log: %s", msg);
}); });
av_log_set_level(AV_LOG_TRACE); av_log_set_level(AV_LOG_ERROR);
// Reset variables at all costs // Reset variables at all costs
scoped_av av; scoped_av av;
@ -1198,11 +1211,11 @@ namespace utils
// We need to skip this frame if it has the same timestamp. // We need to skip this frame if it has the same timestamp.
if (pts <= last_video_pts) if (pts <= last_video_pts)
{ {
media_log.trace("video_encoder: skipping frame. last_pts=%d, pts=%d", last_video_pts, pts); media_log.trace("video_encoder: skipping frame. last_pts=%d, pts=%d, timestamp_ms=%d", last_video_pts, pts, frame_data.timestamp_ms);
} }
else if (av.video.context) else if (av.video.context)
{ {
media_log.trace("video_encoder: adding new frame. timestamp=%d", frame_data.timestamp_ms); media_log.trace("video_encoder: adding new frame. timestamp_ms=%d", frame_data.timestamp_ms);
if (int err = av_frame_make_writable(av.video.frame); err < 0) if (int err = av_frame_make_writable(av.video.frame); err < 0)
{ {
@ -1289,7 +1302,7 @@ namespace utils
// We need to skip this frame if it has the same timestamp. // We need to skip this frame if it has the same timestamp.
if (pts <= last_audio_pts) if (pts <= last_audio_pts)
{ {
media_log.error("video_encoder: skipping sample. last_pts=%d, pts=%d", last_audio_pts, pts); media_log.trace("video_encoder: skipping sample. last_pts=%d, pts=%d, timestamp_us=%d", last_audio_pts, pts, sample_data.timestamp_us);
} }
else if (av.audio.context) else if (av.audio.context)
{ {

View file

@ -39,25 +39,25 @@ namespace utils
s64 get_pts(usz timestamp_ms) const s64 get_pts(usz timestamp_ms) const
{ {
return static_cast<s64>(std::round((timestamp_ms * m_framerate) / 1000.f)); return static_cast<s64>(std::round((timestamp_ms * m_framerate) / 1000.0));
} }
s64 get_audio_pts(usz timestamp_us) const s64 get_audio_pts(usz timestamp_us) const
{ {
static constexpr f32 us_per_sec = 1000000.0f; static constexpr f64 us_per_sec = 1000000.0;
const f32 us_per_block = us_per_sec / (m_sample_rate / static_cast<f32>(m_samples_per_block)); const f64 us_per_block = us_per_sec / (m_sample_rate / static_cast<f64>(m_samples_per_block));
return static_cast<s64>(std::ceil(timestamp_us / us_per_block)); return static_cast<s64>(std::round(timestamp_us / us_per_block));
} }
usz get_timestamp_ms(s64 pts) const usz get_timestamp_ms(s64 pts) const
{ {
return static_cast<usz>(std::round((pts * 1000) / static_cast<f32>(m_framerate))); return static_cast<usz>(std::round((pts * 1000) / static_cast<f64>(m_framerate)));
} }
usz get_audio_timestamp_us(s64 pts) const usz get_audio_timestamp_us(s64 pts) const
{ {
static constexpr f32 us_per_sec = 1000000.0f; static constexpr f64 us_per_sec = 1000000.0;
const f32 us_per_block = us_per_sec / (m_sample_rate / static_cast<f32>(m_samples_per_block)); const f64 us_per_block = us_per_sec / (m_sample_rate / static_cast<f64>(m_samples_per_block));
return static_cast<usz>(pts * us_per_block); return static_cast<usz>(pts * us_per_block);
} }