ffmpeg scan remap fix, configure.ac all or none fix, 3rd party libs: ffmpeg, turbo...
[goodguy/cinelerra.git] / cinelerra-5.1 / cinelerra / ffmpeg.C
index 493be6abeace4e55e9eac4177964649a63c6fc2e..5ff87abc9779a9428d26d69bca3601da3718a13b 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);
@@ -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;
@@ -3534,7 +3541,25 @@ int FFMPEG::scan(IndexState *index_state, int64_t *scan_position, int *canceled)
                av_dict_copy(&copts, opts, 0);
                AVStream *st = fmt_ctx->streams[i];
                AVCodecID codec_id = st->codecpar->codec_id;
-               AVCodec *decoder = avcodec_find_decoder(codec_id);
+               AVCodec *decoder = 0;
+               switch( st->codecpar->codec_type ) {
+               case AVMEDIA_TYPE_VIDEO:
+                       if( opt_video_decoder )
+                               decoder = avcodec_find_decoder_by_name(opt_video_decoder);
+                       else
+                               video_codec_remaps.update(codec_id, decoder);
+                       break;
+               case AVMEDIA_TYPE_AUDIO:
+                       if( opt_audio_decoder )
+                               decoder = avcodec_find_decoder_by_name(opt_audio_decoder);
+                       else
+                               audio_codec_remaps.update(codec_id, decoder);
+                       break;
+               default:
+                       continue;
+               }
+               if( !decoder && !(decoder = avcodec_find_decoder(codec_id)) )
+                       continue;
                AVCodecContext *avctx = avcodec_alloc_context3(decoder);
                if( !avctx ) {
                        eprintf(_("cant allocate codec context\n"));
@@ -3615,8 +3640,8 @@ int FFMPEG::scan(IndexState *index_state, int64_t *scan_position, int *canceled)
                        if( vidx < 0 ) break;
                        FFVideoStream *vid = ffvideo[vidx];
                        if( !vid->avctx ) break;
-                       int64_t tstmp = pkt.dts;
-                       if( tstmp == AV_NOPTS_VALUE ) tstmp = pkt.pts;
+                       int64_t tstmp = pkt.pts;
+                       if( tstmp == AV_NOPTS_VALUE ) tstmp = pkt.dts;
                        if( tstmp != AV_NOPTS_VALUE && (pkt.flags & AV_PKT_FLAG_KEY) && pkt.pos > 0 ) {
                                if( vid->nudge != AV_NOPTS_VALUE ) tstmp -= vid->nudge;
                                double secs = to_secs(tstmp, st->time_base);