这里弄过简单的例子,来说明下尺寸变换是如何实现的。
比如,现在有个1920x1080的图片,要将其修改为960x1080的,怎么办了。
我们先看第一行,一共1920个像素点,此时需要转换为960个像素点,每个像素点有r,g,b三元素,则我们可以将原图中的第一个像素点和第二个像素点的r,g,b分别相加,然后除以2,就类似得到输出图中的第一个元素的r,g,b。
同理将原图中的第三个像素点和第四个像素点的r,g,b分别相加,然后除以2,就类似得到输出图中的第二个元素的r,g,b。
ffmpeg中像素的存储格式是yuv,可以仿照r,g,b进行处理。
下面列举下例子,本地有个1920x1080的视频文件,现在需要读取该视频文件,并且修改尺寸为960x1080。
工程结构如下所示,注意,这里的命名不严谨,Crop应该为Scale。

下面的代码展示了核心逻辑,其中pFrameVideoA为原视频文件对应的帧,pFrame_out为输出视频对应的帧。
///此处进行视频剪辑处理
uint8_t *dataY = pFrameVideoA->data[0];
uint8_t *dataU = pFrameVideoA->data[1];
uint8_t *dataV = pFrameVideoA->data[2];
for (int i = 0; i < iOriginalYSize; i += 2)
{
dataCropY[i / 2] = (dataY[i] + dataY[i + 1]) / 2;
}
for (int i = 0; i < iOriginalUSize; i += 2)
{
dataCropU[i / 2] = (dataU[i] + dataU[i + 1]) / 2;
}
for (int i = 0; i < iOriginalVSize; i += 2)
{
dataCropV[i / 2] = (dataV[i] + dataV[i + 1]) / 2;
}
memcpy(pFrame_out->data[0], dataCropY, iOriginalYSize / 2);
memcpy(pFrame_out->data[1], dataCropU, iOriginalUSize / 2);
memcpy(pFrame_out->data[2], dataCropV, iOriginalVSize / 2);
FfmpegMyCropTest.cpp的内容如下:
#include <iostream>
#include "CropFile.h"
#ifdef __cplusplus
extern "C"
{
#endif
#pragma comment(lib, "avcodec.lib")
#pragma comment(lib, "avformat.lib")
#pragma comment(lib, "avutil.lib")
#pragma comment(lib, "avdevice.lib")
#pragma comment(lib, "avfilter.lib")
#pragma comment(lib, "postproc.lib")
#pragma comment(lib, "swresample.lib")
#pragma comment(lib, "swscale.lib")
#ifdef __cplusplus
};
#endif
int main()
{
CCropFile cVideoCopy;
const char *pFileA = "E:\\learn\\ffmpeg\\FfmpegFilterTest\\x64\\Release\\in-vs.mp4";
const char *pFileOut = "E:\\learn\\ffmpeg\\FfmpegFilterTest\\x64\\Release\\out-mycrop.mp4";
cVideoCopy.StartMyCrop(pFileA, pFileOut);
cVideoCopy.WaitFinish();
return 0;
}
CropFile.h的内容如下:
#pragma once
#include <Windows.h>
#ifdef __cplusplus
extern "C"
{
#endif
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libswscale/swscale.h"
#include "libswresample/swresample.h"
#include "libavdevice/avdevice.h"
#include "libavutil/audio_fifo.h"
#include "libavutil/avutil.h"
#include "libavutil/fifo.h"
#include "libavutil/frame.h"
#include "libavutil/imgutils.h"
#include "libavfilter/avfilter.h"
#include "libavfilter/buffersink.h"
#include "libavfilter/buffersrc.h"
#ifdef __cplusplus
};
#endif
class CCropFile
{
public:
CCropFile();
~CCropFile();
public:
int StartMyCrop(const char *pFileA, const char *pFileOut);
int WaitFinish();
private:
int OpenFileA(const char *pFileA);
int OpenOutPut(const char *pFileOut);
int InitFilter(const char* filter_desc);
private:
static DWORD WINAPI VideoAReadProc(LPVOID lpParam);
void VideoARead<

最低0.47元/天 解锁文章
7214

被折叠的 条评论
为什么被折叠?



