Introduction to video and audio data processing: color space -- ffmpeg

summary

This article briefly describes the color space conversion of libswscale based on FFmpeg; Libswscale realizes the conversion of various image pixel formats, such as the conversion between YUV and RGB; Here is a brief introduction to the use of libswscale's color space conversion.

technological process

Related processes

Libswscale is very convenient to use. There are only three main functions:
(1) sws_getContext(): initialize the SwsContext structure with parameters.
(2) sws_scale(): convert one frame of image.
(3) sws_freeContext(): release the SwsContext structure.
Where sws_getContext() can also use another interface function SWS_ Replaced by getcachedcontext().

Initialization method

Initialize SwsContext. We choose SWS here_ getContext(); In addition to the above functions, there is another method, which is more flexible and can configure more parameters. The functions called by this method are as follows:
1)  sws_alloc_context(): allocate memory for SwsContext structure.
2)  av_opt_set_XXX(): via av_opt_set_int(),av_opt_set()... And a series of methods to set the value of SwsContext structure. It should be noted here that the definition of SwsContext structure cannot be seen, so the member variables cannot be assigned directly, and must be assigned through AV_ opt_ An API such as set () can assign values to it.
3)  sws_init_context(): initializes the SwsContext structure.
Compared with the first method, this complex method can configure some sws_getContext() cannot configure parameters. For example, set whether the value range of YUV pixels of the image is JPEG standard (the value range of Y, U and V is 0-255) or MPEG standard (the value range of Y is 16-235, and the value range of U and V is 16-240).

setup code

m_imgConvertCtx = sws_getContext(cfg->srcWide, cfg->srcHigh, srcIter->second,
		cfg->dstWide, cfg->dstHigh, dstIter->second, SWS_BICUBIC, NULL, NULL, NULL);

Conversion method

There is no special description for the conversion function. Call sws_scale(); It is worth noting that the parameters of this function need to be arranged according to the corresponding color space;

Conversion code

sws_scale(m_imgConvertCtx, m_srcPointers, m_srcLinesizes, 0, m_srcHigh, m_dstPointers, m_dstLinesizes);

Release method

	if (nullptr != m_imgConvertCtx)
	{
		sws_freeContext(m_imgConvertCtx);
	}

	m_imgConvertCtx = nullptr;

Overall code introduction

The demo corresponding to FFmpeg color space conversion is encapsulated into a class function, which mainly provides the mutual conversion functions of NV12, NV21, YUV420P, YUV422P, RGB24 and RGBA. If you need to expand, you can implement the corresponding function.

Header file: colorconversionffmpeg h

/**
 * FFmpeg Color space conversion
 * YUV Transformation
 *
 * Liang Qidong liang
 * 18088708700@163.com
 * https://blog.csdn.net/u011645307
 *
 *
 * This program realizes the conversion between YUV data of FFmpeg and the conversion between YUV and RGB.
 * The following are provided:
 * 	FFMPEG_AV_PIX_FMT_NOKNOW,
 *	FFMPEG_AV_PIX_FMT_NV12,
 *	FFMPEG_AV_PIX_FMT_NV21,
 *	FFMPEG_AV_PIX_FMT_YUV420P,
 *	FFMPEG_AV_PIX_FMT_YUV422P,
 *	FFMPEG_AV_PIX_FMT_RGB24,
 *	FFMPEG_AV_PIX_FMT_RGBA
 *  Mutual conversion function
 */
#ifndef COLOR_CONVERSION_FFMPEG_H
#define	COLOR_CONVERSION_FFMPEG_H

#ifdef _WIN32
//Windows
extern "C"
{
#include "libswscale/swscale.h"
#include "libavutil/opt.h"
#include "libavutil/imgutils.h"
};
#else
//Linux...
#ifdef __cplusplus
extern "C"
{
#endif
#include <libavutil/opt.h>
#include <libswscale/swscale.h>
#include <libavutil/imgutils.h>
#ifdef __cplusplus
};
#endif
#endif

#include <map>
#include <functional>

