X-Git-Url: https://git.cinelerra-gg.org/git/?a=blobdiff_plain;f=cinelerra-5.1%2Fcinelerra%2Fffmpeg.C;h=23549f9a0c603a82175ffd1f1176f8d59193b19a;hb=1da768016a2ecba0296b03d75c02879f99a0f582;hp=bf6a6fe61786c8f104434d525240ae2ce15c9a8b;hpb=750c685e0f667cfe57bdb5eaf3cd2a061f44b01d;p=goodguy%2Fcinelerra.git diff --git a/cinelerra-5.1/cinelerra/ffmpeg.C b/cinelerra-5.1/cinelerra/ffmpeg.C index bf6a6fe6..23549f9a 100644 --- a/cinelerra-5.1/cinelerra/ffmpeg.C +++ b/cinelerra-5.1/cinelerra/ffmpeg.C @@ -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,17 +446,17 @@ 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; - av_seek_frame(fmt_ctx, idx, INT64_MIN, flags); + av_seek_frame(fmt_ctx, idx, 0, flags); need_packet = 1; flushed = 0; seeked = 1; st_eof(0); 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); @@ -758,7 +762,9 @@ int FFStream::seek(int64_t no, double rate) if( pkt_ts >= tstmp ) break; } if( retry < 0 ) { - fprintf(stderr,"FFStream::seek: retry limit, pos=%jd tstmp=%jd\n",pos,tstmp); + ff_err(AVERROR(EIO), "FFStream::seek: %s\n" + " retry limit, pos=%jd tstmp=%jd, ", + ffmpeg->fmt_ctx->url, pos, tstmp); ret = -1; } if( ret < 0 ) break; @@ -772,6 +778,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; @@ -1086,6 +1093,7 @@ int FFVideoStream::decode_hw_format(AVCodec *decoder, AVHWDeviceType type) if( !config ) { fprintf(stderr, "Decoder %s does not support device type %s.\n", decoder->name, av_hwdevice_get_type_name(type)); + ret = -1; break; } if( (config->methods & AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX) != 0 &&