root/headers/os/media/MediaRoster.h
/*
 * Copyright (c) 2008 Haiku, Inc. All rights reserved.
 * Distributed under the terms of the the MIT licence.
 *
 */

//! The BMediaRoster is the main API to the Media Kit.

#ifndef _MEDIA_ROSTER_H
#define _MEDIA_ROSTER_H

#include <MediaDefs.h>
#include <MediaNode.h>


typedef enum {
        B_ISA_BUS,
        B_PCI_BUS,
        B_PCMCIA_BUS,
        B_UNKNOWN_BUS = 0x80
} bus_type;


class BBufferGroup;
class BMediaAddOn;
class BMimeType;
class BParameterWeb;
class BString;

struct dormant_flavor_info;
struct entry_ref;

namespace BPrivate { namespace media {
        class DefaultDeleter;
        class BMediaRosterEx;
} } // BPrivate::media


class BMediaRoster : public BLooper {
public:

        // Retrieving the global instance of the BMediaRoster:
        static  BMediaRoster*           Roster(status_t* _error = NULL);
                                // This version will create a roster instance if there isn't
                                // one already. Thread safe for multiple calls to Roster().

        static  BMediaRoster*           CurrentRoster();
                                // This version won't create an instance if there isn't one
                                // already. It is not thread safe if you call Roster() at the
                                // same time.

        // Check if the media services are running.
        static  bool                            IsRunning();

        // Getting common instances of system nodes:
                        status_t                        GetVideoInput(media_node* _node);
                        status_t                        GetAudioInput(media_node* _node);
                        status_t                        GetVideoOutput(media_node* _node);
                        status_t                        GetAudioMixer(media_node* _node);
                        status_t                        GetAudioOutput(media_node* _node);
                                // The output should not be used directly in common use cases.
                                // Use the mixer node instead.
                        status_t                        GetAudioOutput(media_node* _node,
                                                                        int32* _inputId, BString* _inputName);
                        status_t                        GetTimeSource(media_node* _node);

        // Setting common system nodes:
                        status_t                        SetVideoInput(const media_node& producer);
                        status_t                        SetVideoInput(
                                                                        const dormant_node_info& producer);

                        status_t                        SetAudioInput(const media_node& producer);
                        status_t                        SetAudioInput(
                                                                        const dormant_node_info& producer);

                        status_t                        SetVideoOutput(const media_node& consumer);
                        status_t                        SetVideoOutput(
                                                                        const dormant_node_info& consumer);

                        status_t                        SetAudioOutput(
                                                                        const media_node& consumer);
                        status_t                        SetAudioOutput(
                                                                        const media_input& inputToOutput);
                        status_t                        SetAudioOutput(
                                                                        const dormant_node_info& consumer);

        // Get a media_node from a node ID -- this is how you reference your
        // own nodes!
                        status_t                        GetNodeFor(media_node_id node,
                                                                        media_node* clone);
                        status_t                        GetSystemTimeSource(media_node* clone);
                                // Typically, you'll want to use GetTimeSource() instead.
                        status_t                        ReleaseNode(const media_node& node);
                                // This method might free the node if there are no
                                // more references.
                        BTimeSource*            MakeTimeSourceFor(const media_node& for_node);
                                // Release() the returned object when done!

                        status_t                        Connect(const media_source& from,
                                                                        const media_destination& to,
                                                                        media_format* _inOutFormat,
                                                                        media_output* _output,
                                                                        media_input* _input);
                                // Note that the media_source and media_destination found in
                                // _output and _input are the ones actually used. From and to
                                // are only "hints" that the app should not use once a real
                                // connection has been established.

                        enum connect_flags {
                                B_CONNECT_MUTED = 0x1
                        };
                
                        status_t                        Connect(const media_source& from,
                                                                        const media_destination& to,
                                                                        media_format* _inOutFormat,
                                                                        media_output* _output,
                                                                        media_input* _input,
                                                                        uint32 flags, void* _reserved = NULL);
                                
