12

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

Vukašin Manojlović
  • 3,717
  • 3
  • 19
  • 31
Mr.G
  • 1,275
  • 1
  • 18
  • 48

1 Answers1

4

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.

Rhythmic Fistman
  • 34,352
  • 5
  • 87
  • 159
  • thank you for your answer i will check this , why does the capture timestamps is not equal to actual timestamp , i printed this value , and its not the same as in web – Mr.G Mar 31 '15 at 05:49
  • 1
    good question, I'm not sure why capture timestamps aren't relative to when you start capturing (why _they_ don't start at 0). – Rhythmic Fistman Mar 31 '15 at 05:55
  • is there anyway i can make a connection to presentation timestamp which recieves from camera delegate method to real timestamp , ?? do i have to use a map for this ?? but this seems like a resource waste – Mr.G Mar 31 '15 at 06:03
  • well in my case , have to create a separate clip for whole movie , and to this i have to sync time-stamp from backend server , for this , i need to have a connection to presentation time-stamp with actual timestamp , ill try this with metadata , – Mr.G Mar 31 '15 at 07:00
  • The timestamps are relative to the global system hosttime timebase. This makes it possible to synchronise media captured with other APIs. – Rhythmic Fistman Feb 28 '23 at 05:57