tcp: Fix 64 bit build with debugging features enabled.
[haiku.git] / src / kits / media / MediaNode.cpp
blobbece94a000881a451c8c9355790af1ed72866d5e
1 /*
2 * Copyright (c) 2015, Dario Casalinuovo
3 * Copyright (c) 2002, 2003 Marcus Overhagen <Marcus@Overhagen.de>
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files or portions
7 * thereof (the "Software"), to deal in the Software without restriction,
8 * including without limitation the rights to use, copy, modify, merge,
9 * publish, distribute, sublicense, and/or sell copies of the Software,
10 * and to permit persons to whom the Software is furnished to do so, subject
11 * to the following conditions:
13 * * Redistributions of source code must retain the above copyright notice,
14 * this list of conditions and the following disclaimer.
16 * * Redistributions in binary form must reproduce the above copyright notice
17 * in the binary, as well as this list of conditions and the following
18 * disclaimer in the documentation and/or other materials provided with
19 * the distribution.
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
24 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27 * THE SOFTWARE.
32 #include <BufferConsumer.h>
33 #include <BufferProducer.h>
34 #include <Controllable.h>
35 #include <FileInterface.h>
36 #include <MediaRoster.h>
37 #include <MediaNode.h>
38 #include <SupportDefs.h>
39 #include <TimeSource.h>
41 #include <string.h>
43 #include "DataExchange.h"
44 #include "debug.h"
45 #include "MediaMisc.h"
46 #include "MediaRosterEx.h"
47 #include "Notifications.h"
48 #include "ServerInterface.h"
49 #include "TimeSourceObject.h"
50 #include "TimeSourceObjectManager.h"
52 using std::nothrow;
53 using std::nothrow_t;
55 #undef TRACE
56 //#define TRACE_MEDIA_NODE
57 #ifdef TRACE_MEDIA_NODE
58 #define TRACE printf
59 #else
60 #define TRACE(x...)
61 #endif
63 // Don't rename this one, it's used and exported for binary compatibility
64 int32 BMediaNode::_m_changeTag = 0;
66 // media_node
68 media_node media_node::null;
70 media_node::media_node()
72 node(-1),
73 port(-1),
74 kind(0)
79 media_node::~media_node()
83 // media_input
85 media_input::media_input()
87 name[0] = '\0';
91 media_input::~media_input()
95 // media_output
97 media_output::media_output()
99 name[0] = '\0';
103 media_output::~media_output()
107 // live_node_info
109 live_node_info::live_node_info()
111 hint_point(0.0f, 0.0f)
113 name[0] = '\0';
117 live_node_info::~live_node_info()
121 // BMediaNode
123 BMediaNode::~BMediaNode()
125 CALLED();
126 // BeBook: UnregisterNode() unregisters a node from the Media Server.
127 // It's called automatically by the BMediaNode destructor, but it might
128 // be convenient to call it sometime before you delete your node instance,
129 // depending on your implementation and circumstances.
131 // First we remove the time source
132 if (fTimeSource) {
133 fTimeSource->RemoveMe(this);
134 fTimeSource->Release();
135 fTimeSource = NULL;
138 // Attention! We do not delete their control ports, since they are only a
139 // shadow object, and the real one still exists
140 if ((fKinds & NODE_KIND_SHADOW_TIMESOURCE) == 0) {
141 if (fControlPort > 0)
142 delete_port(fControlPort);
143 } else {
144 TRACE("BMediaNode::~BMediaNode: shadow timesource,"
145 " not unregistering\n");
150 BMediaNode*
151 BMediaNode::Acquire()
153 CALLED();
154 atomic_add(&fRefCount,1);
155 return this;
159 BMediaNode*
160 BMediaNode::Release()
162 CALLED();
163 if (atomic_add(&fRefCount, -1) == 1) {
164 TRACE("BMediaNode::Release() saving node %ld configuration\n", fNodeID);
165 MediaRosterEx(BMediaRoster::Roster())->SaveNodeConfiguration(this);
166 if (DeleteHook(this) != B_OK) {
167 ERROR("BMediaNode::Release(): DeleteHook failed\n");
168 return Acquire();
170 return NULL;
172 return this;
176 const char*
177 BMediaNode::Name() const
179 CALLED();
180 return fName;
184 media_node_id
185 BMediaNode::ID() const
187 CALLED();
188 return fNodeID;
192 uint64
193 BMediaNode::Kinds() const
195 CALLED();
196 return fKinds & NODE_KIND_USER_MASK;
200 media_node
201 BMediaNode::Node() const
203 CALLED();
204 media_node temp;
205 temp.node = ID();
206 // We *must* call ControlPort(), some derived nodes
207 // use it to start the port read thread!
208 temp.port = ControlPort();
209 temp.kind = Kinds();
210 return temp;
214 BMediaNode::run_mode
215 BMediaNode::RunMode() const
217 CALLED();
218 return fRunMode;
222 BTimeSource*
223 BMediaNode::TimeSource() const
225 PRINT(7, "CALLED BMediaNode::TimeSource()\n");
227 // Return the currently assigned time source
228 if (fTimeSource != 0)
229 return fTimeSource;
231 TRACE("BMediaNode::TimeSource node %ld enter\n", ID());
233 // If the node doesn't have a time source object, we need to create one.
234 // If the node is still unregistered, we can't call MakeTimeSourceFor(),
235 // but since the node does still have the default system time source, we
236 // can use GetSystemTimeSource
238 BMediaNode* self = const_cast<BMediaNode*>(this);
239 self->fTimeSource = MediaRosterEx(
240 BMediaRoster::Roster())->MakeTimeSourceObject(fTimeSourceID);
242 ASSERT(fTimeSource == self->fTimeSource);
244 if (fTimeSource == 0) {
245 ERROR("BMediaNode::TimeSource: MakeTimeSourceFor failed\n");
246 } else {
247 ASSERT(fTimeSourceID == fTimeSource->ID());
248 fTimeSource->AddMe(self);
251 TRACE("BMediaNode::TimeSource node %ld leave\n", ID());
253 return fTimeSource;
257 port_id
258 BMediaNode::ControlPort() const
260 PRINT(7, "CALLED BMediaNode::ControlPort()\n");
261 return fControlPort;
265 status_t
266 BMediaNode::ReportError(node_error what, const BMessage* info)
268 CALLED();
270 // Sanity check the what value
271 switch (what) {
272 case BMediaNode::B_NODE_FAILED_START:
273 case BMediaNode::B_NODE_FAILED_STOP:
274 case BMediaNode::B_NODE_FAILED_SEEK:
275 case BMediaNode::B_NODE_FAILED_SET_RUN_MODE:
276 case BMediaNode::B_NODE_FAILED_TIME_WARP:
277 case BMediaNode::B_NODE_FAILED_PREROLL:
278 case BMediaNode::B_NODE_FAILED_SET_TIME_SOURCE_FOR:
279 case BMediaNode::B_NODE_IN_DISTRESS:
280 break;
281 default:
282 ERROR("BMediaNode::ReportError: invalid what!\n");
283 return B_BAD_VALUE;
286 // Transmits the error code specified by what to anyone
287 // that's receiving notifications from this node
288 return BPrivate::media::notifications::ReportError(Node(), what, info);
292 status_t
293 BMediaNode::NodeStopped(bigtime_t whenPerformance)
295 UNIMPLEMENTED();
296 // Called by derived classes when they have
297 // finished handling a stop request.
299 // Notify anyone who is listening for stop notifications!
300 BPrivate::media::notifications::NodeStopped(Node(), whenPerformance);
302 // NOTE: If your node is a BBufferProducer, downstream consumers
303 // will be notified that your node stopped (automatically, no less) through
304 // the BBufferConsumer::ProducerDataStatus(B_PRODUCER_STOPPED) call.
306 return B_OK;
311 * Used in couple with AddTimer, this will cause the BMediaRoster::SyncToNode()
312 * call that requested the timer to return to the caller with an appropriate
313 * value.
315 void
316 BMediaNode::TimerExpired(bigtime_t notifyPoint, int32 cookie, status_t error)
318 CALLED();
319 if (write_port((port_id)cookie, 0, &error, sizeof(error)) < 0) {
320 TRACE("BMediaNode::TimerExpired: error writing port" B_PRId32
321 ", at notifyPoint" B_PRId64 "\n", cookie, notifyPoint);
326 BMediaNode::BMediaNode(const char* name)
328 TRACE("BMediaNode::BMediaNode: name '%s'\n", name);
329 _InitObject(name, NODE_JUST_CREATED_ID, 0);
333 status_t
334 BMediaNode::WaitForMessage(bigtime_t waitUntil, uint32 flags,
335 void* _reserved_)
337 TRACE("entering: BMediaNode::WaitForMessage()\n");
339 // This function waits until either real time specified by
340 // waitUntil or a message is received on the control port.
341 // The flags are currently unused and should be 0.
342 // Note: about 16 KByte stack used
343 char data[B_MEDIA_MESSAGE_SIZE];
344 int32 message;
345 ssize_t size;
346 while (true) {
347 size = read_port_etc(ControlPort(), &message, data,
348 sizeof(data), B_ABSOLUTE_TIMEOUT, waitUntil);
350 if (size >= 0)
351 break;
353 status_t error = (status_t)size;
354 if (error == B_INTERRUPTED)
355 continue;
357 if (error != B_TIMED_OUT && error != B_BAD_PORT_ID) {
358 ERROR("BMediaNode::WaitForMessage: read_port_etc error: %s\n",
359 strerror(error));
362 return error;
365 TRACE("BMediaNode::WaitForMessage request is: %#lx, node %ld, this %p\n",
366 message, fNodeID, this);
368 if (message == GENERAL_PURPOSE_WAKEUP)
369 return B_OK;
371 if (message > NODE_MESSAGE_START && message < NODE_MESSAGE_END) {
372 TRACE("BMediaNode::WaitForMessage calling BMediaNode\n");
374 if (B_OK == BMediaNode::HandleMessage(message, data, size))
375 return B_OK;
378 if (message > PRODUCER_MESSAGE_START && message < PRODUCER_MESSAGE_END) {
379 if (!fProducerThis)
380 fProducerThis = dynamic_cast<BBufferProducer*>(this);
382 TRACE("BMediaNode::WaitForMessage calling BBufferProducer %p\n",
383 fProducerThis);
385 if (fProducerThis && fProducerThis->BBufferProducer::HandleMessage(
386 message, data, size) == B_OK) {
387 return B_OK;
391 if (message > CONSUMER_MESSAGE_START && message < CONSUMER_MESSAGE_END) {
392 if (!fConsumerThis)
393 fConsumerThis = dynamic_cast<BBufferConsumer*>(this);
395 TRACE("BMediaNode::WaitForMessage calling BBufferConsumer %p\n",
396 fConsumerThis);
398 if (fConsumerThis && fConsumerThis->BBufferConsumer::HandleMessage(
399 message, data, size) == B_OK) {
400 return B_OK;
404 if (message > FILEINTERFACE_MESSAGE_START
405 && message < FILEINTERFACE_MESSAGE_END) {
406 if (!fFileInterfaceThis)
407 fFileInterfaceThis = dynamic_cast<BFileInterface*>(this);
409 TRACE("BMediaNode::WaitForMessage calling BFileInterface %p\n",
410 fFileInterfaceThis);
412 if (fFileInterfaceThis
413 && fFileInterfaceThis->BFileInterface::HandleMessage(
414 message, data, size) == B_OK) {
415 return B_OK;
419 if (message > CONTROLLABLE_MESSAGE_START
420 && message < CONTROLLABLE_MESSAGE_END) {
421 if (!fControllableThis)
422 fControllableThis = dynamic_cast<BControllable*>(this);
424 TRACE("BMediaNode::WaitForMessage calling BControllable %p\n",
425 fControllableThis);
427 if (fControllableThis
428 && fControllableThis->BControllable::HandleMessage(
429 message, data, size) == B_OK) {
430 return B_OK;
434 if (message > TIMESOURCE_MESSAGE_START
435 && message < TIMESOURCE_MESSAGE_END) {
436 if (!fTimeSourceThis)
437 fTimeSourceThis = dynamic_cast<BTimeSource*>(this);
439 TRACE("BMediaNode::WaitForMessage calling BTimeSource %p\n",
440 fTimeSourceThis);
442 if (fTimeSourceThis && fTimeSourceThis->BTimeSource::HandleMessage(
443 message, data, size) == B_OK) {
444 return B_OK;
448 TRACE("BMediaNode::WaitForMessage calling default HandleMessage\n");
449 if (HandleMessage(message, data, size) == B_OK)
450 return B_OK;
452 HandleBadMessage(message, data, size);
454 return B_ERROR;
458 void
459 BMediaNode::Start(bigtime_t performance_time)
461 CALLED();
462 // This hook function is called when a node is started
463 // by a call to the BMediaRoster. The specified
464 // performanceTime, the time at which the node
465 // should start running, may be in the future.
466 // It may be overriden by derived classes.
467 // The BMediaEventLooper class handles this event!
468 // The BMediaNode class does nothing here.
472 void
473 BMediaNode::Stop(bigtime_t performance_time, bool immediate)
475 CALLED();
476 // This hook function is called when a node is stopped
477 // by a call to the BMediaRoster. The specified
478 // performanceTime, the time at which the node
479 // should stop running, may be in the future.
480 // It may be overriden by derived classes.
481 // The BMediaEventLooper class handles this event!
482 // The BMediaNode class does nothing here.
486 void
487 BMediaNode::Seek(bigtime_t media_time, bigtime_t performance_time)
489 CALLED();
490 // This hook function is called when a node is asked
491 // to seek to the specified mediaTime by a call to
492 // the BMediaRoster. The specified performanceTime,
493 // the time at which the node should begin the seek
494 // operation, may be in the future.
495 // It may be overriden by derived classes.
496 // The BMediaEventLooper class handles this event!
497 // The BMediaNode class does nothing here.
501 void
502 BMediaNode::SetRunMode(run_mode mode)
504 CALLED();
506 // This is a hook function, and
507 // may be overriden by derived classes.
509 // The functionality here is only to
510 // support those people that don't
511 // use the roster to set the run mode
512 fRunMode = mode;
516 void
517 BMediaNode::TimeWarp(bigtime_t at_real_time, bigtime_t to_performance_time)
519 CALLED();
520 // May be overriden by derived classes.
524 void
525 BMediaNode::Preroll()
527 CALLED();
528 // May be overriden by derived classes.
532 void
533 BMediaNode::SetTimeSource(BTimeSource* time_source)
535 CALLED();
536 // This is a hook function, and
537 // may be overriden by derived classes.
539 if (time_source == NULL || time_source == fTimeSource)
540 return;
542 // We just trip into debugger, code that tries to do this is broken.
543 debugger("BMediaNode::SetTimeSource() can't be used to set a timesource, "
544 "use BMediaRoster::SetTimeSourceFor()!\n");
548 status_t
549 BMediaNode::HandleMessage(int32 message, const void* data, size_t size)
551 TRACE("BMediaNode::HandleMessage %#lx, node %ld\n", message, fNodeID);
552 switch (message) {
553 case NODE_FINAL_RELEASE:
555 TRACE("BMediaNode::HandleMessage NODE_FINAL_RELEASE, this %p\n",
556 this);
558 // This is called by the media server to delete the object
559 // after is has been released by all nodes that are using it.
560 // We forward the function to the BMediaRoster, since the
561 // deletion must be done from a different thread, or the
562 // outermost destructor that will exit the thread that is
563 // reading messages from the port (this thread contex) will
564 // quit, and ~BMediaNode destructor won't be called ever.
565 BMessage msg(NODE_FINAL_RELEASE);
566 msg.AddPointer("node", this);
567 BMediaRoster::Roster()->PostMessage(&msg);
568 return B_OK;
571 case NODE_START:
573 const node_start_command* command
574 = static_cast<const node_start_command*>(data);
575 TRACE("BMediaNode::HandleMessage NODE_START, node %ld\n", fNodeID);
576 Start(command->performance_time);
577 return B_OK;
580 case NODE_STOP:
582 const node_stop_command* command
583 = static_cast<const node_stop_command*>(data);
584 TRACE("BMediaNode::HandleMessage NODE_STOP, node %ld\n", fNodeID);
585 Stop(command->performance_time, command->immediate);
586 return B_OK;
589 case NODE_SEEK:
591 const node_seek_command* command
592 = static_cast<const node_seek_command*>(data);
593 TRACE("BMediaNode::HandleMessage NODE_SEEK, node %ld\n", fNodeID);
594 Seek(command->media_time, command->performance_time);
595 return B_OK;
598 case NODE_SET_RUN_MODE:
600 const node_set_run_mode_command* command
601 = static_cast<const node_set_run_mode_command*>(data);
602 TRACE("BMediaNode::HandleMessage NODE_SET_RUN_MODE,"
603 " node %ld\n", fNodeID);
604 // Need to change PRODUCER_SET_RUN_MODE_DELAY
605 fRunMode = command->mode;
606 SetRunMode(fRunMode);
607 return B_OK;
610 case NODE_TIME_WARP:
612 const node_time_warp_command* command
613 = static_cast<const node_time_warp_command*>(data);
614 TRACE("BMediaNode::HandleMessage NODE_TIME_WARP,"
615 " node %ld\n", fNodeID);
616 TimeWarp(command->at_real_time, command->to_performance_time);
617 return B_OK;
620 case NODE_PREROLL:
622 TRACE("BMediaNode::HandleMessage NODE_PREROLL, "
623 " node %ld\n", fNodeID);
624 Preroll();
625 return B_OK;
628 case NODE_ROLL:
630 const node_roll_command* command
631 = static_cast<const node_roll_command*>(data);
633 TRACE("BMediaNode::HandleMessage NODE_ROLL, node %ld\n",
634 fNodeID);
636 if (command->seek_media_time != B_INFINITE_TIMEOUT)
637 Seek(command->seek_media_time,
638 command->start_performance_time);
640 Start(command->start_performance_time);
641 Stop(command->stop_performance_time, false);
642 return B_OK;
645 case NODE_SYNC_TO:
647 const node_sync_to_request* request
648 = static_cast<const node_sync_to_request*>(data);
649 node_sync_to_reply reply;
651 TRACE("BMediaNode::HandleMessage NODE_SYNC_TO, node %ld\n",
652 fNodeID);
654 // If AddTimer return an error the caller will know that the node
655 // doesn't support this feature or there was a problem when adding
656 // it, this will result in SyncToNode returning immediately
657 // to the caller with an error.
658 status_t status = AddTimer(request->performance_time,
659 request->port);
661 request->SendReply(status, &reply, sizeof(reply));
662 return B_OK;
665 case NODE_SET_TIMESOURCE:
667 const node_set_timesource_command* command
668 = static_cast<const node_set_timesource_command*>(data);
670 TRACE("BMediaNode::HandleMessage NODE_SET_TIMESOURCE,"
671 " node %ld, timesource %ld enter\n",
672 fNodeID, command->timesource_id);
674 fTimeSourceID = command->timesource_id;
676 if (fTimeSource) {
677 // As this node already had a timesource, to remove this node
678 // from time source control
679 fTimeSource->RemoveMe(this);
680 // Release the time source
681 fTimeSource->Release();
682 // Force next call to TimeSource() to create a new object
683 fTimeSource = 0;
686 // Create new time source object and call the SetTimeSource
687 // hook function to notify any derived class
688 fTimeSource = TimeSource();
689 SetTimeSource(fTimeSource);
691 TRACE("BMediaNode::HandleMessage NODE_SET_TIMESOURCE, node %ld,"
692 "timesource %ld leave\n", fNodeID, command->timesource_id);
694 return B_OK;
697 case NODE_GET_TIMESOURCE:
699 const node_get_timesource_request* request
700 = static_cast<const node_get_timesource_request*>(data);
702 TRACE("BMediaNode::HandleMessage NODE_GET_TIMESOURCE,"
703 " node %ld\n", fNodeID);
705 node_get_timesource_reply reply;
706 reply.timesource_id = fTimeSourceID;
707 request->SendReply(B_OK, &reply, sizeof(reply));
708 return B_OK;
711 case NODE_GET_ATTRIBUTES_FOR:
713 const node_get_attributes_for_request *request =
714 (const node_get_attributes_for_request*) data;
716 TRACE("BMediaNode::HandleMessage NODE_GET_ATTRIBUTES_FOR,"
717 "node %ld\n", fNodeID);
719 node_get_attributes_for_reply reply;
721 media_node_attribute* addr;
722 area_id dataArea = clone_area("client attributes area",
723 (void**)&addr, B_ANY_ADDRESS, B_WRITE_AREA,
724 request->area);
726 if (dataArea < 0) {
727 ERROR("NODE_GET_ATTRIBUTES_FOR can't clone area\n");
728 return B_NO_MEMORY;
731 status_t status = GetNodeAttributes(addr, request->count);
732 if (status == B_OK) {
733 // NOTE: we do it because there's not an easy way
734 // to guess the number of attributes filled.
735 size_t i;
736 for (i = 0; i < request->count; i++) {
737 if (addr[i].what <= 0)
738 break;
740 reply.filled_count = i;
742 request->SendReply(status, &reply, sizeof(reply));
743 delete_area(dataArea);
744 return B_OK;
747 case NODE_REQUEST_COMPLETED:
749 const node_request_completed_command* command
750 = static_cast<const node_request_completed_command*>(data);
751 TRACE("BMediaNode::HandleMessage NODE_REQUEST_COMPLETED,"
752 " node %ld\n", fNodeID);
753 RequestCompleted(command->info);
754 return B_OK;
757 default:
758 return B_ERROR;
761 return B_ERROR;
765 void
766 BMediaNode::HandleBadMessage(int32 code, const void* buffer, size_t size)
768 CALLED();
770 TRACE("BMediaNode::HandleBadMessage: code %#08lx, buffer %p, size %ld\n",
771 code, buffer, size);
772 if (code < NODE_MESSAGE_START || code > TIMESOURCE_MESSAGE_END) {
773 ERROR("BMediaNode::HandleBadMessage: unknown code!\n");
774 } else {
775 // All messages targeted to nodes should be handled here,
776 // messages targetted to the wrong node should be handled
777 // by returning an error, not by stalling the sender.
778 const request_data* request = static_cast<const request_data* >(buffer);
779 reply_data reply;
780 request->SendReply(B_ERROR, &reply, sizeof(reply));
785 void
786 BMediaNode::AddNodeKind(uint64 kind)
788 TRACE("BMediaNode::AddNodeKind: node %ld, this %p\n", fNodeID, this);
789 fKinds |= kind;
793 void*
794 BMediaNode::operator new(size_t size)
796 CALLED();
797 return ::operator new(size);
801 void*
802 BMediaNode::operator new(size_t size, const nothrow_t&) throw()
804 CALLED();
805 return ::operator new(size, nothrow);
809 void
810 BMediaNode::operator delete(void* ptr)
812 CALLED();
813 ::operator delete(ptr);
817 void
818 BMediaNode::operator delete(void* ptr, const nothrow_t&) throw()
820 CALLED();
821 ::operator delete(ptr, nothrow);
825 status_t
826 BMediaNode::RequestCompleted(const media_request_info& info)
828 CALLED();
829 // This function is called whenever
830 // a request issued by the node is completed.
831 // May be overriden by derived classes.
832 // info.change_tag can be used to match up requests against
833 // the accompaning calles from
834 // BBufferConsumer::RequestFormatChange()
835 // BBufferConsumer::SetOutputBuffersFor()
836 // BBufferConsumer::SetOutputEnabled()
837 // BBufferConsumer::SetVideoClippingFor()
838 return B_OK;
842 status_t
843 BMediaNode::DeleteHook(BMediaNode* node)
845 CALLED();
846 // Attention! We do not unregister TimeSourceObject nodes,
847 // since they are only a shadow object, and the real one still exists
848 if ((fKinds & NODE_KIND_SHADOW_TIMESOURCE) == 0)
849 BMediaRoster::Roster()->UnregisterNode(this);
850 delete this; // delete "this" or "node", both are the same
851 return B_OK;
855 void
856 BMediaNode::NodeRegistered()
858 CALLED();
859 // The Media Server calls this hook function
860 // after the node has been registered.
861 // May be overriden by derived classes.
865 status_t
866 BMediaNode::GetNodeAttributes(media_node_attribute* outAttributes,
867 size_t inMaxCount)
869 CALLED();
870 // This is implemented by derived classes that fills
871 // it's own attributes to a max of inMaxCount elements.
872 return B_ERROR;
876 status_t
877 BMediaNode::AddTimer(bigtime_t at_performance_time, int32 cookie)
879 CALLED();
880 return B_ERROR;
884 status_t BMediaNode::_Reserved_MediaNode_0(void*) { return B_ERROR; }
885 status_t BMediaNode::_Reserved_MediaNode_1(void*) { return B_ERROR; }
886 status_t BMediaNode::_Reserved_MediaNode_2(void*) { return B_ERROR; }
887 status_t BMediaNode::_Reserved_MediaNode_3(void*) { return B_ERROR; }
888 status_t BMediaNode::_Reserved_MediaNode_4(void*) { return B_ERROR; }
889 status_t BMediaNode::_Reserved_MediaNode_5(void*) { return B_ERROR; }
890 status_t BMediaNode::_Reserved_MediaNode_6(void*) { return B_ERROR; }
891 status_t BMediaNode::_Reserved_MediaNode_7(void*) { return B_ERROR; }
892 status_t BMediaNode::_Reserved_MediaNode_8(void*) { return B_ERROR; }
893 status_t BMediaNode::_Reserved_MediaNode_9(void*) { return B_ERROR; }
894 status_t BMediaNode::_Reserved_MediaNode_10(void*) { return B_ERROR; }
895 status_t BMediaNode::_Reserved_MediaNode_11(void*) { return B_ERROR; }
896 status_t BMediaNode::_Reserved_MediaNode_12(void*) { return B_ERROR; }
897 status_t BMediaNode::_Reserved_MediaNode_13(void*) { return B_ERROR; }
898 status_t BMediaNode::_Reserved_MediaNode_14(void*) { return B_ERROR; }
899 status_t BMediaNode::_Reserved_MediaNode_15(void*) { return B_ERROR; }
902 private unimplemented
903 BMediaNode::BMediaNode()
904 BMediaNode::BMediaNode(const BMediaNode &clone)
905 BMediaNode &BMediaNode::operator=(const BMediaNode &clone)
908 void
909 BMediaNode::_InitObject(const char* name, media_node_id id, uint64 kinds)
911 TRACE("BMediaNode::_InitObject: nodeid %ld, this %p\n", id, this);
913 fNodeID = id;
914 fRefCount = 1;
915 fName[0] = 0;
916 if (name)
917 strlcpy(fName, name, B_MEDIA_NAME_LENGTH);
918 fRunMode = B_INCREASE_LATENCY;
919 fKinds = kinds;
920 fProducerThis = 0;
921 fConsumerThis = 0;
922 fFileInterfaceThis = 0;
923 fControllableThis = 0;
924 fTimeSourceThis = 0;
926 // Create control port
927 fControlPort = create_port(64, fName);
929 // Nodes are assigned the system time source by default
930 fTimeSourceID = NODE_SYSTEM_TIMESOURCE_ID;
932 // We can't create the timesource object here, because
933 // every timesource is a BMediaNode, which would result
934 // in infinite recursions
935 fTimeSource = NULL;
939 BMediaNode::BMediaNode(const char* name, media_node_id id, uint32 kinds)
941 TRACE("BMediaNode::BMediaNode: name '%s', nodeid %ld, kinds %#lx\n",
942 name, id, kinds);
943 _InitObject(name, id, kinds);
947 int32
948 BMediaNode::NewChangeTag()
950 CALLED();
951 // Change tags have been used in BeOS R4 to match up
952 // format change requests between producer and consumer,
953 // This has changed starting with R4.5
954 // now "change tags" are used with the following functions:
955 // BMediaNode::RequestCompleted()
956 // BBufferConsumer::RequestFormatChange()
957 // BBufferConsumer::SetOutputBuffersFor()
958 // BBufferConsumer::SetOutputEnabled()
959 // BBufferConsumer::SetVideoClippingFor()
960 return atomic_add(&BMediaNode::_m_changeTag,1);
963 // BeOS R4 deprecated API
965 int32
966 BMediaNode::IncrementChangeTag()
968 CALLED();
969 // Only present in BeOS R4
970 // Obsoleted in BeOS R4.5 and later
971 // "updates the change tag, so that downstream consumers
972 // know that the node is in a new state."
973 // not supported, only for binary compatibility
974 return 0;
978 int32
979 BMediaNode::ChangeTag()
981 UNIMPLEMENTED();
982 // Only present in BeOS R4
983 // Obsoleted in BeOS R4.5 and later
984 // "returns the node's current change tag value."
985 // not supported, only for binary compatibility
986 return 0;
990 int32
991 BMediaNode::MintChangeTag()
993 UNIMPLEMENTED();
994 // Only present in BeOS R4
995 // Obsoleted in BeOS R4.5 and later
996 // "mints a new, reserved, change tag."
997 // "Call ApplyChangeTag() to apply it to the node"
998 // not supported, only for binary compatibility
999 return 0;
1003 status_t
1004 BMediaNode::ApplyChangeTag(int32 previously_reserved)
1006 UNIMPLEMENTED();
1007 // Only present in BeOS R4
1008 // Obsoleted in BeOS R4.5 and later
1009 // "this returns B_OK if the new change tag is"
1010 // "successfully applied, or B_MEDIA_STALE_CHANGE_TAG if the new change"
1011 // "count you tried to apply is already obsolete."
1012 // not supported, only for binary compatibility
1013 return B_OK;