#ifndef FFMPEG_PIX_FORMAT
#define	FFMPEG_PIX_FORMAT
typedef enum FFmpegAVPixelFormat
{
	FFMPEG_AV_PIX_FMT_NOKNOW,
	FFMPEG_AV_PIX_FMT_NV12,
	FFMPEG_AV_PIX_FMT_NV21,
	FFMPEG_AV_PIX_FMT_YUV420P,
	FFMPEG_AV_PIX_FMT_YUV422P,
	FFMPEG_AV_PIX_FMT_RGB24,
	FFMPEG_AV_PIX_FMT_RGBA

}FFmpegAVPixelFormat;

#endif//FFMPEG_PIX_FORMAT
#ifndef FFMPEG_SCALE_CONFIG
#define	FFMPEG_SCALE_CONFIG
typedef struct FFmpegSwscaleConfig
{
	unsigned int srcWide;
	unsigned int srcHigh;
	FFmpegAVPixelFormat srcFormat;
	unsigned int dstWide;
	unsigned int dstHigh;
	FFmpegAVPixelFormat dstFormat;

	FFmpegSwscaleConfig()
	{
		srcWide = 0;
		srcHigh = 0;
		srcFormat = FFMPEG_AV_PIX_FMT_NOKNOW;
		dstWide = 0;
		dstHigh = 0;
		dstFormat = FFMPEG_AV_PIX_FMT_NOKNOW;
	}
}FFmpegSwscaleConfig;
#endif // !FFMPEG_SCALE_CONFIG

class ColorConversionFFmpeg
{
public:
	ColorConversionFFmpeg();
	~ColorConversionFFmpeg();

	long Init(FFmpegSwscaleConfig* cfg);
	long Conversion(const char* inputBuff, char* outputBuff);
	long UnInit();

private:
	long BuffToAVPixFmtYUV420P(char* inputBuff, unsigned char** pixBuff);
	long BuffToAVPixFmtRGBA(char* inputBuff, unsigned char** pixBuff);
	long BuffToAVPixFmtRGB24(char* inputBuff, unsigned char** pixBuff);
	long BuffToAVPixFmtNV12(char* inputBuff, unsigned char** pixBuff);
	long BuffToAVPixFmtNV21(char* inputBuff, unsigned char** pixBuff);
	long BuffToAVPixFmtYUV422P(char* inputBuff, unsigned char** pixBuff);

	long AVPixFmtYUV420PToBuff(unsigned char** pixBuff, char* outputBuff);
	long AVPixFmtNV12ToBuff(unsigned char** pixBuff, char* outputBuff);
	long AVPixFmtNV21ToBuff(unsigned char** pixBuff, char* outputBuff);
	long AVPixFmtYUV422PToBuff(unsigned char** pixBuff, char* outputBuff);
	long AVPixFmtRGB24ToBuff(unsigned char** pixBuff, char* outputBuff);
	long AVPixFmtRGBAToBuff(unsigned char** pixBuff, char* outputBuff);

private:
	SwsContext* m_imgConvertCtx;
	uint8_t* m_srcPointers[4]{ nullptr,nullptr,nullptr,nullptr };
	int m_srcLinesizes[4]{0,0,0,0};
	uint8_t* m_dstPointers[4]{ nullptr,nullptr,nullptr,nullptr };
	int m_dstLinesizes[4]{ 0,0,0,0 };

	int m_srcHigh;
	int m_srcWide;
	std::function < long(char* inputBuff, unsigned char** pixBuff) > m_infun;
	std::function < long(unsigned char** pixBuff, char* outputBuff) > m_outfun;
	std::map<FFmpegAVPixelFormat, AVPixelFormat>			m_PixelFormatMap;
	std::map<FFmpegAVPixelFormat,
		std::function < long(
			char* inputBuff,
			unsigned char** pixBuff) >>					    m_srcFormatFunMap;
	std::map<FFmpegAVPixelFormat,
		std::function < long(
			unsigned char** pixBuff,
			char* outputBuff) >>						    m_dstFormatFunMap;
};
#endif//COLOR_CONVERSION_FFMPEG_H

Source file: colorconversionffmpeg cpp

#include "ColorConversionFFmpeg.h"

