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:
Dario Casalinuovo
2016-11-29 01:22:35 +01:00
parent 8ab68339fb
commit ecb395852e
10 changed files with 548 additions and 277 deletions
+22 -37
View File
@@ -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;
-8
View File
@@ -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;
};
+8 -51
View File
@@ -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;
+178
View File
@@ -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