ffmpeg开发基础知识

Table of Contents

  1. 基本概念
  2. ffmpeg命令行规则
  3. 开发环境搭建
    1. windows下ffmpeg开发
    2. linux下ffmpeg开发
  4. ffmpeg库的组成
  5. ffmpeg编程特点
  6. 常用数据结构及解释
    1. AVFormatContext:封装格式上下文
      1. 简单说明
      2. 常用的相关函数
    2. AVCodecContext:编解码上下文
      1. 简单说明
      2. 常用的相关函数
    3. AVCodec:编解码器结构体
      1. 简单说明
      2. 常用的关联函数
    4. AVPacket:编码流数据包
      1. 简单说明
      2. 常用的相关函数
    5. AVFrame:原始数据包
      1. 简单说明
      2. 常用的相关函数
    6. SwsContext:像素数据变换上下文
      1. 简单说明
      2. 关联函数
    7. AVFilterContext:滤波上下文
      1. 简单说明
      2. 关联函数
  7. 编程核心流程

基本概念

  • muxing/demuxing是multiplexing/demultiplexing的简称,对应音视频文件处理中的封装/解封装过程,即从文件中获取编码流的过程
  • encoding/decoding是音视频文件处理中的编码/解码过程,即对应原始数据->编码流/编码流->原始数据的过程
  • filter指的是针对音频/视频的一种处理,也被称为滤镜,例如音频去噪即可使用filter来实现,这是针对原始数据的一种处理

ffmpeg命令行规则

ffmpeg作为一个命令行工具,拥有众多的命令参数,但是简而言之,ffmpeg的命令行主要可以划分为5个类别:

ffmpeg {1} {2} -i {3} {4} {5}
1. global options
2. input file options
3. input url
4. output file options
5. output url

ffmpeg \
-y \ # global options
-c:a libfdk_aac -c:v libx264 \ # input options
-i bunny_1080p_60fps.mp4 \ # input url
-c:v libvpx-vp9 -c:a libvorbis \ # output options
bunny_1080p_60fps_vp9.webm # output url

开发环境搭建

windows下ffmpeg开发

  1. 下载ffmpeg dev库和shared库,链接:https://ffmpeg.zeranoe.com/builds/
  2. dev库包含头文件和导入库,shared中的bin目录包含执行最后生成的exe所需的dll

linux下ffmpeg开发

以ubuntu下为例,主要需要使用apt安装libav*-dev和相应的runtime即可,具体名称看下节ffmpeg库的组成

ffmpeg库的组成

模块 功能
libavcodec encoding/decoding libaray
libavfilter graph-based frame editing library
libavformat I/O and muxing/demuxing library
libavdevice special devices muxing/demuxing library
libavutil common utility library
libswresample audio resampling, format conversion and mixing
libpostproc post processing library
libswscale color conversion and scaling library

ffmpeg编程特点

ffmpeg在编程时,主要有以下几大特点:

  1. 输入和输出,编码和解码等结构体类型相同,依靠其内部参数进行区别

  2. 大量使用上下文结构体,所谓上下文指的是:完成一个操作需要使用的工具和环境,对应到ffmpeg编程中可以理解为参数和功能都需要填充到上下文中,依靠统一的上下文操作接口来实现不同操作

  3. 大量使用字符串进行参数的设置,ffmpeg中很多参数可以字符串的形式进行设置,主要提供两种方式:AVDictionary(类似map,键值对形式配置参数)、命令行参数类型(所有参数写成一行,和命令行传参一样)

    例如:在命令行中使用gdirab抓屏时,命令行如下:
    ffmpeg -f gdigrab -framerate 30 -offset_x 10 -offset_y 20 -video_size 640x480 -show_region 1 -i desktop output.mkv
    则在编程中,可以使用如下方式:
      AVDictionary* opt_dict = nullptr;
      av_dict_set( &opt_dict, "framerate", "30", 0 );
      av_dict_set( &opt_dict, "video_size", "640*480", 0 );
      av_dict_set( &opt_dict, "offset_x", "10", 0 );
      av_dict_set( &opt_dict, "offset_y", "20", 0 );
      av_dict_set( &opt_dict, "show_region", "1", 0 );
      AVFormatContext* input_fmt_ctx = avformat_alloc_context();
      // 在这里使用AVDictionary方式进行参数设置
      avformat_open_input( &input_fmt_ctx, "desktop", input_format, &opt_dict );
    
  4. ffmpeg的命令行可以为编程提供助力,例如查看编码器的支持,封装格式的支持,filter的支持等等,查看编解码器的私有参数等

    Print help / information / capabilities:
    -L                  show license
    -h topic            show help
    -? topic            show help
    -help topic         show help
    --help topic        show help
    -version            show version
    -buildconf          show build configuration
    -formats            show available formats
    -muxers             show available muxers
    -demuxers           show available demuxers
    -devices            show available devices
    -codecs             show available codecs
    -decoders           show available decoders
    -encoders           show available encoders
    -bsfs               show available bit stream filters
    -protocols          show available protocols
    -filters            show available filters
    -pix_fmts           show available pixel formats
    -layouts            show standard channel layouts
    -sample_fmts        show available audio sample formats
    -colors             show available color names
    -sources device     list sources of the input device
    -sinks device       list sinks of the output device
    -hwaccels           show available HW acceleration methods
    
    Getting help:
      -h      -- print basic options
      -h long -- print more options
      -h full -- print all options (including all format and codec specific options, very long)
      -h type=name -- print all options for the named decoder/encoder/demuxer/muxer/filter/bsf
      See man ffmpeg for detailed description of the options.
    

