OSErr DoPlayMovie(Boolean useOverlay)
{
    Rect movieBounds;
	OSErr err;

    BailErr((err = GetAMovieFile(&mMovie)));
    
    GetMovieBox(mMovie, &movieBounds);
    mMovieController = NewMovieController(mMovie, &movieBounds, mcTopLeftMovie | mcNotVisible);
    
    NormalizeMovieRect(mMovie);
    
    GetMovieBox(mMovie, &movieBounds);
	BailErr((err = InitializeMungData(movieBounds, 
							FrontWindow(), 
							useOverlay, /* overlay */
							true, 		/* clamp */
							false 		/* draw with QT Effect */
							)));
	// This is key, as we need to draw all frames in our
	// offscreen gworld first. Once there, our custom
	// decompressor component can perform overlay drawing
	// or color clamping
    SetMovieGWorld(mMovie, GetMungDataOffscreen(), nil);
	
	// Our DrawCompleteProc calls BlitOneMungData which
    SetupMovieDrawCompleteProc();
    // ---------
    
    SetMovieActive(mMovie, true);
#ifndef __APPLE_CC__
	// Due to a bug in Jaguar, some QT functions are missing from 
	// /System/Library/CFMSupport/CarbonLib, so we must manually
	// grab the function pointers from the QuickTime.framework
	// for CFM Carbon applications. MachO Carbon applications do not
	// have the problem.
    GetMissingQTFunctionPointers();
#endif
    InstallMovieIdlingEventLoopTimer(&mMovieTimerState);
        // start the movie playing
    MCDoAction(mMovieController, mcActionPrerollAndPlay, (void*)Long2Fix(1));

bail:
    return err;

}
OSErr CreateNewSGChannelForRecording(ComponentInstance seqGrab, SGDataUPP dataProc, CGrafPtr drawPort, Rect *theRect, SGChannel *sgChannel, long refCon)
{
	OSErr err = noErr;
	
	BailErr((err = SGInitialize(seqGrab)));

	// tell it we're not making a movie
	BailErr((err = SGSetDataRef(seqGrab,0,0,seqGrabDontMakeMovie)));
	// It wants a port, even if its not drawing to it
	BailErr((err = SGSetGWorld(seqGrab, drawPort, GetMainDevice())));
	BailErr((err = SGNewChannel(seqGrab, VideoMediaType, sgChannel)));
	
	// let the user configure the video channel
	BailErr((err = SGSettingsDialog(seqGrab, *sgChannel, 0, nil, 0, nil, 0)));
	BailErr((err = SGSetChannelBounds(*sgChannel, theRect)));
	// set usage for new video channel to avoid playthrough
	BailErr((err = SGSetChannelUsage(*sgChannel, seqGrabRecord ))); //note we don't set seqGrabPlayDuringRecord
    BailErr((err = SGSetDataProc(seqGrab, dataProc, refCon)));
	BailErr((err = SGStartRecord(seqGrab)));

bail:
    return err;
}
Beispiel #3
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;
}