1 /*
2  * This file is part of MPlayer.
3  *
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.
8  *
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.
13  *
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.
17  */
18 
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <unistd.h>
22 
23 #include "config.h"
24 #include "mp_msg.h"
25 #include "help_mp.h"
26 
27 #include "ad_internal.h"
28 #include "dec_audio.h"
29 #include "libaf/reorder_ch.h"
30 
31 static const ad_info_t info =
32 {
33 	"Win32/DMO decoders",
34 	"dmo",
35 	"A'rpi",
36 	"avifile.sf.net",
37 	""
38 };
39 
LIBAD_EXTERN(dmo)40 LIBAD_EXTERN(dmo)
41 
42 #include "loader/dmo/DMO_AudioDecoder.h"
43 
44 static int init(sh_audio_t *sh)
45 {
46   return 1;
47 }
48 
preinit(sh_audio_t * sh_audio)49 static int preinit(sh_audio_t *sh_audio)
50 {
51   DMO_AudioDecoder* ds_adec;
52   int chans=(audio_output_channels==sh_audio->wf->nChannels) ?
53       audio_output_channels : (sh_audio->wf->nChannels>=2 ? 2 : 1);
54   if(!(ds_adec=DMO_AudioDecoder_Open(codec_idx2str(sh_audio->codec->dll_idx),&sh_audio->codec->guid,sh_audio->wf,chans)))
55   {
56     mp_msg(MSGT_DECAUDIO,MSGL_ERR,MSGTR_MissingDLLcodec,codec_idx2str(sh_audio->codec->dll_idx));
57     return 0;
58   }
59     sh_audio->i_bps=sh_audio->wf->nAvgBytesPerSec;
60     sh_audio->channels=chans;
61     sh_audio->samplerate=sh_audio->wf->nSamplesPerSec;
62     sh_audio->samplesize=2;
63     sh_audio->audio_in_minsize=4*sh_audio->wf->nBlockAlign;
64     if(sh_audio->audio_in_minsize<8192) sh_audio->audio_in_minsize=8192;
65     sh_audio->audio_out_minsize=4*16384;
66     sh_audio->context = ds_adec;
67   mp_msg(MSGT_DECVIDEO,MSGL_V,"INFO: Win32/DMO audio codec init OK!\n");
68   return 1;
69 }
70 
uninit(sh_audio_t * sh)71 static void uninit(sh_audio_t *sh)
72 {
73     DMO_AudioDecoder* ds_adec = sh->context;
74     DMO_AudioDecoder_Destroy(ds_adec);
75 }
76 
control(sh_audio_t * sh_audio,int cmd,void * arg,...)77 static int control(sh_audio_t *sh_audio,int cmd,void* arg, ...)
78 {
79   int skip;
80     switch(cmd)
81     {
82       case ADCTRL_SKIP_FRAME:
83 		    skip=sh_audio->wf->nBlockAlign;
84 		    if(skip<16){
85 		      skip=(sh_audio->wf->nAvgBytesPerSec/16)&(~7);
86 		      if(skip<16) skip=16;
87 		    }
88 		    demux_read_data(sh_audio->ds,NULL,skip);
89 	  return CONTROL_TRUE;
90     }
91   return CONTROL_UNKNOWN;
92 }
93 
decode_audio(sh_audio_t * sh_audio,unsigned char * buf,int minlen,int maxlen)94 static int decode_audio(sh_audio_t *sh_audio,unsigned char *buf,int minlen,int maxlen)
95 {
96 	DMO_AudioDecoder* ds_adec = sh_audio->context;
97 //	int len=-1;
98         int size_in=0;
99         int size_out=0;
100         int srcsize=DMO_AudioDecoder_GetSrcSize(ds_adec, maxlen);
101         mp_msg(MSGT_DECAUDIO,MSGL_DBG3,"DMO says: srcsize=%d  (buffsize=%d)  out_size=%d\n",srcsize,sh_audio->a_in_buffer_size,maxlen);
102         if(srcsize>sh_audio->a_in_buffer_size) srcsize=sh_audio->a_in_buffer_size; // !!!!!!
103         if(sh_audio->a_in_buffer_len<srcsize){
104           sh_audio->a_in_buffer_len+=
105             demux_read_data(sh_audio->ds,&sh_audio->a_in_buffer[sh_audio->a_in_buffer_len],
106             srcsize-sh_audio->a_in_buffer_len);
107         }
108         DMO_AudioDecoder_Convert(ds_adec, sh_audio->a_in_buffer,sh_audio->a_in_buffer_len,
109             buf,maxlen, &size_in,&size_out);
110         mp_dbg(MSGT_DECAUDIO,MSGL_DBG2,"DMO: audio %d -> %d converted  (in_buf_len=%d of %d)  %d\n",size_in,size_out,sh_audio->a_in_buffer_len,sh_audio->a_in_buffer_size,ds_tell_pts(sh_audio->ds));
111         if(size_in>=sh_audio->a_in_buffer_len){
112           sh_audio->a_in_buffer_len=0;
113         } else {
114           sh_audio->a_in_buffer_len-=size_in;
115           memmove(sh_audio->a_in_buffer,&sh_audio->a_in_buffer[size_in],sh_audio->a_in_buffer_len);
116         }
117         if (size_out > 0 && sh_audio->channels >= 5) {
118           reorder_channel_nch(buf, AF_CHANNEL_LAYOUT_WAVEEX_DEFAULT,
119                               AF_CHANNEL_LAYOUT_MPLAYER_DEFAULT,
120                               sh_audio->channels,
121                               size_out / sh_audio->samplesize,
122                               sh_audio->samplesize);
123         }
124 //        len=size_out;
125   return size_out;
126 }
127