⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 video4beos.cxx

📁 sloedgy open sip stack source code
💻 CXX
📖 第 1 页 / 共 2 页
字号:
VideoConsumer::GetNextInput(
	int32 * cookie,
	media_input * out_input)
{
  PTRACE(TL, "VideoConsumer::GetNextInput");

  // custom build a destination for this connection
  // put connection number in id

  if (*cookie < 1)
  {
    mIn.node = Node();
    mIn.destination.id = *cookie;
    sprintf(mIn.name, "PWLV");
    *out_input = mIn;
    (*cookie)++;
    return B_OK;
  }
  else
  {
    PTRACE(1, "VideoConsumer::GetNextInput - bad index");
    return B_MEDIA_BAD_DESTINATION;
  }
}

void
VideoConsumer::DisposeInputCookie(int32 /*cookie*/)
{
}

status_t
VideoConsumer::GetLatencyFor(
  const media_destination &for_whom,
  bigtime_t * out_latency,
  media_node_id * out_timesource)
{
  PTRACE(TL, "VideoConsumer::GetLatencyFor");
	
  if (for_whom != mIn.destination)
    return B_MEDIA_BAD_DESTINATION;
	
  *out_latency = mMyLatency;
  *out_timesource = TimeSource()->ID();
  return B_OK;
}


status_t
VideoConsumer::FormatChanged(
  const media_source & producer,
  const media_destination & consumer, 
  int32 from_change_count,
  const media_format &format)
{
  PTRACE(TL, "VideoConsumer::FormatChanged");
	
  if (consumer != mIn.destination)
    return B_MEDIA_BAD_DESTINATION;

  if (producer != mIn.source)
    return B_MEDIA_BAD_SOURCE;

  mIn.format = format;
	
  return CreateBuffers(format);
}

void
VideoConsumer::HandleEvent(
  const media_timed_event *event,
  bigtime_t lateness,
  bool realTimeEvent)
{
  PTRACE(TL, "VideoConsumer::HandleEvent");
	
  BBuffer *buffer;
	
  switch (event->type)
  {
    case BTimedEventQueue::B_START:
    PTRACE(TL, "VideoConsumer::HandleEvent - start");
	break;

    case BTimedEventQueue::B_STOP:
    PTRACE(TL, "VideoConsumer::HandleEvent - stop");
    EventQueue()->FlushEvents(event->event_time, 
      BTimedEventQueue::B_ALWAYS, true, BTimedEventQueue::B_HANDLE_BUFFER);
	break;

    case BTimedEventQueue::B_HANDLE_BUFFER:
    PTRACE(TL, "VideoConsumer::HandleEvent - handle buffer");
    buffer = (BBuffer *) event->pointer;
    if (RunState() == B_STARTED)
    {
      // see if this is one of our buffers
      uint32 index = 0;
      mOurBuffers = true;
      while(index < 3)
      if ((uint32)buffer == mBufferMap[index])
        break;
      else
        index++;
						
      if (index == 3)
      {
        // no, buffers belong to consumer
	    mOurBuffers = false;
	    index = 0;
      }

      PWaitAndSignal ws(mFrameMutex);
	  memcpy(mFrames[index]->Bits(), buffer->Data(), mFrames[index]->BitsLength());
  }
  else
   buffer->Recycle();
   break;

 default:
   PTRACE(1, "VideoConsumer::HandleEvent - bad event");
   break;
  }			
}

void VideoConsumer::GetFrame(BYTE* buffer, 
   PINDEX* bytesReturned, 
  PColourConverter* converter) 
{ 
    PAssertNULL(bytesReturned);
    
    PWaitAndSignal ws(mFrameMutex);
    {
      const BYTE* frame = (const BYTE*) mFrames[0]->Bits();
    
      if (converter != NULL) 
      {
        converter->Convert(frame, buffer, bytesReturned);
      } 
      else 
      {
        memcpy(buffer, frame, *bytesReturned);
      }
    }
}

///////////////////////////////////////////////////////////////////////////////
// PVideoDevice

PVideoInputDevice_BeOSVideo::PVideoInputDevice_BeOSVideo()
  : captureThread(NULL)
{
  PTRACE(TL, "PVideoInputDevice_BeOSVideo");
  
  captureThread = NULL;
  isCapturingNow = FALSE;
}

BOOL PVideoInputDevice_BeOSVideo::Open(const PString & devName, BOOL startImmediate)
{
  PTRACE(TL, "PVideoInputDevice_BeOSVideo::Open");

  Close();

  frameWidth = CIFWidth;
  frameHeight = CIFHeight;
  colourFormat = "RGB32";

  deviceName = devName;

  if (startImmediate)
    return Start();
    
  return TRUE;
}


