changeset 7228:0a21be7df603

merged with dll_init.c, moved some variables from sh_audio to private struct
author alex
date Sun, 01 Sep 2002 17:11:10 +0000
parents cc139517e0e1
children b4d025d64eb3
files libmpcodecs/ad_acm.c
diffstat 1 files changed, 178 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/libmpcodecs/ad_acm.c	Sun Sep 01 16:57:06 2002 +0000
+++ b/libmpcodecs/ad_acm.c	Sun Sep 01 17:11:10 2002 +0000
@@ -8,24 +8,32 @@
 
 #ifdef USE_WIN32DLL
 
+#include "loader.h"
+//#include "wine/mmreg.h"
+#include "wine/vfw.h"
+#include "wine/avifmt.h"
+
 #include "ad_internal.h"
 
 static ad_info_t info = 
 {
 	"Win32/ACM decoders",
 	"acm",
-	"Nick Kurshev",
-	"avifile.sf.net",
+	"A'rpi",
+	"A'rpi & Alex",
 	""
 };
 
 LIBAD_EXTERN(acm)
 
-#include "dll_init.h"
+typedef struct {
+    WAVEFORMATEX *o_wf;
+    HACMSTREAM handle;
+} acm_context_t;
 
 static int init(sh_audio_t *sh_audio)
 {
-    int ret=acm_decode_audio(sh_audio,sh_audio->a_buffer,4096,sh_audio->a_buffer_size);
+    int ret=decode_audio(sh_audio,sh_audio->a_buffer,4096,sh_audio->a_buffer_size);
     if(ret<0){
         mp_msg(MSGT_DECAUDIO,MSGL_INFO,"ACM decoding error: %d\n",ret);
         return 0;
@@ -36,22 +44,116 @@
 
 static int preinit(sh_audio_t *sh_audio)
 {
-  /* Win32 ACM audio codec: */
-  if(init_acm_audio_codec(sh_audio)){
+    HRESULT ret;
+    WAVEFORMATEX *in_fmt = sh_audio->wf;
+    unsigned int srcsize = 0;
+    acm_context_t *priv;
+    
+    priv = malloc(sizeof(acm_context_t));
+    if (!priv)
+	return 0;
+    sh_audio->context = priv;
+    
+    mp_msg(MSGT_WIN32, MSGL_V, "======= Win32 (ACM) AUDIO Codec init =======\n");
+
+//    priv->handle = NULL;
+
+    priv->o_wf = malloc(sizeof(WAVEFORMATEX));
+    if (!priv->o_wf)
+    {
+	mp_msg(MSGT_DECAUDIO,MSGL_ERR,MSGTR_ACMiniterror);
+	return 0;
+    }
+
+    priv->o_wf->nChannels = in_fmt->nChannels;
+    priv->o_wf->nSamplesPerSec = in_fmt->nSamplesPerSec;
+    priv->o_wf->nAvgBytesPerSec = 2*in_fmt->nSamplesPerSec*in_fmt->nChannels;
+    priv->o_wf->wFormatTag = WAVE_FORMAT_PCM;
+    priv->o_wf->nBlockAlign = 2*in_fmt->nChannels;
+    priv->o_wf->wBitsPerSample = 16;
+//    priv->o_wf->wBitsPerSample = inf_fmt->wBitsPerSample;
+    priv->o_wf->cbSize = 0;
+    
+    if (verbose)
+    {
+	mp_msg(MSGT_DECAUDIO, MSGL_V, "Input format:\n");
+	print_wave_header(in_fmt);
+	mp_msg(MSGT_DECAUDIO, MSGL_V, "Output format:\n");
+	print_wave_header(priv->o_wf);
+    }
+
+    win32_codec_name = sh_audio->codec->dll;
+    ret = acmStreamOpen(&priv->handle, (HACMDRIVER)NULL, in_fmt,
+			priv->o_wf, NULL, 0, 0, 0);
+    if (ret)
+    {
+	if (ret == ACMERR_NOTPOSSIBLE)
+	    mp_msg(MSGT_WIN32, MSGL_ERR, "ACM_Decoder: Unappropriate audio format\n");
+	else
+	    mp_msg(MSGT_WIN32, MSGL_ERR, "ACM_Decoder: acmStreamOpen error: %d\n",
+		(int)ret);
+	mp_msg(MSGT_DECAUDIO,MSGL_ERR,MSGTR_ACMiniterror);
+	return 0;
+    }
+    mp_msg(MSGT_WIN32, MSGL_V, "Audio codec opened OK! ;-)\n");
+    
+    acmStreamSize(priv->handle, in_fmt->nBlockAlign, &srcsize, ACM_STREAMSIZEF_SOURCE);
+    //if (verbose) printf("Audio ACM output buffer min. size: %ld (reported by codec)\n", srcsize);
+    srcsize *= 2;
+    //if (srcsize < MAX_OUTBURST) srcsize = MAX_OUTBURST;
+    if (!srcsize)
+    {
+	mp_msg(MSGT_WIN32, MSGL_WARN, "Warning! ACM codec reports srcsize=0\n");
+	srcsize = 16384;
+    }
+    // limit srcsize to 4-16kb
+    //while(srcsize && srcsize<4096) srcsize*=2;
+    //while(srcsize>16384) srcsize/=2;
+    sh_audio->audio_out_minsize=srcsize; // audio output min. size
+    mp_msg(MSGT_WIN32,MSGL_V,"Audio ACM output buffer min. size: %ld\n",srcsize);
+
+    acmStreamSize(priv->handle, srcsize, &srcsize, ACM_STREAMSIZEF_DESTINATION);
+//    if(srcsize<in_fmt->nBlockAlign) srcsize=in_fmt->nBlockAlign;
+
+    mp_msg(MSGT_WIN32,MSGL_V,"Audio ACM input buffer min. size: %ld\n",srcsize);
+
+    sh_audio->audio_in_minsize=2*srcsize; // audio input min. size
+    
     sh_audio->i_bps=sh_audio->wf->nAvgBytesPerSec;
-    sh_audio->channels=sh_audio->o_wf.nChannels;
-    sh_audio->samplerate=sh_audio->o_wf.nSamplesPerSec;
-  } else {
-    mp_msg(MSGT_DECAUDIO,MSGL_ERR,MSGTR_ACMiniterror);
-    return 0;
-  }
-  mp_msg(MSGT_DECVIDEO,MSGL_V,"INFO: Win32/ACM audio codec init OK!\n");
-  return 1;
+    sh_audio->channels=priv->o_wf->nChannels;
+    sh_audio->samplerate=priv->o_wf->nSamplesPerSec;
+
+    mp_msg(MSGT_DECVIDEO,MSGL_V,"INFO: Win32/ACM audio codec init OK!\n");
+    return 1;
 }
 
 static void uninit(sh_audio_t *sh)
 {
-    close_acm_audio_codec(sh);
+    HRESULT ret;
+    acm_context_t *priv = sh->context;
+    
+    ret = acmStreamClose(priv->handle, 0);
+    
+    if (ret)
+    switch(ret)
+    {
+	case ACMERR_BUSY:
+	case ACMERR_CANCELED:
+	    mp_msg(MSGT_WIN32, MSGL_DBG2, "ACM_Decoder: stream busy, waiting..\n");
+	    sleep(100);
+	    return(uninit(sh));
+	case ACMERR_UNPREPARED:
+	case ACMERR_NOTPOSSIBLE:
+	    return(0);
+	default:
+	    mp_msg(MSGT_WIN32, MSGL_WARN, "ACM_Decoder: unknown error occured: %d\n", ret);
+	    return(0);
+    }
+    
+//    MSACM_UnregisterAllDrivers();
+
+    free(priv->o_wf);
+    free(priv);
 }
 
 static int control(sh_audio_t *sh_audio,int cmd,void* arg, ...)
@@ -73,6 +175,66 @@
 
 static int decode_audio(sh_audio_t *sh_audio,unsigned char *buf,int minlen,int maxlen)
 {
-  return acm_decode_audio(sh_audio,buf,minlen,maxlen);
+    ACMSTREAMHEADER ash;
+    HRESULT hr;
+    DWORD srcsize=0;
+    DWORD len=minlen;
+    acm_context_t *priv = sh_audio->context;
+
+    acmStreamSize(priv->handle, len, &srcsize, ACM_STREAMSIZEF_DESTINATION);
+    mp_msg(MSGT_WIN32,MSGL_DBG3,"acm says: srcsize=%ld  (buffsize=%d)  out_size=%d\n",srcsize,sh_audio->a_in_buffer_size,len);
+
+    if(srcsize<sh_audio->wf->nBlockAlign){
+       srcsize=sh_audio->wf->nBlockAlign;
+       acmStreamSize(priv->handle, srcsize, &len, ACM_STREAMSIZEF_SOURCE);
+       if(len>maxlen) len=maxlen;
+    }
+
+//    if(srcsize==0) srcsize=((WAVEFORMATEX *)&sh_audio->o_wf_ext)->nBlockAlign;
+    if(srcsize>sh_audio->a_in_buffer_size) srcsize=sh_audio->a_in_buffer_size; // !!!!!!
+    if(sh_audio->a_in_buffer_len<srcsize){
+      sh_audio->a_in_buffer_len+=
+        demux_read_data(sh_audio->ds,&sh_audio->a_in_buffer[sh_audio->a_in_buffer_len],
+        srcsize-sh_audio->a_in_buffer_len);
+    }
+    mp_msg(MSGT_WIN32,MSGL_DBG3,"acm convert %d -> %d bytes\n",sh_audio->a_in_buffer_len,len);
+    memset(&ash, 0, sizeof(ash));
+    ash.cbStruct=sizeof(ash);
+    ash.fdwStatus=0;
+    ash.dwUser=0; 
+    ash.pbSrc=sh_audio->a_in_buffer;
+    ash.cbSrcLength=sh_audio->a_in_buffer_len;
+    ash.pbDst=buf;
+    ash.cbDstLength=len;
+    hr=acmStreamPrepareHeader(priv->handle,&ash,0);
+    if(hr){
+      mp_msg(MSGT_WIN32,MSGL_V,"ACM_Decoder: acmStreamPrepareHeader error %d\n",(int)hr);
+      return -1;
+    }
+    hr=acmStreamConvert(priv->handle,&ash,0);
+    if(hr){
+      mp_msg(MSGT_WIN32,MSGL_DBG2,"ACM_Decoder: acmStreamConvert error %d\n",(int)hr);
+      switch(hr)
+      {
+	case ACMERR_NOTPOSSIBLE:
+	case ACMERR_UNPREPARED:
+	    mp_msg(MSGT_WIN32, MSGL_DBG2, "ACM_Decoder: acmStreamConvert error: probarly not initialized!\n");
+      }
+//      return -1;
+    }
+    if(verbose>1)
+      mp_msg(MSGT_WIN32,MSGL_DBG2,"acm converted %d -> %d\n",ash.cbSrcLengthUsed,ash.cbDstLengthUsed);
+    if(ash.cbSrcLengthUsed>=sh_audio->a_in_buffer_len){
+      sh_audio->a_in_buffer_len=0;
+    } else {
+      sh_audio->a_in_buffer_len-=ash.cbSrcLengthUsed;
+      memcpy(sh_audio->a_in_buffer,&sh_audio->a_in_buffer[ash.cbSrcLengthUsed],sh_audio->a_in_buffer_len);
+    }
+    len=ash.cbDstLengthUsed;
+    hr=acmStreamUnprepareHeader(priv->handle,&ash,0);
+    if(hr){
+      mp_msg(MSGT_WIN32,MSGL_V,"ACM_Decoder: acmStreamUnprepareHeader error %d\n",(int)hr);
+    }
+    return len;
 }
 #endif