常用数据结构及解释

AVFormatContext:封装格式上下文

简单说明

该上下文提供输入输出封装格式的读取和写入的上下文管理,但是一个上下文只提供一种功能,要么是解封装(读取),要么是封装编码数据(写入)

常用的相关函数

函数 功能
avformat_alloc_context 初始化结构体
avformat_free_context 销毁结构体
av_dump_format 打印上下文信息
avformat_open_input 输入上下文专用,用于打开一个文件/设备,若是设备,其值可以参考ffmpeg -devices命令的输出
avformat_find_stream_info 输入上下文专用,初始化上下文中关于打开的文件/设备中的流信息
avformat_alloc_output_context2 输出上下文专用,用于绑定一个输出到上下文中
avformat_new_stream 输出上下文专用,用于在输出上下文中新建一个流
avformat_write_header 输出上下文专用,用于写入一个视频文件头信息
av_write_frame 输出上下文专用,用于写入一个编码数据包
av_write_trailer 输出上下文专用,用于写入一个视频文件尾

AVCodecContext:编解码上下文

简单说明

该上下文提供编码/解码能力的上下文管理,但是同一个上下文只提供一种功能,要么是编码,要么是解码

常用的相关函数

函数 功能
avcodec_alloc_context3 初始化一个编解码上下文
avcodec_free_context 销毁结构体
avcodec_parameters_to_context 将编解码器的参数拷贝至上下文中(一般在解码环节使用)
avcodec_parameters_from_context 从上下文中拷贝编解码器的数据(一般在编码环节使用)
avcodec_send_packet 解码专用,将一个编码流数据包发送至解码器
avcodec_receive_frame 解码专用,从解码器中提取一个解码后的原始数据包
avcodec_send_frame 编码专用,将一个原始数据包发送至编码器
avcodec_receive_packet 编码专用,从编码器中提取一个编码后的数据包

AVCodec:编解码器结构体

简单说明

该结构体用于封装编解码器信息,但是同一个结构体要么是编码器,要么是解码器

常用的关联函数

函数 功能
avcodec_find_encoder 通过AVCodecID获取相应的编码器
avcodec_find_decoder 通过AVCodecID获取相应的解码器
avcodec_find_encoder_by_name 通过字符串名称获取相应的编码器,其字符串值的来源可以参考ffmpeg -encoders命令的输出
avcodec_find_decoder_by_name 通过字符串名称获取相应的解码器,其字符串值的来源可以参考ffmpeg -decoders命令的输出

AVPacket:编码流数据包

简单说明

该结构体包含的是编码过的数据包格式,要想对其进行处理,需要使用其对应的解码器,将其解码为原始数据AVFrame

常用的相关函数

函数 功能
av_packet_alloc 仅初始化一个结构体,但由于此时无法确定其内容大小,所以其结构体内的data项还未分配内存
av_packet_unref 释放其结构体内的数据buffer,并设置结构体内的值为默认值
av_packet_free 释放其结构体内的数据buffer(如果有),并释放结构体

AVFrame:原始数据包

简单说明

该结构体用于封装原始的音视频数据,但是需要注意的是,原始的音视频数据也是具有格式的,其格式为一个类型为AVPixelFormat(视频)/AVSampleFormat(音频)的枚举量

常用的相关函数

函数 功能
av_frame_alloc 仅初始化一个结构体,但由于此时无法确定其内容大小,所以其结构体内的data项还未分配内存
av_frame_unref 释放其结构体内的数据buffer,并设置结构体内的值为默认值
av_frame_free 释放其结构体内的数据buffer(如果有),并释放结构体

SwsContext:像素数据变换上下文

简单说明

该结构体提供一些数据变换的上下文管理,所谓数据变换指的是:图像的拉伸/缩放,图像的像素格式变换等(RGB->YUV)

关联函数

函数 功能
sws_getContext 获取数据变换上下文
sws_freeContext 释放结构体

AVFilterContext:滤波上下文

简单说明

为音频/视频的一次滤波操作提供上下文管理

关联函数

函数 功能
avfilter_graph_alloc_filter 在filter graph中创建一个滤波上下文
avfilter_link 将filter graph中的filter进行连接
av_buffersrc_add_frame 将帧数据送入输入src filter(filter graph的输入端)中
av_buffersink_get_frame 将帧数据从sink filter(filter graph的输出端)中读出

编程核心流程

  1. 初始化输入上下文AVFormatContext,然后绑定一个输入文件/设备/网络流
  2. 从上下文中提取要处理的编码流信息(流的种类可以有:视频流/音频流/字幕流等)
  3. 从编码流中获取该流所用的编码器类型,通过该类型找到相应的解码器
  4. 使用该解码器初始化解码上下文AVCodecContext
  5. 使用输入上下文读出一个AVPacket数据包,然后使用解码上下文进行解码为AVFrame数据包
  6. 此时,视任务类型,可能需要以下操作:转像素格式/缩放/数据处理等等操作,操作可能涉及的库有:libavfilter、libswscale(像素变换和图像拉伸)、libswresample(音频重采样、格式转换和混音)
  7. 假设数据已经处理完毕,需要输出时,则需要使用输出上下文和一个编码上下文(需要在之前就准备好,输出上下文需要绑定输出文件/设备,编码上下文需要先指定编码器并设定编码的参数)
  8. 使用编码上下文将数据进行编码,编码完成后使用输出上下文进行输出
发布了3 篇原创文章 · 获赞 0 · 访问量 297
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 1024 设计师: 上身试试

分享到微信朋友圈

×

扫一扫,手机浏览