使用ffmpeg库编译错误undefined reference to `BZ2_bzDecompressInit'

本文介绍了解决使用FFmpeg解码Matroska格式文件时遇到的未定义引用错误的方法,通过添加-lbz2参数成功解决了问题。
gcc -DNIGHT demo.c -lalgnight -lavcodec -lavdevice -lavfilter -lavformat -lavutil -lswresample -lswscale -lz -lm -o app

./libffmpeg/lib/libavformat.a(matroskadec.o): In function `matroska_decode_buffer':
/root/ffmpeg-0.11/libavformat/matroskadec.c:1100: undefined reference to `BZ2_bzDecompressInit'

解决办法:

参数后加上-lbz2


-lz 是对于zip的支持

-lm是对于数学函数的支持

/usr/bin/ld: warning: libavcodec.so.57, needed by /usr/local/lib/dji/bag/libdecoder_hdr_soft.so, not found (try using -rpath or -rpath-link) /usr/bin/ld: warning: libavutil.so.55, needed by /usr/local/lib/dji/bag/libdecoder_hdr_soft.so, not found (try using -rpath or -rpath-link) /usr/bin/ld: /usr/local/lib/dji/bag/libdecoder_hdr_soft.so: undefined reference to `av_free@LIBAVUTIL_55' /usr/bin/ld: /usr/local/lib/dji/bag/libdecoder_hdr_soft.so: undefined reference to `av_packet_alloc@LIBAVCODEC_57' /usr/bin/ld: /usr/local/lib/dji/bag/libdecoder_hdr_soft.so: undefined reference to `avcodec_send_packet@LIBAVCODEC_57' /usr/bin/ld: /usr/local/lib/dji/bag/libdecoder_hdr_soft.so: undefined reference to `avcodec_close@LIBAVCODEC_57' /usr/bin/ld: /usr/local/lib/dji/bag/libdecoder_hdr_soft.so: undefined reference to `av_frame_free@LIBAVUTIL_55' /usr/bin/ld: /usr/local/lib/dji/bag/libdecoder_hdr_soft.so: undefined reference to `av_frame_alloc@LIBAVUTIL_55' /usr/bin/ld: /usr/local/lib/dji/bag/libdecoder_hdr_soft.so: undefined reference to `avcodec_open2@LIBAVCODEC_57' /usr/bin/ld: /usr/local/lib/dji/bag/libdecoder_hdr_soft.so: undefined reference to `avcodec_register_all@LIBAVCODEC_57' /usr/bin/ld: /usr/local/lib/dji/bag/libdecoder_hdr_soft.so: undefined reference to `avcodec_receive_frame@LIBAVCODEC_57' /usr/bin/ld: /usr/local/lib/dji/bag/libdecoder_hdr_soft.so: undefined reference to `avcodec_find_decoder@LIBAVCODEC_57' /usr/bin/ld: /usr/local/lib/dji/bag/libdecoder_hdr_soft.so: undefined reference to `avcodec_alloc_context3@LIBAVCODEC_57' collect2: error: ld returned 1 exit status make[2]: *** [CMakeFiles/parser_H265.dir/build.make:169: parser_H265] Error 1 make[1]: *** [CMakeFiles/Makefile2:111: CMakeFiles/parser_H265.dir/all] Error 2 make[1]: *** Waiting for unfinished jobs.... [100%] Linking CXX executable obtain_dbag_data [100%] Built target obtain_dbag_data make: *** [Makefile:91: all] Error 2 解决
09-27
std::string yuv_to_h264_string(const std::string& yuv_path, int width, int height, int frame_count) { // 1. 初始化FFmpeg av_register_all(); avcodec_register_all(); // 2. 查找H264编码器 const AVCodec* codec = avcodec_find_encoder(AV_CODEC_ID_H264); if (!codec) { throw std::runtime_error("H264 encoder not found"); } // 3. 创建编码器上下文 AVCodecContext* codec_ctx = avcodec_alloc_context3(codec); if (!codec_ctx) { throw std::runtime_error("Could not allocate video codec context"); } // 4. 设置编码参数 codec_ctx->bit_rate = 400000; codec_ctx->width = width; codec_ctx->height = height; codec_ctx->time_base = (AVRational){1, 25}; codec_ctx->framerate = (AVRational){25, 1}; codec_ctx->gop_size = 10; codec_ctx->max_b_frames = 1; codec_ctx->pix_fmt = AV_PIX_FMT_YUV420P; // 5. 打开编码器 if (avcodec_open2(codec_ctx, codec, nullptr) < 0) { throw std::runtime_error("Could not open codec"); } // 6. 创建帧缓冲区 AVFrame* frame = av_frame_alloc(); if (!frame) { throw std::runtime_error("Could not allocate video frame"); } frame->format = codec_ctx->pix_fmt; frame->width = codec_ctx->width; frame->height = codec_ctx->height; if (av_frame_get_buffer(frame, 0) < 0) { throw std::runtime_error("Could not allocate frame buffer"); } // 7. 打开YUV输入文件 std::ifstream yuv_file(yuv_path, std::ios::binary); if (!yuv_file.is_open()) { throw std::runtime_error("Could not open YUV file"); } // 8. 初始化数据包 AVPacket* pkt = av_packet_alloc(); if (!pkt) { throw std::runtime_error("Could not allocate packet"); } // 9. 存储H264数据的缓冲区 std::string h264_data; // 10. 逐帧编码循环 for (int i = 0; i < frame_count; ++i) { // 读取YUV数据 int frame_size = width * height * 3 / 2; // YUV420P格式 std::vector<uint8_t> yuv_buffer(frame_size); yuv_file.read(reinterpret_cast<char*>(yuv_buffer.data()), frame_size); // 准备帧数据 if (av_frame_make_writable(frame) < 0) { throw std::runtime_error("Frame not writable"); } // 填充YUV平面数据 frame->data[0] = yuv_buffer.data(); // Y分量 frame->data[1] = yuv_buffer.data() + width * height; // U分量 frame->data[2] = yuv_buffer.data() + width * height + width * height / 4; // V分量 frame->linesize[0] = width; frame->linesize[1] = width / 2; frame->linesize[2] = width / 2; frame->pts = i; // 编码帧 int ret = avcodec_send_frame(codec_ctx, frame); if (ret < 0) { throw std::runtime_error("Error sending frame to encoder"); } // 接收编码后的数据包 while (ret >= 0) { ret = avcodec_receive_packet(codec_ctx, pkt); if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) { break; } else if (ret < 0) { throw std::runtime_error("Error during encoding"); } // 将H264数据添加到字符串 h264_data.append(reinterpret_cast<char*>(pkt->data), pkt->size); av_packet_unref(pkt); } } // 11. 冲刷编码器 avcodec_send_frame(codec_ctx, nullptr); while (true) { int ret = avcodec_receive_packet(codec_ctx, pkt); if (ret == AVERROR_EOF) break; if (ret < 0) throw std::runtime_error("Error flushing encoder"); // 添加剩余数据 h264_data.append(reinterpret_cast<char*>(pkt->data), pkt->size); av_packet_unref(pkt); } // 12. 清理资源 av_frame_free(&frame); av_packet_free(&pkt); avcodec_free_context(&codec_ctx); yuv_file.close(); return h264_data; }这段代码添加了这些之后, /usr/lib/aarch64-linux-gnu/libavcodec.so.58 /usr/lib/aarch64-linux-gnu/libavcodec.so.58.134.100 /usr/lib/aarch64-linux-gnu/libavcodec.so /usr/lib/aarch64-linux-gnu/libavcodec.a,还是报错如下,如何解决,[main] 正在生成文件夹: /home/aiec/Templates/test/build all [build] 正在启动生成 [proc] 正在执行命令: /usr/bin/cmake --build /home/aiec/Templates/test/build --config Debug --target all -j 8 -- [build] Consolidate compiler generated dependencies of target CrossCompileProject [build] [ 50%] Linking CXX executable bin/CrossCompileProject [build] /usr/bin/ld: CMakeFiles/CrossCompileProject.dir/TrainControl.cpp.o: in function `yuv_to_h264_string(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int, int, int)&#39;: [build] /home/aiec/Templates/test/TrainControl.cpp:471: undefined reference to `av_register_all()&#39; [build] /usr/bin/ld: /home/aiec/Templates/test/TrainControl.cpp:472: undefined reference to `avcodec_register_all()&#39; [build] /usr/bin/ld: /home/aiec/Templates/test/TrainControl.cpp:475: undefined reference to `avcodec_find_encoder(AVCodecID)&#39; [build] /usr/bin/ld: /home/aiec/Templates/test/TrainControl.cpp:481: undefined reference to `avcodec_alloc_context3(AVCodec const*)&#39; [build] /usr/bin/ld: /home/aiec/Templates/test/TrainControl.cpp:497: undefined reference to `avcodec_open2(AVCodecContext*, AVCodec const*, AVDictionary**)&#39; [build] /usr/bin/ld: /home/aiec/Templates/test/TrainControl.cpp:502: undefined reference to `av_frame_alloc()&#39; [build] /usr/bin/ld: /home/aiec/Templates/test/TrainControl.cpp:510: undefined reference to `av_frame_get_buffer(AVFrame*, int)&#39; [build] /usr/bin/ld: /home/aiec/Templates/test/TrainControl.cpp:521: undefined reference to `av_packet_alloc()&#39; [build] /usr/bin/ld: /home/aiec/Templates/test/TrainControl.cpp:537: undefined reference to `av_frame_make_writable(AVFrame*)&#39; [build] /usr/bin/ld: /home/aiec/Templates/test/TrainControl.cpp:552: undefined reference to `avcodec_send_frame(AVCodecContext*, AVFrame const*)&#39; [build] /usr/bin/ld: /home/aiec/Templates/test/TrainControl.cpp:559: undefined reference to `avcodec_receive_packet(AVCodecContext*, AVPacket*)&#39; [build] /usr/bin/ld: /home/aiec/Templates/test/TrainControl.cpp:568: undefined reference to `av_packet_unref(AVPacket*)&#39; [build] /usr/bin/ld: /home/aiec/Templates/test/TrainControl.cpp:573: undefined reference to `avcodec_send_frame(AVCodecContext*, AVFrame const*)&#39; [build] /usr/bin/ld: /home/aiec/Templates/test/TrainControl.cpp:575: undefined reference to `avcodec_receive_packet(AVCodecContext*, AVPacket*)&#39; [build] /usr/bin/ld: /home/aiec/Templates/test/TrainControl.cpp:581: undefined reference to `av_packet_unref(AVPacket*)&#39; [build] /usr/bin/ld: /home/aiec/Templates/test/TrainControl.cpp:585: undefined reference to `av_frame_free(AVFrame**)&#39; [build] /usr/bin/ld: /home/aiec/Templates/test/TrainControl.cpp:586: undefined reference to `av_packet_free(AVPacket**)&#39; [build] /usr/bin/ld: /home/aiec/Templates/test/TrainControl.cpp:587: undefined reference to `avcodec_free_context(AVCodecContext**)&#39; [build] collect2: error: ld returned 1 exit status [build] gmake[2]: *** [CMakeFiles/CrossCompileProject.dir/build.make:160: bin/CrossCompileProject] Error 1 [build] gmake[1]: *** [CMakeFiles/Makefile2:83: CMakeFiles/CrossCompileProject.dir/all] Error 2 [build] gmake: *** [Makefile:91: all] Error 2 [proc] 命令“/usr/bin/cmake --build /home/aiec/Templates/test/build --config Debug --target all -j 8 --”已退出,代码为 2 [driver] 生成完毕: 00:00:01.544 [build] 生成已完成,退出代码为 2
11-05
在海思平台进行 FFmpeg 交叉编译时出现 `undefined reference to &#39;__atomic_load_8&#39;` 错误,通常是因为链接器找不到 `libatomic` 。可以尝试以下解决办法: #### 1. 确认 `libatomic` 已安装 首先要确保 `libatomic` 已经正确交叉编译并安装到指定的目标路径。如果还未安装,可以参考前面提到的交叉编译 `libatomic` 的步骤进行安装。 #### 2. 指定 `libatomic` 路径和链接选项 在 FFmpeg 交叉编译时,需要明确指定 `libatomic` 的路径和链接选项。可以通过在 `./configure` 命令中添加相关参数来实现: ```bash ./configure --cross-prefix=<cross_prefix> --target-os=linux --arch=<arch> --enable-cross-compile --extra-ldflags="-L/path/to/libatomic -latomic" ``` 其中: - `<cross_prefix>` 是交叉编译工具链的前缀,例如 `arm-hisiv500-linux-`。 - `<arch>` 是目标架构,例如 `arm`。 - `-L/path/to/libatomic` 指定 `libatomic` 的路径。 - `-latomic` 告诉链接器链接 `libatomic` 。 #### 3. 检查环境变量 确保 `LDFLAGS` 环境变量中包含了 `libatomic` 的路径和链接选项: ```bash export LDFLAGS="-L/path/to/libatomic -latomic" ``` #### 示例 假设交叉编译工具链前缀是 `arm-hisiv500-linux-`,目标架构是 `arm`,`libatomic` 安装在 `/opt/arm-gcc/lib` 目录下: ```bash ./configure --cross-prefix=arm-hisiv500-linux- --target-os=linux --arch=arm --enable-cross-compile --extra-ldflags="-L/opt/arm-gcc/lib -latomic" make ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值