简体   繁体   中英

Monotouch - CMSampleBufferGetSampleTimingInfoArray

I'm currently working on a proof of concept app written in monotouch that would record videos. I need to adjust the time of the CMSampleBuffer, I found a code that do just that however it's written in Objective-C. I tried translating the code below, but I can't find any mapping to this function - CMSampleBufferGetSampleTimingInfoArray , how are we going to call this function in monotouch? Below is the complete code for adjusting time but in Objective-C:

- (CMSampleBufferRef) adjustTime:(CMSampleBufferRef) sample by:(CMTime) offset
{
    CMItemCount count;
    CMSampleBufferGetSampleTimingInfoArray(sample, 0, nil, &count);
    CMSampleTimingInfo* pInfo = malloc(sizeof(CMSampleTimingInfo) * count);
    CMSampleBufferGetSampleTimingInfoArray(sample, count, pInfo, &count);
    for (CMItemCount i = 0; i < count; i++)
    {
        pInfo[i].decodeTimeStamp = CMTimeSubtract(pInfo[i].decodeTimeStamp, offset);
        pInfo[i].presentationTimeStamp = CMTimeSubtract(pInfo[i].presentationTimeStamp, offset);
    }
    CMSampleBufferRef sout;
    CMSampleBufferCreateCopyWithNewTiming(nil, sample, count, pInfo, &sout);
    free(pInfo);
    return sout;
}

This is untested, but I believe it should get you on the right track:

[DllImport(Constants.CoreMediaLibrary)]
int CMSampleBufferGetSampleTimingInfoArray (
    IntPtr sbuf,
    int timingArrayEntries,
    CMSampleTimingInfo [] timingArrayOut,
    out int timingArrayEntriesNeededOut
);

[DllImport(Constants.CoreMediaLibrary)]
int CMSampleBufferCreateCopyWithNewTiming (
    IntPtr allocator,
    IntPtr originalSBuf,
    int numSampleTimingEntries,
    CMSampleTimingInfo []sampleTimingArray,
    out IntPtr sBufCopyOut
);

CMSampleBuffer AdjustTime (CMSampleBuffer sample, CMTime offset)
{
    int count;
    CMSampleBufferGetSampleTimingInfoArray (sample.Handle, 0, null, out count);
    CMSampleTimingInfo [] pInfo = new CMSampleTimingInfo [count];
    CMSampleBufferGetSampleTimingInfoArray (sample.Handle, count, pInfo, out count);
    for (int i = 0; i < count; i++) {
        pInfo [i].DecodeTimeStamp = CMTime.Subtract (pInfo [i].DecodeTimeStamp, offset);
        pInfo [i].PresentationTimeStamp = CMTime.Subtract (pInfo [i].PresentationTimeStamp, offset);
    }
    IntPtr sout;
    CMSampleBufferCreateCopyWithTiming (IntPtr.Zero, sample, count, pInfo, out sout);
    // Unfortunately the constructor we need is internal, but that can be fixed
    // for a future version of Xamarin.iOS.
    return (CMSampleBuffer) typeof (CMSampleBuffer).GetConstructor (BindingFlags.Instance | BindingFlags.NonPublic, null, new Type [] { typeof (IntPtr), typeof (bool) }, null).Invoke (new object [] { sout, true });
}

Update

I have implemented some of the required API in Xamarin.iOS now, so in future versions you'll be able to do this:

CMSampleBuffer AdjustTime (CMSampleBuffer sample, CMTime offset)
{
    var info = sample.GetSampleTimingInfo ();
    for (int i = 0; i < info.Length; i++) {
        info [i].DecodeTimeStamp = CMTime.Subtract (info [i].DecodeTimeStamp, offset);
        info [i].PresentationTimeStamp = CMTime.Subtract (info [i].PresentationTimeStamp, offset);
    }
    return CMSampleBuffer.CreateWithNewTiming (sample, info)
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM