前言
本文参考雷霄骅的博文最简单的基于FFMPEG的Helloworld程序,使用c++根据ffmpeg-4.1版本改写(原文代码基于旧版本ffmpeg)。代码见下文。
本文代码地址见https://github.com/2997215859/ffplay-learn/blob/master/Video/print_info.cpp
本文代码基于ffmpeg-4.1版本,事先需要安装好ffmpeg
本文代码提供CMakeLists.txt,见附录CMakeLists.txt部分,或根据CMakeLists.txt改写。需要链接的库如下(基本上安装ffmpeg、ffplay、SDL2之后就有了)。
avdevice avfilter avformat avcodec swscale swresample postproc avutil m xcb xcb-shm xcb xcb-shape xcb xcb-xfixes xcb-render xcb-shape xcb asound pthread m fontconfig freetype freetype z bz2 lzma SDL2 SDL2main
代码
主函数
int main () { cout << "\n<<Configuration>>\n" << configurationInfo(); // 打印ffmpeg的configure信息 cout << "\n<<URLProtocol>>\n" << urlProtocolInfo(); // 打印URL cout << "\n<AVFormat>\n" << formationInfo(); cout << "\n<<AVCodec>>\n" << avcodecInfo(); cout << "\n<<AVFilter>>\n" << avfilterInfo(); return 0; }
分函数
1. 打印ffempg的configure信息,直接调用avdevice_configuration函数,返回char字符串
string configurationInfo () { return string(avdevice_configuration()); }
2. 利用avio_enum_protocols迭代libavformat/protocol_list.c中的url_protocols数组,从而输出ffmpeg支持的IO协议
string urlProtocolInfo () { string info; URLProtocol *pup = NULL; // input avio_enum_protocols((void**)&pup, 0); while (pup != NULL) { const char *t = avio_enum_protocols((void**)&pup, 0); info += string("[In ][") + string(t==NULL?"": t) + string("]\n"); } pup = NULL; avio_enum_protocols((void**)&pup, 1); while (pup != NULL) { const char *t = avio_enum_protocols((void**)&pup, 1); info += string("[Out ][") + string(t==NULL?"": t) + string("]\n"); } return info; }
3. 利用av_demuxer_iterate和av_muxer_iterate函数迭代libavformat/demuxer_list.c中的demuxer_list数组,从而输出ffmpeg支持的格式
string formationInfo(){ string info; void *opaque = NULL; const AVInputFormat *inFormat; const AVOutputFormat *outFormat; //Output while ((inFormat = av_demuxer_iterate(&opaque)) != NULL) info += string("[In ] ") + inFormat->name + "\n"; // In while ((outFormat = av_muxer_iterate(&opaque)) != NULL) info += string("[Out ] ") + outFormat->name + "\n"; return info; }
4. 利用av_codec_iterate迭代libavcodec/codec_lists.c中的codec_list数组,从而输出ffmpeg支持的编码器信息
string avcodecInfo() { string info; void *opaque = NULL; const AVCodec *coder; while ((coder = av_codec_iterate(&opaque)) != NULL) { if (coder->decode != NULL) info += "[Dec]"; switch (coder->type) { case AVMEDIA_TYPE_VIDEO: info += "[Video]"; break; case AVMEDIA_TYPE_AUDIO: info += "[Audio]"; break; default: info += "[Other]"; break; } info += string("") + coder->name + "\n"; } return info; }
5. 利用av_filter_iterate迭代libavfilter/filter_list.c中的filter_list数组,从而输出ffmpeg支持的滤波器
string avfilterInfo() { string info; void *opaque = NULL; const AVFilter *filter; while ((filter = av_filter_iterate(&opaque)) != NULL) info += string("[") + filter->name + "]\n"; return info; }
附录
完整代码
#include <cstdio> #include <iostream> #include <string> using namespace std; #define __STDC_CONSTANT_MACROS #ifdef __cplusplus extern "C" { #endif #include <libavformat/avformat.h> #include <libavcodec/avcodec.h> #include <libavfilter/avfilter.h> #include <libavdevice/avdevice.h> #include <libavutil/mem.h> #ifdef __cplusplus }; #endif struct URLProtocol; /** * configuration information */ string configurationInfo () { return string(avdevice_configuration()); } /** * protocol support information * @return */ string urlProtocolInfo () { string info; URLProtocol *pup = NULL; // input avio_enum_protocols((void**)&pup, 0); while (pup != NULL) { const char *t = avio_enum_protocols((void**)&pup, 0); info += string("[In ][") + string(t==NULL?"": t) + string("]\n"); } pup = NULL; avio_enum_protocols((void**)&pup, 1); while (pup != NULL) { const char *t = avio_enum_protocols((void**)&pup, 1); info += string("[Out ][") + string(t==NULL?"": t) + string("]\n"); } return info; } /** * AVFormat Support Information */ string formationInfo(){ string info; void *opaque = NULL; const AVInputFormat *inFormat; const AVOutputFormat *outFormat; //Output while ((inFormat = av_demuxer_iterate(&opaque)) != NULL) info += string("[In ] ") + inFormat->name + "\n"; // In while ((outFormat = av_muxer_iterate(&opaque)) != NULL) info += string("[Out ] ") + outFormat->name + "\n"; return info; } /** * AVCodec Support Information * @return */ string avcodecInfo() { string info; void *opaque = NULL; const AVCodec *coder; while ((coder = av_codec_iterate(&opaque)) != NULL) { if (coder->decode != NULL) info += "[Dec]"; switch (coder->type) { case AVMEDIA_TYPE_VIDEO: info += "[Video]"; break; case AVMEDIA_TYPE_AUDIO: info += "[Audio]"; break; default: info += "[Other]"; break; } info += string("") + coder->name + "\n"; } return info; } /** * AVFilter Support Information */ string avfilterInfo() { string info; void *opaque = NULL; const AVFilter *filter; while ((filter = av_filter_iterate(&opaque)) != NULL) info += string("[") + filter->name + "]\n"; return info; } int main () { cout << "\n<<Configuration>>\n" << configurationInfo(); cout << "\n<<URLProtocol>>\n" << urlProtocolInfo(); cout << "\n<AVFormat>\n" << formationInfo(); cout << "\n<<AVCodec>>\n" << avcodecInfo(); cout << "\n<<AVFilter>>\n" << avfilterInfo(); return 0; }
CMakeLists.txt
cmake_minimum_required(VERSION 3.13) project(player) set(CMAKE_CXX_STANDARD 11) include_directories(.) include_directories(/usr/include/.) include_directories(/usr/local/include/.) # 设置可执行文件生成路径 set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/bin") # 生成debug版本 SET(CMAKE_BUILD_TYPE "release") if (CMAKE_BUILD_TYPE STREQUAL debug) add_definitions(-D_DEBUG) endif () SET(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g -ggdb -std=c++11") SET(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall -std=c++11") link_directories(/usr/lib/) link_directories(/usr/local/lib/) add_executable(print_info print_info.cpp) target_link_libraries(print_info avdevice avfilter avformat avcodec swscale swresample postproc avutil # avresample m xcb xcb-shm xcb xcb-shape xcb xcb-xfixes xcb-render xcb-shape xcb asound pthread m fontconfig freetype freetype z bz2 lzma SDL2 SDL2main)
没有帐号?立即注册