mirror of
https://github.com/mpv-player/mpv
synced 2025-02-27 10:50:53 +00:00
Patch by D. Holm to make audio with dxr3 working.
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@3187 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
parent
22c633f15e
commit
d9dca0c290
29
DOCS/DXR3
29
DOCS/DXR3
@ -1,6 +1,11 @@
|
||||
DXR3/H+ video/audio output plugins manual by David Holm
|
||||
=======================================================
|
||||
|
||||
2001-11-27: -ao dxr3 now works, still a few bugs though
|
||||
you might have to reload the em8300 modules
|
||||
after a playback or you might get static the
|
||||
next time you use the dxr3 audio interface.
|
||||
|
||||
1. Introduction
|
||||
|
||||
The DXR3 and Hollywood+ are two not too different mpeg-(1/2) and ac3
|
||||
@ -64,8 +69,7 @@ These days, you have two uses for this card:
|
||||
|
||||
After installation you will have two new outdevices in mplayer:
|
||||
-vo dxr3 For video output
|
||||
-ao dxr3 For audio output (due to an unresolved bug
|
||||
this is not recommended/useful!)
|
||||
-ao dxr3 For audio output
|
||||
|
||||
MPEG-1, MPEG-2, VCD and DVD Notes
|
||||
There are some notes to take into account here for optimum playback.
|
||||
@ -83,22 +87,17 @@ When playing divx's add "-vc odivx", if you get any other divx codec
|
||||
to run faster tell me which one because I'll be interested in how it
|
||||
could possibly be any faster than OpenDivX4Linux...
|
||||
|
||||
Unsupported Codecs:
|
||||
If you ever get a codec unsupported message, lookup the codec in the
|
||||
codecs.conf file (search for "videocodec <codecname>"), copy the entire
|
||||
codec section and send it to me and I'll make sure it works with the
|
||||
next patch (or the next after that if I have a thousand things to take
|
||||
care of first ;) my e-mail is at the bottom of this page.
|
||||
|
||||
4. Todo
|
||||
|
||||
* Scale video played using windows codecs (High)
|
||||
* Make the osd use the subpic feature of the dxr3 (almost done)(High)
|
||||
* Driver options (probably not until libvo2) (Medium)
|
||||
Other codecs:
|
||||
Currently they don't work. I'm working on implementing libvo2 which
|
||||
will be a much more convenient and faster way of working with
|
||||
vo<->codec interaction. If libvo2 takes longer to develop than I
|
||||
have estimated perhaps I'll add more codec support to libvo. Otherwise
|
||||
you'll just have to wait for libvo2. (there is an implementation
|
||||
for other codecs, but I think it's pretty broken currently ;)
|
||||
|
||||
|
||||
|
||||
5. Contacting me
|
||||
4. Contacting me
|
||||
|
||||
You can contact me either by e-mailing me, <dholm@iname.com> or by using
|
||||
icq: 798427
|
||||
|
@ -16,6 +16,9 @@
|
||||
#include "audio_out.h"
|
||||
#include "audio_out_internal.h"
|
||||
|
||||
void perror( const char *s );
|
||||
#include <errno.h>
|
||||
int sys_nerr;
|
||||
extern int verbose;
|
||||
|
||||
static ao_info_t info =
|
||||
@ -28,15 +31,6 @@ static ao_info_t info =
|
||||
|
||||
LIBAO_EXTERN(dxr3)
|
||||
|
||||
// there are some globals:
|
||||
// ao_samplerate
|
||||
// ao_channels
|
||||
// ao_format
|
||||
// ao_bps
|
||||
// ao_outburst
|
||||
// ao_buffersize
|
||||
|
||||
//static char *em8300_ma="/dev/em8300_ma";
|
||||
static audio_buf_info dxr3_buf_info;
|
||||
static int fd_control = 0, fd_audio = 0;
|
||||
|
||||
@ -73,30 +67,33 @@ static int init(int rate,int channels,int format,int flags)
|
||||
printf("AO: [dxr3] Can't open em8300 control /dev/em8300\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
ao_format = format;
|
||||
if( ioctl (fd_audio, SNDCTL_DSP_SETFMT, &ao_format) < 0 )
|
||||
|
||||
ioctl(fd_audio, SNDCTL_DSP_RESET, NULL);
|
||||
ao_data.format = format;
|
||||
if( ioctl (fd_audio, SNDCTL_DSP_SETFMT, &ao_data.format) < 0 )
|
||||
printf( "AO: [dxr3] Unable to set audio format\n" );
|
||||
if(format == AFMT_AC3 && ao_format != AFMT_AC3)
|
||||
if(format == AFMT_AC3 && ao_data.format != AFMT_AC3)
|
||||
{
|
||||
printf("AO: [dxr3] Can't set audio device /dev/em8300_ma to AC3 output\n");
|
||||
return 0;
|
||||
}
|
||||
printf("AO: [dxr3] Sample format: %s (requested: %s)\n",
|
||||
audio_out_format_name(ao_format), audio_out_format_name(format));
|
||||
audio_out_format_name(ao_data.format), audio_out_format_name(format));
|
||||
|
||||
if(format != AFMT_AC3)
|
||||
{
|
||||
ao_channels=channels-1;
|
||||
if( ioctl (fd_audio, SNDCTL_DSP_STEREO, &ao_channels) < 0 )
|
||||
ao_data.channels=channels-1;
|
||||
if( ioctl (fd_audio, SNDCTL_DSP_STEREO, &ao_data.channels) < 0 )
|
||||
printf( "AO: [dxr3] Unable to set number of channels\n" );
|
||||
|
||||
// set rate
|
||||
ao_samplerate=rate;
|
||||
if( ioctl (fd_audio, SNDCTL_DSP_SPEED, &ao_samplerate) < 0 )
|
||||
ao_data.bps = (channels+1)*rate;
|
||||
ao_data.samplerate=rate;
|
||||
if( ioctl (fd_audio, SNDCTL_DSP_SPEED, &ao_data.samplerate) < 0 )
|
||||
printf( "AO: [dxr3] Unable to set samplerate\n" );
|
||||
printf("AO: [dxr3] Using %d Hz samplerate (requested: %d)\n",ao_samplerate,rate);
|
||||
printf("AO: [dxr3] Using %d Hz samplerate (requested: %d)\n",ao_data.samplerate,rate);
|
||||
}
|
||||
else ao_data.bps *= 2;
|
||||
|
||||
if( ioctl(fd_audio, SNDCTL_DSP_GETOSPACE, &dxr3_buf_info)==-1 )
|
||||
{
|
||||
@ -104,44 +101,20 @@ static int init(int rate,int channels,int format,int flags)
|
||||
printf("AO: [dxr3] Driver doesn't support SNDCTL_DSP_GETOSPACE :-(\n");
|
||||
if( ioctl( fd_audio, SNDCTL_DSP_GETBLKSIZE, &r) ==-1 )
|
||||
{
|
||||
printf( "AO: [dxr3] %d bytes/frag (config.h)\n", ao_outburst );
|
||||
printf( "AO: [dxr3] %d bytes/frag (config.h)\n", ao_data.outburst );
|
||||
}
|
||||
else
|
||||
{
|
||||
ao_outburst=r;
|
||||
printf( "AO: [dxr3] %d bytes/frag (GETBLKSIZE)\n",ao_outburst);
|
||||
ao_data.outburst=r;
|
||||
printf( "AO: [dxr3] %d bytes/frag (GETBLKSIZE)\n",ao_data.outburst);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("AO: [dxr3] frags: %3d/%d (%d bytes/frag) free: %6d\n",
|
||||
dxr3_buf_info.fragments+1, dxr3_buf_info.fragstotal, dxr3_buf_info.fragsize, dxr3_buf_info.bytes);
|
||||
if(ao_buffersize==-1) ao_buffersize=dxr3_buf_info.bytes;
|
||||
ao_outburst=dxr3_buf_info.fragsize;
|
||||
}
|
||||
|
||||
if(ao_buffersize==-1){
|
||||
// Measuring buffer size:
|
||||
void* data;
|
||||
ao_buffersize=0;
|
||||
#ifdef HAVE_AUDIO_SELECT
|
||||
data=malloc(ao_outburst); memset(data,0,ao_outburst);
|
||||
while(ao_buffersize<0x40000){
|
||||
fd_set rfds;
|
||||
struct timeval tv;
|
||||
FD_ZERO(&rfds); FD_SET(fd_audio,&rfds);
|
||||
tv.tv_sec=0; tv.tv_usec = 0;
|
||||
if(!select(fd_audio+1, NULL, &rfds, NULL, &tv)) break;
|
||||
write(fd_audio,data,ao_outburst);
|
||||
ao_buffersize+=ao_outburst;
|
||||
}
|
||||
free(data);
|
||||
if(ao_buffersize==0){
|
||||
printf("\nAO: [dxr3] *** Your audio driver DOES NOT support select() ***\n");
|
||||
printf("Recompile mplayer with #undef HAVE_AUDIO_SELECT in config.h !\n\n");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
ao_data.buffersize=(dxr3_buf_info.bytes/2)-1;
|
||||
ao_data.outburst=dxr3_buf_info.fragsize;
|
||||
}
|
||||
|
||||
ioval = EM8300_PLAYMODE_PLAY;
|
||||
@ -159,6 +132,7 @@ static void uninit()
|
||||
if( ioctl(fd_audio, SNDCTL_DSP_RESET, NULL) < 0 )
|
||||
printf( "AO: [dxr3] Unable to reset device\n" );
|
||||
close( fd_audio );
|
||||
close( fd_control ); /* Just in case */
|
||||
}
|
||||
|
||||
// stop playing and empty buffers (for seeking/pause)
|
||||
@ -171,8 +145,6 @@ static void reset()
|
||||
// stop playing, keep buffers (for pause)
|
||||
static void audio_pause()
|
||||
{
|
||||
// for now, just call reset();
|
||||
// reset();
|
||||
int ioval;
|
||||
fd_control = open( "/dev/em8300", O_WRONLY );
|
||||
if( fd_control < 0 )
|
||||
@ -202,35 +174,35 @@ static void audio_resume()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// return: how many bytes can be played without blocking
|
||||
static int get_space()
|
||||
{
|
||||
int space = 0;
|
||||
if( ioctl(fd_audio, SNDCTL_DSP_GETOSPACE, &dxr3_buf_info) < 0 )
|
||||
if( ioctl(fd_audio, SNDCTL_DSP_GETODELAY, &space) < 0 )
|
||||
{
|
||||
printf( "AO: [dxr3] Unable to get free space in buffer\n" );
|
||||
return 0;
|
||||
printf( "AO: [dxr3] Unable to get unplayed bytes in buffer\n" );
|
||||
return ao_data.outburst;
|
||||
}
|
||||
|
||||
space = dxr3_buf_info.fragments*dxr3_buf_info.fragsize;
|
||||
space = ao_data.buffersize - space;
|
||||
return space;
|
||||
}
|
||||
|
||||
static int play(void* data,int len,int flags)
|
||||
{
|
||||
int pts = ao_pts;
|
||||
if( ioctl( fd_audio, EM8300_IOCTL_AUDIO_SETPTS, &pts ) < 0 )
|
||||
if( ioctl( fd_audio, EM8300_IOCTL_AUDIO_SETPTS, &ao_data.pts ) < 0 )
|
||||
printf( "AO: [dxr3] Unable to set pts\n" );
|
||||
return write(fd_audio,data,len);
|
||||
}
|
||||
|
||||
// return: how many unplayed bytes are in the buffer
|
||||
static int get_delay()
|
||||
static float get_delay()
|
||||
{
|
||||
int r=0;
|
||||
if( ioctl(fd_audio, SNDCTL_DSP_GETODELAY, &r) < 0 )
|
||||
int r=0;
|
||||
if( ioctl(fd_audio, SNDCTL_DSP_GETODELAY, &r) < 0 )
|
||||
{
|
||||
printf( "AO: [dxr3] Unable to get unplayed bytes in buffer\n" );
|
||||
return r;
|
||||
return ((float)ao_data.buffersize)/(float)ao_data.bps;
|
||||
}
|
||||
return (((float)r)/(float)ao_data.bps);
|
||||
}
|
||||
|
||||
|
@ -381,7 +381,7 @@ init(uint32_t scr_width, uint32_t scr_height, uint32_t width, uint32_t height, u
|
||||
/* open it */
|
||||
if (avcodec_open(&codec_context, codec) < 0)
|
||||
{
|
||||
printf(stderr, "VO: [dxr3] Could not open codec\n");
|
||||
printf( "VO: [dxr3] Could not open codec\n" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -424,7 +424,6 @@ static void draw_osd(void)
|
||||
|
||||
static uint32_t draw_frame(uint8_t * src[])
|
||||
{
|
||||
int pts = 0;
|
||||
if( img_format == IMGFMT_MPEGPES )
|
||||
{
|
||||
int data_left;
|
||||
@ -432,8 +431,7 @@ static uint32_t draw_frame(uint8_t * src[])
|
||||
unsigned char *data = p->data;
|
||||
|
||||
data_left = p->size;
|
||||
pts = p->timestamp;
|
||||
if( ioctl( fd_video, EM8300_IOCTL_VIDEO_SETPTS, &pts ) < 0 )
|
||||
if( ioctl( fd_video, EM8300_IOCTL_VIDEO_SETPTS, &vo_pts ) < 0 )
|
||||
printf( "VO: [dxr3] Unable to set PTS in draw_frame\n" );
|
||||
while( data_left )
|
||||
data_left -= write( fd_video, &((unsigned char*)p->data)[p->size-data_left], data_left );
|
||||
@ -516,8 +514,7 @@ static uint32_t draw_frame(uint8_t * src[])
|
||||
#undef ONE_HALF
|
||||
#undef FIX(x)
|
||||
//End of ffmpeg code, see ffmpeg.sourceforge.net for terms of license
|
||||
pts = vo_pts;
|
||||
if( ioctl( fd_video, EM8300_IOCTL_VIDEO_SETPTS, &pts ) < 0 )
|
||||
if( ioctl( fd_video, EM8300_IOCTL_VIDEO_SETPTS, &vo_pts ) < 0 )
|
||||
printf( "VO: [dxr3] Unable to set PTS in draw_frame\n" );
|
||||
tmp_size = out_size = avcodec_encode_video(&codec_context, outbuf, outbuf_size, &picture);
|
||||
while( out_size )
|
||||
@ -535,8 +532,8 @@ static uint32_t draw_frame(uint8_t * src[])
|
||||
{
|
||||
}
|
||||
}
|
||||
pts = vo_pts;
|
||||
if( ioctl( fd_video, EM8300_IOCTL_VIDEO_SETPTS, &pts ) < 0 )
|
||||
|
||||
if( ioctl( fd_video, EM8300_IOCTL_VIDEO_SETPTS, &vo_pts ) < 0 )
|
||||
printf( "VO: [dxr3] Unable to set PTS in draw_frame\n" );
|
||||
tmp_size = out_size = avcodec_encode_video(&codec_context, outbuf, outbuf_size, &picture);
|
||||
while( out_size )
|
||||
|
Loading…
Reference in New Issue
Block a user