BBufferConsumer

Derived from: virtual BMediaNode

Declared in: be/media/BufferConsumer.h

Library: libmedia.so

Allocation: Constructor only

[method summary]

BBufferConsumer is the counterpart to the BBufferProducer class--it receives BBuffers from the BBufferProducers that are connected to it, manipulates them in some fashion (either by altering the contents of the buffer or by playing the buffer's data to the speakers or to the screen), and possibly then passes them along to another BBufferConsumer (if the node also inherits from BBufferProducer).

The functions in this class aren't called by applications or by other nodes; they're called exclusively by the Media Kit to control and obtain information about a buffer consumer.

A BBufferConsumer publishes certain inputs, identified by a media_destination structure, on which connections may be requested by a client application.

<<<add further discussion here, as necessary>>>


Constructor and Destructor


BBufferConsumer()

protected:

      BBufferConsumer(media_type consumerType = B_MEDIA_UNKNOWN_TYPE) 

The BBufferConsumer constructor. Specify as consumerType the type of data the BBufferConsumer accepts.


~BBufferConsumer

The BBufferConsumer destructor is private and cannot be called directly. Call BMediaRoster::Release() when you're done using the BBufferConsumer; the Media Server will dispose of it at the appropriate time.


Member Functions


AcceptFormat()

      virtual status_t AcceptFormat(const media_destination &destination,
         media_format *format) = 0

Implement this hook function to check that the specified format is reasonable for the specified destination, and to fill in any wildcard fields for which your BBufferConsumer has specific requirements.

If the format isn't reasonable (or is of a class that's unsuitable for dest), return B_BAD_FORMAT.

When AcceptFormat() returns B_OK, the Media Kit will expect a connection request on destination with the specified format not to fail due to a format incompatibility.

Don't try to ask the upstream producer about the format; it's waiting synchronously for your response, and doing so will cause deadlock.


BufferReceived()

protected:

      virtual void BufferReceived(BBuffer *buffer) = 0

When a BBufferProducer sends buffers to one of your BBufferConsumer's inputs, it will eventually arrive here, at the BufferReceived() function (usually after first being dispatched by HandleMessage()).

Override this hook function to add the buffer to your internal playback queue, or to do whatever your node needs to do with buffers you consume. If you implement both BBufferProducer and BBufferConsumer, it's possible you might examine or alter the data in the buffer and then call BBufferProducer::BroadcastBuffer() to send it along to someone else.

Information about the contents and timing requirements of the buffer can be obtained by calling BBuffer::Header() on it.


Connected()

protected:

      virtual status_t Connected(const media_source &producer,
         const media_destination &whichInput,
         const media_format *format,
         media_input *ioName) = 0

