繁体   English   中英

为什么 getFrameAtIndex 比 getFrameAtTime() 快

[英]Why getFrameAtIndex faster than getFrameAtTime()

我正在尝试从视频中获取所有帧(一个接一个),现在我正在使用它:

    int framesCount = videoInformation.getFramesCount();
    for (int i = 0; i < framesCount; i++) {
         Bitmap currentFrame = mediaMetadataRetriever.getFrameAtIndex(i);

对于5 秒的视频,提取所有帧(159 帧)需要13 秒

由于getFrameAtIndex(i)需要 API 28,我尝试使用getFrameAtTime()

    long timeS = videoInformation.getDuration() / videoInformation.getFps();
    int framesCount = videoInformation.getFramesCount();
    for (int i = 0; i < framesCount; i++) {
          Bitmap currentFrame = (mediaMetadataRetriever.getFrameAtTime(i*timeS*1000, MediaMetadataRetriever.OPTION_CLOSEST_SYNC));

对于相同的5 秒视频,获取所有帧需要近48

我不能说两者的本机实现,因为这两个函数都调用它们各自的本机函数,但是,如果您查看getFrameAtIndex ,您可以看到它:

可以通过读取metadata访问总framecount ,并使用index检索帧,类似于Arrays

int frameCount = Integer.parseInt(extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_FRAME_COUNT));

getFrameAtIndex()调用getFramesAtIndexInternal()

   private @NonNull List<Bitmap> getFramesAtIndexInternal(
            int frameIndex, int numFrames, @Nullable BitmapParams params) {
        if (!"yes".equals(extractMetadata(MediaMetadataRetriever.METADATA_KEY_HAS_VIDEO))) {
            throw new IllegalStateException("Does not contain video or image sequences");
        }
        int frameCount = Integer.parseInt(
                extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_FRAME_COUNT));
        if (frameIndex < 0 || numFrames < 1
                || frameIndex >= frameCount
                || frameIndex > frameCount - numFrames) {
            throw new IllegalArgumentException("Invalid frameIndex or numFrames: "
                + frameIndex + ", " + numFrames);
        }
        return _getFrameAtIndex(frameIndex, numFrames, params);
    }

getFrameAtTime并不是真正基于索引的,而是寻找/搜索,直到它与您通过的所需时间或最接近的时间匹配帧时间戳:

public @Nullable Bitmap getFrameAtTime(long timeUs, @Option int option) {
    if (option < OPTION_PREVIOUS_SYNC ||
        option > OPTION_CLOSEST) {
        throw new IllegalArgumentException("Unsupported option: " + option);
    }

    return _getFrameAtTime(timeUs, option, -1 /*dst_width*/, -1 /*dst_height*/, null);
}

https://github.com/aosp-mirror/platform_frameworks_base/blob/master/media/java/android/media/MediaMetadataRetriever.java

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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