使用ffmpeg sws_scale NV12转YUV420P,自己创建linesize和地址参数
作者 | 将狼才鲸 |
---|---|
创建日期 | 2022-04-03 |
-
ffmpeg4.3.1版本
-
因为在网上没找到教怎么自己生成sws_scale()函数参数的,我也是摸索了好几个钟头才弄清楚,所以,特写此文章。
我的整个工程Gitee源码目录:qt_gui_simple2complex/ source / 007_Embeded_Player
- 代码展示:
#include "libswscale/swscale.h" // NV12转YUV420
#define MDATA_LEN (2 * 1024 * 1024) // for 1280 * 720 max
static unsigned char mdata[MDATA_LEN]; // NV12原始的一帧数据
static unsigned char yuv420_mdata[MDATA_LEN];
static int ySize = 0; // 宽乘以高
static int width = 1280;
static int height = 720;
static struct SwsContext *m_pSwsCtx = NULL;// NV12转YUV420P
int nv12_to_yuv420p()
{
int ret;
ySize = width * height;
// 注册NV12转YUV420P的句柄,当前编码器只支持YUV420P输入
m_pSwsCtx = sws_getContext(width,
height,
AV_PIX_FMT_NV12,
width,
height,
AV_PIX_FMT_YUV420P, SWS_FAST_BILINEAR, NULL, NULL, NULL);
char *indata = mdata;
char *outdata = yuv420_mdata;
/* NV12转YUV420 */
//[使用ffmpeg编码原始nv12帧](http://cn.voidcc.com/question/p-rajvdmfe-dw.html)
//[全网首发:FFMpeg使用NVIDIA DECODER,解码后的数据是NV12,不是YUV420P](https://blog.51cto.com/u_13161667/3306044)
int nv12_linesize[3];
int yuv420_linesize[3];
yuv420_linesize[0] = width; // YUV各个分量的长度
yuv420_linesize[1] = width / 2;
yuv420_linesize[2] = width / 2;
nv12_linesize[0] = width;
nv12_linesize[1] = width;
nv12_linesize[2] = 0;
unsigned char *inaddr[3] = {indata, indata + ySize, 0};
unsigned char *outaddr[3] = {outdata, outdata + ySize, outdata + ySize + ySize / 4};
do {
ret = sws_scale(m_pSwsCtx, inaddr, nv12_linesize, 0, pCodecCtx->height,
outaddr, yuv420_linesize);
// 转换完的数据在outdata中
// 函数如果返回720则说明转换成功,如果返回0则说明函数内部处理出错
} while (0); // 可以修改为循环处理多帧
// 释放内存
sws_freeContext(m_pSwsCtx);
return 0;
}