                        status_t                        Disconnect(media_node_id sourceNode,
                                                                        const media_source& source,
                                                                        media_node_id destinationNode,
                                                                        const media_destination& destination);

                
                        status_t                        Disconnect(const media_output& output,
                                                                        const media_input& input);
                                // NOTE: This is a Haiku extension.

                        status_t                        StartNode(const media_node& node,
                                                                        bigtime_t atPerformanceTime);
                        status_t                        StopNode(const media_node& node,
                                                                        bigtime_t atPerformanceTime,
                                                                        bool immediate = false);
                                // If "immediate" is true, "atPerformanceTime" is ignored.
                        status_t                        SeekNode(const media_node& node,
                                                                        bigtime_t toMediaTime,
                                                                        bigtime_t atPerformanceTime = 0);
                                // NOTE: The node needs to be running.

                        status_t                        StartTimeSource(const media_node& node,
                                                                        bigtime_t atRealTime);
                        status_t                        StopTimeSource(const media_node& node,
                                                                        bigtime_t atRealTime,
                                                                        bool immediate = false);
                        status_t                        SeekTimeSource(const media_node& node,
                                                                        bigtime_t toPerformanceTime,
                                                                        bigtime_t atRealTime);

                        status_t                        SyncToNode(const media_node& node,
                                                                        bigtime_t atTime,
                                                                        bigtime_t timeout = B_INFINITE_TIMEOUT);
                        status_t                        SetRunModeNode(const media_node& node,
                                                                        BMediaNode::run_mode mode);
                        status_t                        PrerollNode(const media_node& node);
                                // NOTE: This method is synchronous.
                        status_t                        RollNode(const media_node& node, 
                                                                        bigtime_t startPerformance,
                                                                        bigtime_t stopPerformance,
                                                                        bigtime_t atMediaTime
                                                                                = -B_INFINITE_TIMEOUT);

                        status_t                        SetProducerRunModeDelay(const media_node& node,
                                                                        bigtime_t delay,
                                                                        BMediaNode::run_mode mode
                                                                                = BMediaNode::B_RECORDING);
                                // NOTE: Should only be used with B_RECORDING
                        status_t                        SetProducerRate(const media_node& producer,
                                                                        int32 numer, int32 denom);
                                // NOTE: This feature is not necessarily supported by the node.

        // Retrieving information about available inputs/outputs.
        // Nodes will have available inputs/outputs as long as they are capable
        // of accepting more connections. The node may create an additional
        // output or input as the currently available is taken into usage.
                        status_t                        GetLiveNodeInfo(const media_node& node,
                                                                        live_node_info* _liveInfo);
                        status_t                        GetLiveNodes(live_node_info* _liveNodes,
                                                                        int32* inOutTotalCount,
                                                                        const media_format* hasInput = NULL,
                                                                        const media_format* hasOutput = NULL,
                                                                        const char* name = NULL,
                                                                        uint64 nodeKinds = 0);
                                                                                // B_BUFFER_PRODUCER etc.

                        status_t                        GetFreeInputsFor(const media_node& node,
                                                                        media_input* _freeInputsBuffer,
                                                                        int32 bufferCapacity,
                                                                        int32* _foundCount,
                                                                        media_type filterType
                                                                                = B_MEDIA_UNKNOWN_TYPE);
                        status_t                        GetConnectedInputsFor(const media_node& node,
                                                                        media_input* _activeInputsBuffer,
                                                                        int32 bufferCapacity,
                                                                        int32* _foundCount);
                        status_t                        GetAllInputsFor(const media_node& node,
                                                                        media_input* _inputsBuffer,
                                                                        int32 bufferCapacity,
                                                                        int32* _foundCount);
                        status_t                        GetFreeOutputsFor(const media_node& node,
                                                                        media_output* _freeOutputsBuffer,
                                                                        int32 bufferCapacity,
                                                                        int32* _foundCount,
                                                                        media_type filterType
                                                                                = B_MEDIA_UNKNOWN_TYPE);
                        status_t                        GetConnectedOutputsFor(const media_node& node,
                                                                        media_output* _activeOutputsBuffer,
                                                                        int32 bufferCapacity,
                                                                        int32* _foundCount);
                        status_t                        GetAllOutputsFor(const media_node& node,
                                                                        media_output* _outputsBuffer,
                                                                        int32 bufferCapacity,
                                                                        int32* _foundCount);

