changeset 13595:f67d20c01332

Support for 24 bit and 20 bit LPCM (simple and slow :-( )
author reimar
date Sat, 09 Oct 2004 20:04:27 +0000
parents acfe017b6195
children 3a2e1e6ae834
files help/help_mp-en.h libmpcodecs/ad_dvdpcm.c
diffstat 2 files changed, 62 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/help/help_mp-en.h	Sat Oct 09 13:13:28 2004 +0000
+++ b/help/help_mp-en.h	Sat Oct 09 20:04:27 2004 +0000
@@ -53,6 +53,8 @@
 "\n";
 #endif
 
+#define MSGTR_SamplesWanted "Samples of this format are needed to improve support. Please contact the developers.\n"
+
 // ========================= MPlayer messages ===========================
 
 // mplayer.c:
--- a/libmpcodecs/ad_dvdpcm.c	Sat Oct 09 13:13:28 2004 +0000
+++ b/libmpcodecs/ad_dvdpcm.c	Sat Oct 09 20:04:27 2004 +0000
@@ -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 @@
 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 @@
 	    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 @@
 	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 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;
 }