diff --git a/headers/private/media/MediaMisc.h b/headers/private/media/MediaMisc.h index 67af41014f..4f726289cb 100644 --- a/headers/private/media/MediaMisc.h +++ b/headers/private/media/MediaMisc.h @@ -20,17 +20,12 @@ #define BAD_MEDIA_SERVER_PORT -222 #define BAD_MEDIA_ADDON_SERVER_PORT -444 -#define SHADOW_TIMESOURCE_CONTROL_PORT -333 -#define IS_SHADOW_TIMESOURCE(_node) ((_node).node > 0 && (_node).port == SHADOW_TIMESOURCE_CONTROL_PORT) - -#define SYSTEM_TIMESOURCE_CONTROL_PORT -666 -#define IS_SYSTEM_TIMESOURCE(_node) ((_node).node > 0 && (_node).port == SYSTEM_TIMESOURCE_CONTROL_PORT) +#define IS_SYSTEM_TIMESOURCE(_node) ((_node).node == NODE_SYSTEM_TIMESOURCE_ID) #define NODE_KIND_USER_MASK 0x00000000FFFFFFFFULL #define NODE_KIND_COMPARE_MASK 0x000000007FFFFFFFULL #define NODE_KIND_NO_REFCOUNTING 0x0000000080000000ULL #define NODE_KIND_SHADOW_TIMESOURCE 0x0000000100000000ULL -#define NODE_KIND_SYSTEM_TIMESOURCE 0x0000000200000000ULL #define ROUND_UP_TO_PAGE(size) (((size) + B_PAGE_SIZE - 1) & ~(B_PAGE_SIZE - 1)) diff --git a/src/kits/media/MediaNode.cpp b/src/kits/media/MediaNode.cpp index c6b1a0367b..ef0860606b 100644 --- a/src/kits/media/MediaNode.cpp +++ b/src/kits/media/MediaNode.cpp @@ -144,6 +144,8 @@ BMediaNode::~BMediaNode() if (fControlPort > 0) delete_port(fControlPort); + } else { + TRACE("BMediaNode::~BMediaNode: shadow timesource, not unregistering\n"); } } @@ -238,11 +240,11 @@ BMediaNode::TimeSource() const // can use GetSystemTimeSource BMediaNode *self = const_cast(this); - if (fTimeSourceID == NODE_SYSTEM_TIMESOURCE_ID) { - self->fTimeSource = _TimeSourceObjectManager->GetSystemTimeSource(); - } else { +// if (fTimeSourceID == NODE_SYSTEM_TIMESOURCE_ID) { +// self->fTimeSource = _TimeSourceObjectManager->GetSystemTimeSource(); +// } else { self->fTimeSource = MediaRosterEx(BMediaRoster::Roster())->MakeTimeSourceObject(fTimeSourceID); - } +// } ASSERT(fTimeSource == self->fTimeSource); if (fTimeSource == 0) { diff --git a/src/kits/media/MediaRoster.cpp b/src/kits/media/MediaRoster.cpp index 5cf4856569..4439863145 100644 --- a/src/kits/media/MediaRoster.cpp +++ b/src/kits/media/MediaRoster.cpp @@ -637,7 +637,7 @@ BMediaRoster::MakeTimeSourceFor(const media_node & for_node) CALLED(); - if ((for_node.node == NODE_SYSTEM_TIMESOURCE_ID) && (for_node.kind & B_TIME_SOURCE)) { + if (IS_SYSTEM_TIMESOURCE(for_node)) { // special handling for the system time source TRACE("BMediaRoster::MakeTimeSourceFor, asked for system time source\n"); return MediaRosterEx(this)->MakeTimeSourceObject(NODE_SYSTEM_TIMESOURCE_ID); @@ -655,6 +655,7 @@ BMediaRoster::MakeTimeSourceFor(const media_node & for_node) BTimeSource *source; status_t rv; + // ask the node to get it's current timesource id rv = QueryPort(for_node.port, NODE_GET_TIMESOURCE, &request, sizeof(request), &reply, sizeof(reply)); if (rv != B_OK) { ERROR("BMediaRoster::MakeTimeSourceFor: request failed\n"); @@ -687,7 +688,8 @@ BMediaRosterEx::MakeTimeSourceObject(media_node_id timesource_id) return NULL; } - //ReleaseNode(clone); + // XXX release? + ReleaseNode(clone); return source; } @@ -999,11 +1001,11 @@ BMediaRoster::StartTimeSource(const media_node & node, //ERROR("BMediaRoster::StartTimeSource node %ld is system timesource\n", node.node); return B_OK; } - if (IS_SHADOW_TIMESOURCE(node)) { - // XXX debug this - ERROR("BMediaRoster::StartTimeSource node %ld is shadow timesource\n", node.node); - return B_OK; - } +// if (IS_SHADOW_TIMESOURCE(node)) { +// // XXX debug this +// ERROR("BMediaRoster::StartTimeSource node %ld is shadow timesource\n", node.node); +// return B_OK; +// } if (IS_INVALID_NODE(node)) { ERROR("BMediaRoster::StartTimeSource node %ld invalid\n", node.node); return B_MEDIA_BAD_NODE; @@ -1034,11 +1036,11 @@ BMediaRoster::StopTimeSource(const media_node & node, //ERROR("BMediaRoster::StopTimeSource node %ld is system timesource\n", node.node); return B_OK; } - if (IS_SHADOW_TIMESOURCE(node)) { - // XXX debug this - ERROR("BMediaRoster::StopTimeSource node %ld is shadow timesource\n", node.node); - return B_OK; - } +// if (IS_SHADOW_TIMESOURCE(node)) { +// // XXX debug this +// ERROR("BMediaRoster::StopTimeSource node %ld is shadow timesource\n", node.node); +// return B_OK; +// } if (IS_INVALID_NODE(node)) { ERROR("BMediaRoster::StopTimeSource node %ld invalid\n", node.node); return B_MEDIA_BAD_NODE; @@ -1071,11 +1073,11 @@ BMediaRoster::SeekTimeSource(const media_node & node, // returning B_ERROR would break StampTV return B_OK; } - if (IS_SHADOW_TIMESOURCE(node)) { - // XXX debug this - ERROR("BMediaRoster::SeekTimeSource node %ld is shadow timesource\n", node.node); - return B_OK; - } +// if (IS_SHADOW_TIMESOURCE(node)) { +// // XXX debug this +// ERROR("BMediaRoster::SeekTimeSource node %ld is shadow timesource\n", node.node); +// return B_OK; +// } if (IS_INVALID_NODE(node)) { ERROR("BMediaRoster::SeekTimeSource node %ld invalid\n", node.node); return B_MEDIA_BAD_NODE; diff --git a/src/kits/media/SoundPlayNode.cpp b/src/kits/media/SoundPlayNode.cpp index 46c32f2974..16cb52b8b4 100644 --- a/src/kits/media/SoundPlayNode.cpp +++ b/src/kits/media/SoundPlayNode.cpp @@ -127,7 +127,7 @@ void _SoundPlayNode::NodeRegistered(void) mOutput.source.port = ControlPort(); mOutput.source.id = 1; mOutput.node = Node(); - sprintf(mOutput.name, "output %ld", mOutput.source.id); + strcpy(mOutput.name, Name()); Run(); } @@ -326,7 +326,7 @@ _SoundPlayNode::PrepareToConnect(const media_source& what, const media_destinati mOutput.destination = where; mOutput.format = *format; *out_source = mOutput.source; - strncpy(out_name, mOutput.name, B_MEDIA_NAME_LENGTH); + strcpy(out_name, Name()); return B_OK; } @@ -356,8 +356,7 @@ _SoundPlayNode::Connect(status_t error, const media_source& source, const media_ // that we agreed on, and report our connection name again. mOutput.destination = destination; mOutput.format = format; - strncpy(io_name, mOutput.name, B_MEDIA_NAME_LENGTH); - io_name[B_MEDIA_NAME_LENGTH -1] = 0; + strcpy(io_name, Name()); // Now that we're connected, we can determine our downstream latency. // Do so, then make sure we get our events early enough. diff --git a/src/kits/media/TimeSourceObject.cpp b/src/kits/media/TimeSourceObject.cpp index 3501157902..352a9b2cf3 100644 --- a/src/kits/media/TimeSourceObject.cpp +++ b/src/kits/media/TimeSourceObject.cpp @@ -21,13 +21,17 @@ TimeSourceObject::TimeSourceObject(const media_node &node) TRACE("TimeSourceObject::TimeSourceObject enter, id = %ld\n", node.node); if (fControlPort > 0) delete_port(fControlPort); + + // we use the control port of the real time source object. + // this way, all messages are send to the real time source, + // and this shadow object won't receive any. fControlPort = node.port; ASSERT(fNodeID == node.node); ASSERT(fKinds == node.kind); - if (node.node == NODE_SYSTEM_TIMESOURCE_ID) { strcpy(fName, "System Clock"); + fIsRealtime = true; } else { live_node_info lni; if (B_OK == BMediaRoster::Roster()->GetLiveNodeInfo(node, &lni)) { @@ -39,7 +43,6 @@ TimeSourceObject::TimeSourceObject(const media_node &node) AddNodeKind(NODE_KIND_SHADOW_TIMESOURCE); AddNodeKind(NODE_KIND_NO_REFCOUNTING); - fControlPort = SHADOW_TIMESOURCE_CONTROL_PORT; // XXX if we don't do this, we get a infinite loop somewhere. This needs to be debugged TRACE("TimeSourceObject::TimeSourceObject leave, node id %ld\n", fNodeID); } @@ -49,6 +52,7 @@ TimeSourceObject::TimeSourceOp( const time_source_op_info & op, void * _reserved) { + // we don't get anything here return B_OK; } @@ -64,27 +68,14 @@ TimeSourceObject::AddOn(int32 *internal_id) const TimeSourceObject::DeleteHook(BMediaNode *node) { status_t status; -// printf("TimeSourceObject::DeleteHook enter\n"); +// if (fIsRealtime) { +// ERROR("TimeSourceObject::DeleteHook: system time source clone delete hook called\n"); +// return B_ERROR; +// } + printf("TimeSourceObject::DeleteHook enter\n"); _TimeSourceObjectManager->ObjectDeleted(this); status = BTimeSource::DeleteHook(node); -// printf("TimeSourceObject::DeleteHook leave\n"); + printf("TimeSourceObject::DeleteHook leave\n"); return status; } -SystemTimeSourceObject::SystemTimeSourceObject(const media_node &node) - : BMediaNode("System Clock", node.node, node.kind), - TimeSourceObject(node) -{ -// printf("SystemTimeSourceObject::SystemTimeSourceObject enter, id = %ld\n", id); - fIsRealtime = true; - AddNodeKind(NODE_KIND_SYSTEM_TIMESOURCE); - AddNodeKind(NODE_KIND_NO_REFCOUNTING); -// printf("SystemTimeSourceObject::SystemTimeSourceObject leave, node id %ld\n", ID()); -} - -/* virtual */ status_t -SystemTimeSourceObject::DeleteHook(BMediaNode * node) -{ - ERROR("SystemTimeSourceObject::DeleteHook called\n"); - return B_ERROR; -} diff --git a/src/kits/media/TimeSourceObject.h b/src/kits/media/TimeSourceObject.h index 2407950ef9..2ad21f41fd 100644 --- a/src/kits/media/TimeSourceObject.h +++ b/src/kits/media/TimeSourceObject.h @@ -31,17 +31,6 @@ protected: virtual status_t DeleteHook(BMediaNode * node); }; -class SystemTimeSourceObject : public TimeSourceObject -{ -public: - SystemTimeSourceObject(const media_node &node); - -protected: - // override from BMediaNode - virtual status_t DeleteHook(BMediaNode * node); - -}; - } } using namespace BPrivate::media; #endif diff --git a/src/kits/media/TimeSourceObjectManager.cpp b/src/kits/media/TimeSourceObjectManager.cpp index f8ec6c12df..1582172f6f 100644 --- a/src/kits/media/TimeSourceObjectManager.cpp +++ b/src/kits/media/TimeSourceObjectManager.cpp @@ -24,11 +24,11 @@ namespace BPrivate { namespace media { TimeSourceObjectManager::TimeSourceObjectManager() - : fSystemTimeSource(0) +// : fSystemTimeSource(0) { CALLED(); fLock = new BLocker("timesource object manager locker"); - fMap = new Map; + fMap = new Map; } @@ -50,40 +50,6 @@ TimeSourceObjectManager::~TimeSourceObjectManager() delete fMap; } -void -TimeSourceObjectManager::InitSystemTimeSource() -{ - CALLED(); - BAutolock lock(fLock); - - if (fSystemTimeSource != 0) - return; - - TRACE("TimeSourceObjectManager::InitSystemTimeSource enter\n"); - - media_node node; - node.node = NODE_SYSTEM_TIMESOURCE_ID; - node.port = SYSTEM_TIMESOURCE_CONTROL_PORT; - node.kind = B_TIME_SOURCE; - - fSystemTimeSource = new SystemTimeSourceObject(node); - - TRACE("TimeSourceObjectManager::InitSystemTimeSource leave\n"); -} - - -BTimeSource * -TimeSourceObjectManager::GetSystemTimeSource() -{ - CALLED(); - BAutolock lock(fLock); - - if (fSystemTimeSource == 0) - InitSystemTimeSource(); - - return dynamic_cast(fSystemTimeSource->Acquire()); -} - /* BMediaRoster::MakeTimeSourceFor does use this function to request * a time source object. If it is already in memory, it will be * Acquired(), if not, a new TimeSourceObject will be created. @@ -95,32 +61,11 @@ TimeSourceObjectManager::GetTimeSource(const media_node &node) BAutolock lock(fLock); // printf("TimeSourceObjectManager::GetTimeSource, node id %ld\n", node.node); - - if (fSystemTimeSource == 0) - InitSystemTimeSource(); - - if (NODE_SYSTEM_TIMESOURCE_ID == node.node) - return dynamic_cast(fSystemTimeSource->Acquire()); - + BTimeSource **pts; if (fMap->Get(node.node, &pts)) return dynamic_cast((*pts)->Acquire()); -/* - media_node clone; - status_t rv; - - rv = BMediaRoster::Roster()->GetNodeFor(node.node, &clone); - if (rv != B_OK) { - ERROR("TimeSourceObjectManager::GetTimeSource, GetNodeFor %ld failed\n", node.node); - return NULL; - } - - BTimeSource *ts; - ts = new TimeSourceObject(clone); - fMap->Insert(clone.node, ts); - return ts; -*/ // time sources are not accounted in node reference counting BTimeSource *ts; ts = new TimeSourceObject(node); diff --git a/src/kits/media/TimeSourceObjectManager.h b/src/kits/media/TimeSourceObjectManager.h index b7a51ad579..6d73d28bff 100644 --- a/src/kits/media/TimeSourceObjectManager.h +++ b/src/kits/media/TimeSourceObjectManager.h @@ -18,16 +18,11 @@ public: ~TimeSourceObjectManager(); BTimeSource *GetTimeSource(const media_node &node); - BTimeSource *GetSystemTimeSource(); void ObjectDeleted(BTimeSource *timesource); -private: - void InitSystemTimeSource(); - private: Map *fMap; BLocker *fLock; - BTimeSource *fSystemTimeSource; }; }; // namespace media diff --git a/src/servers/media/NodeManager.cpp b/src/servers/media/NodeManager.cpp index 7cc47ca535..2380060e14 100644 --- a/src/servers/media/NodeManager.cpp +++ b/src/servers/media/NodeManager.cpp @@ -405,7 +405,7 @@ NodeManager::GetDormantNodeInfo(dormant_node_info *node_info, const media_node & registered_node *rn; for (fRegisteredNodeMap->Rewind(); fRegisteredNodeMap->GetNext(&rn); ) { if (rn->nodeid == node.node) { - if (rn->addon_id == -1) { // This function must return an error if the node is application owned + if (rn->addon_id == -1 && node.node != NODE_SYSTEM_TIMESOURCE_ID) { // This function must return an error if the node is application owned TRACE("NodeManager::GetDormantNodeInfo NODE IS APPLICATION OWNED! node %ld, addon_id %ld, addon_flavor_id %ld, name \"%s\"\n", node.node, rn->addon_id, rn->addon_flavor_id, rn->name); return B_ERROR; } diff --git a/src/servers/media/media_server.cpp b/src/servers/media/media_server.cpp index 33f285904b..ee37b87cf6 100644 --- a/src/servers/media/media_server.cpp +++ b/src/servers/media/media_server.cpp @@ -76,7 +76,7 @@ public: void HandleMessage(int32 code, void *data, size_t size); void ArgvReceived(int32 argc, char **argv); static int32 controlthread(void *arg); - void StartSystemTimeSource(); +// void StartSystemTimeSource(); /* functionality not yet implemented 00014a00 T _ServerApp::_ServerApp(void) @@ -123,7 +123,7 @@ ServerApp::ServerApp() control_thread = spawn_thread(controlthread, "media_server control", 105, this); resume_thread(control_thread); - StartSystemTimeSource(); +// StartSystemTimeSource(); gNodeManager->LoadState(); gAppManager->StartAddonServer(); } @@ -171,6 +171,7 @@ ServerApp::QuitRequested() return true; } +/* void ServerApp::StartSystemTimeSource() { @@ -193,6 +194,7 @@ ServerApp::StartSystemTimeSource() TRACE("StartSystemTimeSource leave\n"); } +*/ void ServerApp::HandleMessage(int32 code, void *data, size_t size) diff --git a/src/servers/media_addon/Jamfile b/src/servers/media_addon/Jamfile index 151d10eaac..51533043ed 100644 --- a/src/servers/media_addon/Jamfile +++ b/src/servers/media_addon/Jamfile @@ -8,5 +8,6 @@ SubDirHdrs [ FDirName $(OBOS_TOP) src servers media ] ; Server media_addon_server : main.cpp + SystemTimeSource.cpp ; LinkSharedOSLibs media_addon_server : be libmedia.so root ; diff --git a/src/servers/media_addon/SystemTimeSource.cpp b/src/servers/media_addon/SystemTimeSource.cpp new file mode 100644 index 0000000000..b4cdea42a6 --- /dev/null +++ b/src/servers/media_addon/SystemTimeSource.cpp @@ -0,0 +1,66 @@ + +#include "debug.h" +#include "SystemTimeSource.h" + + +SystemTimeSource::SystemTimeSource() + : BMediaNode("System Clock"), + BTimeSource(), + fControlThread(-1) +{ + TRACE("SystemTimeSource::SystemTimeSource\n"); +} + +SystemTimeSource::~SystemTimeSource() +{ + TRACE("SystemTimeSource::~SystemTimeSource enter\n"); + + close_port(ControlPort()); + if (fControlThread != -1) { + status_t err; + wait_for_thread(fControlThread, &err); + } + TRACE("SystemTimeSource::~SystemTimeSource exit\n"); +} + +BMediaAddOn* +SystemTimeSource::AddOn(int32 * internal_id) const +{ + return NULL; +} + +status_t +SystemTimeSource::TimeSourceOp(const time_source_op_info & op, void * _reserved) +{ + TRACE("######## SystemTimeSource::TimeSourceOp\n"); + bigtime_t real = RealTime(); + PublishTime(real, real, 1.0); + return B_OK; +} + + +/* virtual */ void +SystemTimeSource::NodeRegistered() +{ + ASSERT(fControlThread == -1); + fControlThread = spawn_thread(_ControlThreadStart, "System Clock control", 12, this); + resume_thread(fControlThread); +} + +int32 +SystemTimeSource::_ControlThreadStart(void *arg) +{ + reinterpret_cast(arg)->ControlThread(); + return 0; +} + +void +SystemTimeSource::ControlThread() +{ + TRACE("SystemTimeSource::ControlThread() enter\n"); + status_t err; + do { + err = WaitForMessage(B_INFINITE_TIMEOUT); + } while (err == B_OK || err == B_ERROR); + TRACE("SystemTimeSource::ControlThread() exit\n"); +} diff --git a/src/servers/media_addon/SystemTimeSource.h b/src/servers/media_addon/SystemTimeSource.h new file mode 100644 index 0000000000..39c289e61d --- /dev/null +++ b/src/servers/media_addon/SystemTimeSource.h @@ -0,0 +1,20 @@ + +#include + +class SystemTimeSource : public BTimeSource +{ +public: + SystemTimeSource(); + ~SystemTimeSource(); + + void NodeRegistered(); + + BMediaAddOn* AddOn(int32 * internal_id) const; + status_t TimeSourceOp(const time_source_op_info & op, void * _reserved); + + + static int32 _ControlThreadStart(void *arg); + void ControlThread(); + + thread_id fControlThread; +}; diff --git a/src/servers/media_addon/main.cpp b/src/servers/media_addon/main.cpp index a6d82e82de..597073a6d2 100644 --- a/src/servers/media_addon/main.cpp +++ b/src/servers/media_addon/main.cpp @@ -50,6 +50,7 @@ char __dont_remove_copyright_from_binary[] = "Copyright (c) 2002, 2003 Marcus Ov #include "Notifications.h" #include "MediaMisc.h" #include "MediaRosterEx.h" +#include "SystemTimeSource.h" //#define USER_ADDON_PATH "../add-ons/media" @@ -121,6 +122,9 @@ MediaAddonServer::~MediaAddonServer() for (filemap->Rewind(); filemap->GetNext(&id); ) _DormantNodeManager->UnregisterAddon(*id); + + // XXX unregister system time source + delete filemap; delete infomap; } @@ -193,6 +197,19 @@ MediaAddonServer::ReadyToRun() } ASSERT(fStartup == true); + + // The very first thing to do is to create the system time source, + // register it with the server, and make it the default SYSTEM_TIME_SOURCE + BMediaNode *ts = new SystemTimeSource; + result = mediaroster->RegisterNode(ts); + if (result != B_OK) + debugger("Can't register system time source"); + if (ts->ID() != NODE_SYSTEM_TIMESOURCE_ID) + debugger("System time source got wrong node ID"); + media_node node = ts->Node(); + result = MediaRosterEx(mediaroster)->SetNode(SYSTEM_TIME_SOURCE, &node); + if (result != B_OK) + debugger("Can't setup system time source as default"); // During startup, first all add-ons are loaded, then all // nodes (flavors) representing physical inputs and outputs