This hook function is called when a connection is being established to your input whichInput from the specified producer. The connection will be composed of media data with the specified format (which you've previously accepted via AcceptFormat()).

Your implementation of Connected() should do whatever preparation you need to do to handle data input on the connection, and fill out the outInput buffer with information about the connection from your node's point-of-view. You can set outInput's destination field different from whichInput if whichInput is a global connection-establishing input that's used to negotiate a connection, then create a new input to actually handle the data stream.

Since your BBufferConsumer has already had the opportunity to reject the specified format, it's poor form to return an error from this function. You should only return an error if the resources needed to establish the connection have become unavailable prior to the time Connected() was called.

On entry, the ioName argument contains the name given the connection by the producer (this may be an empty string if the producer didn't assign a name). Your consumer should always make sure there's a valid name here, because it's a bad thing to have unnamed connections, and there's no guarantee that the producer will fill this in. If you don't have a good, descriptive name for a connection, the name should minimally contain the name of the node and a number that makes the connection's name unique (such as "MyNode Input 1" or "MyNode Output 3").

Return B_OK if the connection is started safely, otherwise, return an appropriate error code.


ConsumerType()

      media_type ConsumerType(const void)

Returns the type of media the BBufferConsumer consumes.


Disconnected()

protected:

      virtual void Disconnected(const media_source &producer,
         const media_destination &whichInput) = 0

This hook function is called when a connection is being terminated. You should do whatever needs to be done in order to ensure that future inquiries about the input whichInput reference media_source::null (or, if another connection is later established on the input, that producer).


DisposeInputCookie()

protected:

      virtual void DisposeInputCookie(int32 cookie) = 0

If the cookie value you return in GetNextInput() is a pointer to an object that needs to be deleted when the iteration process is completed, be sure to implement DisposeInputCookie() to do so.


RequestFormatChange()


GetLatencyFor()

protected:

      virtual status_t GetLatencyFor(const media_destination &forWhom,
         bigtime_t *outLatency,
         media_node_id *outTimeSource) = 0

Implement this hook function to calculate the total latency for the media_destination specified by forWhom and store the resulting value in outLatency. Also, return the time source your node is slaved to in outTimeSource.

If your node is a BBufferProducer as well as a BBufferConsumer, you should include in your computed latency the latency of any nodes downstream from the specified connection that are slaved to the same time source.

Return B_OK if you successfully compute the latency; otherwise, return an appropriate error.


GetNextInput()

      virtual status_t GetNextInput(int32 *cookie, media_input *outInput) = 0

The first time a client calls this function, the value pointed to by cookie will be 0. You should fill the buffer pointed to by outInput with information about your first input, and set the value at cookie to something (other than zero) that will let you keep track of what to return the next time GetNextInput() is called.

Each successive call to GetNextInput() will pass back, in cookie, the value you returned in cookie the last time the function was called by that client, and you should fill outInput with information about the next input, and store a new value in cookie to continue to track your progress through the inputs.

Whenever this function is called with a value of zero in cookie, you must start over with the first input.

When you reach the last input, return B_ERROR to indicate that there aren't any more inputs.


HandleMessage()

protected:

      virtual status_t HandleMessage(int32 message, const void *data, size_t size)

When your node derived from BBufferConsumer receives a message on its control port, you should try dispatching it by calling BBufferConsumer::HandleMessage(). If BBufferConsumer doesn't understand the message, it'll return B_ERROR and you can try dispatching it to another class from which your node is derived, or handle it yourself.

If this function returns B_OK, the message has been handled.

See also: BMediaNode::HandleMessage(), About Multiple Virtual Inheritance


NotifyLateProducer()

static:

      void NotifyLateProducer(const media_source &source, bigtime_t howLate,
         bigtime_t performanceTime)

Notifies the BBufferProducer specified by source that it's running late by howLate microseconds; the notification conditions as of the specified performanceTime. Call this function when you detect that data is arriving too late and the run mode is B_DECREASE_PRECISION, B_INCREASE_LATENCY, or B_DROP_DATA (any of which permits adjustment of the media playback to maintain timeliness).

The producer should process this notification immediately and take the appropriate action.


ProducerDataStatus()

protected:

      virtual void ProducerDataStatus(const media_destination &destination,
         int32 status, bigtime_t atMediaTime) = 0

This hook function is called to inform your consumer about changes in the availability of buffers from the producer that's connected to the input destination. The status argument specifies what change has occurred, and atMediaTime indicates when the change happened (or when it will happen).

This lets you keep track of which inputs you should await data from; for example, if your consumer is processing data arriving from four producers, and one of them stops sending buffers to the consumer, the producer that's stopping will cause a call to ProducerDataStatus() to let you know not to await buffers anymore. This way, you know that when buffers have arrived from the other three inputs, it's okay to begin processing the buffers.

Constant Meaning
B_DATA_NOT_AVAILABLE The producer doesn't have any data available.
B_DATA_AVAILABLE The producer has data available.


RegionToClipData()

protected:

      static status_t RegionToClipData(const BRegion *region, int32 *format,
         int32 *ioSize, void *data)

Converts a BRegion into the clipping format used internally by the Media Kit. Prior to calling RegionToClipData(), ioSize is set to the size of the buffer pointed to by data. On return, format is the format of the clipping data, ioSize is changed to the actual number of bytes of data returned, and data contains the actual clipping data.

The clip data format is described in the section Video Clipping .

RETURN CODES

B_OK. Clip data returned without errors.

B_NO_MEMORY. The data buffer isn't big enough.

See also: Video Clipping


RequestFormatChange, FormatChanged()

protected:

      static status_t RequestFormatChange(const media_source &source,
         const media_destination &destination,
         media_format *ioNewFormat, int32 *outFromChangeTag)
      virtual status_t FormatChanged(const media_source &source,
         const media_destination &destination, int32 fromChangeTag,
         media_format newFormat) = 0

RequestFormatChange() requests that the producer source connected to the consumer destination change the format it produces to the format specified by ioNewFormat.

On return, ioNewFormat contains the actual format to which the data flow has been changed; this may differ from the requested format if wildcards were used in the request. The change will take effect at the change tag value returned in outFromChangeTag.

FormatChanged() is called by the upstream producer when the media format your node will be receiving changes, and indicates the new format in newFormat and the change tag value at which the new format will take effect in fromChangeTag. You should implement this function so your node will know that the data format is going to change. Note that this may be called in response to your AcceptFormat() call, if your AcceptFormat() call alters any wildcard fields in the specified format.

Because FormatChanged() is called by the producer, you don't need to (and shouldn't) ask it if the new format is acceptable.

If the format change isn't possible, return an appropriate error from FormatChanged(); this error will be passed back to the producer that initiated the new format negotiation in the first place.

RETURN CODES

B_OK. No error.

B_MEDIA_BAD_SOURCE. The specified source isn't valid.

B_MEDIA_BAD_DESTINATION. The specified destination is invalid.

Port errors. See 34653: className: Ports.


SetOutputEnabled()

protected:

      static status_t SetOutputEnabled(const media_source &output,
         bool enabled,
         int32 *outFromChangeTag)

Specifies whether or not the specified output should be transmitting buffers. If enabled is true, the producer should transmit buffers; otherwise it should not. The change in state will occur at the change tag value indicated by outFromChangeTag.

RETURN CODES

B_OK. The change was requested successfully.

Other errors. The change could not be made.


SetVideoClippingFor()

protected:

      static status_t SetVideoClippingFor(const media_source &output,
         const int16 *shortsList,
         int32 shortCount,
         const media_video_display_info &display,
         int32 &outFromChangeTag)

This function requests that the specified output clip all its writing in buffers it sends to the BBufferConsumer to the specified clipping region. This information is in the format returned by RegionToClipData(). On return, outFromChangeTag indicates the change tag value at which the change will take effect.

The media_video_display_info structure referenced by display describes the current configuration of the video in terms of color space, resolution, and so forth.

The clip data format is described in the section Video Clipping .

RETURN CODES

B_OK. The clipping request has been sent without errors.

B_MEDIA_BAD_CLIP_FORMAT. The clipping data isn't formatted correctly.

Port errors. See 34653: className: Ports.

See also: Video Clipping






The Be Book, in lovely HTML, for BeOS Release 4.

Copyright © 1998 Be, Inc. All rights reserved.

Last modified December 22, 1998.