diff options
Diffstat (limited to 'libao2')
-rw-r--r-- | libao2/ao_mpegpes.c | 146 |
1 files changed, 138 insertions, 8 deletions
diff --git a/libao2/ao_mpegpes.c b/libao2/ao_mpegpes.c index ec856a6671..031d96cc27 100644 --- a/libao2/ao_mpegpes.c +++ b/libao2/ao_mpegpes.c @@ -1,6 +1,12 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> +#include <inttypes.h> +#include <sys/poll.h> #include "config.h" @@ -16,6 +22,8 @@ #include "audio_out_internal.h" #include "libaf/af_format.h" +#include "libmpdemux/mpeg_packetizer.h" +#include "subopt-helper.h" #include "mp_msg.h" #include "help_mp.h" @@ -29,8 +37,12 @@ audioMixer_t dvb_mixer={255,255}; audio_mixer_t dvb_mixer={255,255}; #endif #endif + +#define true 1 +#define false 0 + extern int vo_mpegpes_fd; -extern int vo_mpegpes_fd2; +int vo_mpegpes_fd2 = -1; #include <errno.h> @@ -83,15 +95,131 @@ static int control(int cmd,void *arg){ static int freq=0; static int freq_id=0; -// open & setup audio device -// return: 1=success 0=fail -static int init(int rate,int channels,int format,int flags){ +#ifdef HAVE_DVB +static int init_device(int card) +{ + char ao_file[30]; +#ifndef HAVE_DVB_HEAD + mp_msg(MSGT_VO,MSGL_INFO, "Opening /dev/ost/audio\n"); + sprintf(ao_file, "/dev/ost/audio"); +#else + mp_msg(MSGT_VO,MSGL_INFO, "Opening /dev/dvb/adapter%d/audio0\n", card); + sprintf(ao_file, "/dev/dvb/adapter%d/audio0", card); +#endif + if((vo_mpegpes_fd2 = open(ao_file,O_RDWR|O_NONBLOCK)) < 0) + { + perror("DVB AUDIO DEVICE: "); + return -1; + } + if( (ioctl(vo_mpegpes_fd2,AUDIO_SELECT_SOURCE, AUDIO_SOURCE_MEMORY) < 0)) + { + perror("DVB AUDIO SELECT SOURCE: "); + return -1; + } + if((ioctl(vo_mpegpes_fd2,AUDIO_PLAY) < 0)) + { + perror("DVB AUDIO PLAY: "); + return -1; + } + if((ioctl(vo_mpegpes_fd2,AUDIO_SET_AV_SYNC, true) < 0)) + { + perror("DVB AUDIO SET AV SYNC: "); + return -1; + } + //FIXME: in vo_mpegpes audio was inited as MUTEd + if((ioctl(vo_mpegpes_fd2,AUDIO_SET_MUTE, false) < 0)) + { + perror("DVB AUDIO SET MUTE: "); + return -1; + } + return vo_mpegpes_fd2; +} +#endif + +static int preinit(const char *arg) +{ + int card = 1; + char *ao_file = NULL; + + opt_t subopts[] = { + {"card", OPT_ARG_INT, &card, NULL}, + {"file", OPT_ARG_MSTRZ, &ao_file, NULL}, + {NULL} + }; + + if(subopt_parse(ao_subdevice, subopts) != 0) + { + mp_msg(MSGT_VO, MSGL_ERR, "AO_MPEGPES, Unrecognized options\n"); + return -1; + } + if((card < 1) || (card > 4)) + { + mp_msg(MSGT_VO, MSGL_ERR, "DVB card number must be between 1 and 4\n"); + return -1; + } + card--; #ifdef HAVE_DVB - if(vo_mpegpes_fd2<0) return 0; // couldn't open audio dev + if(!ao_file) + return init_device(card); +#else + if(!ao_file) + { + if(vo_mpegpes_fd >= 0) + { + vo_mpegpes_fd2 = vo_mpegpes_fd; + return vo_mpegpes_fd2; //video fd + } + else + ao_file = "audiograb.mpg"; + } +#endif + + vo_mpegpes_fd2=open(ao_file,O_WRONLY|O_CREAT,0666); + if(vo_mpegpes_fd2<0) + { + perror("ao_mpegpes"); + return -1; + } + return vo_mpegpes_fd2; +} + +static int my_ao_write(unsigned char* data,int len){ + int orig_len = len; +#ifdef HAVE_DVB +#define NFD 1 + struct pollfd pfd[NFD]; + + pfd[0].fd = vo_mpegpes_fd2; + pfd[0].events = POLLOUT; + + while(len>0){ + if(poll(pfd,NFD,1)){ + if(pfd[0].revents & POLLOUT){ + int ret=write(vo_mpegpes_fd2,data,len); + if(ret<=0){ + perror("write"); + usleep(0); + } else { + len-=ret; + data+=ret; + } + } else usleep(1000); + } + } + #else - if(vo_mpegpes_fd<0) return 0; // no file + if(vo_mpegpes_fd2<0) return 0; // no file + write(vo_mpegpes_fd2,data,len); // write to file #endif + return orig_len; +} + + +// open & setup audio device +// return: 1=success 0=fail +static int init(int rate,int channels,int format,int flags){ + if(preinit(NULL)<0) return 0; ao_data.channels=2; ao_data.outburst=2000; @@ -161,6 +289,8 @@ extern int vo_pts; static int get_space(void){ float x=(float)(vo_pts-ao_data.pts)/90000.0; int y; + //FIXME: is it correct? + if(vo_mpegpes_fd < 0) return 32000; //not using -vo mpegpes // printf("vo_pts: %5.3f ao_pts: %5.3f\n",vo_pts/90000.0,ao_data.pts/90000.0); if(x<=0) return 0; y=freq*4*x;y/=ao_data.outburst;y*=ao_data.outburst; @@ -175,7 +305,7 @@ static int get_space(void){ static int play(void* data,int len,int flags){ // printf("\nao_mpegpes: play(%d) freq=%d\n",len,freq_id); if(ao_data.format==AF_FORMAT_MPEG2) - send_pes_packet(data,len,0x1C0,ao_data.pts); + send_mpeg_pes_packet (data, len, 0x1C0, ao_data.pts, 1, my_ao_write); else { int i; unsigned short *s=data; @@ -183,7 +313,7 @@ static int play(void* data,int len,int flags){ // printf("ao_mpegpes: len=%d \n",len); if(ao_data.format==AF_FORMAT_S16_LE || ao_data.format==AF_FORMAT_AC3) for(i=0;i<len/2;i++) s[i]=(s[i]>>8)|(s[i]<<8); // le<->be - send_lpcm_packet(data,len,0xA0,ao_data.pts,freq_id); + send_mpeg_lpcm_packet(data, len, 0xA0, ao_data.pts, freq_id, my_ao_write); } return len; } |