diff --git a/plugins/obs-ffmpeg/texture-amf.cpp b/plugins/obs-ffmpeg/texture-amf.cpp index 2de251227..209af488c 100644 --- a/plugins/obs-ffmpeg/texture-amf.cpp +++ b/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,