man/hu/mplayer.1 synced with r19052
[mplayer/greg.git] / libao2 / ao_mpegpes.c
blobec856a6671db147138b703fba57c397422f85def
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
5 #include "config.h"
7 #ifdef HAVE_DVB_HEAD
8 #define HAVE_DVB 1
9 #endif
11 #ifdef HAVE_DVB
12 #include <sys/ioctl.h>
13 #endif
15 #include "audio_out.h"
16 #include "audio_out_internal.h"
18 #include "libaf/af_format.h"
20 #include "mp_msg.h"
21 #include "help_mp.h"
23 #ifdef HAVE_DVB
24 #ifndef HAVE_DVB_HEAD
25 #include <ost/audio.h>
26 audioMixer_t dvb_mixer={255,255};
27 #else
28 #include <linux/dvb/audio.h>
29 audio_mixer_t dvb_mixer={255,255};
30 #endif
31 #endif
32 extern int vo_mpegpes_fd;
33 extern int vo_mpegpes_fd2;
35 #include <errno.h>
37 static ao_info_t info =
39 #ifdef HAVE_DVB
40 "DVB audio output",
41 #else
42 "Mpeg-PES audio output",
43 #endif
44 "mpegpes",
45 "A'rpi",
49 LIBAO_EXTERN(mpegpes)
52 // to set/get/query special features/parameters
53 static int control(int cmd,void *arg){
54 #ifdef HAVE_DVB
55 switch(cmd){
56 case AOCONTROL_GET_VOLUME:
57 if(vo_mpegpes_fd2>=0){
58 ((ao_control_vol_t*)(arg))->left=dvb_mixer.volume_left/2.56;
59 ((ao_control_vol_t*)(arg))->right=dvb_mixer.volume_right/2.56;
60 return CONTROL_OK;
62 return CONTROL_ERROR;
63 case AOCONTROL_SET_VOLUME:
64 if(vo_mpegpes_fd2>=0){
65 dvb_mixer.volume_left=((ao_control_vol_t*)(arg))->left*2.56;
66 dvb_mixer.volume_right=((ao_control_vol_t*)(arg))->right*2.56;
67 if(dvb_mixer.volume_left>255) dvb_mixer.volume_left=255;
68 if(dvb_mixer.volume_right>255) dvb_mixer.volume_right=255;
69 // printf("Setting DVB volume: %d ; %d \n",dvb_mixer.volume_left,dvb_mixer.volume_right);
70 if ( (ioctl(vo_mpegpes_fd2,AUDIO_SET_MIXER, &dvb_mixer) < 0)){
71 mp_msg(MSGT_AO, MSGL_ERR, MSGTR_AO_MPEGPES_CantSetMixer,
72 strerror(errno));
73 return CONTROL_ERROR;
75 return CONTROL_OK;
77 return CONTROL_ERROR;
79 #endif
80 return CONTROL_UNKNOWN;
83 static int freq=0;
84 static int freq_id=0;
86 // open & setup audio device
87 // return: 1=success 0=fail
88 static int init(int rate,int channels,int format,int flags){
90 #ifdef HAVE_DVB
91 if(vo_mpegpes_fd2<0) return 0; // couldn't open audio dev
92 #else
93 if(vo_mpegpes_fd<0) return 0; // no file
94 #endif
96 ao_data.channels=2;
97 ao_data.outburst=2000;
98 switch(format){
99 case AF_FORMAT_S16_LE:
100 case AF_FORMAT_S16_BE:
101 case AF_FORMAT_MPEG2:
102 case AF_FORMAT_AC3:
103 ao_data.format=format;
104 break;
105 default:
106 ao_data.format=AF_FORMAT_S16_BE;
109 retry:
110 switch(rate){
111 case 48000: freq_id=0;break;
112 case 96000: freq_id=1;break;
113 case 44100: freq_id=2;break;
114 case 32000: freq_id=3;break;
115 default:
116 mp_msg(MSGT_AO, MSGL_ERR, MSGTR_AO_MPEGPES_UnsupSamplerate, rate);
117 #if 0
118 if(rate>48000) rate=96000; else
119 if(rate>44100) rate=48000; else
120 if(rate>32000) rate=44100; else
121 rate=32000;
122 goto retry;
123 #else
124 rate=48000; freq_id=0;
125 #endif
128 ao_data.bps=rate*2*2;
129 freq=ao_data.samplerate=rate;
131 return 1;
134 // close audio device
135 static void uninit(int immed){
139 // stop playing and empty buffers (for seeking/pause)
140 static void reset(void){
144 // stop playing, keep buffers (for pause)
145 static void audio_pause(void)
147 // for now, just call reset();
148 reset();
151 // resume playing, after audio_pause()
152 static void audio_resume(void)
156 void send_pes_packet(unsigned char* data,int len,int id,int timestamp);
157 void send_lpcm_packet(unsigned char* data,int len,int id,int timestamp,int freq_id);
158 extern int vo_pts;
160 // return: how many bytes can be played without blocking
161 static int get_space(void){
162 float x=(float)(vo_pts-ao_data.pts)/90000.0;
163 int y;
164 // printf("vo_pts: %5.3f ao_pts: %5.3f\n",vo_pts/90000.0,ao_data.pts/90000.0);
165 if(x<=0) return 0;
166 y=freq*4*x;y/=ao_data.outburst;y*=ao_data.outburst;
167 if(y>32000) y=32000;
168 // printf("diff: %5.3f -> %d \n",x,y);
169 return y;
172 // plays 'len' bytes of 'data'
173 // it should round it down to outburst*n
174 // return: number of bytes played
175 static int play(void* data,int len,int flags){
176 // printf("\nao_mpegpes: play(%d) freq=%d\n",len,freq_id);
177 if(ao_data.format==AF_FORMAT_MPEG2)
178 send_pes_packet(data,len,0x1C0,ao_data.pts);
179 else {
180 int i;
181 unsigned short *s=data;
182 // if(len>2000) len=2000;
183 // printf("ao_mpegpes: len=%d \n",len);
184 if(ao_data.format==AF_FORMAT_S16_LE || ao_data.format==AF_FORMAT_AC3)
185 for(i=0;i<len/2;i++) s[i]=(s[i]>>8)|(s[i]<<8); // le<->be
186 send_lpcm_packet(data,len,0xA0,ao_data.pts,freq_id);
188 return len;
191 // return: delay in seconds between first and last sample in buffer
192 static float get_delay(void){
194 return 0.0;