added 5 changesets to branch 'refs/remotes/orangejua-github/media' old head: 0000000000000000000000000000000000000000 new head: 3cd56ded1698018803f0b2435f849683eb2f58fa overview: https://github.com/orangejua/haiku/compare/3cd56de ---------------------------------------------------------------------------- 0314e47: Revert hrev43164. * Revert as discussed on the mailing list (Dec 2012). This reverts commit ba5e652d79a41a15230b0940003e7dc352b41974. 3cdcaaf: Code style cleanup, no functional change intended. 77460c0: Introduce type perf_time_t and use it throughout the MediaKit. * To make it easier to discern whether a parameter or variable holds a time value in real or performance time, define a type perf_time_t. It is simply a typedef to bigtime_t. * Use perf_time_t in parameters of MediaKit APIs and implementations. e34a7bb: Fix BMediaEventLooper timing and lateness handling. * As noted by Pete Goodeve in #7285, there was a sign reversal in time calculation. Also, there was a mixup of performance and real time. This commit fixes both. * As suggested by bonefish in #7285, fulfill seamlessness constraint of node latencies by calculating lateness based on how early the event was enqueued. This makes lateness values correct even when kernel timing is erratic. * Call WaitForMessage without waiting when dequeueing events late. When we receive an ongoing series of late events we would otherwise go into an infinite loop of always breaking out of the inner loop early and never calling WaitForMessage, control port messages would never be handled. 3cd56de: Fix lateness handling in hmulti_audio.media_addon. * It used to calculate event lateness on its own, ignoring the value passed by BMediaEventLooper, and mixing up performance and real time. * To fulfill seamlessness constraint, it has to use the lateness value passed by BMediaEventLooper, which is based on how late the event was received. [ Julian Harnath <github@xxxxxxxxxxxx> ] ---------------------------------------------------------------------------- 35 files changed, 1019 insertions(+), 885 deletions(-) headers/os/media/BufferConsumer.h | 6 +- headers/os/media/BufferProducer.h | 10 +- headers/os/media/Controllable.h | 6 +- headers/os/media/MediaDefs.h | 5 +- headers/os/media/MediaEventLooper.h | 16 +- headers/os/media/MediaNode.h | 20 +- headers/os/media/MediaRoster.h | 26 +- headers/os/media/ParameterWeb.h | 16 +- headers/os/media/SoundPlayer.h | 8 +- headers/os/media/TimeSource.h | 18 +- headers/os/media/TimedEventQueue.h | 16 +- headers/private/media/Notifications.h | 4 +- headers/private/media/ServerInterface.h | 20 +- headers/private/media/SoundConsumer.h | 17 +- headers/private/media/SoundUtils.h | 4 +- .../media/media-add-ons/mixer/AudioMixer.cpp | 21 +- .../media/media-add-ons/mixer/AudioMixer.h | 1 - .../media-add-ons/multi_audio/MultiAudioNode.cpp | 20 +- src/kits/media/BufferConsumer.cpp | 12 +- src/kits/media/BufferProducer.cpp | 8 +- src/kits/media/Controllable.cpp | 2 +- src/kits/media/MediaEventLooper.cpp | 328 ++++++++----- src/kits/media/MediaNode.cpp | 477 ++++++++++--------- src/kits/media/MediaRoster.cpp | 14 +- src/kits/media/MediaTrack.cpp | 4 +- src/kits/media/Notifications.cpp | 4 +- src/kits/media/ParameterWeb.cpp | 4 +- src/kits/media/SoundConsumer.cpp | 19 +- src/kits/media/SoundPlayNode.cpp | 8 +- src/kits/media/SoundPlayNode.h | 8 +- src/kits/media/SoundPlayer.cpp | 8 +- src/kits/media/TimeSource.cpp | 27 +- src/kits/media/TimedEventQueue.cpp | 203 ++++---- src/kits/media/TimedEventQueuePrivate.cpp | 433 +++++++++-------- src/kits/media/TimedEventQueuePrivate.h | 111 ++--- ############################################################################ Commit: 0314e477b2050064c85eecd204b285df0f71c629 Author: Julian Harnath <github@xxxxxxxxxxxx> Date: Sat Oct 19 10:10:53 2013 UTC Revert hrev43164. * Revert as discussed on the mailing list (Dec 2012). This reverts commit ba5e652d79a41a15230b0940003e7dc352b41974. ---------------------------------------------------------------------------- diff --git a/headers/os/media/TimedEventQueue.h b/headers/os/media/TimedEventQueue.h index 190a792..732fd17 100644 --- a/headers/os/media/TimedEventQueue.h +++ b/headers/os/media/TimedEventQueue.h @@ -38,9 +38,8 @@ struct media_timed_event { int32 data; int64 bigdata; char user_data[64]; - bigtime_t queued_time; // Real time when put in queue - uint32 _reserved_media_timed_event_[6]; + uint32 _reserved_media_timed_event_[8]; }; diff --git a/headers/private/media/ServerInterface.h b/headers/private/media/ServerInterface.h index 2c28980..07913e1 100644 --- a/headers/private/media/ServerInterface.h +++ b/headers/private/media/ServerInterface.h @@ -37,8 +37,6 @@ enum { // Raw port based communication enum { - GENERAL_PURPOSE_WAKEUP = 0, // when no action but wait termination needed - ADD_ON_SERVER_RESCAN_ADD_ON_FLAVORS = 0x50, ADD_ON_SERVER_RESCAN_FINISHED_NOTIFY, ADD_ON_SERVER_INSTANTIATE_DORMANT_NODE, diff --git a/src/add-ons/media/media-add-ons/mixer/AudioMixer.cpp b/src/add-ons/media/media-add-ons/mixer/AudioMixer.cpp index 5bcc820..ff14f99 100644 --- a/src/add-ons/media/media-add-ons/mixer/AudioMixer.cpp +++ b/src/add-ons/media/media-add-ons/mixer/AudioMixer.cpp @@ -1,7 +1,7 @@ /* * Copyright 2002 David Shipman, * Copyright 2003-2007 Marcus Overhagen - * Copyright 2007-2011 Haiku Inc. All rights reserved. + * Copyright 2007-2010 Haiku Inc. All rights reserved. * * Distributed under the terms of the MIT License. */ @@ -113,8 +113,7 @@ AudioMixer::AudioMixer(BMediaAddOn *addOn, bool isSystemMixer) fDownstreamLatency(1), fInternalLatency(1), fDisableStop(false), - fLastLateNotification(0), - fLastLateness(0) + fLastLateNotification(0) { BMediaNode::AddNodeKind(B_SYSTEM_MIXER); @@ -320,12 +319,12 @@ AudioMixer::BufferReceived(BBuffer *buffer) void AudioMixer::HandleInputBuffer(BBuffer* buffer, bigtime_t lateness) { - if (lateness > kMaxJitter && lateness > fLastLateness) { + if (lateness > kMaxJitter) { debug_printf("AudioMixer: Dequeued input buffer %" B_PRIdBIGTIME " usec late\n", lateness); if (RunMode() == B_DROP_DATA || RunMode() == B_DECREASE_PRECISION || RunMode() == B_INCREASE_LATENCY) { - debug_printf("AudioMixer: sending notify\n"); + debug_printf("sending notify\n"); // Build a media_source out of the header data media_source source = media_source::null; @@ -335,12 +334,13 @@ AudioMixer::HandleInputBuffer(BBuffer* buffer, bigtime_t lateness) NotifyLateProducer(source, lateness, TimeSource()->Now()); if (RunMode() == B_DROP_DATA) { - debug_printf("AudioMixer: dropping buffer\n"); + debug_printf("dropping buffer\n"); return; } } } - fLastLateness = lateness; + + // printf("Received buffer with lateness %Ld\n", lateness); fCore->Lock(); fCore->BufferReceived(buffer, lateness); @@ -1012,19 +1012,18 @@ AudioMixer::LateNoticeReceived(const media_source& what, bigtime_t howMuch, if (what == fCore->Output()->MediaOutput().source && RunMode() == B_INCREASE_LATENCY) { - // We need to ignore subsequent notices whose arrival time here - // lies within the last lateness, because queued-up buffers will all be 'late' + // We need to ignore subsequent notices whose performance time + // lies before the performance time of the last notification if (performanceTime < fLastLateNotification) return; fInternalLatency += howMuch; // At some point a too large latency can get annoying - // (actually more than annoying, as there won't be enough buffers long before this!) if (fInternalLatency > kMaxLatency) fInternalLatency = kMaxLatency; - fLastLateNotification = TimeSource()->Now() + howMuch; + fLastLateNotification = TimeSource()->Now(); debug_printf("AudioMixer: increasing internal latency to %" B_PRIdBIGTIME " usec\n", fInternalLatency); diff --git a/src/add-ons/media/media-add-ons/mixer/AudioMixer.h b/src/add-ons/media/media-add-ons/mixer/AudioMixer.h index 123593c..9939cbb 100644 --- a/src/add-ons/media/media-add-ons/mixer/AudioMixer.h +++ b/src/add-ons/media/media-add-ons/mixer/AudioMixer.h @@ -136,7 +136,6 @@ private: bool fDisableStop; media_format fDefaultFormat; bigtime_t fLastLateNotification; - bigtime_t fLastLateness; }; diff --git a/src/kits/media/MediaEventLooper.cpp b/src/kits/media/MediaEventLooper.cpp index c8172c7..0da0a3e 100644 --- a/src/kits/media/MediaEventLooper.cpp +++ b/src/kits/media/MediaEventLooper.cpp @@ -31,7 +31,6 @@ #include <TimeSource.h> #include <scheduler.h> #include <Buffer.h> -#include <ServerInterface.h> #include "debug.h" /************************************************************* @@ -212,7 +211,6 @@ BMediaEventLooper::ControlLoop() status_t err; bigtime_t latency; bigtime_t waituntil; - bigtime_t lateness; for (;;) { // while there are no events or it is not time for the earliest event, // process messages using WaitForMessages. Whenever this funtion times out, @@ -225,37 +223,31 @@ BMediaEventLooper::ControlLoop() // only the scheduling latency). latency = fEventLatency + fSchedulingLatency; + if (fEventQueue.HasEvents() && (TimeSource()->Now() - latency) >= fEventQueue.FirstEventTime()) { +// printf("node %02d waiting for %12Ld that has already happened, now %12Ld\n", ID(), fEventQueue.FirstEventTime(), system_time()); + is_realtime = false; + break; + } + if (fRealTimeQueue.HasEvents() && (TimeSource()->RealTime() - fSchedulingLatency) >= fRealTimeQueue.FirstEventTime()) { + latency = fSchedulingLatency; + is_realtime = true; + break; + } waituntil = B_INFINITE_TIMEOUT; if (fEventQueue.HasEvents()) { - const media_timed_event *firstEvent = fEventQueue.FirstEvent(); - waituntil = TimeSource()->RealTimeFor(firstEvent->event_time, latency); + waituntil = TimeSource()->RealTimeFor(fEventQueue.FirstEventTime(), latency); +// printf("node %02d waiting for %12Ld that will happen at %12Ld\n", ID(), fEventQueue.FirstEventTime(), waituntil); is_realtime = false; - lateness = firstEvent->queued_time - waituntil; - if (lateness > 0) { -// if (lateness > 1000) -// printf("node %02ld handling %12Ld at %12Ld -- %Ld late, queued at %Ld now %12Ld \n", -// ID(), fEventQueue.FirstEventTime(), TimeSource()->Now(), lateness, -// firstEvent->queued_time, TimeSource()->RealTime()); - is_realtime = false; - break; - } -// printf("node %02ld waiting for %12Ld that will happen at %12Ld\n", ID(), fEventQueue.FirstEventTime(), waituntil); } if (fRealTimeQueue.HasEvents()) { - const media_timed_event *firstEvent = fRealTimeQueue.FirstEvent(); bigtime_t temp; - temp = firstEvent->event_time - fSchedulingLatency; - lateness = firstEvent->queued_time - temp; - if (lateness > 0) { - is_realtime = true; - break; - } + temp = fRealTimeQueue.FirstEventTime() - fSchedulingLatency; if (temp < waituntil) { waituntil = temp; is_realtime = true; + latency = fSchedulingLatency; } } - lateness = 0; // remove any extraneous value if we get this far err = WaitForMessage(waituntil); if (err == B_TIMED_OUT) break; @@ -267,9 +259,16 @@ BMediaEventLooper::ControlLoop() else err = fEventQueue.RemoveFirstEvent(&event); -// printf("node %02ld handling %12Ld at %12Ld\n", ID(), event.event_time, TimeSource()->Now()); +// printf("node %02d handling %12Ld at %12Ld\n", ID(), event.event_time, system_time()); - if (err == B_OK) DispatchEvent(&event, lateness, is_realtime); + if (err == B_OK) { + bigtime_t lateness; + if (is_realtime) + lateness = TimeSource()->RealTime() - event.event_time; + else + lateness = TimeSource()->RealTime() - TimeSource()->RealTimeFor(event.event_time, 0) + fEventLatency; + DispatchEvent(&event, lateness, is_realtime); + } } } @@ -391,7 +390,6 @@ BMediaEventLooper::SetEventLatency(bigtime_t latency) latency = 0; fEventLatency = latency; - write_port_etc(ControlPort(), GENERAL_PURPOSE_WAKEUP, 0, 0, B_TIMEOUT, 0); } diff --git a/src/kits/media/MediaNode.cpp b/src/kits/media/MediaNode.cpp index c4c67fc..66fda88 100644 --- a/src/kits/media/MediaNode.cpp +++ b/src/kits/media/MediaNode.cpp @@ -387,8 +387,6 @@ BMediaNode::WaitForMessage(bigtime_t waitUntil, TRACE("BMediaNode::WaitForMessage request is: %#lx, node %ld, this %p\n", message, fNodeID, this); - if (message == GENERAL_PURPOSE_WAKEUP) return B_OK; // no action needed - if (message > NODE_MESSAGE_START && message < NODE_MESSAGE_END) { TRACE("BMediaNode::WaitForMessage calling BMediaNode\n"); if (B_OK == BMediaNode::HandleMessage(message, data, size)) diff --git a/src/kits/media/TimedEventQueuePrivate.cpp b/src/kits/media/TimedEventQueuePrivate.cpp index c5517c9..99fbeed 100644 --- a/src/kits/media/TimedEventQueuePrivate.cpp +++ b/src/kits/media/TimedEventQueuePrivate.cpp @@ -29,19 +29,16 @@ /* Implements _event_queue_imp used by BTimedEventQueue, not thread save! */ -#include <string.h> - +#include <TimedEventQueue.h> #include <Autolock.h> #include <Buffer.h> #include <InterfaceDefs.h> //defines B_DELETE -#include <TimedEventQueue.h> -#include <TimeSource.h> - #include "TimedEventQueuePrivate.h" - #include "Debug.h" #include "debug.h" +#include <string.h> + _event_queue_imp::_event_queue_imp() : fLock(new BLocker("BTimedEventQueue locker")), fEventCount(0), @@ -78,8 +75,6 @@ _event_queue_imp::AddEvent(const media_timed_event &event) return B_BAD_VALUE; } - *(bigtime_t *)&event.queued_time = BTimeSource::RealTime(); - //create a new queue if (fFirstEntry == NULL) { ASSERT(fEventCount == 0); ############################################################################ Commit: 3cdcaafd83fa8b501d6ea434393031eeab35c4ed Author: Julian Harnath <github@xxxxxxxxxxxx> Date: Sat Oct 19 10:14:13 2013 UTC Code style cleanup, no functional change intended. ---------------------------------------------------------------------------- diff --git a/headers/os/media/MediaNode.h b/headers/os/media/MediaNode.h index ba5950d..ac7286d 100644 --- a/headers/os/media/MediaNode.h +++ b/headers/os/media/MediaNode.h @@ -190,8 +190,8 @@ protected: // When you've handled a stop request, call this function. If anyone is // listening for stop information from you, they will be notified. // Especially important for offline capable Nodes. - status_t NodeStopped(bigtime_t performanceTime); - void TimerExpired(bigtime_t notifyPerformanceTime, + status_t NodeStopped(bigtime_t whenPerformanceTime); + void TimerExpired(bigtime_t notifyPoint, int32 cookie, status_t error = B_OK); // NOTE: Constructor initializes the reference count to 1. @@ -239,7 +239,7 @@ public: protected: // Hook method which is called when requests have completed, or failed. virtual status_t RequestCompleted( - const media_request_info & info); + const media_request_info& info); virtual status_t DeleteHook(BMediaNode* node); @@ -250,7 +250,7 @@ public: // Fill out your attributes in the provided array, returning however // many you have. virtual status_t GetNodeAttributes( - media_node_attribute* _attributes, + media_node_attribute* outAttributes, size_t inMaxCount); virtual status_t AddTimer(bigtime_t atPerformanceTime, @@ -334,7 +334,7 @@ protected: // for use by BBufferConsumer, mostly private: - // NOTE: Dont' rename this one, it's static and needed for binary + // NOTE: Don't rename this one, it's static and needed for binary // compatibility static int32 _m_changeTag; // not to be confused with _mChangeCount diff --git a/headers/os/media/TimedEventQueue.h b/headers/os/media/TimedEventQueue.h index 732fd17..dc040ba 100644 --- a/headers/os/media/TimedEventQueue.h +++ b/headers/os/media/TimedEventQueue.h @@ -15,7 +15,7 @@ struct media_timed_event { media_timed_event(bigtime_t inTime, int32 inType); media_timed_event(bigtime_t inTime, - int32 inType, void*inPointer, + int32 inType, void* inPointer, uint32 inCleanup); media_timed_event( bigtime_t inTime, int32 inType, @@ -46,7 +46,7 @@ struct media_timed_event { bool operator==(const media_timed_event& a, const media_timed_event& b); bool operator!=(const media_timed_event& a, const media_timed_event& b); bool operator<(const media_timed_event& a, const media_timed_event& b); -bool operator>(const media_timed_event& a, const media_timed_event&b); +bool operator>(const media_timed_event& a, const media_timed_event& b); /*! A priority queue for holding media_timed_events. Sorts by increasing time, @@ -180,7 +180,7 @@ private: virtual status_t _Reserved_BTimedEventQueue_23(void*, ...); private: - _event_queue_imp* fImp; + _event_queue_imp* fImplementation; uint32 _reserved_timed_event_queue_[6]; }; diff --git a/src/kits/media/MediaEventLooper.cpp b/src/kits/media/MediaEventLooper.cpp index 0da0a3e..8eabed2 100644 --- a/src/kits/media/MediaEventLooper.cpp +++ b/src/kits/media/MediaEventLooper.cpp @@ -28,26 +28,13 @@ */ #include <MediaEventLooper.h> -#include <TimeSource.h> -#include <scheduler.h> -#include <Buffer.h> -#include "debug.h" -/************************************************************* - * protected BMediaEventLooper - *************************************************************/ +#include <Buffer.h> +#include <scheduler.h> +#include <TimeSource.h> -/* virtual */ -BMediaEventLooper::~BMediaEventLooper() -{ - CALLED(); +#include "debug.h" - // don't call Quit(); here, except if the user was stupid - if (fControlThread != -1) { - printf("You MUST call BMediaEventLooper::Quit() in your destructor!\n"); - Quit(); - } -} /* explicit */ BMediaEventLooper::BMediaEventLooper(uint32 apiVersion) : @@ -67,6 +54,24 @@ BMediaEventLooper::BMediaEventLooper(uint32 apiVersion) : fRealTimeQueue.SetCleanupHook(BMediaEventLooper::_CleanUpEntry, this); } + +/* virtual */ +BMediaEventLooper::~BMediaEventLooper() +{ + CALLED(); + + // don't call Quit(); here, except if the user was stupid + if (fControlThread != -1) { + printf("You MUST call BMediaEventLooper::Quit() in your " + "destructor!\n"); + Quit(); + } +} + + +// #pragma mark - BMediaNode interface + + /* virtual */ void BMediaEventLooper::NodeRegistered() { @@ -80,22 +85,26 @@ BMediaEventLooper::NodeRegistered() /* virtual */ void -BMediaEventLooper::Start(bigtime_t performance_time) +BMediaEventLooper::Start(bigtime_t performanceTime) { CALLED(); + // <BeBook> // This hook function is called when a node is started // by a call to the BMediaRoster. The specified // performanceTime, the time at which the node // should start running, may be in the future. - fEventQueue.AddEvent(media_timed_event(performance_time, BTimedEventQueue::B_START)); + // </BeBook> + fEventQueue.AddEvent(media_timed_event(performanceTime, + BTimedEventQueue::B_START)); } /* virtual */ void -BMediaEventLooper::Stop(bigtime_t performance_time, +BMediaEventLooper::Stop(bigtime_t performanceTime, bool immediate) { CALLED(); + // <BeBook> // This hook function is called when a node is stopped // by a call to the BMediaRoster. The specified performanceTime, // the time at which the node should stop, may be in the future. @@ -104,60 +113,71 @@ BMediaEventLooper::Stop(bigtime_t performance_time, // you're promising not to write into any BBuffers you may have // received from your downstream consumers, and you promise not // to send any more buffers until Start() is called again. + // </BeBook> if (immediate) { - // always be sure to add to the front of the queue so we can make sure it is - // handled before any buffers are sent! - performance_time = 0; + // always be sure to add to the front of the queue so we can make + // sure it is handled before any buffers are sent! + performanceTime = 0; } - fEventQueue.AddEvent(media_timed_event(performance_time, BTimedEventQueue::B_STOP)); + fEventQueue.AddEvent(media_timed_event(performanceTime, + BTimedEventQueue::B_STOP)); } /* virtual */ void -BMediaEventLooper::Seek(bigtime_t media_time, - bigtime_t performance_time) +BMediaEventLooper::Seek(bigtime_t mediaTime, + bigtime_t performanceTime) { CALLED(); + // <BeBook> // This hook function is called when a node is asked to seek to // the specified mediaTime by a call to the BMediaRoster. // The specified performanceTime, the time at which the node // should begin the seek operation, may be in the future. - fEventQueue.AddEvent(media_timed_event(performance_time, BTimedEventQueue::B_SEEK, NULL, - BTimedEventQueue::B_NO_CLEANUP, 0, media_time, NULL)); + // </BeBook> + fEventQueue.AddEvent(media_timed_event(performanceTime, + BTimedEventQueue::B_SEEK, NULL, BTimedEventQueue::B_NO_CLEANUP, + 0, mediaTime, NULL)); } /* virtual */ void -BMediaEventLooper::TimeWarp(bigtime_t at_real_time, - bigtime_t to_performance_time) +BMediaEventLooper::TimeWarp(bigtime_t atRealTime, + bigtime_t toPerformanceTime) { CALLED(); + // <BeBook> // This hook function is called when the time source to which the // node is slaved is repositioned (via a seek operation) such that // there will be a sudden jump in the performance time progression // as seen by the node. The to_performance_time argument indicates // the new performance time; the change should occur at the real // time specified by the at_real_time argument. + // </BeBook> // place in the realtime queue - fRealTimeQueue.AddEvent(media_timed_event(at_real_time, BTimedEventQueue::B_WARP, - NULL, BTimedEventQueue::B_NO_CLEANUP, 0, to_performance_time, NULL)); - - // BeBook: Your implementation of TimeWarp() should call through to BMediaNode::TimeWarp() - // BeBook: as well as all other inherited forms of TimeWarp() + fRealTimeQueue.AddEvent(media_timed_event(atRealTime, + BTimedEventQueue::B_WARP, NULL, BTimedEventQueue::B_NO_CLEANUP, 0, + toPerformanceTime, NULL)); + + // <BeBook> + // Your implementation of TimeWarp() should call through to + // BMediaNode::TimeWarp() as well as all other inherited forms + // of TimeWarp() + // </BeBook> // XXX should we do this here? - BMediaNode::TimeWarp(at_real_time, to_performance_time); + BMediaNode::TimeWarp(atRealTime, toPerformanceTime); } /* virtual */ status_t -BMediaEventLooper::AddTimer(bigtime_t at_performance_time, +BMediaEventLooper::AddTimer(bigtime_t atPerformanceTime, int32 cookie) { CALLED(); // XXX what do we need to do here? - return BMediaNode::AddTimer(at_performance_time,cookie); + return BMediaNode::AddTimer(atPerformanceTime, cookie); } @@ -165,16 +185,18 @@ BMediaEventLooper::AddTimer(bigtime_t at_performance_time, BMediaEventLooper::SetRunMode(run_mode mode) { CALLED(); - // The SetRunMode() hook function is called when someone requests that your node's run mode be changed. + // The SetRunMode() hook function is called when someone requests that your + // node's run mode be changed. // bump or reduce priority when switching from/to offline run mode - int32 priority; - priority = (mode == B_OFFLINE) ? min_c(B_NORMAL_PRIORITY, fSetPriority) : fSetPriority; + int32 priority = (mode == B_OFFLINE) ? + min_c(B_NORMAL_PRIORITY, fSetPriority) : fSetPriority; if (priority != fCurrentPriority) { fCurrentPriority = priority; if (fControlThread > 0) { set_thread_priority(fControlThread, fCurrentPriority); - fSchedulingLatency = estimate_max_scheduling_latency(fControlThread); + fSchedulingLatency = + estimate_max_scheduling_latency(fControlThread); printf("BMediaEventLooper: SchedulingLatency is %" B_PRId64 "\n", fSchedulingLatency); } @@ -184,13 +206,19 @@ BMediaEventLooper::SetRunMode(run_mode mode) } +// #pragma mark - BMediaEventLooper hook functions + + /* virtual */ void -BMediaEventLooper::CleanUpEvent(const media_timed_event *event) +BMediaEventLooper::CleanUpEvent(const media_timed_event* event) { CALLED(); + // <BeBook> // Implement this function to clean up after custom events you've created // and added to your queue. It's called when a custom event is removed from - // the queue, to let you handle any special tidying-up that the event might require. + // the queue, to let you handle any special tidying-up that the event might + // require. + // </BeBook> } @@ -207,67 +235,81 @@ BMediaEventLooper::ControlLoop() { CALLED(); - bool is_realtime = false; - status_t err; + bool isRealtime = false; + status_t status; bigtime_t latency; - bigtime_t waituntil; + bigtime_t waitUntil; for (;;) { // while there are no events or it is not time for the earliest event, - // process messages using WaitForMessages. Whenever this funtion times out, - // we need to handle the next event + // process messages using WaitForMessages. Whenever this funtion times + // out, we need to handle the next event for (;;) { if (RunState() == B_QUITTING) return; - // BMediaEventLooper compensates your performance time by adding the event latency - // (see SetEventLatency()) and the scheduling latency (or, for real-time events, - // only the scheduling latency). + + // <BeBook> + // BMediaEventLooper compensates your performance time by adding + // the event latency (see SetEventLatency()) and the scheduling + // latency (or, for real-time events, only the scheduling latency). + // </BeBook> latency = fEventLatency + fSchedulingLatency; - if (fEventQueue.HasEvents() && (TimeSource()->Now() - latency) >= fEventQueue.FirstEventTime()) { -// printf("node %02d waiting for %12Ld that has already happened, now %12Ld\n", ID(), fEventQueue.FirstEventTime(), system_time()); - is_realtime = false; + if (fEventQueue.HasEvents() + && TimeSource()->Now() - latency + >= fEventQueue.FirstEventTime()) { +// printf("node %02d waiting for %12Ld that has already happened," +// " now %12Ld\n", ID(), fEventQueue.FirstEventTime(), +// system_time()); + isRealtime = false; break; } - if (fRealTimeQueue.HasEvents() && (TimeSource()->RealTime() - fSchedulingLatency) >= fRealTimeQueue.FirstEventTime()) { + if (fRealTimeQueue.HasEvents() + && TimeSource()->RealTime() - fSchedulingLatency + >= fRealTimeQueue.FirstEventTime()) { latency = fSchedulingLatency; - is_realtime = true; + isRealtime = true; break; } - waituntil = B_INFINITE_TIMEOUT; + waitUntil = B_INFINITE_TIMEOUT; if (fEventQueue.HasEvents()) { - waituntil = TimeSource()->RealTimeFor(fEventQueue.FirstEventTime(), latency); -// printf("node %02d waiting for %12Ld that will happen at %12Ld\n", ID(), fEventQueue.FirstEventTime(), waituntil); - is_realtime = false; + waitUntil = TimeSource()->RealTimeFor( + fEventQueue.FirstEventTime(), latency); +// printf("node %02d waiting for %12Ld that will happen at " +// "%12Ld\n", ID(), fEventQueue.FirstEventTime(), waitUntil); + isRealtime = false; } if (fRealTimeQueue.HasEvents()) { bigtime_t temp; temp = fRealTimeQueue.FirstEventTime() - fSchedulingLatency; - if (temp < waituntil) { - waituntil = temp; - is_realtime = true; + if (temp < waitUntil) { + waitUntil = temp; + isRealtime = true; latency = fSchedulingLatency; } } - err = WaitForMessage(waituntil); - if (err == B_TIMED_OUT) + status = WaitForMessage(waitUntil); + if (status == B_TIMED_OUT) break; } - /// we have timed out - so handle the next event + // we have timed out - so handle the next event media_timed_event event; - if (is_realtime) - err = fRealTimeQueue.RemoveFirstEvent(&event); + if (isRealtime) + status = fRealTimeQueue.RemoveFirstEvent(&event); else - err = fEventQueue.RemoveFirstEvent(&event); + status = fEventQueue.RemoveFirstEvent(&event); -// printf("node %02d handling %12Ld at %12Ld\n", ID(), event.event_time, system_time()); +// printf("node %02d handling %12Ld at %12Ld\n", ID(), +// event.event_time, system_time()); - if (err == B_OK) { + if (status == B_OK) { bigtime_t lateness; - if (is_realtime) + if (isRealtime) lateness = TimeSource()->RealTime() - event.event_time; else - lateness = TimeSource()->RealTime() - TimeSource()->RealTimeFor(event.event_time, 0) + fEventLatency; - DispatchEvent(&event, lateness, is_realtime); + lateness = TimeSource()->RealTime() + - TimeSource()->RealTimeFor(event.event_time, 0) + + fEventLatency; + DispatchEvent(&event, lateness, isRealtime); } } } @@ -280,12 +322,11 @@ BMediaEventLooper::ControlThread() return fControlThread; } -/************************************************************* - * protected BMediaEventLooper - *************************************************************/ + +// #pragma mark - protected BMediaEventLooper -BTimedEventQueue * +BTimedEventQueue* BMediaEventLooper::EventQueue() { CALLED(); @@ -293,7 +334,7 @@ BMediaEventLooper::EventQueue() } -BTimedEventQueue * +BTimedEventQueue* BMediaEventLooper::RealTimeQueue() { CALLED(); @@ -354,7 +395,8 @@ BMediaEventLooper::SetPriority(int32 priority) priority = 120; fSetPriority = priority; - fCurrentPriority = (RunMode() == B_OFFLINE) ? min_c(B_NORMAL_PRIORITY, fSetPriority) : fSetPriority; + fCurrentPriority = (RunMode() == B_OFFLINE) ? + min_c(B_NORMAL_PRIORITY, fSetPriority) : fSetPriority; if (fControlThread > 0) { set_thread_priority(fControlThread, fCurrentPriority); @@ -417,12 +459,14 @@ BMediaEventLooper::Run() if (fControlThread != -1) return; // thread already running - // until now, the run state is B_UNREGISTERED, but we need to start in B_STOPPED state. + // until now, the run state is B_UNREGISTERED, but we need to start in + // B_STOPPED state. SetRunState(B_STOPPED); char threadName[32]; sprintf(threadName, "%.20s control", Name()); - fControlThread = spawn_thread(_ControlThreadStart, threadName, fCurrentPriority, this); + fControlThread = spawn_thread(_ControlThreadStart, threadName, + fCurrentPriority, this); resume_thread(fControlThread); // get latency information @@ -443,8 +487,8 @@ BMediaEventLooper::Quit() SetRunState(B_QUITTING); close_port(ControlPort()); if (fControlThread != -1) { - status_t err; - wait_for_thread(fControlThread, &err); + status_t status; + wait_for_thread(fControlThread, &status); fControlThread = -1; } SetRunState(B_TERMINATED); @@ -452,7 +496,7 @@ BMediaEventLooper::Quit() void -BMediaEventLooper::DispatchEvent(const media_timed_event *event, +BMediaEventLooper::DispatchEvent(const media_timed_event* event, bigtime_t lateness, bool realTimeEvent) { @@ -484,33 +528,32 @@ BMediaEventLooper::DispatchEvent(const media_timed_event *event, _DispatchCleanUp(event); } -/************************************************************* - * private BMediaEventLooper - *************************************************************/ + +// #pragma mark - private BMediaEventLooper /* static */ int32 -BMediaEventLooper::_ControlThreadStart(void *arg) +BMediaEventLooper::_ControlThreadStart(void* arg) { CALLED(); - ((BMediaEventLooper *)arg)->SetRunState(B_STOPPED); - ((BMediaEventLooper *)arg)->ControlLoop(); - ((BMediaEventLooper *)arg)->SetRunState(B_QUITTING); + ((BMediaEventLooper*)arg)->SetRunState(B_STOPPED); + ((BMediaEventLooper*)arg)->ControlLoop(); + ((BMediaEventLooper*)arg)->SetRunState(B_QUITTING); return 0; } /* static */ void -BMediaEventLooper::_CleanUpEntry(const media_timed_event *event, - void *context) +BMediaEventLooper::_CleanUpEntry(const media_timed_event* event, + void* context) { PRINT(6, "CALLED BMediaEventLooper::_CleanUpEntry()\n"); - ((BMediaEventLooper *)context)->_DispatchCleanUp(event); + ((BMediaEventLooper*)context)->_DispatchCleanUp(event); } void -BMediaEventLooper::_DispatchCleanUp(const media_timed_event *event) +BMediaEventLooper::_DispatchCleanUp(const media_timed_event* event) { PRINT(6, "CALLED BMediaEventLooper::_DispatchCleanUp()\n"); @@ -519,19 +562,12 @@ BMediaEventLooper::_DispatchCleanUp(const media_timed_event *event) CleanUpEvent(event); } -/* -// unimplemented -BMediaEventLooper::BMediaEventLooper(const BMediaEventLooper &) -BMediaEventLooper &BMediaEventLooper::operator=(const BMediaEventLooper &) -*/ -/************************************************************* - * protected BMediaEventLooper - *************************************************************/ +// #pragma mark - protected BMediaEventLooper status_t -BMediaEventLooper::DeleteHook(BMediaNode *node) +BMediaEventLooper::DeleteHook(BMediaNode* node) { CALLED(); // this is the DeleteHook that gets called by the media server @@ -540,9 +576,15 @@ BMediaEventLooper::DeleteHook(BMediaNode *node) return BMediaNode::DeleteHook(node); } -/************************************************************* - * private BMediaEventLooper - *************************************************************/ + +// #pragma mark - FBC padding and forbidden methods + + +/* +// unimplemented +BMediaEventLooper::BMediaEventLooper(const BMediaEventLooper &) +BMediaEventLooper &BMediaEventLooper::operator=(const BMediaEventLooper &) +*/ status_t BMediaEventLooper::_Reserved_BMediaEventLooper_0(int32 arg,...) { return B_ERROR; } status_t BMediaEventLooper::_Reserved_BMediaEventLooper_1(int32 arg,...) { return B_ERROR; } @@ -568,4 +610,3 @@ status_t BMediaEventLooper::_Reserved_BMediaEventLooper_20(int32 arg,...) { retu status_t BMediaEventLooper::_Reserved_BMediaEventLooper_21(int32 arg,...) { return B_ERROR; } status_t BMediaEventLooper::_Reserved_BMediaEventLooper_22(int32 arg,...) { return B_ERROR; } status_t BMediaEventLooper::_Reserved_BMediaEventLooper_23(int32 arg,...) { return B_ERROR; } - diff --git a/src/kits/media/MediaNode.cpp b/src/kits/media/MediaNode.cpp index 66fda88..2282f29 100644 --- a/src/kits/media/MediaNode.cpp +++ b/src/kits/media/MediaNode.cpp @@ -26,27 +26,33 @@ * THE SOFTWARE. * */ -//#define DEBUG 7 -#include <MediaRoster.h> #include <MediaNode.h> -#include <TimeSource.h> + +#include <string.h> + #include <BufferConsumer.h> #include <BufferProducer.h> #include <Controllable.h> #include <FileInterface.h> -#include <string.h> +#include <MediaRoster.h> +#include <TimeSource.h> + +#include "DataExchange.h" #include "debug.h" #include "MediaMisc.h" #include "MediaRosterEx.h" -#include "DataExchange.h" -#include "ServerInterface.h" #include "Notifications.h" +#include "ServerInterface.h" #include "TimeSourceObject.h" #include "TimeSourceObjectManager.h" + using std::nothrow; using std::nothrow_t; + +//#define DEBUG 7 + #undef TRACE //#define TRACE_MEDIA_NODE #ifdef TRACE_MEDIA_NODE @@ -59,33 +65,32 @@ using std::nothrow_t; // don't rename this one, it's used and exported for binary compatibility int32 BMediaNode::_m_changeTag = 0; -/************************************************************* - * media_node - *************************************************************/ + +// #pragma mark - media_node + // final & verified media_node::media_node() - : node(-1), + : + node(-1), port(-1), kind(0) { } + // final & verified media_node::~media_node() { } -/************************************************************* - * static media_node variables - *************************************************************/ // final & verified media_node media_node::null; -/************************************************************* - * media_input - *************************************************************/ + +// #pragma mark - media_input + // final media_input::media_input() @@ -93,14 +98,15 @@ media_input::media_input() name[0] = '\0'; } + // final media_input::~media_input() { } -/************************************************************* - * media_output - *************************************************************/ + +// #pragma mark - media_output + // final media_output::media_output() @@ -113,33 +119,36 @@ media_output::~media_output() { } -/************************************************************* - * live_node_info - *************************************************************/ + +// #pragma mark - live_node_info + // final & verified live_node_info::live_node_info() - : hint_point(0.0f, 0.0f) + : + hint_point(0.0f, 0.0f) { name[0] = '\0'; } + // final & verified live_node_info::~live_node_info() { } -/************************************************************* - * protected BMediaNode - *************************************************************/ + +// #pragma mark - protected BMediaNode + /* virtual */ BMediaNode::~BMediaNode() { CALLED(); - // 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. + // BeBook: UnregisterNode() unregisters a node from the Media Server. It's + // BeBook: called automatically by the BMediaNode destructor, but it might + // BeBook: be convenient to call it sometime before you delete your node + // BeBook: instance, depending on your implementation and circumstances. // first we remove the time source if (fTimeSource) { @@ -148,38 +157,40 @@ BMediaNode::~BMediaNode() fTimeSource = NULL; } - // Attention! We do not unregister TimeSourceObject nodes, - // or delete their control ports, since they are only a - // shadow object, and the real one still exists - if (0 == (fKinds & NODE_KIND_SHADOW_TIMESOURCE)) { + // Attention! We do not unregister TimeSourceObject nodes, or delete their + // control ports, since they are only a shadow object, and the real one + // still exists. + if ((fKinds & NODE_KIND_SHADOW_TIMESOURCE) == 0) { BMediaRoster::Roster()->UnregisterNode(this); if (fControlPort > 0) delete_port(fControlPort); } else { - TRACE("BMediaNode::~BMediaNode: shadow timesource, not unregistering\n"); + TRACE("BMediaNode::~BMediaNode: shadow timesource, not " + "unregistering\n"); } } -/************************************************************* - * public BMediaNode - *************************************************************/ -BMediaNode * +// #pragma mark - public BMediaNode + + +BMediaNode* BMediaNode::Acquire() { CALLED(); - atomic_add(&fRefCount,1); + atomic_add(&fRefCount, 1); return this; } -BMediaNode * +BMediaNode* BMediaNode::Release() { CALLED(); if (atomic_add(&fRefCount, -1) == 1) { - TRACE("BMediaNode::Release() saving node %ld configuration\n", fNodeID); + TRACE("BMediaNode::Release() saving node %ld configuration\n", + fNodeID); MediaRosterEx(BMediaRoster::Roster())->SaveNodeConfiguration(this); if (DeleteHook(this) != B_OK) { ERROR("BMediaNode::Release(): DeleteHook failed\n"); @@ -191,7 +202,7 @@ BMediaNode::Release() } -const char * +const char* BMediaNode::Name() const { CALLED(); @@ -221,7 +232,9 @@ BMediaNode::Node() const CALLED(); media_node temp; temp.node = ID(); - temp.port = ControlPort(); // we *must* call ControlPort(), some derived nodes use it to start the port read thread! + temp.port = ControlPort(); + // we *must* call ControlPort(), some derived nodes use it to start + // the port read thread! temp.kind = Kinds(); return temp; } @@ -235,13 +248,13 @@ BMediaNode::RunMode() const } -BTimeSource * +BTimeSource* BMediaNode::TimeSource() const { PRINT(7, "CALLED BMediaNode::TimeSource()\n"); // return the currently assigned time source - if (fTimeSource != 0) + if (fTimeSource != NULL) return fTimeSource; TRACE("BMediaNode::TimeSource node %ld enter\n", ID()); @@ -249,17 +262,18 @@ BMediaNode::TimeSource() const // If the node doesn't have a time source object, we need to create one. // If the node is still unregistered, we can't call MakeTimeSourceFor(), // but since the node does still have the default system time source, we - // can use GetSystemTimeSource + // can use GetSystemTimeSource(). - BMediaNode *self = const_cast<BMediaNode *>(this); + BMediaNode* self = const_cast<BMediaNode*>(this); // if (fTimeSourceID == NODE_SYSTEM_TIMESOURCE_ID) { // self->fTimeSource = _TimeSourceObjectManager->GetSystemTimeSource(); // } else { - self->fTimeSource = MediaRosterEx(BMediaRoster::Roster())->MakeTimeSourceObject(fTimeSourceID); + self->fTimeSource = MediaRosterEx( + BMediaRoster::Roster())->MakeTimeSourceObject(fTimeSourceID); // } ASSERT(fTimeSource == self->fTimeSource); - if (fTimeSource == 0) { + if (fTimeSource == NULL) { ERROR("BMediaNode::TimeSource: MakeTimeSourceFor failed\n"); } else { ASSERT(fTimeSourceID == fTimeSource->ID()); @@ -280,13 +294,11 @@ BMediaNode::ControlPort() const } -/************************************************************* - * protected BMediaNode - *************************************************************/ +// #pragma mark - protected BMediaNode + status_t -BMediaNode::ReportError(node_error what, - const BMessage *info) +BMediaNode::ReportError(node_error what, const BMessage* info) { CALLED(); @@ -313,27 +325,26 @@ BMediaNode::ReportError(node_error what, status_t -BMediaNode::NodeStopped(bigtime_t whenPerformance) +BMediaNode::NodeStopped(bigtime_t whenPerformanceTime) { UNIMPLEMENTED(); // called by derived classes when they have // finished handling a stop request. // notify anyone who is listening for stop notifications! - BPrivate::media::notifications::NodeStopped(Node(), whenPerformance); + BPrivate::media::notifications::NodeStopped(Node(), whenPerformanceTime); - // XXX If your node is a BBufferProducer, downstream consumers - // XXX will be notified that your node stopped (automatically, no less) - // XXX through the BBufferConsumer::ProducerDataStatus(B_PRODUCER_STOPPED) call. + // BeBook: If your node is a BBufferProducer, downstream consumers + // BeBook: will be notified that your node stopped (automatically, no less) + // BeBook: through the + // BeBook: BBufferConsumer::ProducerDataStatus(B_PRODUCER_STOPPED) call. return B_OK; } void -BMediaNode::TimerExpired(bigtime_t notifyPoint, - int32 cookie, - status_t error) +BMediaNode::TimerExpired(bigtime_t notifyPoint, int32 cookie, status_t error) { UNIMPLEMENTED(); // Used with AddTimer @@ -344,7 +355,7 @@ BMediaNode::TimerExpired(bigtime_t notifyPoint, /* explicit */ -BMediaNode::BMediaNode(const char *name) +BMediaNode::BMediaNode(const char* name) { TRACE("BMediaNode::BMediaNode: name '%s'\n", name); _InitObject(name, NODE_JUST_CREATED_ID, 0); @@ -352,17 +363,18 @@ BMediaNode::BMediaNode(const char *name) status_t -BMediaNode::WaitForMessage(bigtime_t waitUntil, - uint32 flags, - void *_reserved_) +BMediaNode::WaitForMessage(bigtime_t waitUntil, uint32 flags, void* _reserved_) { TRACE("entering: BMediaNode::WaitForMessage()\n"); + // <BeBook> // This function waits until either real time specified by // waitUntil or a message is received on the control port. // The flags are currently unused and should be 0. + // </BeBook> - char data[B_MEDIA_MESSAGE_SIZE]; // about 16 KByte stack used + char data[B_MEDIA_MESSAGE_SIZE]; + // about 16 KByte stack used int32 message; ssize_t size; while (true) { @@ -389,39 +401,41 @@ BMediaNode::WaitForMessage(bigtime_t waitUntil, if (message > NODE_MESSAGE_START && message < NODE_MESSAGE_END) { TRACE("BMediaNode::WaitForMessage calling BMediaNode\n"); - if (B_OK == BMediaNode::HandleMessage(message, data, size)) + if (BMediaNode::HandleMessage(message, data, size) == B_OK) return B_OK; } if (message > PRODUCER_MESSAGE_START && message < PRODUCER_MESSAGE_END) { - if (!fProducerThis) - fProducerThis = dynamic_cast<BBufferProducer *>(this); + if (fProducerThis == NULL) + fProducerThis = dynamic_cast<BBufferProducer*>(this); TRACE("BMediaNode::WaitForMessage calling BBufferProducer %p\n", fProducerThis); - if (fProducerThis && fProducerThis->BBufferProducer::HandleMessage( + if (fProducerThis != NULL + && fProducerThis->BBufferProducer::HandleMessage( message, data, size) == B_OK) { return B_OK; } } if (message > CONSUMER_MESSAGE_START && message < CONSUMER_MESSAGE_END) { - if (!fConsumerThis) - fConsumerThis = dynamic_cast<BBufferConsumer *>(this); + if (fConsumerThis == NULL) + fConsumerThis = dynamic_cast<BBufferConsumer*>(this); TRACE("BMediaNode::WaitForMessage calling BBufferConsumer %p\n", fConsumerThis); - if (fConsumerThis && fConsumerThis->BBufferConsumer::HandleMessage( - message, data, size) == B_OK) { + if (fConsumerThis != NULL + && fConsumerThis->BBufferConsumer::HandleMessage( + message, data, size) == B_OK) { return B_OK; } } if (message > FILEINTERFACE_MESSAGE_START && message < FILEINTERFACE_MESSAGE_END) { - if (!fFileInterfaceThis) - fFileInterfaceThis = dynamic_cast<BFileInterface *>(this); + if (fFileInterfaceThis == NULL) + fFileInterfaceThis = dynamic_cast<BFileInterface*>(this); TRACE("BMediaNode::WaitForMessage calling BFileInterface %p\n", fFileInterfaceThis); - if (fFileInterfaceThis + if (fFileInterfaceThis != NULL && fFileInterfaceThis->BFileInterface::HandleMessage( message, data, size) == B_OK) { return B_OK; @@ -430,11 +444,11 @@ BMediaNode::WaitForMessage(bigtime_t waitUntil, if (message > CONTROLLABLE_MESSAGE_START && message < CONTROLLABLE_MESSAGE_END) { - if (!fControllableThis) - fControllableThis = dynamic_cast<BControllable *>(this); + if (fControllableThis == NULL) + fControllableThis = dynamic_cast<BControllable*>(this); TRACE("BMediaNode::WaitForMessage calling BControllable %p\n", fControllableThis); - if (fControllableThis + if (fControllableThis != NULL && fControllableThis->BControllable::HandleMessage( message, data, size) == B_OK) { return B_OK; @@ -443,18 +457,19 @@ BMediaNode::WaitForMessage(bigtime_t waitUntil, if (message > TIMESOURCE_MESSAGE_START && message < TIMESOURCE_MESSAGE_END) { - if (!fTimeSourceThis) - fTimeSourceThis = dynamic_cast<BTimeSource *>(this); + if (fTimeSourceThis == NULL) + fTimeSourceThis = dynamic_cast<BTimeSource*>(this); TRACE("BMediaNode::WaitForMessage calling BTimeSource %p\n", fTimeSourceThis); - if (fTimeSourceThis && fTimeSourceThis->BTimeSource::HandleMessage( + if (fTimeSourceThis != NULL + && fTimeSourceThis->BTimeSource::HandleMessage( message, data, size) == B_OK) { return B_OK; } } TRACE("BMediaNode::WaitForMessage calling default HandleMessage\n"); - if (B_OK == HandleMessage(message, data, size)) + if (HandleMessage(message, data, size) == B_OK) return B_OK; HandleBadMessage(message, data, size); @@ -464,13 +479,15 @@ BMediaNode::WaitForMessage(bigtime_t waitUntil, /* virtual */ void -BMediaNode::Start(bigtime_t performance_time) +BMediaNode::Start(bigtime_t atPerformanceTime) { CALLED(); + // <BeBook> // This hook function is called when a node is started // by a call to the BMediaRoster. The specified // performanceTime, the time at which the node // should start running, may be in the future. + // </BeBook> // It may be overriden by derived classes. // The BMediaEventLooper class handles this event! // The BMediaNode class does nothing here. @@ -478,14 +495,15 @@ BMediaNode::Start(bigtime_t performance_time) /* virtual */ void -BMediaNode::Stop(bigtime_t performance_time, - bool immediate) +BMediaNode::Stop(bigtime_t atPerformanceTime, bool immediate) { CALLED(); + // <BeBook> // This hook function is called when a node is stopped // by a call to the BMediaRoster. The specified // performanceTime, the time at which the node // should stop running, may be in the future. + // </BeBook> // It may be overriden by derived classes. // The BMediaEventLooper class handles this event! // The BMediaNode class does nothing here. @@ -493,15 +511,16 @@ BMediaNode::Stop(bigtime_t performance_time, /* virtual */ void -BMediaNode::Seek(bigtime_t media_time, - bigtime_t performance_time) +BMediaNode::Seek(bigtime_t toMediaTime, bigtime_t atPerformanceTime) { CALLED(); + // <BeBook> // This hook function is called when a node is asked // to seek to the specified mediaTime by a call to // the BMediaRoster. The specified performanceTime, // the time at which the node should begin the seek // operation, may be in the future. + // </BeBook> // It may be overriden by derived classes. // The BMediaEventLooper class handles this event! // The BMediaNode class does nothing here. @@ -524,8 +543,7 @@ BMediaNode::SetRunMode(run_mode mode) /* virtual */ void -BMediaNode::TimeWarp(bigtime_t at_real_time, - bigtime_t to_performance_time) +BMediaNode::TimeWarp(bigtime_t atRealTime, bigtime_t toPerformanceTime) { CALLED(); // May be overriden by derived classes. @@ -541,33 +559,34 @@ BMediaNode::Preroll() /* virtual */ void -BMediaNode::SetTimeSource(BTimeSource *time_source) +BMediaNode::SetTimeSource(BTimeSource* timeSource) { CALLED(); // this is a hook function, and // may be overriden by derived classes. - if (time_source == NULL || time_source == fTimeSource) + if (timeSource == NULL || timeSource == fTimeSource) return; // we just trip into debugger, code that tries to do this is broken. - debugger("BMediaNode::SetTimeSource() can't be used to set a timesource, use BMediaRoster::SetTimeSourceFor()!\n"); + debugger("BMediaNode::SetTimeSource() can't be used to set a timesource, " + "use BMediaRoster::SetTimeSourceFor()!\n"); } -/************************************************************* - * public BMediaNode - *************************************************************/ + +// #pragma mark - public BMediaNode + /* virtual */ status_t -BMediaNode::HandleMessage(int32 message, - const void *data, - size_t size) +BMediaNode::HandleMessage(int32 message, const void* data, size_t size) { TRACE("BMediaNode::HandleMessage %#lx, node %ld\n", message, fNodeID); + switch (message) { case NODE_FINAL_RELEASE: { - // const node_final_release_command *command = static_cast<const node_final_release_command *>(data); + // const node_final_release_command* command = + // static_cast<const node_final_release_command*>(data); // This is called by the media server to delete the object // after is has been released by all nodes that are using it. // We forward the function to the BMediaRoster, since the @@ -576,17 +595,19 @@ BMediaNode::HandleMessage(int32 message, // reading messages from the port (this thread contex) will // quit, and ~BMediaNode destructor won't be called ever. - TRACE("BMediaNode::HandleMessage NODE_FINAL_RELEASE, this %p\n", this); - BMessage msg(NODE_FINAL_RELEASE); - msg.AddPointer("node", this); - BMediaRoster::Roster()->PostMessage(&msg); + TRACE("BMediaNode::HandleMessage NODE_FINAL_RELEASE, this %p\n", + this); + BMessage finalRelease(NODE_FINAL_RELEASE); + finalRelease.AddPointer("node", this); + BMediaRoster::Roster()->PostMessage(&finalRelease); return B_OK; } 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); TRACE("BMediaNode::HandleMessage NODE_START, node %ld\n", fNodeID); Start(command->performance_time); return B_OK; @@ -594,7 +615,8 @@ BMediaNode::HandleMessage(int32 message, 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); TRACE("BMediaNode::HandleMessage NODE_STOP, node %ld\n", fNodeID); Stop(command->performance_time, command->immediate); return B_OK; @@ -602,7 +624,8 @@ BMediaNode::HandleMessage(int32 message, 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); TRACE("BMediaNode::HandleMessage NODE_SEEK, node %ld\n", fNodeID); Seek(command->media_time, command->performance_time); return B_OK; @@ -610,8 +633,10 @@ BMediaNode::HandleMessage(int32 message, case NODE_SET_RUN_MODE: { - const node_set_run_mode_command *command = static_cast<const node_set_run_mode_command *>(data); - TRACE("BMediaNode::HandleMessage NODE_SET_RUN_MODE, node %ld\n", fNodeID); + const node_set_run_mode_command* command = + static_cast<const node_set_run_mode_command*>(data); + TRACE("BMediaNode::HandleMessage NODE_SET_RUN_MODE, node %ld\n", + fNodeID); // when changing this, also change PRODUCER_SET_RUN_MODE_DELAY fRunMode = command->mode; SetRunMode(fRunMode); @@ -620,35 +645,40 @@ BMediaNode::HandleMessage(int32 message, case NODE_TIME_WARP: { - const node_time_warp_command *command = static_cast<const node_time_warp_command *>(data); - TRACE("BMediaNode::HandleMessage NODE_TIME_WARP, node %ld\n", fNodeID); + const node_time_warp_command* command = + static_cast<const node_time_warp_command*>(data); + TRACE("BMediaNode::HandleMessage NODE_TIME_WARP, node %ld\n", + fNodeID); TimeWarp(command->at_real_time, command->to_performance_time); return B_OK; } case NODE_PREROLL: { - TRACE("BMediaNode::HandleMessage NODE_PREROLL, node %ld\n", fNodeID); + TRACE("BMediaNode::HandleMessage NODE_PREROLL, node %ld\n", + fNodeID); Preroll(); return B_OK; } case NODE_SET_TIMESOURCE: { - 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); - TRACE("BMediaNode::HandleMessage NODE_SET_TIMESOURCE, node %ld, timesource %ld enter\n", fNodeID, command->timesource_id); + TRACE("BMediaNode::HandleMessage NODE_SET_TIMESOURCE, node %ld, " + "timesource %ld enter\n", fNodeID, command->timesource_id); fTimeSourceID = command->timesource_id; - if (fTimeSource) { + if (fTimeSource != NULL) { // as this node already had a timesource, we need // we need to remove this node from time source control fTimeSource->RemoveMe(this); // Then release the time source fTimeSource->Release(); // force next call to TimeSource() to create a new object - fTimeSource = 0; + fTimeSource = NULL; } // create new time source object @@ -657,15 +687,18 @@ BMediaNode::HandleMessage(int32 message, // any derived class SetTimeSource(fTimeSource); - TRACE("BMediaNode::HandleMessage NODE_SET_TIMESOURCE, node %ld, timesource %ld leave\n", fNodeID, command->timesource_id); + TRACE("BMediaNode::HandleMessage NODE_SET_TIMESOURCE, node %ld, " + "timesource %ld leave\n", fNodeID, command->timesource_id); return B_OK; } case NODE_GET_TIMESOURCE: { - const node_get_timesource_request *request = static_cast<const node_get_timesource_request *>(data); - TRACE("BMediaNode::HandleMessage NODE_GET_TIMESOURCE, node %ld\n", fNodeID); + const node_get_timesource_request* request = + static_cast<const node_get_timesource_request*>(data); + TRACE("BMediaNode::HandleMessage NODE_GET_TIMESOURCE, node %ld\n", + fNodeID); node_get_timesource_reply reply; reply.timesource_id = fTimeSourceID; request->SendReply(B_OK, &reply, sizeof(reply)); @@ -674,8 +707,10 @@ BMediaNode::HandleMessage(int32 message, case NODE_REQUEST_COMPLETED: { - const node_request_completed_command *command = static_cast<const node_request_completed_command *>(data); - TRACE("BMediaNode::HandleMessage NODE_REQUEST_COMPLETED, node %ld\n", fNodeID); + const node_request_completed_command* command = + static_cast<const node_request_completed_command*>(data); + TRACE("BMediaNode::HandleMessage NODE_REQUEST_COMPLETED, node " + "%ld\n", fNodeID); RequestCompleted(command->info); return B_OK; } @@ -686,13 +721,12 @@ BMediaNode::HandleMessage(int32 message, void -BMediaNode::HandleBadMessage(int32 code, - const void *buffer, - size_t size) +BMediaNode::HandleBadMessage(int32 code, const void* buffer, size_t size) { CALLED(); - TRACE("BMediaNode::HandleBadMessage: code %#08lx, buffer %p, size %ld\n", code, buffer, size); + TRACE("BMediaNode::HandleBadMessage: code %#08lx, buffer %p, size %ld\n", + code, buffer, size); if (code < NODE_MESSAGE_START || code > TIMESOURCE_MESSAGE_END) { ERROR("BMediaNode::HandleBadMessage: unknown code!\n"); } else { @@ -700,7 +734,7 @@ BMediaNode::HandleBadMessage(int32 code, * messages targetted to the wrong node should be handled * by returning an error, not by stalling the sender. */ - const request_data *request = static_cast<const request_data *>(buffer); + const request_data* request = static_cast<const request_data*>(buffer); reply_data reply; request->SendReply(B_ERROR, &reply, sizeof(reply)); } @@ -716,48 +750,51 @@ BMediaNode::AddNodeKind(uint64 kind) } -void * +void* BMediaNode::operator new(size_t size) { CALLED(); return ::operator new(size); } -void * -BMediaNode::operator new(size_t size, - const nothrow_t &) throw() + +void* +BMediaNode::operator new(size_t size, const nothrow_t&) throw() { CALLED(); return ::operator new(size, nothrow); } + void -BMediaNode::operator delete(void *ptr) +BMediaNode::operator delete(void* ptr) { CALLED(); ::operator delete(ptr); } + void -BMediaNode::operator delete(void * ptr, - const nothrow_t &) throw() +BMediaNode::operator delete(void* ptr, const nothrow_t&) throw() { CALLED(); ::operator delete(ptr, nothrow); } -/************************************************************* - * protected BMediaNode - *************************************************************/ + + +// #pragma mark - protected BMediaNode + /* virtual */ status_t -BMediaNode::RequestCompleted(const media_request_info &info) +BMediaNode::RequestCompleted(const media_request_info& info) { CALLED(); - // This function is called whenever a request issued by the node is completed. + // BeBook: This function is called whenever a request issued by the node is + // BeBook: completed. // May be overriden by derived classes. - // info.change_tag can be used to match up requests against - // the accompaning calles from + // info.change tag can be used to match up requests against + // the accompaning calls from // BBufferConsumer::RequestFormatChange() // BBufferConsumer::SetOutputBuffersFor() // BBufferConsumer::SetOutputEnabled() @@ -765,9 +802,50 @@ BMediaNode::RequestCompleted(const media_request_info &info) return B_OK; } -/************************************************************* - * private BMediaNode - *************************************************************/ + +/* virtual */ status_t +BMediaNode::DeleteHook(BMediaNode* node) +{ + CALLED(); + delete this; + // delete "this" or "node", both are the same + return B_OK; +} + + +/* virtual */ void +BMediaNode::NodeRegistered() +{ + CALLED(); + // The Media Server calls this hook function after the node has been + // registered. May be overriden by derived classes. +} + + +// #pragma mark - public BMediaNode + + +/* virtual */ status_t +BMediaNode::GetNodeAttributes(media_node_attribute* outAttributes, + size_t inMaxCount) +{ + UNIMPLEMENTED(); + + return B_ERROR; +} + + +/* virtual */ status_t +BMediaNode::AddTimer(bigtime_t atPerformanceTime, int32 cookie) +{ + UNIMPLEMENTED(); + + return B_ERROR; +} + + +// #pragma mark - private BMediaNode + int32 BMediaNode::IncrementChangeTag() @@ -775,7 +853,8 @@ BMediaNode::IncrementChangeTag() CALLED(); // Only present in BeOS R4 // Obsoleted in BeOS R4.5 and later - // "updates the change tag, so that downstream consumers know that the node is in a new state." + // "updates the change tag, so that downstream consumers know that the node + // is in a new state." // not supported, only for binary compatibility return 0; } @@ -807,7 +886,7 @@ BMediaNode::MintChangeTag() status_t -BMediaNode::ApplyChangeTag(int32 previously_reserved) +BMediaNode::ApplyChangeTag(int32 previouslyReserved) { UNIMPLEMENTED(); // Only present in BeOS R4 @@ -819,68 +898,25 @@ BMediaNode::ApplyChangeTag(int32 previously_reserved) return B_OK; } -/************************************************************* - * protected BMediaNode - *************************************************************/ -/* virtual */ status_t -BMediaNode::DeleteHook(BMediaNode *node) -{ - CALLED(); - delete this; // delete "this" or "node", both are the same - return B_OK; -} +status_t BMediaNode::_Reserved_MediaNode_0(void*) { return B_ERROR; } +status_t BMediaNode::_Reserved_MediaNode_1(void*) { return B_ERROR; } +status_t BMediaNode::_Reserved_MediaNode_2(void*) { return B_ERROR; } +status_t BMediaNode::_Reserved_MediaNode_3(void*) { return B_ERROR; } +status_t BMediaNode::_Reserved_MediaNode_4(void*) { return B_ERROR; } +status_t BMediaNode::_Reserved_MediaNode_5(void*) { return B_ERROR; } +status_t BMediaNode::_Reserved_MediaNode_6(void*) { return B_ERROR; } +status_t BMediaNode::_Reserved_MediaNode_7(void*) { return B_ERROR; } +status_t BMediaNode::_Reserved_MediaNode_8(void*) { return B_ERROR; } +status_t BMediaNode::_Reserved_MediaNode_9(void*) { return B_ERROR; } +status_t BMediaNode::_Reserved_MediaNode_10(void*) { return B_ERROR; } +status_t BMediaNode::_Reserved_MediaNode_11(void*) { return B_ERROR; } +status_t BMediaNode::_Reserved_MediaNode_12(void*) { return B_ERROR; } +status_t BMediaNode::_Reserved_MediaNode_13(void*) { return B_ERROR; } +status_t BMediaNode::_Reserved_MediaNode_14(void*) { return B_ERROR; } +status_t BMediaNode::_Reserved_MediaNode_15(void*) { return B_ERROR; } -/* virtual */ void -BMediaNode::NodeRegistered() -{ - CALLED(); - // The Media Server calls this hook function after the node has been registered. - // May be overriden by derived classes. -} - -/************************************************************* - * public BMediaNode - *************************************************************/ - -/* virtual */ status_t -BMediaNode::GetNodeAttributes(media_node_attribute *outAttributes, - size_t inMaxCount) -{ - UNIMPLEMENTED(); - - return B_ERROR; -} - - -/* virtual */ status_t -BMediaNode::AddTimer(bigtime_t at_performance_time, - int32 cookie) -{ - UNIMPLEMENTED(); - - return B_ERROR; -} - - -status_t BMediaNode::_Reserved_MediaNode_0(void *) { return B_ERROR; } -status_t BMediaNode::_Reserved_MediaNode_1(void *) { return B_ERROR; } -status_t BMediaNode::_Reserved_MediaNode_2(void *) { return B_ERROR; } -status_t BMediaNode::_Reserved_MediaNode_3(void *) { return B_ERROR; } -status_t BMediaNode::_Reserved_MediaNode_4(void *) { return B_ERROR; } -status_t BMediaNode::_Reserved_MediaNode_5(void *) { return B_ERROR; } -status_t BMediaNode::_Reserved_MediaNode_6(void *) { return B_ERROR; } -status_t BMediaNode::_Reserved_MediaNode_7(void *) { return B_ERROR; } -status_t BMediaNode::_Reserved_MediaNode_8(void *) { return B_ERROR; } -status_t BMediaNode::_Reserved_MediaNode_9(void *) { return B_ERROR; } -status_t BMediaNode::_Reserved_MediaNode_10(void *) { return B_ERROR; } -status_t BMediaNode::_Reserved_MediaNode_11(void *) { return B_ERROR; } -status_t BMediaNode::_Reserved_MediaNode_12(void *) { return B_ERROR; } -status_t BMediaNode::_Reserved_MediaNode_13(void *) { return B_ERROR; } -status_t BMediaNode::_Reserved_MediaNode_14(void *) { return B_ERROR; } -status_t BMediaNode::_Reserved_MediaNode_15(void *) { return B_ERROR; } - /* private unimplemented BMediaNode::BMediaNode() @@ -888,15 +924,24 @@ BMediaNode::BMediaNode(const BMediaNode &clone) BMediaNode &BMediaNode::operator=(const BMediaNode &clone) */ + +BMediaNode::BMediaNode(const char* name, media_node_id id, uint32 kinds) +{ + TRACE("BMediaNode::BMediaNode: name '%s', nodeid %ld, kinds %#lx\n", + name, id, kinds); + _InitObject(name, id, kinds); +} + + void -BMediaNode::_InitObject(const char *name, media_node_id id, uint64 kinds) +BMediaNode::_InitObject(const char* name, media_node_id id, uint64 kinds) { TRACE("BMediaNode::_InitObject: nodeid %ld, this %p\n", id, this); fNodeID = id; fRefCount = 1; fName[0] = 0; - if (name) + if (name != NULL) strlcpy(fName, name, B_MEDIA_NAME_LENGTH); fRunMode = B_INCREASE_LATENCY; fKinds = kinds; @@ -919,18 +964,8 @@ BMediaNode::_InitObject(const char *name, media_node_id id, uint64 kinds) } -BMediaNode::BMediaNode(const char *name, - media_node_id id, - uint32 kinds) -{ - TRACE("BMediaNode::BMediaNode: name '%s', nodeid %ld, kinds %#lx\n", name, id, kinds); - _InitObject(name, id, kinds); -} - +// #pragma mark - protected BMediaNode -/************************************************************* - * protected BMediaNode - *************************************************************/ /* static */ int32 BMediaNode::NewChangeTag() @@ -946,5 +981,5 @@ BMediaNode::NewChangeTag() // BBufferConsumer::SetOutputBuffersFor() // BBufferConsumer::SetOutputEnabled() // BBufferConsumer::SetVideoClippingFor() - return atomic_add(&BMediaNode::_m_changeTag,1); + return atomic_add(&BMediaNode::_m_changeTag, 1); } diff --git a/src/kits/media/TimedEventQueue.cpp b/src/kits/media/TimedEventQueue.cpp index cf270ce..ececc7c 100644 --- a/src/kits/media/TimedEventQueue.cpp +++ b/src/kits/media/TimedEventQueue.cpp @@ -5,13 +5,15 @@ ***********************************************************************/ #include <TimedEventQueue.h> + #include <string.h> -#include "TimedEventQueuePrivate.h" + #include "debug.h" +#include "TimedEventQueuePrivate.h" + + +// #pragma mark - struct media_timed_event -/************************************************************* - * struct media_timed_event - *************************************************************/ media_timed_event::media_timed_event() { @@ -20,8 +22,7 @@ media_timed_event::media_timed_event() } -media_timed_event::media_timed_event(bigtime_t inTime, - int32 inType) +media_timed_event::media_timed_event(bigtime_t inTime, int32 inType) { CALLED(); memset(this, 0, sizeof(*this)); @@ -30,10 +31,8 @@ media_timed_event::media_timed_event(bigtime_t inTime, } -media_timed_event::media_timed_event(bigtime_t inTime, - int32 inType, - void *inPointer, - uint32 inCleanup) +media_timed_event::media_timed_event(bigtime_t inTime, int32 inType, + void* inPointer, uint32 inCleanup) { CALLED(); memset(this, 0, sizeof(*this)); @@ -44,14 +43,9 @@ media_timed_event::media_timed_event(bigtime_t inTime, } -media_timed_event::media_timed_event(bigtime_t inTime, - int32 inType, - void *inPointer, - uint32 inCleanup, - int32 inData, - int64 inBigdata, - char *inUserData, - size_t dataSize) +media_timed_event::media_timed_event(bigtime_t inTime, int32 inType, + void* inPointer, uint32 inCleanup, int32 inData, int64 inBigdata, + char* inUserData, size_t dataSize) { CALLED(); memset(this, 0, sizeof(*this)); @@ -61,11 +55,12 @@ media_timed_event::media_timed_event(bigtime_t inTime, cleanup = inCleanup; data = inData; bigdata = inBigdata; - memcpy(user_data,inUserData,min_c(sizeof(media_timed_event::user_data),dataSize)); + memcpy(user_data, inUserData, + min_c(sizeof(media_timed_event::user_data), dataSize)); } -media_timed_event::media_timed_event(const media_timed_event &clone) +media_timed_event::media_timed_event(const media_timed_event& clone) { CALLED(); *this = clone; @@ -73,7 +68,7 @@ media_timed_event::media_timed_event(const media_timed_event &clone) void -media_timed_event::operator=(const media_timed_event &clone) +media_timed_event::operator=(const media_timed_event& clone) { CALLED(); memcpy(this, &clone, sizeof(*this)); @@ -85,58 +80,64 @@ media_timed_event::~media_timed_event() CALLED(); } -/************************************************************* - * global operators - *************************************************************/ -bool operator==(const media_timed_event & a, const media_timed_event & b) +// #pragma mark - global operators + + +bool +operator==(const media_timed_event& a, const media_timed_event& b) { CALLED(); - return (0 == memcmp(&a,&b,sizeof(media_timed_event))); + return (memcmp(&a, &b, sizeof(media_timed_event)) == 0); } -bool operator!=(const media_timed_event & a, const media_timed_event & b) + +bool +operator!=(const media_timed_event& a, const media_timed_event& b) { CALLED(); - return (0 != memcmp(&a,&b,sizeof(media_timed_event))); + return (memcmp(&a, &b, sizeof(media_timed_event)) != 0); } -bool operator<(const media_timed_event & a, const media_timed_event & b) + +bool +operator<(const media_timed_event& a, const media_timed_event& b) { CALLED(); return a.event_time < b.event_time; } -bool operator>(const media_timed_event & a, const media_timed_event &b) + +bool +operator>(const media_timed_event& a, const media_timed_event& b) { CALLED(); return a.event_time > b.event_time; } -/************************************************************* - * public BTimedEventQueue - *************************************************************/ +// #pragma mark - public BTimedEventQueue -void * -BTimedEventQueue::operator new(size_t s) +void* +BTimedEventQueue::operator new(size_t size) { CALLED(); - return ::operator new(s); + return ::operator new(size); } void -BTimedEventQueue::operator delete(void *p, size_t s) +BTimedEventQueue::operator delete(void* ptr, size_t size) { CALLED(); - return ::operator delete(p); + return ::operator delete(ptr); } -BTimedEventQueue::BTimedEventQueue() : - fImp(new _event_queue_imp) +BTimedEventQueue::BTimedEventQueue() + : + fImplementation(new _event_queue_imp) { CALLED(); } @@ -145,31 +146,31 @@ BTimedEventQueue::BTimedEventQueue() : BTimedEventQueue::~BTimedEventQueue() { CALLED(); - delete fImp; + delete fImplementation; } status_t -BTimedEventQueue::AddEvent(const media_timed_event &event) +BTimedEventQueue::AddEvent(const media_timed_event& event) { CALLED(); - return fImp->AddEvent(event); + return fImplementation->AddEvent(event); } status_t -BTimedEventQueue::RemoveEvent(const media_timed_event *event) +BTimedEventQueue::RemoveEvent(const media_timed_event* event) { CALLED(); - return fImp->RemoveEvent(event); + return fImplementation->RemoveEvent(event); } status_t -BTimedEventQueue::RemoveFirstEvent(media_timed_event *outEvent) +BTimedEventQueue::RemoveFirstEvent(media_timed_event* outEvent) { CALLED(); - return fImp->RemoveFirstEvent(outEvent); + return fImplementation->RemoveFirstEvent(outEvent); } @@ -177,7 +178,7 @@ bool BTimedEventQueue::HasEvents() const { CALLED(); - return fImp->HasEvents(); + return fImplementation->HasEvents(); } @@ -185,15 +186,15 @@ int32 BTimedEventQueue::EventCount() const { CALLED(); - return fImp->EventCount(); + return fImplementation->EventCount(); } -const media_timed_event * +const media_timed_event* BTimedEventQueue::FirstEvent() const { CALLED(); - return fImp->FirstEvent(); + return fImplementation->FirstEvent(); } @@ -201,15 +202,15 @@ bigtime_t BTimedEventQueue::FirstEventTime() const { CALLED(); - return fImp->FirstEventTime(); + return fImplementation->FirstEventTime(); } -const media_timed_event * +const media_timed_event* BTimedEventQueue::LastEvent() const { CALLED(); - return fImp->LastEvent(); + return fImplementation->LastEvent(); } @@ -217,56 +218,51 @@ bigtime_t BTimedEventQueue::LastEventTime() const { CALLED(); - return fImp->LastEventTime(); + return fImplementation->LastEventTime(); } -const media_timed_event * -BTimedEventQueue::FindFirstMatch(bigtime_t eventTime, - time_direction direction, - bool inclusive, - int32 eventType) +const media_timed_event* +BTimedEventQueue::FindFirstMatch(bigtime_t eventTime, time_direction direction, + bool inclusive, int32 eventType) { CALLED(); - return fImp->FindFirstMatch(eventTime, direction, inclusive, eventType); + return fImplementation->FindFirstMatch(eventTime, direction, inclusive, + eventType); } status_t -BTimedEventQueue::DoForEach(for_each_hook hook, - void *context, - bigtime_t eventTime, - time_direction direction, - bool inclusive, - int32 eventType) +BTimedEventQueue::DoForEach(for_each_hook hook, void *context, + bigtime_t eventTime, time_direction direction, bool inclusive, + int32 eventType) { CALLED(); - return fImp->DoForEach(hook, context, eventTime, direction, inclusive, eventType); + return fImplementation->DoForEach(hook, context, eventTime, direction, + inclusive, eventType); } void -BTimedEventQueue::SetCleanupHook(cleanup_hook hook, - void *context) +BTimedEventQueue::SetCleanupHook(cleanup_hook hook, void* context) { CALLED(); - fImp->SetCleanupHook(hook, context); + fImplementation->SetCleanupHook(hook, context); } status_t -BTimedEventQueue::FlushEvents(bigtime_t eventTime, - time_direction direction, - bool inclusive, - int32 eventType) +BTimedEventQueue::FlushEvents(bigtime_t eventTime, time_direction direction, + bool inclusive, int32 eventType) { CALLED(); - return fImp->FlushEvents(eventTime, direction, inclusive, eventType); + return fImplementation->FlushEvents(eventTime, direction, inclusive, + eventType); } -/************************************************************* - * private BTimedEventQueue - *************************************************************/ + +// #pragma mark - private BTimedEventQueue + /* // unimplemented @@ -274,27 +270,28 @@ BTimedEventQueue::BTimedEventQueue(const BTimedEventQueue &other) BTimedEventQueue &BTimedEventQueue::operator=(const BTimedEventQueue &other) */ -status_t BTimedEventQueue::_Reserved_BTimedEventQueue_0(void *, ...) { return B_ERROR; } -status_t BTimedEventQueue::_Reserved_BTimedEventQueue_1(void *, ...) { return B_ERROR; } -status_t BTimedEventQueue::_Reserved_BTimedEventQueue_2(void *, ...) { return B_ERROR; } -status_t BTimedEventQueue::_Reserved_BTimedEventQueue_3(void *, ...) { return B_ERROR; } -status_t BTimedEventQueue::_Reserved_BTimedEventQueue_4(void *, ...) { return B_ERROR; } -status_t BTimedEventQueue::_Reserved_BTimedEventQueue_5(void *, ...) { return B_ERROR; } -status_t BTimedEventQueue::_Reserved_BTimedEventQueue_6(void *, ...) { return B_ERROR; } -status_t BTimedEventQueue::_Reserved_BTimedEventQueue_7(void *, ...) { return B_ERROR; } -status_t BTimedEventQueue::_Reserved_BTimedEventQueue_8(void *, ...) { return B_ERROR; } -status_t BTimedEventQueue::_Reserved_BTimedEventQueue_9(void *, ...) { return B_ERROR; } -status_t BTimedEventQueue::_Reserved_BTimedEventQueue_10(void *, ...) { return B_ERROR; } -status_t BTimedEventQueue::_Reserved_BTimedEventQueue_11(void *, ...) { return B_ERROR; } -status_t BTimedEventQueue::_Reserved_BTimedEventQueue_12(void *, ...) { return B_ERROR; } -status_t BTimedEventQueue::_Reserved_BTimedEventQueue_13(void *, ...) { return B_ERROR; } -status_t BTimedEventQueue::_Reserved_BTimedEventQueue_14(void *, ...) { return B_ERROR; } -status_t BTimedEventQueue::_Reserved_BTimedEventQueue_15(void *, ...) { return B_ERROR; } -status_t BTimedEventQueue::_Reserved_BTimedEventQueue_16(void *, ...) { return B_ERROR; } -status_t BTimedEventQueue::_Reserved_BTimedEventQueue_17(void *, ...) { return B_ERROR; } -status_t BTimedEventQueue::_Reserved_BTimedEventQueue_18(void *, ...) { return B_ERROR; } -status_t BTimedEventQueue::_Reserved_BTimedEventQueue_19(void *, ...) { return B_ERROR; } -status_t BTimedEventQueue::_Reserved_BTimedEventQueue_20(void *, ...) { return B_ERROR; } -status_t BTimedEventQueue::_Reserved_BTimedEventQueue_21(void *, ...) { return B_ERROR; } -status_t BTimedEventQueue::_Reserved_BTimedEventQueue_22(void *, ...) { return B_ERROR; } -status_t BTimedEventQueue::_Reserved_BTimedEventQueue_23(void *, ...) { return B_ERROR; } + +status_t BTimedEventQueue::_Reserved_BTimedEventQueue_0(void*, ...) { return B_ERROR; } +status_t BTimedEventQueue::_Reserved_BTimedEventQueue_1(void*, ...) { return B_ERROR; } +status_t BTimedEventQueue::_Reserved_BTimedEventQueue_2(void*, ...) { return B_ERROR; } +status_t BTimedEventQueue::_Reserved_BTimedEventQueue_3(void*, ...) { return B_ERROR; } +status_t BTimedEventQueue::_Reserved_BTimedEventQueue_4(void*, ...) { return B_ERROR; } +status_t BTimedEventQueue::_Reserved_BTimedEventQueue_5(void*, ...) { return B_ERROR; } +status_t BTimedEventQueue::_Reserved_BTimedEventQueue_6(void*, ...) { return B_ERROR; } +status_t BTimedEventQueue::_Reserved_BTimedEventQueue_7(void*, ...) { return B_ERROR; } +status_t BTimedEventQueue::_Reserved_BTimedEventQueue_8(void*, ...) { return B_ERROR; } +status_t BTimedEventQueue::_Reserved_BTimedEventQueue_9(void*, ...) { return B_ERROR; } +status_t BTimedEventQueue::_Reserved_BTimedEventQueue_10(void*, ...) { return B_ERROR; } +status_t BTimedEventQueue::_Reserved_BTimedEventQueue_11(void*, ...) { return B_ERROR; } +status_t BTimedEventQueue::_Reserved_BTimedEventQueue_12(void*, ...) { return B_ERROR; } +status_t BTimedEventQueue::_Reserved_BTimedEventQueue_13(void*, ...) { return B_ERROR; } +status_t BTimedEventQueue::_Reserved_BTimedEventQueue_14(void*, ...) { return B_ERROR; } +status_t BTimedEventQueue::_Reserved_BTimedEventQueue_15(void*, ...) { return B_ERROR; } +status_t BTimedEventQueue::_Reserved_BTimedEventQueue_16(void*, ...) { return B_ERROR; } +status_t BTimedEventQueue::_Reserved_BTimedEventQueue_17(void*, ...) { return B_ERROR; } +status_t BTimedEventQueue::_Reserved_BTimedEventQueue_18(void*, ...) { return B_ERROR; } +status_t BTimedEventQueue::_Reserved_BTimedEventQueue_19(void*, ...) { return B_ERROR; } +status_t BTimedEventQueue::_Reserved_BTimedEventQueue_20(void*, ...) { return B_ERROR; } +status_t BTimedEventQueue::_Reserved_BTimedEventQueue_21(void*, ...) { return B_ERROR; } +status_t BTimedEventQueue::_Reserved_BTimedEventQueue_22(void*, ...) { return B_ERROR; } +status_t BTimedEventQueue::_Reserved_BTimedEventQueue_23(void*, ...) { return B_ERROR; } diff --git a/src/kits/media/TimedEventQueuePrivate.cpp b/src/kits/media/TimedEventQueuePrivate.cpp index 99fbeed..ad3e7d5 100644 --- a/src/kits/media/TimedEventQueuePrivate.cpp +++ b/src/kits/media/TimedEventQueuePrivate.cpp @@ -27,19 +27,25 @@ * */ -/* Implements _event_queue_imp used by BTimedEventQueue, not thread save! +/* Implements _event_queue_imp used by BTimedEventQueue, not thread safe! */ -#include <TimedEventQueue.h> + + +#include "TimedEventQueuePrivate.h" + #include <Autolock.h> #include <Buffer.h> #include <InterfaceDefs.h> //defines B_DELETE -#include "TimedEventQueuePrivate.h" -#include "Debug.h" +#include <TimedEventQueue.h> + #include "debug.h" +#include "Debug.h" #include <string.h> -_event_queue_imp::_event_queue_imp() : + +_event_queue_imp::_event_queue_imp() + : fLock(new BLocker("BTimedEventQueue locker")), fEventCount(0), fFirstEntry(NULL), @@ -52,75 +58,76 @@ _event_queue_imp::_event_queue_imp() : _event_queue_imp::~_event_queue_imp() { - event_queue_entry *entry; + event_queue_entry* entry; entry = fFirstEntry; while (entry) { - event_queue_entry *deleteme; - deleteme = entry; + event_queue_entry* deleteMe; + deleteMe = entry; entry = entry->next; - delete deleteme; + delete deleteMe; } delete fLock; } status_t -_event_queue_imp::AddEvent(const media_timed_event &event) +_event_queue_imp::AddEvent(const media_timed_event& event) { BAutolock lock(fLock); -// printf(" adding %12Ld at %12Ld\n", event.event_time, system_time()); +// printf(" adding %12Ld at %12Ld\n", event.event_time, +// system_time()); - if (event.type <= 0) { + if (event.type <= 0) return B_BAD_VALUE; - } - //create a new queue + // create a new queue if (fFirstEntry == NULL) { ASSERT(fEventCount == 0); ASSERT(fLastEntry == NULL); fFirstEntry = fLastEntry = new event_queue_entry; fFirstEntry->event = event; - fFirstEntry->prev = NULL; + fFirstEntry->previous = NULL; fFirstEntry->next = NULL; fEventCount++; return B_OK; } - //insert at queue begin + // insert at queue begin if (fFirstEntry->event.event_time >= event.event_time) { - event_queue_entry *newentry = new event_queue_entry; - newentry->event = event; - newentry->prev = NULL; - newentry->next = fFirstEntry; - fFirstEntry->prev = newentry; - fFirstEntry = newentry; + event_queue_entry* newEntry = new event_queue_entry; + newEntry->event = event; + newEntry->previous = NULL; + newEntry->next = fFirstEntry; + fFirstEntry->previous = newEntry; + fFirstEntry = newEntry; fEventCount++; return B_OK; } - //insert at queue end + // insert at queue end if (fLastEntry->event.event_time <= event.event_time) { - event_queue_entry *newentry = new event_queue_entry; - newentry->event = event; - newentry->prev = fLastEntry; - newentry->next = NULL; - fLastEntry->next = newentry; - fLastEntry = newentry; + event_queue_entry* newEntry = new event_queue_entry; + newEntry->event = event; + newEntry->previous = fLastEntry; + newEntry->next = NULL; + fLastEntry->next = newEntry; + fLastEntry = newEntry; fEventCount++; return B_OK; } - //insert into the queue - for (event_queue_entry *entry = fLastEntry; entry; entry = entry->prev) { + // insert into the queue + for (event_queue_entry* entry = fLastEntry; entry; + entry = entry->previous) { if (entry->event.event_time <= event.event_time) { - //insert after entry - event_queue_entry *newentry = new event_queue_entry; - newentry->event = event; - newentry->prev = entry; - newentry->next = entry->next; - (entry->next)->prev = newentry; - entry->next = newentry; + // insert after entry + event_queue_entry* newEntry = new event_queue_entry; + newEntry->event = event; + newEntry->previous = entry; + newEntry->next = entry->next; + (entry->next)->previous = newEntry; + entry->next = newEntry; fEventCount++; return B_OK; } @@ -132,14 +139,14 @@ _event_queue_imp::AddEvent(const media_timed_event &event) status_t -_event_queue_imp::RemoveEvent(const media_timed_event *event) +_event_queue_imp::RemoveEvent(const media_timed_event* event) { BAutolock lock(fLock); - for (event_queue_entry *entry = fFirstEntry; entry; entry = entry->next) { + for (event_queue_entry* entry = fFirstEntry; entry; entry = entry->next) { if (entry->event == *event) { // No cleanup here - RemoveEntry(entry); + _RemoveEntry(entry); return B_OK; } } @@ -149,7 +156,7 @@ _event_queue_imp::RemoveEvent(const media_timed_event *event) status_t -_event_queue_imp::RemoveFirstEvent(media_timed_event * outEvent) +_event_queue_imp::RemoveFirstEvent(media_timed_event* outEvent) { BAutolock lock(fLock); @@ -159,11 +166,10 @@ _event_queue_imp::RemoveFirstEvent(media_timed_event * outEvent) if (outEvent != 0) { // No cleanup here *outEvent = fFirstEntry->event; - } else { - CleanupEvent(&fFirstEntry->event); - } + } else + _CleanupEvent(&fFirstEntry->event); - RemoveEntry(fFirstEntry); + _RemoveEntry(fFirstEntry); return B_OK; } @@ -179,14 +185,14 @@ _event_queue_imp::HasEvents() const int32 _event_queue_imp::EventCount() const { - #if DEBUG > 1 +#if DEBUG > 1 Dump(); - #endif +#endif return fEventCount; } -const media_timed_event * +const media_timed_event* _event_queue_imp::FirstEvent() const { return fFirstEntry ? &fFirstEntry->event : NULL; @@ -200,7 +206,7 @@ _event_queue_imp::FirstEventTime() const } -const media_timed_event * +const media_timed_event* _event_queue_imp::LastEvent() const { return fLastEntry ? &fLastEntry->event : NULL; @@ -214,54 +220,58 @@ _event_queue_imp::LastEventTime() const } -const media_timed_event * +const media_timed_event* _event_queue_imp::FindFirstMatch(bigtime_t eventTime, - BTimedEventQueue::time_direction direction, - bool inclusive, - int32 eventType) + BTimedEventQueue::time_direction direction, bool inclusive, + int32 eventType) { - event_queue_entry *end; - event_queue_entry *entry; + event_queue_entry* end; + event_queue_entry* entry; BAutolock lock(fLock); switch (direction) { case BTimedEventQueue::B_ALWAYS: for (entry = fFirstEntry; entry; entry = entry->next) { - if (eventType == BTimedEventQueue::B_ANY_EVENT || eventType == entry->event.type) + if (eventType == BTimedEventQueue::B_ANY_EVENT + || eventType == entry->event.type) return &entry->event; } return NULL; case BTimedEventQueue::B_BEFORE_TIME: - end = GetEnd_BeforeTime(eventTime, inclusive); + end = _GetEndBeforeTime(eventTime, inclusive); if (end == NULL) return NULL; end = end->next; for (entry = fFirstEntry; entry != end; entry = entry->next) { - if (eventType == BTimedEventQueue::B_ANY_EVENT || eventType == entry->event.type) { + if (eventType == BTimedEventQueue::B_ANY_EVENT + || eventType == entry->event.type) { return &entry->event; } } return NULL; case BTimedEventQueue::B_AT_TIME: - { - bool found_time = false; - for (entry = fFirstEntry; entry; entry = entry->next) { - if (eventTime == entry->event.event_time) { - found_time = true; - if (eventType == BTimedEventQueue::B_ANY_EVENT || eventType == entry->event.type) - return &entry->event; - } else if (found_time) - return NULL; - } - return NULL; + { + bool foundTime = false; + for (entry = fFirstEntry; entry; entry = entry->next) { + if (eventTime == entry->event.event_time) { + foundTime = true; + if (eventType == BTimedEventQueue::B_ANY_EVENT + || eventType == entry->event.type) [ *** diff truncated: 621 lines dropped *** ] ############################################################################ Commit: 77460c05e96bdb866521dcddc4d962d979ec7133 Author: Julian Harnath <github@xxxxxxxxxxxx> Date: Sat Oct 19 10:21:41 2013 UTC Introduce type perf_time_t and use it throughout the MediaKit. * To make it easier to discern whether a parameter or variable holds a time value in real or performance time, define a type perf_time_t. It is simply a typedef to bigtime_t. * Use perf_time_t in parameters of MediaKit APIs and implementations. ---------------------------------------------------------------------------- ############################################################################ Commit: e34a7bb1583ace314e9c9132c6ec1534f94bca9c Author: Julian Harnath <github@xxxxxxxxxxxx> Date: Sat Oct 19 10:30:44 2013 UTC Ticket: https://dev.haiku-os.org/ticket/7285 Fix BMediaEventLooper timing and lateness handling. * As noted by Pete Goodeve in #7285, there was a sign reversal in time calculation. Also, there was a mixup of performance and real time. This commit fixes both. * As suggested by bonefish in #7285, fulfill seamlessness constraint of node latencies by calculating lateness based on how early the event was enqueued. This makes lateness values correct even when kernel timing is erratic. * Call WaitForMessage without waiting when dequeueing events late. When we receive an ongoing series of late events we would otherwise go into an infinite loop of always breaking out of the inner loop early and never calling WaitForMessage, control port messages would never be handled. ---------------------------------------------------------------------------- ############################################################################ Commit: 3cd56ded1698018803f0b2435f849683eb2f58fa Author: Julian Harnath <github@xxxxxxxxxxxx> Date: Sat Oct 19 10:39:48 2013 UTC Fix lateness handling in hmulti_audio.media_addon. * It used to calculate event lateness on its own, ignoring the value passed by BMediaEventLooper, and mixing up performance and real time. * To fulfill seamlessness constraint, it has to use the lateness value passed by BMediaEventLooper, which is based on how late the event was received. ----------------------------------------------------------------------------