最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

c++ - FFmpeg av_seek_frame() successful, but decoding always starts from the beginning - Stack Overflow

programmeradmin3浏览0评论

I'm working on a video player using FFmpeg in C++, where I need to seek to a specific PTS (timestamp) and start decoding from there. However, even after a successful av_seek_frame(), decoding always starts from frame 0 instead of the target frame.

void decodeLoop() {
      while (!stopThread) {

          std::unique_lock<std::mutex> lock(mtx);
          cv.wait(lock, [this] { return decoding || stopThread; });

          if (stopThread) break;

          int64_t reqTimestamp = requestedTimestamp.load();

          // **Skip redundant seeks**
          if (reqTimestamp == lastRequestedTimestamp.load()) {
              continue;  // Avoid unnecessary seeks
          }

          int64_t requestedTS = requestedTimestamp.load();
          AVRational stream_tb = fmt_ctx->streams[video_stream_index]->time_base;
          int64_t target_pts = reqTimestamp;
          target_pts = FFMAX(target_pts, 0); // Ensure it's not negative

          int seek_flags = AVSEEK_FLAG_BACKWARD;

          if (av_seek_frame(fmt_ctx, video_stream_index, target_pts, seek_flags) >= 0) {
              avcodec_flush_buffers(codec_ctx);  // Clear old frames from the decoder
              avformat_flush(fmt_ctx);          // **Flush demuxer**
              qDebug() << "Seek successful to PTS:" << target_pts;
       //      avfilter_graph_free(&filter_graph);  // Reset filter graph
          }
          else {
              qDebug() << "Seeking failed!";
              decoding = false;
              continue;
          }

          lock.unlock();

          // Keep decoding frames until we reach (or slightly exceed) requestedTimestamp
          bool frameDecoded = false;
          while (av_read_frame(fmt_ctx, pkt) >= 0) {
              if (pkt->stream_index == video_stream_index) {
                  if (avcodec_send_packet(codec_ctx, pkt) == 0) {
                      while (avcodec_receive_frame(codec_ctx, frame) == 0) {
                          int64_t frame_pts = frame->pts;

                          // Skip frames before reaching target PTS
                          if (frame_pts < requestedTimestamp.load()) {

                              qDebug() << "SKIPPING FRAMES " << frame_pts;
                              av_frame_unref(frame);  // Free unused frame memory
                              continue;  // Discard early frames
                          }

                          qDebug() << "DECODING THE SEEKED FRAMES " << frame_pts;

                          if (frame_pts >= requestedTimestamp.load()) {
                             
                                  // Accept frame only if it's close enough to the target PTS
                                  current_pts.store(frame_pts);
                                  lastRequestedTimestamp.store(requestedTimestamp.load());
                                  convertHWFrameToImage(frame);
                                  emit frameDecodedSignal(outputImage);
                                  frameDecoded = true;
                                  break;  // Stop decoding once we reach the desired frame
                             
                          }
                      }
                  }
              }
              av_packet_unref(pkt);

              if (frameDecoded) break;
          }

          decoding = false;
      }
  }
发布评论

评论列表(0)

  1. 暂无评论