MCPcopy Create free account
hub / github.com/OpenShot/libopenshot / GetAudioPTSLocation

Method GetAudioPTSLocation

src/FFmpegReader.cpp:2624–2682  ·  view source on GitHub ↗

Calculate Starting video frame and sample # for an audio PTS

Source from the content-addressed store, hash-verified

2622
2623// Calculate Starting video frame and sample # for an audio PTS
2624AudioLocation FFmpegReader::GetAudioPTSLocation(int64_t pts) {
2625 const double audio_timebase_value =
2626 (info.audio_timebase.num > 0 && info.audio_timebase.den > 0)
2627 ? info.audio_timebase.ToDouble()
2628 : (1.0 / 48000.0);
2629 const double fps_value = (info.fps.num > 0 && info.fps.den > 0) ? info.fps.ToDouble() : 30.0;
2630
2631 // Get the audio packet start time (in seconds)
2632 double audio_seconds = (double(pts) * audio_timebase_value) + pts_offset_seconds;
2633
2634 // Divide by the video timebase, to get the video frame number (frame # is decimal at this point)
2635 double frame = (audio_seconds * fps_value) + 1;
2636
2637 // Frame # as a whole number (no more decimals)
2638 int64_t whole_frame = int64_t(frame);
2639
2640 // Remove the whole number, and only get the decimal of the frame
2641 double sample_start_percentage = frame - double(whole_frame);
2642
2643 // Get Samples per frame
2644 int samples_per_frame = Frame::GetSamplesPerFrame(whole_frame, info.fps, info.sample_rate, info.channels);
2645
2646 // Calculate the sample # to start on
2647 int sample_start = round(double(samples_per_frame) * sample_start_percentage);
2648
2649 // Protect against broken (i.e. negative) timestamps
2650 if (whole_frame < 1)
2651 whole_frame = 1;
2652 if (sample_start < 0)
2653 sample_start = 0;
2654
2655 // Prepare final audio packet location
2656 AudioLocation location = {whole_frame, sample_start};
2657
2658 // Compare to previous audio packet (and fix small gaps due to varying PTS timestamps)
2659 if (previous_packet_location.frame != -1) {
2660 if (location.is_near(previous_packet_location, samples_per_frame, samples_per_frame)) {
2661 int64_t orig_frame = location.frame;
2662 int orig_start = location.sample_start;
2663
2664 // Update sample start, to prevent gaps in audio
2665 location.sample_start = previous_packet_location.sample_start;
2666 location.frame = previous_packet_location.frame;
2667
2668 // Debug output
2669 ZmqLogger::Instance()->AppendDebugMethod("FFmpegReader::GetAudioPTSLocation (Audio Gap Detected)", "Source Frame", orig_frame, "Source Audio Sample", orig_start, "Target Frame", location.frame, "Target Audio Sample", location.sample_start, "pts", pts);
2670
2671 } else {
2672 // Debug output
2673 ZmqLogger::Instance()->AppendDebugMethod("FFmpegReader::GetAudioPTSLocation (Audio Gap Ignored - too big)", "Previous location frame", previous_packet_location.frame, "Target Frame", location.frame, "Target Audio Sample", location.sample_start, "pts", pts);
2674 }
2675 }
2676
2677 // Set previous location
2678 previous_packet_location = location;
2679
2680 // Return the associated video frame and starting sample #
2681 return location;

Callers

nothing calls this directly

Calls 3

ToDoubleMethod · 0.80
is_nearMethod · 0.80
AppendDebugMethodMethod · 0.80

Tested by

no test coverage detected