最简单的基于FFMPEG的Helloworld程序
初步接触FFMPEG,参考雷大神的文章 https://blog.csdn.net/leixiaohua1020/article/details/46889849,从最简单的开始学起。
从17年到现在ffmpeg的版本变化很多,API很多都已经失效,需要重新在官网中查询相关demo,现将代码整理如下:
ffmpeg版本:4.2.1,开发环境:vs2017
开发环境请参考 https://blog.csdn.net/yao_hou/article/details/80553660
#include "pch.h"
#include <stdio.h>
#include <iostream>
#ifdef _WIN32
extern "C"
{
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libavfilter/avfilter.h"
};
#endif
/**
* FFmpeg类库的配置信息
*/
void configurationinfo()
{
printf("编码器版本号为:%d\n",avcodec_version());
printf("编码器配置信息为:%s\n", avcodec_configuration());
printf("编码器授权标识为:%s\n", avcodec_license());
//strcpy_s(info, 40000, avcodec_configuration());
}
struct URLProtocol;
/**
* FFmpeg类库支持的协议
*/
void urlprotocolinfo()
{
//av_register_all();
struct URLProtocol *pup = NULL;
//Input
struct URLProtocol **p_temp = &pup;
avio_enum_protocols((void **)p_temp, 0);
printf("支持的输入协议为:\n");
while ((*p_temp) != NULL) {
printf(" [In ][%10s]\n", avio_enum_protocols((void **)p_temp, 0));
}
pup = NULL;
//Output
avio_enum_protocols((void **)p_temp, 1);
printf("支持的输出协议为:\n");
while ((*p_temp) != NULL) {
printf(" [Out][%10s]\n", avio_enum_protocols((void **)p_temp, 1));
}
}
/**
* FFmpeg类库支持的封装格式
*/
void avformatinfo()
{
printf("封装器版本为:%d\n", avformat_version());
/*AVInputFormat *if_temp = av_iformat_next(NULL);
AVOutputFormat *of_temp = av_oformat_next(NULL);*/
void *ifmt_opaque = NULL;
void *ofmt_opaque = NULL;
const AVInputFormat *if_temp = NULL;
const AVOutputFormat *of_temp = NULL;
//Iutput
while ((if_temp = av_demuxer_iterate(&ifmt_opaque))) {
printf(" [In ] %10s\n", if_temp->name);
}
//Output
while ((of_temp = av_muxer_iterate(&ofmt_opaque))) {
printf(" [Out ] %10s\n", of_temp->name);
}
}
//static const AVCodec *next_codec_for_id(enum AVCodecID id, const AVCodec *prev, int encoder)
//{
// while ((prev = av_codec_next(prev))) {
// if (prev->id == id &&(encoder ? av_codec_is_encoder(prev) : av_codec_is_decoder(prev)))
// return prev;
// }
// return NULL;
//}
/**
* FFmpeg类库支持的编解码器
*/
void avcodecinfo()
{
/*const AVCodecDescriptor *desc = NULL;
while ((desc=avcodec_descriptor_next(desc))) {
printf("%s\n", desc->name);
}*/
const AVCodec *codec = NULL;
//av_codec_next:官方文档中未被声明为否决
while (codec = av_codec_next(codec)) {
switch (codec->type) {
case AVMEDIA_TYPE_VIDEO:
if (codec->decode != NULL) {
printf("[Dec][VIDEO] %10s\n", codec->name);
}
else {
printf("[Enc][VIDEO] %10s\n", codec->name);
}
break;
case AVMEDIA_TYPE_AUDIO:
if (codec->decode != NULL) {
printf("[Dec][AUDIO] %10s\n", codec->name);
}
else {
printf("[Enc][AUDIO] %10s\n", codec->name);
}
break;
default:
if (codec->decode != NULL) {
printf("[Dec][OTHER] %10s\n", codec->name);
}
else {
printf("[Enc][OTHER] %10s\n", codec->name);
}
break;
}
}
}
/**
* FFmpeg类库支持的滤镜
*/
void avfilterinfo()
{
void *opaque = NULL;
const AVFilter *filter = NULL;
while (filter = av_filter_iterate(&opaque)) {
if (filter->inputs != NULL) {
printf("[In]%s\n", filter->name);
}
else {
printf("[Out]%s\n", filter->name);
}
filter->next;
}
}
int main()
{
configurationinfo();
urlprotocolinfo();
avformatinfo();
avcodecinfo();
avfilterinfo();
return 0;
}
关于函数av_codec_next:虽然在代码中被声明为已否决,但官方文档及相关demo中还是继续使用,暂时没有找到可以替代的函数。所以改项目中需要将VS的SDL检查关闭,具体可参考https://www.cnblogs.com/lgh1992314/p/5834634.html