4

I'm trying to compile a modified version of this transcoding example from the FFMPEG site, I've used all the required includes and joined the libs using this :

INCLUDEPATH += $$(FFMPEG_DEV_PATH)\include
    LIBS += -L$$(FFMPEG_DEV_PATH)\lib -lavformat -lavcodec -lavutil -lswscale -liconv -lz -lavfilter

but I get this linking error that I can't understand :

  "avio_close(AVIOContext*)", referenced from:
      PhVideoEncoder::PhVideoEncoder(QString) in PhVideoEncoder.o
  "av_strerror(int, char*, unsigned long)", referenced from:
      av_make_error_string(char*, unsigned long, int) in PhVideoEncoder.o
  "av_rescale_q(long long, AVRational, AVRational)", referenced from:
      PhVideoEncoder::encode_write_frame(AVFrame*, unsigned int, int*) in PhVideoEncoder.o
  "av_frame_free(AVFrame**)", referenced from:
      PhVideoEncoder::PhVideoEncoder(QString) in PhVideoEncoder.o
      PhVideoEncoder::filter_encode_write_frame(AVFrame*, unsigned int) in PhVideoEncoder.o
      PhVideoEncoder::encode_write_frame(AVFrame*, unsigned int, int*) in PhVideoEncoder.o
  "av_read_frame(AVFormatContext*, AVPacket*)", referenced from:
      PhVideoEncoder::PhVideoEncoder(QString) in PhVideoEncoder.o
  "avcodec_close(AVCodecContext*)", referenced from:
      PhVideoEncoder::PhVideoEncoder(QString) in PhVideoEncoder.o
  "avcodec_open2(AVCodecContext*, AVCodec const*, AVDictionary**)", referenced from:
      PhVideoEncoder::open_input_file(char const*) in PhVideoEncoder.o
      PhVideoEncoder::open_output_file(char const*) in PhVideoEncoder.o
  "av_dump_format(AVFormatContext*, int, char const*, int)", referenced from:
      PhVideoEncoder::open_input_file(char const*) in PhVideoEncoder.o
      PhVideoEncoder::open_output_file(char const*) in PhVideoEncoder.o
  "av_frame_alloc()", referenced from:
      PhVideoEncoder::PhVideoEncoder(QString) in PhVideoEncoder.o
      PhVideoEncoder::filter_encode_write_frame(AVFrame*, unsigned int) in PhVideoEncoder.o
  "av_free_packet(AVPacket*)", referenced from:
      PhVideoEncoder::PhVideoEncoder(QString) in PhVideoEncoder.o
  "av_init_packet(AVPacket*)", referenced from:
      PhVideoEncoder::encode_write_frame(AVFrame*, unsigned int, int*) in PhVideoEncoder.o
  "av_opt_set_bin(void*, char const*, unsigned char const*, int, int)", referenced from:
      PhVideoEncoder::init_filter(FilteringContext*, AVCodecContext*, AVCodecContext*, char const*) in PhVideoEncoder.o
  "av_register_all()", referenced from:
      PhVideoEncoder::PhVideoEncoder(QString) in PhVideoEncoder.o
  "av_rescale_q_rnd(long long, AVRational, AVRational, AVRounding)", referenced from:
      PhVideoEncoder::PhVideoEncoder(QString) in PhVideoEncoder.o
      PhVideoEncoder::encode_write_frame(AVFrame*, unsigned int, int*) in PhVideoEncoder.o
  "av_write_trailer(AVFormatContext*)", referenced from:
      PhVideoEncoder::PhVideoEncoder(QString) in PhVideoEncoder.o
  "avfilter_graph_free(AVFilterGraph**)", referenced from:
      PhVideoEncoder::PhVideoEncoder(QString) in PhVideoEncoder.o
  "avfilter_inout_free(AVFilterInOut**)", referenced from:
      PhVideoEncoder::init_filter(FilteringContext*, AVCodecContext*, AVCodecContext*, char const*) in PhVideoEncoder.o
  "avformat_new_stream(AVFormatContext*, AVCodec const*)", referenced from:
      PhVideoEncoder::open_output_file(char const*) in PhVideoEncoder.o
  "avformat_open_input(AVFormatContext**, char const*, AVInputFormat*, AVDictionary**)", referenced from:
      PhVideoEncoder::open_input_file(char const*) in PhVideoEncoder.o
  "avcodec_copy_context(AVCodecContext*, AVCodecContext const*)", referenced from:
      PhVideoEncoder::open_output_file(char const*) in PhVideoEncoder.o
  "avcodec_find_decoder(AVCodecID)", referenced from:
      PhVideoEncoder::open_input_file(char const*) in PhVideoEncoder.o
  "avcodec_find_encoder(AVCodecID)", referenced from:
      PhVideoEncoder::open_output_file(char const*) in PhVideoEncoder.o
  "avfilter_get_by_name(char const*)", referenced from:
      PhVideoEncoder::init_filter(FilteringContext*, AVCodecContext*, AVCodecContext*, char const*) in PhVideoEncoder.o
  "avfilter_graph_alloc()", referenced from:
      PhVideoEncoder::init_filter(FilteringContext*, AVCodecContext*, AVCodecContext*, char const*) in PhVideoEncoder.o
  "avfilter_inout_alloc()", referenced from:
      PhVideoEncoder::init_filter(FilteringContext*, AVCodecContext*, AVCodecContext*, char const*) in PhVideoEncoder.o
  "avformat_close_input(AVFormatContext**)", referenced from:
      PhVideoEncoder::PhVideoEncoder(QString) in PhVideoEncoder.o
  "avcodec_decode_audio4(AVCodecContext*, AVFrame*, int*, AVPacket const*)", referenced from:
      PhVideoEncoder::PhVideoEncoder(QString) in PhVideoEncoder.o
  "avcodec_decode_video2(AVCodecContext*, AVFrame*, int*, AVPacket const*)", referenced from:
      PhVideoEncoder::PhVideoEncoder(QString) in PhVideoEncoder.o
  "avcodec_encode_audio2(AVCodecContext*, AVPacket*, AVFrame const*, int*)", referenced from:
      PhVideoEncoder::encode_write_frame(AVFrame*, unsigned int, int*) in PhVideoEncoder.o
  "avcodec_encode_video2(AVCodecContext*, AVPacket*, AVFrame const*, int*)", referenced from:
      PhVideoEncoder::encode_write_frame(AVFrame*, unsigned int, int*) in PhVideoEncoder.o
  "avfilter_graph_config(AVFilterGraph*, void*)", referenced from:
      PhVideoEncoder::init_filter(FilteringContext*, AVCodecContext*, AVCodecContext*, char const*) in PhVideoEncoder.o
  "avfilter_register_all()", referenced from:
      PhVideoEncoder::PhVideoEncoder(QString) in PhVideoEncoder.o
  "avformat_free_context(AVFormatContext*)", referenced from:
      PhVideoEncoder::PhVideoEncoder(QString) in PhVideoEncoder.o
  "avformat_write_header(AVFormatContext*, AVDictionary**)", referenced from:
      PhVideoEncoder::open_output_file(char const*) in PhVideoEncoder.o
  "av_get_sample_fmt_name(AVSampleFormat)", referenced from:
      PhVideoEncoder::init_filter(FilteringContext*, AVCodecContext*, AVCodecContext*, char const*) in PhVideoEncoder.o
  "av_buffersink_get_frame(AVFilterContext*, AVFrame*)", referenced from:
      PhVideoEncoder::filter_encode_write_frame(AVFrame*, unsigned int) in PhVideoEncoder.o
  "avfilter_graph_parse_ptr(AVFilterGraph*, char const*, AVFilterInOut**, AVFilterInOut**, void*)", referenced from:
      PhVideoEncoder::init_filter(FilteringContext*, AVCodecContext*, AVCodecContext*, char const*) in PhVideoEncoder.o
  "avformat_find_stream_info(AVFormatContext*, AVDictionary**)", referenced from:
      PhVideoEncoder::open_input_file(char const*) in PhVideoEncoder.o
  "av_interleaved_write_frame(AVFormatContext*, AVPacket*)", referenced from:
      PhVideoEncoder::PhVideoEncoder(QString) in PhVideoEncoder.o
      PhVideoEncoder::encode_write_frame(AVFrame*, unsigned int, int*) in PhVideoEncoder.o
  "av_buffersrc_add_frame_flags(AVFilterContext*, AVFrame*, int)", referenced from:
      PhVideoEncoder::filter_encode_write_frame(AVFrame*, unsigned int) in PhVideoEncoder.o
  "avfilter_graph_create_filter(AVFilterContext**, AVFilter const*, char const*, char const*, void*, AVFilterGraph*)", referenced from:
      PhVideoEncoder::init_filter(FilteringContext*, AVCodecContext*, AVCodecContext*, char const*) in PhVideoEncoder.o
  "av_get_default_channel_layout(int)", referenced from:
      PhVideoEncoder::init_filter(FilteringContext*, AVCodecContext*, AVCodecContext*, char const*) in PhVideoEncoder.o
  "avformat_alloc_output_context2(AVFormatContext**, AVOutputFormat*, char const*, char const*)", referenced from:
      PhVideoEncoder::open_output_file(char const*) in PhVideoEncoder.o
  "av_get_channel_layout_nb_channels(unsigned long long)", referenced from:
      PhVideoEncoder::open_output_file(char const*) in PhVideoEncoder.o
  "av_frame_get_best_effort_timestamp(AVFrame const*)", referenced from:
      PhVideoEncoder::PhVideoEncoder(QString) in PhVideoEncoder.o
  "av_log(void*, int, char const*, ...)", referenced from:
      PhVideoEncoder::PhVideoEncoder(QString) in PhVideoEncoder.o
      PhVideoEncoder::filter_encode_write_frame(AVFrame*, unsigned int) in PhVideoEncoder.o
      PhVideoEncoder::flush_encoder(unsigned int) in PhVideoEncoder.o
      PhVideoEncoder::open_input_file(char const*) in PhVideoEncoder.o
      PhVideoEncoder::open_output_file(char const*) in PhVideoEncoder.o
      PhVideoEncoder::init_filter(FilteringContext*, AVCodecContext*, AVCodecContext*, char const*) in PhVideoEncoder.o
      PhVideoEncoder::encode_write_frame(AVFrame*, unsigned int, int*) in PhVideoEncoder.o
      ...
  "av_free(void*)", referenced from:
      PhVideoEncoder::PhVideoEncoder(QString) in PhVideoEncoder.o
  "av_malloc(unsigned long)", referenced from:
      av_malloc_array(unsigned long, unsigned long) in PhVideoEncoder.o
  "av_strdup(char const*)", referenced from:
      PhVideoEncoder::init_filter(FilteringContext*, AVCodecContext*, AVCodecContext*, char const*) in PhVideoEncoder.o
  "avio_open(AVIOContext**, char const*, int)", referenced from:
      PhVideoEncoder::open_output_file(char const*) in PhVideoEncoder.o

