2 * This file is part of MPlayer.
4 * MPlayer is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * MPlayer is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25 #include "libmpdemux/aviprint.h"
26 #include "loader/wineacm.h"
28 #include "ad_internal.h"
29 #include "osdep/timer.h"
31 static const ad_info_t info
=
47 static int init(sh_audio_t
*sh_audio
)
49 int ret
=decode_audio(sh_audio
,sh_audio
->a_buffer
,4096,sh_audio
->a_buffer_size
);
51 mp_msg(MSGT_DECAUDIO
,MSGL_INFO
,"ACM decoding error: %d\n",ret
);
54 sh_audio
->a_buffer_len
=ret
;
58 static int preinit(sh_audio_t
*sh_audio
)
61 WAVEFORMATEX
*in_fmt
= sh_audio
->wf
;
65 priv
= malloc(sizeof(acm_context_t
));
68 sh_audio
->context
= priv
;
70 mp_msg(MSGT_WIN32
, MSGL_V
, "======= Win32 (ACM) AUDIO Codec init =======\n");
72 // priv->handle = NULL;
74 priv
->o_wf
= malloc(sizeof(WAVEFORMATEX
));
77 mp_tmsg(MSGT_DECAUDIO
,MSGL_ERR
,"Could not load/initialize Win32/ACM audio codec (missing DLL file?).\n");
81 priv
->o_wf
->nChannels
= in_fmt
->nChannels
;
82 priv
->o_wf
->nSamplesPerSec
= in_fmt
->nSamplesPerSec
;
83 priv
->o_wf
->nAvgBytesPerSec
= 2*in_fmt
->nSamplesPerSec
*in_fmt
->nChannels
;
84 priv
->o_wf
->wFormatTag
= WAVE_FORMAT_PCM
;
85 priv
->o_wf
->nBlockAlign
= 2*in_fmt
->nChannels
;
86 priv
->o_wf
->wBitsPerSample
= 16;
87 // priv->o_wf->wBitsPerSample = inf_fmt->wBitsPerSample;
88 priv
->o_wf
->cbSize
= 0;
90 if ( mp_msg_test(MSGT_DECAUDIO
,MSGL_V
) )
92 mp_msg(MSGT_DECAUDIO
, MSGL_V
, "Input format:\n");
93 print_wave_header(in_fmt
, MSGL_V
);
94 mp_msg(MSGT_DECAUDIO
, MSGL_V
, "Output format:\n");
95 print_wave_header(priv
->o_wf
, MSGL_V
);
98 MSACM_RegisterDriver((const char *)sh_audio
->codec
->dll
, in_fmt
->wFormatTag
, 0);
99 ret
= acmStreamOpen(&priv
->handle
, (HACMDRIVER
)NULL
, in_fmt
,
100 priv
->o_wf
, NULL
, 0, 0, 0);
103 if (ret
== ACMERR_NOTPOSSIBLE
)
104 mp_msg(MSGT_WIN32
, MSGL_ERR
, "ACM_Decoder: Unappropriate audio format\n");
106 mp_msg(MSGT_WIN32
, MSGL_ERR
, "ACM_Decoder: acmStreamOpen error: %d\n",
108 mp_tmsg(MSGT_DECAUDIO
,MSGL_ERR
,"Could not load/initialize Win32/ACM audio codec (missing DLL file?).\n");
111 mp_msg(MSGT_WIN32
, MSGL_V
, "Audio codec opened OK! ;-)\n");
113 acmStreamSize(priv
->handle
, in_fmt
->nBlockAlign
, &srcsize
, ACM_STREAMSIZEF_SOURCE
);
114 //if ( mp_msg_test(MSGT_DECAUDIO,MSGL_V) ) printf("Audio ACM output buffer min. size: %ld (reported by codec)\n", srcsize);
116 //if (srcsize < MAX_OUTBURST) srcsize = MAX_OUTBURST;
119 mp_msg(MSGT_WIN32
, MSGL_WARN
, "Warning! ACM codec reports srcsize=0\n");
122 // limit srcsize to 4-16kb
123 //while(srcsize && srcsize<4096) srcsize*=2;
124 //while(srcsize>16384) srcsize/=2;
125 sh_audio
->audio_out_minsize
=srcsize
; // audio output min. size
126 mp_msg(MSGT_WIN32
,MSGL_V
,"Audio ACM output buffer min. size: %ld\n",srcsize
);
128 acmStreamSize(priv
->handle
, srcsize
, &srcsize
, ACM_STREAMSIZEF_DESTINATION
);
129 // if(srcsize<in_fmt->nBlockAlign) srcsize=in_fmt->nBlockAlign;
133 mp_msg(MSGT_WIN32
, MSGL_WARN
, "Warning! ACM codec reports srcsize=0\n");
134 srcsize
= 2*in_fmt
->nBlockAlign
;
137 mp_msg(MSGT_WIN32
,MSGL_V
,"Audio ACM input buffer min. size: %ld\n",srcsize
);
139 sh_audio
->audio_in_minsize
=2*srcsize
; // audio input min. size
141 sh_audio
->i_bps
=sh_audio
->wf
->nAvgBytesPerSec
;
142 sh_audio
->channels
=priv
->o_wf
->nChannels
;
143 sh_audio
->samplerate
=priv
->o_wf
->nSamplesPerSec
;
144 sh_audio
->samplesize
=2;
146 mp_msg(MSGT_DECVIDEO
,MSGL_V
,"INFO: Win32/ACM audio codec init OK!\n");
150 static void uninit(sh_audio_t
*sh
)
153 acm_context_t
*priv
= sh
->context
;
156 ret
= acmStreamClose(priv
->handle
, 0);
162 case ACMERR_CANCELED
:
163 mp_msg(MSGT_WIN32
, MSGL_DBG2
, "ACM_Decoder: stream busy, waiting..\n");
164 usec_sleep(100000000);
166 case ACMERR_UNPREPARED
:
167 case ACMERR_NOTPOSSIBLE
:
170 mp_msg(MSGT_WIN32
, MSGL_WARN
, "ACM_Decoder: unknown error occurred: %ld\n", ret
);
174 MSACM_UnregisterAllDrivers();
180 static int control(sh_audio_t
*sh_audio
,int cmd
,void* arg
, ...)
185 case ADCTRL_SKIP_FRAME
:
186 skip
=sh_audio
->wf
->nBlockAlign
;
188 skip
=(sh_audio
->wf
->nAvgBytesPerSec
/16)&(~7);
191 demux_read_data(sh_audio
->ds
,NULL
,skip
);
194 return CONTROL_UNKNOWN
;
197 static int decode_audio(sh_audio_t
*sh_audio
,unsigned char *buf
,int minlen
,int maxlen
)
203 acm_context_t
*priv
= sh_audio
->context
;
205 acmStreamSize(priv
->handle
, len
, &srcsize
, ACM_STREAMSIZEF_DESTINATION
);
206 mp_msg(MSGT_WIN32
,MSGL_DBG3
,"acm says: srcsize=%ld (buffsize=%d) out_size=%ld\n",srcsize
,sh_audio
->a_in_buffer_size
,len
);
208 if(srcsize
<sh_audio
->wf
->nBlockAlign
){
209 srcsize
=sh_audio
->wf
->nBlockAlign
;
210 acmStreamSize(priv
->handle
, srcsize
, &len
, ACM_STREAMSIZEF_SOURCE
);
211 if(len
>maxlen
) len
=maxlen
;
214 // if(srcsize==0) srcsize=((WAVEFORMATEX *)&sh_audio->o_wf_ext)->nBlockAlign;
215 if(srcsize
>sh_audio
->a_in_buffer_size
) srcsize
=sh_audio
->a_in_buffer_size
; // !!!!!!
216 if(sh_audio
->a_in_buffer_len
<srcsize
){
217 sh_audio
->a_in_buffer_len
+=
218 demux_read_data(sh_audio
->ds
,&sh_audio
->a_in_buffer
[sh_audio
->a_in_buffer_len
],
219 srcsize
-sh_audio
->a_in_buffer_len
);
221 mp_msg(MSGT_WIN32
,MSGL_DBG3
,"acm convert %d -> %ld bytes\n",sh_audio
->a_in_buffer_len
,len
);
222 memset(&ash
, 0, sizeof(ash
));
223 ash
.cbStruct
=sizeof(ash
);
226 ash
.pbSrc
=sh_audio
->a_in_buffer
;
227 ash
.cbSrcLength
=sh_audio
->a_in_buffer_len
;
230 hr
=acmStreamPrepareHeader(priv
->handle
,&ash
,0);
232 mp_msg(MSGT_WIN32
,MSGL_V
,"ACM_Decoder: acmStreamPrepareHeader error %d\n",(int)hr
);
235 hr
=acmStreamConvert(priv
->handle
,&ash
,0);
237 mp_msg(MSGT_WIN32
,MSGL_DBG2
,"ACM_Decoder: acmStreamConvert error %d\n",(int)hr
);
240 case ACMERR_NOTPOSSIBLE
:
241 case ACMERR_UNPREPARED
:
242 mp_msg(MSGT_WIN32
, MSGL_DBG2
, "ACM_Decoder: acmStreamConvert error: probarly not initialized!\n");
246 mp_msg(MSGT_WIN32
,MSGL_DBG2
,"acm converted %ld -> %ld\n",ash
.cbSrcLengthUsed
,ash
.cbDstLengthUsed
);
247 if(ash
.cbSrcLengthUsed
>=sh_audio
->a_in_buffer_len
){
248 sh_audio
->a_in_buffer_len
=0;
250 sh_audio
->a_in_buffer_len
-=ash
.cbSrcLengthUsed
;
251 memcpy(sh_audio
->a_in_buffer
,&sh_audio
->a_in_buffer
[ash
.cbSrcLengthUsed
],sh_audio
->a_in_buffer_len
);
253 len
=ash
.cbDstLengthUsed
;
254 hr
=acmStreamUnprepareHeader(priv
->handle
,&ash
,0);
256 mp_msg(MSGT_WIN32
,MSGL_V
,"ACM_Decoder: acmStreamUnprepareHeader error %d\n",(int)hr
);