1. 缓冲是什么?缓冲区是什么?(超级重要)
缓冲:
是冲击的力度减弱。
缓冲区(buffer)
,它是内存空间的一部分。也就是说,在内存空间中预留了一定的存储空间,这些存储空间用来缓冲输入或输出的数据
,这部分预留的空间就叫做缓冲区,显然缓冲区是具有一定大小的。
2. 为什么要引入缓冲区?缓冲区的具体 2 个作用?(超级重要)
为什么要引入缓冲区:
高速设备与低速设备的不匹配,势必会让高速设备花时间等待低速设备,我们可以在这两者之间设立一个缓冲区
。
缓冲区作用①:
可以解除两者的制约关系,数据可以直接送往缓冲区,高速设备不用再等待低速设备。(比如打印机打印文档)
缓冲区作用②:
可以减少数据的读写次数,保护磁盘的寿命。(比如 IO 操作)
3. 编程中的 Context(上下文)是什么含义?
上下文
这个东西不是一个具体的东西,上下文
在不同的地方表示不同的含义,要感性理解。- context 其实说白了,和
文章的上下文
是一个意思,再通俗一点,我觉得叫环境更好。
.... 林冲大叫一声“啊也!” ....
问:这句话林冲的“啊也”表达了林冲怎样的心里?
答:啊你妈个头啊!
- 看一篇文章,给你摘录一段,没前没后,你读不懂,因为有语境,就是语言环境存在,一段话说了什么,要通过
上下文
来判断。 - 子程序之于程序,进程之于操作系统,甚至app的一屏之于app,都是一个道理。
- app点击一个按钮进入一个新的界面,也要保存你是在哪个屏幕跳过来的等等信息,以便你点击返回的时候能正确跳回,如果不存肯定就无法正确跳回了。(这就是上下文的经典例子)
4. 图片的像素格式转换关键代码如下(转换一帧)
思路
创建上下文 → 将数据加载到输入缓冲区 → sws_scale()转换数据 → 将数据装载到输出缓冲区
typedef struct {
char *pixels;
int width;
int height;
AVPixelFormat format;
} RawVideoFrame;
void FFmpegs::convertRawVideo(RawVideoFrame &in,
RawVideoFrame &out) {
// 上下文
SwsContext *ctx = nullptr;
// 输入、输出缓冲区(指向每一个平面的数据)
uint8_t *inData[4], *outData[4];
// 每个平面的大小
int inStrides[4], outStrides[4];
// 每一帧图片的大小
int inFrameSize, outFrameSize;
// 返回结果
int ret = 0;
// 创建上下文
ctx = sws_getContext(in.width, in.height, in.format,
out.width, out.height, out.format,
SWS_BILINEAR, nullptr, nullptr, nullptr);
if (!ctx) {
qDebug() << "sws_getContext error";
goto end;
}
// 输入缓冲区
ret = av_image_alloc(inData, inStrides, in.width, in.height, in.format, 1);
END(av_image_alloc)
// 输出缓冲区
ret = av_image_alloc(outData, outStrides, out.width, out.height, out.format, 1);
// 计算每一帧图片的大小
inFrameSize = av_image_get_buffer_size(in.format, in.width, in.height, 1);
outFrameSize = av_image_get_buffer_size(out.format, out.width, out.height, 1);
// 拷贝输入数据
memcpy(inData[0], in.pixels, inFrameSize);
// 转换
sws_scale(ctx, inData, inStrides, 0, in.height, outData, outStrides);
// 写到输出文件中去
out.pixels = (char*) malloc(outFrameSize);
memcpy(out.pixels, outData[0], outFrameSize);
end:
av_freep(&inData[0]);
av_freep(&outData[0]);
sws_freeContext(ctx);
}