I tried looking for missing libraries but with no luck... What am I missing ?

EDIT

Thanks to the first answer, I added the extern C stuff but I still face a few errors :

Undefined symbols for architecture x86_64:
  "_av_buffersink_get_frame", referenced from:
      PhVideoEncoder::filter_encode_write_frame(AVFrame*, unsigned int) in PhVideoEncoder.o
  "_av_buffersrc_add_frame_flags", referenced from:
      PhVideoEncoder::filter_encode_write_frame(AVFrame*, unsigned int) in PhVideoEncoder.o
  "_avfilter_get_by_name", referenced from:
      PhVideoEncoder::init_filter(FilteringContext*, AVCodecContext*, AVCodecContext*, char const*) in PhVideoEncoder.o
  "_avfilter_graph_alloc", referenced from:
      PhVideoEncoder::init_filter(FilteringContext*, AVCodecContext*, AVCodecContext*, char const*) in PhVideoEncoder.o
  "_avfilter_graph_config", referenced from:
      PhVideoEncoder::init_filter(FilteringContext*, AVCodecContext*, AVCodecContext*, char const*) in PhVideoEncoder.o
  "_avfilter_graph_create_filter", referenced from:
      PhVideoEncoder::init_filter(FilteringContext*, AVCodecContext*, AVCodecContext*, char const*) in PhVideoEncoder.o
  "_avfilter_graph_free", referenced from:
      PhVideoEncoder::PhVideoEncoder(QString) in PhVideoEncoder.o
  "_avfilter_graph_parse_ptr", referenced from:
      PhVideoEncoder::init_filter(FilteringContext*, AVCodecContext*, AVCodecContext*, char const*) in PhVideoEncoder.o
  "_avfilter_inout_alloc", referenced from:
      PhVideoEncoder::init_filter(FilteringContext*, AVCodecContext*, AVCodecContext*, char const*) in PhVideoEncoder.o
  "_avfilter_inout_free", referenced from:
      PhVideoEncoder::init_filter(FilteringContext*, AVCodecContext*, AVCodecContext*, char const*) in PhVideoEncoder.o
  "_avfilter_register_all", referenced from:
      PhVideoEncoder::PhVideoEncoder(QString) in PhVideoEncoder.o
