Swift 4 - AVFoundation AVAssetWriter PTS/DTS值错误问题求助
Hey there! Let's dig into this PTS/DTS issue you're facing with your Aperture custom bitrate setup. It's great that your video quality and frame rate are working as expected—those are the big wins, and the timing metadata fix is just a matter of getting the timestamp logic right.
First, a quick recap for context: PTS (Presentation Time Stamp) tells the player when to display a frame, while DTS (Decode Time Stamp) tells the decoder when to process it. For simple I/P frame streams (no B-frames), these values should be identical and monotonically increasing. If you're using B-frames, DTS will be earlier than PTS for those frames, but we'll start with the most common scenario first.
Common Issues in Your Current Code
Chances are your code is either:
- Not setting consistent time bases across your video stream
- Generating non-sequential PTS/DTS values
- Ignoring the frame duration when calculating timestamps
Step-by-Step Code Fixes
1. Set a Consistent Time Base First
Before you start writing frames, define a time base that matches your target frame rate. This ensures all timestamps are aligned properly:
// Adjust the timescale to match your frame rate (e.g., 30 for 30fps, 60 for 60fps) let targetFrameRate = 30 let videoTimeScale = CMTimeScale(targetFrameRate) let frameDuration = CMTimeMake(value: 1, timescale: videoTimeScale) // Configure your AVAssetWriterInput with this time base if let videoInput = assetWriterInput { videoInput.expectsMediaDataInRealTime = false // Disable real-time mode for better timestamp control (safe for offline recording) // Ensure your output settings use the same time scale let videoSettings: [String: Any] = [ AVVideoCodecKey: AVVideoCodecType.h264, AVVideoWidthKey: 1920, AVVideoHeightKey: 1080, AVVideoAverageBitRateKey: yourCustomBitrateValue, AVVideoCompressionPropertiesKey: [ AVVideoMaxKeyFrameIntervalKey: targetFrameRate * 2, // 2-second keyframes AVVideoTimeScaleKey: videoTimeScale ] ] }
2. Calculate Sequential PTS/DTS for Each Frame
Track the frame index and generate timestamps that increment consistently. For streams without B-frames, DTS can mirror PTS directly:
// Declare a class-level variable to track frame count private var currentFrameIndex: Int64 = 0 // When processing a frame to write: func writeFrame(_ sampleBuffer: CMSampleBuffer) { guard let videoInput = assetWriterInput, videoInput.isReadyForMoreMediaData else { return } // Calculate PTS: frame index * frame duration let pts = CMTimeMultiplyByInteger(frameDuration, multiplier: currentFrameIndex) // For non-B-frame streams, DTS = PTS let dts = pts // Update the sample buffer's timing info var timingInfo = CMSampleTimingInfo( duration: frameDuration, presentationTimeStamp: pts, decodeTimeStamp: dts ) var timingInfoArray = [timingInfo] if CMSampleBufferSetSampleTimingInfoArray(sampleBuffer, entryCount: 1, arrayToSet: &timingInfoArray) == noErr { videoInput.append(sampleBuffer) currentFrameIndex += 1 } else { print("Failed to update sample buffer timing info") } }
3. Handle B-Frames (If Applicable)
If you're using B-frames (which add compression efficiency but complicate timestamps), you'll need to adjust DTS based on the decoding order. For example, with an IBP frame structure:
- Decode order: I → B → P
- Presentation order: I → P → B
In this case, the B-frame's DTS will be earlier than its PTS. You'll need to track both presentation and decode order indices, but this is more advanced. If you don't need B-frames, it's often easier to disable them in your compression settings to avoid this complexity.
Key Checks to Avoid FFmpeg Errors
- Monotonic Timestamps: Ensure PTS/DTS values always increase—FFmpeg will throw errors if timestamps jump backward or repeat.
- Matching Time Scales: Verify that your
AVAssetWritersettings, frame duration, and timestamps all use the same time scale (e.g., 30 for 30fps). - Frame Order: Write frames in the order they should be decoded, not just displayed (critical if using B-frames).
If you share a snippet of your current timestamp calculation code, I can help tailor this even more precisely. But these changes should resolve most common PTS/DTS mismatches that trigger FFmpeg transcode errors.
内容的提问来源于stack exchange,提问作者Matho

