drain last partial frame in ffmpeg close encoder
authorGood Guy <good1.2guy@gmail.com>
Mon, 1 May 2017 21:58:27 +0000 (15:58 -0600)
committerGood Guy <good1.2guy@gmail.com>
Mon, 1 May 2017 21:58:27 +0000 (15:58 -0600)
cinelerra-5.1/cinelerra/ffmpeg.C
cinelerra-5.1/cinelerra/ffmpeg.h

index 968cb05145108d164ae7fab31ad954432e4f614a..10ad05036ee64b71a5cb8d7e2336434fe2e52108 100644 (file)
@@ -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; i<ffaudio.size(); ++i )
+               ffaudio[i]->drain();
+       for( int i=0; i<ffvideo.size(); ++i )
+               ffvideo[i]->drain();
        mux();
        for( int i=0; i<ffaudio.size(); ++i )
                ffaudio[i]->flush();
index e70bcbfb266f404beba4ab9491d03a243d5c34f6..cbd01c3c1e38c4d27707d938fa033750273f2268 100644 (file)
@@ -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;