views:

1127

answers:

2

Hi to all

I'm implementing a software to caputre video from webcam. I've seen MyRecorder sample in Apple Dev and it works fine.

I've tried to add a button to take a snapshot from video with this code:

- (IBAction)addFrame:(id)sender
{
    CVImageBufferRef imageBuffer;
    @synchronized (self) {
        imageBuffer = CVBufferRetain(mCurrentImageBuffer);
    }
    if (imageBuffer) { 
    [ bla bla bla ]  
    }
}

but mCurrentImageBuffer is always empty. How can I take current frame from my webcam and put on mCurrentImageBuffer?

I've tried to use

(void)captureOutput:(QTCaptureOutput *)captureOutput 
        didOutputVideoFrame:(CVImageBufferRef)videoFrame 
        withSampleBuffer:(QTSampleBuffer *)sampleBuffer 
        fromConnection:(QTCaptureConnection *)connection
{
    CVImageBufferRef imageBufferToRelease;

    CVBufferRetain(videoFrame);

    @synchronized (self) {
        imageBufferToRelease = mCurrentImageBuffer;
        mCurrentImageBuffer = videoFrame;
    }
    CVBufferRelease(imageBufferToRelease);  
}

but it's never called. How can I decide when call captureOutput delegate method? Any idea?

thanks, Andrea

+2  A: 

I've tried to use

- (void)captureOutput:(QTCaptureOutput *)captureOutput 
                                didOutputVideoFrame:(CVImageBufferRef)videoFrame 
                                withSampleBuffer:(QTSampleBuffer *)sampleBuffer 
                                fromConnection:(QTCaptureConnection *)connection

but it's never called.

Is the object implementing this method the capture output object's delegate?

Peter Hosey
This is my problem, I don't understand well this step.
Andrea Girardi
You need to be the capture output object's delegate. See http://developer.apple.com/mac/library/documentation/General/Conceptual/DevPedia-CocoaCore/Delegation.html and the `setDelegate:` method of the capture output object.
Peter Hosey
Perfect, I've seen on Apple sample (very usefull) thanks!
Andrea Girardi
+1  A: 

It looks like you're trying to use the QTKit Capture API for capturing video from your webcam. The MyRecorder sample application is pretty much the simplest functioning video capture program you can make using this API. It wasn't clear from your description, but you need to make sure that you follow their example, and initialize your video session in the same manner as they do in the -awakeFromNib method within MyRecorderController. If you don't, you won't get any video being captured.

As far as the method you're trying to use, -captureOutput:didOutputVideoFrame:withSampleBuffer:fromConnection: is a delegate method for QTCaptureDecompressedVideoOutput. An instance of this class is not present in the MyRecorder sample, because that sample only records compressed video to disk. To use this, you'll need to create an instance of QTCaptureDecompressedVideoOutput, attach it to your QTCaptureSession using -addOutput:error:, and set the delegate for the QTCaptureDecompressedVideoOutput instance to be your class.

For more information on how QTKit handles this sort of thing, you can consult the QTKit Capture section of the QTKit Application Programming Guide.

Brad Larson
I've declared QTCaptureDecompressedVideoOutput on -awakeFromNib method and I've added it to QTCaptureSession but, in this case, image capture works fine and video isn't save on disk.
Andrea Girardi
http://www.agdev.net/works/MYRecorder.zip
Andrea Girardi
The problem is that I've 2 type of addOutput: QTCaptureDecompressedVideoOutput to save image and mCaptureMovieFileOutput to store video. Is possible to have 2 output or have I to define 2 QTCaptureSession?
Andrea Girardi
You should be able to have two outputs with a single video input. Apple shows a flowchart for this in the QTKit guide linked above. How processor intensive is your image capture? Maybe it's not returning from the delegate method fast enough to allow the video recording to take place. By default, the video capture uses H.264 encoding, which is pretty heavy. You could try setting the video to QTCompressionOptions240SizeMPEG4Video and see what happens.
Brad Larson
I've modified the initialization -awakeFromNib procedure and now works with 2 outputs. I've implemented delegate for QTCaptureDecompressedVideoOutput but processor is 60 / 70 % because for every frame delegate method is called. But the result is acceptable. Is possible to call delegate only when capture key has been pressed?
Andrea Girardi
Why not use a boolean instance variable that gets set to YES when you hit the capture key? You could check this instance variable in the delegate method and only run your capture code if the variable is set to YES.
Brad Larson