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:
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -47,7 +47,6 @@ SharedLibrary media :
|
||||
DormantNodeManager.cpp
|
||||
Notifications.cpp
|
||||
PortPool.cpp
|
||||
SystemTimeSource.cpp
|
||||
SharedBufferList.cpp
|
||||
TrackReader.cpp
|
||||
TimedEventQueuePrivate.cpp
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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";
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user