예제 #1
0
void
MediaWindow::SmartNode::SetTo(const dormant_node_info* info)
{
	_FreeNode();
	if (!info)
		return;

	fNode = new media_node();
	BMediaRoster* roster = BMediaRoster::Roster();

	status_t status = B_OK;
	media_node_id node_id;
	if (roster->GetInstancesFor(info->addon, info->flavor_id, &node_id) == B_OK)
		status = roster->GetNodeFor(node_id, fNode);
	else
		status = roster->InstantiateDormantNode(*info, fNode, B_FLAVOR_IS_GLOBAL);

	if (status != B_OK) {
		fprintf(stderr, "SmartNode::SetTo error with node %" B_PRId32
			": %s\n", fNode->node, strerror(status));
	}

	status = roster->StartWatching(fMessenger, *fNode, B_MEDIA_WILDCARD);
	if (status != B_OK) {
		fprintf(stderr, "SmartNode::SetTo can't start watching for"
			" node %" B_PRId32 "\n", fNode->node);
	}
}
예제 #2
0
void
AudioSettingsView::_FillChannelMenu(const dormant_node_info* nodeInfo)
{
	_EmptyMenu(fChannelMenu);

	BMediaRoster* roster = BMediaRoster::Roster();
	media_node node;
	media_node_id node_id;

	status_t err = roster->GetInstancesFor(nodeInfo->addon,
		nodeInfo->flavor_id, &node_id);
	if (err != B_OK) {
		err = roster->InstantiateDormantNode(*nodeInfo, &node,
			B_FLAVOR_IS_GLOBAL);
	} else {
		err = roster->GetNodeFor(node_id, &node);
	}

	if (err == B_OK) {
		int32 inputCount = 4;
		media_input* inputs = new media_input[inputCount];
		BPrivate::ArrayDeleter<media_input> inputDeleter(inputs);

		while (true) {
			int32 realInputCount = 0;
			err = roster->GetAllInputsFor(node, inputs,
				inputCount, &realInputCount);
			if (realInputCount > inputCount) {
				inputCount *= 2;
				inputs = new media_input[inputCount];
				inputDeleter.SetTo(inputs);
			} else {
				inputCount = realInputCount;
				break;
			}
		}

		if (err == B_OK) {
			BMessage message(ML_DEFAULT_CHANNEL_CHANGED);

			for (int32 i = 0; i < inputCount; i++) {
				media_input* input = new media_input();
				memcpy(input, &inputs[i], sizeof(*input));
				ChannelMenuItem* channelItem = new ChannelMenuItem(input,
					new BMessage(message));
				fChannelMenu->AddItem(channelItem);

				if (channelItem->DestinationID() == 0)
					channelItem->SetMarked(true);
			}
		}
	}

	if (Window())
		fChannelMenu->SetTargetForItems(BMessenger(this));
}
예제 #3
0
void
MediaWindow::SmartNode::SetTo(const dormant_node_info* info)
{
	_FreeNode();
	if (!info)
		return;

	fNode = new media_node();
	BMediaRoster* roster = BMediaRoster::Roster();

	// TODO: error codes
	media_node_id node_id;
	if (roster->GetInstancesFor(info->addon, info->flavor_id, &node_id) == B_OK)
		roster->GetNodeFor(node_id, fNode);
	else
		roster->InstantiateDormantNode(*info, fNode, B_FLAVOR_IS_GLOBAL);
	roster->StartWatching(fMessenger, *fNode, B_MEDIA_WILDCARD);
}
예제 #4
0
void
MediaAddonServer::_InstantiatePhysicalInputsAndOutputs(AddOnInfo& info)
{
	CALLED();
	int32 count = info.addon->CountFlavors();

	for (int32 i = 0; i < count; i++) {
		const flavor_info* flavorinfo;
		if (info.addon->GetFlavorAt(i, &flavorinfo) != B_OK) {
			ERROR("MediaAddonServer::InstantiatePhysialInputsAndOutputs "
				"GetFlavorAt failed for index %ld!\n", i);
			continue;
		}
		if ((flavorinfo->kinds & (B_PHYSICAL_INPUT | B_PHYSICAL_OUTPUT)) != 0) {
			media_node node;

			dormant_node_info dormantNodeInfo;
			dormantNodeInfo.addon = info.id;
			dormantNodeInfo.flavor_id = flavorinfo->internal_id;
			strcpy(dormantNodeInfo.name, flavorinfo->name);

			PRINT("MediaAddonServer::InstantiatePhysialInputsAndOutputs: "
				"\"%s\" is a physical input/output\n", flavorinfo->name);
			status_t status = fMediaRoster->InstantiateDormantNode(
				dormantNodeInfo, &node);
			if (status != B_OK) {
				ERROR("MediaAddonServer::InstantiatePhysialInputsAndOutputs "
					"Couldn't instantiate node flavor, internal_id %ld, "
					"name %s\n", flavorinfo->internal_id, flavorinfo->name);
			} else {
				PRINT("Node created!\n");
				info.active_flavors.push_back(node);
			}
		}
	}
}
예제 #5
0
void
App::MessageReceived(BMessage* message)
{
	status_t err;
	
//	message->PrintToStream();

	switch(message->what) {
		case M_INSTANTIATE:
		{
			// fetch node info
			dormant_node_info info;
			const void *data;
			ssize_t dataSize;
			err = message->FindData("info", B_RAW_TYPE, &data, &dataSize);
			if (err < B_OK) {
				PRINT((
					"!!! App::MessageReceived(M_INSTANTIATE):\n"
					"    missing 'info'\n"));
				break;
			}
			if (dataSize != sizeof(info)) {
				PRINT((
					"*   App::MessageReceived(M_INSTANTIATE):\n"
					"    warning: 'info' size mismatch\n"));
				if (dataSize > ssize_t(sizeof(info)))
					dataSize = sizeof(info);
			}
			memcpy(reinterpret_cast<void *>(&info), data, dataSize);				

			// attempt to instantiate
			BMediaRoster* r = BMediaRoster::Roster();
			media_node node;
			err = r->InstantiateDormantNode(info, &node);
			
//			if(err == B_OK)	
//				// reference it
//				err = r->GetNodeFor(node.node, &node);

			// send status			
			if (err == B_OK) {
				BMessage m(M_INSTANTIATE_COMPLETE);
				m.AddInt32("node_id", node.node);
				message->SendReply(&m);
			}
			else {
				BMessage m(M_INSTANTIATE_FAILED);
				m.AddInt32("error", err);
				message->SendReply(&m);
			}

			break;
		}

		case M_RELEASE:
		{
			// fetch node info
			live_node_info info;
			const void *data;
			ssize_t dataSize;
			err = message->FindData("info", B_RAW_TYPE, &data, &dataSize);
			if (err < B_OK) {
				PRINT((
					"!!! App::MessageReceived(M_RELEASE):\n"
					"    missing 'info'\n"));
				break;
			}
			if (dataSize != sizeof(info)) {
				PRINT((
					"*   App::MessageReceived(M_RELEASE):\n"
					"    warning: 'info' size mismatch\n"));
				if(dataSize > ssize_t(sizeof(info)))
					dataSize = sizeof(info);
			}
			memcpy(reinterpret_cast<void *>(&info), data, dataSize);				

			// attempt to release
			BMediaRoster* r = BMediaRoster::Roster();
			media_node node;
			err = r->ReleaseNode(info.node);

			// send status			
			if (err == B_OK) {
				BMessage m(M_RELEASE_COMPLETE);
				m.AddInt32("node_id", info.node.node);
				message->SendReply(&m);
			}
			else {
				BMessage m(M_RELEASE_FAILED);
				m.AddInt32("error", err);
				message->SendReply(&m);
			}

			break;
		}

		default:
			_inherited::MessageReceived(message);
	}
}
예제 #6
0
void
NodeHarnessWin::MessageReceived(BMessage *msg)
{
	status_t err;

	switch (msg->what)
	{
	case BUTTON_CONNECT:
		mIsConnected = true;

		// set the button states appropriately
		mConnectButton->SetEnabled(false);
		mStartButton->SetEnabled(true);

		// set up the node network
		{
			BMediaRoster* r = BMediaRoster::Roster();

			// find a node that can handle an audio file
#if TEST_WITH_AUDIO
			entry_ref inRef;
			dormant_node_info info;

			::get_ref_for_path("/boot/optional/sound/virtual (void)", &inRef);
			err = r->SniffRef(inRef, B_BUFFER_PRODUCER | B_FILE_INTERFACE, &info);
			ErrorCheck(err, "couldn't find file reader node\n");

			err = r->InstantiateDormantNode(info, &mConnection.producer, B_FLAVOR_IS_LOCAL);
			ErrorCheck(err, "couldn't instantiate file reader node\n");

			bigtime_t dummy_length;			// output = media length; we don't use it
			err = r->SetRefFor(mConnection.producer, inRef, false, &dummy_length);
			ErrorCheck(err, "unable to SetRefFor() to read that sound file!\n");
#else
			r->GetVideoInput(&mConnection.producer);
#endif

			entry_ref logRef;
			::get_ref_for_path("/tmp/node_log", &logRef);

			mLogNode = new LoggingConsumer(logRef);
			err = r->RegisterNode(mLogNode);
			ErrorCheck(err, "unable to register LoggingConsumer node!\n");
			// make sure the Media Roster knows that we're using the node
			r->GetNodeFor(mLogNode->Node().node, &mConnection.consumer);

			// trim down the log's verbosity a touch
			mLogNode->SetEnabled(LOG_HANDLE_EVENT, false);

			// fire off a window with the LoggingConsumer's controls in it
			BParameterWeb* web;
			r->GetParameterWebFor(mConnection.consumer, &web);
			BView* view = BMediaTheme::ViewFor(web);
			BWindow* win = new BWindow(BRect(250, 200, 300, 300), "Controls",
				B_TITLED_WINDOW, B_ASYNCHRONOUS_CONTROLS);
			win->AddChild(view);
			win->ResizeTo(view->Bounds().Width(), view->Bounds().Height());
			win->Show();

			// set the nodes' time sources
			r->GetTimeSource(&mTimeSource);
			r->SetTimeSourceFor(mConnection.consumer.node, mTimeSource.node);
			r->SetTimeSourceFor(mConnection.producer.node, mTimeSource.node);

			// got the nodes; now we find the endpoints of the connection
			media_input logInput;
			media_output soundOutput;
			int32 count;
			err = r->GetFreeOutputsFor(mConnection.producer, &soundOutput, 1, &count);
			ErrorCheck(err, "unable to get a free output from the producer node");
			err = r->GetFreeInputsFor(mConnection.consumer, &logInput, 1, &count);
			ErrorCheck(err, "unable to get a free input to the LoggingConsumer");

			// fill in the rest of the Connection object
			mConnection.source = soundOutput.source;
			mConnection.destination = logInput.destination;

			// got the endpoints; now we connect it!
			media_format format;
#if TEST_WITH_AUDIO
			format.type = B_MEDIA_RAW_AUDIO;			// !!! hmmm.. how to fully wildcard this?
			format.u.raw_audio = media_raw_audio_format::wildcard;
#else
			format.type = B_MEDIA_RAW_VIDEO;			// !!! hmmm.. how to fully wildcard this?
			format.u.raw_video = media_raw_video_format::wildcard;
#endif
			err = r->Connect(mConnection.source, mConnection.destination, &format, &soundOutput, &logInput);
			ErrorCheck(err, "unable to connect nodes");
			mConnection.format = format;

			// for video input, we need to set the downstream latency for record -> playback
			bigtime_t latency;
			r->GetLatencyFor(mConnection.producer, &latency);
			printf("Setting producer run mode latency to %" B_PRIdBIGTIME "\n", latency);
			r->SetProducerRunModeDelay(mConnection.producer, latency + 6000);

			// preroll first, to be a good citizen
			r->PrerollNode(mConnection.consumer);
			r->PrerollNode(mConnection.producer);

			// start the LoggingConsumer and leave it running
			BTimeSource* ts = r->MakeTimeSourceFor(mTimeSource);
			r->StartNode(mConnection.consumer, ts->Now());
			ts->Release();
		}
		break;

	case BUTTON_START:
		mStartButton->SetEnabled(false);
		mStopButton->SetEnabled(true);

		// start the consumer running
		{
			bigtime_t latency;
			BMediaRoster* r = BMediaRoster::Roster();
			BTimeSource* ts = r->MakeTimeSourceFor(mConnection.consumer);
			r->GetLatencyFor(mConnection.producer, &latency);
			r->StartNode(mConnection.producer, ts->Now() + latency);
			ts->Release();
			mIsRunning = true;
		}
		break;

	case BUTTON_STOP:
		StopNodes();
		break;

	default:
		BWindow::MessageReceived(msg);
		break;
	}
}