summaryrefslogtreecommitdiffstats
path: root/libmpcodecs
diff options
context:
space:
mode:
authorreimar <reimar@b3059339-0415-0410-9bf9-f77b7e298cf2>2004-10-09 20:04:27 +0000
committerreimar <reimar@b3059339-0415-0410-9bf9-f77b7e298cf2>2004-10-09 20:04:27 +0000
commit018dcd7451380e7e1f1d088e167238ccd44eb176 (patch)
tree31c08456d8adf273606ef508abc2e9c424846d50 /libmpcodecs
parentfd60a3de4b7b713bab6fbbd915ea05f87c2e628e (diff)
downloadmpv-018dcd7451380e7e1f1d088e167238ccd44eb176.tar.bz2
mpv-018dcd7451380e7e1f1d088e167238ccd44eb176.tar.xz
Support for 24 bit and 20 bit LPCM (simple and slow :-( )
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@13596 b3059339-0415-0410-9bf9-f77b7e298cf2
Diffstat (limited to 'libmpcodecs')
-rw-r--r--libmpcodecs/ad_dvdpcm.c60
1 files changed, 60 insertions, 0 deletions
diff --git a/libmpcodecs/ad_dvdpcm.c b/libmpcodecs/ad_dvdpcm.c
index 918dd26bbb..b05d35e0d8 100644
--- a/libmpcodecs/ad_dvdpcm.c
+++ b/libmpcodecs/ad_dvdpcm.c
@@ -3,6 +3,8 @@
#include <unistd.h>
#include "config.h"
+#include "mp_msg.h"
+#include "help_mp.h"
#include "ad_internal.h"
#include "../libaf/af_format.h"
@@ -20,6 +22,7 @@ LIBAD_EXTERN(dvdpcm)
static int init(sh_audio_t *sh)
{
/* DVD PCM Audio:*/
+ sh->i_bps = 0;
if(sh->codecdata_len==3){
// we have LPCM header:
unsigned char h=sh->codecdata[1];
@@ -35,6 +38,9 @@ static int init(sh_audio_t *sh)
sh->sample_format = AFMT_S16_BE;
sh->samplesize = 2;
break;
+ case 1:
+ mp_msg(MSGT_DECAUDIO, MSGL_INFO, MSGTR_SamplesWanted);
+ sh->i_bps = sh->channels * sh->samplerate * 5 / 2;
case 2:
sh->sample_format = AFMT_AF_FLAGS | AF_FORMAT_I |
AF_FORMAT_BE | AF_FORMAT_US;
@@ -51,6 +57,7 @@ static int init(sh_audio_t *sh)
sh->sample_format = AFMT_S16_BE;
sh->samplesize = 2;
}
+ if (!sh->i_bps)
sh->i_bps = sh->samplesize * sh->channels * sh->samplerate;
return 1;
}
@@ -82,6 +89,59 @@ static int control(sh_audio_t *sh,int cmd,void* arg, ...)
static int decode_audio(sh_audio_t *sh_audio,unsigned char *buf,int minlen,int maxlen)
{
int j,len;
+ if (sh_audio->samplesize == 3) {
+ if (((sh_audio->codecdata[1] >> 6) & 3) == 1) {
+ // 20 bit
+ // not sure if the "& 0xf0" and "<< 4" are the right way around
+ // can somebody clarify?
+ for (j = 0; j < minlen; j += 12) {
+ char tmp[10];
+ len = demux_read_data(sh_audio->ds, tmp, 10);
+ if (len < 10) break;
+ // first sample
+ buf[j + 0] = tmp[0];
+ buf[j + 1] = tmp[1];
+ buf[j + 2] = tmp[8] & 0xf0;
+ // second sample
+ buf[j + 3] = tmp[2];
+ buf[j + 4] = tmp[3];
+ buf[j + 5] = tmp[8] << 4;
+ // third sample
+ buf[j + 6] = tmp[4];
+ buf[j + 7] = tmp[5];
+ buf[j + 8] = tmp[9] & 0xf0;
+ // fourth sample
+ buf[j + 9] = tmp[6];
+ buf[j + 10] = tmp[7];
+ buf[j + 11] = tmp[9] << 4;
+ }
+ len = j;
+ } else {
+ // 24 bit
+ for (j = 0; j < minlen; j += 12) {
+ char tmp[12];
+ len = demux_read_data(sh_audio->ds, tmp, 12);
+ if (len < 12) break;
+ // first sample
+ buf[j + 0] = tmp[0];
+ buf[j + 1] = tmp[1];
+ buf[j + 2] = tmp[8];
+ // second sample
+ buf[j + 3] = tmp[2];
+ buf[j + 4] = tmp[3];
+ buf[j + 5] = tmp[9];
+ // third sample
+ buf[j + 6] = tmp[4];
+ buf[j + 7] = tmp[5];
+ buf[j + 8] = tmp[10];
+ // fourth sample
+ buf[j + 9] = tmp[6];
+ buf[j + 10] = tmp[7];
+ buf[j + 11] = tmp[11];
+ }
+ len = j;
+ }
+ } else
len=demux_read_data(sh_audio->ds,buf,(minlen+3)&(~3));
return len;
}