This message is used to get or return an empty or full buffer, depending on whether the stream handler is a target or source of data. The message can return or request not only the next available buffer, but also the next n buffers. For example, a target stream handler can request the next 3 available full buffers, instead of the next available buffer, if it needs to speed up its consumption of buffers.
The target stream handler should return the empty buffers in the reverse order in which they were retrieved from the Sync/Stream Manager. The target stream handler must be able to accept a NULL buffer pointer on a BUF_GETFULL request because the BUF_EOS flag may be set, but there may not be any buffers left to consume.
All buffers allocated by the Sync/Stream Manager are fixed and cannot be swapped.
The Sync/Stream Manager provides the ability for a source stream handler to associate one cue point with a buffer that it passes to the Sync/Stream Manager. This buffer and attribute remain in the data stream until the target stream handler requests it. The attribute for the buffer is passed with the buffer to the target. See the ulMessageParm and mmtimeOffset parameters for a description of the buffer attribute. The target stream handler then must report an EVENT_PLAYLISTCUEPOINT event, at the appropriate time, with the buffer attribute as the message parameter (the ulMessageParm field in the PLAYL_EVCB structure).
This source stream handler feature of the Sync/Stream Manager supports the memory-playlist ability to send a cue-point event as close to the actual time it occurs as possible. For this to work, it must be the target stream handler that detects the cue-point event and reports it to the application media control driver. If the system-memory stream handler is the source stream handler, it must notify the target stream handler to report a cue-point event.
The contents of the ulMessageParm parameter are defined by the user application. For example, if the system-memory stream handler is the source stream handler, and it receives a playlist from the user application, the playlist CUEPOINT instruction defines the contents of the buffer attribute passed to the target stream handler. The target stream handler then reports the event and passes the buffer attribute as an event parameter.
For split streams, a buffer can be divided into multiple variable-length records. This is useful for streaming interleaved data from one source stream handler, in multiple streams, to one or more target stream handlers, where each stream represents a different data type.
The source stream handler requests one buffer at a time from the Sync/Stream Manager and returns filled records to the Sync/Stream Manager. The source stream handler specifies which stream the records will go in. Each stream goes to a different target stream handler. The pRecord field of the pointer table are not used for normal non-split streams. The source stream handler can return multiple records of a specific data type to a stream, but these all must be contained within the same buffer. The last record of each buffer is indicated by using the BUF_LASTRECORD flag; it is only sent to the stream that receives the last record for a buffer. The BUF_EOS flag, on the other hand, is sent to all streams when the last buffer or record is returned to the Sync/Stream Manager.
The SMH_NOTIFY message also can accept user-provided buffers into a stream to be passed directly from the source stream handler to the target stream handler. This is accomplished with the BUF_GIVEBUF flag, which enables the source stream handler to give a buffer and length to the Sync/Stream Manager eventually to be passed to the target stream handler for a BUF_GETFULL request. Each buffer given to the Sync/Stream Manager is used once. The BUF_GIVEBUF is only available on DLL SMH_NOTIFY calls. The Sync/Stream Manager returns ERROR_TOO_MANY_BUFFERS to the source stream handler if it attempts to give too many buffers. The BUF_GIVEBUF feature is provided primarily for the memory stream handler to be able to stream data from an application's memory.
For DLL stream handlers, all pointers returned are 32-bit flat process linear addresses. For device driver stream handlers, pointers returned in an SMH_NOTIFY message are either 32-bit, flat, global linear addresses, physical addresses, or GDT selector and offset addresses. The latter is the default. The others are selectable for each SMH_NOTIFY message.
Note: The physical addresses are pointers to physically contiguous memory, not a page table. The SPCBBUF_NONCONTIGUOUS bit must not be set to On in the SPCB to get a physical address from the Sync/Stream Manager. The Sync/Stream Manager fails requests for physical addresses if this bit is set.
Valid Source SH (PRODUCER) Request Combinations to SMH_NOTIFY:
Any combination of BUF_GETEMPTY and BUF_RETURNFULL can be used for the same SMH_NOTIFY function.
Either BUF_LINEAR or BUF_PHYSICAL can be used with any combination of BUF_GETEMPTY, BUF_RETURNFULL, BUF_GIVEBUF, BUF_GDT, and BUF_EXTENDEDPTR. BUF_LINEAR and BUF_PHYSICAL are valid only for device driver stream handlers.
BUF_GIVEBUF
Valid Target SH (Consumer) Request Combinations to SMH_NOTIFY:
Any combination of BUF_GETFULL and BUF_RETURNEMPTY can be used for the same SMH_NOTIFY function. As far as the target stream handler is concerned, records are the same as buffers.
Either BUF_LINEAR or BUF_PHYSICAL can be used with any combination of BUF_GETFULL and BUF_RETURNEMPTY. BUF_LINEAR and BUF_PHYSICAL are valid only for device driver stream handlers.
BUF_GETFULL