Ejemplo n.º 1
0
void KMInstance::allocate(size_t nbObs, size_t nbAtt) {
	_data = RectMatrix(nbObs, nbAtt);
	_cst = 0;
	_weights.assign(nbObs, 1);
	_must = KMConstraints(nbObs);
	_cannot = KMConstraints(nbObs);
}
Ejemplo n.º 2
0
// ######################################################################
static void setVideoChannelBounds(SGChannel videoChannel,
                                  const Rect* scaledSourceBounds,
                                  const Rect* scaledVideoBounds)
{
  // Notes: see Q&A 1250

  // calculate the matrix to transform the
  // scaledSourceBounds to the source bounds
  Rect sourceBounds;
  SGGetSrcVideoBounds(videoChannel, &sourceBounds);

  MatrixRecord scaledSourceBoundsToSourceBounds;
  RectMatrix(&scaledSourceBoundsToSourceBounds,
             scaledSourceBounds, &sourceBounds);

  // apply the same transform to the
  // scaledVideoBounds to get the video bounds
  Rect videoBounds = *scaledVideoBounds;
  TransformRect(&scaledSourceBoundsToSourceBounds, &videoBounds, 0);

  if (noErr != SGSetVideoRect(videoChannel, &videoBounds))
    {
      // some video digitizers may only be able to capture full frame
      // and will return qtParamErr or possibly digiUnimpErr if they
      // can't handle working with less than full frame
      SGSetVideoRect(videoChannel, &sourceBounds);
    }

  // the channel bounds is scaledVideoBounds offset to (0, 0)
  Rect channelBounds = *scaledVideoBounds;
  OffsetRect(&channelBounds, -channelBounds.left, -channelBounds.top);

  // Note: SGSetChannelBounds merely allows the client to specify it's
  // preferred bounds. The actual bounds returned by the vDig in the
  // image description may be different
  if (noErr != SGSetChannelBounds(videoChannel, &channelBounds))
    LFATAL("SGSetChannelBounds() failed");
}
Ejemplo n.º 3
0
OSErr CreateDecompSeqForSGChannelData(SGChannel sgChannel, Rect *srcBounds, GWorldPtr imageDestination, ImageSequence *imageSeqID)
{
	OSErr err = noErr;
	
	ImageDescriptionHandle	imageDesc = (ImageDescriptionHandle)NewHandle(sizeof(ImageDescription));
	if (imageDesc)
	{

		err = SGGetChannelSampleDescription(sgChannel,(Handle)imageDesc);
		// The original version of this code had a bug - it passed in a Crop Rect to DecompressSequenceBegin instead of a scaling matrix
		// This only worked because of another bug inside QT that reated the crop Rect as a destination rect for DV
		// the following code does the right thing in all cases.
		
		if (err == noErr)
		{
			MatrixRecord 	mr;
			Rect 			fromR;

			fromR.left = 0;
			fromR.top = 0;
			fromR.right = (**imageDesc).width;
			fromR.bottom = (**imageDesc).height;
			RectMatrix(&mr, &fromR, srcBounds);
			
			err = DecompressSequenceBegin(imageSeqID, imageDesc, imageDestination, 0, nil, &mr,srcCopy,nil,0, codecNormalQuality, bestSpeedCodec);
		}
		
		DisposeHandle((Handle)imageDesc);
	}
	else
	{
		err = MemError();
	}
	
	return err;
}
Ejemplo n.º 4
0
static GstStateChangeReturn
gst_osx_video_src_change_state (GstElement * element, GstStateChange transition)
{
  GstStateChangeReturn result;
  GstOSXVideoSrc *self;
  ComponentResult err;

  result = GST_STATE_CHANGE_SUCCESS;
  self = GST_OSX_VIDEO_SRC (element);

  // ###: prepare_capture in READY->PAUSED?

  switch (transition) {
    case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
    {
      ImageDescriptionHandle imageDesc;
      Rect sourceRect;
      MatrixRecord scaleMatrix;

      if (!prepare_capture (self))
        return GST_STATE_CHANGE_FAILURE;

      // ###: should we start recording /after/ making the decompressionsequence?
      //   CocoaSequenceGrabber does it beforehand, so we do too, but it feels
      //   wrong.
      err = SGStartRecord (self->seq_grab);
      if (err != noErr) {
        /* since we prepare here, we should also unprepare */
        SGRelease (self->seq_grab);

        GST_ERROR_OBJECT (self, "SGStartRecord returned %d", (int) err);
        return GST_STATE_CHANGE_FAILURE;
      }

      imageDesc = (ImageDescriptionHandle) NewHandle (0);

      err = SGGetChannelSampleDescription (self->video_chan,
          (Handle) imageDesc);
      if (err != noErr) {
        SGStop (self->seq_grab);
        SGRelease (self->seq_grab);
        DisposeHandle ((Handle) imageDesc);
        GST_ERROR_OBJECT (self, "SGGetChannelSampleDescription returned %d",
            (int) err);
        return GST_STATE_CHANGE_FAILURE;
      }

      GST_DEBUG_OBJECT (self, "actual capture resolution is %dx%d",
          (int) (**imageDesc).width, (int) (**imageDesc).height);

      SetRect (&sourceRect, 0, 0, (**imageDesc).width, (**imageDesc).height);
      RectMatrix (&scaleMatrix, &sourceRect, &self->rect);

      err = DecompressSequenceBegin (&self->dec_seq, imageDesc, self->world,
          NULL, NULL, &scaleMatrix, srcCopy, NULL, 0, codecNormalQuality,
          bestSpeedCodec);
      if (err != noErr) {
        SGStop (self->seq_grab);
        SGRelease (self->seq_grab);
        DisposeHandle ((Handle) imageDesc);
        GST_ERROR_OBJECT (self, "DecompressSequenceBegin returned %d",
            (int) err);
        return GST_STATE_CHANGE_FAILURE;
      }

      DisposeHandle ((Handle) imageDesc);
      break;
    }
    default:
      break;
  }

  result = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
  if (result == GST_STATE_CHANGE_FAILURE)
    return result;

  switch (transition) {
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      SGStop (self->seq_grab);

      err = CDSequenceEnd (self->dec_seq);
      if (err != noErr)
        GST_WARNING_OBJECT (self, "CDSequenceEnd returned %d", (int) err);
      self->dec_seq = 0;

      SGRelease (self->seq_grab);
      break;
    default:
      break;
  }

  return result;
}
Ejemplo n.º 5
0
// ######################################################################
OSErr QuickTimeGrabber::Impl::grabData(SGChannel c, Ptr p,
                                       long len, TimeValue time)
{
  if (itsGotFrame)
    {
      LDEBUG("already got a frame on this iteration");
      return noErr;
    }

  // we only care about the video
  if (c != itsSGChanVideo.it)
    {
      return noErr;
    }

  // reset frame and time counters after a stop/start
  if (time < itsPrevTime)
    {
      LDEBUG("resetting frame/time counters (current=%ld, last=%ld)",
             (long) time, (long) itsPrevTime);
      itsPrevTime = 0;
      itsFrameCount = 0;
    }

  if (itsTimeScale == 0)
    {
      LDEBUG("setting up time scale & timebase");

      Fixed framesPerSecond;
      long  milliSecPerFrameIgnore, bytesPerSecondIgnore;

      // first time here so get the time scale & timebase
      if (noErr != SGGetChannelTimeScale(c, &itsTimeScale))
        {
          itsErrorMsg = "SGGetChannelTimeScale() failed";
          return OSErr(-1);
        }

      if (noErr != SGGetTimeBase(itsSeqGrab.it, &itsTimeBase))
        {
          itsErrorMsg = "SGGetTimeBase() failed";
          return OSErr(-1);
        }

      if (noErr != VDGetDataRate(SGGetVideoDigitizerComponent(c),
                                 &milliSecPerFrameIgnore,
                                 &framesPerSecond,
                                 &bytesPerSecondIgnore))
        {
          itsErrorMsg = "VDGetDataRate() failed";
          return OSErr(-1);
        }
    }

  if (itsDrawSeq == 0)
    {
      LDEBUG("setting up decompression sequence");

      // set up decompression sequence
      ImageDescriptionHandle imageDesc =
        (ImageDescriptionHandle)NewHandle(0);

      // retrieve a channel's current sample description, the channel
      // returns a sample description that is appropriate to the type
      // of data being captured
      if (noErr != SGGetChannelSampleDescription(c, (Handle)imageDesc))
        {
          itsErrorMsg = "SGGetChannelSampleDescription() failed";
          return OSErr(-1);
        }

      // make a scaling matrix for the sequence
      Rect sourceRect = { 0, 0 };
      sourceRect.right = (**imageDesc).width;
      sourceRect.bottom = (**imageDesc).height;

      Rect scaleRect;
      GetPixBounds(GetGWorldPixMap(itsGWorld), &scaleRect);

      // if DV do high quality 720x480 both fields
      CodecFlags cFlags =
        (kDVCNTSCCodecType == (**imageDesc).cType)
        ? codecHighQuality
        : codecNormalQuality;

      MatrixRecord scaleMatrix;
      RectMatrix(&scaleMatrix, &sourceRect, &scaleRect);

      LINFO("sourceRect = %dx%d, scaleRect = %dx%d",
            sourceRect.right - sourceRect.left,
            sourceRect.bottom - sourceRect.top,
            scaleRect.right - scaleRect.left,
            scaleRect.bottom - scaleRect.top);

      // begin the process of decompressing a sequence of frames this
      // is a set-up call and is only called once for the sequence -
      // the ICM will interrogate different codecs and construct a
      // suitable decompression chain, as this is a time consuming
      // process we don't want to do this once per frame (eg. by using
      // DecompressImage) for more information see Ice Floe #8
      // http://developer.apple.com/quicktime/icefloe/dispatch008.html
      // the destination is specified as the GWorld
      CGrafPtr dest = itsGWorld;
      if (noErr != DecompressSequenceBeginS
          (&itsDrawSeq,     // pointer to field to receive unique ID for sequence
           imageDesc,       // handle to image description structure
           p,               // points to the compressed image data
           len,             // size of the data buffer
           dest,            // port for the DESTINATION image
           NULL,            // graphics device handle, if port is set, set to NULL
           NULL,            // decompress the entire source image - no source extraction
           &scaleMatrix,    // transformation matrix
           srcCopy,         // transfer mode specifier
           (RgnHandle)NULL, // clipping region in dest. coordinate system to use as a mask
           0,               // flags
           cFlags,          // accuracy in decompression
           bestSpeedCodec)) // compressor identifier or special identifiers ie. bestSpeedCodec
        {
          itsErrorMsg = "DSeqBegin failed";
          return OSErr(-1);
        }

      DisposeHandle((Handle)imageDesc);

    } // itsDrawSeq == 0

  // get the TimeBase time and figure out the delta between that time
  // and this frame time
  const TimeValue timeBaseTime = GetTimeBaseTime(itsTimeBase,
                                                 itsTimeScale, NULL);
  const TimeValue timeBaseDelta = timeBaseTime - time;
  const TimeValue frameTimeDelta = time - itsPrevTime;

  if (timeBaseDelta < 0)
    {
      itsErrorMsg = "bogus timeBaseDelta";
      return OSErr(-1);
    }

  // if we have more than one queued frame and our capture rate drops
  // below 10 frames, skip the frame to try and catch up
  if ((itsQueuedFrameCount > 1)
      &&  ((itsTimeScale / frameTimeDelta) < 10)
      && (itsSkipFrameCount < 15))
    {
      LDEBUG("dropping frame");
      ++itsSkipFrameCount;
      ++itsSkipFrameCountTotal;
    }
  else
    {
      itsFrameCount++;

      CodecFlags ignore;

      // decompress a frame into the window - can queue a frame for async decompression when passed in a completion proc
      if (noErr != DecompressSequenceFrameS
          (itsDrawSeq, // sequence ID returned by DecompressSequenceBegin
           p,          // pointer to compressed image data
           len,        // size of the buffer
           0,          // in flags
           &ignore,    // out flags
           NULL))      // async completion proc
        {
          itsErrorMsg =  "DSeqFrameS failed";
          return OSErr(-1);
        }

      // get the information we need from the GWorld
      Rect pbound;
      GetPixBounds(GetGWorldPixMap(itsGWorld), &pbound);

      char* const baseAddr =
        GetPixBaseAddr(GetGWorldPixMap(itsGWorld));

      const long rowBytes =
        QTGetPixMapHandleRowBytes(GetGWorldPixMap(itsGWorld));

      itsCurrentImage.resize(Dims(pbound.right - pbound.left,
                                     pbound.bottom - pbound.top));

      Image<PixRGB<byte> >::iterator itr = itsCurrentImage.beginw();

      for (int y = pbound.top; y < pbound.bottom; ++y)
        {
          char* p = baseAddr + rowBytes * (y-pbound.top);

          for (int x = pbound.left; x < pbound.right; ++x)
            {
              const UInt32 color = *((UInt32*)(p) + x - pbound.left);
              const UInt32 R = (color & 0x00FF0000) >> 16;
              const UInt32 G = (color & 0x0000FF00) >> 8;
              const UInt32 B = (color & 0x000000FF) >> 0;

              *itr++ = PixRGB<byte>(R,G,B);
            }
        }

      itsSkipFrameCount = 0;
      itsPrevTime = time;
      itsGotFrame = true;
    }

  // status information
  const float fps = (float)itsTimeScale / (float)frameTimeDelta;
  const float averagefps = ((float)itsFrameCount * (float)itsTimeScale) / (float)time;
  const UInt8 minutes = (time / itsTimeScale) / 60;
  const UInt8 seconds = (time / itsTimeScale) % 60;
  const UInt8 frames = (time % itsTimeScale) / frameTimeDelta;
  LDEBUG("#%06ld t:%ld nq:%u, %02d:%02d.%02d, fps:%5.1f av:%5.1f",
         itsFrameCount, time, itsQueuedFrameCount,
         minutes, seconds, frames, fps, averagefps);

  return noErr;
}
Ejemplo n.º 6
0
pascal OSErr sgdata_callback(SGChannel c, Ptr p, long len, long *offset, long chRefCon, TimeValue time, short writeType, long refCon)
{
#pragma unused(offset,chRefCon,time,writeType)
    
    CodecFlags     ignore;
    V4lState *s=(V4lState *)refCon;
    ComponentResult err = noErr;
    
    if (!s) goto bail;
   
    Rect boundsRect = {0, 0, s->vsize.height, s->vsize.width}; /* 240 , 320*/
    if (s->pgworld) {

      if (s->decomseq == 0) {
	Rect sourceRect = { 0, 0 };
	MatrixRecord scaleMatrix;
	ImageDescriptionHandle imageDesc = (ImageDescriptionHandle)NewHandle(0);
	
	err = SGGetChannelSampleDescription(c,(Handle)imageDesc);
	BailErr(err);
	
	// make a scaling matrix for the sequence
	sourceRect.right = (**imageDesc).width;
	sourceRect.bottom = (**imageDesc).height;
	RectMatrix(&scaleMatrix, &sourceRect, &boundsRect);
            
	err = DecompressSequenceBegin(&s->decomseq,  // pointer to field to receive unique ID for sequence
				      imageDesc,        // handle to image description structure
				      s->pgworld,    // port for the DESTINATION image
				      NULL,            // graphics device handle, if port is set, set to NULL
				      NULL,            // source rectangle defining the portion of the image to decompress
				      &scaleMatrix,        // transformation matrix
				      srcCopy,          // transfer mode specifier
				      NULL,            // clipping region in dest. coordinate system to use as a mask
				      0,            // flags
				      codecNormalQuality,    // accuracy in decompression
				      bestSpeedCodec);      // compressor identifier or special identifiers ie. bestSpeedCodec
	BailErr(err);
	
	DisposeHandle((Handle)imageDesc);
	imageDesc = NULL;
      }
      
      // decompress a frame into the GWorld - can queue a frame for async decompression when passed in a completion proc
      // once the image is in the GWorld it can be manipulated at will
      err = DecompressSequenceFrameS(s->decomseq,  // sequence ID returned by DecompressSequenceBegin
				     p,            // pointer to compressed image data
				     len,          // size of the buffer
				     0,            // in flags
				     &ignore,        // out flags
				     NULL);          // async completion proc
        BailErr(err);
        
    {
      unsigned line;
      mblk_t *buf;
      int size = s->vsize.width * s->vsize.height * 3;
      buf=allocb(size,0);
      
      PixMap * pixmap = *GetGWorldPixMap(s->pgworld);
      uint8_t * data;
      unsigned rowBytes = pixmap->rowBytes & (((unsigned short) 0xFFFF) >> 2);
      unsigned pixelSize = pixmap->pixelSize / 8; // Pixel size in bytes
      unsigned lineOffset = rowBytes - s->vsize.width * pixelSize;
      
      data = (uint8_t *) GetPixBaseAddr(GetGWorldPixMap(s->pgworld));
      
      for (line = 0 ; line < s->vsize.height ; line++) {
	unsigned offset = line * (s->vsize.width * pixelSize + lineOffset);
	memcpy(buf->b_wptr + ((line * s->vsize.width) * pixelSize), data + offset, (rowBytes - lineOffset));
      }

      if (s->pix_fmt==MS_RGB24)
	{
	  /* Conversion from top down bottom up (BGR to RGB and flip) */
	  unsigned long Index,nPixels;
	  unsigned char *blue;
	  unsigned char tmp;
	  short iPixelSize;

	  blue=buf->b_wptr;

	  nPixels=s->vsize.width*s->vsize.height;
	  iPixelSize=24/8;

	  for(Index=0;Index!=nPixels;Index++)  // For each pixel
	    {
	      tmp=*blue;
	      *blue=*(blue+2);
	      *(blue+2)=tmp;
	      blue+=iPixelSize;
	    }
	}

      buf->b_wptr+=size;
      ms_mutex_lock(&s->mutex);
      putq(&s->rq, buf);
      ms_mutex_unlock(&s->mutex);
    }
  }

bail:
  return err;
}