15 #include <sys/ioctl.h>
18 #include "audio_out.h"
19 #include "audio_out_internal.h"
21 #include "libaf/af_format.h"
22 #include "libmpdemux/mpeg_packetizer.h"
23 #include "subopt-helper.h"
30 #include <ost/audio.h>
31 audioMixer_t dvb_mixer
={255,255};
33 #include <linux/dvb/audio.h>
34 audio_mixer_t dvb_mixer
={255,255};
41 extern int vo_mpegpes_fd
;
42 int vo_mpegpes_fd2
= -1;
46 static ao_info_t info
=
51 "MPEG-PES audio output",
61 // to set/get/query special features/parameters
62 static int control(int cmd
,void *arg
){
65 case AOCONTROL_GET_VOLUME
:
66 if(vo_mpegpes_fd2
>=0){
67 ((ao_control_vol_t
*)(arg
))->left
=dvb_mixer
.volume_left
/2.56;
68 ((ao_control_vol_t
*)(arg
))->right
=dvb_mixer
.volume_right
/2.56;
72 case AOCONTROL_SET_VOLUME
:
73 if(vo_mpegpes_fd2
>=0){
74 dvb_mixer
.volume_left
=((ao_control_vol_t
*)(arg
))->left
*2.56;
75 dvb_mixer
.volume_right
=((ao_control_vol_t
*)(arg
))->right
*2.56;
76 if(dvb_mixer
.volume_left
>255) dvb_mixer
.volume_left
=255;
77 if(dvb_mixer
.volume_right
>255) dvb_mixer
.volume_right
=255;
78 // printf("Setting DVB volume: %d ; %d \n",dvb_mixer.volume_left,dvb_mixer.volume_right);
79 if ( (ioctl(vo_mpegpes_fd2
,AUDIO_SET_MIXER
, &dvb_mixer
) < 0)){
80 mp_msg(MSGT_AO
, MSGL_ERR
, MSGTR_AO_MPEGPES_CantSetMixer
,
89 return CONTROL_UNKNOWN
;
96 static int init_device(int card
)
100 mp_msg(MSGT_VO
,MSGL_INFO
, "Opening /dev/ost/audio\n");
101 sprintf(ao_file
, "/dev/ost/audio");
103 mp_msg(MSGT_VO
,MSGL_INFO
, "Opening /dev/dvb/adapter%d/audio0\n", card
);
104 sprintf(ao_file
, "/dev/dvb/adapter%d/audio0", card
);
106 if((vo_mpegpes_fd2
= open(ao_file
,O_RDWR
|O_NONBLOCK
)) < 0)
108 mp_msg(MSGT_VO
, MSGL_ERR
, "DVB AUDIO DEVICE: %s\n", strerror(errno
));
111 if( (ioctl(vo_mpegpes_fd2
,AUDIO_SELECT_SOURCE
, AUDIO_SOURCE_MEMORY
) < 0))
113 mp_msg(MSGT_VO
, MSGL_ERR
, "DVB AUDIO SELECT SOURCE: %s\n", strerror(errno
));
116 if((ioctl(vo_mpegpes_fd2
,AUDIO_PLAY
) < 0))
118 mp_msg(MSGT_VO
, MSGL_ERR
, "DVB AUDIO PLAY: %s\n", strerror(errno
));
121 if((ioctl(vo_mpegpes_fd2
,AUDIO_SET_AV_SYNC
, true) < 0))
123 mp_msg(MSGT_VO
, MSGL_ERR
, "DVB AUDIO SET AV SYNC: %s\n", strerror(errno
));
126 //FIXME: in vo_mpegpes audio was initialized as MUTEd
127 if((ioctl(vo_mpegpes_fd2
,AUDIO_SET_MUTE
, false) < 0))
129 mp_msg(MSGT_VO
, MSGL_ERR
, "DVB AUDIO SET MUTE: %s\n", strerror(errno
));
132 return vo_mpegpes_fd2
;
136 static int preinit(const char *arg
)
139 char *ao_file
= NULL
;
142 {"card", OPT_ARG_INT
, &card
, NULL
},
143 {"file", OPT_ARG_MSTRZ
, &ao_file
, NULL
},
147 if(subopt_parse(ao_subdevice
, subopts
) != 0)
149 mp_msg(MSGT_VO
, MSGL_ERR
, "AO_MPEGPES, Unrecognized options\n");
154 //search the first usable card
159 sprintf(file
, "/dev/dvb/adapter%d/audio0", n
);
160 if(access(file
, F_OK
| W_OK
)==0)
167 if((card
< 1) || (card
> 4))
169 mp_msg(MSGT_VO
, MSGL_ERR
, "DVB card number must be between 1 and 4\n");
176 return init_device(card
);
179 return vo_mpegpes_fd
; //video fd
182 vo_mpegpes_fd2
=open(ao_file
,O_WRONLY
|O_CREAT
,0666);
185 mp_msg(MSGT_VO
, MSGL_ERR
, "ao_mpegpes: %s\n", strerror(errno
));
188 return vo_mpegpes_fd2
;
191 static int my_ao_write(unsigned char* data
,int len
){
195 struct pollfd pfd
[NFD
];
197 pfd
[0].fd
= vo_mpegpes_fd2
;
198 pfd
[0].events
= POLLOUT
;
202 if(pfd
[0].revents
& POLLOUT
){
203 int ret
=write(vo_mpegpes_fd2
,data
,len
);
205 mp_msg(MSGT_VO
, MSGL_ERR
, "ao_mpegpes write: %s\n", strerror(errno
));
216 if(vo_mpegpes_fd2
<0) return 0; // no file
217 write(vo_mpegpes_fd2
,data
,len
); // write to file
223 // open & setup audio device
224 // return: 1=success 0=fail
225 static int init(int rate
,int channels
,int format
,int flags
){
226 if(preinit(NULL
)<0) return 0;
229 ao_data
.outburst
=2000;
231 case AF_FORMAT_S16_BE
:
232 case AF_FORMAT_MPEG2
:
234 ao_data
.format
=format
;
237 ao_data
.format
=AF_FORMAT_S16_BE
;
241 case 48000: freq_id
=0;break;
242 case 96000: freq_id
=1;break;
243 case 44100: freq_id
=2;break;
244 case 32000: freq_id
=3;break;
246 mp_msg(MSGT_AO
, MSGL_ERR
, MSGTR_AO_MPEGPES_UnsupSamplerate
, rate
);
248 if(rate
>48000) rate
=96000; else
249 if(rate
>44100) rate
=48000; else
250 if(rate
>32000) rate
=44100; else
254 rate
=48000; freq_id
=0;
258 ao_data
.bps
=rate
*2*2;
259 freq
=ao_data
.samplerate
=rate
;
264 // close audio device
265 static void uninit(int immed
){
269 // stop playing and empty buffers (for seeking/pause)
270 static void reset(void){
274 // stop playing, keep buffers (for pause)
275 static void audio_pause(void)
277 // for now, just call reset();
281 // resume playing, after audio_pause()
282 static void audio_resume(void)
288 // return: how many bytes can be played without blocking
289 static int get_space(void){
290 float x
=(float)(vo_pts
-ao_data
.pts
)/90000.0;
292 //FIXME: is it correct?
293 if(vo_mpegpes_fd
< 0) return 32000; //not using -vo mpegpes
294 // printf("vo_pts: %5.3f ao_pts: %5.3f\n",vo_pts/90000.0,ao_data.pts/90000.0);
296 y
=freq
*4*x
;y
/=ao_data
.outburst
;y
*=ao_data
.outburst
;
298 // printf("diff: %5.3f -> %d \n",x,y);
302 // plays 'len' bytes of 'data'
303 // it should round it down to outburst*n
304 // return: number of bytes played
305 static int play(void* data
,int len
,int flags
){
306 // printf("\nao_mpegpes: play(%d) freq=%d\n",len,freq_id);
307 if(ao_data
.format
==AF_FORMAT_MPEG2
)
308 send_mpeg_pes_packet (data
, len
, 0x1C0, ao_data
.pts
, 1, my_ao_write
);
311 unsigned short *s
=data
;
312 // if(len>2000) len=2000;
313 // printf("ao_mpegpes: len=%d \n",len);
314 if(ao_data
.format
==AF_FORMAT_AC3
)
315 for(i
=0;i
<len
/2;i
++) s
[i
]=(s
[i
]>>8)|(s
[i
]<<8); // le<->be
316 send_mpeg_lpcm_packet(data
, len
, 0xA0, ao_data
.pts
, freq_id
, my_ao_write
);
321 // return: delay in seconds between first and last sample in buffer
322 static float get_delay(void){