目录
3.1 关于提示找不到“stdio" "iostream"头文件的问题
一、问题背景
硬件平台:正点原子-imx6ull
背景介绍:在imx6ull已经移植好了ffmpeg,在进行ffmpeg编程过程中,使用雷神的例程,无法交叉编译通过。下面针对出现的现象、排查思路、解决方案进行讲解。
二、问题现象
2.1 ffmpeg测试例程
/**
* 最简单的FFmpeg Helloworld程序
* Simplest FFmpeg HelloWorld
*
* 雷霄骅 Lei Xiaohua
* leixiaohua1020@126.com
* 中国传媒大学/数字电视技术
* Communication University of China / Digital TV Technology
* http://blog.csdn.net/leixiaohua1020
*
*
* 本程序是基于FFmpeg函数的最简单的程序。它可以打印出FFmpeg类库的下列信息:
* Protocol: FFmpeg类库支持的协议
* AVFormat: FFmpeg类库支持的封装格式
* AVCodec: FFmpeg类库支持的编解码器
* AVFilter: FFmpeg类库支持的滤镜
* Configure: FFmpeg类库的配置信息
*
* This is the simplest program based on FFmpeg API. It can show following
* informations about FFmpeg library:
* Protocol: Protocols supported by FFmpeg.
* AVFormat: Container format supported by FFmpeg.
* AVCodec: Encoder/Decoder supported by FFmpeg.
* AVFilter: Filters supported by FFmpeg.
* Configure: configure information of FFmpeg.
*
*/
#include <stdio.h>
#define __STDC_CONSTANT_MACROS
#ifdef _WIN32
//Windows
extern "C"
{
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libavfilter/avfilter.h"
};
#else
//Linux...
#ifdef __cplusplus
extern "C"
{
#endif
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavfilter/avfilter.h>
#ifdef __cplusplus
};
#endif
#endif
//FIX
struct URLProtocol;
/**
* Protocol Support Information
*/
char * urlprotocolinfo(){
char *info=(char *)malloc(40000);
memset(info,0,40000);
av_register_all();
struct URLProtocol *pup = NULL;
//Input
struct URLProtocol **p_temp = &pup;
avio_enum_protocols((void **)p_temp, 0);
while ((*p_temp) != NULL){
sprintf(info, "%s[In ][%10s]\n", info, avio_enum_protocols((void **)p_temp, 0));
}
pup = NULL;
//Output
avio_enum_protocols((void **)p_temp, 1);
while ((*p_temp) != NULL){
sprintf(info, "%s[Out][%10s]\n", info, avio_enum_protocols((void **)p_temp, 1));
}
return info;
}
/**
* AVFormat Support Information
*/
char * avformatinfo(){
char *info=(char *)malloc(40000);
memset(info,0,40000);
av_register_all();
AVInputFormat *if_temp = av_iformat_next(NULL);
AVOutputFormat *of_temp = av_oformat_next(NULL);
//Input
while(if_temp!=NULL){
sprintf(info, "%s[In ] %10s\n", info, if_temp->name);
if_temp=if_temp->next;
}
//Output
while (of_temp != NULL){
sprintf(info, "%s[Out] %10s\n", info, of_temp->name);
of_temp = of_temp->next;
}
return info;
}
/**
* AVCodec Support Information
*/
char * avcodecinfo()
{
char *info=(char *)malloc(40000);
memset(info,0,40000);
av_register_all();
AVCodec *c_temp = av_codec_next(NULL);
while(c_temp!=NULL){
if (c_temp->decode!=NULL){
sprintf(info, "%s[Dec]", info);
}
else{
sprintf(info, "%s[Enc]", info);
}
switch (c_temp->type){
case AVMEDIA_TYPE_VIDEO:
sprintf(info, "%s[Video]", info);
break;
case AVMEDIA_TYPE_AUDIO:
sprintf(info, "%s[Audio]", info);
break;
default:
sprintf(info, "%s[Other]", info);
break;
}
sprintf(info, "%s %10s\n", info, c_temp->name);
c_temp=c_temp->next;
}
return info;
}
/**
* AVFilter Support Information
*/
char * avfilterinfo()
{
char *info=(char *)malloc(40000);
memset(info,0,40000);
avfilter_register_all();
AVFilter *f_temp = (AVFilter *)avfilter_next(NULL);
while (f_temp != NULL){
sprintf(info, "%s[%15s]\n", info, f_temp->name);
f_temp=f_temp->next;
}
return info;
}
/**
* Configuration Information
*/
char * configurationinfo()
{
char *info=(char *)malloc(40000);
memset(info,0,40000);
av_register_all();
sprintf(info, "%s\n", avcodec_configuration());
return info;
}
int main(int argc, char* argv[])
{
char *infostr=NULL;
infostr=configurationinfo();
printf("\n<<Configuration>>\n%s",infostr);
free(infostr);
infostr=urlprotocolinfo();
printf("\n<<URLProtocol>>\n%s",infostr);
free(infostr);
infostr=avformatinfo();
printf("\n<<AVFormat>>\n%s",infostr);
free(infostr);
infostr=avcodecinfo();
printf("\n<<AVCodec>>\n%s",infostr);
free(infostr);
infostr=avfilterinfo();
printf("\n<<AVFilter>>\n%s",infostr);
free(infostr);
return 0;
}
2.2 编译脚本
编译脚本中,能够使用x86的gcc工具链以及arm开发板的交叉编译工具链进行编译。
其中gcc工具链经过测试可以使用。但是arm交叉编译工具链无法正常运行,提示错误如下。
2.3 错误提示
错误提示链接器ld无法找到对应的动态库。
三、问题排查
3.1 关于提示找不到“stdio" "iostream"头文件的问题
3.1.1查看工具链头文件检索位置
echo | arm-linux-gnueabihf-g++ -v -x c++ -E -
3.1.2 根据工具链路径查找头文件
find /usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin/../lib/gcc/arm-linux-gnueabihf/4.9.4/../../../../arm-linux-gnueabihf/* -name "iostream"
根据上述查找结果可以知道arm-linux-gnueabihf-工具链的头文件路径为:/usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/arm-lnux-gnueabihf/include/c++/4.94。
3.1.3 在编译脚本中指定头文件路径
-I /usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/arm-linux-gnueabihf/include/c++/4.9.4
3.2 关于提示找不到ffmpeg动态库的问题
3.2.1 问题现象
提示libavfilter\libavcodec动态库没有找到,以及由于没有找到动态库而出现的未定义引用的错误。
3.2.2 排查指定的动态库路径是否错误
3.2.3 排查动态库路径中是否存在文件缺失
3.2.4 有效解决方案
经过3.2.2 3.2.3的排查,发现都没有存在问题,此时排查陷入困境。
通过网上查阅资料,通过参考 关于C#:链接libavcodec和libavformat:未定义的引用 | 码农家园 (codenong.com),添加-lswcale与-lswresample的动态库连接。即可消除未找到libavfilter libavcodec动态库的错误。