Browse Source

obs-ffmpeg: Use AMD example PTS/DTS offset

All this does is it uses the same exact code AMD uses with their own
example FFmpeg muxer code. Although instead of adding to the PTS, it
subtracts from the DTS.
Jim 3 years ago
parent
commit
a6c2bb1294
1 changed files with 21 additions and 2 deletions
  1. 21 2
      plugins/obs-ffmpeg/texture-amf.cpp

+ 21 - 2
plugins/obs-ffmpeg/texture-amf.cpp

@@ -104,6 +104,7 @@ struct amf_base {
 
 	amf_int64 max_throughput = 0;
 	amf_int64 throughput = 0;
+	int64_t dts_offset = 0;
 	uint32_t cx;
 	uint32_t cy;
 	uint32_t linesize = 0;
@@ -113,6 +114,7 @@ struct amf_base {
 	bool bframes_supported = false;
 	bool using_bframes = false;
 	bool first_update = true;
+	bool calculated_dts_offset = false;
 
 	inline amf_base(bool fallback) : fallback(fallback) {}
 	virtual ~amf_base() = default;
@@ -477,8 +479,25 @@ static void convert_to_encoder_packet(amf_base *enc, AMFDataPtr &data,
 	packet->dts = convert_to_obs_ts(enc, data->GetPts());
 	packet->keyframe = type == AMF_VIDEO_ENCODER_OUTPUT_DATA_TYPE_IDR;
 
-	if (enc->using_bframes)
-		packet->dts -= 2;
+	if (enc->using_bframes) {
+		int64_t duration = data->GetDuration() / 500000;
+
+		if (!enc->calculated_dts_offset) {
+			if (packet->pts == packet->dts) {
+				enc->dts_offset = duration;
+			} else if (packet->pts > packet->dts) {
+				enc->dts_offset =
+					duration - packet->pts + packet->dts;
+			}
+
+			enc->calculated_dts_offset = true;
+		}
+
+		packet->dts = packet->dts - enc->dts_offset;
+
+		if (packet->pts < packet->dts)
+			packet->pts = packet->dts;
+	}
 }
 
 static void amf_encode_base(amf_base *enc, AMFSurface *amf_surf,