better time source support

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@2356 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
beveloper
2003-01-05 23:35:07 +00:00
parent 1ab4cb426e
commit 835140c89a
14 changed files with 226 additions and 122 deletions
+2 -1
View File
@@ -111,7 +111,7 @@ struct media_node_attribute
};
namespace BPrivate { namespace media { class TimeSourceObject; } }
namespace BPrivate { namespace media { class TimeSourceObject; class SystemTimeSourceObject; } }
class BMediaNode
@@ -256,6 +256,7 @@ private:
friend class MNodeManager;
friend class BBufferProducer; // for getting _mNodeID
friend class BPrivate::media::TimeSourceObject;
friend class BPrivate::media::SystemTimeSourceObject;
// Deprecated in 4.1
int32 IncrementChangeTag();
+3
View File
@@ -18,6 +18,7 @@
class _BSlaveNodeStorageP;
struct _time_transmit_buf;
namespace BPrivate { namespace media { class TimeSourceObject; class SystemTimeSourceObject; } }
class BTimeSource :
@@ -100,6 +101,8 @@ private:
friend class BMediaNode;
friend class BMediaRoster;
friend class _ServerApp;
friend class BPrivate::media::TimeSourceObject;
friend class BPrivate::media::SystemTimeSourceObject;
BTimeSource( /* private unimplemented */
const BTimeSource & clone);
-1
View File
@@ -47,7 +47,6 @@ SharedLibrary media :
DormantNodeManager.cpp
Notifications.cpp
PortPool.cpp
SystemTimeSource.cpp
SharedBufferList.cpp
TrackReader.cpp
TimedEventQueuePrivate.cpp
+5 -4
View File
@@ -13,7 +13,6 @@
#include <string.h>
#include "debug.h"
#include "DataExchange.h"
#include "SystemTimeSource.h"
#include "ServerInterface.h"
#include "Notifications.h"
@@ -101,10 +100,12 @@ BMediaNode::~BMediaNode()
// BeBook: UnregisterNode() unregisters a node from the Media Server. It's called automatically
// BeBook: by the BMediaNode destructor, but it might be convenient to call it sometime before
// BeBook: you delete your node instance, depending on your implementation and circumstances.
(BMediaRoster::Roster())->UnregisterNode(this);
// BeBook: you delete your node instance, depending on your implementation and circumstances.
// ATT! We do not unregister TimeSourceObject nodes (identified by fControlPort == -999666)
if (fControlPort != -999666) // must match value in TimeSourceObject::TimeSourceObject()
(BMediaRoster::Roster())->UnregisterNode(this);
if (fControlPort != -1)
if (fControlPort > 0)
delete_port(fControlPort);
if (fTimeSource)
fTimeSource->Release();
+4 -6
View File
@@ -14,11 +14,11 @@
#include "debug.h"
#include "TList.h"
#include "PortPool.h"
#include "SystemTimeSource.h"
#include "ServerInterface.h"
#include "DataExchange.h"
#include "DormantNodeManager.h"
#include "Notifications.h"
#include "TimeSourceObjectManager.h"
namespace BPrivate { namespace media {
extern team_id team;
@@ -437,17 +437,15 @@ BMediaRoster::ReleaseNode(const media_node & node)
BTimeSource *
BMediaRoster::MakeTimeSourceFor(const media_node & for_node)
{
BROKEN();
CALLED();
printf("BMediaRoster::MakeTimeSourceFor enter, node %ld, port %ld, kind %#lx\n", for_node.node, for_node.port, for_node.kind);
static BTimeSource *source = 0;
if (source == 0)
source = new _SysTimeSource();
BTimeSource *source = _TimeSourceObjectManager->GetTimeSource(for_node);
printf("BMediaRoster::MakeTimeSourceFor leave, node %ld, port %ld, kind %#lx\n", source->Node().node, source->Node().port, source->Node().kind);
return dynamic_cast<BTimeSource *>(source->Acquire());
return source;
}
-49
View File
@@ -1,49 +0,0 @@
/***********************************************************************
* Copyright (c) 2002 Marcus Overhagen. All Rights Reserved.
* This file may be used under the terms of the OpenBeOS License.
*
* The realtime BTimeSource
***********************************************************************/
// XXX This works only as long a BTimeSource is only supporting realtime
#include <OS.h>
#include <stdio.h>
#include <MediaRoster.h>
#include "SystemTimeSource.h"
_SysTimeSource::_SysTimeSource() :
BMediaNode("system time source")
{
printf("_SysTimeSource::_SysTimeSource enter\n");
BMediaRoster::Roster()->RegisterNode(this); // XXX
printf("_SysTimeSource::_SysTimeSource leave\n");
}
/* virtual */ status_t
_SysTimeSource::SnoozeUntil(
bigtime_t performance_time,
bigtime_t with_latency,
bool retry_signals)
{
bigtime_t time = performance_time - with_latency;
status_t err;
do {
err = snooze_until(time, B_SYSTEM_TIMEBASE);
} while (err == B_INTERRUPTED && retry_signals);
return err;
}
/* virtual */ status_t
_SysTimeSource::TimeSourceOp(
const time_source_op_info & op,
void * _reserved)
{
return B_OK;
}
/* virtual */ BMediaAddOn*
_SysTimeSource::AddOn(int32 * internal_id) const
{
return NULL;
}
-31
View File
@@ -1,31 +0,0 @@
/***********************************************************************
* Copyright (c) 2002 Marcus Overhagen. All Rights Reserved.
* This file may be used under the terms of the OpenBeOS License.
*
* The realtime BTimeSource
***********************************************************************/
#ifndef _SYSTEM_TIME_SOURCE_H_
#define _SYSTEM_TIME_SOURCE_H_
#include <TimeSource.h>
class _SysTimeSource : public BTimeSource
{
public:
_SysTimeSource();
virtual status_t SnoozeUntil(
bigtime_t performance_time,
bigtime_t with_latency = 0,
bool retry_signals = false);
protected:
virtual status_t TimeSourceOp(
const time_source_op_info & op,
void * _reserved);
virtual BMediaAddOn* AddOn(
int32 * internal_id) const;
};
#endif
+52 -7
View File
@@ -11,14 +11,17 @@
#include <stdio.h>
#include <MediaRoster.h>
#include "TimeSourceObject.h"
#include "TimeSourceObjectManager.h"
TimeSourceObject::TimeSourceObject(const media_node &node) :
BMediaNode("some timesource object")
TimeSourceObject::TimeSourceObject(media_node_id id) :
BMediaNode("some timesource object", id, B_TIME_SOURCE),
BTimeSource(id)
{
printf("TimeSourceObject::TimeSourceObject enter\n");
printf("TimeSourceObject::TimeSourceObject enter, id = %ld\n", id);
delete_port(fControlPort);
fControlPort = -999666;
printf("TimeSourceObject::TimeSourceObject leave\n");
fControlPort = -999666; // must match value in BMediaNode::~BMediaNode()
ASSERT(id == fNodeID);
printf("TimeSourceObject::TimeSourceObject leave, node id %ld\n", fNodeID);
}
/* virtual */ status_t
@@ -27,7 +30,12 @@ TimeSourceObject::SnoozeUntil(
bigtime_t with_latency,
bool retry_signals)
{
return B_ERROR;
bigtime_t time = performance_time - with_latency;
status_t err;
do {
err = snooze_until(time, B_SYSTEM_TIMEBASE);
} while (err == B_INTERRUPTED && retry_signals);
return err;
}
/* virtual */ status_t
@@ -39,7 +47,44 @@ TimeSourceObject::TimeSourceOp(
}
/* virtual */ BMediaAddOn*
TimeSourceObject::AddOn(int32 * internal_id) const
TimeSourceObject::AddOn(int32 *internal_id) const
{
if (internal_id)
*internal_id = 0;
return NULL;
}
/* virtual */ status_t
TimeSourceObject::DeleteHook(BMediaNode * node)
{
printf("TimeSourceObject::DeleteHook enter\n");
_TimeSourceObjectManager->ObjectDeleted(this);
BTimeSource::DeleteHook(node);
printf("TimeSourceObject::DeleteHook leave\n");
}
SystemTimeSourceObject::SystemTimeSourceObject(media_node_id id)
: BMediaNode("System Time Source", id, B_TIME_SOURCE),
TimeSourceObject(id)
{
printf("SystemTimeSourceObject::SystemTimeSourceObject enter, id = %ld\n", id);
printf("SystemTimeSourceObject::SystemTimeSourceObject leave, node id %ld\n", ID());
}
/* virtual */ status_t
SystemTimeSourceObject::SnoozeUntil(
bigtime_t performance_time,
bigtime_t with_latency = 0,
bool retry_signals = false)
{
return TimeSourceObject::SnoozeUntil(performance_time, with_latency, retry_signals);
}
/* virtual */ status_t
SystemTimeSourceObject::DeleteHook(BMediaNode * node)
{
FATAL("SystemTimeSourceObject::DeleteHook called\n");
return B_ERROR;
}
+21 -2
View File
@@ -16,20 +16,39 @@ namespace BPrivate { namespace media {
class TimeSourceObject : public BTimeSource
{
public:
TimeSourceObject(const media_node &node);
TimeSourceObject(media_node_id id);
virtual status_t SnoozeUntil(
bigtime_t performance_time,
bigtime_t with_latency = 0,
bool retry_signals = false);
protected:
virtual status_t TimeSourceOp(
const time_source_op_info & op,
void * _reserved);
virtual BMediaAddOn* AddOn(
virtual BMediaAddOn* AddOn(
int32 * internal_id) const;
// override from BMediaNode
virtual status_t DeleteHook(BMediaNode * node);
};
class SystemTimeSourceObject : public TimeSourceObject
{
public:
SystemTimeSourceObject(media_node_id id);
virtual status_t SnoozeUntil(
bigtime_t performance_time,
bigtime_t with_latency = 0,
bool retry_signals = false);
protected:
// override from BMediaNode
virtual status_t DeleteHook(BMediaNode * node);
};
} } using namespace BPrivate::media;
+100
View File
@@ -7,5 +7,105 @@
#include <OS.h>
#include <stdio.h>
#include <MediaRoster.h>
#include <Autolock.h>
#include "TimeSourceObjectManager.h"
#include "TimeSourceObject.h"
#include "debug.h"
static BPrivate::media::TimeSourceObjectManager manager;
BPrivate::media::TimeSourceObjectManager *_TimeSourceObjectManager = &manager;
namespace BPrivate {
namespace media {
TimeSourceObjectManager::TimeSourceObjectManager()
: fSystemTimeSource(0),
fSystemTimeSourceID(0)
{
fLock = new BLocker("timesource object manager locker");
fMap = new Map<media_node_id,BTimeSource *>;
}
TimeSourceObjectManager::~TimeSourceObjectManager()
{
delete fLock;
// force unloading all currently loaded
BTimeSource **pts;
for (fMap->Rewind(); fMap->GetNext(&pts); ) {
FATAL("Forcing release of TimeSource id %ld...\n", (*pts)->ID());
int debugcnt = 0;
while ((*pts)->Release() != NULL)
debugcnt++;
FATAL("Forcing release of TimeSource done, released %d times\n", debugcnt);
}
delete fMap;
}
BTimeSource *
TimeSourceObjectManager::GetTimeSource(const media_node &node)
{
BAutolock lock(fLock);
printf("TimeSourceObjectManager::GetTimeSource, node id %ld\n", node.node);
if (fSystemTimeSource == 0) {
media_node clone;
status_t rv;
rv = BMediaRoster::Roster()->GetSystemTimeSource(&clone);
if (rv != B_OK) {
FATAL("TimeSourceObjectManager::GetTimeSource, GetSystemTimeSource failed\n");
return NULL;
}
fSystemTimeSourceID = clone.node;
fSystemTimeSource = new SystemTimeSourceObject(fSystemTimeSourceID);
ASSERT(fSystemTimeSourceID == fSystemTimeSource->ID());
}
if (node.node == fSystemTimeSourceID)
return dynamic_cast<BTimeSource *>(fSystemTimeSource->Acquire());
BTimeSource **pts;
if (fMap->Get(node.node, &pts))
return dynamic_cast<BTimeSource *>((*pts)->Acquire());
media_node clone;
status_t rv;
rv = BMediaRoster::Roster()->GetNodeFor(node.node, &clone);
if (rv != B_OK) {
FATAL("TimeSourceObjectManager::GetTimeSource, GetNodeFor %ld failed\n", node.node);
return NULL;
}
BTimeSource *ts;
ts = new TimeSourceObject(clone.node);
fMap->Insert(clone.node, ts);
return ts;
}
void
TimeSourceObjectManager::ObjectDeleted(BTimeSource *timesource)
{
BAutolock lock(fLock);
printf("TimeSourceObjectManager::ObjectDeleted, node id %ld\n", timesource->ID());
bool b;
b = fMap->Remove(timesource->ID());
if (!b) {
FATAL("TimeSourceObjectManager::ObjectDeleted, Remove failed\n");
}
status_t rv;
rv = BMediaRoster::Roster()->ReleaseNode(timesource->Node());
if (rv != B_OK) {
FATAL("TimeSourceObjectManager::ObjectDeleted, ReleaseNode failed\n");
}
}
}; // namespace media
}; // namespace BPrivate
+26
View File
@@ -6,4 +6,30 @@
#ifndef _TIME_SOURCE_OBJECT_MANAGER_H_
#define _TIME_SOURCE_OBJECT_MANAGER_H_
#include "TMap.h"
namespace BPrivate {
namespace media {
class TimeSourceObjectManager
{
public:
TimeSourceObjectManager();
~TimeSourceObjectManager();
BTimeSource *GetTimeSource(const media_node &node);
void ObjectDeleted(BTimeSource *timesource);
private:
Map<media_node_id,BTimeSource *> *fMap;
BLocker *fLock;
BTimeSource *fSystemTimeSource;
media_node_id fSystemTimeSourceID;
};
}; // namespace media
}; // namespace BPrivate
extern BPrivate::media::TimeSourceObjectManager *_TimeSourceObjectManager;
#endif
+7 -4
View File
@@ -22,11 +22,13 @@ DefaultManager::~DefaultManager()
status_t
DefaultManager::LoadState()
{
return B_OK;
}
status_t
DefaultManager::SaveState()
{
return B_OK;
}
status_t
@@ -40,7 +42,7 @@ DefaultManager::Set(node_type type, const media_node *node, const dormant_node_i
case AUDIO_OUTPUT:
case AUDIO_OUTPUT_EX:
case TIME_SOURCE:
return B_OK;
return B_ERROR;
case SYSTEM_TIME_SOURCE: //called by the media_server's ServerApp::StartSystemTimeSource()
{
@@ -68,10 +70,10 @@ DefaultManager::Get(media_node_id *nodeid, char *input_name, int32 *input_id, no
case AUDIO_MIXER:
case AUDIO_OUTPUT:
case AUDIO_OUTPUT_EX:
case TIME_SOURCE:
*nodeid = -1;
return B_OK;
*nodeid = -999;
return B_ERROR;
case TIME_SOURCE:
case SYSTEM_TIME_SOURCE:
*nodeid = fSystemTimeSource;
return B_OK;
@@ -87,6 +89,7 @@ DefaultManager::Get(media_node_id *nodeid, char *input_name, int32 *input_id, no
status_t
DefaultManager::Rescan()
{
return B_OK;
}
void
+2 -2
View File
@@ -208,7 +208,7 @@ NodeManager::GetClone(media_node *node, char *input_name, int32 *input_id, node_
}
ASSERT(id == node->node);
FATAL("NodeManager::GetClone leave: node id %ld, node port %ld, node kind %Ld\n", node->node, node->port, node->kind);
FATAL("NodeManager::GetClone leave: node id %ld, node port %ld, node kind %#lx\n", node->node, node->port, node->kind);
return B_OK;
}
@@ -700,7 +700,7 @@ get_node_type(node_type t)
CASE(AUDIO_OUTPUT_EX)
CASE(TIME_SOURCE)
CASE(SYSTEM_TIME_SOURCE)
default: "unknown";
default: return "unknown";
}
};
+4 -15
View File
@@ -14,10 +14,6 @@
#include "media_server.h"
#include "debug.h"
#include "/boot/home/develop/openbeos/current/src/kits/media/SystemTimeSource.h"
#include <MediaRoster.h>
#include <MediaNode.h>
/*
*
* An implementation of a new media_server for the OpenBeOS MediaKit
@@ -152,21 +148,14 @@ void
ServerApp::StartSystemTimeSource()
{
printf("StartSystemTimeSource enter\n");
media_node node;
status_t rv;
BTimeSource *source;
printf("StartSystemTimeSource creating object\n");
source = new _SysTimeSource;
printf("StartSystemTimeSource registering\n");
BMediaRoster::Roster()->RegisterNode(source);
printf("StartSystemTimeSource getting Node()\n");
node = source->Node();
// register a dummy node
media_node node;
rv = gNodeManager->RegisterNode(&node.node, -1, 0, "Fake System Time Source", B_TIME_SOURCE, -1, -1);
ASSERT(rv == B_OK);
printf("StartSystemTimeSource setting as default\n");