fix for ffmpeg seek pos 0, add pactl probe
[goodguy/history.git] / cinelerra-5.1 / cinelerra / ffmpeg.C
index 68a131589b9306794143ddba06753bd77bc2e32b..74d1d74522528855c84bcd5bedf766ed99640070 100644 (file)
@@ -47,21 +47,15 @@ static void ff_err(int ret, const char *fmt, ...)
        fprintf(stderr,_("%s  err: %s\n"),msg, errmsg);
 }
 
-FFPacket::FFPacket()
-{
-       init();
-}
-
-FFPacket::~FFPacket()
-{
-       av_packet_unref(&pkt);
-}
-
 void FFPacket::init()
 {
        av_init_packet(&pkt);
        pkt.data = 0; pkt.size = 0;
 }
+void FFPacket::finit()
+{
+       av_packet_unref(&pkt);
+}
 
 FFrame::FFrame(FFStream *fst)
 {
@@ -449,7 +443,7 @@ int FFStream::flush()
 
 int FFStream::seek(int64_t no, double rate)
 {
-       if( no < 0 ) no = 0;
+       int64_t tstmp = -INT64_MAX+1;
 // default ffmpeg native seek
        int npkts = 1;
        int64_t pos = no, plmt = -1;
@@ -461,27 +455,30 @@ int FFStream::seek(int64_t no, double rate)
                if( no-n < 30*rate ) {
                        if( n < 0 ) n = 0;
                        pos = n;
-                       if( ++i < marks.size() ) plmt = marks[i].pos;
+                       if( i < marks.size() ) plmt = marks[i].pos;
                        npkts = MAX_RETRY;
                }
        }
-       double secs = pos / rate;
-       int64_t pkt_ts, tstmp = secs * st->time_base.den / st->time_base.num;
-       if( nudge != AV_NOPTS_VALUE ) tstmp += nudge;
+       if( pos > 0 ) {
+               double secs = pos / rate;
+               tstmp = secs * st->time_base.den / st->time_base.num;
+               if( nudge != AV_NOPTS_VALUE ) tstmp += nudge;
+       }
        int ret = avformat_seek_file(fmt_ctx, st->index,
                -INT64_MAX, tstmp, INT64_MAX, AVSEEK_FLAG_ANY);
        if( ret >= 0 ) {
                avcodec_flush_buffers(st->codec);
+               ipkt.finit();  ipkt.init();
                need_packet = 0;  flushed = 0;
                seeked = 1;  st_eof(0);
 // read up to retry packets, limited to npkts in stream, and not past pkt.pos plmt
-               for( int retry=MAX_RETRY; ret>=0 && --retry>=0; ) {
+               for(;;) {
                        if( read_packet() <= 0 ) { ret = -1;  break; }
                        if( plmt >= 0 && ipkt->pos >= plmt ) break;
                        if( ipkt->stream_index != st->index ) continue;
                        if( --npkts <= 0 ) break;
-                       if( (pkt_ts=ipkt->dts) == AV_NOPTS_VALUE &&
-                           (pkt_ts=ipkt->pts) == AV_NOPTS_VALUE ) continue;
+                       int64_t pkt_ts = ipkt->dts != AV_NOPTS_VALUE ? ipkt->dts : ipkt->pts;
+                       if( pkt_ts == AV_NOPTS_VALUE ) continue;
                        if( pkt_ts >= tstmp ) break;
                }
        }
@@ -706,6 +703,7 @@ int FFAudioStream::encode_frame(AVPacket *pkt, AVFrame *frame, int &got_packet)
 void FFAudioStream::load_markers()
 {
        IndexState *index_state = ffmpeg->file_base->asset->index_state;
+       if( index_state->marker_status == MARKERS_NOTTESTED ) return;
        if( !index_state || idx >= index_state->audio_markers.size() ) return;
        FFStream::load_markers(*index_state->audio_markers[idx], sample_rate);
 }
@@ -1219,12 +1217,14 @@ void FFMPEG::set_asset_format(Asset *asset, const char *text)
 {
        if( asset->format != FILE_FFMPEG ) return;
        strcpy(asset->fformat, text);
-       strcpy(asset->ff_audio_options, "");
-       strcpy(asset->ff_video_options, "");
-       asset->audio_data = !load_defaults("audio", text, asset->acodec,
-               asset->ff_audio_options, sizeof(asset->ff_audio_options));
-       asset->video_data = !load_defaults("video", text, asset->vcodec,
-               asset->ff_video_options, sizeof(asset->ff_video_options));
+       if( !asset->ff_audio_options[0] ) {
+               asset->audio_data = !load_defaults("audio", text, asset->acodec,
+                       asset->ff_audio_options, sizeof(asset->ff_audio_options));
+       }
+       if( !asset->ff_video_options[0] ) {
+               asset->video_data = !load_defaults("video", text, asset->vcodec,
+                       asset->ff_video_options, sizeof(asset->ff_video_options));
+       }
 }
 
 int FFMPEG::get_encoder(const char *options,
@@ -1989,8 +1989,8 @@ void FFMPEG::stop_muxer()
        if( running() ) {
                done = 1;
                mux_lock->unlock();
-               join();
        }
+       join();
 }
 
 void FFMPEG::flow_off()
@@ -2499,7 +2499,7 @@ printf("audio%d pad %ld %ld (%ld)\n", aud->idx, pos, aud->curr_pos, pos-aud->cur
                                int got_frame = 0;
                                int ret = aud->decode_frame(&pkt, frame, got_frame);
                                if( ret <= 0 ) break;
-                               if( got_frame ) {
+                               if( got_frame && frame->channels == nch ) {
                                        float *samples;
                                        int len = aud->get_samples(samples,
                                                 &frame->extended_data[0], frame->nb_samples);