        // Event notification support:
                        status_t                        StartWatching(const BMessenger& target);
                        status_t                        StartWatching(const BMessenger& target,
                                                                        int32 notificationType);
                        status_t                        StartWatching(const BMessenger& target,
                                                                        const media_node& node,
                                                                        int32 notificationType);
                        status_t                        StopWatching(const BMessenger& target);
                        status_t                        StopWatching(const BMessenger& target,
                                                                        int32 notificationType);
                        status_t                        StopWatching(const BMessenger& target,
                                                                        const media_node& node,
                                                                        int32 notificationType);

                        status_t                        RegisterNode(BMediaNode* node);
                        status_t                        UnregisterNode(BMediaNode* node);

                        status_t                        SetTimeSourceFor(media_node_id node,
                                                                        media_node_id timeSource);

        // Building a control GUI for a node:
                        status_t                        GetParameterWebFor(const media_node& node, 
                                                                        BParameterWeb** _web);
                        status_t                        StartControlPanel(const media_node& node,
                                                                        BMessenger* _messenger = NULL);

        // Information about nodes which are not running, but could
        // be instantiated from add-ons:
                        status_t                        GetDormantNodes(dormant_node_info* _info,
                                                                        int32* _inOutCount,
                                                                        const media_format* _hasInput = NULL,
                                                                        const media_format* _hasOutput = NULL,
                                                                        const char* name = NULL,
                                                                        uint64 requireKinds = 0,
                                                                        uint64 denyKinds = 0);
                        status_t                        InstantiateDormantNode(
                                                                        const dormant_node_info& info,
                                                                        media_node* _node,
                                                                        uint32 flags);
                                // NOTE: Supported flags are currently B_FLAVOR_IS_GLOBAL
                                // or B_FLAVOR_IS_LOCAL
                        status_t                        InstantiateDormantNode(
                                                                        const dormant_node_info& info,
                                                                        media_node* _node);
                        status_t                        GetDormantNodeFor(const media_node& node,
                                                                        dormant_node_info* _info);
                        status_t                        GetDormantFlavorInfoFor(
                                                                        const dormant_node_info& info,
                                                                        dormant_flavor_info* _flavor);

        // Latency information:
                        status_t                        GetLatencyFor(const media_node& producer,
                                                                        bigtime_t* _latency);
                        status_t                        GetInitialLatencyFor(
                                                                        const media_node& producer,
                                                                        bigtime_t* _latency,
                                                                        uint32* _flags = NULL);
                        status_t                        GetStartLatencyFor(
                                                                        const media_node& timeSource,
                                                                        bigtime_t* _latency);

        // Finding a suitable node to playback a file:
                        status_t                        GetFileFormatsFor(
                                                                        const media_node& fileInterface, 
                                                                        media_file_format* _formatsBuffer,
                                                                        int32* _inOutNumInfos);
                        status_t                        SetRefFor(const media_node& fileInterface,
                                                                        const entry_ref& file,
                                                                        bool createAndTruncate,
                                                                        bigtime_t* _length);
                                                                                // if create is false
                        status_t                        GetRefFor(const media_node& node,
                                                                        entry_ref* _ref,
                                                                        BMimeType* mimeType = NULL);
                        status_t                        SniffRefFor(const media_node& fileInterface,
                                                                        const entry_ref& ref, BMimeType* _mimeType,
                                                                        float* _capability);
        // This is the generic "here's a file, now can someone please play it"
        // interface:
                        status_t                        SniffRef(const entry_ref& ref,
                                                                        uint64 requireNodeKinds,
                                                                                // if you need an EntityInterface
                                                                                // or BufferConsumer or something
                                                                        dormant_node_info* _node,
                                                                        BMimeType* _mimeType = NULL);
                        status_t                        GetDormantNodeForType(const BMimeType& type,
                                                                        uint64 requireNodeKinds,
                                                                        dormant_node_info* _info);
                        status_t                        GetReadFileFormatsFor(
                                                                        const dormant_node_info& node,
                                                                        media_file_format* _readFormatsBuffer,
                                                                        int32 bufferCapacity, int32* _foundCount);
                        status_t                        GetWriteFileFormatsFor(
                                                                        const dormant_node_info& node,
                                                                        media_file_format* _writeFormatsBuffer,
                                                                        int32 bufferCapacity, int32* _foundCount);

