void CodyCam::MessageReceived(BMessage *message) { switch (message->what) { case msg_start: { BTimeSource* timeSource = fMediaRoster->MakeTimeSourceFor(fTimeSourceNode); bigtime_t real = BTimeSource::RealTime(); bigtime_t perf = timeSource->PerformanceTimeFor(real) + 10000; status_t status = fMediaRoster->StartNode(fProducerNode, perf); if (status != B_OK) ERROR("error starting producer!"); timeSource->Release(); break; } case msg_stop: fMediaRoster->StopNode(fProducerNode, 0, true); break; case msg_video: { if (fVideoControlWindow) { fVideoControlWindow->Activate(); break; } BParameterWeb* web = NULL; BView* view = NULL; media_node node = fProducerNode; status_t err = fMediaRoster->GetParameterWebFor(node, &web); if (err >= B_OK && web != NULL) { view = BMediaTheme::ViewFor(web); fVideoControlWindow = new ControlWindow( BRect(2 * WINDOW_OFFSET_X + WINDOW_SIZE_X, WINDOW_OFFSET_Y, 2 * WINDOW_OFFSET_X + WINDOW_SIZE_X + view->Bounds().right, WINDOW_OFFSET_Y + view->Bounds().bottom), view, node); fMediaRoster->StartWatching(BMessenger(NULL, fVideoControlWindow), node, B_MEDIA_WEB_CHANGED); fVideoControlWindow->Show(); } break; } case msg_about: (new BAlert("About CodyCam", "CodyCam\n\nThe Original BeOS webcam", "Close"))->Go(); break; case msg_control_win: // our control window is being asked to go away // set our pointer to NULL fVideoControlWindow = NULL; break; default: BApplication::MessageReceived(message); break; } }
status_t CodyCam::_SetUpNodes() { status_t status = B_OK; /* find the media roster */ fMediaRoster = BMediaRoster::Roster(&status); if (status != B_OK) { fWindow->ErrorAlert(B_TRANSLATE("Cannot find the media roster"), status); return status; } /* find the time source */ status = fMediaRoster->GetTimeSource(&fTimeSourceNode); if (status != B_OK) { fWindow->ErrorAlert(B_TRANSLATE("Cannot get a time source"), status); return status; } /* find a video producer node */ INFO("CodyCam acquiring VideoInput node\n"); status = fMediaRoster->GetVideoInput(&fProducerNode); if (status != B_OK) { fWindow->ErrorAlert(B_TRANSLATE("Cannot find a video source. You need " "a webcam to use CodyCam."), status); return status; } /* create the video consumer node */ fVideoConsumer = new VideoConsumer("CodyCam", ((VideoWindow*)fWindow)->VideoView(), ((VideoWindow*)fWindow)->StatusLine(), NULL, 0); if (!fVideoConsumer) { fWindow->ErrorAlert(B_TRANSLATE("Cannot create a video window"), B_ERROR); return B_ERROR; } /* register the node */ status = fMediaRoster->RegisterNode(fVideoConsumer); if (status != B_OK) { fWindow->ErrorAlert(B_TRANSLATE("Cannot register the video window"), status); return status; } fPort = fVideoConsumer->ControlPort(); /* find free producer output */ int32 cnt = 0; status = fMediaRoster->GetFreeOutputsFor(fProducerNode, &fProducerOut, 1, &cnt, B_MEDIA_RAW_VIDEO); if (status != B_OK || cnt < 1) { status = B_RESOURCE_UNAVAILABLE; fWindow->ErrorAlert(B_TRANSLATE("Cannot find an available video stream"), status); return status; } /* find free consumer input */ cnt = 0; status = fMediaRoster->GetFreeInputsFor(fVideoConsumer->Node(), &fConsumerIn, 1, &cnt, B_MEDIA_RAW_VIDEO); if (status != B_OK || cnt < 1) { status = B_RESOURCE_UNAVAILABLE; fWindow->ErrorAlert(B_TRANSLATE("Can't find an available connection to " "the video window"), status); return status; } /* Connect The Nodes!!! */ media_format format; format.type = B_MEDIA_RAW_VIDEO; media_raw_video_format vid_format = {0, 1, 0, 239, B_VIDEO_TOP_LEFT_RIGHT, 1, 1, {B_RGB32, VIDEO_SIZE_X, VIDEO_SIZE_Y, VIDEO_SIZE_X * 4, 0, 0}}; format.u.raw_video = vid_format; /* connect producer to consumer */ status = fMediaRoster->Connect(fProducerOut.source, fConsumerIn.destination, &format, &fProducerOut, &fConsumerIn); if (status != B_OK) { fWindow->ErrorAlert(B_TRANSLATE("Cannot connect the video source to " "the video window"), status); return status; } /* set time sources */ status = fMediaRoster->SetTimeSourceFor(fProducerNode.node, fTimeSourceNode.node); if (status != B_OK) { fWindow->ErrorAlert(B_TRANSLATE("Cannot set the time source for the " "video source"), status); return status; } status = fMediaRoster->SetTimeSourceFor(fVideoConsumer->ID(), fTimeSourceNode.node); if (status != B_OK) { fWindow->ErrorAlert(B_TRANSLATE("Cannot set the time source for the " "video window"), status); return status; } /* figure out what recording delay to use */ bigtime_t latency = 0; status = fMediaRoster->GetLatencyFor(fProducerNode, &latency); status = fMediaRoster->SetProducerRunModeDelay(fProducerNode, latency); /* start the nodes */ bigtime_t initLatency = 0; status = fMediaRoster->GetInitialLatencyFor(fProducerNode, &initLatency); if (status < B_OK) { fWindow->ErrorAlert(B_TRANSLATE("Error getting initial latency for the " "capture node"), status); return status; } initLatency += estimate_max_scheduling_latency(); BTimeSource* timeSource = fMediaRoster->MakeTimeSourceFor(fProducerNode); bool running = timeSource->IsRunning(); /* workaround for people without sound cards */ /* because the system time source won't be running */ bigtime_t real = BTimeSource::RealTime(); if (!running) { status = fMediaRoster->StartTimeSource(fTimeSourceNode, real); if (status != B_OK) { timeSource->Release(); fWindow->ErrorAlert(B_TRANSLATE("Cannot start time source!"), status); return status; } status = fMediaRoster->SeekTimeSource(fTimeSourceNode, 0, real); if (status != B_OK) { timeSource->Release(); fWindow->ErrorAlert(B_TRANSLATE("Cannot seek time source!"), status); return status; } } bigtime_t perf = timeSource->PerformanceTimeFor(real + latency + initLatency); timeSource->Release(); /* start the nodes */ status = fMediaRoster->StartNode(fProducerNode, perf); if (status != B_OK) { fWindow->ErrorAlert(B_TRANSLATE("Cannot start the video source"), status); return status; } status = fMediaRoster->StartNode(fVideoConsumer->Node(), perf); if (status != B_OK) { fWindow->ErrorAlert(B_TRANSLATE("Cannot start the video window"), status); return status; } return status; }
status_t NodeManager::_StartNodes() { status_t status = B_NO_INIT; if (!fMediaRoster) return status; bigtime_t latency = 0; bigtime_t initLatency = 0; if (fVideoProducer && fVideoConsumer) { // figure out what recording delay to use status = fMediaRoster->GetLatencyFor(fVideoConnection.producer, &latency); if (status < B_OK) { print_error("error getting latency for video producer", status); } else TRACE("video latency: %Ld\n", latency); status = fMediaRoster->SetProducerRunModeDelay( fVideoConnection.producer, latency); if (status < B_OK) { print_error("error settings run mode delay for video producer", status); } // start the nodes status = fMediaRoster->GetInitialLatencyFor( fVideoConnection.producer, &initLatency); if (status < B_OK) { print_error("error getting initial latency for video producer", status); } } initLatency += estimate_max_scheduling_latency(); if (fAudioProducer) { // TODO: was this supposed to be added to initLatency?!? bigtime_t audioLatency = 0; status = fMediaRoster->GetLatencyFor(fAudioConnection.producer, &audioLatency); TRACE("audio latency: %Ld\n", audioLatency); } BTimeSource* timeSource; if (fVideoProducer) { timeSource = fMediaRoster->MakeTimeSourceFor( fVideoConnection.producer); } else { timeSource = fMediaRoster->MakeTimeSourceFor( fAudioConnection.producer); } bool running = timeSource->IsRunning(); // workaround for people without sound cards // because the system time source won't be running bigtime_t real = BTimeSource::RealTime(); if (!running) { status = fMediaRoster->StartTimeSource(fTimeSource, real); if (status != B_OK) { timeSource->Release(); print_error("cannot start time source!", status); return status; } status = fMediaRoster->SeekTimeSource(fTimeSource, 0, real); if (status != B_OK) { timeSource->Release(); print_error("cannot seek time source!", status); return status; } } bigtime_t perf = timeSource->PerformanceTimeFor(real + latency + initLatency); timeSource->Release(); // start the nodes if (fVideoProducer && fVideoConsumer) { status = fMediaRoster->StartNode(fVideoConnection.consumer, perf); if (status != B_OK) { print_error("Can't start the video consumer", status); return status; } status = fMediaRoster->StartNode(fVideoConnection.producer, perf); if (status != B_OK) { print_error("Can't start the video producer", status); return status; } } if (fAudioProducer) { status = fMediaRoster->StartNode(fAudioConnection.producer, perf); if (status != B_OK) { print_error("Can't start the audio producer", status); return status; } } fPerformanceTimeBase = perf; return status; }