4

I tried to capture audio with 48 kHz in FFmpeg, the code as below:

 AVInputFormat* ifmt = av_find_input_format("dshow");
    CHECK_POINTER_RETURN_VALUE(ifmt, false)

    pFmtCtx = avformat_alloc_context();
    CHECK_POINTER_RETURN_VALUE(pFmtCtx, false)

    AVDictionary *param = nullptr;
    std::string sr = std::to_string(48000);
    av_dict_set(&param, "sample_rate",sr.c_str(), 0);

    int error = avformat_open_input(&pFmtCtx, ffName.c_str(), ifmt, &param);
    if (error != 0) {
        char buf[2014];
        av_strerror(error, buf, 1024);
        LOG(ERROR)<<"open audio device failed,err is "<<buf;
         return false;
    }

but "avformat_open_input" return fail, err shows "I/O error", if the sample rate is 44100, all is OK.

Now FFmpeg doesn't support capturing 48 kHz audio?

Brad
  • 159,648
  • 54
  • 349
  • 530
TONY
  • 101
  • 7
  • There is no perceptible difference between 44.1khz (CD quality) and 48khz. Best of luck on this - but I would not waste time debugging to enable the additional sampling. – moi Sep 11 '21 at 07:58
  • 1
    Does your hardware support 48k? – mausworks Sep 11 '21 at 09:56
  • @moi 48 kHz is most commonly used with video, whereas 44.1 kHz is with CDs. The difference in sample rate has less to do with quality and more to do with compatibility. – Brad Sep 11 '21 at 23:02
  • @diemaus At least in my use case, yes, my hardware is actually running at 48 kHz all the time, and supports up to 96 kHz. Yet, FFmpeg seems to cap out at 44.1 kHz. – Brad Sep 11 '21 at 23:03
  • I found the problem... it appears to be a limitation of the data structure FFmpeg is using from DirectShow. Interfaces that can do multiples of 44.1 kHz and 48 kHz can't be adequately described with `AUDIO_STREAM_CONFIG_CAPS`. Bug report here: https://trac.ffmpeg.org/ticket/9420#comment:14 A very simple workaround is to comment some lines out of dshow.c, where the checking of sample rate and what not are done. – Brad Sep 29 '21 at 18:42

2 Answers2

1

This was an issue with the DirectShow API that FFmpeg was using. It has been resolved with a change to FFmpeg: https://github.com/FFmpeg/FFmpeg/commit/d9a9b4c877b85fea5a5bad74c3d592a756047f79

Specifically, DirectShow doesn't adequately describe the audio device capabilities with AUDIO_STREAM_CONFIG_CAPS when the audio device supports both 44.1 kHz and 48 kHz as clock multiples. WAVEFORMATEX within the AM_MEDIA_TYPE must be used instead.

Brad
  • 159,648
  • 54
  • 349
  • 530
-1

As @die maus mentioned, the fact that this works if sample rate is set to 44100, but not 48000, likely indicates that your input device does not support sampling at 48 kHz. This is not a limitation of FFmpeg, but of the hardware.

And as @moi suggested, unless you have a specific need for 48 kHz, 44.1 should work just fine.

If you really need 48 kHz (e.g. you are sending the audio to something else that expects 48 kHz), you can resample the audio. FFmpeg includes libswresample for this purpose; see the example here.

ijc
  • 494
  • 3
  • 5
  • Are you *sure* this isn't a limitation of FFmpeg? In my case, my hardware is actually running at 48 kHz, and supports up to 96 kHz. Yet, FFmpeg won't go higher than 44.1 kHz for DirectShow capture. – Brad Sep 11 '21 at 23:09
  • @Brad It's not a limitation of FFmpeg in general; I've captured 48 kHz audio with other inputs (alsa). Could be an issue with DirectShow or FFmpeg's DirectShow support. Can you see the correct range of sample rates for your device in system settings (something like [this](https://filestore.community.support.microsoft.com/api/images/e7649206-1199-49d9-81ef-a0c6b2b86c4f))? What output do you get from `ffmpeg -f dshow -list_options true -i audio=` (mentioned [here](https://trac.ffmpeg.org/wiki/DirectShow))? – ijc Sep 12 '21 at 07:00
  • Yeah, I understand FFmpeg can go higher, but it seems there is a limitation in the DirectShow module. Listing options for any device I have maxes out at 44.1 kHz. For example: https://pastebin.com/EtMcwWvV And yet, under the sound device properties in Windows, you can see that it's actually set to 48 kHz: https://imgur.com/a/ExuH1yE – Brad Sep 12 '21 at 22:43
  • Ah, okay. It may indeed be a bug in the module. In the short term your best bet may be using 44.1k, resampling, or trying another library (e.g. [GStreamer](https://gstreamer.freedesktop.org/), [libVLC](https://www.videolan.org/vlc/libvlc.html), or DirectShow itself), depending on your use case. You could also [file a bug report](https://ffmpeg.org/bugreports.html); I couldn't find any tickets that sounded like this, but I did find a possibly-related [post on SuperUser](https://superuser.com/questions/1638424/ffmpeg-detects-incorrect-audio-options-for-dshow-dante-via-virtual-audio-device). – ijc Sep 13 '21 at 23:52
  • For what it's worth, Audacity uses PortAudio and can sample at 48 kHz and above via DirectSound, so I'm guessing this has to do with FFmpeg's implementation. I've been skimming the source code and haven't found the specific issue though. That SuperUser report you linked to is identical to what I was looking for, thanks. Indeed, I get this problem with Dante as well. – Brad Sep 13 '21 at 23:57
  • Bug ticket created: https://trac.ffmpeg.org/ticket/9420#ticket – Brad Sep 14 '21 at 00:27