file probe prefs, updated dcraw, bugs - garbage, accel, ffmpeg/giphy.gif
[goodguy/history.git] / cinelerra-5.1 / cinelerra / ffmpeg.C
index 968cb05145108d164ae7fab31ad954432e4f614a..f2b02c24449952f529b229101966da1a7702469f 100644 (file)
@@ -320,11 +320,15 @@ int FFStream::decode_activate()
                                ret = AVERROR(ENOMEM);
                        }
                        if( ret >= 0 ) {
+                               av_codec_set_pkt_timebase(avctx, st->time_base);
+                               if( decoder->capabilities & AV_CODEC_CAP_DR1 )
+                                       avctx->flags |= CODEC_FLAG_EMU_EDGE;
                                avcodec_parameters_to_context(avctx, st->codecpar);
                                ret = avcodec_open2(avctx, decoder, &copts);
                        }
-                       if( ret >= 0 )
+                       if( ret >= 0 ) {
                                reading = 1;
+                       }
                        else
                                eprintf(_("open decoder failed\n"));
                }
@@ -721,31 +725,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 +879,11 @@ int FFVideoStream::encode(VFrame *vframe)
        return ret >= 0 ? 0 : 1;
 }
 
+int FFVideoStream::drain()
+{
+       return 0;
+}
+
 int FFVideoStream::encode_frame(AVFrame *frame)
 {
        if( frame ) {
@@ -2066,7 +2083,7 @@ int FFMPEG::decode_activate()
                        }
                }
                int64_t nudge = vstart_time > min_nudge ? vstart_time :
-                       astart_time > min_nudge ? astart_time : AV_NOPTS_VALUE;
+                       astart_time > min_nudge ? astart_time : 0;
                for( int vidx=0; vidx<ffvideo.size(); ++vidx ) {
                        if( ffvideo[vidx]->nudge == AV_NOPTS_VALUE )
                                ffvideo[vidx]->nudge = nudge;
@@ -2298,6 +2315,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();