Hi all, I am working on an application that involves real time video
editing with Core Framework in Cocoa. For testing we basically have a
DVI cam hooked up to a Mac Book Pro and need to be able to edit the
stream it produces. I successfully got the video into quick time using
QTKit, but am having trouble aquiring the frames with a display link.
The example in the Core Video guide shows it initializing the video
source from file with this method:
* (id)initWithFilePath: (NSString*)theFilePath
, but I need to get the frames I can already access into the display
link for OpenGL rendering and Core Image effects. Right now i have it
output via QTCaptureView. But if I want to do openGL rendering/Core
Image effects on the frame does it need to be an NSOpenGLView? If
anyone has any ideas or advice I would greatly appreciate it. Thanks
in advance!
Here is what I have thus far....maybe it will help show where I am at
and hoping to go.
//
// VideoDisplayController.m
// Prototype492
//
// Created on 3/7/08.
//
#import "VideoDisplayController.h"
@[EMAIL PROTECTED]
VideoDisplayController
/*
start the video capture session if it's not running
*/
- (IBAction)startVideoCapture:(id)sender
{
if(![captureSession isRunning])
{
[captureSession startRunning];
}
}
/*
stop the video capture session if it's running
*/
- (IBAction)stopVideoCapture:(id)sender
{
if([captureSession isRunning])
{
[captureSession stopRunning];
}
}
/*
initialization of UI elements
*/
- (void)awakeFromNib
{
NSLog(@[EMAIL PROTECTED]
"initializing video controller");
if(!captureSession) {
//creating capture session
captureSession = [[QTCaptureSession alloc] init];
//flags for connecting inputs and outputs
BOOL successConnect = NO;
NSError *error = nil;
//finding and creating the input device and adding it to
the
capture session
//if unsuccessful, send a message to error log
//note: using QTMediaTypeMuxed for DV camera... otherwise use
QTMediaTypeVideo
videoCaptureDevice = [QTCaptureDevice
defaultInputDeviceWithMediaType:QTMediaTypeMuxed];
//if the video capture device is found, attempt to open it
and
add it to the capture session
if(videoCaptureDevice)
{
successConnect = [videoCaptureDevice open:&error];
if(!successConnect)
{
NSLog(@[EMAIL PROTECTED]
"error opening video capture device");
videoCaptureDevice = nil;
//other error handling code goes here
}
captureVideoDeviceInput = [[QTCaptureDeviceInput alloc]
initWithDevice:videoCaptureDevice];
//attempt to add capture device input to the capture
session
successConnect = [captureSession
addInput:captureVideoDeviceInput error:&error];
if(!successConnect)
{
NSLog(@[EMAIL PROTECTED]
"error adding video capture device
input to capture
session");
//other error handling code goes here
}
//adding decompressed video output to capture session
decompressedVideoOutput =
[[QTCaptureDecompressedVideoOutput alloc]
init];
//assigning delegate to decompressed video
output
[decompressedVideoOutput setDelegate: self];
successConnect = [captureSession
addOutput:decompressedVideoOutput
error:&error];
if(!successConnect)
{
NSLog(@[EMAIL PROTECTED]
"error adding decompressed video
output to capture
session");
//other error handling code goes here
}
//linking capture session to the capture view
[captureView setCaptureSession:captureSession];
//[captureSession startRunning];
}
else
{
NSLog(@[EMAIL PROTECTED]
"couldn't find video capture device");
}
}
}
/*
delegate method called when decompressedVideoOutput receives a frame
it is not called in the main thread, so a synhronized block is used
delegates of decompressedVideoOutput receive this message
and then can used the provided video frame for further image
processing
captureOutput - the QTCaptureDecompressedVideoOutput instance that
sent the frame (decompressedVideoOutput)
videoFrame - Core Video image buffer containing the decompressed frame
sampleBuffer sample buffer containing additional info about the frame
connection - connnection from which vdieo was received
*/
- (void)captureOutput:(QTCaptureOutput *)captureOutput
didOutputVideoFrame:(CVImageBufferRef)videoFrame
withSampleBuffer:(QTSampleBuffer *)sampleBuffer
fromConnection:(QTCaptureConnection *)connection
{
CVImageBufferRef releasedImageBuffer;
CVBufferRetain(videoFrame);
@[EMAIL PROTECTED]
(self)
{
//basically, have frame to be released refer to the current
frame
//then update the reference to the current frame with
the next frame
in the "video stream"
releasedImageBuffer = currentImageBuffer;
currentImageBuffer = videoFrame;
}
CVBufferRelease(releasedImageBuffer);
}
/*
event that's fired when window is closed
stop the session and close any opened devices
*/
- (void)windowWillClose:(NSNotification *)notification
{
if([captureSession isRunning])
{
[captureSession stopRunning];
}
if([videoCaptureDevice isOpen])
{
[videoCaptureDevice close];
}
}
/*
event that fires when memory is to be deallocated when object is
killed
*/
- (void)dealloc
{
[captureSession release];
[captureVideoDeviceInput release];
[decompressedVideoOutput release];
[super dealloc];
}
@[EMAIL PROTECTED]
VideoDisplayController.h
// Prototype492v1.1
//
// Updated on 3/8/08.
//
#import <Cocoa/Cocoa.h>
#import <QTKit/QTkit.h>
#import "VideoView.h"
@[EMAIL PROTECTED]
VideoDisplayController : NSOpenGLView
{
QTCaptureSession *captureSession;
QTCaptureDevice *videoCaptureDevice;
QTCaptureDeviceInput *captureVideoDeviceInput;
QTCaptureDecompressedVideoOutput *decompressedVideoOutput;
//stores most recent frame grabbed from a CVImageBufferRef
CVImageBufferRef currentImageBuffer;
//this is the panel on which the video from the DV camera will be
displayed
IBOutlet QTCaptureView *captureView;
//IBOutlet VideoView *openGLVideoView;
}
- (IBAction)startVideoCapture:(id)sender;
- (IBAction)stopVideoCapture:(id)sender;
@[EMAIL PROTECTED]