- By刘立博
- 2021-01-10 23:07:41
- 2749人已阅读
程序流程设计
函数简介
获取转换上下文 sws_getCachedContext()
struct SwsContext *context :如果传入的上下文为NULL,则会创建上下文。如果不为NULL则会查找缓存中的上下文,若存在则返回指针,若不存在则会创建一个新的上下文。
int srcW : 输入视频宽度
int srcH : 输入视频高度
enum AVPixelFormat srcFormat : 输入视频像素格式
int dstW : 输出视频宽度
int dstH : 输出视频高度
enum AVPixelFormat dstFormat : 输出视频像素格式
int flags : 转换算法
SwsFilter *srcFilter : 输入视频过滤器
SwsFilter *dstFilter : 输出视频过滤器
const double *param : 配置项
转换图像像素和尺寸 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[] : 输出图像每行字节数
YUV与RGBA互转
读取YUV文件test.yuv将其转换为1280X720的RGBA文件testOut.rgba
再读取testOut.rgba将其转换为1280X720的YUV文件testOut.yuv
#include <iostream>
#include <fstream>
using namespace std;
extern "C" {
#include <libswscale/swscale.h>
}
#pragma comment(lib,"swscale.lib")
int main(int argc, char* argv[])
{
int srcWidth = 1280;
int srcHeight = 720;
int desWidth = 1280;
int desHeight = 720;
unsigned char* yuvData[3] = { 0 };
int yuvLineSize[3] = { srcWidth,srcWidth / 2,srcWidth / 2 };
yuvData[0] = new unsigned char[srcWidth * srcHeight];
yuvData[1] = new unsigned char[srcWidth * srcHeight/4];
yuvData[2] = new unsigned char[srcWidth * srcHeight/4];
unsigned char* rgbaData = new unsigned char[desWidth * desHeight * 4];
int rgbaLineSize = desWidth * 4;
ifstream ifs;
ifs.open("test.yuv", ios::binary);
ofstream ofs;
ofs.open("testOut.rgba",ios::binary);
SwsContext* yuv2Rgba = nullptr;
for (;;)
{
//读取YUV
ifs.read((char*)yuvData[0], srcWidth * srcHeight);
ifs.read((char*)yuvData[1], srcWidth * srcHeight/4);
ifs.read((char*)yuvData[2], srcWidth * srcHeight/4);
if (ifs.gcount() == 0) break;
//获取上下文
yuv2Rgba = sws_getCachedContext(
yuv2Rgba,
srcWidth,srcHeight,AV_PIX_FMT_YUV420P,
desWidth,desHeight,AV_PIX_FMT_RGBA,
SWS_BILINEAR,
0,0,0
);
unsigned char* desData[1];
desData[0] = rgbaData;
int desLineSize[1] = { rgbaLineSize };
//YUV转RGBA
int r = sws_scale(
yuv2Rgba,
yuvData,
yuvLineSize,
0,
desHeight,
desData,
desLineSize
);
//写入文件
ofs.write((char*)rgbaData, desWidth * desHeight * 4);
cout << r << endl;
}
cout << "rgba 2 yuv" << endl;
ofs.close();
ifs.close();
ifs.open("testOut.rgba", ios::binary);
ofs.open("testOut.yuv", ios::binary);
SwsContext* rgba2yuv = nullptr;
for (;;)
{
//读取RGBA文件
ifs.read((char*)rgbaData, desWidth * desHeight * 4);
if (ifs.gcount() == 0) break;
//获取上下文
rgba2yuv = sws_getCachedContext(
rgba2yuv,
desWidth,desHeight,
AV_PIX_FMT_RGBA,
srcWidth,srcHeight,
AV_PIX_FMT_YUV420P,
SWS_BILINEAR,
0,0,0
);
unsigned char* data[1];
data[0] = rgbaData;
int srcLineSize[1] = { rgbaLineSize };
//RGBA转YUV
int r = sws_scale(
rgba2yuv,
data,
srcLineSize,
0,
desHeight,
yuvData,
yuvLineSize
);
//写入YUV文件
ofs.write((char*)rgbaData, desWidth * desHeight * 2);
cout << r << endl;
}
delete yuvData[0];
delete yuvData[1];
delete yuvData[2];
delete rgbaData;
ofs.close();
ifs.close();
return 0;
}