【问题标题】:Is there a faster way to grab frames by skipping frames?有没有更快的方法通过跳帧来抓帧?
【发布时间】:2020-05-04 14:17:13
【问题描述】:

我循环通过av_read_frameavcodec_decode_video2 来读取mp4 视频中的像素数据。

int i = 0;
while (av_read_frame(pFormatCtx, &pkt)>=0) {
    AVPacket orig_pkt = pkt;
    do {
        int ret = 0;
        int decoded = pkt.size;
        got
        if (i%7==0) { // Only process 1/7th of frames
            ret = avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &pkt);
            if (got_frame) {
                // get pixel data
            } else {
                printf("Error: could not get frame %d", i );
            }
        }
        ret = decoded;
        pkt.data += ret;
        pkt.size -= ret;
    } while (pkt.size > 0);
    av_free_packet(&orig_pkt);
}

这是一个 35FPS 的视频,但我只需要读取大约 5FPS 的像素数据。

i%7==0 条件导致超过 1/7 的帧被丢弃。删除该行会导致所有帧都被缓慢处理而不会丢失任何帧。

有没有一种只读取 1/7 帧的快速方法?

【问题讨论】:

  • 我不敢相信您发布的代码有效:如果 i%7 != 0ret 设置为 0pkt.datapkt.size 并没有真正发生任何事情继续...直到i %7 == 0
  • 您想阅读 1/7 的帧,但又不想放弃其他 6/7?这是没有意义的。 “不读书”和掉线是一回事,不是吗?
  • @IngoLeonhardt 抱歉,在将代码简化为基本要素时(为了便于阅读),我删除了该功能。它现在已更新为工作必需品。

标签: c ffmpeg mp4 h.264


【解决方案1】:

这取决于视频。大多数视频被压缩成“图片组”,其中第一张图片是关键帧,其余的是预测帧。一个关键帧可以自己解码,但只有在之前的所有预测帧(包括前一个关键帧)都被解码后才能解码预测帧(实际上比这要复杂一点,但现在已经足够好了)。如果您正在解码的视频都是关键帧(例如 MJPEG),是的,您可以跳过任何您想要的帧。如果不是,并且您跳过一帧,则必须跳过所有帧直到下一个关键帧。关键帧通常约为 2 到 10 秒(假设 30fps 视频为 60-300 帧)。但这可能或多或少。

您可以通过检查AV_PKT_FLAG_KEY & pkt.flags来检查帧是否为关键帧

你可以这样做:

if (AV_PKT_FLAG_KEY &pkt.flags) {
    ret = avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &pkt);
...
}

但是您无法决定解码哪些帧,视频文件本身会决定。

【讨论】:

    猜你喜欢
    • 2020-07-25
    • 1970-01-01
    • 2022-08-21
    • 2018-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-08
    • 1970-01-01
    相关资源
    最近更新 更多