comparison libmpcodecs/ad_dvdpcm.c @ 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 97a6f049c9f8
children e0d400094e88
comparison
equal deleted inserted replaced
13594:acfe017b6195 13595:f67d20c01332
1 #include <stdio.h> 1 #include <stdio.h>
2 #include <stdlib.h> 2 #include <stdlib.h>
3 #include <unistd.h> 3 #include <unistd.h>
4 4
5 #include "config.h" 5 #include "config.h"
6 #include "mp_msg.h"
7 #include "help_mp.h"
6 #include "ad_internal.h" 8 #include "ad_internal.h"
7 #include "../libaf/af_format.h" 9 #include "../libaf/af_format.h"
8 10
9 static ad_info_t info = 11 static ad_info_t info =
10 { 12 {
18 LIBAD_EXTERN(dvdpcm) 20 LIBAD_EXTERN(dvdpcm)
19 21
20 static int init(sh_audio_t *sh) 22 static int init(sh_audio_t *sh)
21 { 23 {
22 /* DVD PCM Audio:*/ 24 /* DVD PCM Audio:*/
25 sh->i_bps = 0;
23 if(sh->codecdata_len==3){ 26 if(sh->codecdata_len==3){
24 // we have LPCM header: 27 // we have LPCM header:
25 unsigned char h=sh->codecdata[1]; 28 unsigned char h=sh->codecdata[1];
26 sh->channels=1+(h&7); 29 sh->channels=1+(h&7);
27 switch((h>>4)&3){ 30 switch((h>>4)&3){
33 switch ((h >> 6) & 3) { 36 switch ((h >> 6) & 3) {
34 case 0: 37 case 0:
35 sh->sample_format = AFMT_S16_BE; 38 sh->sample_format = AFMT_S16_BE;
36 sh->samplesize = 2; 39 sh->samplesize = 2;
37 break; 40 break;
41 case 1:
42 mp_msg(MSGT_DECAUDIO, MSGL_INFO, MSGTR_SamplesWanted);
43 sh->i_bps = sh->channels * sh->samplerate * 5 / 2;
38 case 2: 44 case 2:
39 sh->sample_format = AFMT_AF_FLAGS | AF_FORMAT_I | 45 sh->sample_format = AFMT_AF_FLAGS | AF_FORMAT_I |
40 AF_FORMAT_BE | AF_FORMAT_US; 46 AF_FORMAT_BE | AF_FORMAT_US;
41 sh->samplesize = 3; 47 sh->samplesize = 3;
42 break; 48 break;
49 sh->channels=2; 55 sh->channels=2;
50 sh->samplerate=48000; 56 sh->samplerate=48000;
51 sh->sample_format = AFMT_S16_BE; 57 sh->sample_format = AFMT_S16_BE;
52 sh->samplesize = 2; 58 sh->samplesize = 2;
53 } 59 }
60 if (!sh->i_bps)
54 sh->i_bps = sh->samplesize * sh->channels * sh->samplerate; 61 sh->i_bps = sh->samplesize * sh->channels * sh->samplerate;
55 return 1; 62 return 1;
56 } 63 }
57 64
58 static int preinit(sh_audio_t *sh) 65 static int preinit(sh_audio_t *sh)
80 } 87 }
81 88
82 static int decode_audio(sh_audio_t *sh_audio,unsigned char *buf,int minlen,int maxlen) 89 static int decode_audio(sh_audio_t *sh_audio,unsigned char *buf,int minlen,int maxlen)
83 { 90 {
84 int j,len; 91 int j,len;
92 if (sh_audio->samplesize == 3) {
93 if (((sh_audio->codecdata[1] >> 6) & 3) == 1) {
94 // 20 bit
95 // not sure if the "& 0xf0" and "<< 4" are the right way around
96 // can somebody clarify?
97 for (j = 0; j < minlen; j += 12) {
98 char tmp[10];
99 len = demux_read_data(sh_audio->ds, tmp, 10);
100 if (len < 10) break;
101 // first sample
102 buf[j + 0] = tmp[0];
103 buf[j + 1] = tmp[1];
104 buf[j + 2] = tmp[8] & 0xf0;
105 // second sample
106 buf[j + 3] = tmp[2];
107 buf[j + 4] = tmp[3];
108 buf[j + 5] = tmp[8] << 4;
109 // third sample
110 buf[j + 6] = tmp[4];
111 buf[j + 7] = tmp[5];
112 buf[j + 8] = tmp[9] & 0xf0;
113 // fourth sample
114 buf[j + 9] = tmp[6];
115 buf[j + 10] = tmp[7];
116 buf[j + 11] = tmp[9] << 4;
117 }
118 len = j;
119 } else {
120 // 24 bit
121 for (j = 0; j < minlen; j += 12) {
122 char tmp[12];
123 len = demux_read_data(sh_audio->ds, tmp, 12);
124 if (len < 12) break;
125 // first sample
126 buf[j + 0] = tmp[0];
127 buf[j + 1] = tmp[1];
128 buf[j + 2] = tmp[8];
129 // second sample
130 buf[j + 3] = tmp[2];
131 buf[j + 4] = tmp[3];
132 buf[j + 5] = tmp[9];
133 // third sample
134 buf[j + 6] = tmp[4];
135 buf[j + 7] = tmp[5];
136 buf[j + 8] = tmp[10];
137 // fourth sample
138 buf[j + 9] = tmp[6];
139 buf[j + 10] = tmp[7];
140 buf[j + 11] = tmp[11];
141 }
142 len = j;
143 }
144 } else
85 len=demux_read_data(sh_audio->ds,buf,(minlen+3)&(~3)); 145 len=demux_read_data(sh_audio->ds,buf,(minlen+3)&(~3));
86 return len; 146 return len;
87 } 147 }