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

7.6k Views Asked by At

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??

1

There are 1 best solutions below

5
On

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.