Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get the current captured timestamp of Camera data from CMSampleBufferRef in iOS

I developed and iOS application which will save captured camera data into a file and I used

(void) captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection

to capture CMSampleBufferRef and this will encode into H264 format, and frames will be saved to a file using AVAssetWriter.

I followed the sample source code to create this app:

Now I want to get the timestamp of saved video frames to create a new movie file. For this, I have done the following things

  1. Locate the file and create AVAssestReader to read the file

    CMSampleBufferRef sample = [asset_reader_output copyNextSampleBuffer];   
    CMSampleBufferRef buffer;
    
    while ([assestReader status] == AVAssetReaderStatusReading) {
        buffer = [asset_reader_output copyNextSampleBuffer];
    
        // CMSampleBufferGetPresentationTimeStamp(buffer);
    
        CMTime presentationTimeStamp = CMSampleBufferGetPresentationTimeStamp(buffer);
        UInt32 timeStamp = (1000 * presentationTimeStamp.value) / presentationTimeStamp.timescale;
    
        NSLog(@"timestamp %u", (unsigned int) timeStamp);
        NSLog(@"reading");
    
        // CFRelease(buffer);
    }
    

printed value gives me a wrong timestamp and I need to get frame's captured time.

Is there any way to get frame captured timestamp?

I've read an answer to get it to timestamp but it does not properly elaborate my question above.

Update:

I read the sample time-stamp before it writes to a file, it gave me xxxxx value (33333.23232). After I tried to read the file it gave me different value. Any specific reason for this??

like image 963
Mr.G Avatar asked Mar 27 '15 08:03

Mr.G


1 Answers

The file timestamps are different to the capture timestamps because they are relative to the beginning of the file. This means they are the capture timestamps you want, minus the timestamp of the very first frame captured:

 presentationTimeStamp = fileFramePresentationTime + firstFrameCaptureTime

So when reading from the file, this should calculate the capture timestamp you want:

 CMTime firstCaptureFrameTimeStamp = // the first capture timestamp you see
 CMTime presentationTimeStamp = CMTimeAdd(CMSampleBufferGetPresentationTimeStamp(buffer), firstCaptureFrameTimeStamp);

If you do this calculation between launches of your app, you'll need to serialise and deserialise the first frame capture time, which you can do with CMTimeCopyAsDictionary and CMTimeMakeFromDictionary.

You could store this in the output file, via AVAssetWriter's metadata property.

like image 93
Rhythmic Fistman Avatar answered Sep 20 '22 09:09

Rhythmic Fistman