diff --git a/audio.c b/audio.c index 165483f..cd1f9cf 100644 --- a/audio.c +++ b/audio.c @@ -105,20 +105,20 @@ typedef struct _audio_module_ { const char *Name; ///< audio output module name - void (*Thread) (void); ///< module thread handler - void (*Enqueue) (const void *, int); ///< enqueue samples for output - void (*VideoReady) (void); ///< video ready, start audio - void (*FlushBuffers) (void); ///< flush sample buffers - void (*Poller) (void); ///< output poller - int (*FreeBytes) (void); ///< number of bytes free in buffer - int (*UsedBytes) (void); ///< number of bytes used in buffer - uint64_t(*GetDelay) (void); ///< get current audio delay - void (*SetVolume) (int); ///< set output volume - int (*Setup) (int *, int *, int); ///< setup channels, samplerate - void (*Play) (void); ///< play - void (*Pause) (void); ///< pause - void (*Init) (void); ///< initialize audio output module - void (*Exit) (void); ///< cleanup audio output module + void (*const Thread) (void); ///< module thread handler + void (*const Enqueue) (const void *, int); ///< enqueue samples for output + void (*const VideoReady) (void); ///< video ready, start audio + void (*const FlushBuffers) (void); ///< flush sample buffers + void (*const Poller) (void); ///< output poller + int (*const FreeBytes) (void); ///< number of bytes free in buffer + int (*const UsedBytes) (void); ///< number of bytes used in buffer + int64_t(*const GetDelay) (void); ///< get current audio delay + void (*const SetVolume) (int); ///< set output volume + int (*const Setup) (int *, int *, int); ///< setup channels, samplerate + void (*const Play) (void); ///< play + void (*const Pause) (void); ///< pause + void (*const Init) (void); ///< initialize audio output module + void (*const Exit) (void); ///< cleanup audio output module } AudioModule; static const AudioModule NoopModule; ///< forward definition of noop module @@ -912,17 +912,17 @@ static void AlsaInitMixer(void) ** ** @todo FIXME: handle the case no audio running */ -static uint64_t AlsaGetDelay(void) +static int64_t AlsaGetDelay(void) { int err; snd_pcm_sframes_t delay; - uint64_t pts; + int64_t pts; if (!AlsaPCMHandle || !AudioSampleRate) { - return 0UL; + return 0L; } if (!AudioRunning) { // audio not running - return 0UL; + return 0L; } // FIXME: thread safe? __assert_fail_base in snd_pcm_delay @@ -940,8 +940,8 @@ static uint64_t AlsaGetDelay(void) delay = 0L; } - pts = ((uint64_t) delay * 90 * 1000) / AudioSampleRate; - pts += ((uint64_t) RingBufferUsedBytes(AlsaRingBuffer) * 90 * 1000) + pts = ((int64_t) delay * 90 * 1000) / AudioSampleRate; + pts += ((int64_t) RingBufferUsedBytes(AlsaRingBuffer) * 90 * 1000) / (AudioSampleRate * AudioChannels * AudioBytesProSample); Debug(4, "audio/alsa: hw+sw delay %zd %" PRId64 " ms\n", RingBufferUsedBytes(AlsaRingBuffer), pts / 90); @@ -1732,16 +1732,16 @@ static void OssInitMixer(void) ** ** @returns audio delay in time stamps. */ -static uint64_t OssGetDelay(void) +static int64_t OssGetDelay(void) { int delay; - uint64_t pts; + int64_t pts; if (OssPcmFildes == -1) { // setup failure - return 0UL; + return 0L; } if (!AudioRunning) { // audio not running - return 0UL; + return 0L; } // delay in bytes in kernel buffers delay = -1; @@ -1754,7 +1754,7 @@ static uint64_t OssGetDelay(void) delay = 0; } - pts = ((uint64_t) (delay + RingBufferUsedBytes(OssRingBuffer)) * 90 * 1000) + pts = ((int64_t) (delay + RingBufferUsedBytes(OssRingBuffer)) * 90 * 1000) / (AudioSampleRate * AudioChannels * AudioBytesProSample); Debug(4, "audio/oss: hw+sw delay %zd %" PRId64 " ms\n", RingBufferUsedBytes(OssRingBuffer), pts / 90); @@ -2003,9 +2003,9 @@ static int NoopUsedBytes(void) ** ** @returns audio delay in time stamps. */ -static uint64_t NoopGetDelay(void) +static int64_t NoopGetDelay(void) { - return 0UL; + return 0L; } /** @@ -2080,9 +2080,8 @@ static void *AudioPlayHandlerThread(void *dummy) // cond_wait can return, without signal! } while (!AudioRunning); - Debug(3, "audio: ----> %d ms\n", (AudioUsedBytes() * 1000) - / (!AudioSampleRate - || !AudioChannels + + Debug(3, "audio: ----> %d ms start\n", (AudioUsedBytes() * 1000) + / (!AudioSampleRate + !AudioChannels + AudioSampleRate * AudioChannels * AudioBytesProSample)); pthread_mutex_unlock(&AudioMutex); @@ -2118,7 +2117,6 @@ static void *AudioPlayHandlerThread(void *dummy) } #endif - Debug(3, "audio: play start\n"); AudioUsedModule->Thread(); } @@ -2192,7 +2190,7 @@ void AudioEnqueue(const void *samples, int count) static uint32_t last; static uint32_t tick; static uint32_t max = 101; - uint64_t delay; + int64_t delay; delay = AudioGetDelay(); tick = GetMsTicks(); @@ -2208,7 +2206,7 @@ void AudioEnqueue(const void *samples, int count) // Update audio clock (stupid gcc developers thinks INT64_C is unsigned) if (AudioPTS != (int64_t) INT64_C(0x8000000000000000)) { AudioPTS += - ((int64_t) count * 90000) / (AudioSampleRate * AudioChannels * + ((int64_t) count * 90 * 1000) / (AudioSampleRate * AudioChannels * AudioBytesProSample); } } @@ -2259,7 +2257,7 @@ int AudioUsedBytes(void) ** ** @returns audio delay in time stamps. */ -uint64_t AudioGetDelay(void) +int64_t AudioGetDelay(void) { return AudioUsedModule->GetDelay(); } @@ -2275,7 +2273,6 @@ void AudioSetClock(int64_t pts) if (AudioPTS != pts) { Debug(4, "audio: set clock to %#012" PRIx64 " %#012" PRIx64 " pts\n", AudioPTS, pts); - } #endif AudioPTS = pts; diff --git a/audio.h b/audio.h index 94ac55a..2393b6f 100644 --- a/audio.h +++ b/audio.h @@ -32,7 +32,7 @@ extern void AudioFlushBuffers(void); ///< flush audio buffers extern void AudioPoller(void); ///< poll audio events/handling extern int AudioFreeBytes(void); ///< free bytes in audio output extern int AudioUsedBytes(void); ///< used bytes in audio output -extern uint64_t AudioGetDelay(void); ///< get current audio delay +extern int64_t AudioGetDelay(void); ///< get current audio delay extern void AudioSetClock(int64_t); ///< set audio clock base extern int64_t AudioGetClock(); ///< get current audio clock extern void AudioSetVolume(int); ///< set volume diff --git a/video.c b/video.c index a7ffe87..a0afa58 100644 --- a/video.c +++ b/video.c @@ -543,9 +543,9 @@ static void VideoUpdateOutput(AVRational input_aspect_ratio, int input_width, /// /// Reduce output. /// -static void VideoMessage(void) -{ -} +//static void VideoMessage(const char *message) +//{ +//} //---------------------------------------------------------------------------- // GLX @@ -1723,6 +1723,8 @@ static VaapiDecoder *VaapiNewHwDecoder(void) decoder->OutputWidth = VideoWindowWidth; decoder->OutputHeight = VideoWindowHeight; + decoder->PTS = AV_NOPTS_VALUE; + // get/put still not working //decoder->GetPutImage = !VaapiBuggyIntel || VaapiNewIntel; decoder->GetPutImage = !VaapiBuggyIntel; @@ -4345,10 +4347,12 @@ static void VaapiDisplayFrame(void) /// static void VaapiSyncDisplayFrame(VaapiDecoder * decoder) { + int err; int filled; int64_t audio_clock; int64_t video_clock; + err = 0; if (Video60HzMode && !(decoder->FramesDisplayed % 6)) { // FIXME: drop next frame? decoder->DupNextFrame++; @@ -4372,6 +4376,7 @@ static void VaapiSyncDisplayFrame(VaapiDecoder * decoder) || video_clock > audio_clock + VideoAudioDelay + 120 * 90)) { Debug(3, "video: initial slow down %d\n", decoder->StartCounter); decoder->DupNextFrame = 2; + err = 1; } if (decoder->DupNextFrame) { @@ -4383,22 +4388,25 @@ static void VaapiSyncDisplayFrame(VaapiDecoder * decoder) if (abs(video_clock - audio_clock) > 5000 * 90) { Debug(3, "video: pts difference too big\n"); + err = 1; } else if (video_clock > audio_clock + VideoAudioDelay + 100 * 90) { Debug(3, "video: slow down video\n"); + err = 1; decoder->DupNextFrame += 2; } else if (video_clock > audio_clock + VideoAudioDelay + 45 * 90) { Debug(3, "video: slow down video\n"); + err = 1; decoder->DupNextFrame++; } else if (audio_clock + VideoAudioDelay > video_clock + 15 * 90 && filled > 1) { Debug(3, "video: speed up video\n"); + err = 1; decoder->DropNextFrame = 1; } } #if defined(DEBUG) || defined(AV_INFO) // debug audio/video sync - if (decoder->DupNextFrame || decoder->DropNextFrame - || !(decoder->FramesDisplayed % AV_INFO_TIME)) { + if (err || !(decoder->FramesDisplayed % AV_INFO_TIME)) { Info("video: %s%+5" PRId64 " %4" PRId64 " %3d/\\ms %3d v-buf\n", Timestamp2String(video_clock), abs((video_clock - audio_clock) / 90) < @@ -7411,10 +7419,12 @@ static void VdpauDisplayFrame(void) /// static void VdpauSyncDisplayFrame(VdpauDecoder * decoder) { + int err; int filled; int64_t audio_clock; int64_t video_clock; + err = 0; if (Video60HzMode && !(decoder->FramesDisplayed % 6)) { // FIXME: drop next frame? decoder->DupNextFrame++; @@ -7437,6 +7447,7 @@ static void VdpauSyncDisplayFrame(VdpauDecoder * decoder) && (audio_clock == (int64_t) AV_NOPTS_VALUE || video_clock > audio_clock + VideoAudioDelay + 120 * 90)) { Debug(3, "video: initial slow down %d\n", decoder->StartCounter); + err = 1; decoder->DupNextFrame = 2; } @@ -7449,22 +7460,25 @@ static void VdpauSyncDisplayFrame(VdpauDecoder * decoder) if (abs(video_clock - audio_clock) > 5000 * 90) { Debug(3, "video: pts difference too big\n"); + err = 1; } else if (video_clock > audio_clock + VideoAudioDelay + 100 * 90) { Debug(3, "video: slow down video\n"); + err = 1; decoder->DupNextFrame += 2; } else if (video_clock > audio_clock + VideoAudioDelay + 45 * 90) { Debug(3, "video: slow down video\n"); + err = 1; decoder->DupNextFrame++; } else if (audio_clock + VideoAudioDelay > video_clock + 15 * 90 && filled > 1 + 2 * decoder->Interlaced) { Debug(3, "video: speed up video\n"); + err = 1; decoder->DropNextFrame = 1; } } #if defined(DEBUG) || defined(AV_INFO) // debug audio/video sync - if (decoder->DupNextFrame || decoder->DropNextFrame - || !(decoder->FramesDisplayed % AV_INFO_TIME)) { + if (err || !(decoder->FramesDisplayed % AV_INFO_TIME)) { Info("video: %s%+5" PRId64 " %4" PRId64 " %3d/\\ms %3d v-buf\n", Timestamp2String(video_clock), abs((video_clock - audio_clock) / 90) < @@ -7486,7 +7500,8 @@ static void VdpauSyncRenderFrame(VdpauDecoder * decoder, { // FIXME: temp debug if (0 && frame->pkt_pts != (int64_t) AV_NOPTS_VALUE) { - Info("render frame pts %s\n", Timestamp2String(frame->pkt_pts)); + Debug(3, "video: render frame pts %s\n", + Timestamp2String(frame->pkt_pts)); } VideoSetPts(&decoder->PTS, decoder->Interlaced, frame); @@ -9699,9 +9714,9 @@ void VideoExit(void) int SysLogLevel; ///< show additional debug informations uint32_t VideoSwitch; ///< required -uint64_t AudioGetDelay(void) ///< required +int64_t AudioGetDelay(void) ///< required { - return 0UL; + return 0L; } int64_t AudioGetClock(void) ///< required