mirror of
https://projects.vdr-developer.org/git/vdr-plugin-softhddevice.git
synced 2023-10-10 19:16:51 +02:00
Support upsampling 3,5 to 8 channels.
Improve next ring buffer handling. Improve audio/video sync debug.
This commit is contained in:
parent
d5e111238d
commit
7ed6975330
39
audio.c
39
audio.c
@ -546,6 +546,13 @@ static void AudioUpmix(const int16_t * in, int in_chan, int frames,
|
|||||||
/**
|
/**
|
||||||
** Resample ffmpeg sample format to hardware format.
|
** Resample ffmpeg sample format to hardware format.
|
||||||
**
|
**
|
||||||
|
** FIXME: use libswresample for this and move it to codec.
|
||||||
|
** FIXME: ffmpeg to alsa conversion is already done in codec.c.
|
||||||
|
**
|
||||||
|
** ffmpeg L R C Ls Rs -> alsa L R Ls Rs C
|
||||||
|
** ffmpeg L R C LFE Ls Rs -> alsa L R Ls Rs C LFE
|
||||||
|
** ffmpeg L R C LFE Ls Rs Rl Rr -> alsa L R Ls Rs C LFE Rl Rr
|
||||||
|
**
|
||||||
** @param in input sample buffer
|
** @param in input sample buffer
|
||||||
** @param in_chan nr. of input channels
|
** @param in_chan nr. of input channels
|
||||||
** @param frames number of frames in sample buffer
|
** @param frames number of frames in sample buffer
|
||||||
@ -581,6 +588,9 @@ static void AudioResample(const int16_t * in, int in_chan, int frames,
|
|||||||
AudioSurround2Stereo(in, in_chan, frames, out);
|
AudioSurround2Stereo(in, in_chan, frames, out);
|
||||||
break;
|
break;
|
||||||
case 5 * 8 + 6:
|
case 5 * 8 + 6:
|
||||||
|
case 3 * 8 + 8:
|
||||||
|
case 5 * 8 + 8:
|
||||||
|
case 6 * 8 + 8:
|
||||||
AudioUpmix(in, in_chan, frames, out, out_chan);
|
AudioUpmix(in, in_chan, frames, out, out_chan);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -1956,6 +1966,7 @@ static int AudioNextRing(void)
|
|||||||
int use_ac3;
|
int use_ac3;
|
||||||
int sample_rate;
|
int sample_rate;
|
||||||
int channels;
|
int channels;
|
||||||
|
size_t used;
|
||||||
|
|
||||||
// update audio format
|
// update audio format
|
||||||
// not always needed, but check if needed is too complex
|
// not always needed, but check if needed is too complex
|
||||||
@ -1975,12 +1986,18 @@ static int AudioNextRing(void)
|
|||||||
AudioResetCompressor();
|
AudioResetCompressor();
|
||||||
AudioResetNormalizer();
|
AudioResetNormalizer();
|
||||||
|
|
||||||
|
Debug(3, "audio: a/v next buf(%d,%4zdms)\n", atomic_read(&AudioRingFilled),
|
||||||
|
(RingBufferUsedBytes(AudioRing[AudioRingRead].RingBuffer) * 1000)
|
||||||
|
/ (AudioRing[AudioRingWrite].HwSampleRate *
|
||||||
|
AudioRing[AudioRingWrite].HwChannels * AudioBytesProSample));
|
||||||
|
|
||||||
// stop, if not enough in next buffer
|
// stop, if not enough in next buffer
|
||||||
if (AudioStartThreshold >=
|
used = RingBufferUsedBytes(AudioRing[AudioRingRead].RingBuffer);
|
||||||
RingBufferUsedBytes(AudioRing[AudioRingRead].RingBuffer)) {
|
if (AudioStartThreshold * 4 < used || (AudioVideoIsReady
|
||||||
return 1;
|
&& AudioStartThreshold < used)) {
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2029,10 +2046,13 @@ static void *AudioPlayHandlerThread(void *dummy)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (flush) {
|
if (flush) {
|
||||||
|
Debug(3, "audio: flush\n");
|
||||||
AudioUsedModule->FlushBuffers();
|
AudioUsedModule->FlushBuffers();
|
||||||
if (AudioNextRing()) {
|
if (AudioNextRing()) {
|
||||||
|
Debug(3, "audio: break after flush\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
Debug(3, "audio: continue after flush\n");
|
||||||
}
|
}
|
||||||
// try to play some samples
|
// try to play some samples
|
||||||
err = AudioUsedModule->Thread();
|
err = AudioUsedModule->Thread();
|
||||||
@ -2275,11 +2295,12 @@ void AudioVideoReady(int64_t pts)
|
|||||||
(used * 90 * 1000) / (AudioRing[AudioRingWrite].HwSampleRate *
|
(used * 90 * 1000) / (AudioRing[AudioRingWrite].HwSampleRate *
|
||||||
AudioRing[AudioRingWrite].HwChannels * AudioBytesProSample);
|
AudioRing[AudioRingWrite].HwChannels * AudioBytesProSample);
|
||||||
|
|
||||||
Debug(3, "audio: a/v buf:%4zdms %s|%s = %dms video ready\n",
|
Debug(3, "audio: a/v sync buf(%d,%4zdms) %s|%s = %dms %s\n",
|
||||||
|
atomic_read(&AudioRingFilled),
|
||||||
(used * 1000) / (AudioRing[AudioRingWrite].HwSampleRate *
|
(used * 1000) / (AudioRing[AudioRingWrite].HwSampleRate *
|
||||||
AudioRing[AudioRingWrite].HwChannels * AudioBytesProSample),
|
AudioRing[AudioRingWrite].HwChannels * AudioBytesProSample),
|
||||||
Timestamp2String(audio_pts), Timestamp2String(pts),
|
Timestamp2String(pts), Timestamp2String(audio_pts),
|
||||||
(int)(pts - audio_pts) / 90);
|
(int)(pts - audio_pts) / 90, AudioRunning ? "running" : "ready");
|
||||||
|
|
||||||
if (!AudioRunning) {
|
if (!AudioRunning) {
|
||||||
int skip;
|
int skip;
|
||||||
@ -2290,7 +2311,7 @@ void AudioVideoReady(int64_t pts)
|
|||||||
pts - 15 * 20 * 90 - AudioBufferTime * 90 - audio_pts +
|
pts - 15 * 20 * 90 - AudioBufferTime * 90 - audio_pts +
|
||||||
VideoAudioDelay;
|
VideoAudioDelay;
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf("%dms %dms %dms\n", (int)(pts - audio_pts) / 90,
|
fprintf(stderr, "%dms %dms %dms\n", (int)(pts - audio_pts) / 90,
|
||||||
VideoAudioDelay / 90, skip / 90);
|
VideoAudioDelay / 90, skip / 90);
|
||||||
#endif
|
#endif
|
||||||
// guard against old PTS
|
// guard against old PTS
|
||||||
@ -2303,7 +2324,7 @@ void AudioVideoReady(int64_t pts)
|
|||||||
AudioSkip = skip - used;
|
AudioSkip = skip - used;
|
||||||
skip = used;
|
skip = used;
|
||||||
}
|
}
|
||||||
Debug(3, "audio: advance %dms %d/%zd\n",
|
Debug(3, "audio: sync advance %dms %d/%zd\n",
|
||||||
(skip * 1000) / (AudioRing[AudioRingWrite].HwSampleRate *
|
(skip * 1000) / (AudioRing[AudioRingWrite].HwSampleRate *
|
||||||
AudioRing[AudioRingWrite].HwChannels *
|
AudioRing[AudioRingWrite].HwChannels *
|
||||||
AudioBytesProSample), skip, used);
|
AudioBytesProSample), skip, used);
|
||||||
|
Loading…
Reference in New Issue
Block a user