FFmpeg学习:常用api——封装格式相关

封装格式相关

av_find_input_format

av_find_input_format函数是通过av_demuxer_iterate函数遍历所有解封装格式列表和音视频输入设备列表,然后通过av_match_name函数判断name是否等于short_name,来返回AVInputFormat结构的

/**
 * Find AVInputFormat based on the short name of the input format.
 * 根据输入格式的短名称查找AVInputFormat。
 */
ff_const59 AVInputFormat *av_find_input_format(const char *short_name)

avformat_open_input()

用于打开输入媒体流与读取头部信息,包括本地文件、网络流、自定义缓冲区

//原型如下:
avformat_open_input(AVFormatContext **ps, const char *url, ff_const59 AVInputFormat *fmt, AVDictionary **options):媒体打开函数
ps:函数调用成功之后处理过的AVFormatContext结构体。
file:打开的视音频流的URL。
fmt:强制指定AVFormatContext中AVInputFormat的。这个参数一般情况下可以设置为NULL,这样FFmpeg可以自动检测AVInputFormat。
dictionay:附加的一些选项,一般情况下可以设置为NULL。

函数执行成功的话,其返回值大于等于0。

指定参数(打开设备初始化参数,如摄像头)

参考初始化

可用配置参数

libavformat/options_table.h,其中包含了它支持的参数设置。
常用配置参数

  • rtbufsize:设置用于缓冲实时帧的最大内存,例如
  • pixel_format:原像素数据的采集格式,可选值
  • avioflags:可能值:{"direct"}减少缓冲
  • video_size:视频采集分辨率,可选值
  • framerate:帧率,可选值举例
  • start_time_realtime:直播减少延时的,但是测试没啥效果,可选值举例
  • vcodec:指定采用编码器,可选值举例
  • rtsp_transport:推流时传输协议,可选值举例
  • max_delay:最大延迟,可选值{"5000000"},单位微妙
  • muxdelay:单位 秒

//实时播放使用udp,减小带宽并防止断线
av_dict_set(&options, "rtsp_transport", "udp", 0);
//等待3秒超时
av_dict_set(&options, "listen_timeout", "3", 0);

配置参数的使用方法
AVInputFormat* ifmt = av_find_input_format("dshow");
AVDictionary* options = NULL;
av_dict_set(&options, "pixel_format", "yuyv422", 0);//指定像素格式
av_dict_set(&options, "avioflags", "direct", 0);//指定
av_dict_set(&options, "video_size", "320x180", 0);
av_dict_set(&options, "framerate", "30", 0);
av_dict_set(&options, "vcodec", "mjpeg", 0);
avformat_open_input(&pFormatCtx, "video=Integrated Camera", ifmt, &options);

sws_scale库

可以在一个函数里面同时实现:1.图像色彩空间转换;2.分辨率缩放;3.前后图像滤波处理。核心函数有三个

【第一】初始化sws_scale

struct SwsContext *sws_getContext(int srcW, int srcH, enum AVPixelFormat srcFormat,
                                  int dstW, int dstH, enum AVPixelFormat dstFormat,
                                  int flags,
                                  SwsFilter *srcFilter, SwsFilter *dstFilter, const double *param);

参数含义如下:

  • int srcW, int srcH, enum AVPixelFormat srcFormat定义输入图像信息(寬、高、颜色空间(像素格式))
  • int dstW, int dstH, enum AVPixelFormat dstFormat定义输出图像信息寬、高、颜色空间(像素格式))。
  • int flags选择缩放算法(只有当输入输出图像大小不同时有效)
  • SwsFilter *srcFilter, SwsFilter *dstFilter分别定义输入/输出图像滤波器信息,如果不做前后图像滤波,输入NULL
  • const double *param定义特定缩放算法需要的参数(?),默认为NULL

函数返回SwsContext结构体,定义了基本变换信息。如果是对一个序列的所有帧做相同的处理,函数sws_getContext只需要调用一次就可以了

【第二】变换函数

int sws_scale(struct SwsContext *c,
              const uint8_t *const srcSlice[], const int srcStride[],
              int srcSliceY, int srcSliceH,
              uint8_t *const dst[], const int dstStride[]);

参数含义:

  • struct SwsContext *c,为上面sws_getContext函数返回值;
  • const uint8_t *const srcSlice[], const int srcStride[]定义输入图像信息(当前处理区域的每个通道数据指针,每个通道行字节数)
  • int srcSliceY, int srcSliceH,定义在输入图像上处理区域,srcSliceY是起始位置,srcSliceH是处理多少行。如果srcSliceY=0,srcSliceH=height,表示一次性处理完整个图像

stride定义下一行的起始位置。stride和width不一定相同,这是因为:
1.由于数据帧存储的对齐,有可能会向每行后面增加一些填充字节这样 stride = width + N;
2.packet色彩空间下,每个像素几个通道数据混合在一起,例如RGB24,每个像素3字节连续存放,因此下一行的位置需要跳过3*width字节。
srcSlice和srcStride的维数相同,由srcFormat值来。
csp 维数 宽width 跨度stride 高
YUV420 3 w, w/2, w/2 s, s/2, s/2 h, h/2, h/2
YUYV 1 w, w/2, w/2 2s, 0, 0 h, h, h
NV12 2 w, w/2, w/2 s, s, 0 h, h/2
RGB24 1 w, w, w 3s, 0, 0 h, 0, 0

【第三】释放sws_scale

void sws_freeContext(struct SwsContext *swsContext);
posted @ 2022-07-18 19:38  小超不挑食  阅读(595)  评论(0编辑  收藏  举报