裁剪FFmpeg编译GIF编码Demo时链接错误的排查与解决
FFmpeg裁剪后GIF编码Demo编译链接错误排查与解决
需求背景
我需要使用FFmpeg的GIF编码功能将ARGB图像编码为GIF,因为GIF库的编码效果不如FFmpeg。但avcodec等库体积过大,因此对FFmpeg进行裁剪,仅保留GIF编码功能。
FFmpeg裁剪配置脚本
#!/bin/sh # ./configure --prefix=$(pwd)/output --arch=arm --target-os=linux --enable-cross-compile --disable-asm --cross-prefix=arm-linux-gnueabihf- ./configure --prefix=$(pwd)/output --target-os=linux --disable-asm \ --disable-gpl --enable-nonfree --enable-error-resilience --enable-debug --enable-shared --enable-small --enable-zlib \ --disable-ffmpeg --disable-ffprobe --disable-ffplay --disable-programs --disable-symver\ --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-decoder=h264 --enable-avformat \ --disable-txtpages --enable-avcodec --enable-avutil \ --disable-avresample --disable-avfilter --disable-avdevice --disable-postproc \ --disable-swscale --enable-decoder=gif --enable-demuxer=gif --enable-muxer=gif --disable-iconv \ --disable-v4l2-m2m --disable-indevs --disable-outdevs make clean make -j8 make install
GIF编码测试Demo代码
#include <stdio.h> // #include "output/include/imgutils.h" #include "libavcodec/avcodec.h" #include "libavformat/avformat.h" #include "libavutil/avutil.h" int main() { AVCodec *enc_codec; AVCodecContext *enc_ctx = NULL; AVStream *stream = NULL; int ret; AVFormatContext *fmt_ctx = avformat_alloc_context(); if (!fmt_ctx) { fprintf(stderr, "Could not allocate format context\n"); return 1; } AVInputFormat *input_fmt = av_find_input_format("image2"); if ((ret = avformat_open_input(&fmt_ctx, "input.bmp", input_fmt, NULL)) < 0) { fprintf(stderr, "Could not open input file %d\n", ret); return ret; } AVCodec *dec_codec = avcodec_find_decoder(AV_CODEC_ID_BMP); if (!dec_codec) { fprintf(stderr, "Decoder not found\n"); return 1; } AVCodecContext *dec_ctx = avcodec_alloc_context3(dec_codec); if (!dec_ctx) { fprintf(stderr, "Could not allocate decoder context\n"); return 1; } if ((ret = avcodec_open2(dec_ctx, dec_codec, NULL)) < 0) { fprintf(stderr, "Could not open decoder\n"); return 1; } AVOutputFormat *out_fmt = av_guess_format("gif", NULL, NULL); if (!out_fmt) { fprintf(stderr, "Could not find output format\n"); return 1; } AVFormatContext *out_ctx = NULL; if ((ret = avformat_alloc_output_context2(&out_ctx, out_fmt, NULL, NULL)) < 0) { fprintf(stderr, "Could not allocate output context\n"); return 1; } stream = avformat_new_stream(out_ctx, NULL); if (!stream) { fprintf(stderr, "Could not create new stream\n"); return 1; } enc_codec = avcodec_find_encoder(AV_CODEC_ID_GIF); if (!enc_codec) { fprintf(stderr, "Encoder not found\n"); return 1; } enc_ctx = avcodec_alloc_context3(enc_codec); if (!enc_ctx) { fprintf(stderr, "Could not allocate encoder context\n"); return 1; } if ((ret = avcodec_parameters_from_context(stream->codecpar, dec_ctx)) < 0) { fprintf(stderr, "Could not copy decoder parameters\n"); return 1; } if ((ret = avcodec_open2(enc_ctx, enc_codec, NULL)) < 0) { fprintf(stderr, "Could not open encoder\n"); return 1; } enc_ctx->pix_fmt = AV_PIX_FMT_RGB8; enc_ctx->width = dec_ctx->width; enc_ctx->height = dec_ctx->height; enc_ctx->time_base = (AVRational){1, 25}; avformat_init_output(out_ctx, NULL); if (!(out_fmt->flags & AVFMT_NOFILE)) { if ((ret = avio_open(&out_ctx->pb, "output.gif", AVIO_FLAG_WRITE)) < 0) { fprintf(stderr, "Could not open output file\n"); return ret; } } avformat_write_header(out_ctx, NULL); AVFrame *frame = av_frame_alloc(); AVPacket pkt; int frame_count = 0; while (av_read_frame(fmt_ctx, &pkt) >= 0) { avcodec_send_packet(dec_ctx, &pkt); while (avcodec_receive_frame(dec_ctx, frame) == 0) { avcodec_send_frame(enc_ctx, frame); while (avcodec_receive_packet(enc_ctx, &pkt) == 0) { pkt.stream_index = stream->index; av_interleaved_write_frame(out_ctx, &pkt); av_packet_unref(&pkt); } frame_count++; printf("Encoded frame %d\n", frame_count); } av_packet_unref(&pkt); } av_write_trailer(out_ctx); avcodec_close(enc_ctx); avcodec_free_context(&enc_ctx); avcodec_close(dec_ctx); avcodec_free_context(&dec_ctx); av_frame_free(&frame); avformat_close_input(&fmt_ctx); avformat_free_context(fmt_ctx); avio_close(out_ctx->pb); avformat_free_context(out_ctx); return 0; }
Demo编译脚本
#!/bin/sh gcc -o x2gif x2gif.c -L ./output/lib/ -l:libavformat.a -l:libavcodec.a -l:libavutil.a -lz -I ./output/include/
编译错误信息
./output/lib/libavutil.a(lfg.o): In function `av_bmg_get': /data1/yang/tool/ffmpeg-3.4.4/libavutil/lfg.c:59: undefined reference to `log' ./output/lib/libavutil.a(hwcontext_cuda.o): In function `cuda_free_functions': /data1/yang/tool/ffmpeg-3.4.4/./compat/cuda/dynlink_loader.h:175: undefined reference to `dlclose' ./output/lib/libavutil.a(hwcontext_cuda.o): In function `cuda_load_functions': /data1/yang/tool/ffmpeg-3.4.4/./compat/cuda/dynlink_loader.h:192: undefined reference to `dlopen' /data1/yang/tool/ffmpeg-3.4.4/./compat/cuda/dynlink_loader.h:194: undefined reference to `dlsym' /data1/yang/tool/ffmpeg-3.4.4/./compat/cuda/dynlink_loader.h:195: undefined reference to `dlsym' /data1/yang/tool/ffmpeg-3.4.4/./compat/cuda/dynlink_loader.h:196: undefined reference to `dlsym' /data1/yang/tool/ffmpeg-3.4.4/./compat/cuda/dynlink_loader.h:197: undefined reference to `dlsym' /data1/yang/tool/ffmpeg-3.4.4/./compat/cuda/dynlink_loader.h:198: undefined reference to `dlsym' ./output/lib/libavutil.a(hwcontext_cuda.o):/data1/yang/tool/ffmpeg-3.4.4/./compat/cuda/dynlink_loader.h:199: more undefined references to `dlsym' follow ./output/lib/libavutil.a(rational.o): In function `av_d2q': /data1/yang/tool/ffmpeg-3.4.4/libavutil/rational.c:120: undefined reference to `floor' ./output/lib/libavutil.a(eval.o): In function `eval_expr': /data1/yang/tool/ffmpeg-3.4.4/libavutil/eval.c:184: undefined reference to `exp' /data1/yang/tool/ffmpeg-3.4.4/libavutil/eval.c:185: undefined reference to `exp' /data1/yang/tool/ffmpeg-3.4.4/libavutil/eval.c:189: undefined reference to `floor' /data1/yang/tool/ffmpeg-3.4.4/libavutil/eval.c:190: undefined reference to `ceil' /data1/yang/tool/ffmpeg-3.4.4/libavutil/eval.c:191: undefined reference to `trunc' /data1/yang/tool/ffmpeg-3.4.4/libavutil/eval.c:192: undefined reference to `round' /data1/yang/tool/ffmpeg-3.4.4/libavutil/eval.c:263: undefined reference to `pow' /data1/yang/tool/ffmpeg-3.4.4/libavutil/eval.c:300: undefined reference to `floor' /data1/yang/tool/ffmpeg-3.4.4/libavutil/eval.c:309: undefined reference to `pow' /data1/yang/tool/ffmpeg-3.4.4/libavutil/eval.c:315: undefined reference to `hypot' /data1/yang/tool/ffmpeg-3.4.4/libavutil/eval.c:316: undefined reference to `atan2' ./output/lib/libavutil.a(eval.o): In function `ff_exp10': /data1/yang/tool/ffmpeg-3.4.4/libavutil/ffmath.h:44: undefined reference to `exp2' ./output/lib/libavutil.a(eval.o): In function `parse_primary': /data1/yang/tool/ffmpeg-3.4.4/libavutil/eval.c:417: undefined reference to `sinh' /data1/yang/tool/ffmpeg-3.4.4/libavutil/eval.c:418: undefined reference to `cosh' /data1/yang/tool/ffmpeg-3.4.4/libavutil/eval.c:419: undefined reference to `tanh' /data1/yang/tool/ffmpeg-3.4.4/libavutil/eval.c:420: undefined reference to `sin' /data1/yang/tool/ffmpeg-3.4.4/libavutil/eval.c:421: undefined reference to `cos' /data1/yang/tool/ffmpeg-3.4.4/libavutil/eval.c:422: undefined reference to `tan' /data1/yang/tool/ffmpeg-3.4.4/libavutil/eval.c:423: undefined reference to `atan' /data1/yang/tool/ffmpeg-3.4.4/libavutil/eval.c:424: undefined reference to `asin' /data1/yang/tool/ffmpeg-3.4.4/libavutil/eval.c:425: undefined reference to `acos' /data1/yang/tool/ffmpeg-3.4.4/libavutil/eval.c:426: undefined reference to `exp' /data1/yang/tool/ffmpeg-3.4.4/libavutil/eval.c:427: undefined reference to `log' /data1/yang/tool/ffmpeg-3.4.4/libavutil/eval.c:428: undefined reference to `fabs'
问题
如何排查并解决该编译链接错误?
内容的提问来源于stack exchange,提问作者yangjinhui2936
相关产品推荐
相关产品推荐

