diff options
author | Uoti Urpala <uau@mplayer2.org> | 2011-07-31 16:31:07 +0300 |
---|---|---|
committer | Uoti Urpala <uau@mplayer2.org> | 2011-07-31 16:31:07 +0300 |
commit | 9d25699c5831c5188968c8ed69d32a5d534b8ff6 (patch) | |
tree | 42a154e2939755af7fa30e4ac9a94be90ef99280 | |
parent | ce9ce9d0c3a7e4e15d816a824f7312ad4c3c7cfc (diff) | |
download | mpv-9d25699c5831c5188968c8ed69d32a5d534b8ff6.tar.bz2 mpv-9d25699c5831c5188968c8ed69d32a5d534b8ff6.tar.xz |
audio: export audio pts to AO drivers
Currently the pts value is not directly used by any AO. Will be used
by encoding code.
-rw-r--r-- | libao2/ao_ivtv.c | 6 | ||||
-rw-r--r-- | libao2/ao_mpegpes.c | 8 | ||||
-rw-r--r-- | libao2/ao_v4l2.c | 6 | ||||
-rw-r--r-- | libao2/audio_out.h | 3 | ||||
-rw-r--r-- | mplayer.c | 45 |
5 files changed, 40 insertions, 28 deletions
diff --git a/libao2/ao_ivtv.c b/libao2/ao_ivtv.c index 540bc2f38a..e05537cbd8 100644 --- a/libao2/ao_ivtv.c +++ b/libao2/ao_ivtv.c @@ -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; } diff --git a/libao2/ao_mpegpes.c b/libao2/ao_mpegpes.c index 0ede363864..fe3f20fc85 100644 --- a/libao2/ao_mpegpes.c +++ b/libao2/ao_mpegpes.c @@ -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; } diff --git a/libao2/ao_v4l2.c b/libao2/ao_v4l2.c index 2eac1031e5..2bc74379a0 100644 --- a/libao2/ao_v4l2.c +++ b/libao2/ao_v4l2.c @@ -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; } diff --git a/libao2/audio_out.h b/libao2/audio_out.h index 628b9c3ae7..e96e123700 100644 --- a/libao2/audio_out.h +++ b/libao2/audio_out.h @@ -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; @@ -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 |