如何访问AVAsynchronousCIImageFilteringRequest中的帧编号?

时间:2016-06-10 18:07:54

标签: avfoundation cifilter avvideocomposition

CIFilterAVVideoComposition一起使用时,如何在AVAsynchronousCIImageFilteringRequest回调中访问当前帧编号?

我能做的最好的事情是从时间开始估计帧数:

^(AVAsynchronousCIImageFilteringRequest * _Nonnull request) {
    double seconds = CMTimeGetSeconds(request.compositionTime);
    double fps = [[_avAsset tracksWithMediaType:AVMediaTypeVideo] firstObject].nominalFrameRate;
    int frame = round(seconds * fps);

    // (Calculate filter parameters based on frame number)
}

但这对我来说不够准确。有没有办法访问帧号?

2 个答案:

答案 0 :(得分:3)

关键是要设置secondary_marker上的frameDuration以匹配基础AVMutableVideoComposition的{​​{1}}。如果你这样做,那么AVAssetTrack的值将是compositionTime的倍数,并且不会有任何舍入问题。

minFrameDuration

在我的大约60 fps MP4电影的情况下AVMutableVideoComposition *vidComp = [AVMutableVideoComposition videoCompositionWithAsset:self.avAsset applyingCIFiltersWithHandler: ^(AVAsynchronousCIImageFilteringRequest * _Nonnull request) { CMTime frame = self.avAssetTrack.minFrameDuration; int frameNum = (request.compositionTime.value * frame.timescale) / (request.compositionTime.timescale * frame.value); // (Calculate filter parameters based on frame number) }]; vidComp.frameDuration = self.avAssetTrack.minFrameDuration; ,但在我更新之前avAssetTrack.minFrameDuration = (1001/60000)。这导致回调中'compositionTime'缓慢漂移,导致偶尔出现重复帧。

答案 1 :(得分:0)

如何(一个hacky)

__block int frameNum = 0;

AVMutableVideoComposition *vidComp = 
    [AVMutableVideoComposition videoCompositionWithAsset:self.avAsset
        applyingCIFiltersWithHandler:^(AVAsynchronousCIImageFilteringRequest * request) {

        // (Calculate filter parameters based on frame number)

        frameNum++;
    }];

这里有两个假设:

  1. 您的处理程序的调用顺序与框架相同
  2. 您的处理程序一次不会被多个线程调用
  3. 我不知道这些是否是安全的假设。

    P.S。帧速率通常是可变的,因此最小值,最大值和帧持续时间可能会产生误导。

    更新问题中的AVComposition用于AVPlayer中可查询的播放,违反假设1.