BOOL PVideoInputDevice_BeOSVideo::IsOpen() 
{
  PTRACE(TL, "PVideoInputDevice_BeOSVideo::IsOpen");
  return TRUE;
}


BOOL PVideoInputDevice_BeOSVideo::Close()
{
  PTRACE(TL, "PVideoInputDevice_BeOSVideo::Close");

  if (!IsOpen())
    return FALSE;
 
  Stop();

  return TRUE;
}


BOOL PVideoInputDevice_BeOSVideo::Start()
{
  PTRACE(TL, "PVideoInputDevice_BeOSVideo::Start");

  if (IsCapturing())
    return TRUE;
   
  StartNodes();    

  isCapturingNow = TRUE;

  return isCapturingNow;
}


BOOL PVideoInputDevice_BeOSVideo::Stop()
{
  PTRACE(TL, "PVideoInputDevice_BeOSVideo::Stop");

  if (!IsCapturing())
    return FALSE;

  StopNodes();
  ::snooze(100000);

  isCapturingNow = FALSE;

  return TRUE;
}


BOOL PVideoInputDevice_BeOSVideo::IsCapturing()
{
  return isCapturingNow;
}


BOOL PVideoInputDevice_BeOSVideo::TestAllFormats() 
{
  BOOL running = IsCapturing();
  if (running)
    Stop();

  if (running)
    return Start();

  return TRUE;
}


BOOL PVideoInputDevice_BeOSVideo::SetFrameRate(unsigned rate)
{
  PTRACE(TL, "PVideoInputDevice_BeOSVideo::SetFrameRate");

  if (!PVideoDevice::SetFrameRate(rate))
    return FALSE;

  BOOL running = IsCapturing();
  if (running)
    Stop();
  
  if (running)
    return Start();

  return TRUE;
}


BOOL PVideoInputDevice_BeOSVideo::SetFrameSize(unsigned width, unsigned height)
{
  PTRACE(TL, "PVideoInputDevice_BeOSVideo::SetFrameSize, width " << width << " height " << height);

  BOOL running = IsCapturing();
  if (running)
    Stop();

  if (!PVideoDevice::SetFrameSize(width, height))
    return FALSE;

  if (running)
    return Start();

  return TRUE;
}

BOOL PVideoInputDevice_BeOSVideo::SetColourFormat(const PString & colourFmt)
{
  PTRACE(TL, "PVideoInputDevice_BeOSVideo::SetColourFormat, format" << colourFmt);
 
  BOOL running = IsCapturing();
  if (running)
    Stop();

  if (!PVideoDevice::SetColourFormat(colourFmt)) {
    return FALSE;
  }

  converter = PColourConverter::Create("RGB32", colourFormat, frameWidth, frameHeight);
  if (converter == NULL) {
    PTRACE(1, "Failed to make a converter.");
    return FALSE;
  }

//  if (converter->SetSrcFrameSize(width,height) == FALSE) {
//    PTRACE(1, "Failed to set source frame size of a converter.");
//    return FALSE;
//  }
//  if (converter->SetDstFrameSize(desiredFrameWidth, desiredFrameHeight, FALSE) == FALSE) {
//    PTRACE(1, "Failed to set destination frame size (+scaling) of a converter.");
//    return FALSE;
//  }
    
  if (running)
    return Start();

  return TRUE;
}


PStringList PVideoInputDevice_BeOSVideo::GetInputDeviceNames()
{
  PStringList list;

  list.AppendString("MediaKit"); 
  return list;
}


PINDEX PVideoInputDevice_BeOSVideo::GetMaxFrameBytes()
{
  if (!IsOpen())
    return 0;
  
  return GetMaxFrameBytesConverted(frameWidth * frameHeight *4); // RGB32 only 
}


BOOL PVideoInputDevice_BeOSVideo::GetFrameData(BYTE * buffer, PINDEX * bytesReturned)
{
  return GetFrameDataNoDelay(buffer, bytesReturned);
}

BOOL PVideoInputDevice_BeOSVideo::GetFrameDataNoDelay(BYTE * buffer, PINDEX * bytesReturned)
{
  PTRACE(TL, "PVideoInputDevice_BeOSVideo::GetFrameDataNoDelay");
  if (!IsCapturing()) 
    return FALSE;
  
  *bytesReturned = GetMaxFrameBytes();
  fVideoConsumer->GetFrame(buffer, bytesReturned, converter);
   
  return TRUE;
}

status_t PVideoInputDevice_BeOSVideo::StartNodes()
{
  PTRACE(TL, "StartNodes!");
  status_t status = B_OK;

  // find the media roster 
  fMediaRoster = BMediaRoster::Roster(&status);
  if (status != B_OK) 
  {
    PTRACE(3, "Can't find the media roster, status " << status);
    return status;
  }	

  // find the time source 
  status = fMediaRoster->GetTimeSource(&fTimeSourceNode);
  if (status != B_OK) 
  {
    PTRACE(3, "Can't get a time source, status " << status);
    return status;
  }

  // find a video producer node 
  PTRACE(3, "PVideoInputDevice_BeOSVideo acquiring video input node");
  status = fMediaRoster->GetVideoInput(&fProducerNode);
  if (status != B_OK) 
  {
    PTRACE(3, "Can't find a video input!, status " << status);
    return status;
  } 

  // create the video consumer node 
  fVideoConsumer = new VideoConsumer("PWLV", NULL, 0, frameWidth, frameHeight);

  if (!fVideoConsumer) 
  {
    PTRACE(3, "Can't create a video consumer");
    return B_ERROR;
  }
	
  // register the node 
  status = fMediaRoster->RegisterNode(fVideoConsumer);
  if (status != B_OK) 
  {
    PTRACE(3, "Can't register the video consumer, status " << 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;
    PTRACE(3, "Can't find an available video stream, status " << 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;
    PTRACE(3, 
     "Can't find an available connection to the video consumer, status " << status);
    return status;
  }

  // Connect The Nodes!!! 
  media_format format;
  format.type = B_MEDIA_RAW_VIDEO;
  media_raw_video_format vid_format = 
    { 0, 1, 0, 175, // YK
       B_VIDEO_TOP_LEFT_RIGHT, 1, 1, 
      {B_RGB32, 0, 0, 0, 0, 0}};

  vid_format.display.line_width = frameWidth;
  vid_format.display.line_count = frameHeight; 
  vid_format.display.bytes_per_row = frameWidth * 4; // RGB32 only

  format.u.raw_video = vid_format; 
	
  // connect producer to consumer 
  status = fMediaRoster->Connect(fProducerOut.source, fConsumerIn.destination,
				&format, &fProducerOut, &fConsumerIn);
  if (status != B_OK) 
  {
    PTRACE(3, "Can't connect the video source to the video consumer, status " << status);
    return status;
  }
	
  // set time sources 
  status = fMediaRoster->SetTimeSourceFor(fProducerNode.node, fTimeSourceNode.node);
  if (status != B_OK) 
  {
    PTRACE(3, "Can't set the timesource for the video source, status " << status);
    return status;
  }
	
  status = fMediaRoster->SetTimeSourceFor(fVideoConsumer->ID(), fTimeSourceNode.node);
  if (status != B_OK) 
  {
    PTRACE(3, "Can't set the timesource for the video consumer, status " << 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) 
  {
    PTRACE(3, "error getting initial latency for fCaptureNode, status " << 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();
      PTRACE(3, "Cannot start time source!, status" << status);
      return status;
    }
   
    status = fMediaRoster->SeekTimeSource(fTimeSourceNode, 0, real);
    if (status != B_OK) 
    {
       timeSource->Release();
       PTRACE(3, "Cannot seek time source!, status " << 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) 
  {
    PTRACE(3, "Can't start the video source, status " << status);
    return status;
  }

  status = fMediaRoster->StartNode(fVideoConsumer->Node(), perf);
  if (status != B_OK) 
  {
    PTRACE(3, "Can't start the video consumer, status " << status);
    return status;
  }
	
  return status;
}

void PVideoInputDevice_BeOSVideo::StopNodes()
{
  PTRACE(TL, "StopNodes");
  if (!fMediaRoster)
    return;
	
  if (fVideoConsumer)
  {
    // stop 	
    PTRACE(TL, "Stopping nodes!");
    fMediaRoster->StopNode(fProducerNode, 0, true);
    fMediaRoster->StopNode(fVideoConsumer->Node(), 0, true);
	
    // disconnect 
    fMediaRoster->Disconnect(
        fProducerOut.node.node, fProducerOut.source,
	fConsumerIn.node.node, fConsumerIn.destination);
								
    if(fProducerNode != media_node::null) 
    {
      PTRACE(TL, "Releasing fProducerNode");
      fMediaRoster->ReleaseNode(fProducerNode);
      fProducerNode = media_node::null;
    }

     fMediaRoster->ReleaseNode(fVideoConsumer->Node());		
     fVideoConsumer = NULL;
     
  } // if video consumer
}

// End Of File ///////////////////////////////////////////////////////////////

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -