Internal seek implementation.
731{
732 if (!ctx || !ctx->is_valid()) {
733 set_error(
"Invalid context for seeking");
734 return false;
735 }
736
737 if (frame_position > ctx->total_frames) {
738 frame_position = ctx->total_frames;
739 }
740
741 if (ctx->sample_rate == 0) {
743 return false;
744 }
745
746 if (ctx->audio_stream_index < 0 || ctx->audio_stream_index >= static_cast<int>(ctx->format_context->nb_streams)) {
748 return false;
749 }
750
751 AVStream* stream = ctx->format_context->streams[ctx->audio_stream_index];
752
753 int64_t timestamp = av_rescale_q(
754 frame_position,
755 AVRational { 1, static_cast<int>(ctx->sample_rate) },
756 stream->time_base);
757
758 int ret = av_seek_frame(
759 ctx->format_context,
760 ctx->audio_stream_index,
761 timestamp,
762 AVSEEK_FLAG_BACKWARD);
763
764 if (ret < 0) {
766 return false;
767 }
768
769 avcodec_flush_buffers(ctx->codec_context);
770
771 if (ctx->swr_context) {
772 uint8_t** dummy = nullptr;
773 int linesize = 0;
774
775 int alloc_ret = av_samples_alloc_array_and_samples(
776 &dummy, &linesize,
777 ctx->channels, 2048, AV_SAMPLE_FMT_DBL, 0);
778
779 if (alloc_ret >= 0 && dummy) {
780 while (swr_convert(ctx->swr_context, dummy, 2048, nullptr, 0) > 0) {
781 }
782
783 av_freep(&dummy[0]);
784 av_freep(&dummy);
785 }
786 }
787
789 return true;
790}
void set_error(const std::string &error) const
Set the last error message.
std::atomic< uint64_t > m_current_frame_position
Current frame position for reading.