                        status_t                        GetFormatFor(const media_output& output,
                                                                        media_format* _inOutFormat,
                                                                        uint32 flags = 0);
                        status_t                        GetFormatFor(const media_input& input,
                                                                        media_format* _inOutFormat,
                                                                        uint32 flags = 0);
                        status_t                        GetFormatFor(const media_node& node,
                                                                        media_format* _inOutFormat,
                                                                        float quality = B_MEDIA_ANY_QUALITY);
                        ssize_t                         GetNodeAttributesFor(const media_node& node,
                                                                        media_node_attribute* outArray,
                                                                        size_t inMaxCount);
                        media_node_id           NodeIDFor(port_id sourceOrDestinationPort);
                        status_t                        GetInstancesFor(media_addon_id addon,
                                                                        int32 flavor,media_node_id* _id,
                                                                        int32* _inOutCount = NULL);
                                                                                // _inOutCount defaults to 1
                                                                                // if unspecified (NULL).

        // Returns the preferred audio buffer size
                        ssize_t                         AudioBufferSizeFor(int32 channelCount,
                                                                        uint32 sampleFormat, float frameRate,
                                                                        bus_type busType = B_UNKNOWN_BUS);

        // Use MediaFlags to inquire about specific features of the Media Kit.
        // Returns < 0 for "not present", positive size for output data size.
        // 0 means that the capability is present, but no data about it.
        static  ssize_t                         MediaFlags(media_flags cap, void* buffer,
                                                                        size_t maxSize);

        // BLooper overrides
        virtual void                            MessageReceived(BMessage* message);
        virtual bool                            QuitRequested();

        virtual BHandler*                       ResolveSpecifier(BMessage* message,
                                                                        int32 index, BMessage* specifier,
                                                                        int32 form, const char* property);
        virtual status_t                        GetSupportedSuites(BMessage* data);

        virtual                                         ~BMediaRoster();

private:

        // Reserving virtual function slots.
        virtual status_t                        _Reserved_MediaRoster_0(void*);
        virtual status_t                        _Reserved_MediaRoster_1(void*);
        virtual status_t                        _Reserved_MediaRoster_2(void*);
        virtual status_t                        _Reserved_MediaRoster_3(void*);
        virtual status_t                        _Reserved_MediaRoster_4(void*);
        virtual status_t                        _Reserved_MediaRoster_5(void*);
        virtual status_t                        _Reserved_MediaRoster_6(void*);
        virtual status_t                        _Reserved_MediaRoster_7(void*);

        friend class BPrivate::media::DefaultDeleter;
        friend class BPrivate::media::BMediaRosterEx;

        // Constructor is private, since you are supposed to use
        // Roster() or CurrentRoster().
                                                                BMediaRoster();

        // Those methods are deprecated or considered useless
        // NOTE: planned to be removed once we break the API.
                        status_t                        SetOutputBuffersFor(const media_source& output,
                                                                        BBufferGroup* group,
                                                                        bool willReclaim = false);

                        status_t                        SetRealtimeFlags(uint32 enabledFlags);
                        status_t                        GetRealtimeFlags(uint32* _enabledFlags);

        static  status_t                        ParseCommand(BMessage& reply);

                        status_t                        GetDefaultInfo(media_node_id forDefault,
                                                                        BMessage& _config);
                        status_t                        SetRunningDefault(media_node_id forDefault,
                                                                        const media_node& node);
        // End of deprecated methods

private:
                        uint32                          _reserved_media_roster_[67];

        static  BMediaRoster*           sDefaultInstance;
};


#endif // _MEDIA_ROSTER_H