BMediaNode

Derived from: none

Declared in: be/media/MediaNode.h

Library: libmedia.so

Allocation: Constructor only

[method summary]

The BMediaNode class is the superclass of all participant nodes in the Media Kit. However, you'll never derive directly from BMediaNode; instead, you'll derive from one of the system interface classes which in turn are derived from BMediaNode. Look at the documentation for those other classes (such as BBufferProducer and BBufferConsumer) for details on how they're used, or see Creating New Node Classes for discussion on how this is done.

Because of the quirks of virtual inheritance (required by the use of multiple inheritance), your node's constructor will have to call the BMediaNode constructor. About Multiple Virtual Inheritance

Applications don't call a node's member functions directly; instead, you call the BMediaRoster with a reference to the node and let the request come to the node through the control port. The only exception is if the node is subclassed directly within the application, in which case Acquire() and Release() can be called directly.


Constructor and Destructor


BMediaNode()

protected:

      explicit BMediaNode(const char *name) 

Call this from your derived node's constructor.

The node is created with a reference count of 1; the count is incremented each time the Acquire() call is issued, and decremented each time Release() is called. When the reference count becomes zero, the node is deleted.


~BMediaNode

      ~BMediaNode() 

You may never delete a BMediaNode because you don't know for certain when the Media Server is done with it. Instead, the Media Server maintains a reference count for the node, and when it is no longer in use, the node will be deleted automatically.


Member Functions


Acquire(), Release()

      BMediaNode *Acquire(void)
      BMediaNode *Release(void)

Acquire() returns a pointer to the node, after incrementing the node's reference count.

Release() releases the node by decrementing its reference count. If the count reaches zero, the node is deleted and NULL is returned; otherwise, a pointer to the node is returned.

Although you usually can't call node member functions directly from within an application, you can call Acquire() and Release() directly if the node is subclassed within the application itself (rather than in an add-on).


AddNodeKind()

      void AddNodeKind(uint64 kind)

Adds a kind to the set of kinds supported by the node. This lets the system know what types of node interfaces are supported by the node's implementation. Possible values include B_BUFFER_PRODUCER (which indicates that the node implements the BBufferProducer protocol) and B_PHYSICAL_INPUT (which indicates that the node implements a physical input, such as a sound digitizing input device). For a complete list of kind values, see node_kind .

In general, you don't need to call this function. The base system classes call AddNodeKind() automatically to set up the node type flags; for example, a BBufferProducer automatically calls AddNodeKind(B_BUFFER_PRODUCER). The only time it's necessary go call AddNodeKind() is if the node you're implementing is a physical device or a mixer, in which case you need to add the B_PHYSICAL_INPUT, B_PHYSICAL_OUTPUT, or B_SYSTEM_MIXER flag.


AddOn()

      virtual BMediaAddOn *AddOn(int32 *outInternalID) const = 0

Implement this function to return a pointer to the BMediaAddOn that instantiated the node. If the node lives in an application (rather than in an add-on), return NULL. If the node is in an add-on, outInternalID should be changed to contain the internal ID number of the node within the add-on.


ChangeTag(), IncrementChangeTag()

protected:

      int32 ChangeTag(void) const
      int32 IncrementChangeTag(void)
      int32 MintChangeTag(void)
      status_t ApplyChangeTag(int32 previouslyReservedTag)


ChangeTag(), returns, the, node's, current, change, tag, value.

IncrementChangeTag() updates the change tag, so that downstream consumers know that the node is in a new state.

MintChangeTag() mints a new, reserved, change tag. Call ApplyChangeTag() to apply it to the node; this returns B_OK if the new change tag is successfully applied, or B_MEDIA_STALE_CHANGE_TAG if the new change count you tried to apply is already obsolete.


ControlPort()

      virtual port_id ControlPort(void) const = 0

Returns the port_id of the port to which the node listens for requests. Your node must implement this to return a valid Kernel Kit port.


HandleBadMessage()

      void HandleBadMessage(int32 message, const void *data, size_t size)

If your node receives a message that neither the node, nor any interface from which the node is derived, understands the message, pass the message along to this function, which will work magic to deal with the problem one way or another. All arguments received by the HandleMessage() function should be passed directly through to HandleBadMessage().


HandleMessage()

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

Given a message received on the control port, this function dispatches the message to the appropriate BMediaNode hook function. If the message doesn't correspond to a hook function, B_ERROR is returned.

