• ffmpeg 学习:001-搭建开发环境


    介绍

    由于命令行的ffmpeg工具无法满足产品的性能要求,需要对视频流进行兼容。所以需要调试有关的参数。
    FFmpeg全名是Fast Forward MPEG(Moving Picture Experts Group)是一个集成了各种编解码器的库,可以说是一个全能型的工具,从视频采集、视频编码到视频传输(包括RTP、RTCP、RTMP、RTSP等等协议)都可以直接使用FFMPEG来完成,更重要的一点FFMPEG是跨平台的,Windows、Linux、Aandroid、IOS这些主流系统通吃。因此初期强烈建议直接使用FFMPEG。

    编译有关的库:

    Linux版本的可以根据源码进行编译,可以参考本人的编译博文:

    Ubuntu 移植 ffmpeg + x264
    arm linux 移植 FFMPEG库 + x264
    注:为了兼顾 arm 与 host ,本人选择了同时都支持的 ffmpegv.4.0.1。此后的学习都以此为版本。

    Windows MacOS 版本 可以在官网进行下载Dev版本的:
    ffmpeg bulid分为3个版本:Static,Shared,Dev。前两个版本可以直接在命令行中使用,他们的区别在于:

    Static(静态库版本): 里面只有3个应用程序:ffmpeg.exe,ffplay.exe,ffprobe.exe,相关的Dll已经被编译到exe里面去了。作为工具而言此版本就可以满足我们的需求;
    Shared(动态库版本):里面除了3个应用程序:ffmpeg.exe,ffplay.exe,ffprobe.exe之外,还有一些Dll,比如说avcodec-54.dll之类的。Shared里面的exe在运行的时候,需要到相应的Dll调用功能。程序运行过程必须依赖于提供的dll文件;
    Dev(开发者版本):是用于开发的,里面包含了库文件xxx.lib以及头文件xxx.h,这个版本不包含exe文件。dev版本中include文件夹内文件用途

    备注:应用程序在开发期间需要用到dev版本下的lib库,应用程序编译后执行期间需要shared中的dll库文件的支持

    新建工程

    Linux版本的工程(在此后的文章中,本人都在Linux环境下进行开发)
    无论是x86还是arm,一般都用makefile 进行工程的管理。
    下面提供一个通用的makefile模板:(注意tab字符)

    #           Makefile edited by Schips
    #           2019-06-21 schips@dingtalk.com
    
    # 文件类型
    PSFS            =.cpp
    
    # 源文件所在目录
    SRC_LIST    = .
    # 头文件所在目录
    INCLUDE         = include
    
    # 编译选项
    CFLAGS      = -g -Wall
    CC          = g++
    CXX         = g++
    
    
    # 库路径
    LDLIBS      = ./lib
    
    # 库名
    LIBS        = avutil avcodec avdevice avfilter swscale swresample avformat  x264 postproc
    
    # 调试用
    INSIGHT     = gdb
    
    # 输出文件名
    TGT         = demo
    OTHER_CSRC  =
    OTHER_ASRC  =
    ASRC        =
    
    ########################################
    # 不需要改动
    INC_P  = -I
    LIBD_P = -L
    LIB_P  = -l
    CFLAGS      += $(addprefix $(INC_P), $(INCLUDE))
    LDFLAGS     += $(addprefix $(LIBD_P), $(LDLIBS))
    LIB_ALL     += $(addprefix $(LIB_P), $(LIBS))
    SRC_LIST    ?= .
    SRCSS       += $(addsuffix /*$(PSFS), $(SRC_LIST))
    CSRC        += $(wildcard  $(SRCSS))
    
    OBJS        = $(CSRC:$(PSFS)=.o) $(ASRC:.S=.o)
    NOLINK_OBJS = $(OTHER_CSRC:$(PSFS)=.o) $(OTHER_ASRC:.S=.o)
    DEPS        = $(OBJS:.o=.d) $(NOLINK_OBJS:.o=.d)
    BIN         = $(TGT)
    
    .PHONY: clean all
    
    all: $(BIN)
    
    debug:
            $(INSIGHT) --se=$(TGT)
    
    $(BIN): $(OBJS) $(NOLINK_OBJS)
            $(CC) $(LDFLAGS) $(OBJS) $(LIB_ALL) -o $@
    
    clean:
            rm -f $(DEPS)
            rm -f $(OBJS) $(NOLINK_OBJS)
            rm -f $(BIN)
    
    # ---------------------------------------------------------------------------
    # rules for code generation
    # ---------------------------------------------------------------------------
    %.o:    %$(PSFS)
            $(CC) $(CFLAGS) -o $@ -c $<
    
    %.o:    %.S
            $(CC) $(ASFLAGS) -o $@ -c $<
    
    # ---------------------------------------------------------------------------
    #  # compiler generated dependencies
    # ---------------------------------------------------------------------------
    -include $(LWOS_DEPS) $(PORT_DEPS) $(APPL_DEPS)
    
    
    

    Windows 搭建ffmpeg工程的方法比较常见,请各位自行寻找,也可以追随先驱雷神的脚步,

    cpp 代码

    为了高效又快速开发,我们这里使用了雷神的被整理好的代码库作为搭建环境的测试。
    最简单的ffmpeg代码:simplest_ffmpeg_helloworld

    /**
     * 最简单的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]
    ", 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]
    ", 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
    ", info, if_temp->name);
    		if_temp=if_temp->next;
    	}
    	//Output
    	while (of_temp != NULL){
    		sprintf(info, "%s[Out] %10s
    ", 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
    ", 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]
    ", 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
    ", avcodec_configuration());
    
    	return info;
    }
    
    int main(int argc, char* argv[])
    {
    	char *infostr=NULL;
    	infostr=configurationinfo();
    	printf("
    <<Configuration>>
    %s",infostr);
    	free(infostr);
    
    	infostr=urlprotocolinfo();
    	printf("
    <<URLProtocol>>
    %s",infostr);
    	free(infostr);
    
    	infostr=avformatinfo();
    	printf("
    <<AVFormat>>
    %s",infostr);
    	free(infostr);
    
    	infostr=avcodecinfo();
    	printf("
    <<AVCodec>>
    %s",infostr);
    	free(infostr);
    
    	infostr=avfilterinfo();
    	printf("
    <<AVFilter>>
    %s",infostr);
    	free(infostr);
    
    	return 0;
    }
    
    

    测试

    准备好上文的Makefile以及cpp文件,直接输入make,执行生成的文件即可。

    $ ./demo
    
    <<Configuration>>
    --target-os=linux --prefix=/home/schips/ffmpeg/install/ffmpeg --enable-shared --enable-static --enable-gpl --enable-nonfree --enable-ffmpeg --disable-ffplay --enable-ffserver --enable-swscale --enable-pthreads --disable-armv5te --disable-armv6 --disable-armv6t2 --disable-yasm --disable-stripping --enable-libx264 --extra-cflags=-I/home/schips/ffmpeg/install/x264/include --extra-ldflags=-L/home/schips/ffmpeg/install/x264/lib
    
    <<URLProtocol>>
    [In ][     cache]
    [In ][    concat]
    [In ][    crypto]
    [In ][      data]
    [In ][ffrtmphttp]
    ...
    [      showwaves]
    [   showwavespic]
    [  spectrumsynth]
    [         amovie]
    [          movie]
    [        abuffer]
    [         buffer]
    [    abuffersink]
    [     buffersink]
    [          afifo]
    [           fifo]
    
    
  • 相关阅读:
    想更改Github仓库中的某个文件结构
    记git一些基本用法
    剑指Offer-Python(16-20)
    剑指Offer-Python(11-15)
    初次使用flask
    Python的Cmd模块的简易运用学习
    SQL-全称量词查询
    线段树模板1
    OJ输入输出超时(C++)
    二叉查找树(BST)定义
  • 原文地址:https://www.cnblogs.com/schips/p/12193376.html
Copyright © 2020-2023  润新知