fix min speed value 0.005, fix canvas lock hang, fix reset_caches crashing on vicon...
[goodguy/cinelerra.git] / cinelerra-5.1 / cinelerra / ffmpeg.C
index 58d280c00edf60315dd93d383e05196d9ee04a49..499974f0e201ac30f3937dc90125d554d746d47c 100644 (file)
@@ -285,6 +285,7 @@ FFStream::FFStream(FFMPEG *ffmpeg, AVStream *st, int fidx)
 
 FFStream::~FFStream()
 {
+       frm_lock->lock("FFStream::~FFStream");
        if( reading > 0 || writing > 0 ) avcodec_close(avctx);
        if( avctx ) avcodec_free_context(&avctx);
        if( fmt_ctx ) avformat_close_input(&fmt_ctx);
@@ -295,6 +296,7 @@ FFStream::~FFStream()
        if( frame ) av_frame_free(&frame);
        if( fframe ) av_frame_free(&fframe);
        if( probe_frame ) av_frame_free(&probe_frame);
+       frm_lock->unlock();
        delete frm_lock;
        if( stats_fp ) fclose(stats_fp);
        if( stats_in ) av_freep(&stats_in);
@@ -428,14 +430,14 @@ int FFStream::decode_activate()
                                        avctx->thread_count = ffmpeg->ff_cpus();
                                ret = avcodec_open2(avctx, decoder, &copts);
                        }
+                       AVFrame *hw_frame = 0;
                        if( ret >= 0 && hw_type != AV_HWDEVICE_TYPE_NONE ) {
-                               AVFrame *frame = av_frame_alloc();
-                               if( !frame ) {
+                               if( !(hw_frame=av_frame_alloc()) ) {
                                        fprintf(stderr, "FFStream::decode_activate: av_frame_alloc failed\n");
                                        ret = AVERROR(ENOMEM);
                                }
                                if( ret >= 0 )
-                                       ret = decode(frame);
+                                       ret = decode(hw_frame);
                        }
                        if( ret < 0 && hw_type != AV_HWDEVICE_TYPE_NONE ) {
                                ff_err(ret, "HW device init failed, using SW decode.\nfile:%s\n",
@@ -444,7 +446,7 @@ int FFStream::decode_activate()
                                avcodec_free_context(&avctx);
                                av_buffer_unref(&hw_device_ctx);
                                hw_device_ctx = 0;
-                               av_frame_free(&frame);
+                               av_frame_free(&hw_frame);
                                hw_type = AV_HWDEVICE_TYPE_NONE;
                                int flags = AVSEEK_FLAG_BACKWARD | AVSEEK_FLAG_ANY;
                                int idx = st->index;
@@ -454,7 +456,7 @@ int FFStream::decode_activate()
                                ret = 0;
                                continue;
                        }
-                       probe_frame = frame;
+                       probe_frame = hw_frame;
                        if( ret >= 0 )
                                reading = 1;
                        else
@@ -491,7 +493,7 @@ int FFStream::decode(AVFrame *frame)
        }
        int ret = 0;
        int retries = MAX_RETRY;
-
+       frm_lock->lock("FFStream::decode");
        while( ret >= 0 && !flushed && --retries >= 0 ) {
                if( need_packet ) {
                        if( (ret=read_packet()) < 0 ) break;
@@ -514,6 +516,7 @@ int FFStream::decode(AVFrame *frame)
                        flushed = st_eof();
                }
        }
+       frm_lock->unlock();
 
        if( retries < 0 ) {
                fprintf(stderr, "FFStream::decode: Retry limit\n");
@@ -726,6 +729,7 @@ int FFStream::seek(int64_t no, double rate)
        tstmp = av_rescale_q(tstmp, time_base, AV_TIME_BASE_Q);
        idx = -1;
 #endif
+       frm_lock->lock("FFStream::seek");
        av_frame_free(&probe_frame);
        avcodec_flush_buffers(avctx);
        avformat_flush(fmt_ctx);
@@ -772,6 +776,7 @@ int FFStream::seek(int64_t no, double rate)
                        break;
                }
        }
+       frm_lock->unlock();
        if( ret < 0 ) {
 printf("** seek fail %jd, %jd\n", pos, tstmp);
                seeked = need_packet = 0;