ColorConversionFFmpeg::ColorConversionFFmpeg()
	: m_imgConvertCtx(nullptr)
	, m_infun(nullptr)
	, m_outfun(nullptr)
	, m_srcHigh(0)
	, m_srcWide(0)
{

	m_PixelFormatMap.insert(std::pair<FFmpegAVPixelFormat, AVPixelFormat>(FFMPEG_AV_PIX_FMT_NV12, AV_PIX_FMT_NV12));
	m_PixelFormatMap.insert(std::pair<FFmpegAVPixelFormat, AVPixelFormat>(FFMPEG_AV_PIX_FMT_NV21, AV_PIX_FMT_NV21));
	m_PixelFormatMap.insert(std::pair<FFmpegAVPixelFormat, AVPixelFormat>(FFMPEG_AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV420P));
	m_PixelFormatMap.insert(std::pair<FFmpegAVPixelFormat, AVPixelFormat>(FFMPEG_AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV422P));
	m_PixelFormatMap.insert(std::pair<FFmpegAVPixelFormat, AVPixelFormat>(FFMPEG_AV_PIX_FMT_RGB24, AV_PIX_FMT_RGB24));
	m_PixelFormatMap.insert(std::pair<FFmpegAVPixelFormat, AVPixelFormat>(FFMPEG_AV_PIX_FMT_RGBA, AV_PIX_FMT_BGRA));

	m_srcFormatFunMap[FFMPEG_AV_PIX_FMT_NV12] = std::bind(&ColorConversionFFmpeg::BuffToAVPixFmtNV12,
		this,
		std::placeholders::_1,
		std::placeholders::_2);
	m_srcFormatFunMap[FFMPEG_AV_PIX_FMT_NV21] = std::bind(&ColorConversionFFmpeg::BuffToAVPixFmtNV21,
		this,
		std::placeholders::_1,
		std::placeholders::_2);
	m_srcFormatFunMap[FFMPEG_AV_PIX_FMT_YUV420P] = std::bind(&ColorConversionFFmpeg::BuffToAVPixFmtYUV420P,
		this,
		std::placeholders::_1,
		std::placeholders::_2);
	m_srcFormatFunMap[FFMPEG_AV_PIX_FMT_YUV422P] = std::bind(&ColorConversionFFmpeg::BuffToAVPixFmtYUV422P,
		this,
		std::placeholders::_1,
		std::placeholders::_2);
	m_srcFormatFunMap[FFMPEG_AV_PIX_FMT_RGB24] = std::bind(&ColorConversionFFmpeg::BuffToAVPixFmtRGB24,
		this,
		std::placeholders::_1,
		std::placeholders::_2);
	m_srcFormatFunMap[FFMPEG_AV_PIX_FMT_RGBA] = std::bind(&ColorConversionFFmpeg::BuffToAVPixFmtRGBA,
		this,
		std::placeholders::_1,
		std::placeholders::_2);


	m_dstFormatFunMap[FFMPEG_AV_PIX_FMT_NV12] = std::bind(&ColorConversionFFmpeg::AVPixFmtNV12ToBuff,
		this,
		std::placeholders::_1,
		std::placeholders::_2);
	m_dstFormatFunMap[FFMPEG_AV_PIX_FMT_NV21] = std::bind(&ColorConversionFFmpeg::AVPixFmtNV21ToBuff,
		this,
		std::placeholders::_1,
		std::placeholders::_2);
	m_dstFormatFunMap[FFMPEG_AV_PIX_FMT_YUV420P] = std::bind(&ColorConversionFFmpeg::AVPixFmtYUV420PToBuff,
		this,
		std::placeholders::_1,
		std::placeholders::_2);
	m_dstFormatFunMap[FFMPEG_AV_PIX_FMT_YUV422P] = std::bind(&ColorConversionFFmpeg::AVPixFmtYUV422PToBuff,
		this,
		std::placeholders::_1,
		std::placeholders::_2);
	m_dstFormatFunMap[FFMPEG_AV_PIX_FMT_RGB24] = std::bind(&ColorConversionFFmpeg::AVPixFmtRGB24ToBuff,
		this,
		std::placeholders::_1,
		std::placeholders::_2);
	m_dstFormatFunMap[FFMPEG_AV_PIX_FMT_RGBA] = std::bind(&ColorConversionFFmpeg::AVPixFmtRGBAToBuff,
		this,
		std::placeholders::_1,
		std::placeholders::_2);

}

ColorConversionFFmpeg::~ColorConversionFFmpeg()
{
	m_PixelFormatMap.clear();
	m_srcFormatFunMap.clear();
	m_dstFormatFunMap.clear();

}

