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
,指示数据包是流中的最后一个数据包,EosPacketLength 是数据包的有效长度(以字节为单位)。 有关详细信息,请参阅 KSSTREAM_HEADER 结构 (ks.h)中的 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 |