FFmpeg学习:视频重采样

视频重采样

视频重采样参数

1.图像色彩空间转换;
2.分辨率缩放;
3.前后图像滤波处理

图像宽高、像素格式、尺寸转换算法

视频像素和尺寸转换api

【第一】创建格式转换上下文
SwsContext* video_swscontext = NULL;
【第二】格式变换上下文初始化

【函数原型】

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

【flags缩放算法】

点击查看代码
/* values for the flags, the stuff on the command line is different */
#define SWS_FAST_BILINEAR     1
#define SWS_BILINEAR          2
#define SWS_BICUBIC           4
#define SWS_X                 8
#define SWS_POINT          0x10
#define SWS_AREA           0x20
#define SWS_BICUBLIN       0x40
#define SWS_GAUSS          0x80
#define SWS_SINC          0x100
#define SWS_LANCZOS       0x200
#define SWS_SPLINE        0x400

#define SWS_SRC_V_CHR_DROP_MASK     0x30000
#define SWS_SRC_V_CHR_DROP_SHIFT    16

#define SWS_PARAM_DEFAULT           123456

#define SWS_PRINT_INFO              0x1000

//the following 3 flags are not completely implemented
//internal chrominance subsampling info
#define SWS_FULL_CHR_H_INT    0x2000
//input subsampling info
#define SWS_FULL_CHR_H_INP    0x4000
#define SWS_DIRECT_BGR        0x8000
#define SWS_ACCURATE_RND      0x40000
#define SWS_BITEXACT          0x80000
#define SWS_ERROR_DIFFUSION  0x800000

#define SWS_MAX_REDUCE_CUTOFF 0.002

#define SWS_CS_ITU709         1
#define SWS_CS_FCC            4
#define SWS_CS_ITU601         5
#define SWS_CS_ITU624         5
#define SWS_CS_SMPTE170M      5
#define SWS_CS_SMPTE240M      7
#define SWS_CS_DEFAULT        5
#define SWS_CS_BT2020         9
【第三】格式转换函数 sws_scale

【函数原型】

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[]);

【参数分析】

  • const uint8_t *const srcSlice[];原数据存放的地址,一个数组至于取几个要看前面像素格式决定的,如果是YUV平面格式的就要取3位分别对应YUV,如果是RGB打包格式的那么就只取一位。
  • const int srcStride[], 一行字节数的大小,就是之前frame里面的linesize。
  • int srcSliceY 定义在输入图像上处理区域,srcSliceY是起始位置,
  • int srcSliceH srcSliceH是处理多少行。如果srcSliceY=0,srcSliceH=height,表示一次性处理完整个图像
  • uint8_t *const dst[];转换后的目的数据存放的空间,是一个指针数组,因此要提前分配空间,
  • const int dstStride[] 输出的一行的大小
【第四】释放上下文
void sws_freeContext(struct SwsContext *swsContext);
使用举例
	//像素格式和尺寸转换上下文
	SwsContext *vctx = NULL;
	unsigned char *rgb = NULL;
//在解码后得到解码帧后进行转换的,注意内存的申请和格式转换
	//视频
	if (cc == vc)
	{
		vctx = sws_getCachedContext(
			vctx,	//传NULL会新创建
			frame->width, frame->height,		//输入的宽高
			(AVPixelFormat)frame->format,	//输入格式 YUV420p
			frame->width, frame->height,	//输出的宽高
			AV_PIX_FMT_RGBA,				//输入格式RGBA
			SWS_BILINEAR,					//尺寸变化的算法
			0, 0, 0);
		//if(vctx)
		//cout << "像素格式尺寸转换上下文创建或者获取成功!" << endl;
		//else
		//	cout << "像素格式尺寸转换上下文创建或者获取失败!" << endl;
		if (vctx)
		{
			//申请转换后数据存放的内存
			if (!rgb) rgb = new unsigned char[frame->width*frame->height * 4];
			//转换为对应存放格式,因为是要转换为打包的RGBA格式因此只需要一维,如果是YUV420P的则需要三维都需要内存地址的,否则会奔溃
			uint8_t *data[2] = { 0 };
			data[0] = rgb;
			int lines[2] = { 0 };
			lines[0] = frame->width * 4;//存放一行数据大小,
			re = sws_scale(vctx,
				frame->data,		//输入数据
				frame->linesize,	//输入行大小
				0,
				frame->height,		//输入高度
				data,				//输出数据和大小
				lines				//一行的大小
			);
			cout << "sws_scale = " << re << endl;
		}
	}

参考

封装格式api
FFmpeg-2、编解码及视频像素格式尺寸转换和音频重采样

posted @ 2022-07-30 13:49  小超不挑食  阅读(402)  评论(0编辑  收藏  举报