Skip to content

Commit e5bcb1b

Browse files
authored
Merge pull request #2181 from pedroSG94/fix/surface-pts-shares-audio-origin
Fix/surface pts shares audio origin
2 parents 90bdca8 + 911fc23 commit e5bcb1b

1 file changed

Lines changed: 18 additions & 5 deletions

File tree

encoder/src/main/java/com/pedro/encoder/video/VideoEncoder.java

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,21 @@ public void formatChanged(@NonNull MediaCodec mediaCodec, @NonNull MediaFormat m
444444
spsPpsSetted = sendSPSandPPS(mediaFormat);
445445
}
446446

447+
/**
448+
* Surface mode: rebase the timestamp to something relative. The GlInterface stamps the surface
449+
* with the TimeUtils clock, so we share the origin with the audio encoder. A surface fed directly
450+
* (decoder in FromFileBase, MediaProjection in DisplayBase without opengl) uses another time base
451+
* and must be rebased against its own first frame.
452+
* Using 1 second to difference both ways.
453+
*/
454+
private long rebaseSurfacePts(long pts) {
455+
if (firstTimestamp == 0) {
456+
boolean sharedClock = presentTimeUs > 0 && Math.abs(pts - TimeUtils.getCurrentTimeMicro()) < 1_000_000;
457+
firstTimestamp = sharedClock ? presentTimeUs : pts;
458+
}
459+
return Math.max(0, pts - firstTimestamp);
460+
}
461+
447462
@Override
448463
protected boolean checkBuffer(@NonNull ByteBuffer byteBuffer, @NonNull MediaCodec.BufferInfo bufferInfo) {
449464
if (forceKey && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
@@ -510,12 +525,10 @@ protected boolean checkBuffer(@NonNull ByteBuffer byteBuffer, @NonNull MediaCode
510525
// Buffer mode: synthesize PTS from wall clock.
511526
bufferInfo.presentationTimeUs = TimeUtils.getCurrentTimeMicro() - presentTimeUs;
512527
} else {
513-
// Surface mode: EGL timestamp is camera sensor time (nanoseconds from boot ÷ 1000).
514-
// It has clean, jitter-free intervals — but it's a huge absolute value that breaks RTMP.
515-
// Rebase to relative by subtracting the first frame's PTS → clean intervals, starts at 0.
516-
if (firstTimestamp == 0) firstTimestamp = bufferInfo.presentationTimeUs;
517-
bufferInfo.presentationTimeUs -= firstTimestamp;
528+
bufferInfo.presentationTimeUs = rebaseSurfacePts(bufferInfo.presentationTimeUs);
518529
}
530+
} else if (formatVideoEncoder == FormatVideoEncoder.SURFACE) {
531+
bufferInfo.presentationTimeUs = rebaseSurfacePts(bufferInfo.presentationTimeUs);
519532
} else {
520533
if (firstTimestamp == 0) firstTimestamp = bufferInfo.presentationTimeUs;
521534
bufferInfo.presentationTimeUs -= firstTimestamp;

0 commit comments

Comments
 (0)