2

I have been trying what works automatically on Linux for hours now on, or for, Windows. I want to link a program (PhenoCam, but for this question only the short sample ffmpeg program listed below) with ffmpeg.

Setup

Currently I am on Linux, compiling with mingw and using the Zeranoe ffmpeg builds. The directory setup looks like this:

dumpVideoInfo.c
+ bin
  avformat-54.dll
  avutil-51.dll
+ lib
  avcodec.lib
  avcodec.dll.a
  avutil.lib
  avutil.dll.a

Problems

Trying to link dynamically with the .dll files causes a File format not recognized error.

$ i586-mingw32msvc-gcc -v -Wall -Iinclude dumpVideoInfo.c -o dumpVideoInfo.exe -L./bin64 -lavformat-54 -lavutil-51
./bin64/avformat-54.dll: file not recognized: File format not recognized

Trying to link it with the .lib/.dll.a caused undefined reference errors:

$ i586-mingw32msvc-gcc -v -Wall -Iinclude dumpVideoInfo.c -o dumpVideoInfo.exe -L./lib64 -lavformat -lavutil
/tmp/ccSKJQAc.o:dumpVideoInfo.c:(.text+0x30): undefined reference to `_av_register_all'
/tmp/ccSKJQAc.o:dumpVideoInfo.c:(.text+0x6e): undefined reference to `_avformat_open_input'
/tmp/ccSKJQAc.o:dumpVideoInfo.c:(.text+0xbf): undefined reference to `_avformat_find_stream_info'
/tmp/ccSKJQAc.o:dumpVideoInfo.c:(.text+0xef): undefined reference to `_av_dump_format'
/tmp/ccSKJQAc.o:dumpVideoInfo.c:(.text+0xfe): undefined reference to `_av_free'

Partial solution

As already hinted by the bin64/lib64 directories above, I was using 64 bit libraries. The errors from above disappeared after changing to the 32 bit libraries.

Remaining problems

  1. No matter whether I link to the bin/ or lib/ directory (.dll or .lib/.dll.a) the resulting executable stays 23 KB and still requires the .dll files. How can I link the program statically?
  2. What is the difference between the .lib and the .dll.a files?

Code

#include <stdio.h>
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"

int main(int argc, char *argv[])
{
    char *filename;
    if (argc > 1) {
        filename = argv[1];
    } else {
        printf("No video file given.");
        return 2;
    }

    av_register_all();

    AVFormatContext *pFormatContext = NULL;

    printf("Reading info for file %s.\n", filename);
    fflush(stdout);

    int ret;
    if ((ret = avformat_open_input(&pFormatContext, filename, NULL, NULL)) != 0) {
    printf("Could not open file %s.\n", filename);
        return 2;
    }
    if (avformat_find_stream_info(pFormatContext, NULL) < 0) {
    printf("No stream information found.\n");
        return 2;
    }
    av_dump_format(pFormatContext, 0, filename, 0);

    av_free(pFormatContext);
    return 0;
}

Thanks for your answers.

Simon A. Eugster
  • 4,114
  • 4
  • 36
  • 31

1 Answers1

1

This library format appears to be only for dynamic linking: the .dll.a files are import libraries for GCC-style compilers, while the .lib files are import libraries for MSVC compilers.

When linked to these static import libraries, the resulting program does not actually contain any of the FFMpeg code. Instead, it only contains references to FFMpeg which must loaded in from a DLL when the program starts.

I was running into a similar conundrum, as the chocolatey version of FFMpeg appears to only provide dynamic libraries. I ended up just copying the DLLs with my executable, although that is an expensive and wasteful thing to do (I am only decoding H264 frames).

It does appear that there is someone on GitHub maintaining static libraries for ffmpeg, but I have not tried the libs: https://github.com/eugeneware/ffmpeg-static/releases/

Alec Graves
  • 152
  • 8