mirror of
https://github.com/mpv-player/mpv
synced 2025-02-03 05:31:34 +00:00
Improved A-V sync, patch by Ed Wildgoose [lists(at)wildgooses<dot>com].
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@13890 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
parent
6809f8f51a
commit
cd72d2f203
@ -10,6 +10,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <jack/jack.h>
|
||||||
|
|
||||||
#include "audio_out.h"
|
#include "audio_out.h"
|
||||||
#include "audio_out_internal.h"
|
#include "audio_out_internal.h"
|
||||||
@ -20,6 +21,8 @@
|
|||||||
//#include "bio2jack.h"
|
//#include "bio2jack.h"
|
||||||
|
|
||||||
static int driver = 0;
|
static int driver = 0;
|
||||||
|
long latency = 0;
|
||||||
|
long approx_bytes_in_jackd = 0;
|
||||||
|
|
||||||
//bio2jack stuff:
|
//bio2jack stuff:
|
||||||
#define ERR_SUCCESS 0
|
#define ERR_SUCCESS 0
|
||||||
@ -34,6 +37,7 @@ void JACK_Reset(int deviceID); /* free all buffered data and reset several value
|
|||||||
long JACK_Write(int deviceID, char *data, unsigned long bytes); /* returns the number of bytes written */
|
long JACK_Write(int deviceID, char *data, unsigned long bytes); /* returns the number of bytes written */
|
||||||
long JACK_GetJackLatency(int deviceID); /* return the latency in milliseconds of jack */
|
long JACK_GetJackLatency(int deviceID); /* return the latency in milliseconds of jack */
|
||||||
int JACK_SetState(int deviceID, enum status_enum state); /* playing, paused, stopped */
|
int JACK_SetState(int deviceID, enum status_enum state); /* playing, paused, stopped */
|
||||||
|
int JACK_SetAllVolume(int deviceID, unsigned int volume);
|
||||||
int JACK_SetVolumeForChannel(int deviceID, unsigned int channel, unsigned int volume);
|
int JACK_SetVolumeForChannel(int deviceID, unsigned int channel, unsigned int volume);
|
||||||
void JACK_GetVolumeForChannel(int deviceID, unsigned int channel, unsigned int *volume);
|
void JACK_GetVolumeForChannel(int deviceID, unsigned int channel, unsigned int *volume);
|
||||||
//
|
//
|
||||||
@ -71,18 +75,47 @@ static int control(int cmd, void *arg)
|
|||||||
ao_control_vol_t *vol = (ao_control_vol_t *)arg;
|
ao_control_vol_t *vol = (ao_control_vol_t *)arg;
|
||||||
unsigned int l = (int )vol->left,
|
unsigned int l = (int )vol->left,
|
||||||
r = (int )vol->right,
|
r = (int )vol->right,
|
||||||
|
avg_vol = (l + r) / 2,
|
||||||
err = 0;
|
err = 0;
|
||||||
|
|
||||||
if((err = JACK_SetVolumeForChannel(driver, 0, l))) {
|
switch (ao_data.channels) {
|
||||||
|
case 6:
|
||||||
|
if((err = JACK_SetVolumeForChannel(driver, 5, avg_vol))) {
|
||||||
mp_msg(MSGT_AO, MSGL_ERR,
|
mp_msg(MSGT_AO, MSGL_ERR,
|
||||||
"AO: [Jack] Setting left volume failed, error %d\n",err);
|
"AO: [Jack] Setting lfe volume failed, error %d\n",err);
|
||||||
|
return CONTROL_ERROR;
|
||||||
|
}
|
||||||
|
case 5:
|
||||||
|
if((err = JACK_SetVolumeForChannel(driver, 4, avg_vol))) {
|
||||||
|
mp_msg(MSGT_AO, MSGL_ERR,
|
||||||
|
"AO: [Jack] Setting center volume failed, error %d\n",err);
|
||||||
|
return CONTROL_ERROR;
|
||||||
|
}
|
||||||
|
case 4:
|
||||||
|
if((err = JACK_SetVolumeForChannel(driver, 3, r))) {
|
||||||
|
mp_msg(MSGT_AO, MSGL_ERR,
|
||||||
|
"AO: [Jack] Setting rear right volume failed, error %d\n",err);
|
||||||
return CONTROL_ERROR;
|
return CONTROL_ERROR;
|
||||||
}
|
}
|
||||||
|
case 3:
|
||||||
|
if((err = JACK_SetVolumeForChannel(driver, 2, l))) {
|
||||||
|
mp_msg(MSGT_AO, MSGL_ERR,
|
||||||
|
"AO: [Jack] Setting rear left volume failed, error %d\n",err);
|
||||||
|
return CONTROL_ERROR;
|
||||||
|
}
|
||||||
|
case 2:
|
||||||
if((err = JACK_SetVolumeForChannel(driver, 1, r))) {
|
if((err = JACK_SetVolumeForChannel(driver, 1, r))) {
|
||||||
mp_msg(MSGT_AO, MSGL_ERR,
|
mp_msg(MSGT_AO, MSGL_ERR,
|
||||||
"AO: [Jack] Setting right volume failed, error %d\n",err);
|
"AO: [Jack] Setting right volume failed, error %d\n",err);
|
||||||
return CONTROL_ERROR;
|
return CONTROL_ERROR;
|
||||||
}
|
}
|
||||||
|
case 1:
|
||||||
|
if((err = JACK_SetVolumeForChannel(driver, 0, l))) {
|
||||||
|
mp_msg(MSGT_AO, MSGL_ERR,
|
||||||
|
"AO: [Jack] Setting left volume failed, error %d\n",err);
|
||||||
|
return CONTROL_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return CONTROL_OK;
|
return CONTROL_OK;
|
||||||
}
|
}
|
||||||
@ -98,9 +131,20 @@ static int init(int rate_hz, int channels, int format, int flags)
|
|||||||
unsigned long rate;
|
unsigned long rate;
|
||||||
unsigned int bits_per_sample;
|
unsigned int bits_per_sample;
|
||||||
|
|
||||||
|
unsigned long jack_port_flags=JackPortIsPhysical;
|
||||||
|
unsigned int jack_port_name_count=0;
|
||||||
|
const char *jack_port_name=NULL;
|
||||||
|
|
||||||
mp_msg(MSGT_AO, MSGL_INFO, "AO: [Jack] Initialising library.\n");
|
mp_msg(MSGT_AO, MSGL_INFO, "AO: [Jack] Initialising library.\n");
|
||||||
JACK_Init();
|
JACK_Init();
|
||||||
|
|
||||||
|
if (ao_subdevice) {
|
||||||
|
jack_port_flags = 0;
|
||||||
|
jack_port_name_count = 1;
|
||||||
|
jack_port_name = ao_subdevice;
|
||||||
|
mp_msg(MSGT_AO, MSGL_INFO, "AO: [Jack] Trying to use jack device:%s.\n", ao_subdevice);
|
||||||
|
}
|
||||||
|
|
||||||
switch (format) {
|
switch (format) {
|
||||||
case AFMT_U8:
|
case AFMT_U8:
|
||||||
case AFMT_S8:
|
case AFMT_S8:
|
||||||
@ -117,7 +161,8 @@ static int init(int rate_hz, int channels, int format, int flags)
|
|||||||
|
|
||||||
rate = rate_hz;
|
rate = rate_hz;
|
||||||
|
|
||||||
err = JACK_Open(&driver, bits_per_sample, &rate, channels);
|
err = JACK_OpenEx(&driver, bits_per_sample, &rate, channels, channels,
|
||||||
|
&jack_port_name, jack_port_name_count, jack_port_flags);
|
||||||
|
|
||||||
/* if sample rates doesn't match try to open device with jack's rate and
|
/* if sample rates doesn't match try to open device with jack's rate and
|
||||||
* let mplayer convert it (rate now contains that which jackd use) */
|
* let mplayer convert it (rate now contains that which jackd use) */
|
||||||
@ -125,7 +170,8 @@ static int init(int rate_hz, int channels, int format, int flags)
|
|||||||
mp_msg(MSGT_AO, MSGL_INFO,
|
mp_msg(MSGT_AO, MSGL_INFO,
|
||||||
"AO: [Jack] Sample rate mismatch, trying to resample.\n");
|
"AO: [Jack] Sample rate mismatch, trying to resample.\n");
|
||||||
|
|
||||||
err = JACK_Open(&driver, bits_per_sample, &rate, channels);
|
err = JACK_OpenEx(&driver, bits_per_sample, &rate, channels, channels,
|
||||||
|
&jack_port_name, jack_port_name_count, jack_port_flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* any other error */
|
/* any other error */
|
||||||
@ -135,11 +181,23 @@ static int init(int rate_hz, int channels, int format, int flags)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err = JACK_SetAllVolume(driver, 100);
|
||||||
|
if(err != ERR_SUCCESS) {
|
||||||
|
// This is not fatal, but would be peculiar...
|
||||||
|
mp_msg(MSGT_AO, MSGL_ERR,
|
||||||
|
"AO: [Jack] JACK_SetAllVolume() failed, error %d\n", err);
|
||||||
|
}
|
||||||
|
|
||||||
|
latency = JACK_GetJackLatency(driver);
|
||||||
|
|
||||||
ao_data.format = format;
|
ao_data.format = format;
|
||||||
ao_data.channels = channels;
|
ao_data.channels = channels;
|
||||||
ao_data.samplerate = rate;
|
ao_data.samplerate = rate;
|
||||||
ao_data.bps = ( rate * channels * m );
|
ao_data.bps = ( rate * channels * m );
|
||||||
|
|
||||||
|
// Rather rough way to find out the rough number of bytes buffered
|
||||||
|
approx_bytes_in_jackd = JACK_GetJackBufferedBytes(driver) * 2;
|
||||||
|
|
||||||
mp_msg(MSGT_AO, MSGL_INFO,
|
mp_msg(MSGT_AO, MSGL_INFO,
|
||||||
"AO: [Jack] OK. I'm ready to go (%d Hz/%d channels/%d bit)\n",
|
"AO: [Jack] OK. I'm ready to go (%d Hz/%d channels/%d bit)\n",
|
||||||
ao_data.samplerate, ao_data.channels, bits_per_sample);
|
ao_data.samplerate, ao_data.channels, bits_per_sample);
|
||||||
@ -152,8 +210,6 @@ static void uninit(int immed)
|
|||||||
{
|
{
|
||||||
int errval = 0;
|
int errval = 0;
|
||||||
|
|
||||||
JACK_Reset(driver);
|
|
||||||
|
|
||||||
if((errval = JACK_Close(driver)))
|
if((errval = JACK_Close(driver)))
|
||||||
mp_msg(MSGT_AO, MSGL_ERR,
|
mp_msg(MSGT_AO, MSGL_ERR,
|
||||||
"AO: [Jack] error closing device, error %d\n", errval);
|
"AO: [Jack] error closing device, error %d\n", errval);
|
||||||
@ -181,6 +237,9 @@ static void audio_resume()
|
|||||||
static void reset()
|
static void reset()
|
||||||
{
|
{
|
||||||
JACK_Reset(driver);
|
JACK_Reset(driver);
|
||||||
|
latency = JACK_GetJackLatency(driver);
|
||||||
|
// Rather rough way to find out the rough number of bytes buffered
|
||||||
|
approx_bytes_in_jackd = JACK_GetJackBufferedBytes(driver) * 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -192,6 +251,8 @@ static int get_space()
|
|||||||
|
|
||||||
static float get_delay()
|
static float get_delay()
|
||||||
{
|
{
|
||||||
return (float )JACK_GetJackLatency(driver);
|
float ret = 0;
|
||||||
|
ret = (JACK_GetBytesStored(driver) + approx_bytes_in_jackd + latency) / (float)ao_data.bps;
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user