EVT_ACX_STREAM_SET_RENDER_PACKET回呼函式 (acxstreams.h)

EvtAcxStreamSetRenderPacket 事件會告知驅動程式用戶端剛剛釋放的封包。

如果沒有問題,此封包應該是 (CurrentRenderPacket + 1),其中 CurrentRenderPacket 是驅動程式目前串流的來源封包。 驅動程式應該會在轉譯封包時繼續增加 CurrentRenderPacket,而不是變更其 CurrentRenderPacket 以符合此值。 屬性會包含封包索引(以 0 為基礎),如果適當的話,EOS 旗標的位元組位移位於目前封包的數據流結尾。

語法

EVT_ACX_STREAM_SET_RENDER_PACKET EvtAcxStreamSetRenderPacket;

NTSTATUS EvtAcxStreamSetRenderPacket(
  ACXSTREAM Stream,
  ULONG Packet,
  ULONG Flags,
  ULONG EosPacketLength
)
{...}

參數

Stream

ACXSTREAM 物件代表線路所建立的音訊數據流。 如需詳細資訊,請參閱 ACX - ACX 物件的摘要

Packet

OS 寫入 WaveRT 緩衝區的封包數目。 根據驅動程式所提供的值,AcxRtStreamNotifyPacketComplete而定,封包號碼可能會略過值。

Flags

旗標可以是 0 或 KSSTREAM_HEADER_OPTIONSF_ENDOFSTREAM = 0x200,表示 Packet 是數據流中的最後一個封包,而 EosPacketLength 是封包的有效長度。 如需詳細資訊,請參閱 KSSTREAM_HEADER 結構中的 OptionsFlags

EosPacketLength

如果在 Flags 中指定 KSSTREAM_HEADER_OPTIONSF_ENDOFSTREAM = 0x200,則為 EOS 封包的長度。 零是有效的值。 如果未在 Flags 中指定 KSSTREAM_HEADER_OPTIONSF_ENDOFSTREAM,則應該忽略此參數。 EosPacketLength 是以位元組為單位來測量。

傳回值

如果呼叫成功,則傳回 STATUS_SUCCESS。 否則,它會傳回適當的錯誤碼。 如需詳細資訊,請參閱使用NTSTATUS值

STATUS_DATA_LATE_ERROR – 如果 OS 通過已傳輸或目前正在傳輸的封包號碼,驅動程式會傳回此錯誤。 在此情況下,發生故障狀況。 驅動程式可以選擇性地使用封包的某些數據,或繼續播放先前寫入此封包號碼的數據。

STATUS_DATA_OVERRUN – 如果 OS 通過高於可以儲存在 WaveRT 緩衝區中的封包號碼,驅動程式就會傳回此錯誤。 在此情況下,發生故障狀況。 驅動程式可以選擇性地忽略封包中的數據。

STATUS_INVALID_DEVICE_STATE – 如果 OS 在先前設定KSSTREAM_HEADER_OPTIONSF_ENDOFSTREAM旗標之後呼叫此例程,驅動程式會傳回此錯誤。

STATUS_INVALID_PARAMETER – 如果驅動程序發現任何其他參數無效,除了其他錯誤狀態的特定案例之外,驅動程式會傳回此錯誤。 這包括上述未特別定義的旗標值。

言論

OS 呼叫此例程之後,驅動程式可以選擇性地使用所提供的資訊來優化硬體傳輸。 例如,驅動程式可能會優化 DMA 傳輸,或程式硬體以停止在指定封包的結尾傳輸,以防 OS 不會再次呼叫此例程,以通知驅動程式另一個封包。 這可以減輕下溢的聽覺效果,例如引入可聽見的間距,而不是重複迴圈緩衝區。 不過,驅動程式仍有義務以名義即時速率增加其內部封包計數器和訊號通知事件。

根據硬體功能,如果指定了KSSTREAM_HEADER_OPTIONSF_ENDOFSTREAM旗標,驅動程式可能會無聲填滿在 EOS 封包後面的 WaveRT 緩衝區部分,以防硬體傳輸超過 EOS 位置的數據。

用戶端會從預先輪替緩衝區開始。 當用戶端呼叫 ReleaseBuffer 時,這會轉譯為 AudioKSE 中的呼叫,該呼叫會呼叫 ACX 層,這會在作用中 ACXSTREAM 上呼叫 EvtAcxStreamSetRenderPacket。 屬性會包含封包索引(以 0 為基礎),如果適當的話,EOS 旗標的位元組位移位於目前封包的數據流結尾。   

範例使用方式如下所示。

    //
    // Init RT streaming callbacks.
    //
    ACX_RT_STREAM_CALLBACKS rtCallbacks;
    ACX_RT_STREAM_CALLBACKS_INIT(&rtCallbacks);

    rtCallbacks.EvtAcxStreamSetRenderPacket = EvtStreamSetRenderPacket;

    status = AcxStreamInitAssignAcxRtStreamCallbacks(StreamInit, &rtCallbacks);
#pragma code_seg("PAGE")
NTSTATUS
EvtStreamSetRenderPacket(
    _In_ ACXSTREAM Stream,
    _In_ ULONG     Packet,
    _In_ ULONG     Flags,
    _In_ ULONG     EosPacketLength
    )
{
    PSTREAM_CONTEXT ctx;
    NTSTATUS        status = STATUS_SUCCESS;

    PAGED_CODE();

    ctx = GetStreamContext(Stream);

    currentPacket = (ULONG)InterlockedCompareExchange((LONG*)&ctx->m_CurrentPacket, -1, -1);

    if (Packet <= currentPacket)
    {
        status = STATUS_DATA_LATE_ERROR;
    }
    else if (Packet > currentPacket + 1)
    {
        status = STATUS_DATA_OVERRUN;
    }

    return status;
}

ACX 需求

ACX 最低版本: 1.0

如需 ACX 版本的詳細資訊,請參閱 ACX 版本概觀

要求

要求 價值
標頭 acxstreams.h
IRQL PASSIVE_LEVEL

另請參閱