5

I am on a Macbook and I am trying to read video from a camera using the ffmpeg library. The camera is a 10 meter USB underwater camera. I am using the C API through a D binding called ffmpeg-d. However, upon trying to open the input, I get this:

[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

So how can I avoid this problem? Would setting the framerate manually be the answer? And if so, how could I do that?

Here is a really short program to replicate my problem.

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;
}
hpm
  • 1,202
  • 13
  • 34
  • does it work if you manually specify the size and framerate to something listed there? There was a bug like that in the ffmpeg program 6 months ago but they kind of fixed it if you specify size & framerate: https://trac.ffmpeg.org/ticket/4880 – WebFreak001 Apr 04 '16 at 08:27
  • @WebFreak001 Nice! `ffmpeg -f avfoundation -video_size 640x480 -framerate 30 -i "USB" out.png` works. How can that be replicated in the API? – hpm Apr 04 '16 at 08:37
  • Have a look at https://arashafiei.wordpress.com/2012/10/16/specifying-input-frame-rate-to-capture-from-from-webcam/. Though not D, it seems that instead of `null` you should pass some kind of `av_dict` (pointer), where you specify the framerate. It pretty much equals the command line interface, I think. – Ilja Everilä Apr 04 '16 at 08:49
  • See, now that you added some code, the answer was pretty obvious to someone who'd never used the said API. Upvoted. – Antti Haapala -- Слава Україні Apr 04 '16 at 09:01

2 Answers2

6

I have no experience at all with D or the libraries in use, but I can point you in the right direction. You should pass AVDictionary** options to avformat_open_input

options A dictionary filled with AVFormatContext and demuxer-private options. On return this parameter will be destroyed and replaced with a dict containing options that were not found. May be NULL.

To me it seems that the structure of that dictionary follows the command line options pretty much 1-to-1, so you should add the value "30" under the key "framerate".

Ilja Everilä
  • 50,538
  • 7
  • 126
  • 127
  • Well, very nice find with that blog post. It actually works. I tried using a dictionary earlier, but only with the function avformat_find_stream_info (because a search on Google suggested that). I suppose I just don't have very good luck with Google. Anyways, thanks a lot. – hpm Apr 04 '16 at 09:01
0

I have noticed in some api you should provide "framerate" instead of "r"

  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jan 03 '22 at 00:04
  • This does not provide an answer to the question. Once you have sufficient [reputation](https://stackoverflow.com/help/whats-reputation) you will be able to [comment on any post](https://stackoverflow.com/help/privileges/comment); instead, [provide answers that don't require clarification from the asker](https://meta.stackexchange.com/questions/214173/why-do-i-need-50-reputation-to-comment-what-can-i-do-instead). - [From Review](/review/late-answers/30722882) – Nico Haase Jan 04 '22 at 15:06