Cuda Encoding Creates Slow Motion video file from live source

I’ve created my Directshow compatible filter to utilize the NVENC API but I am getting strange results when encoding live video (640x480@30fps). The video has all the content but plays in “slow motion” (e.g. a 5 second recording will play for ~12 seconds). I can’t figure out if this is a sample timestamp issue or what. I am trying to decode the SPS/PPS now to see if there is anything I can glean, but media players report the frame rate correctly at 30FPS, it just plays in slow motion like the PTS is messed up or something.

Has anyone else had this issue? Ideas on where I should start digging?

Here is the code I use to initialize:

    CUresult cuRes = cuInit(0);
    if (cuRes == CUDA_ERROR_NOT_INITIALIZED)
        return E_UNEXPECTED;

    int n = 0;
    cuDeviceGetCount(&n);
    if (n < 1)
        return E_UNEXPECTED;

    // Obtain the device and create a context for use
    CUdevice device = NULL;
    cuDeviceGet(&device, 0);
    m_Context = NULL;
    cuCtxCreate(&m_Context, 0, device);

    // Configure and create the encoder
    m_pEncoder = new NvEncoderCuda(m_Context, m_nWidth, m_nHeight, (NV_ENC_BUFFER_FORMAT)m_pnvBufferFormat);
    if (!m_pEncoder)
        return E_UNEXPECTED;

    NV_ENC_INITIALIZE_PARAMS m_pnvParams = { NV_ENC_INITIALIZE_PARAMS_VER };
    NV_ENC_CONFIG m_pnvEncConfig = { NV_ENC_CONFIG_VER };
    m_pnvParams.encodeConfig = &m_pnvEncConfig;

    m_pEncoder->CreateDefaultEncoderParams(&m_pnvParams, NV_ENC_CODEC_HEVC_GUID, NV_ENC_PRESET_P4_GUID, NV_ENC_TUNING_INFO_ULTRA_LOW_LATENCY);

    m_pnvParams.enableEncodeAsync = 0;

    m_pEncoder->CreateEncoder(&m_pnvParams);

And the code to encode the frame(s):

    std::vector<std::vector<uint8_t>> vPacket;
        
    BYTE* pBufferIn = NULL;
    if (pIn->GetPointer(&pBufferIn) < 0)
        return S_FALSE;
    
    const NvEncInputFrame* encoderInputFrame = m_pEncoder->GetNextInputFrame();
    NvEncoderCuda::CopyToDeviceFrame(m_Context, pBufferIn, 0, (CUdeviceptr)encoderInputFrame->inputPtr,
        (int)encoderInputFrame->pitch,
        m_pEncoder->GetEncodeWidth(),
        m_pEncoder->GetEncodeHeight(),
        CU_MEMORYTYPE_HOST,
        encoderInputFrame->bufferFormat,
        encoderInputFrame->chromaOffsets,
        encoderInputFrame->numChromaPlanes);
    
    m_pEncoder->EncodeFrame(vPacket);
    //int pSize = vPacket.size();

    BYTE* pBufferOut = NULL;
    if (pOut->GetPointer(&pBufferOut) < 0)
        return S_FALSE;

    for (std::vector<uint8_t>& packet : vPacket)
    {
        // For each encoded packet
        memcpy(pBufferOut, packet.data(), packet.size());
        pOut->SetActualDataLength(packet.size());
    }