long ColorConversionFFmpeg::Init(FFmpegSwscaleConfig* cfg)
{
	if (nullptr == cfg)
	{
		return -1;
	}
	auto srcIter = m_PixelFormatMap.find(cfg->srcFormat);
	auto dstIter = m_PixelFormatMap.find(cfg->dstFormat);
	if (srcIter == m_PixelFormatMap.end() ||
		dstIter == m_PixelFormatMap.end())
	{
		return -2;
	}
	auto srcFormatFunIter = m_srcFormatFunMap.find(cfg->srcFormat);
	auto dstFormatFunIter = m_dstFormatFunMap.find(cfg->dstFormat);
	if (dstFormatFunIter == m_dstFormatFunMap.end() ||
		srcFormatFunIter == m_srcFormatFunMap.end())
	{
		return -3;
	}

	m_infun = srcFormatFunIter->second;
	m_outfun = dstFormatFunIter->second;

	int nSrctBuffLen = 0, nDstBuffLen = 0;

	nSrctBuffLen = av_image_alloc(m_srcPointers, m_srcLinesizes, cfg->srcWide, cfg->srcHigh, srcIter->second, 1);
	if (nSrctBuffLen <= 0)
	{
		return -4;
	}
	nDstBuffLen = av_image_alloc(m_dstPointers, m_dstLinesizes, cfg->dstWide, cfg->dstHigh, dstIter->second, 1);
	if (nDstBuffLen <= 0 )
	{
		av_freep(&m_srcPointers[0]);
		return -5;
	}

	m_imgConvertCtx = sws_getContext(cfg->srcWide, cfg->srcHigh, srcIter->second,
		cfg->dstWide, cfg->dstHigh, dstIter->second, SWS_BICUBIC, NULL, NULL, NULL);
	
	if (nullptr == m_imgConvertCtx)
	{
		av_freep(&m_srcPointers);
		av_freep(&m_dstPointers);
		return -6;
	}

	m_srcHigh = cfg->srcHigh;
	m_srcWide = cfg->srcWide;

	return 0;
}

long ColorConversionFFmpeg::Conversion(const char* inputBuff, char* outputBuff)
{
	if (nullptr == m_infun ||
		nullptr == m_outfun ||
		nullptr == m_dstPointers[0] ||
		nullptr == m_srcPointers[0] ||
		nullptr == m_imgConvertCtx)
	{
		return 0;
	}
	
	m_infun(const_cast<char*>(inputBuff), m_srcPointers);

	sws_scale(m_imgConvertCtx, m_srcPointers, m_srcLinesizes, 0, m_srcHigh, m_dstPointers, m_dstLinesizes);

	m_outfun(m_dstPointers, outputBuff);
	return 0;
}

long ColorConversionFFmpeg::UnInit()
{
	if (m_srcPointers)
	{
		av_freep(&m_srcPointers);
	}
	if (m_dstPointers)
	{
		av_freep(&m_dstPointers);
	}

	m_dstPointers[0] = nullptr;
	m_srcPointers[0] = nullptr;

	if (nullptr != m_imgConvertCtx)
	{
		sws_freeContext(m_imgConvertCtx);
	}

	m_imgConvertCtx = nullptr;
	m_outfun = nullptr;
	m_infun = nullptr;

	return 0;
}

long ColorConversionFFmpeg::BuffToAVPixFmtYUV420P(char* inputBuff, unsigned char** pixBuff)
{
	memcpy(pixBuff[0], inputBuff, static_cast<size_t>(m_srcWide * m_srcHigh));											//Y
	memcpy(pixBuff[1], inputBuff + m_srcWide * m_srcHigh, m_srcWide * m_srcHigh / 4);				//U
	memcpy(pixBuff[2], inputBuff + m_srcWide * m_srcHigh * 5 / 4, m_srcWide * m_srcHigh / 4);		//V
	return 0;
}

long ColorConversionFFmpeg::BuffToAVPixFmtRGBA(char* inputBuff, unsigned char** pixBuff)
{
	memcpy(pixBuff[0], inputBuff, m_srcWide * m_srcHigh*4);
	return 0;
}

long ColorConversionFFmpeg::BuffToAVPixFmtRGB24(char* inputBuff, unsigned char** pixBuff)
{
	memcpy(pixBuff[0], inputBuff, m_srcWide * m_srcHigh * 3);
	return 0;
}

