diff options
author | wm4 <wm4@nowhere> | 2016-08-01 19:59:59 +0200 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2016-08-01 19:59:59 +0200 |
commit | 251299da4f32095da6c406967cb32d7028d2c841 (patch) | |
tree | bc4b03cede74330f53b230a7d5aec3478410a27a | |
parent | 2e3db648b5194a2cd34b40cddce88ffb0ca0f090 (diff) | |
download | mpv-251299da4f32095da6c406967cb32d7028d2c841.tar.bz2 mpv-251299da4f32095da6c406967cb32d7028d2c841.tar.xz |
af_lavcac3enc: fix buffering timestamps calculations
In theory, an encoder could buffer some data.
-rw-r--r-- | audio/filter/af_lavcac3enc.c | 12 |
1 files changed, 9 insertions, 3 deletions
diff --git a/audio/filter/af_lavcac3enc.c b/audio/filter/af_lavcac3enc.c index 153d80ba1c..d0fdab0b08 100644 --- a/audio/filter/af_lavcac3enc.c +++ b/audio/filter/af_lavcac3enc.c @@ -57,6 +57,7 @@ typedef struct af_ac3enc_s { struct mp_audio *pending; // unconsumed input data int in_samples; // samples of input per AC3 frame int out_samples; // upper bound on encoded output per AC3 frame + int64_t encoder_buffered; int cfg_add_iec61937_header; int cfg_bit_rate; @@ -168,6 +169,7 @@ static int control(struct af_instance *af, int cmd, void *arg) s->in_samples = s->lavc_actx->frame_size; mp_audio_realloc(s->input, s->in_samples); s->input->samples = 0; + s->encoder_buffered = 0; return AF_OK; } case AF_CONTROL_RESET: @@ -176,6 +178,7 @@ static int control(struct af_instance *af, int cmd, void *arg) talloc_free(s->pending); s->pending = NULL; s->input->samples = 0; + s->encoder_buffered = 0; return AF_OK; } return AF_UNKNOWN; @@ -198,8 +201,8 @@ static void uninit(struct af_instance* af) static void update_delay(struct af_instance *af) { af_ac3enc_t *s = af->priv; - af->delay = ((s->pending ? s->pending->samples : 0) + s->input->samples) / - (double)s->input->rate; + af->delay = ((s->pending ? s->pending->samples : 0) + s->input->samples + + s->encoder_buffered) / (double)s->input->rate; } static int filter_frame(struct af_instance *af, struct mp_audio *audio) @@ -289,6 +292,7 @@ static int filter_out(struct af_instance *af) MP_FATAL(af, "Encode failed.\n"); goto done; } + s->encoder_buffered += s->input->samples; s->input->samples = 0; } int lavc_ret = avcodec_receive_packet(s->lavc_actx, &pkt); @@ -320,6 +324,8 @@ static int filter_out(struct af_instance *af) MP_DBG(af, "avcodec_encode_audio got %d, pending %d.\n", pkt.size, s->pending->samples + s->input->samples); + s->encoder_buffered -= AC3_FRAME_SIZE; + struct mp_audio *out = mp_audio_pool_get(af->out_pool, af->data, s->out_samples); if (!out) @@ -355,12 +361,12 @@ static int filter_out(struct af_instance *af) swap_16((uint16_t *)(buf + header_len), pkt.size / 2); out->samples = frame_size / out->sstride; af_add_output_frame(af, out); - update_delay(af); err = 0; done: av_packet_unref(&pkt); av_frame_free(&frame); + update_delay(af); return err; } |