/* * Copyright 2009, Haiku, Inc. All rights reserved. * Distributed under the terms of the MIT License. */ #ifndef _BUFFER_PRODUCER_H #define _BUFFER_PRODUCER_H #include class BBuffer; class BBufferGroup; class BRegion; namespace BPrivate { namespace media { class BMediaRosterEx; } } class BBufferProducer : public virtual BMediaNode { protected: // NOTE: This has to be at the top to force a vtable. virtual ~BBufferProducer(); public: // Supported formats for low-level clipping data enum { B_CLIP_SHORT_RUNS = 1 }; // Handy conversion function for dealing with clip information. static status_t ClipDataToRegion(int32 format, int32 size, const void* data, BRegion* region); media_type ProducerType(); protected: explicit BBufferProducer(media_type producer_type /* = B_MEDIA_UNKNOWN_TYPE */); enum suggestion_quality { B_ANY_QUALITY = 0, B_LOW_QUALITY = 10, B_MEDIUM_QUALITY = 50, B_HIGH_QUALITY = 100 }; // BBufferProducer interface virtual status_t FormatSuggestionRequested(media_type type, int32 quality, media_format* format) = 0; virtual status_t FormatProposal(const media_source& output, media_format* ioFormat) = 0; // If the format isn't good, put a good format into ioFormat and // return error. // If format has wildcard, specialize to what you can do (and change). // If you can change the format, return OK. // The request comes from your destination sychronously, so you cannot ask // it whether it likes it -- you should assume it will since it asked. virtual status_t FormatChangeRequested( const media_source& source, const media_destination& destination, media_format* ioFormat, int32* _deprecated_) = 0; virtual status_t GetNextOutput( int32* ioCookie, media_output* _output) = 0; virtual status_t DisposeOutputCookie(int32 cookie) = 0; // In this function, you should either pass on the group to your upstream // guy, or delete your current group and hang on to this group. Deleting // the previous group (unless you passed it on with the reclaim flag set // to false) is very important, else you will 1) leak memory and 2) block // someone who may want to reclaim the buffers living in that group. virtual status_t SetBufferGroup(const media_source& forSource, BBufferGroup* group) = 0; // Format of clipping is (as int16-s): // . Repeat for each line where the clipping is different from // the previous line. If is negative, use the data from line // - (there are 0 pairs after a negative . Yes, we only // support 32k*32k frame buffers for clipping. Any non-0 field of // 'display' means that that field changed, and if you don't support that // change, you should return an error and ignore the request. Note that // the buffer offset values do not have wildcards; 0 (or -1, or whatever) // are real values and must be adhered to. virtual status_t VideoClippingChanged( const media_source& forSource, int16 numShorts, int16* clipData, const media_video_display_info& display, int32 * _deprecated_); // Iterates over all outputs and maxes the latency found virtual status_t GetLatency(bigtime_t* _lantency); virtual status_t PrepareToConnect(const media_source& what, const media_destination& where, media_format* format, media_source* _source, char* _name) = 0; virtual void Connect(status_t error, const media_source& source, const media_destination& destination, const media_format& format, char* ioName) = 0; virtual void Disconnect(const media_source& what, const media_destination& where) = 0; virtual void LateNoticeReceived(const media_source& what, bigtime_t howMuch, bigtime_t performanceTime) = 0; virtual void EnableOutput(const media_source& what, bool enabled, int32* _deprecated_) = 0; virtual status_t SetPlayRate(int32 numer, int32 denom); // NOTE: Call this from the thread that listens to the port! virtual status_t HandleMessage(int32 message, const void* data, size_t size); virtual void AdditionalBufferRequested( const media_source& source, media_buffer_id previousBuffer, bigtime_t previousTime, const media_seek_tag* previousTag /* = NULL */); virtual void LatencyChanged(const media_source& source, const media_destination& destination, bigtime_t newLatency, uint32 flags); // NOTE: Use this function to pass on the buffer on to the BBufferConsumer. status_t SendBuffer(BBuffer* buffer, const media_destination& destination); status_t SendDataStatus(int32 status, const media_destination& destination, bigtime_t atTime); // Check in advance if a target is prepared to accept a format. You may // want to call this from Connect(), although that's not required. status_t ProposeFormatChange(media_format* format, const media_destination& forDestination); // Tell consumer to accept a proposed format change // NOTE: You must not call SendBuffer while this call is pending! status_t ChangeFormat(const media_source& forSource, const media_destination& forDestination, media_format* format); // Check how much latency the down-stream graph introduces. status_t FindLatencyFor( const media_destination& forDestination, bigtime_t* _latency, media_node_id* _timesource); // Find the tag of a previously seen buffer to expedite seeking status_t FindSeekTag( const media_destination& forDestination, bigtime_t inTargetTime, media_seek_tag* _tag, bigtime_t* _taggedTime, uint32* _flags = 0, uint32 flags = 0); // Set the initial latency, which is the maximum additional latency // that will be imposed while starting/syncing to a signal (such as // starting a TV capture card in the middle of a field). Most nodes // have this at 0 (the default); only TV input Nodes need it currently // because they slave to a low-resolution (59.94 Hz) clock that arrives // from the outside world. Call this from the constructor if you need it. void SetInitialLatency(bigtime_t inInitialLatency, uint32 flags = 0); // TODO: Needs a Perform() virtual method! private: // FBC padding and forbidden methods BBufferProducer(); BBufferProducer(const BBufferProducer& other); BBufferProducer& operator=(const BBufferProducer& other); status_t _Reserved_BufferProducer_0(void*); // was AdditionalBufferRequested() status_t _Reserved_BufferProducer_1(void*); // was LatencyChanged() virtual status_t _Reserved_BufferProducer_2(void*); virtual status_t _Reserved_BufferProducer_3(void*); virtual status_t _Reserved_BufferProducer_4(void*); virtual status_t _Reserved_BufferProducer_5(void*); virtual status_t _Reserved_BufferProducer_6(void*); virtual status_t _Reserved_BufferProducer_7(void*); virtual status_t _Reserved_BufferProducer_8(void*); virtual status_t _Reserved_BufferProducer_9(void*); virtual status_t _Reserved_BufferProducer_10(void*); virtual status_t _Reserved_BufferProducer_11(void*); virtual status_t _Reserved_BufferProducer_12(void*); virtual status_t _Reserved_BufferProducer_13(void*); virtual status_t _Reserved_BufferProducer_14(void*); virtual status_t _Reserved_BufferProducer_15(void*); private: friend class BBufferConsumer; friend class BMediaNode; friend class BMediaRoster; friend class BPrivate::media::BMediaRosterEx; static status_t clip_shorts_to_region(const int16* data, int count, BRegion* output); static status_t clip_region_to_shorts(const BRegion* input, int16* data, int maxCount, int* _count); private: media_type fProducerType; bigtime_t fInitialLatency; uint32 fInitialFlags; bigtime_t fDelay; uint32 _reserved_buffer_producer_[12]; }; #endif // _BUFFER_PRODUCER_H