Как получить доступ к номеру кадра внутри AVAsynchronousCIImageFilteringRequest?

При использовании CIFilter с AVVideoCompositionкак я могу получить доступ к текущему номеру кадра в 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 ответа

Решение

Ключ должен установить frameDuration на AVMutableVideoComposition чтобы соответствовать тому из основного AVAssetTrack, если вы сделаете это, то значения compositionTime будет даже кратно minFrameDuration и не будет никаких проблем с округлением.

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;

В моем случае фильм MP4 ~ 60 кадров в секунду, avAssetTrack.minFrameDuration = (1001/60000), но vidComp.frameDuration = (1501/90000) прежде чем я обновлю это. Это привело к медленному дрейфу "составить время" в обратном вызове, что привело к случайным повторным кадрам.

Как насчет (хаки)

__block int frameNum = 0;

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

        // (Calculate filter parameters based on frame number)

        frameNum++;
    }];

?

Здесь есть два предположения:

  1. ваш обработчик вызывается в том же порядке, что и кадры
  2. ваш обработчик не вызывается более чем одним потоком одновременно

Я не знаю, это безопасные предположения или нет.

Частота кадров ps довольно часто варьируется, поэтому min, max и длительность кадра могут вводить в заблуждение.

ОБНОВИТЬ AVComposition из вопроса предназначен для поиска в AVPlayer что нарушает предположение 1.

Другие вопросы по тегам