如何避免不支持的帧率错误?

5

我正在使用Macbook尝试使用ffmpeg库读取来自摄像机的视频。这个摄像机是一个10米长的USB水下摄像机。我通过名为ffmpeg-d的D绑定使用C API。但是,在尝试打开输入时,我遇到了以下问题:

[avfoundation @ 0x7fe0d2800000] Selected framerate (29.970030) is not supported by the device
[avfoundation @ 0x7fe0d2800000] Supported modes:
[avfoundation @ 0x7fe0d2800000]   160x120@[30.000030 30.000030]fps
[avfoundation @ 0x7fe0d2800000]   176x144@[30.000030 30.000030]fps
[avfoundation @ 0x7fe0d2800000]   320x240@[30.000030 30.000030]fps
[avfoundation @ 0x7fe0d2800000]   352x288@[30.000030 30.000030]fps
[avfoundation @ 0x7fe0d2800000]   640x480@[30.000030 30.000030]fps

那么我该如何避免这个问题呢?手动设置帧率会是答案吗?如果是,我该如何做到呢?

这里有一个非常简短的程序可以复制我的问题。

import std.stdio;

import ffmpeg.libavdevice.avdevice;
import ffmpeg.libavcodec.avcodec;
import ffmpeg.libavformat.avformat;
import ffmpeg.libavfilter.avfilter;
import ffmpeg.libavutil.avutil;
import ffmpeg.libavutil.mem;
import ffmpeg.libavutil.pixfmt;
import ffmpeg.libswscale.swscale;

import std.string;

void main()
{
    av_register_all();
    avdevice_register_all();

    string           cameraSource        = "USB";

    AVCodecContext*  cameraCodecContext  = null;
    AVFormatContext* cameraFormatContext = avformat_alloc_context();
    AVCodec*         cameraCodec         = null;
    AVInputFormat*   cameraFormat        = av_find_input_format("avfoundation");
    AVFrame*         rawFrame = null, convertedFrame = null;

    if (avformat_open_input(&cameraFormatContext, cameraSource.toStringz, cameraFormat, null) != 0) return;
}

如果您手动将大小和帧速率指定为其中列出的某个值,它是否有效?6个月前ffmpeg程序中有一个类似的错误,但如果您指定大小和帧速率,则已经部分修复了该问题:https://trac.ffmpeg.org/ticket/4880 - WebFreak001
@WebFreak001 不错!ffmpeg -f avfoundation -video_size 640x480 -framerate 30 -i "USB" out.png可行。如何在API中复制它? - hpm
请查看https://arashafiei.wordpress.com/2012/10/16/specifying-input-frame-rate-to-capture-from-from-webcam/。虽然不是D语言,但似乎应该传递某种`av_dict`(指针),其中您可以指定帧速率,而不是使用`null`。我认为这与命令行界面几乎相同。 - Ilja Everilä
看,现在你添加了一些代码,对于从未使用过该API的人来说,答案非常明显。点赞。 - Antti Haapala -- Слава Україні
2个回答

6

我对D语言和使用的库完全没有经验,但我可以指导你正确的方向。您应该将AVDictionary** options传递给avformat_open_input

options 包含AVFormatContext和解复用器私有选项的字典。返回时,此参数将被销毁并替换为包含未找到的选项的字典。可以为空。

对我来说,这个字典的结构似乎与命令行选项几乎是1对1的,因此您应该在键“framerate”下添加值“30”。


非常好的博客文章,你找到了一个很好的方法。我之前尝试使用字典,但只有在使用avformat_find_stream_info函数时才有效(因为谷歌搜索建议这样做)。我想我在谷歌上运气不太好。无论如何,非常感谢。 - hpm

0

我注意到在一些API中,你应该提供“帧速率”而不是“r”。


你的回答可以通过提供更多支持信息来改进。请编辑以添加进一步的细节,例如引用或文档,以便他人可以确认你的答案是正确的。您可以在帮助中心中找到有关如何编写良好答案的更多信息。 - Community
这并不是该问题的答案。当你有足够的声望时,你将能够在任何帖子中进行评论; 相反,请提供不需要询问者澄清的答案。-来自审阅 - Nico Haase

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接