[PATCH] mencoder: Support flushing audio encoders at end of stream.
--- libmpcodecs/ae_lame.c | 4 +++- libmpcodecs/ae_twolame.c | 3 +++ mencoder.c | 6 ++++-- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/libmpcodecs/ae_lame.c b/libmpcodecs/ae_lame.c index 435a8ba..699eb29 100644 --- a/libmpcodecs/ae_lame.c +++ b/libmpcodecs/ae_lame.c @@ -136,7 +136,9 @@ static int get_frame_size(audio_encoder_t *encoder) static int encode_lame(audio_encoder_t *encoder, uint8_t *dest, void *src, int len, int max_size) { int n = 0; - if(encoder->params.channels == 1) + if (!src) + n = lame_encode_flush(lame, dest, max_size); + else if (encoder->params.channels == 1) n = lame_encode_buffer(lame, (short *)src, (short *)src, len/2, dest, max_size); else n = lame_encode_buffer_interleaved(lame,(short *)src, len/4, dest, max_size); diff --git a/libmpcodecs/ae_twolame.c b/libmpcodecs/ae_twolame.c index 0ffe4dd..91ea7ad 100644 --- a/libmpcodecs/ae_twolame.c +++ b/libmpcodecs/ae_twolame.c @@ -112,6 +112,9 @@ static int encode_twolame(audio_encoder_t *encoder, uint8_t *dest, void *src, in mpae_twolame_ctx *ctx = encoder->priv; int ret_size = 0, r2; + if (!src) + return twolame_encode_flush(ctx->twolame_ctx, dest, max_size); + len /= (2*encoder->params.channels); ret_size = twolame_encode_buffer_interleaved(ctx->twolame_ctx, src, len, dest, max_size); r2 = mp_decode_mp3_header(dest); diff --git a/mencoder.c b/mencoder.c index 671d4c2..777adef 100644 --- a/mencoder.c +++ b/mencoder.c @@ -1340,7 +1340,7 @@ if(sh_audio){ len = dec_audio(sh_audio, aencoder->decode_buffer, len); mux_a->buffer_len += aencoder->encode(aencoder, mux_a->buffer + mux_a->buffer_len, - aencoder->decode_buffer, len, mux_a->buffer_size-mux_a->buffer_len); + len <= 0 && sh_audio->ds->eof ? NULL : aencoder->decode_buffer, len, mux_a->buffer_size-mux_a->buffer_len); if(mux_a->buffer_len < mux_a->wf->nBlockAlign) len = 0; else @@ -1360,9 +1360,11 @@ if(sh_audio){ break; } len = dec_audio(sh_audio,aencoder->decode_buffer, aencoder->decode_buffer_size); + // try flushing encoder + if (len <= 0 && sh_audio->ds->eof) + len = aencoder->encode(aencoder, mux_a->buffer + mux_a->buffer_len, NULL, 0, mux_a->buffer_size-mux_a->buffer_len); if(len <= 0) { - len = 0; break; } len = aencoder->encode(aencoder, mux_a->buffer + mux_a->buffer_len, aencoder->decode_buffer, len, mux_a->buffer_size-mux_a->buffer_len); -- 2.0.0.rc0
--- libmpcodecs/ae_lame.c | 4 +++- libmpcodecs/ae_twolame.c | 3 +++ mencoder.c | 13 ++++++++----- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/libmpcodecs/ae_lame.c b/libmpcodecs/ae_lame.c index 435a8ba..699eb29 100644 --- a/libmpcodecs/ae_lame.c +++ b/libmpcodecs/ae_lame.c @@ -136,7 +136,9 @@ static int get_frame_size(audio_encoder_t *encoder) static int encode_lame(audio_encoder_t *encoder, uint8_t *dest, void *src, int len, int max_size) { int n = 0; - if(encoder->params.channels == 1) + if (!src) + n = lame_encode_flush(lame, dest, max_size); + else if (encoder->params.channels == 1) n = lame_encode_buffer(lame, (short *)src, (short *)src, len/2, dest, max_size); else n = lame_encode_buffer_interleaved(lame,(short *)src, len/4, dest, max_size); diff --git a/libmpcodecs/ae_twolame.c b/libmpcodecs/ae_twolame.c index ba4aca4..1a70061 100644 --- a/libmpcodecs/ae_twolame.c +++ b/libmpcodecs/ae_twolame.c @@ -112,6 +112,9 @@ static int encode_twolame(audio_encoder_t *encoder, uint8_t *dest, void *src, in mpae_twolame_ctx *ctx = encoder->priv; int ret_size = 0, r2; + if (!src) + return twolame_encode_flush(ctx->twolame_ctx, dest, max_size); + len /= (2*encoder->params.channels); ret_size = twolame_encode_buffer_interleaved(ctx->twolame_ctx, src, len, dest, max_size); r2 = mp_decode_mp3_header(dest); diff --git a/mencoder.c b/mencoder.c index 671d4c2..4e95fa7 100644 --- a/mencoder.c +++ b/mencoder.c @@ -1340,7 +1340,7 @@ if(sh_audio){ len = dec_audio(sh_audio, aencoder->decode_buffer, len); mux_a->buffer_len += aencoder->encode(aencoder, mux_a->buffer + mux_a->buffer_len, - aencoder->decode_buffer, len, mux_a->buffer_size-mux_a->buffer_len); + len <= 0 && sh_audio->ds->eof ? NULL : aencoder->decode_buffer, len, mux_a->buffer_size-mux_a->buffer_len); if(mux_a->buffer_len < mux_a->wf->nBlockAlign) len = 0; else @@ -1362,10 +1362,13 @@ if(sh_audio){ len = dec_audio(sh_audio,aencoder->decode_buffer, aencoder->decode_buffer_size); if(len <= 0) { - len = 0; - break; - } - len = aencoder->encode(aencoder, mux_a->buffer + mux_a->buffer_len, aencoder->decode_buffer, len, mux_a->buffer_size-mux_a->buffer_len); + // try flushing encoder + if (sh_audio->ds->eof) + len = aencoder->encode(aencoder, mux_a->buffer + mux_a->buffer_len, NULL, 0, mux_a->buffer_size-mux_a->buffer_len); + if (len <= 0) + break; + } else + len = aencoder->encode(aencoder, mux_a->buffer + mux_a->buffer_len, aencoder->decode_buffer, len, mux_a->buffer_size-mux_a->buffer_len); mux_a->buffer_len += len; } } -- 2.0.0.rc0
On Tue, May 06, 2014 at 08:31:35PM +0200, Reimar Döffinger wrote:
--- libmpcodecs/ae_lame.c | 4 +++- libmpcodecs/ae_twolame.c | 3 +++ mencoder.c | 6 ++++-- 3 files changed, 10 insertions(+), 3 deletions(-)
If you haven't guessed it this one was buggy, I was trying too hard to make the code simpler and broke it instead... Next one passed basic testing, but nothing beyond that. I expect it will end up fixing the hangs on EOF as well, but it is not meant as a proper fix for that issue.
On Wed, May 7, 2014 at 4:01 AM, Reimar Döffinger <Reimar.Doeffinger@gmx.de> wrote:
+ // try flushing encoder + if (len <= 0 && sh_audio->ds->eof) + len = aencoder->encode(aencoder, mux_a->buffer + mux_a->buffer_len, NULL, 0, mux_a->buffer_size-mux_a->buffer_len);
Have you checked that lavc and all other codecs properly handle a NULL src pointer? Wouldn't it be better to add another function to the aencoder struct so that we can do aencoder->flush(mux_a->buffer+...) rather than overload a function with multiple meanings? Also, I don't see anything which is going to trigger the lavc's own frame padding here - does it do it automatically? Kieran
On 07.05.2014, at 15:59, Kieran Clancy <clancy.kieran+mplayer@gmail.com> wrote:
On Wed, May 7, 2014 at 4:01 AM, Reimar Döffinger <Reimar.Doeffinger@gmx.de> wrote:
+ // try flushing encoder + if (len <= 0 && sh_audio->ds->eof) + len = aencoder->encode(aencoder, mux_a->buffer + mux_a->buffer_len, NULL, 0, mux_a->buffer_size-mux_a->buffer_len);
Have you checked that lavc and all other codecs properly handle a NULL src pointer?
Which "others"? We don't have that many, I think toolame is the only one remaining. Note that len will be 0, so if it dereferences the pointer I'd call that a bug.
Wouldn't it be better to add another function to the aencoder struct so that we can do aencoder->flush(mux_a->buffer+...) rather than overload a function with multiple meanings?
No, because:
Also, I don't see anything which is going to trigger the lavc's own frame padding here - does it do it automatically?
It is triggered by a NULL pointer, so this just makes MPlayer follow FFmpeg API. (though it will need some minor special handling if/when we switch to encode_audio2 API)
participants (2)
-
Kieran Clancy -
Reimar Döffinger