ld: symbol(s) not found for architecture x86_64
Community
  • 1
  • 1
Thomas Ayoub
  • 29,063
  • 15
  • 95
  • 142

2 Answers2

9

See this post - most likely when mixing C++ code with the C interface of FFMPEG you forgot the extern "C" keyword so linker is using C++ function name mangling and thus cannot find the references. You should wrap the FFMPEG includes with extern "C" like this:

extern "C" { 
#include <libavcodec/avcodec.h> 
#include <libavformat/avformat.h>
}
Community
  • 1
  • 1
Rudolfs Bundulis
  • 11,636
  • 6
  • 33
  • 71
  • 1
    Sir, you deserve a medal. But I face a few more error which are not fixed by you amazing answer. I'll edit my question – Thomas Ayoub Sep 09 '14 at 10:53
  • @Thomas Are you linking against 32bit FFMPEG or 64bit? Seems that your app and FFMPEG have different architectures. – Rudolfs Bundulis Sep 09 '14 at 10:58
  • I've not the single clue where should I find that ? – Thomas Ayoub Sep 09 '14 at 11:03
  • If my assumption that you are on Mac OS/Linux is right, you can use otool to dump on the FFMPEG .so files to determine the version - see this http://stackoverflow.com/questions/12001195/how-can-i-know-which-architecture-an-a-file-is-built-for . What OS are you on (is my assumption about Mac OS X right)? Where did you obtain the FFMPEG libraries (well on Linux the packaging system should install the right architecture, on Mac OS X I don't actually know how you obtain the binaries of FFMPEG)? If you built it from source, did you build it correctly? – Rudolfs Bundulis Sep 09 '14 at 11:06
  • Yes, I'm running Mac OS 10.9.4. I use brew to install (download and compile) packages and it works well with my others softwares. – Thomas Ayoub Sep 09 '14 at 11:09
  • Ok, it's been a while since I used Mac OS X and I'm not sure I correctly remember if all the brew, macports and other softwares actually allowed to choose the architecture. Can you run the otool on the library? – Rudolfs Bundulis Sep 09 '14 at 11:12
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/60888/discussion-between-thomas-and-rudolfs-bundulis). – Thomas Ayoub Sep 09 '14 at 11:16
0

The link to FFmpeg site with transcoding example is broken now, but you can find it here: http://ffmpeg.org/doxygen/trunk/doc_2examples_2transcoding_8c-example.html

I think the problem is that the example uses a later version of FFmpeg. I'm using an Android port of FFmpeg 1.0 from https://github.com/appunite/AndroidFFmpeg and I'm also facing the same issues (ie undeclared avfilter_graph_parse_ptr). My FFmpeg source code does not have it but declares avfilter_graph_parse instead.

My source code desn't have transcoding example, I think doc/examples/decoding_encoding.c should be used instead.

I changed code to use old functions, for example av_frame_free -> avcodec_free_frame, av_buffersrc_write_frame_flags -> av_buffersrc_write_frame and so on, now it at least compiles...

Mixaz
  • 4,068
  • 1
  • 29
  • 55