time sources now publish and retrieve timing information
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@2372 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -17,8 +17,12 @@
|
|||||||
|
|
||||||
|
|
||||||
class _BSlaveNodeStorageP;
|
class _BSlaveNodeStorageP;
|
||||||
struct _time_transmit_buf;
|
|
||||||
namespace BPrivate { namespace media { class TimeSourceObject; class SystemTimeSourceObject; } }
|
namespace BPrivate { namespace media {
|
||||||
|
class TimeSourceObject;
|
||||||
|
class SystemTimeSourceObject;
|
||||||
|
struct TimeSourceTransmit;
|
||||||
|
} }
|
||||||
|
|
||||||
|
|
||||||
class BTimeSource :
|
class BTimeSource :
|
||||||
@@ -118,13 +122,14 @@ virtual status_t _Reserved_TimeSource_4(void *);
|
|||||||
virtual status_t _Reserved_TimeSource_5(void *);
|
virtual status_t _Reserved_TimeSource_5(void *);
|
||||||
|
|
||||||
bool fStopped;
|
bool fStopped;
|
||||||
|
area_id fArea;
|
||||||
area_id _mArea;
|
volatile BPrivate::media::TimeSourceTransmit *fBuf;
|
||||||
volatile _time_transmit_buf * _mBuf;
|
|
||||||
_BSlaveNodeStorageP * _mSlaveNodes;
|
_BSlaveNodeStorageP * _mSlaveNodes;
|
||||||
|
|
||||||
area_id _mOrigArea;
|
area_id _mOrigArea;
|
||||||
uint32 _reserved_time_source_[11];
|
bool fIsRealtime;
|
||||||
|
bool _reserved_bool_[3];
|
||||||
|
uint32 _reserved_time_source_[10];
|
||||||
|
|
||||||
explicit BTimeSource(
|
explicit BTimeSource(
|
||||||
media_node_id id);
|
media_node_id id);
|
||||||
|
|||||||
@@ -202,6 +202,8 @@ BMediaNode::TimeSource() const
|
|||||||
self->fTimeSource = roster->MakeTimeSourceFor(clone);
|
self->fTimeSource = roster->MakeTimeSourceFor(clone);
|
||||||
if (fTimeSource == 0) {
|
if (fTimeSource == 0) {
|
||||||
FATAL("BMediaNode::TimeSource: Error, MakeTimeSourceFor failed\n");
|
FATAL("BMediaNode::TimeSource: Error, MakeTimeSourceFor failed\n");
|
||||||
|
} else {
|
||||||
|
fTimeSource->AddMe(self);
|
||||||
}
|
}
|
||||||
rv = roster->ReleaseNode(clone);
|
rv = roster->ReleaseNode(clone);
|
||||||
if (fTimeSource == 0) {
|
if (fTimeSource == 0) {
|
||||||
@@ -471,8 +473,11 @@ BMediaNode::SetTimeSource(BTimeSource *time_source)
|
|||||||
newnode->Release();
|
newnode->Release();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (fTimeSource)
|
if (fTimeSource) {
|
||||||
|
fTimeSource->RemoveMe(this);
|
||||||
fTimeSource->Release();
|
fTimeSource->Release();
|
||||||
|
newsource->AddMe(this);
|
||||||
|
}
|
||||||
fTimeSource = newsource;
|
fTimeSource = newsource;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -490,6 +495,7 @@ BMediaNode::HandleMessage(int32 message,
|
|||||||
case NODE_START:
|
case NODE_START:
|
||||||
{
|
{
|
||||||
const node_start_command *command = static_cast<const node_start_command *>(data);
|
const node_start_command *command = static_cast<const node_start_command *>(data);
|
||||||
|
printf("NODE_START, node %ld\n", fNodeID);
|
||||||
Start(command->performance_time);
|
Start(command->performance_time);
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
@@ -497,6 +503,7 @@ BMediaNode::HandleMessage(int32 message,
|
|||||||
case NODE_STOP:
|
case NODE_STOP:
|
||||||
{
|
{
|
||||||
const node_stop_command *command = static_cast<const node_stop_command *>(data);
|
const node_stop_command *command = static_cast<const node_stop_command *>(data);
|
||||||
|
printf("NODE_STOP, node %ld\n", fNodeID);
|
||||||
Stop(command->performance_time, command->immediate);
|
Stop(command->performance_time, command->immediate);
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
@@ -504,6 +511,7 @@ BMediaNode::HandleMessage(int32 message,
|
|||||||
case NODE_SEEK:
|
case NODE_SEEK:
|
||||||
{
|
{
|
||||||
const node_seek_command *command = static_cast<const node_seek_command *>(data);
|
const node_seek_command *command = static_cast<const node_seek_command *>(data);
|
||||||
|
printf("NODE_SEEK, node %ld\n", fNodeID);
|
||||||
Seek(command->media_time, command->performance_time);
|
Seek(command->media_time, command->performance_time);
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
@@ -531,12 +539,12 @@ BMediaNode::HandleMessage(int32 message,
|
|||||||
|
|
||||||
case NODE_SET_TIMESOURCE:
|
case NODE_SET_TIMESOURCE:
|
||||||
{
|
{
|
||||||
printf("NODE_SET_TIMESOURCE enter\n");
|
|
||||||
const node_set_timesource_command *command = static_cast<const node_set_timesource_command *>(data);
|
const node_set_timesource_command *command = static_cast<const node_set_timesource_command *>(data);
|
||||||
BMediaRoster *roster;
|
BMediaRoster *roster;
|
||||||
BTimeSource *newsource;
|
BTimeSource *newsource;
|
||||||
media_node clone;
|
media_node clone;
|
||||||
status_t rv;
|
status_t rv;
|
||||||
|
printf("NODE_SET_TIMESOURCE, node %ld, timesource %ld\n", fNodeID, command->timesource_id);
|
||||||
roster = BMediaRoster::Roster();
|
roster = BMediaRoster::Roster();
|
||||||
rv = roster->GetNodeFor(command->timesource_id, &clone);
|
rv = roster->GetNodeFor(command->timesource_id, &clone);
|
||||||
if (rv != B_OK) {
|
if (rv != B_OK) {
|
||||||
@@ -551,13 +559,14 @@ BMediaNode::HandleMessage(int32 message,
|
|||||||
}
|
}
|
||||||
roster->ReleaseNode(clone);
|
roster->ReleaseNode(clone);
|
||||||
if (fTimeSource) {
|
if (fTimeSource) {
|
||||||
|
fTimeSource->RemoveMe(this);
|
||||||
fTimeSource->Release();
|
fTimeSource->Release();
|
||||||
fTimeSource = newsource;
|
fTimeSource = newsource;
|
||||||
SetTimeSource(fTimeSource);
|
SetTimeSource(fTimeSource);
|
||||||
} else {
|
} else {
|
||||||
fTimeSource = newsource;
|
fTimeSource = newsource;
|
||||||
}
|
}
|
||||||
printf("NODE_SET_TIMESOURCE leave\n");
|
fTimeSource->AddMe(this);
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -793,7 +802,6 @@ BMediaNode::_InitObject(const char *name, media_node_id id, uint64 kinds)
|
|||||||
_mChangeCount = 0; // deprecated
|
_mChangeCount = 0; // deprecated
|
||||||
_mChangeCountReserved = 0; // deprecated
|
_mChangeCountReserved = 0; // deprecated
|
||||||
fKinds = kinds;
|
fKinds = kinds;
|
||||||
// fTimeSourceID = -1;
|
|
||||||
fProducerThis = 0;
|
fProducerThis = 0;
|
||||||
fConsumerThis = 0;
|
fConsumerThis = 0;
|
||||||
fFileInterfaceThis = 0;
|
fFileInterfaceThis = 0;
|
||||||
|
|||||||
@@ -438,12 +438,24 @@ BTimeSource *
|
|||||||
BMediaRoster::MakeTimeSourceFor(const media_node & for_node)
|
BMediaRoster::MakeTimeSourceFor(const media_node & for_node)
|
||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
|
|
||||||
printf("BMediaRoster::MakeTimeSourceFor enter, node %ld, port %ld, kind %#lx\n", for_node.node, for_node.port, for_node.kind);
|
|
||||||
|
|
||||||
BTimeSource *source = _TimeSourceObjectManager->GetTimeSource(for_node);
|
BTimeSource *source;
|
||||||
|
|
||||||
printf("BMediaRoster::MakeTimeSourceFor leave, node %ld, port %ld, kind %#lx\n", source->Node().node, source->Node().port, source->Node().kind);
|
// printf("BMediaRoster::MakeTimeSourceFor enter, node %ld, port %ld, kind %#lx\n", for_node.node, for_node.port, for_node.kind);
|
||||||
|
|
||||||
|
if (0 == (for_node.kind & B_TIME_SOURCE)) {
|
||||||
|
FATAL("BMediaRoster::MakeTimeSourceFor, node %ld is not a timesource!\n", for_node.node);
|
||||||
|
// XXX It appears that Cortex calls this function on every node, and expects
|
||||||
|
// XXX to be returned a system time source if the for_node is not a timesource
|
||||||
|
media_node clone;
|
||||||
|
GetSystemTimeSource(&clone);
|
||||||
|
source = _TimeSourceObjectManager->GetTimeSource(clone);
|
||||||
|
ReleaseNode(clone);
|
||||||
|
} else {
|
||||||
|
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 source;
|
return source;
|
||||||
}
|
}
|
||||||
@@ -673,6 +685,8 @@ BMediaRoster::StartNode(const media_node & node,
|
|||||||
CALLED();
|
CALLED();
|
||||||
if (node.node <= 0)
|
if (node.node <= 0)
|
||||||
return B_MEDIA_BAD_NODE;
|
return B_MEDIA_BAD_NODE;
|
||||||
|
|
||||||
|
printf("BMediaRoster::StartNode, node %ld, at perf %Ld\n", node.node, at_performance_time);
|
||||||
|
|
||||||
node_start_command command;
|
node_start_command command;
|
||||||
command.performance_time = at_performance_time;
|
command.performance_time = at_performance_time;
|
||||||
@@ -690,6 +704,8 @@ BMediaRoster::StopNode(const media_node & node,
|
|||||||
if (node.node <= 0)
|
if (node.node <= 0)
|
||||||
return B_MEDIA_BAD_NODE;
|
return B_MEDIA_BAD_NODE;
|
||||||
|
|
||||||
|
printf("BMediaRoster::StopNode, node %ld, at perf %Ld %s\n", node.node, at_performance_time, immediate ? "NOW" : "");
|
||||||
|
|
||||||
node_stop_command command;
|
node_stop_command command;
|
||||||
command.performance_time = at_performance_time;
|
command.performance_time = at_performance_time;
|
||||||
command.immediate = immediate;
|
command.immediate = immediate;
|
||||||
@@ -707,6 +723,8 @@ BMediaRoster::SeekNode(const media_node & node,
|
|||||||
if (node.node <= 0)
|
if (node.node <= 0)
|
||||||
return B_MEDIA_BAD_NODE;
|
return B_MEDIA_BAD_NODE;
|
||||||
|
|
||||||
|
printf("BMediaRoster::SeekNode, node %ld, at perf %Ld, to perf %Ld\n", node.node, at_performance_time, to_media_time);
|
||||||
|
|
||||||
node_seek_command command;
|
node_seek_command command;
|
||||||
command.media_time = to_media_time;
|
command.media_time = to_media_time;
|
||||||
command.performance_time = at_performance_time;
|
command.performance_time = at_performance_time;
|
||||||
@@ -720,10 +738,16 @@ BMediaRoster::StartTimeSource(const media_node & node,
|
|||||||
bigtime_t at_real_time)
|
bigtime_t at_real_time)
|
||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
if (node.node <= 0)
|
if (node.node <= 0) {
|
||||||
|
FATAL("BMediaRoster::StartTimeSource node invalid\n");
|
||||||
return B_MEDIA_BAD_NODE;
|
return B_MEDIA_BAD_NODE;
|
||||||
if ((node.kind & B_TIME_SOURCE) == 0)
|
}
|
||||||
|
if ((node.kind & B_TIME_SOURCE) == 0) {
|
||||||
|
FATAL("BMediaRoster::StartTimeSource node is no timesource invalid\n");
|
||||||
return B_MEDIA_BAD_NODE;
|
return B_MEDIA_BAD_NODE;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("BMediaRoster::StartTimeSource, node %ld, at real %Ld\n", node.node, at_real_time);
|
||||||
|
|
||||||
BTimeSource::time_source_op_info msg;
|
BTimeSource::time_source_op_info msg;
|
||||||
msg.op = BTimeSource::B_TIMESOURCE_START;
|
msg.op = BTimeSource::B_TIMESOURCE_START;
|
||||||
@@ -739,10 +763,16 @@ BMediaRoster::StopTimeSource(const media_node & node,
|
|||||||
bool immediate)
|
bool immediate)
|
||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
if (node.node <= 0)
|
if (node.node <= 0) {
|
||||||
|
FATAL("BMediaRoster::StartTimeSource node invalid\n");
|
||||||
return B_MEDIA_BAD_NODE;
|
return B_MEDIA_BAD_NODE;
|
||||||
if ((node.kind & B_TIME_SOURCE) == 0)
|
}
|
||||||
|
if ((node.kind & B_TIME_SOURCE) == 0) {
|
||||||
|
FATAL("BMediaRoster::StartTimeSource node is no timesource invalid\n");
|
||||||
return B_MEDIA_BAD_NODE;
|
return B_MEDIA_BAD_NODE;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("BMediaRoster::StopTimeSource, node %ld, at real %Ld %s\n", node.node, at_real_time, immediate ? "NOW" : "");
|
||||||
|
|
||||||
BTimeSource::time_source_op_info msg;
|
BTimeSource::time_source_op_info msg;
|
||||||
msg.op = immediate ? BTimeSource::B_TIMESOURCE_STOP_IMMEDIATELY : BTimeSource::B_TIMESOURCE_STOP;
|
msg.op = immediate ? BTimeSource::B_TIMESOURCE_STOP_IMMEDIATELY : BTimeSource::B_TIMESOURCE_STOP;
|
||||||
@@ -758,11 +788,17 @@ BMediaRoster::SeekTimeSource(const media_node & node,
|
|||||||
bigtime_t at_real_time)
|
bigtime_t at_real_time)
|
||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
if (node.node <= 0)
|
if (node.node <= 0) {
|
||||||
|
FATAL("BMediaRoster::StartTimeSource node invalid\n");
|
||||||
return B_MEDIA_BAD_NODE;
|
return B_MEDIA_BAD_NODE;
|
||||||
if ((node.kind & B_TIME_SOURCE) == 0)
|
}
|
||||||
|
if ((node.kind & B_TIME_SOURCE) == 0) {
|
||||||
|
FATAL("BMediaRoster::StartTimeSource node is no timesource invalid\n");
|
||||||
return B_MEDIA_BAD_NODE;
|
return B_MEDIA_BAD_NODE;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("BMediaRoster::SeekTimeSource, node %ld, at real %Ld, to perf %Ld\n", node.node, at_real_time, to_performance_time);
|
||||||
|
|
||||||
BTimeSource::time_source_op_info msg;
|
BTimeSource::time_source_op_info msg;
|
||||||
msg.op = BTimeSource::B_TIMESOURCE_SEEK;
|
msg.op = BTimeSource::B_TIMESOURCE_SEEK;
|
||||||
msg.real_time = at_real_time;
|
msg.real_time = at_real_time;
|
||||||
@@ -1324,6 +1360,14 @@ BMediaRoster::RegisterNode(BMediaNode * node)
|
|||||||
|
|
||||||
// call the callback
|
// call the callback
|
||||||
node->NodeRegistered();
|
node->NodeRegistered();
|
||||||
|
|
||||||
|
// if the BMediaNode also inherits from BTimeSource, we need to call BTimeSource::FinishCreate()
|
||||||
|
if (node->Kinds() & B_TIME_SOURCE) {
|
||||||
|
BTimeSource *ts;
|
||||||
|
ts = dynamic_cast<BTimeSource *>(node);
|
||||||
|
if (ts)
|
||||||
|
ts->FinishCreate();
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// register existing inputs and outputs with the
|
// register existing inputs and outputs with the
|
||||||
@@ -1731,7 +1775,7 @@ BMediaRoster::GetLatencyFor(const media_node & producer,
|
|||||||
bigtime_t * out_latency)
|
bigtime_t * out_latency)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED();
|
UNIMPLEMENTED();
|
||||||
*out_latency = 25000;
|
*out_latency = 2000;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1742,7 +1786,7 @@ BMediaRoster::GetInitialLatencyFor(const media_node & producer,
|
|||||||
uint32 * out_flags /* = NULL */)
|
uint32 * out_flags /* = NULL */)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED();
|
UNIMPLEMENTED();
|
||||||
*out_latency = 10000;
|
*out_latency = 1000;
|
||||||
if (out_flags)
|
if (out_flags)
|
||||||
*out_flags = 0;
|
*out_flags = 0;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
|
|||||||
+151
-27
@@ -8,10 +8,20 @@
|
|||||||
#include "DataExchange.h"
|
#include "DataExchange.h"
|
||||||
#include "ServerInterface.h"
|
#include "ServerInterface.h"
|
||||||
|
|
||||||
// XXX This BTimeSource only works for realtime, nothing else is implemented
|
namespace BPrivate { namespace media {
|
||||||
|
|
||||||
|
struct TimeSourceTransmit
|
||||||
|
{
|
||||||
|
#define INDEX_COUNT 128
|
||||||
|
int32 readindex;
|
||||||
|
int32 writeindex;
|
||||||
|
bigtime_t realtime[INDEX_COUNT];
|
||||||
|
bigtime_t perftime[INDEX_COUNT];
|
||||||
|
float drift[INDEX_COUNT];
|
||||||
|
};
|
||||||
|
|
||||||
|
} }
|
||||||
|
|
||||||
// XXX The bebook says that the latency is always calculated in realtime
|
|
||||||
// XXX This is not currently done in this code
|
|
||||||
|
|
||||||
/*************************************************************
|
/*************************************************************
|
||||||
* protected BTimeSource
|
* protected BTimeSource
|
||||||
@@ -20,6 +30,8 @@
|
|||||||
BTimeSource::~BTimeSource()
|
BTimeSource::~BTimeSource()
|
||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
|
if (fArea > 0)
|
||||||
|
delete_area(fArea);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*************************************************************
|
/*************************************************************
|
||||||
@@ -32,8 +44,13 @@ BTimeSource::SnoozeUntil(bigtime_t performance_time,
|
|||||||
bool retry_signals)
|
bool retry_signals)
|
||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
|
bigtime_t time;
|
||||||
return B_ERROR;
|
status_t err;
|
||||||
|
do {
|
||||||
|
time = RealTimeFor(performance_time, with_latency);
|
||||||
|
err = snooze_until(time, B_SYSTEM_TIMEBASE);
|
||||||
|
} while (err == B_INTERRUPTED && retry_signals);
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -49,13 +66,14 @@ bigtime_t
|
|||||||
BTimeSource::PerformanceTimeFor(bigtime_t real_time)
|
BTimeSource::PerformanceTimeFor(bigtime_t real_time)
|
||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
bigtime_t performanceTime;
|
bigtime_t last_perf_time;
|
||||||
float drift;
|
bigtime_t last_real_time;
|
||||||
|
float last_drift;
|
||||||
|
|
||||||
while (GetTime(&performanceTime, &real_time, &drift) != B_OK)
|
while (GetTime(&last_perf_time, &last_real_time, &last_drift) != B_OK)
|
||||||
snooze(1000);
|
snooze(1);
|
||||||
|
|
||||||
return (bigtime_t)(performanceTime + (RealTime() - real_time) * drift);
|
return (bigtime_t)(last_perf_time + (real_time - last_real_time) * last_drift);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -65,7 +83,18 @@ BTimeSource::RealTimeFor(bigtime_t performance_time,
|
|||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
|
|
||||||
return performance_time - with_latency;
|
if (fIsRealtime) {
|
||||||
|
return performance_time - with_latency;
|
||||||
|
}
|
||||||
|
|
||||||
|
bigtime_t last_perf_time;
|
||||||
|
bigtime_t last_real_time;
|
||||||
|
float last_drift;
|
||||||
|
|
||||||
|
while (GetTime(&last_perf_time, &last_real_time, &last_drift) != B_OK)
|
||||||
|
snooze(1);
|
||||||
|
|
||||||
|
return (bigtime_t)(last_real_time + (performance_time - last_perf_time) / last_drift) - with_latency;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -73,6 +102,7 @@ bool
|
|||||||
BTimeSource::IsRunning()
|
BTimeSource::IsRunning()
|
||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
|
printf("BTimeSource::IsRunning() node %ld, port %ld, %s\n", fNodeID, fControlPort, fStopped ? "no" : "yes");
|
||||||
return !fStopped;
|
return !fStopped;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,9 +113,32 @@ BTimeSource::GetTime(bigtime_t *performance_time,
|
|||||||
float *drift)
|
float *drift)
|
||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
*performance_time = *real_time;
|
|
||||||
*drift = 1.0f;
|
|
||||||
|
|
||||||
|
if (fIsRealtime) {
|
||||||
|
*performance_time = *real_time = system_time();
|
||||||
|
*drift = 1.0f;
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
// if (fBuf == 0) {
|
||||||
|
// FATAL("BTimeSource::GetTime: fBuf == 0, name %s, id %ld\n",Name(),ID());
|
||||||
|
// *performance_time = *real_time = system_time();
|
||||||
|
// *drift = 1.0f;
|
||||||
|
// return B_OK;
|
||||||
|
// }
|
||||||
|
|
||||||
|
int32 index;
|
||||||
|
index = atomic_and(&fBuf->readindex, INDEX_COUNT - 1);
|
||||||
|
*real_time = fBuf->realtime[index];
|
||||||
|
*performance_time = fBuf->perftime[index];
|
||||||
|
*drift = fBuf->drift[index];
|
||||||
|
|
||||||
|
// if (*real_time == 0) {
|
||||||
|
// *performance_time = *real_time = system_time();
|
||||||
|
// *drift = 1.0f;
|
||||||
|
// return B_OK;
|
||||||
|
// }
|
||||||
|
|
||||||
|
printf("BTimeSource::GetTime timesource %ld, perf %16Ld, real %16Ld, drift %2.2f\n", ID(), *performance_time, *real_time, *drift);
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -112,31 +165,55 @@ BTimeSource::GetStartLatency(bigtime_t *out_latency)
|
|||||||
|
|
||||||
|
|
||||||
BTimeSource::BTimeSource() :
|
BTimeSource::BTimeSource() :
|
||||||
BMediaNode("called by BTimeSource"),
|
BMediaNode("This one is never called"),
|
||||||
fStopped(false)
|
fStopped(false),
|
||||||
|
fArea(-1),
|
||||||
|
fBuf(NULL),
|
||||||
|
fIsRealtime(false)
|
||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
|
|
||||||
AddNodeKind(B_TIME_SOURCE);
|
AddNodeKind(B_TIME_SOURCE);
|
||||||
|
// printf("##### BTimeSource::BTimeSource() name %s, id %ld\n", Name(), ID());
|
||||||
|
|
||||||
|
// This constructor is only called by real time sources that inherit
|
||||||
|
// BTimeSource. We create the communication area in FinishCreate(),
|
||||||
|
// since we don't have a correct ID() until this node is registered.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
BTimeSource::HandleMessage(int32 message,
|
BTimeSource::HandleMessage(int32 message,
|
||||||
const void *data,
|
const void *rawdata,
|
||||||
size_t size)
|
size_t size)
|
||||||
{
|
{
|
||||||
INFO("BTimeSource::HandleMessage %#lx, node %ld\n", message, fNodeID);
|
INFO("BTimeSource::HandleMessage %#lx, node %ld\n", message, fNodeID);
|
||||||
|
|
||||||
switch (message) {
|
switch (message) {
|
||||||
case TIMESOURCE_OP:
|
case TIMESOURCE_OP:
|
||||||
{
|
{
|
||||||
const time_source_op_info *data = static_cast<const time_source_op_info *>(data);
|
const time_source_op_info *data = static_cast<const time_source_op_info *>(rawdata);
|
||||||
|
switch (data->op) {
|
||||||
|
case B_TIMESOURCE_START:
|
||||||
|
DirectStart(data->real_time);
|
||||||
|
break;
|
||||||
|
case B_TIMESOURCE_STOP:
|
||||||
|
DirectStop(data->real_time, false);
|
||||||
|
break;
|
||||||
|
case B_TIMESOURCE_STOP_IMMEDIATELY:
|
||||||
|
DirectStop(data->real_time, true);
|
||||||
|
break;
|
||||||
|
case B_TIMESOURCE_SEEK:
|
||||||
|
DirectSeek(data->performance_time, data->real_time);
|
||||||
|
break;
|
||||||
|
}
|
||||||
status_t result;
|
status_t result;
|
||||||
result = TimeSourceOp(*data, NULL);
|
result = TimeSourceOp(*data, NULL);
|
||||||
|
if (result != B_OK) {
|
||||||
|
FATAL("BTimeSource::HandleMessage: TimeSourceOp failed\n");
|
||||||
|
}
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -146,7 +223,16 @@ BTimeSource::PublishTime(bigtime_t performance_time,
|
|||||||
bigtime_t real_time,
|
bigtime_t real_time,
|
||||||
float drift)
|
float drift)
|
||||||
{
|
{
|
||||||
// UNIMPLEMENTED(); //XXX
|
printf("BTimeSource::PublishTime timesource %ld, perf %16Ld, real %16Ld, drift %2.2f\n", ID(), performance_time, real_time, drift);
|
||||||
|
if (0 == fBuf)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int32 index;
|
||||||
|
index = atomic_add(&fBuf->writeindex, 1) & (INDEX_COUNT - 1);
|
||||||
|
fBuf->realtime[index] = real_time;
|
||||||
|
fBuf->perftime[index] = performance_time;
|
||||||
|
fBuf->drift[index] = drift;
|
||||||
|
atomic_add(&fBuf->readindex, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -155,6 +241,7 @@ BTimeSource::BroadcastTimeWarp(bigtime_t at_real_time,
|
|||||||
bigtime_t new_performance_time)
|
bigtime_t new_performance_time)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED();
|
UNIMPLEMENTED();
|
||||||
|
// call BMediaNode::TimeWarp() of all slaved nodes
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -162,6 +249,7 @@ void
|
|||||||
BTimeSource::SendRunMode(run_mode mode)
|
BTimeSource::SendRunMode(run_mode mode)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED();
|
UNIMPLEMENTED();
|
||||||
|
// send the run mode change to all slaved nodes
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -170,6 +258,7 @@ BTimeSource::SetRunMode(run_mode mode)
|
|||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
BMediaNode::SetRunMode(mode);
|
BMediaNode::SetRunMode(mode);
|
||||||
|
SendRunMode(mode);
|
||||||
}
|
}
|
||||||
/*************************************************************
|
/*************************************************************
|
||||||
* private BTimeSource
|
* private BTimeSource
|
||||||
@@ -190,19 +279,54 @@ status_t BTimeSource::_Reserved_TimeSource_5(void *) { return B_ERROR; }
|
|||||||
|
|
||||||
/* explicit */
|
/* explicit */
|
||||||
BTimeSource::BTimeSource(media_node_id id) :
|
BTimeSource::BTimeSource(media_node_id id) :
|
||||||
BMediaNode("called by BTimeSource", id, 0),
|
BMediaNode("This one is never called"),
|
||||||
fStopped(false)
|
fStopped(false),
|
||||||
|
fArea(-1),
|
||||||
|
fBuf(NULL),
|
||||||
|
fIsRealtime(false)
|
||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
|
|
||||||
AddNodeKind(B_TIME_SOURCE);
|
AddNodeKind(B_TIME_SOURCE);
|
||||||
|
ASSERT(id > 0);
|
||||||
|
// printf("###### explicit BTimeSource::BTimeSource() id %ld, name %s\n", id, Name());
|
||||||
|
|
||||||
|
// This constructor is only called by the derived BPrivate::media::TimeSourceObject objects
|
||||||
|
// We create a clone of the communication area
|
||||||
|
char name[32];
|
||||||
|
area_id area;
|
||||||
|
sprintf(name, "__timesource_buf_%ld", id);
|
||||||
|
area = find_area(name);
|
||||||
|
if (area <= 0) {
|
||||||
|
FATAL("BTimeSource::BTimeSource couldn't find area, node %ld\n", id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fArea = clone_area("__some_timesource_buf", reinterpret_cast<void **>(const_cast<BPrivate::media::TimeSourceTransmit **>(&fBuf)), B_ANY_ADDRESS, B_READ_AREA | B_WRITE_AREA, area);
|
||||||
|
if (fArea <= 0) {
|
||||||
|
FATAL("BTimeSource::BTimeSource couldn't clone area, node %ld\n", id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BTimeSource::FinishCreate()
|
BTimeSource::FinishCreate()
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED();
|
CALLED();
|
||||||
|
//printf("BTimeSource::FinishCreate(), id %ld\n", ID());
|
||||||
|
|
||||||
|
char name[32];
|
||||||
|
sprintf(name, "__timesource_buf_%ld", ID());
|
||||||
|
fArea = create_area(name, reinterpret_cast<void **>(const_cast<BPrivate::media::TimeSourceTransmit **>(&fBuf)), B_ANY_ADDRESS, B_PAGE_SIZE, B_FULL_LOCK, B_READ_AREA | B_WRITE_AREA);
|
||||||
|
if (fArea <= 0) {
|
||||||
|
FATAL("BTimeSource::BTimeSource couldn't create area, node %ld\n", ID());
|
||||||
|
fBuf = NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fBuf->readindex = 0;
|
||||||
|
fBuf->writeindex = 1;
|
||||||
|
fBuf->realtime[0] = 0;
|
||||||
|
fBuf->perftime[0] = 0;
|
||||||
|
fBuf->drift[0] = 1.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -228,6 +352,7 @@ void
|
|||||||
BTimeSource::DirectStart(bigtime_t at)
|
BTimeSource::DirectStart(bigtime_t at)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED();
|
UNIMPLEMENTED();
|
||||||
|
fStopped = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -236,6 +361,7 @@ BTimeSource::DirectStop(bigtime_t at,
|
|||||||
bool immediate)
|
bool immediate)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED();
|
UNIMPLEMENTED();
|
||||||
|
fStopped = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -252,5 +378,3 @@ BTimeSource::DirectSetRunMode(run_mode mode)
|
|||||||
{
|
{
|
||||||
UNIMPLEMENTED();
|
UNIMPLEMENTED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -17,25 +17,11 @@ TimeSourceObject::TimeSourceObject(media_node_id id) :
|
|||||||
BMediaNode("some timesource object", id, B_TIME_SOURCE),
|
BMediaNode("some timesource object", id, B_TIME_SOURCE),
|
||||||
BTimeSource(id)
|
BTimeSource(id)
|
||||||
{
|
{
|
||||||
printf("TimeSourceObject::TimeSourceObject enter, id = %ld\n", id);
|
// printf("TimeSourceObject::TimeSourceObject enter, id = %ld\n", id);
|
||||||
delete_port(fControlPort);
|
delete_port(fControlPort);
|
||||||
fControlPort = -999666; // must match value in BMediaNode::~BMediaNode()
|
fControlPort = -999666; // must match value in BMediaNode::~BMediaNode()
|
||||||
ASSERT(id == fNodeID);
|
ASSERT(id == fNodeID);
|
||||||
printf("TimeSourceObject::TimeSourceObject leave, node id %ld\n", fNodeID);
|
// printf("TimeSourceObject::TimeSourceObject leave, node id %ld\n", fNodeID);
|
||||||
}
|
|
||||||
|
|
||||||
/* virtual */ status_t
|
|
||||||
TimeSourceObject::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
|
/* virtual */ status_t
|
||||||
@@ -55,12 +41,14 @@ TimeSourceObject::AddOn(int32 *internal_id) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* virtual */ status_t
|
/* virtual */ status_t
|
||||||
TimeSourceObject::DeleteHook(BMediaNode * node)
|
TimeSourceObject::DeleteHook(BMediaNode *node)
|
||||||
{
|
{
|
||||||
printf("TimeSourceObject::DeleteHook enter\n");
|
status_t status;
|
||||||
|
// printf("TimeSourceObject::DeleteHook enter\n");
|
||||||
_TimeSourceObjectManager->ObjectDeleted(this);
|
_TimeSourceObjectManager->ObjectDeleted(this);
|
||||||
BTimeSource::DeleteHook(node);
|
status = BTimeSource::DeleteHook(node);
|
||||||
printf("TimeSourceObject::DeleteHook leave\n");
|
// printf("TimeSourceObject::DeleteHook leave\n");
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -68,18 +56,9 @@ SystemTimeSourceObject::SystemTimeSourceObject(media_node_id id)
|
|||||||
: BMediaNode("System Time Source", id, B_TIME_SOURCE),
|
: BMediaNode("System Time Source", id, B_TIME_SOURCE),
|
||||||
TimeSourceObject(id)
|
TimeSourceObject(id)
|
||||||
{
|
{
|
||||||
printf("SystemTimeSourceObject::SystemTimeSourceObject enter, id = %ld\n", id);
|
// printf("SystemTimeSourceObject::SystemTimeSourceObject enter, id = %ld\n", id);
|
||||||
|
fIsRealtime = true;
|
||||||
printf("SystemTimeSourceObject::SystemTimeSourceObject leave, node 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
|
/* virtual */ status_t
|
||||||
|
|||||||
@@ -18,11 +18,6 @@ class TimeSourceObject : public BTimeSource
|
|||||||
public:
|
public:
|
||||||
TimeSourceObject(media_node_id id);
|
TimeSourceObject(media_node_id id);
|
||||||
|
|
||||||
virtual status_t SnoozeUntil(
|
|
||||||
bigtime_t performance_time,
|
|
||||||
bigtime_t with_latency = 0,
|
|
||||||
bool retry_signals = false);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual status_t TimeSourceOp(
|
virtual status_t TimeSourceOp(
|
||||||
const time_source_op_info & op,
|
const time_source_op_info & op,
|
||||||
@@ -40,11 +35,6 @@ class SystemTimeSourceObject : public TimeSourceObject
|
|||||||
public:
|
public:
|
||||||
SystemTimeSourceObject(media_node_id id);
|
SystemTimeSourceObject(media_node_id id);
|
||||||
|
|
||||||
virtual status_t SnoozeUntil(
|
|
||||||
bigtime_t performance_time,
|
|
||||||
bigtime_t with_latency = 0,
|
|
||||||
bool retry_signals = false);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// override from BMediaNode
|
// override from BMediaNode
|
||||||
virtual status_t DeleteHook(BMediaNode * node);
|
virtual status_t DeleteHook(BMediaNode * node);
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ TimeSourceObjectManager::GetTimeSource(const media_node &node)
|
|||||||
{
|
{
|
||||||
BAutolock lock(fLock);
|
BAutolock lock(fLock);
|
||||||
|
|
||||||
printf("TimeSourceObjectManager::GetTimeSource, node id %ld\n", node.node);
|
// printf("TimeSourceObjectManager::GetTimeSource, node id %ld\n", node.node);
|
||||||
|
|
||||||
if (fSystemTimeSource == 0) {
|
if (fSystemTimeSource == 0) {
|
||||||
media_node clone;
|
media_node clone;
|
||||||
@@ -92,7 +92,7 @@ TimeSourceObjectManager::ObjectDeleted(BTimeSource *timesource)
|
|||||||
{
|
{
|
||||||
BAutolock lock(fLock);
|
BAutolock lock(fLock);
|
||||||
|
|
||||||
printf("TimeSourceObjectManager::ObjectDeleted, node id %ld\n", timesource->ID());
|
// printf("TimeSourceObjectManager::ObjectDeleted, node id %ld\n", timesource->ID());
|
||||||
|
|
||||||
bool b;
|
bool b;
|
||||||
b = fMap->Remove(timesource->ID());
|
b = fMap->Remove(timesource->ID());
|
||||||
|
|||||||
@@ -619,6 +619,8 @@ NodeManager::CleanupTeam(team_id team)
|
|||||||
|
|
||||||
FATAL("NodeManager::CleanupTeam: team %ld\n", team);
|
FATAL("NodeManager::CleanupTeam: team %ld\n", team);
|
||||||
|
|
||||||
|
// XXX send notifications after removing nodes
|
||||||
|
|
||||||
registered_node *rn;
|
registered_node *rn;
|
||||||
for (fRegisteredNodeMap->Rewind(); fRegisteredNodeMap->GetNext(&rn); ) {
|
for (fRegisteredNodeMap->Rewind(); fRegisteredNodeMap->GetNext(&rn); ) {
|
||||||
// if the team hosting this node is gone, remove node from database
|
// if the team hosting this node is gone, remove node from database
|
||||||
|
|||||||
@@ -36,6 +36,10 @@ BufferManager *gBufferManager;
|
|||||||
AppManager *gAppManager;
|
AppManager *gAppManager;
|
||||||
NodeManager *gNodeManager;
|
NodeManager *gNodeManager;
|
||||||
|
|
||||||
|
namespace BPrivate { namespace media {
|
||||||
|
extern team_id team;
|
||||||
|
} } // BPrivate::media
|
||||||
|
|
||||||
|
|
||||||
#define REPLY_TIMEOUT ((bigtime_t)500000)
|
#define REPLY_TIMEOUT ((bigtime_t)500000)
|
||||||
|
|
||||||
@@ -154,7 +158,7 @@ ServerApp::StartSystemTimeSource()
|
|||||||
|
|
||||||
// register a dummy node
|
// register a dummy node
|
||||||
media_node node;
|
media_node node;
|
||||||
rv = gNodeManager->RegisterNode(&node.node, -1, 0, "Fake System Time Source", B_TIME_SOURCE, -1, -1);
|
rv = gNodeManager->RegisterNode(&node.node, -1, 0, "System Clock", B_TIME_SOURCE, -1, BPrivate::media::team);
|
||||||
ASSERT(rv == B_OK);
|
ASSERT(rv == B_OK);
|
||||||
|
|
||||||
printf("StartSystemTimeSource setting as default\n");
|
printf("StartSystemTimeSource setting as default\n");
|
||||||
|
|||||||
Reference in New Issue
Block a user