When you implement a media node of your own (derived from BBufferConsumer, BBufferProducer, etc), you always need to call through to BMediaNode::HandleMessage() from your node's implementation of HandleMessage(). This is crucial, to be sure that every ancestor of your node gets to look at the message and attempt to process it.

For example, if your node inherits from both BBufferProducer and BBufferConsumer, you should call BBufferProducer::HandleMessage() and BBufferConsumer::HandleMessage(), then BMediaNode::HandleMessage(), like this:

   virtual status_t MyBufferProducerConsumer::HandleMessage(int32 message,
            const void *data, size_t size) {
      if (code == SOME_THING_I_DO) {
         DoWhatever();
      }
      else if (BBufferConsumer::HandleMessage(message, data, size) &&
               BBufferProducer::HandleMessage(message, data, size) &&
               BMediaNode::HandleMessage(message, data, size)) {
         BMediaNode::HandleBadMessage(message, data, size);
      }
   }

Note that BMediaNode::HandleBadMessage() is called if none of the HandleMessage() implementations accept the message.

Values of code between 0x60000000 and 0x7FFFFFFF are available for use by applications. Values below 0x60000000 are reserved for use by the Media Kit, and typically correspond to specific virtual hook functions within your node. If you can show just cause for needing to know the code value for a particular hook, you can try emailing devsupport@be.com and see if we agree with you, in which case we may share that information.

Don't reverse-engineer the code values; if you really need to know, as us. Otherwise, we won't know that a particular code shouldn't be changed. In general, it's a bad idea to rely on specific values, although there may be cases in which it's necessary.

RETURN CODES

B_OK. The message was dispatched.

B_ERROR. The message couldn't be dispatched, possibly because it doesn't correspond to a hook function.


ID()

      media_node_id ID(void) const

Returns the media_node_id assigned to the node by the Media Server. The result is 0 if the node hasn't been registered yet, and negative if an error occurred while attempting to register the node.


IncrementChangeTag() see ChangeTag()


Kinds()

      uint64 Kinds(void) const

Returns a bit mask indicating what interfaces the node implements. See node_kind for a list of valid interface kinds.


Name()

      const char *Name(void) const

Returns a human-readable string specifying the node's name. This pointer is only valid until you Release() the node; after that, the pointer may point into empty space.


Node()

      media_node Node(void) const

Returns the media_node structure that will be used by an application when accessing this node via the media roster.


Preroll()

protected:

      virtual void Preroll(void)

This hook function may be called before your node receives a Start() message if the application using the node calls BMediaRoster::PrerollNode(). This gives the node a chance to prepare the media so that when the media is started, the response is as fast as possible.


Release() see Acquire()


ReportError()

protected:

      status_t ReportError(node_error whichError,
         const BMessage *info = NULL)

Transmits the error code specified by whichError to anyone that's receiving notifications from this node (see BMediaRoster::StartWatching() and BMediaRoster::StopWatching() on ). If info isn't NULL, it's used as a model message for the error notification message.

RETURN CODES

B_OK. The error report was sent without error.

BMessage errors. The message couldn't be sent.


RunMode(), SetRunMode()

      run_mode RunMode(void) const

protected:

      virtual void SetRunMode(run_mode mode)

RunMode() returns the node's current run_mode setting.

The SetRunMode() hook function is called when someone requests that your node's run mode be changed.

See also: Run Modes


Seek()

protected:

      virtual void Seek(bigtime_t mediaTime, bigtime_t performanceTime)

This hook function is called when a node is asked to seek to the specified mediaTime by a call to the BMediaRoster.

The specified performanceTime, the time at which the node should begin the seek operation, may be in the future.

Your node is required to queue at least one each of start, stop, and seek requests, so that applications can establish, for example, both the start and stop time without having to monitor your node's progress. The actual size of these three queues is up to you. When the specified time arrives, the request should be filled.

A mediaTime value of 0 indicates the beginning of the media data.


SetRunMode() see RunMode()


SetTimeSource(), TimeSource()

      virtual void SetTimeSource(BTimeSource *timeSource)
      BTimeSource *TimeSource(void) const

The SetTimeSource() hook function is called when someone has requested that the node be slaved to a new time source. Augment this function to make whatever adjustments you need to make to operate at the new time scale.

TimeSource() returns a pointer to the BTimeSource to which the node is currently slaved. If no time source has been explicitly requested, the system time source is in use, and that's what gets returned.

The BTimeSource object returned by TimeSource() is only valid until the next call to HandleMessage() on that object. Therefore, if your node runs more than one thread, you need to serialize calls to TimeSource() (as well as usage of the returned objects) with calls to HandleMessage(). This isn't a problem if you follow the recommended policy of running a single thread that monitors the service port with read_port_etc() and calls HandleMessage() only when a message is actually received.


