From c8c97de4bed1b06c686fe7155e41ecb85d633b34 Mon Sep 17 00:00:00 2001 From: Good Guy Date: Mon, 1 May 2017 15:58:27 -0600 Subject: [PATCH] drain last partial frame in ffmpeg close encoder --- cinelerra-5.1/cinelerra/ffmpeg.C | 31 ++++++++++++++++++++++++------- cinelerra-5.1/cinelerra/ffmpeg.h | 2 ++ 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/cinelerra-5.1/cinelerra/ffmpeg.C b/cinelerra-5.1/cinelerra/ffmpeg.C index 968cb051..10ad0503 100644 --- a/cinelerra-5.1/cinelerra/ffmpeg.C +++ b/cinelerra-5.1/cinelerra/ffmpeg.C @@ -721,31 +721,39 @@ int FFAudioStream::encode(double **samples, int len) if( encode_activate() <= 0 ) return -1; ffmpeg->flow_ctl(); int ret = 0; - int64_t count = load_buffer(samples, len); + int64_t count = samples ? load_buffer(samples, len) : used(); + int frame_sz1 = samples ? frame_sz-1 : 0; FFrame *frm = 0; - while( ret >= 0 && count >= frame_sz ) { + while( ret >= 0 && count > frame_sz1 ) { frm = new FFrame(this); if( (ret=frm->initted()) < 0 ) break; AVFrame *frame = *frm; - float *bfrp = get_outp(frame_sz); + len = count >= frame_sz ? frame_sz : count; + float *bfrp = get_outp(len); ret = swr_convert(resample_context, - (uint8_t **)frame->extended_data, frame_sz, - (const uint8_t **)&bfrp, frame_sz); + (uint8_t **)frame->extended_data, len, + (const uint8_t **)&bfrp, len); if( ret < 0 ) { ff_err(ret, "FFAudioStream::encode: swr_convert failed\n"); break; } + frame->nb_samples = len; frm->queue(curr_pos); frm = 0; - curr_pos += frame_sz; - count -= frame_sz; + curr_pos += len; + count -= len; } delete frm; return ret >= 0 ? 0 : 1; } +int FFAudioStream::drain() +{ + return encode(0,0); +} + int FFAudioStream::encode_frame(AVFrame *frame) { return FFStream::encode_frame(frame); @@ -867,6 +875,11 @@ int FFVideoStream::encode(VFrame *vframe) return ret >= 0 ? 0 : 1; } +int FFVideoStream::drain() +{ + return 0; +} + int FFVideoStream::encode_frame(AVFrame *frame) { if( frame ) { @@ -2298,6 +2311,10 @@ void FFMPEG::run() mux_lock->lock("FFMPEG::run"); if( !done ) mux(); } + for( int i=0; idrain(); + for( int i=0; idrain(); mux(); for( int i=0; iflush(); diff --git a/cinelerra-5.1/cinelerra/ffmpeg.h b/cinelerra-5.1/cinelerra/ffmpeg.h index e70bcbfb..cbd01c3c 100644 --- a/cinelerra-5.1/cinelerra/ffmpeg.h +++ b/cinelerra-5.1/cinelerra/ffmpeg.h @@ -168,6 +168,7 @@ public: int load(int64_t pos, int len); int audio_seek(int64_t pos); int encode(double **samples, int len); + int drain(); int idx; int channel0, channels; @@ -217,6 +218,7 @@ public: int load(VFrame *vframe, int64_t pos); int video_seek(int64_t pos); int encode(VFrame *vframe); + int drain(); int idx; double frame_rate; -- 2.26.2