C++版本的基于FFMPEG的Helloworld程序
? c++ ? ? ffmpeg ? ? hello ?   发布于 2019-01-23   1995人围观  0条评论
? c++ ? ? ffmpeg ? ? hello ?   发表于 2019-01-23   1995人围观  0条评论

前言

本文参考雷霄骅的博文最简单的基于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)

 

上一篇:

下一篇: linux多线程服务端编程第六章-muduo网络库简介 读后感

立即登录,发表评论
没有帐号?立即注册
0 条评论