Start()

protected:

      virtual void Start(bigtime_t performanceTime)

This hook function is called when a node is started by a call to the BMediaRoster.

The specified performanceTime, the time at which the node should start running, may be in the future.

Your node is required to queue at least one each of start, stop, and seek requests, so that applications can establish, for example, both the start and stop time without having to monitor your node's progress. The actual size of these three queues is up to you. When the specified time arrives, the request should be filled.


Stop()

protected:

      virtual void Stop(bigtime_t performanceTime, bool immediate)

This hook function is called when a node is stopped by a call to the BMediaRoster.

The specified performanceTime, the time at which the node should stop, may be in the future.

If immediate is true, your node should ignore the performanceTime value and synchronously stop performance. When Stop() returns, you're promising not to write into any BBuffers you may have received from your downstream consumers, and you promise not to send any more buffers until Start() is called again.

Your node is required to queue at least one each of start, stop, and seek requests, so that applications can establish, for example, both the start and stop time without having to monitor your node's progress. The actual size of these three queues is up to you. When the specified time arrives, the request should be filled.

Nodes must recycle all buffers they may be holding onto when they're stopped.


TimeSource() see SetTimeSource()


TimeWarp()

protected:

      virtual void TimeWarp(bigtime_t atRealTime, bigtime_t newPerformanceTime)

This hook function is called when the time source to which the node is slaved is repositioned (via a seek operation) such that there will be a sudden jump in the performance time progression as seen by the node. The newPerformanceTime argument indicates the new performance time; the change should occur at the real time specified by the atRealTime argument.

The node should respond to this call by preparing for this change, so a serious stutter, failure, or acceleration in performance doesn't occur. Appropriate measures should be taken to minimize the impact on the performance quality; for example, a segment of the sound could be looped or skipped smoothly.

Your implementation of TimeWarp() should call through to BMediaNode::TimeWarp() as well as all other inherited forms of TimeWarp().


Constants


node_error

Declared in: <be/media/MediaNode.h>

Constant Description
B_NODE_FAILED_START The node failed on a Start() request.
B_NODE_FAILED_STOP The node failed on a Stop() request.
B_NODE_FAILED_SEEK The node failed on a Seek() request.
B_NODE_FAILED_SET_RUN_MODE The node's run_mode couldn't be set.
B_NODE_FAILED_TIME_WARP The node couldn't fulfill a time warp request.
B_NODE_FAILED_PREROLL The node failed on a Preroll() request.
B_NODE_FAILED_SET_TIME_SOURCE_FOR The node's time source couldn't be changed.
B_NODE_IN_DISTRESS The node is suffering in general.

The node_error type defines the errors a node can transmit to BMessengers that have registered to watch the node.


node_kind

Declared in: <be/media/MediaNode.h>

Constant Description
B_BUFFER_PRODUCER The flavor implements BBufferProducer.
B_BUFFER_CONSUMER The flavor implements BBufferConsumer.
B_TIME_SOURCE The flavor implements BTimeSource.
B_CONTROLLABLE The flavor implements BControllable.
B_FILE_INTERFACE The flavor implements BFileInterface.
B_ENTITY_INTERFACE The flavor implements BEntityInterface (not available for R4).
B_PHYSICAL_INPUT The flavor represents a physical input point (such as an input jack).
B_PHYSICAL_OUTPUT The flavor represents a physical output point (such as line output).
B_SYSTEM_MIXER The flavor represents the system mixer.

Defines the type or types of node that a particular flavor supports. Note that a flavor can implement more than one type of node, so you can combine these values using a bitwise or.


run_mode

Declared in: <be/media/MediaNode.h>

Constant Description
B_OFFLINE Keep data accurate, even if the performance lags or runs too fast. This is typically used when rendering to disk.
B_RECORDING Time-stamped buffers are being received from a node capturing them from the real world; these buffers are guaranteed to have a time stamp in the past (they're always "late").
B_DECREASE_PRECISION If the performance starts to lag, try to catch up.
B_INCREASE_LATENCY If the performance starts to lag, increase playout delay so buffers are delivered with less tiem to spare before they're needed.
B_DROP_DATA If the performance starts to lag, skip data.

The run_mode type indicates how a node should cope if its performance rate deviates from the desired rate.






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

Copyright © 1998 Be, Inc. All rights reserved.

Last modified December 22, 1998.