Introduce BSimpleMediaClient
* The idea is to move the callback based mechanism into a derived class. The objects can be composed to create working systems. * The BMediaClient class supply RegisterInput/RegisterOutput and BeginInput/BeginOutput is moved to BSimpleMediaClient. * Various minor fixes.
This commit is contained in:
@@ -32,24 +32,6 @@ class BMediaOutput;
|
||||
// performance_time.
|
||||
class BMediaClient {
|
||||
public:
|
||||
enum notification {
|
||||
B_WILL_START = 1, // performance_time
|
||||
B_WILL_STOP, // performance_time immediate
|
||||
B_WILL_SEEK, // performance_time media_time
|
||||
B_WILL_TIMEWARP, // real_time performance_time
|
||||
|
||||
B_FORMAT_SUGGESTION, // media_type type, int32 quality,
|
||||
// media_format* format
|
||||
};
|
||||
|
||||
typedef void (*notify_hook)(void* cookie,
|
||||
notification what,
|
||||
...);
|
||||
|
||||
// TODO: Should allow BControllable capabilities
|
||||
// TODO: Add file interface
|
||||
// TODO: Offline mode is still missing
|
||||
|
||||
BMediaClient(const char* name,
|
||||
media_type type
|
||||
= B_MEDIA_UNKNOWN_TYPE,
|
||||
@@ -67,19 +49,17 @@ public:
|
||||
|
||||
status_t InitCheck() const;
|
||||
|
||||
// TODO: Should allow BControllable capabilities
|
||||
// TODO: Add file interface
|
||||
// TODO: Offline mode is still missing
|
||||
|
||||
// To connect pass the BMediaConnection to this class or to another BMediaClient,
|
||||
// also in another team the connection object will be valid.
|
||||
// When those functions return, the BMediaConnection is added to the
|
||||
// list and is visible to other nodes as not connected.
|
||||
|
||||
// This is supplied to support generic connections not related
|
||||
// to a certain destination or source node, however for various ambiguity
|
||||
// reasons we want the BMediaConnection to be declared as input or output.
|
||||
// You can pass the object returned by this function to another
|
||||
// BMediaClient::BeginConnection() and then Connect(), so that it
|
||||
// will automatically connect to this node.
|
||||
virtual BMediaInput* BeginInput();
|
||||
virtual BMediaOutput* BeginOutput();
|
||||
virtual status_t RegisterInput(BMediaInput* input);
|
||||
virtual status_t RegisterOutput(BMediaOutput* output);
|
||||
|
||||
// Bind internally two connections of the same BMediaClient, so that the
|
||||
// input will be automatically forwarded to the output just after the
|
||||
@@ -126,8 +106,8 @@ public:
|
||||
|
||||
bool IsRunning() const;
|
||||
|
||||
virtual status_t Start(bool force = false);
|
||||
virtual status_t Stop(bool force = false);
|
||||
status_t Start(bool force = false);
|
||||
status_t Stop(bool force = false);
|
||||
status_t Seek(bigtime_t mediaTime,
|
||||
bigtime_t performanceTime);
|
||||
status_t Roll(bigtime_t start, bigtime_t stop,
|
||||
@@ -162,9 +142,6 @@ public:
|
||||
// Default version just return NULL.
|
||||
virtual BMediaAddOn* AddOn(int32* id) const;
|
||||
|
||||
void SetNotificationHook(notify_hook notifyHook = NULL,
|
||||
void* cookie = NULL);
|
||||
|
||||
protected:
|
||||
// This is used when the user want to override the BeginConnection
|
||||
// mechanism, for example to supply your BMediaConnection derived
|
||||
@@ -172,9 +149,21 @@ protected:
|
||||
virtual void AddInput(BMediaInput* input);
|
||||
virtual void AddOutput(BMediaOutput* output);
|
||||
|
||||
virtual void HandleStart(bigtime_t performanceTime);
|
||||
virtual void HandleStop(bigtime_t performanceTime);
|
||||
|
||||
virtual void HandleSeek(bigtime_t mediaTime,
|
||||
bigtime_t performanceTime);
|
||||
|
||||
virtual void HandleTimeWarp(bigtime_t realTime,
|
||||
bigtime_t performanceTime);
|
||||
|
||||
virtual status_t HandleFormatSuggestion(media_type type,
|
||||
int32 quality, media_format* format);
|
||||
|
||||
// Called from BMediaConnection
|
||||
status_t DisconnectConnection(BMediaConnection* conn);
|
||||
status_t ReleaseConnection(BMediaConnection* conn);
|
||||
status_t ConnectionDisconnected(BMediaConnection* conn);
|
||||
status_t ConnectionReleased(BMediaConnection* conn);
|
||||
|
||||
private:
|
||||
BMediaInput* FindInput(
|
||||
@@ -202,10 +191,6 @@ private:
|
||||
bigtime_t fMinLatency;
|
||||
bigtime_t fMaxLatency;
|
||||
|
||||
notify_hook fNotifyHook;
|
||||
|
||||
void* fNotifyCookie;
|
||||
|
||||
BObjectList<BMediaInput> fInputs;
|
||||
BObjectList<BMediaOutput> fOutputs;
|
||||
|
||||
|
||||
@@ -132,14 +132,6 @@ private:
|
||||
void _ProduceNewBuffer(const media_timed_event* event,
|
||||
bigtime_t late);
|
||||
|
||||
void _HandleStart(bigtime_t performanceTime);
|
||||
void _HandleStop(bigtime_t performanceTime,
|
||||
bool immediate);
|
||||
void _HandleSeek(bigtime_t mediaTime,
|
||||
bigtime_t performanceTime);
|
||||
void _HandleTimeWarp(bigtime_t realTime,
|
||||
bigtime_t performanceTime);
|
||||
|
||||
BMediaClient* fOwner;
|
||||
};
|
||||
|
||||
|
||||
@@ -30,42 +30,14 @@ namespace BPrivate { namespace media {
|
||||
// recycle the buffer when you don't want to do anything further.
|
||||
class BMediaConnection {
|
||||
public:
|
||||
enum notification {
|
||||
B_CONNECTED = 1,
|
||||
B_DISCONNECTED,
|
||||
|
||||
B_PREPARE_TO_CONNECT, // media_format* format, media_source* source,
|
||||
// char* name
|
||||
B_CONNECT,
|
||||
B_DISCONNECT,
|
||||
|
||||
B_FORMAT_PROPOSAL, // media_format* format
|
||||
|
||||
B_ASK_FORMAT_CHANGE,
|
||||
B_FORMAT_CHANGED
|
||||
};
|
||||
|
||||
|
||||
// This function is called when it is the moment to handle a buffer.
|
||||
typedef void (*process_hook)(BMediaConnection* connection,
|
||||
BBuffer* buffer);
|
||||
|
||||
// Used to notify or inquire the client about what to do when certain
|
||||
// events happen.
|
||||
typedef status_t (*notify_hook)(notification what,
|
||||
BMediaConnection* connection,
|
||||
...);
|
||||
|
||||
virtual ~BMediaConnection();
|
||||
|
||||
const media_connection& Connection() const;
|
||||
media_connection_id Id() const;
|
||||
const char* Name() const;
|
||||
|
||||
// TODO: while most of the objects for both kinds are common
|
||||
// it would be worthwile to have a private implementation
|
||||
// so that we can better model the differences and avoid
|
||||
// problems.
|
||||
BMediaClient* MediaClient() const;
|
||||
|
||||
bool IsInput() const;
|
||||
bool IsOutput() const;
|
||||
|
||||
@@ -88,9 +60,6 @@ public:
|
||||
|
||||
bool IsConnected() const;
|
||||
|
||||
void SetCookie(void* cookie);
|
||||
void* Cookie() const;
|
||||
|
||||
// Disconnect this connection. When a connection is disconnected,
|
||||
// it can be reused as brand new.
|
||||
status_t Disconnect();
|
||||
@@ -101,26 +70,20 @@ public:
|
||||
// want to preserve it for future connections just Disconnect() it.
|
||||
status_t Release();
|
||||
|
||||
// Use this to set your callbacks.
|
||||
void SetHooks(process_hook processHook = NULL,
|
||||
notify_hook notifyHook = NULL,
|
||||
void* cookie = NULL);
|
||||
|
||||
protected:
|
||||
BMediaConnection(BMediaClient* owner,
|
||||
media_connection_kind kind,
|
||||
media_connection_id id);
|
||||
BMediaConnection(media_connection_kind kind);
|
||||
|
||||
// Those callbacks are shared between BMediaInput and BMediaOutput
|
||||
virtual void Connected(const media_format& format);
|
||||
virtual void Disconnected();
|
||||
|
||||
private:
|
||||
void ConnectionRegistered(BMediaClient* owner,
|
||||
media_connection_id id);
|
||||
|
||||
const media_source& Source() const;
|
||||
const media_destination& Destination() const;
|
||||
|
||||
void _Init();
|
||||
|
||||
media_connection fConnection;
|
||||
|
||||
BMediaClient* fOwner;
|
||||
@@ -130,10 +93,6 @@ private:
|
||||
// see BMediaClient::Bind.
|
||||
BMediaConnection* fBind;
|
||||
|
||||
process_hook fProcessHook;
|
||||
notify_hook fNotifyHook;
|
||||
void* fBufferCookie;
|
||||
|
||||
size_t fBufferSize;
|
||||
bigtime_t fBufferDuration;
|
||||
|
||||
@@ -164,8 +123,7 @@ private:
|
||||
|
||||
class BMediaInput : public BMediaConnection {
|
||||
public:
|
||||
BMediaInput(BMediaClient* owner,
|
||||
media_connection_id id);
|
||||
BMediaInput();
|
||||
|
||||
protected:
|
||||
// Callbacks
|
||||
@@ -195,8 +153,7 @@ private:
|
||||
|
||||
class BMediaOutput : public BMediaConnection {
|
||||
public:
|
||||
BMediaOutput(BMediaClient* owner,
|
||||
media_connection_id id);
|
||||
BMediaOutput();
|
||||
|
||||
void SetOutputEnabled(bool enabled);
|
||||
bool IsOutputEnabled() const;
|
||||
|
||||
Executable
+178
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
* Copyright 2015, Haiku, Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#ifndef _MEDIA_SIMPLE_CLIENT_H
|
||||
#define _MEDIA_SIMPLE_CLIENT_H
|
||||
|
||||
#include <MediaClient.h>
|
||||
#include <MediaConnection.h>
|
||||
|
||||
|
||||
namespace BPrivate { namespace media {
|
||||
|
||||
|
||||
class BSimpleMediaInput;
|
||||
class BSimpleMediaOutput;
|
||||
|
||||
class BSimpleMediaClient : public BMediaClient {
|
||||
public:
|
||||
enum notification {
|
||||
B_WILL_START = 1, // performance_time
|
||||
B_WILL_STOP, // performance_time immediate
|
||||
B_WILL_SEEK, // performance_time media_time
|
||||
B_WILL_TIMEWARP, // real_time performance_time
|
||||
|
||||
B_FORMAT_SUGGESTION, // media_type type, int32 quality,
|
||||
// media_format* format
|
||||
};
|
||||
|
||||
typedef void (*notify_hook)(void* cookie,
|
||||
notification what,
|
||||
...);
|
||||
|
||||
BSimpleMediaClient(const char* name,
|
||||
media_type type
|
||||
= B_MEDIA_UNKNOWN_TYPE,
|
||||
media_client_kind
|
||||
kind = B_MEDIA_PLAYER
|
||||
& B_MEDIA_RECORDER);
|
||||
|
||||
virtual ~BSimpleMediaClient();
|
||||
|
||||
// This is supplied to support generic connections not related
|
||||
// to a certain destination or source node, however for various ambiguity
|
||||
// reasons we want the BMediaConnection to be declared as input or output.
|
||||
// You can pass the object returned by this function to another
|
||||
// BMediaClient::Connect(), so that it will automatically connect to this node.
|
||||
virtual BSimpleMediaInput* BeginInput();
|
||||
virtual BSimpleMediaOutput* BeginOutput();
|
||||
|
||||
void SetNotificationHook(notify_hook notifyHook = NULL,
|
||||
void* cookie = NULL);
|
||||
|
||||
protected:
|
||||
virtual void HandleStart(bigtime_t performanceTime);
|
||||
virtual void HandleStop(bigtime_t performanceTime);
|
||||
|
||||
virtual void HandleSeek(bigtime_t mediaTime,
|
||||
bigtime_t performanceTime);
|
||||
|
||||
virtual void HandleTimeWarp(bigtime_t realTime,
|
||||
bigtime_t performanceTime);
|
||||
|
||||
virtual status_t HandleFormatSuggestion(media_type type,
|
||||
int32 quality, media_format* format);
|
||||
|
||||
private:
|
||||
notify_hook fNotifyHook;
|
||||
void* fNotifyCookie;
|
||||
|
||||
virtual void _ReservedSimpleMediaClient0();
|
||||
virtual void _ReservedSimpleMediaClient1();
|
||||
virtual void _ReservedSimpleMediaClient2();
|
||||
virtual void _ReservedSimpleMediaClient3();
|
||||
virtual void _ReservedSimpleMediaClient4();
|
||||
virtual void _ReservedSimpleMediaClient5();
|
||||
uint32 fPadding[32];
|
||||
};
|
||||
|
||||
|
||||
class BSimpleMediaInput : public BMediaInput {
|
||||
public:
|
||||
enum notification {
|
||||
B_CONNECTED = 1,
|
||||
B_DISCONNECTED,
|
||||
|
||||
B_FORMAT_CHANGED
|
||||
};
|
||||
|
||||
// This function is called when it is the moment to handle a buffer.
|
||||
typedef void (*process_hook)(
|
||||
BMediaConnection* connection,
|
||||
BBuffer* buffer);
|
||||
|
||||
// Used to notify or inquire the client about what to do when certain
|
||||
// events happen.
|
||||
typedef status_t (*notify_hook)(
|
||||
notification what,
|
||||
BMediaConnection* connection,
|
||||
...);
|
||||
|
||||
BSimpleMediaInput();
|
||||
|
||||
// Use this to set your callbacks.
|
||||
void SetHooks(process_hook processHook = NULL,
|
||||
notify_hook notifyHook = NULL,
|
||||
void* cookie = NULL);
|
||||
|
||||
void* Cookie() const;
|
||||
|
||||
protected:
|
||||
virtual void Connected(const media_format& format);
|
||||
virtual void Disconnected();
|
||||
|
||||
void BufferReceived(BBuffer* buffer);
|
||||
|
||||
private:
|
||||
process_hook fProcessHook;
|
||||
notify_hook fNotifyHook;
|
||||
void* fBufferCookie;
|
||||
};
|
||||
|
||||
|
||||
class BSimpleMediaOutput : public BMediaOutput {
|
||||
public:
|
||||
enum notification {
|
||||
B_CONNECTED = 1,
|
||||
B_DISCONNECTED,
|
||||
|
||||
B_PREPARE_TO_CONNECT, // media_format* format, media_source* source,
|
||||
// char* name
|
||||
|
||||
B_FORMAT_PROPOSAL, // media_format* format
|
||||
B_ASK_FORMAT_CHANGE,
|
||||
};
|
||||
|
||||
// This function is called when it is the moment to handle a buffer.
|
||||
typedef void (*process_hook)(
|
||||
BMediaConnection* connection,
|
||||
BBuffer* buffer);
|
||||
|
||||
// Used to notify or inquire the client about what to do when certain
|
||||
// events happen.
|
||||
typedef status_t (*notify_hook)(
|
||||
notification what,
|
||||
BMediaConnection* connection,
|
||||
...);
|
||||
|
||||
BSimpleMediaOutput();
|
||||
|
||||
// Use this to set your callbacks.
|
||||
void SetHooks(process_hook processHook = NULL,
|
||||
notify_hook notifyHook = NULL,
|
||||
void* cookie = NULL);
|
||||
|
||||
void* Cookie() const;
|
||||
|
||||
protected:
|
||||
virtual void Connected(const media_format& format);
|
||||
virtual void Disconnected();
|
||||
|
||||
virtual status_t FormatProposal(media_format* format);
|
||||
|
||||
private:
|
||||
process_hook fProcessHook;
|
||||
notify_hook fNotifyHook;
|
||||
void* fBufferCookie;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
using namespace BPrivate::media;
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user