long ColorConversionFFmpeg::BuffToAVPixFmtNV12(char* inputBuff, unsigned char** pixBuff)
{
	memcpy(pixBuff[0], inputBuff, m_srcHigh*m_srcWide);                    //Y
	memcpy(pixBuff[1], inputBuff + m_srcHigh * m_srcWide, m_srcHigh*m_srcWide / 2);      //Uv
	return 0;
}

long ColorConversionFFmpeg::BuffToAVPixFmtNV21(char* inputBuff, unsigned char** pixBuff)
{
	memcpy(pixBuff[0], inputBuff, m_srcHigh * m_srcWide);                    //Y
	memcpy(pixBuff[1], inputBuff + m_srcHigh * m_srcWide, m_srcHigh * m_srcWide / 2);      //Uv
	return 0;
}

long ColorConversionFFmpeg::BuffToAVPixFmtYUV422P(char* inputBuff, unsigned char** pixBuff)
{
	memcpy(pixBuff[0], inputBuff, m_srcWide * m_srcHigh);											//Y
	memcpy(pixBuff[1], inputBuff + m_srcWide * m_srcHigh, m_srcWide * m_srcHigh / 2);				//U
	memcpy(pixBuff[2], inputBuff + m_srcWide * m_srcHigh * 3 / 2, m_srcWide * m_srcHigh / 2);		//V
	return 0;
}

long ColorConversionFFmpeg::AVPixFmtYUV420PToBuff(unsigned char** pixBuff, char* outputBuff)
{
	memcpy(outputBuff, pixBuff[0], m_srcWide * m_srcHigh);											//Y
	memcpy(outputBuff + m_srcWide * m_srcHigh, pixBuff[1], m_srcWide * m_srcHigh / 4);				//U
	memcpy(outputBuff + m_srcWide * m_srcHigh * 5 / 4, pixBuff[2], m_srcWide * m_srcHigh / 4);		//V
	return 0;
}

long ColorConversionFFmpeg::AVPixFmtNV12ToBuff(unsigned char** pixBuff, char* outputBuff)
{
	memcpy( outputBuff, pixBuff[0], m_srcHigh * m_srcWide);                    //Y
	memcpy( outputBuff + m_srcHigh * m_srcWide, pixBuff[1], m_srcHigh * m_srcWide / 2);      //Uv
	return 0;
}

long ColorConversionFFmpeg::AVPixFmtNV21ToBuff(unsigned char** pixBuff, char* outputBuff)
{
	memcpy(outputBuff, pixBuff[0], m_srcHigh * m_srcWide);                    //Y
	memcpy(outputBuff + m_srcHigh * m_srcWide, pixBuff[1], m_srcHigh * m_srcWide / 2);      //Uv
	return 0;
}

long ColorConversionFFmpeg::AVPixFmtYUV422PToBuff(unsigned char** pixBuff, char* outputBuff)
{
	memcpy(outputBuff, pixBuff[0], m_srcWide * m_srcHigh);											//Y
	memcpy(outputBuff + m_srcWide * m_srcHigh, pixBuff[1], m_srcWide * m_srcHigh / 2);				//U
	memcpy(outputBuff + m_srcWide * m_srcHigh * 3 / 2, pixBuff[2], m_srcWide * m_srcHigh / 2);		//V
	return 0;
}

long ColorConversionFFmpeg::AVPixFmtRGB24ToBuff(unsigned char** pixBuff, char* outputBuff)
{
	memcpy(outputBuff, pixBuff[0], m_srcWide * m_srcHigh * 3);
	return 0;
}

long ColorConversionFFmpeg::AVPixFmtRGBAToBuff(unsigned char** pixBuff, char* outputBuff)
{
	memcpy(outputBuff, pixBuff[0], m_srcWide * m_srcHigh * 4);
	return 0;
}

Test file: main cpp

/**
* FFmpeg Color space conversion test program
* YUV Transformation
*
* Liang Qidong liang
* 18088708700@163.com
* https://blog.csdn.net/u011645307
*
*
* FFmpeg Color space conversion test program
*/

#include <iostream>
#include "ColorConversionFFmpeg.h"


