Support upsampling 3,5 to 8 channels.

Improve next ring buffer handling.
Improve audio/video sync debug.
This commit is contained in:
Johns 2013-01-25 17:05:53 +01:00
parent d5e111238d
commit 7ed6975330
1 changed files with 30 additions and 9 deletions

39
audio.c
View File

@ -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);