Skip to content

Commit

Permalink
Merge pull request pesintta#71 from j1rie/latest
Browse files Browse the repository at this point in the history
improve skip_sync logic
  • Loading branch information
ua0lnj authored Nov 11, 2023
2 parents 63983d6 + 00978c8 commit 97e825d
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 64 deletions.
6 changes: 4 additions & 2 deletions README.txt
Original file line number Diff line number Diff line change
Expand Up @@ -231,8 +231,10 @@ Setup: /etc/vdr/setup.conf
1 enable 60Hz display mode

softhddevice.SoftStartSync = 0
0 disable soft start of audio/video sync
1 enable soft start of audio/video sync
0 early audio + fast SD (was disable soft start)
1 early audio + fast SD + soft start of audio/video sync (was enable soft start)
2 early audio/video sync + fast switch
3 early audio/video sync + accurate swicth

softhddevice.BlackPicture = 0
0 disable black picture during channel switch
Expand Down
6 changes: 3 additions & 3 deletions audio.c
Original file line number Diff line number Diff line change
Expand Up @@ -2172,7 +2172,7 @@ static void *AudioPlayHandlerThread(void *dummy)
continue;
} else {
if (AudioStarted && snd_pcm_state(AlsaPCMHandle) == SND_PCM_STATE_XRUN && !IsReplay()) {
Debug(3, "audio: audio started and underrun, increase AudioBufferTime?!\n");
Warning(_("audio: audio started and underrun, increase AudioBufferTime?!\n"));
}
Debug(3, "audio: buffer empty or pcm not running, and no new ring buffer, goto sleep\n");
break;
Expand Down Expand Up @@ -2470,7 +2470,7 @@ void AudioVideoReady(int64_t pts)
}
first = 0;
}
usleep(10 * 1000);
usleep(10 * 1000); // wait for audio pts
} else {
if (i) {
Debug(3, "audio: a/v start, finally valid audio, looped %d times, %d ms\n", i, i * 10);
Expand Down Expand Up @@ -2506,7 +2506,7 @@ void AudioVideoReady(int64_t pts)
if (!AudioRunning || IsReplay()) {
int skip;

skip = pts - audio_pts - VideoAudioDelay - (IsReplay() ? 0 : AudioBufferTime * 90) + (VideoResolution == VideoResolution576i && !IsReplay() && VideoSoftStartSync > 1 ? 240 * 90 : 0); // early sync
skip = pts - audio_pts - VideoAudioDelay - (IsReplay() ? 0 : 15 * 20 *90 * (VideoSoftStartSync < 2) + AudioBufferTime * 90) + (VideoResolution == VideoResolution576i && !IsReplay() && VideoSoftStartSync > 1 ? 240 * 90 : 0); // early sync
#ifdef DEBUG
fprintf(stderr, "%dms %dms %dms\n", (int)(pts - audio_pts) / 90,
VideoAudioDelay / 90, skip / 90);
Expand Down
2 changes: 2 additions & 0 deletions softhddev.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ static void DumpMpeg(const uint8_t * data, int size);
extern int ConfigAudioBufferTime; ///< config size ms of audio buffer
extern int DisableOglOsd; ///< disable OpenGL OSD
extern char ConfigVideoClearOnSwitch; ///< clear decoder on channel switch
extern volatile char AudioStarted;
char ConfigStartX11Server; ///< flag start the x11 server
static signed char ConfigStartSuspended; ///< flag to start in suspend mode
static char ConfigFullscreen; ///< fullscreen modus
Expand Down Expand Up @@ -2965,6 +2966,7 @@ int SetPlayMode(int play_mode)
if (MyAudioDecoder) { // tell audio parser we have new stream
if (AudioCodecID != AV_CODEC_ID_NONE) {
NewAudioStream = 1;
AudioStarted = 0;
}
}
break;
Expand Down
2 changes: 1 addition & 1 deletion softhddevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1132,7 +1132,7 @@ void cMenuSetupSoft::Create(void)
"pan&scan", "pillarbox", "center cut-out",
};
static const char *const video_sync_mode[] = {
tr("early audio"), tr("early audio + soft sync"), tr("early sync + fast SD"), tr("early sync + accurate SD"),
tr("early audio"), tr("early audio + soft sync"), tr("early sync + fast switch"), tr("early sync + accurate switch"),
};
static const char *const audiodrift[] = {
tr("None"), "PCM", "AC-3", "PCM + AC-3"
Expand Down
117 changes: 59 additions & 58 deletions video.c
Original file line number Diff line number Diff line change
Expand Up @@ -639,6 +639,7 @@ volatile int EnoughVideo;
extern volatile int EnoughAudio;
volatile VideoResolutions VideoResolution;
static int VideoStartThreshold_SD = 16;
static int VideoStartThreshold_HD = 38;
void AudioDelayms(int);
extern volatile char SoftIsPlayingVideo; ///< stream contains video data
//----------------------------------------------------------------------------
Expand Down Expand Up @@ -7533,7 +7534,7 @@ static void VaapiSyncDecoder(VaapiDecoder * decoder)
goto skip_sync;
}

EnoughVideo = (VideoGetBuffers(decoder->Stream) >= (VideoResolution == VideoResolution576i && VideoSoftStartSync == 3 ? VideoStartThreshold_SD : 0)); // accurate SD
EnoughVideo = (VideoGetBuffers(decoder->Stream) >= (VideoResolution == VideoResolution576i ? VideoStartThreshold_SD : VideoStartThreshold_HD) * (VideoSoftStartSync == 3)); // accurate switch
if (!EnoughVideo && EnoughAudio && !AudioRunning && decoder->StartCounter > 200) {
Debug (3,"video: force enough video\n");
EnoughVideo = 1;
Expand Down Expand Up @@ -7631,7 +7632,7 @@ static void VaapiSyncDecoder(VaapiDecoder * decoder)
++decoder->FramesDropped;
VaapiAdvanceDecoderFrame(decoder);
decoder->SyncCounter = 2;
} else if (diff < lower_limit * 90 && atomic_read(&decoder->SurfacesFilled) <= 1 && !IsReplay()) {
} else if (diff < lower_limit * 90 && atomic_read(&decoder->SurfacesFilled) <= 2 && !IsReplay()) { // if double advance video not possible, delay audio
err = VaapiMessage(3, "video: speed up audio, delay audio\n");
AudioDelayms(-diff / 90 + 55);
}
Expand Down Expand Up @@ -11971,7 +11972,7 @@ static void VdpauSyncDecoder(VdpauDecoder * decoder)
goto skip_sync;
}

EnoughVideo = (VideoGetBuffers(decoder->Stream) >= (VideoResolution == VideoResolution576i && VideoSoftStartSync == 3 ? VideoStartThreshold_SD : 0)); // accurate SD
EnoughVideo = (VideoGetBuffers(decoder->Stream) >= (VideoResolution == VideoResolution576i ? VideoStartThreshold_SD : VideoStartThreshold_HD) * (VideoSoftStartSync == 3)); // accurate switch
if (!EnoughVideo && EnoughAudio && !AudioRunning && decoder->StartCounter > 200) {
Debug (3,"video: force enough video\n");
EnoughVideo = 1;
Expand Down Expand Up @@ -12090,22 +12091,22 @@ static void VdpauSyncDecoder(VdpauDecoder * decoder)
skip_sync:
// trigger black picture?
if (decoder->SurfaceField && atomic_read(&decoder->SurfacesFilled) < 1 + 2 * decoder->Interlaced + 1 * !IsReplay()) {
// is it not possible, to advance the surface and/or the field?
if (decoder->SurfaceField && atomic_read(&decoder->SurfacesFilled) < 1 + 2 * decoder->Interlaced) {
++decoder->FramesDuped;
// FIXME: don't warn after stream start, don't warn during pause
err =
VdpauMessage(3,
_("video: decoder buffer empty, "
"duping frame (%d/%d) %d v-buf closing %d\n"), decoder->FramesDuped,
decoder->FrameCounter, VideoGetBuffers(decoder->Stream), decoder->Closing);
}
// some time no new picture or black video configured
if (decoder->Closing < -300 || (VideoShowBlackPicture
&& decoder->Closing)) {
// clear ring buffer to trigger black picture
atomic_set(&decoder->SurfacesFilled, 0);
}
}
// is it not possible, to advance the surface and/or the field? don't warn if radio
if (decoder->SurfaceField && atomic_read(&decoder->SurfacesFilled) < 1 + 2 * decoder->Interlaced && SoftIsPlayingVideo) {
++decoder->FramesDuped;
// FIXME: don't warn after stream start, don't warn during pause
err =
VdpauMessage(3,
_("video: decoder buffer empty, "
"duping frame (%d/%d) %d v-buf closing %d\n"), decoder->FramesDuped,
decoder->FrameCounter, VideoGetBuffers(decoder->Stream), decoder->Closing);
goto out;
}

Expand Down Expand Up @@ -14773,7 +14774,7 @@ static void CuvidSyncDecoder(CuvidDecoder * decoder)
goto skip_sync;
}

EnoughVideo = (VideoGetBuffers(decoder->Stream) >= (VideoResolution == VideoResolution576i && VideoSoftStartSync == 3 ? VideoStartThreshold_SD : 0)); // accurate SD
EnoughVideo = (VideoGetBuffers(decoder->Stream) >= (VideoResolution == VideoResolution576i ? VideoStartThreshold_SD : VideoStartThreshold_HD) * (VideoSoftStartSync == 3)); // accurate switch
if (!EnoughVideo && EnoughAudio && !AudioRunning && decoder->StartCounter > 200) {
Debug (3,"video: force enough video\n");
EnoughVideo = 1;
Expand Down Expand Up @@ -14892,22 +14893,22 @@ static void CuvidSyncDecoder(CuvidDecoder * decoder)
skip_sync:
// trigger black picture?
if (decoder->SurfaceField && atomic_read(&decoder->SurfacesFilled) < 1 + 2 * decoder->Interlaced + 1 * !IsReplay()) {
// is it not possible, to advance the surface and/or the field? don't warn, if radio
if (decoder->SurfaceField && atomic_read(&decoder->SurfacesFilled) < 1 + 2 * decoder->Interlaced && SoftIsPlayingVideo) {
++decoder->FramesDuped;
// FIXME: don't warn after stream start, don't warn during pause
err =
CuvidMessage(3,
("video: decoder buffer empty, "
"duping frame (%d/%d) %d v-buf closing %d\n"), decoder->FramesDuped,
decoder->FrameCounter, VideoGetBuffers(decoder->Stream), decoder->Closing);
}
// some time no new picture or black video configured
if (decoder->Closing < -300 || (VideoShowBlackPicture
&& decoder->Closing)) {
// clear ring buffer to trigger black picture
atomic_set(&decoder->SurfacesFilled, 0);
}
}
// is it not possible, to advance the surface and/or the field? don't warn, if radio
if (decoder->SurfaceField && atomic_read(&decoder->SurfacesFilled) < 1 + 2 * decoder->Interlaced && SoftIsPlayingVideo) {
++decoder->FramesDuped;
// FIXME: don't warn after stream start, don't warn during pause
err =
CuvidMessage(3,
_("video: decoder buffer empty, "
"duping frame (%d/%d) %d v-buf closing %d\n"), decoder->FramesDuped,
decoder->FrameCounter, VideoGetBuffers(decoder->Stream), decoder->Closing);
goto out;
}

Expand Down Expand Up @@ -17349,7 +17350,7 @@ static void NVdecSyncDecoder(NVdecDecoder * decoder)
goto skip_sync;
}

EnoughVideo = (VideoGetBuffers(decoder->Stream) >= (VideoResolution == VideoResolution576i && VideoSoftStartSync == 3 ? VideoStartThreshold_SD : 0)); // accurate SD
EnoughVideo = (VideoGetBuffers(decoder->Stream) >= (VideoResolution == VideoResolution576i ? VideoStartThreshold_SD : VideoStartThreshold_HD) * (VideoSoftStartSync == 3)); // accurate switch
if (!EnoughVideo && EnoughAudio && !AudioRunning && decoder->StartCounter > 200) {
Debug (3,"video: force enough video\n");
EnoughVideo = 1;
Expand Down Expand Up @@ -17447,7 +17448,7 @@ static void NVdecSyncDecoder(NVdecDecoder * decoder)
++decoder->FramesDropped;
NVdecAdvanceDecoderFrame(decoder);
decoder->SyncCounter = 2;
} else if (diff < lower_limit * 90 && atomic_read(&decoder->SurfacesFilled) <= 1 + decoder->Interlaced && !IsReplay()) { //if double advance video not possible, delay audio
} else if (diff < lower_limit * 90 && atomic_read(&decoder->SurfacesFilled) <= 1 + decoder->Interlaced && !IsReplay()) { // if double advance video not possible, delay audio
err = NVdecMessage(3, "video: speed up audio, delay audio\n");
AudioDelayms(-diff / 90 + 55);
}
Expand All @@ -17468,22 +17469,22 @@ static void NVdecSyncDecoder(NVdecDecoder * decoder)
skip_sync:
// trigger black picture?
if (decoder->SurfaceField && atomic_read(&decoder->SurfacesFilled) < 1 + 2 * decoder->Interlaced + 1 * !IsReplay()) {
// is it not possible, to advance the surface and/or the field?
if (decoder->SurfaceField && atomic_read(&decoder->SurfacesFilled) < 1 + 2 * decoder->Interlaced) {
++decoder->FramesDuped;
// FIXME: don't warn after stream start, don't warn during pause
err =
NVdecMessage(3,
_("video: decoder buffer empty, "
"duping frame (%d/%d) %d v-buf closing %d\n"), decoder->FramesDuped,
decoder->FrameCounter, VideoGetBuffers(decoder->Stream), decoder->Closing);
}
// some time no new picture or black video configured
if (decoder->Closing < -300 || (VideoShowBlackPicture
&& decoder->Closing)) {
// clear ring buffer to trigger black picture
atomic_set(&decoder->SurfacesFilled, 0);
// some time no new picture or black video configured
if (decoder->Closing < -300 || (VideoShowBlackPicture
&& decoder->Closing)) {
// clear ring buffer to trigger black picture
atomic_set(&decoder->SurfacesFilled, 0);
}
}
// is it not possible, to advance the surface and/or the field? don't warn if radio
if (decoder->SurfaceField && atomic_read(&decoder->SurfacesFilled) < 1 + 2 * decoder->Interlaced && SoftIsPlayingVideo) {
++decoder->FramesDuped;
// FIXME: don't warn after stream start, don't warn during pause
err =
NVdecMessage(3,
_("video: decoder buffer empty, "
"duping frame (%d/%d) %d v-buf closing %d\n"), decoder->FramesDuped,
decoder->FrameCounter, VideoGetBuffers(decoder->Stream), decoder->Closing);
goto out;
}

Expand Down Expand Up @@ -19628,7 +19629,7 @@ static void CpuSyncDecoder(CpuDecoder * decoder)
goto skip_sync;
}

EnoughVideo = (VideoGetBuffers(decoder->Stream) >= (VideoResolution == VideoResolution576i && VideoSoftStartSync == 3 ? VideoStartThreshold_SD : 0)); // accurate SD
EnoughVideo = (VideoGetBuffers(decoder->Stream) >= (VideoResolution == VideoResolution576i ? VideoStartThreshold_SD : VideoStartThreshold_HD) * (VideoSoftStartSync == 3)); // accurate switch
if (!EnoughVideo && EnoughAudio && !AudioRunning && decoder->StartCounter > 200) {
Debug (3,"video: force enough video\n");
EnoughVideo = 1;
Expand Down Expand Up @@ -19726,7 +19727,7 @@ static void CpuSyncDecoder(CpuDecoder * decoder)
++decoder->FramesDropped;
CpuAdvanceDecoderFrame(decoder);
decoder->SyncCounter = 2;
} else if (diff < lower_limit * 90 && atomic_read(&decoder->SurfacesFilled) <= 1 + decoder->Interlaced && !IsReplay()) { //if double advance video not possible, delay audio
} else if (diff < lower_limit * 90 && atomic_read(&decoder->SurfacesFilled) <= 1 + decoder->Interlaced && !IsReplay()) { // if double advance video not possible, delay audio
err = CpuMessage(3, "video: speed up audio, delay audio\n");
AudioDelayms(-diff / 90 + 55);
}
Expand All @@ -19747,22 +19748,22 @@ static void CpuSyncDecoder(CpuDecoder * decoder)
skip_sync:
// trigger black picture?
if (decoder->SurfaceField && atomic_read(&decoder->SurfacesFilled) < 1 + 2 * decoder->Interlaced + 1 * !IsReplay()) {
// is it not possible, to advance the surface and/or the field?
if (decoder->SurfaceField && atomic_read(&decoder->SurfacesFilled) < 1 + 2 * decoder->Interlaced) {
++decoder->FramesDuped;
// FIXME: don't warn after stream start, don't warn during pause
err =
CpuMessage(3,
_("video: decoder buffer empty, "
"duping frame (%d/%d) %d v-buf closing %d\n"), decoder->FramesDuped,
decoder->FrameCounter, VideoGetBuffers(decoder->Stream), decoder->Closing);
}
// some time no new picture or black video configured
if (decoder->Closing < -300 || (VideoShowBlackPicture
&& decoder->Closing)) {
// clear ring buffer to trigger black picture
atomic_set(&decoder->SurfacesFilled, 0);
// some time no new picture or black video configured
if (decoder->Closing < -300 || (VideoShowBlackPicture
&& decoder->Closing)) {
// clear ring buffer to trigger black picture
atomic_set(&decoder->SurfacesFilled, 0);
}
}
// is it not possible, to advance the surface and/or the field? don't warn if radio
if (decoder->SurfaceField && atomic_read(&decoder->SurfacesFilled) < 1 + 2 * decoder->Interlaced && SoftIsPlayingVideo) {
++decoder->FramesDuped;
// FIXME: don't warn after stream start, don't warn during pause
err =
CpuMessage(3,
_("video: decoder buffer empty, "
"duping frame (%d/%d) %d v-buf closing %d\n"), decoder->FramesDuped,
decoder->FrameCounter, VideoGetBuffers(decoder->Stream), decoder->Closing);
goto out;
}

Expand Down

0 comments on commit 97e825d

Please sign in to comment.