前言
本文参考雷霄骅的博文最简单的基于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)
没有帐号?立即注册