summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohns <johns98@gmx.net>2012-02-07 17:08:59 +0100
committerJohns <johns98@gmx.net>2012-02-07 17:08:59 +0100
commit09cf1f5c858207b0fdb7c50435d4b15edf132470 (patch)
treeb0dc1a5524b3921787f5b280daf4198e8b08e247
parent947f6b312e6cabde44a0bef7ae593fe016b409a5 (diff)
downloadvdr-plugin-softhddevice-09cf1f5c858207b0fdb7c50435d4b15edf132470.tar.gz
vdr-plugin-softhddevice-09cf1f5c858207b0fdb7c50435d4b15edf132470.tar.bz2
Fix bug: alsa+ffmpeg use different channel layout.
-rw-r--r--ChangeLog1
-rw-r--r--codec.c62
2 files changed, 63 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index 89cc3d2..6ce31ea 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,7 @@
User johns
Date:
+ Fix bug: alsa and ffmpeg use different channel layout.
Support more LPCM sample rates and number of channels.
Quick&dirty support for mpeg LPCM streams.
Workaround for text2skin undrawn OSD areas.
diff --git a/codec.c b/codec.c
index 9f4c976..a514a33 100644
--- a/codec.c
+++ b/codec.c
@@ -739,6 +739,62 @@ void CodecSetAudioPassthrough(int mask)
(void)mask;
}
+/**
+** Reorder audio frame.
+**
+** 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
+*/
+static void CodecReorderAudioFrame(int16_t * buf, int size, int channels)
+{
+ int i;
+ int c;
+ int ls;
+ int rs;
+ int lfe;
+
+ switch (channels) {
+ case 5:
+ size /= 2;
+ for (i = 0; i < size; i += 5) {
+ c = buf[i + 2];
+ ls = buf[i + 3];
+ rs = buf[i + 4];
+ buf[i + 2] = ls;
+ buf[i + 3] = rs;
+ buf[i + 4] = c;
+ }
+ break;
+ case 6:
+ size /= 2;
+ for (i = 0; i < size; i += 6) {
+ c = buf[i + 2];
+ ls = buf[i + 3];
+ rs = buf[i + 4];
+ lfe = buf[i + 5];
+ buf[i + 2] = ls;
+ buf[i + 3] = rs;
+ buf[i + 4] = c;
+ buf[i + 5] = lfe;
+ }
+ break;
+ case 8:
+ size /= 2;
+ for (i = 0; i < size; i += 8) {
+ c = buf[i + 2];
+ ls = buf[i + 3];
+ rs = buf[i + 4];
+ lfe = buf[i + 5];
+ buf[i + 2] = ls;
+ buf[i + 3] = rs;
+ buf[i + 4] = c;
+ buf[i + 5] = lfe;
+ }
+ break;
+ }
+}
+
#ifdef USE_AVPARSER
/**
@@ -817,6 +873,8 @@ void CodecAudioDecode(AudioDecoder * audio_decoder, const AVPacket * avpkt)
int err;
int isAC3;
+ // FIXME: use swr_convert from swresample
+ // FIXME: tell ac3 decoder to use downmix
if (audio_decoder->ReSample) {
audio_resample_close(audio_decoder->ReSample);
audio_decoder->ReSample = NULL;
@@ -893,6 +951,8 @@ void CodecAudioDecode(AudioDecoder * audio_decoder, const AVPacket * avpkt)
audio_decoder->HwChannels *
av_get_bytes_per_sample(audio_ctx->sample_fmt);
Debug(4, "codec/audio: %d -> %d\n", buf_sz, outlen);
+ CodecReorderAudioFrame(outbuf, outlen,
+ audio_decoder->HwChannels);
AudioEnqueue(outbuf, outlen);
}
} else {
@@ -971,6 +1031,8 @@ void CodecAudioDecode(AudioDecoder * audio_decoder, const AVPacket * avpkt)
// True HD?
#endif
#endif
+ CodecReorderAudioFrame(buf, buf_sz,
+ audio_decoder->HwChannels);
AudioEnqueue(buf, buf_sz);
}
}