X-Git-Url: http://git.cinelerra-gg.org/git/?a=blobdiff_plain;f=cinelerra-5.1%2Fcinelerra%2Fffmpeg.C;h=547b7f074f1276262838c65b5d6d5f8a361ce424;hb=a0cf574cd7814600dc5730b8204b51cb91f8ad12;hp=8e7e62eef0cca6af322fe7a9f75e40c9a1dfcde4;hpb=17e433a6e5021cc080101fd88ac3236dacb9f2e8;p=goodguy%2Fhistory.git diff --git a/cinelerra-5.1/cinelerra/ffmpeg.C b/cinelerra-5.1/cinelerra/ffmpeg.C index 8e7e62ee..547b7f07 100644 --- a/cinelerra-5.1/cinelerra/ffmpeg.C +++ b/cinelerra-5.1/cinelerra/ffmpeg.C @@ -148,10 +148,13 @@ void FFAudioStream::reset_history() { inp = outp = bfr; hpos = 0; + memset(bfr, 0, lmt-bfr); } void FFAudioStream::iseek(int64_t ofs) { + if( ofs > hpos ) ofs = hpos; + if( ofs > sz ) ofs = sz; outp = inp - ofs*nch; if( outp < bfr ) outp += sz*nch; } @@ -488,7 +491,6 @@ int FFStream::flush() int FFStream::seek(int64_t no, double rate) { - int64_t tstmp = -INT64_MAX+1; // default ffmpeg native seek int npkts = 1; int64_t pos = no, pkt_pos = -1; @@ -505,11 +507,19 @@ int FFStream::seek(int64_t no, double rate) npkts = MAX_RETRY; } } - if( pos > 0 && st->time_base.num > 0 ) { - double secs = pos / rate; - tstmp = secs * st->time_base.den / st->time_base.num; - if( nudge != AV_NOPTS_VALUE ) tstmp += nudge; - } + if( pos == curr_pos ) return 0; + double secs = pos < 0 ? 0. : pos / rate; + AVRational time_base = st->time_base; + int64_t tstmp = time_base.num > 0 ? secs * time_base.den/time_base.num : 0; + if( nudge != AV_NOPTS_VALUE ) tstmp += nudge; + int idx = st->index; +#if 0 +// seek all streams using the default timebase. +// this is how ffmpeg and ffplay work. stream seeks are less tested. + tstmp = av_rescale_q(tstmp, time_base, AV_TIME_BASE_Q); + idx = -1; +#endif + avcodec_flush_buffers(avctx); avformat_flush(fmt_ctx); #if 0 @@ -519,9 +529,9 @@ int FFStream::seek(int64_t no, double rate) seek = pkt_pos; flags = AVSEEK_FLAG_BYTE; } - int ret = avformat_seek_file(fmt_ctx, st->index, -INT64_MAX, seek, INT64_MAX, flags); + int ret = avformat_seek_file(fmt_ctx, st->index, -INT64_MAX, seek, INT64_MAX, flags); #else - int ret = av_seek_frame(fmt_ctx, st->index, tstmp, AVSEEK_FLAG_ANY); + int ret = av_seek_frame(fmt_ctx, idx, tstmp, AVSEEK_FLAG_ANY); #endif int retry = MAX_RETRY; while( ret >= 0 ) { @@ -553,9 +563,9 @@ int FFStream::seek(int64_t no, double rate) } } if( ret < 0 ) { -printf("** seek fail %ld, %ld\n", pos, tstmp); +printf("** seek fail %jd, %jd\n", pos, tstmp); seeked = need_packet = 0; - st_eof(flushed=1); + st_eof(flushed=1); return -1; } //printf("seeked pos = %ld, %ld\n", pos, tstmp); @@ -787,6 +797,11 @@ int FFAudioStream::encode_frame(AVFrame *frame) return FFStream::encode_frame(frame); } +int FFAudioStream::write_packet(FFPacket &pkt) +{ + return FFStream::write_packet(pkt); +} + void FFAudioStream::load_markers() { IndexState *index_state = ffmpeg->file_base->asset->index_state; @@ -917,6 +932,13 @@ int FFVideoStream::encode_frame(AVFrame *frame) return FFStream::encode_frame(frame); } +int FFVideoStream::write_packet(FFPacket &pkt) +{ + if( !(ffmpeg->fmt_ctx->oformat->flags & AVFMT_VARIABLE_FPS) ) + pkt->duration = 1; + return FFStream::write_packet(pkt); +} + AVPixelFormat FFVideoConvert::color_model_to_pix_fmt(int color_model) { switch( color_model ) {