[Live-devel] Troubles with playing backward

d.gordenin at ngslab.ru d.gordenin at ngslab.ru
Tue Jul 1 07:07:14 PDT 2025


On 01.07.2025 16:52, Ross Finlayson <finlayson at live555.com> wrote:
> You are going to have to be *much* more specific, because right now your question makes no sense at all.  Exactly how are you using our software, and what are you trying to do?
> 
> (Remember that our software includes RTSP servers, RTSP clients, proxy servers, and demonstration applications.)
> 
> 
> Ross Finlayson
> Live Networks, Inc.
> http://www.live555.com/
> 
> 
> _______________________________________________
> live-devel mailing list
> live-devel at lists.live555.com
> http://lists.live555.com/mailman/listinfo/live-devel
> 

My VideoSource is:
class VideoSource : public FramedSource
It has void VideoSource::doGetNextFrame(), where I prepare frame and send them.
Firstly I send SPS PPS at the start of the video.
After I find an I-frame:

              ingest::MediaFrame cur_frame = frame_;
              do
              {
                result = storage_manager_->GetPrevVideoFrame(frame_);
                summ_duration += frame_.duration;
              }
              while (result == StorageResult::OK && !frame_.is_key);

              if (result != StorageResult::OK)
              {
                nextTask() = envir().taskScheduler().scheduleDelayedTask(0, (TaskFunc*)FramedSource::afterGetting, this);
                return;
              }

              frame_.duration = summ_duration;

So, duration of this frame is a sum of the frames in the GOP.

After I find SPS, PPS:

              ingest::MediaFrame sps, pps;
              result = storage_manager_->GetPrevVideoFrame(pps);
              pps.frame_time = frame_.frame_time;
              if (result == StorageResult::OK)
                next_frames_.insert(next_frames_.begin(), pps);
              result = storage_manager_->GetPrevVideoFrame(sps);
              sps.frame_time = frame_.frame_time;
              if (result == StorageResult::OK)
                next_frames_.insert(next_frames_.begin(), sps);

I set them the same frame time as I-frame.
Also I tried to insert empty I-frames between the real I-frames, but the issues still present:

              ingest::MediaFrame f = frame_;
              f.raw_data.clear();
              if (cur_frame.frame_time > frame_.frame_time)
              {
                int64_t t = cur_frame.frame_time - frame_.frame_time - 50;
                int i = 1;
                while (t > 50)
                {
                  f.frame_time -= 50 * (i++);
                  next_frames_.insert(next_frames_.begin(), f);
                  //next_frames_.insert(next_frames_.begin(), pps);
                  //next_frames_.insert(next_frames_.begin(), sps);
                  t -= 50;
                }
              }

Also I prepare SEI. After in the next circle:

nextTask() = envir().taskScheduler().scheduleDelayedTask(0, (TaskFunc*)FramedSource::afterGetting, this);

I send the frames in the next_frames_:

  gettimeofday(&fPresentationTime, NULL);

  constexpr uint32_t rtp_clock_rate = 90000;
  uint64_t delta_time = std::abs((int64_t)frame_.frame_time - (int64_t)first_frame_time_);
  rtp_timestamp_ = start_rtp_timestamp_ + (delta_time * rtp_clock_rate) / 1000;

Here rtp_timestamp_ is calculated from frame time and is the same for this group of the frames.
Let me know if you need more info.


More information about the live-devel mailing list