#define NV12_To_I420	0
#define I420_To_NV12	0
#define NV21_To_I420	0
#define I420_To_NV21	0
#define I420_To_RGB32	0
#define RGB32_To_I420	0
#define I420_To_RGB24	0
#define RGB24_To_I420	0
#define NV12_To_YUV422P	0
#define YUV422P_To_NV12	1
int main()
{
	FILE* file_in = nullptr;
	FILE* file_out = nullptr;
	char* input_name = nullptr;
	char* output_name = nullptr;

	int w = 0, h = 0;
	float flotScale = 0;
	int out_w = 0, out_h = 0;
	float out_flotScale = 0;

	FFmpegSwscaleConfig cfg;
	ColorConversionFFmpeg obj;

#if NV12_To_YUV422P
	input_name = const_cast<char*>("../in/nv21_480x272.yuv");
	output_name = const_cast<char*>("../out/yuvv422p_480x272.yuv");

	cfg.srcWide = 480;
	cfg.dstWide = 480;
	cfg.dstHigh = 272;
	cfg.srcHigh = 272;
	cfg.srcFormat = FFMPEG_AV_PIX_FMT_NV12;
	cfg.dstFormat = FFMPEG_AV_PIX_FMT_YUV422P;

	w = 480;
	h = 272;
	flotScale = 1.5;
	out_w = 480;
	out_h = 272;
	out_flotScale = 2;

#endif

#if YUV422P_To_NV12

	input_name = const_cast<char*>("../in/YV16(422)_480x272.yuv");
	output_name = const_cast<char*>("../out/nv21_480x272.yuv");
	cfg.srcWide = 480;
	cfg.dstWide = 480;
	cfg.dstHigh = 272;
	cfg.srcHigh = 272;
	cfg.srcFormat = FFMPEG_AV_PIX_FMT_YUV422P;
	cfg.dstFormat = FFMPEG_AV_PIX_FMT_NV12;

	w = 480;
	h = 272;
	flotScale = 2;
	out_w = 480;
	out_h = 272;
	out_flotScale = 1.5;

#endif

#if NV21_To_I420
	input_name = const_cast<char*>("../in/nv21_480x272.yuv");
	output_name = const_cast<char*>("../out/I420_480x272.yuv");

	cfg.srcWide = 480;
	cfg.dstWide = 480;
	cfg.dstHigh = 272;
	cfg.srcHigh = 272;
	cfg.srcFormat = FFMPEG_AV_PIX_FMT_NV21;
	cfg.dstFormat = FFMPEG_AV_PIX_FMT_YUV420P;

	w = 480;
	h = 272;
	flotScale = 1.5;
	out_w = 480;
	out_h = 272;
	out_flotScale = 1.5;

#endif

#if I420_To_NV21

	input_name = const_cast<char*>("../in/I420_480x272.yuv");
	output_name = const_cast<char*>("../out/nv21_480x272.yuv");
	cfg.srcWide = 480;
	cfg.dstWide = 480;
	cfg.dstHigh = 272;
	cfg.srcHigh = 272;
	cfg.srcFormat = FFMPEG_AV_PIX_FMT_YUV420P;
	cfg.dstFormat = FFMPEG_AV_PIX_FMT_NV21;

	w = 480;
	h = 272;
	flotScale = 1.5;
	out_w = 480;
	out_h = 272;
	out_flotScale = 1.5;

#endif

#if NV12_To_I420
	input_name = const_cast<char*>("../in/nv12_480x272.yuv");
	output_name = const_cast<char*>("../out/I420_480x272.yuv");

	cfg.srcWide = 480;
	cfg.dstWide = 480;
	cfg.dstHigh = 272;
	cfg.srcHigh = 272;
	cfg.srcFormat = FFMPEG_AV_PIX_FMT_NV12;
	cfg.dstFormat = FFMPEG_AV_PIX_FMT_YUV420P;

	w = 480;
	h = 272;
	flotScale = 1.5;
	out_w = 480;
	out_h = 272;
	out_flotScale = 1.5;

#endif

#if I420_To_NV12

	input_name = const_cast<char*>("../in/I420_480x272.yuv");
	output_name = const_cast<char*>("../out/nv12_480x272.yuv");
	cfg.srcWide = 480;
	cfg.dstWide = 480;
	cfg.dstHigh = 272;
	cfg.srcHigh = 272;
	cfg.srcFormat = FFMPEG_AV_PIX_FMT_YUV420P;
	cfg.dstFormat = FFMPEG_AV_PIX_FMT_NV12;

	w = 480;
	h = 272;
	flotScale = 1.5;
	out_w = 480;
	out_h = 272;
	out_flotScale = 1.5;

#endif

#if I420_To_RGB24
	input_name = const_cast<char*>("../in/I420_480x272.yuv");
	output_name = const_cast<char*>("../out/rgb_480x272.rgb");

	w = 480;
	h = 272;
	flotScale = 1.5;
	out_w = 480;
	out_h = 272;
	out_flotScale = 3;

	cfg.srcWide = w;
	cfg.dstWide = out_w;
	cfg.dstHigh = out_h;
	cfg.srcHigh = h;
	cfg.srcFormat = FFMPEG_AV_PIX_FMT_YUV420P;
	cfg.dstFormat = FFMPEG_AV_PIX_FMT_RGB24;


#endif

#if RGB24_To_I420
	input_name = const_cast<char*>("../in/rgb_480x272.rgb");
	output_name = const_cast<char*>("../out/I420_480x272.yuv");

	w = 480;
	h = 272;
	flotScale = 3;
	out_w = 480;
	out_h = 272;
	out_flotScale = 1.5;

	cfg.srcWide = w;
	cfg.dstWide = out_w;
	cfg.dstHigh = out_h;
	cfg.srcHigh = h;
	cfg.dstFormat = FFMPEG_AV_PIX_FMT_YUV420P;
	cfg.srcFormat = FFMPEG_AV_PIX_FMT_RGB24;

#endif

#if I420_To_RGB32
	input_name = const_cast<char*>("../in/I420_480x272.yuv");
	output_name = const_cast<char*>("../out/rgba_480x272.rgb");

	w = 480;
	h = 272;
	flotScale = 1.5;
	out_w = 480;
	out_h = 272;
	out_flotScale = 4;

	cfg.srcWide = w;
	cfg.dstWide = out_w;
	cfg.dstHigh = out_h;
	cfg.srcHigh = h;
	cfg.srcFormat = FFMPEG_AV_PIX_FMT_YUV420P;
	cfg.dstFormat = FFMPEG_AV_PIX_FMT_RGBA;

#endif

#if RGB32_To_I420
	input_name = const_cast<char*>("../in/rgba_480x272.rgb");
	output_name = const_cast<char*>("../out/I420_480x272.yuv");

	w = 480;
	h = 272;
	flotScale = 4;
	out_w = 480;
	out_h = 272;
	out_flotScale = 1.5;

	cfg.srcWide = w;
	cfg.dstWide = out_w;
	cfg.dstHigh = out_h;
	cfg.srcHigh = h;
	cfg.dstFormat = FFMPEG_AV_PIX_FMT_YUV420P;
	cfg.srcFormat = FFMPEG_AV_PIX_FMT_RGBA;

#endif

	int in_buff_len = w * h * flotScale;
	int out_buff_len = out_w * out_h * out_flotScale;
	char* inbuff = new char[in_buff_len];
	char* outbuff = new char[out_buff_len];
	fopen_s(&file_in, input_name, "rb+");
	fopen_s(&file_out, output_name, "wb+");


	int ret = obj.Init(&cfg);
	if (0 != ret)
	{
		printf("ColorConversionFFmpeg::Init ret:%d\n", ret);
		fclose(file_in);
		fclose(file_out);
		file_in = nullptr;
		file_out = nullptr;
		return -1;
	}
	while (true)
	{
		if (fread(inbuff, 1, in_buff_len, file_in) != in_buff_len)
		{
			break;
		}

		ret = obj.Conversion(inbuff, outbuff);
		if (0 != ret)
		{
			printf("ColorConversionFFmpeg::Conversion ret:%d\n", ret);
			continue;
		}
		fwrite(outbuff, 1, out_buff_len, file_out);
	}
	ret = obj.UnInit();
	if (0 != ret)
	{
		printf("ColorConversionFFmpeg::UnInit ret:%d\n", ret);
	}
	fclose(file_in);
	fclose(file_out);
	file_in = nullptr;
	file_out = nullptr;


    std::cout << "Hello World!\n";
}

Code path

csdn:https://download.csdn.net/download/u011645307/21739481?spm=1001.2014.3001.5501

Keywords: C++ image processing Visual Studio

Added by SGTWhitelaw on Sat, 18 Dec 2021 00:05:21 +0200