19 #include <sys/ioctl.h>
22 #include "audio_out.h"
23 #include "audio_out_internal.h"
25 #include "libaf/af_format.h"
26 #include "libmpdemux/mpeg_packetizer.h"
27 #include "subopt-helper.h"
34 #include <ost/audio.h>
35 audioMixer_t dvb_mixer
={255,255};
37 #include <linux/dvb/audio.h>
38 audio_mixer_t dvb_mixer
={255,255};
45 extern int vo_mpegpes_fd
;
46 int vo_mpegpes_fd2
= -1;
50 static ao_info_t info
=
55 "Mpeg-PES audio output",
65 // to set/get/query special features/parameters
66 static int control(int cmd
,void *arg
){
69 case AOCONTROL_GET_VOLUME
:
70 if(vo_mpegpes_fd2
>=0){
71 ((ao_control_vol_t
*)(arg
))->left
=dvb_mixer
.volume_left
/2.56;
72 ((ao_control_vol_t
*)(arg
))->right
=dvb_mixer
.volume_right
/2.56;
76 case AOCONTROL_SET_VOLUME
:
77 if(vo_mpegpes_fd2
>=0){
78 dvb_mixer
.volume_left
=((ao_control_vol_t
*)(arg
))->left
*2.56;
79 dvb_mixer
.volume_right
=((ao_control_vol_t
*)(arg
))->right
*2.56;
80 if(dvb_mixer
.volume_left
>255) dvb_mixer
.volume_left
=255;
81 if(dvb_mixer
.volume_right
>255) dvb_mixer
.volume_right
=255;
82 // printf("Setting DVB volume: %d ; %d \n",dvb_mixer.volume_left,dvb_mixer.volume_right);
83 if ( (ioctl(vo_mpegpes_fd2
,AUDIO_SET_MIXER
, &dvb_mixer
) < 0)){
84 mp_msg(MSGT_AO
, MSGL_ERR
, MSGTR_AO_MPEGPES_CantSetMixer
,
93 return CONTROL_UNKNOWN
;
100 static int init_device(int card
)
103 #ifndef HAVE_DVB_HEAD
104 mp_msg(MSGT_VO
,MSGL_INFO
, "Opening /dev/ost/audio\n");
105 sprintf(ao_file
, "/dev/ost/audio");
107 mp_msg(MSGT_VO
,MSGL_INFO
, "Opening /dev/dvb/adapter%d/audio0\n", card
);
108 sprintf(ao_file
, "/dev/dvb/adapter%d/audio0", card
);
110 if((vo_mpegpes_fd2
= open(ao_file
,O_RDWR
|O_NONBLOCK
)) < 0)
112 mp_msg(MSGT_VO
, MSGL_ERR
, "DVB AUDIO DEVICE: %s\n", strerror(errno
));
115 if( (ioctl(vo_mpegpes_fd2
,AUDIO_SELECT_SOURCE
, AUDIO_SOURCE_MEMORY
) < 0))
117 mp_msg(MSGT_VO
, MSGL_ERR
, "DVB AUDIO SELECT SOURCE: %s\n", strerror(errno
));
120 if((ioctl(vo_mpegpes_fd2
,AUDIO_PLAY
) < 0))
122 mp_msg(MSGT_VO
, MSGL_ERR
, "DVB AUDIO PLAY: %s\n", strerror(errno
));
125 if((ioctl(vo_mpegpes_fd2
,AUDIO_SET_AV_SYNC
, true) < 0))
127 mp_msg(MSGT_VO
, MSGL_ERR
, "DVB AUDIO SET AV SYNC: %s\n", strerror(errno
));
130 //FIXME: in vo_mpegpes audio was inited as MUTEd
131 if((ioctl(vo_mpegpes_fd2
,AUDIO_SET_MUTE
, false) < 0))
133 mp_msg(MSGT_VO
, MSGL_ERR
, "DVB AUDIO SET MUTE: %s\n", strerror(errno
));
136 return vo_mpegpes_fd2
;
140 static int preinit(const char *arg
)
143 char *ao_file
= NULL
;
146 {"card", OPT_ARG_INT
, &card
, NULL
},
147 {"file", OPT_ARG_MSTRZ
, &ao_file
, NULL
},
151 if(subopt_parse(ao_subdevice
, subopts
) != 0)
153 mp_msg(MSGT_VO
, MSGL_ERR
, "AO_MPEGPES, Unrecognized options\n");
156 if((card
< 1) || (card
> 4))
158 mp_msg(MSGT_VO
, MSGL_ERR
, "DVB card number must be between 1 and 4\n");
165 return init_device(card
);
168 return vo_mpegpes_fd
; //video fd
171 vo_mpegpes_fd2
=open(ao_file
,O_WRONLY
|O_CREAT
,0666);
174 mp_msg(MSGT_VO
, MSGL_ERR
, "ao_mpegpes: %s\n", strerror(errno
));
177 return vo_mpegpes_fd2
;
180 static int my_ao_write(unsigned char* data
,int len
){
184 struct pollfd pfd
[NFD
];
186 pfd
[0].fd
= vo_mpegpes_fd2
;
187 pfd
[0].events
= POLLOUT
;
191 if(pfd
[0].revents
& POLLOUT
){
192 int ret
=write(vo_mpegpes_fd2
,data
,len
);
194 mp_msg(MSGT_VO
, MSGL_ERR
, "ao_mpegpes write: %s\n", strerror(errno
));
205 if(vo_mpegpes_fd2
<0) return 0; // no file
206 write(vo_mpegpes_fd2
,data
,len
); // write to file
212 // open & setup audio device
213 // return: 1=success 0=fail
214 static int init(int rate
,int channels
,int format
,int flags
){
215 if(preinit(NULL
)<0) return 0;
218 ao_data
.outburst
=2000;
220 case AF_FORMAT_S16_BE
:
221 case AF_FORMAT_MPEG2
:
223 ao_data
.format
=format
;
226 ao_data
.format
=AF_FORMAT_S16_BE
;
230 case 48000: freq_id
=0;break;
231 case 96000: freq_id
=1;break;
232 case 44100: freq_id
=2;break;
233 case 32000: freq_id
=3;break;
235 mp_msg(MSGT_AO
, MSGL_ERR
, MSGTR_AO_MPEGPES_UnsupSamplerate
, rate
);
237 if(rate
>48000) rate
=96000; else
238 if(rate
>44100) rate
=48000; else
239 if(rate
>32000) rate
=44100; else
243 rate
=48000; freq_id
=0;
247 ao_data
.bps
=rate
*2*2;
248 freq
=ao_data
.samplerate
=rate
;
253 // close audio device
254 static void uninit(int immed
){
258 // stop playing and empty buffers (for seeking/pause)
259 static void reset(void){
263 // stop playing, keep buffers (for pause)
264 static void audio_pause(void)
266 // for now, just call reset();
270 // resume playing, after audio_pause()
271 static void audio_resume(void)
275 void send_pes_packet(unsigned char* data
,int len
,int id
,int timestamp
);
276 void send_lpcm_packet(unsigned char* data
,int len
,int id
,int timestamp
,int freq_id
);
279 // return: how many bytes can be played without blocking
280 static int get_space(void){
281 float x
=(float)(vo_pts
-ao_data
.pts
)/90000.0;
283 //FIXME: is it correct?
284 if(vo_mpegpes_fd
< 0) return 32000; //not using -vo mpegpes
285 // printf("vo_pts: %5.3f ao_pts: %5.3f\n",vo_pts/90000.0,ao_data.pts/90000.0);
287 y
=freq
*4*x
;y
/=ao_data
.outburst
;y
*=ao_data
.outburst
;
289 // printf("diff: %5.3f -> %d \n",x,y);
293 // plays 'len' bytes of 'data'
294 // it should round it down to outburst*n
295 // return: number of bytes played
296 static int play(void* data
,int len
,int flags
){
297 // printf("\nao_mpegpes: play(%d) freq=%d\n",len,freq_id);
298 if(ao_data
.format
==AF_FORMAT_MPEG2
)
299 send_mpeg_pes_packet (data
, len
, 0x1C0, ao_data
.pts
, 1, my_ao_write
);
302 unsigned short *s
=data
;
303 // if(len>2000) len=2000;
304 // printf("ao_mpegpes: len=%d \n",len);
305 if(ao_data
.format
==AF_FORMAT_AC3
)
306 for(i
=0;i
<len
/2;i
++) s
[i
]=(s
[i
]>>8)|(s
[i
]<<8); // le<->be
307 send_mpeg_lpcm_packet(data
, len
, 0xA0, ao_data
.pts
, freq_id
, my_ao_write
);
312 // return: delay in seconds between first and last sample in buffer
313 static float get_delay(void){