mirror of
https://github.com/mpv-player/mpv
synced 2025-01-16 22:37:28 +01:00
audio: export audio pts to AO drivers
Currently the pts value is not directly used by any AO. Will be used by encoding code.
This commit is contained in:
parent
ce9ce9d0c3
commit
9d25699c58
@ -78,7 +78,7 @@ init (int rate, int channels, int format, int flags)
|
||||
ao_data.format = AF_FORMAT_MPEG2;
|
||||
ao_data.buffersize = 2048;
|
||||
ao_data.bps = rate * 2 * 2;
|
||||
ao_data.pts = 0;
|
||||
ao_data.brokenpts = 0;
|
||||
freq = rate;
|
||||
|
||||
/* check for supported audio rate */
|
||||
@ -127,7 +127,7 @@ get_space (void)
|
||||
float x;
|
||||
int y;
|
||||
|
||||
x = (float) (vo_pts - ao_data.pts) / 90000.0;
|
||||
x = (float) (vo_pts - ao_data.brokenpts) / 90000.0;
|
||||
if (x <= 0)
|
||||
return 0;
|
||||
|
||||
@ -148,7 +148,7 @@ play (void *data, int len, int flags)
|
||||
if (ao_data.format != AF_FORMAT_MPEG2)
|
||||
return 0;
|
||||
|
||||
send_mpeg_pes_packet (data, len, MPEG_AUDIO_ID, ao_data.pts, 2, ivtv_write);
|
||||
send_mpeg_pes_packet (data, len, MPEG_AUDIO_ID, ao_data.brokenpts, 2, ivtv_write);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
@ -302,11 +302,11 @@ extern int vo_pts;
|
||||
|
||||
// return: how many bytes can be played without blocking
|
||||
static int get_space(void){
|
||||
float x=(float)(vo_pts-ao_data.pts)/90000.0;
|
||||
float x=(float)(vo_pts-ao_data.brokenpts)/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);
|
||||
// printf("vo_pts: %5.3f ao_pts: %5.3f\n",vo_pts/90000.0,ao_data.brokenpts/90000.0);
|
||||
if(x<=0) return 0;
|
||||
y=freq*4*x;y/=ao_data.outburst;y*=ao_data.outburst;
|
||||
if(y>32000) y=32000;
|
||||
@ -320,11 +320,11 @@ 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_mpeg_pes_packet (data, len, 0x1C0, ao_data.pts, 1, my_ao_write);
|
||||
send_mpeg_pes_packet (data, len, 0x1C0, ao_data.brokenpts, 1, my_ao_write);
|
||||
else {
|
||||
// if(len>2000) len=2000;
|
||||
// printf("ao_mpegpes: len=%d \n",len);
|
||||
send_mpeg_lpcm_packet(data, len, 0xA0, ao_data.pts, freq_id, my_ao_write);
|
||||
send_mpeg_lpcm_packet(data, len, 0xA0, ao_data.brokenpts, freq_id, my_ao_write);
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
@ -75,7 +75,7 @@ init (int rate, int channels, int format, int flags)
|
||||
ao_data.format = AF_FORMAT_MPEG2;
|
||||
ao_data.buffersize = 2048;
|
||||
ao_data.bps = rate * 2 * 2;
|
||||
ao_data.pts = 0;
|
||||
ao_data.brokenpts = 0;
|
||||
freq = rate;
|
||||
|
||||
/* check for supported audio rate */
|
||||
@ -124,7 +124,7 @@ get_space (void)
|
||||
float x;
|
||||
int y;
|
||||
|
||||
x = (float) (vo_pts - ao_data.pts) / 90000.0;
|
||||
x = (float) (vo_pts - ao_data.brokenpts) / 90000.0;
|
||||
if (x <= 0)
|
||||
return 0;
|
||||
|
||||
@ -145,7 +145,7 @@ play (void *data, int len, int flags)
|
||||
if (ao_data.format != AF_FORMAT_MPEG2)
|
||||
return 0;
|
||||
|
||||
send_mpeg_pes_packet (data, len, MPEG_AUDIO_ID, ao_data.pts, 2, v4l2_write);
|
||||
send_mpeg_pes_packet (data, len, MPEG_AUDIO_ID, ao_data.brokenpts, 2, v4l2_write);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
@ -72,7 +72,8 @@ struct ao {
|
||||
int bps;
|
||||
int outburst;
|
||||
int buffersize;
|
||||
int pts;
|
||||
int brokenpts;
|
||||
double pts;
|
||||
struct bstr buffer;
|
||||
int buffer_playable_size;
|
||||
bool initialized;
|
||||
|
45
mplayer.c
45
mplayer.c
@ -2377,11 +2377,25 @@ static void adjust_sync(struct MPContext *mpctx, double frame_time)
|
||||
mpctx->total_avsync_change += change;
|
||||
}
|
||||
|
||||
static int write_to_ao(struct MPContext *mpctx, void *data, int len, int flags)
|
||||
static int write_to_ao(struct MPContext *mpctx, void *data, int len, int flags,
|
||||
double pts)
|
||||
{
|
||||
if (mpctx->paused)
|
||||
return 0;
|
||||
return ao_play(mpctx->ao, data, len, flags);
|
||||
struct ao *ao = mpctx->ao;
|
||||
double bps = ao->bps / mpctx->opts.playback_speed;
|
||||
ao->pts = pts;
|
||||
// hack used by some mpeg-writing AOs
|
||||
ao->brokenpts = ((mpctx->sh_video?mpctx->sh_video->timer:0)+mpctx->delay)
|
||||
*90000.0;
|
||||
int played = ao_play(mpctx->ao, data, len, flags);
|
||||
if (played > 0) {
|
||||
mpctx->delay += played / bps;
|
||||
// Keep correct pts for remaining data - could be used to flush
|
||||
// remaining buffer when closing ao.
|
||||
ao->pts += played / bps;
|
||||
}
|
||||
return played;
|
||||
}
|
||||
|
||||
#define ASYNC_PLAY_DONE -3
|
||||
@ -2399,11 +2413,13 @@ static int audio_start_sync(struct MPContext *mpctx, int playsize)
|
||||
|
||||
int bytes;
|
||||
bool did_retry = false;
|
||||
double written_pts;
|
||||
double bps = ao->bps / opts->playback_speed;
|
||||
while (1) {
|
||||
double written_pts = written_audio_pts(mpctx);
|
||||
double ptsdiff = written_pts - mpctx->video_pts - mpctx->delay
|
||||
written_pts = written_audio_pts(mpctx);
|
||||
double ptsdiff = written_pts - mpctx->sh_video->pts - mpctx->delay
|
||||
- audio_delay;
|
||||
bytes = ptsdiff * ao->bps / mpctx->opts.playback_speed;
|
||||
bytes = ptsdiff * bps;
|
||||
bytes -= bytes % (ao->channels * af_fmt2bits(ao->format) / 8);
|
||||
|
||||
// ogg demuxers give packets without timing
|
||||
@ -2451,9 +2467,8 @@ static int audio_start_sync(struct MPContext *mpctx, int playsize)
|
||||
* in playsize. */
|
||||
char *p = malloc(playsize);
|
||||
memset(p, fillbyte, playsize);
|
||||
playsize = write_to_ao(mpctx, p, playsize, 0);
|
||||
write_to_ao(mpctx, p, playsize, 0, written_pts - bytes / bps);
|
||||
free(p);
|
||||
mpctx->delay += opts->playback_speed*playsize/(double)ao->bps;
|
||||
return ASYNC_PLAY_DONE;
|
||||
}
|
||||
mpctx->syncing_audio = false;
|
||||
@ -2480,10 +2495,10 @@ static int fill_audio_out_buffers(struct MPContext *mpctx)
|
||||
if (ao->untimed && mpctx->sh_video && mpctx->delay > 0)
|
||||
return 0;
|
||||
|
||||
// all the current uses of ao->pts seem to be in aos that handle
|
||||
// sync completely wrong; there should be no need to use ao->pts
|
||||
// in get_space()
|
||||
ao->pts = ((mpctx->sh_video?mpctx->sh_video->timer:0)+mpctx->delay)*90000.0;
|
||||
// hack used by some mpeg-writing AOs
|
||||
ao->brokenpts = ((mpctx->sh_video?mpctx->sh_video->timer:0)+mpctx->delay)
|
||||
*90000.0;
|
||||
|
||||
if (mpctx->paused)
|
||||
playsize = 1; // just initialize things (audio pts at least)
|
||||
else
|
||||
@ -2543,18 +2558,14 @@ static int fill_audio_out_buffers(struct MPContext *mpctx)
|
||||
// play audio:
|
||||
current_module="play_audio";
|
||||
|
||||
// Is this pts value actually useful for the aos that access it?
|
||||
// They're obviously badly broken in the way they handle av sync;
|
||||
// would not having access to this make them more broken?
|
||||
ao->pts = ((mpctx->sh_video?mpctx->sh_video->timer:0)+mpctx->delay)*90000.0;
|
||||
int played = write_to_ao(mpctx, ao->buffer.start, playsize, playflags);
|
||||
int played = write_to_ao(mpctx, ao->buffer.start, playsize, playflags,
|
||||
written_audio_pts(mpctx));
|
||||
assert(played % unitsize == 0);
|
||||
ao->buffer_playable_size = playsize - played;
|
||||
|
||||
if (played > 0) {
|
||||
ao->buffer.len -= played;
|
||||
memmove(ao->buffer.start, ao->buffer.start + played, ao->buffer.len);
|
||||
mpctx->delay += opts->playback_speed * played / ao->bps;
|
||||
} else if (!mpctx->paused && audio_eof && ao_get_delay(ao) < .04) {
|
||||
// Sanity check to avoid hanging in case current ao doesn't output
|
||||
// partial chunks and doesn't check for AOPLAY_FINAL_CHUNK
|
||||
|
Loading…
Reference in New Issue
Block a user