1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
|
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "config.h"
#include "mp_msg.h"
#include "help_mp.h"
extern int verbose; // defined in mplayer.c
#include "stream.h"
#include "demuxer.h"
#include "codec-cfg.h"
#include "stheader.h"
#include "dec_audio.h"
#include "ad.h"
#include "../libao2/afmt.h"
#ifdef USE_FAKE_MONO
int fakemono=0;
#endif
/* used for ac3surround decoder - set using -channels option */
int audio_output_channels = 2;
static ad_functions_t* mpadec;
int init_audio(sh_audio_t *sh_audio)
{
unsigned i;
for (i=0; mpcodecs_ad_drivers[i] != NULL; i++)
if(mpcodecs_ad_drivers[i]->info->id==sh_audio->codec->driver){
mpadec=mpcodecs_ad_drivers[i]; break;
}
if(!mpadec){
mp_msg(MSGT_DECAUDIO,MSGL_ERR,"Requested audio codec family [%s] (vfm=%d) not available (enable it at compile time!)\n",
sh_audio->codec->name, sh_audio->codec->driver);
return 0; // no such driver
}
printf("Selecting Audio Decoder: [%s] %s\n",mpadec->info->short_name,mpadec->info->name);
// reset in/out buffer size/pointer:
sh_audio->a_buffer_size=0;
sh_audio->a_buffer=NULL;
sh_audio->a_in_buffer_size=0;
sh_audio->a_in_buffer=NULL;
// Set up some common usefull defaults. ad->preinit() can override these:
sh_audio->samplesize=2;
#ifdef WORDS_BIGENDIAN
sh_audio->sample_format=AFMT_S16_BE;
#else
sh_audio->sample_format=AFMT_S16_LE;
#endif
sh_audio->samplerate=0;
sh_audio->i_bps=0; // input rate (bytes/sec)
sh_audio->o_bps=0; // output rate (bytes/sec)
sh_audio->audio_out_minsize=8192;/* default size, maybe not enough for Win32/ACM*/
sh_audio->audio_in_minsize=0;
if(!mpadec->preinit(sh_audio))
{
printf("ADecoder preinit failed :(\n");
return 0;
}
/* allocate audio in buffer: */
if(sh_audio->audio_in_minsize>0){
sh_audio->a_in_buffer_size=sh_audio->audio_in_minsize;
mp_msg(MSGT_DECAUDIO,MSGL_V,"dec_audio: Allocating %d bytes for input buffer\n",
sh_audio->a_in_buffer_size);
sh_audio->a_in_buffer=malloc(sh_audio->a_in_buffer_size);
memset(sh_audio->a_in_buffer,0,sh_audio->a_in_buffer_size);
sh_audio->a_in_buffer_len=0;
}
/* allocate audio out buffer: */
sh_audio->a_buffer_size=sh_audio->audio_out_minsize+MAX_OUTBURST; /* worst case calc.*/
mp_msg(MSGT_DECAUDIO,MSGL_V,"dec_audio: Allocating %d + %d = %d bytes for output buffer\n",
sh_audio->audio_out_minsize,MAX_OUTBURST,sh_audio->a_buffer_size);
sh_audio->a_buffer=malloc(sh_audio->a_buffer_size);
if(!sh_audio->a_buffer){
mp_msg(MSGT_DECAUDIO,MSGL_ERR,MSGTR_CantAllocAudioBuf);
return 0;
}
memset(sh_audio->a_buffer,0,sh_audio->a_buffer_size);
sh_audio->a_buffer_len=0;
if(!mpadec->init(sh_audio)){
mp_msg(MSGT_DECAUDIO,MSGL_WARN,"ADecoder init failed :(\n");
uninit_audio(sh_audio); // free buffers
return 0;
}
sh_audio->inited=1;
if(!sh_audio->channels || !sh_audio->samplerate){
mp_msg(MSGT_DECAUDIO,MSGL_WARN,MSGTR_UnknownAudio);
uninit_audio(sh_audio); // free buffers
return 0;
}
if(!sh_audio->o_bps)
sh_audio->o_bps=sh_audio->channels*sh_audio->samplerate*sh_audio->samplesize;
return 1;
}
void uninit_audio(sh_audio_t *sh_audio)
{
if(sh_audio->a_buffer) free(sh_audio->a_buffer);
sh_audio->a_buffer=NULL;
if(sh_audio->a_in_buffer) free(sh_audio->a_in_buffer);
sh_audio->a_in_buffer=NULL;
if(!sh_audio->inited) return;
mp_msg(MSGT_DECAUDIO,MSGL_V,"uninit audio: %d \n",sh_audio->codec->driver);
mpadec->uninit(sh_audio);
sh_audio->inited=0;
}
int decode_audio(sh_audio_t *sh_audio,unsigned char *buf,int minlen,int maxlen)
{
if(sh_audio->inited)
return mpadec->decode_audio(sh_audio,buf,minlen,maxlen);
else
return -1;
}
void resync_audio_stream(sh_audio_t *sh_audio)
{
if(!sh_audio->inited) return;
if(mpadec->control(sh_audio,ADCTRL_RESYNC_STREAM,NULL)==CONTROL_TRUE) return;
// default resync code:
sh_audio->a_in_buffer_len=0; // clear audio input buffer
}
void skip_audio_frame(sh_audio_t *sh_audio)
{
if(!sh_audio->inited) return;
if(mpadec->control(sh_audio,ADCTRL_SKIP_FRAME,NULL)==CONTROL_TRUE) return;
// default skip code:
ds_fill_buffer(sh_audio->ds); // skip block
}
|