Skip to content

Commit a37ad5d

Browse files
committed
audio: use monotonic counter-based PTS for AAC RTSP streams
Replace gettimeofday() with a wallclock-anchored monotonic counter for AAC audio fPresentationTime in IMPDeviceSource. On the first AAC frame we snapshot gettimeofday() as the base, then advance by exactly frameCount * 1024 / sampleRate microseconds per frame. This produces strictly monotonic +1024-sample RTP PTS increments (verified via ffprobe) while staying in the gettimeofday() clock domain required by live555 RTCP SR (RFC 3550 §6.4.1) for correct NTP-RTP timestamp pairing and inter-stream synchronization. The previous gettimeofday()-per-frame approach introduced OS scheduling jitter causing non-monotonic DTS that broke FFmpeg/Frigate MP4 muxing. Also fix AudioReframer timestamp increment from microseconds (*1000000) to milliseconds (*1000) to match the actual unit used by callers. Fixes: themactep/thingino-firmware#1082
1 parent 48104af commit a37ad5d

2 files changed

Lines changed: 28 additions & 15 deletions

File tree

src/AudioReframer.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ void AudioReframer::getReframedFrame(uint8_t *frameData, int64_t &timestamp) {
4242

4343
timestamp = currentTimestamp;
4444
if (inputSampleRate > 0) {
45-
currentTimestamp += (static_cast<int64_t>(outputSamplesPerFrame) * 1000000LL) / inputSampleRate;
45+
currentTimestamp += (outputSamplesPerFrame * 1000) / inputSampleRate;
4646
} // else: keep currentTimestamp stable if misconfigured
4747
}
4848

src/IMPDeviceSource.cpp

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,7 @@
11
#include "IMPDeviceSource.hpp"
22
#include "GroupsockHelper.hh"
33
#include <iostream>
4-
5-
// Use live555's own clock (gettimeofday on the live555 thread) for the audio
6-
// presentation time so that the RTCP SR NTP and RTP timestamps are computed
7-
// from the same clock, keeping pts values near-zero and non-negative.
8-
// Hardware timestamps are still used by AudioWorker for the AudioReframer
9-
// (uniform 1024-sample frame boundaries) and for MP4 recording.
10-
// Video falls back to gettimeofday because H264NALUnit.time is not yet populated.
11-
static void assignPresentationTime(const AudioFrame &, struct timeval &tv) {
12-
gettimeofday(&tv, nullptr);
13-
}
14-
static void assignPresentationTime(const H264NALUnit &, struct timeval &tv) {
15-
gettimeofday(&tv, nullptr);
16-
}
4+
#include <type_traits>
175

186
// explicit instantiation
197
template class IMPDeviceSource<H264NALUnit, video_stream>;
@@ -76,7 +64,32 @@ template <typename FrameType, typename Stream> void IMPDeviceSource<FrameType, S
7664
fFrameSize = nal.data.size();
7765
}
7866

79-
assignPresentationTime(nal, fPresentationTime);
67+
/* Use monotonic counter-based timestamps for AAC to produce perfectly
68+
steady +1024 RTP PTS increments and avoid gettimeofday jitter. */
69+
if constexpr (std::is_same_v<FrameType, AudioFrame>) {
70+
auto *imp_audio = global_audio[encChn]->imp_audio;
71+
if (imp_audio && imp_audio->format == IMPAudioFormat::AAC) {
72+
if (audioFirstFrame) {
73+
gettimeofday(&audioStartTime, NULL);
74+
audioFrameCount = 0;
75+
audioFirstFrame = false;
76+
}
77+
int sampleRate = (imp_audio->sample_rate > 0) ? imp_audio->sample_rate : 16000;
78+
constexpr uint64_t kSamplesPerFrame = 1024;
79+
uint64_t usec_offset = (audioFrameCount * kSamplesPerFrame * 1000000ULL) / static_cast<uint64_t>(sampleRate);
80+
fPresentationTime.tv_sec = audioStartTime.tv_sec + static_cast<time_t>(usec_offset / 1000000ULL);
81+
fPresentationTime.tv_usec = audioStartTime.tv_usec + static_cast<suseconds_t>(usec_offset % 1000000ULL);
82+
if (fPresentationTime.tv_usec >= 1000000) {
83+
fPresentationTime.tv_sec++;
84+
fPresentationTime.tv_usec -= 1000000;
85+
}
86+
audioFrameCount++;
87+
} else {
88+
gettimeofday(&fPresentationTime, NULL);
89+
}
90+
} else {
91+
gettimeofday(&fPresentationTime, NULL);
92+
}
8093

8194
memcpy(fTo, &nal.data[0], fFrameSize);
8295

0 commit comments

Comments
 (0)