gpt4 book ai didi

ios - 如何使用 AVAssetReader 和 AVAssetWriter 控制视频帧率?

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:21:55 36 4
gpt4 key购买 nike

我们正在尝试了解如何控制/指定我们使用 AVAssetReaderAVAssetWriter 编码的视频的帧速率。具体来说,我们正在使用 AVAssetReaderAVAssetWriter 来转码/编码/压缩我们从照片/视频库访问的视频。我们能够控制比特率、宽高比变化等,但无法弄清楚如何控制帧率。具体来说,我们希望能够将 5 分钟长的 30 FPS 视频作为输入,并以 15 FPS 的速度发出 5 分钟的视频。

我们当前处理样本缓冲区的循环是:

[writer startWriting];
[writer startSessionAtSourceTime:kCMTimeZero];
[videoReader startReading];

[videoWriterInput requestMediaDataWhenReadyOnQueue:videoEncoderQueue usingBlock:
^{
while ([videoWriterInput isReadyForMoreMediaData]) {
CMSampleBufferRef sampleBuffer;

if ([videoReader status] == AVAssetReaderStatusReading
&& (sampleBuffer = [videoReaderTrackOutput copyNextSampleBuffer])) {
if (sampleBuffer) {
BOOL result = [videoWriterInput appendSampleBuffer:sampleBuffer];
CFRelease(sampleBuffer);

if (!result) {
[videoReader cancelReading];
break;
}
}
} else {
// deal with status other than AVAssetReaderStatusReading
[videoWriterInput markAsFinished];
// [...]
break;
}
}
}];

我们如何增强或更改它,以便我们可以控制所创建视频的帧速率?我们似乎无法在 SO 或其他任何地方找到清楚说明如何执行此操作的示例。我认为我们应该使用 CMTime 并且可能使用除了上面代码示例中的方法之外的其他一些方法,但细节尚不清楚。

最佳答案

根据您合成帧的方式,您可能只需要设置 movieTimeScale

或者,您需要使用 CMTime 设置每帧的时间,因为您将它添加到编写器。

CMTime time = CMTimeMake(0, 30); // (time, time_scale)

这将以每秒 30 帧的帧速率创建第一帧的时间。将第二个参数设置为您想要的帧速率,不要更改它。为添加到编写器的每一帧增加第一帧。

编辑:

处理传入和传出数据的方法有很多种。因此,对于如何/需要指定时间有很多选择。通常,以上内容适用于使用 AVAssetWriterInputPixelBufferAdaptor(如果您正在编辑视频帧)。

根据您更新的代码,您正在执行更“简单”的传递,您可能需要使用 CMSampleBufferCreateCopyWithNewTiming 生成您收到的 sampleBuffer 的副本来自读者。奇怪的是,我认为,这使得时间安排更加复杂。根据您尝试通过编辑实现的目标,您可能想要创建一个新的单个 CMSampleTimingInfo 可用于所有帧,或者使用 从样本缓冲区获取现有的计时信息CMSampleBufferGetSampleTimingInfoArray 然后创建它的编辑版本。类似的东西:

CMItemCount count;
CMTime newTimeStamp = CMTimeMake(...);
CMSampleBufferGetSampleTimingInfoArray(sampleBuffer, 0, nil, &count);
CMSampleTimingInfo *timingInfo = malloc(sizeof(CMSampleTimingInfo) * count);
CMSampleBufferGetSampleTimingInfoArray(sampleBuffer, count, timingInfo, &count);

for (CMItemCount i = 0; i < count; i++)
{
timingInfo[i].decodeTimeStamp = kCMTimeInvalid;
timingInfo[i].presentationTimeStamp = newTimeStamp;
}

CMSampleBufferRef completedSampleBuffer;
CMSampleBufferCreateCopyWithNewTiming(kCFAllocatorDefault, sampleBuffer, count, timingInfo, &completedSampleBuffer);
free(timingInfo);

您如何选择 newTimeStamp 决定了您将获得什么结果。

关于ios - 如何使用 AVAssetReader 和 AVAssetWriter 控制视频帧率?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16911067/

36 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com