当前位置: 首页 > news >正文

视音频数据处理入门:颜色空间(二)---ffmpeg

目录

概述

流程

相关流程

初始化方法

初始化代码

转换方法

转换代码

释放方法

整体代码介绍

代码路径


概述

本篇简单说一下基于FFmpeg的libswscale的颜色空间转换;Libswscale里面实现了各种图像像素格式的转换,例如:YUV与RGB之间的转换等;这里简单说以下Libswscale的颜色空间转换的使用方法。

流程

相关流程

Libswscale使用起来很方便,最主要的函数只有3个:
(1)       sws_getContext():使用参数初始化SwsContext结构体。
(2)       sws_scale():转换一帧图像。
(3)       sws_freeContext():释放SwsContext结构体。
其中sws_getContext()也可以用另一个接口函数sws_getCachedContext()取代。

初始化方法

初始化SwsContext我们这里选用sws_getContext();除了上述函数之外还有另一种方法,更加灵活,可以配置更多的参数。该方法调用的函数如下所示:
1)  sws_alloc_context():为SwsContext结构体分配内存。
2)  av_opt_set_XXX():通过av_opt_set_int(),av_opt_set()…等等一系列方法设置SwsContext结构体的值。在这里需要注意,SwsContext结构体的定义看不到,所以不能对其中的成员变量直接进行赋值,必须通过av_opt_set()这类的API才能对其进行赋值。
3)  sws_init_context():初始化SwsContext结构体。
与第一种方式相比这种复杂的方法可以配置一些sws_getContext()配置不了的参数。比如说设置图像的YUV像素的取值范围是JPEG标准(Y、U、V取值范围都是0-255)还是MPEG标准(Y取值范围是16-235,U、V的取值范围是16-240)。

初始化代码

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

转换方法

对于转换函数就没有特别说明的了调用sws_scale();值得注意就是这个函数的参数的传递需要按照对应的颜色空间进行排列;

转换代码

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

释放方法

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

整体代码介绍

对应FFmpeg 颜色空间转换的demo这边封装成了一个类函数,主要提供了  NV12、NV21、YUV420P、YUV422P、RGB24、RGBA相互转换功能。如需扩展则实现对应函数即可。

头文件:ColorConversionFFmpeg.h

/*** FFmpeg的颜色空间转换* YUV Transformation** 梁启东 qidong.liang* 18088708700@163.com* https://blog.csdn.net/u011645307*** 本程序实现了FFmpeg的YUV数据之间的转换和YUV与RGB的转换。* 提供了如下:* 	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*  相互转换功能*/
#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_CONFIGclass 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

源文件: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));											//Ymemcpy(pixBuff[1], inputBuff + m_srcWide * m_srcHigh, m_srcWide * m_srcHigh / 4);				//Umemcpy(pixBuff[2], inputBuff + m_srcWide * m_srcHigh * 5 / 4, m_srcWide * m_srcHigh / 4);		//Vreturn 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);                    //Ymemcpy(pixBuff[1], inputBuff + m_srcHigh * m_srcWide, m_srcHigh*m_srcWide / 2);      //Uvreturn 0;
}long ColorConversionFFmpeg::BuffToAVPixFmtNV21(char* inputBuff, unsigned char** pixBuff)
{memcpy(pixBuff[0], inputBuff, m_srcHigh * m_srcWide);                    //Ymemcpy(pixBuff[1], inputBuff + m_srcHigh * m_srcWide, m_srcHigh * m_srcWide / 2);      //Uvreturn 0;
}long ColorConversionFFmpeg::BuffToAVPixFmtYUV422P(char* inputBuff, unsigned char** pixBuff)
{memcpy(pixBuff[0], inputBuff, m_srcWide * m_srcHigh);											//Ymemcpy(pixBuff[1], inputBuff + m_srcWide * m_srcHigh, m_srcWide * m_srcHigh / 2);				//Umemcpy(pixBuff[2], inputBuff + m_srcWide * m_srcHigh * 3 / 2, m_srcWide * m_srcHigh / 2);		//Vreturn 0;
}long ColorConversionFFmpeg::AVPixFmtYUV420PToBuff(unsigned char** pixBuff, char* outputBuff)
{memcpy(outputBuff, pixBuff[0], m_srcWide * m_srcHigh);											//Ymemcpy(outputBuff + m_srcWide * m_srcHigh, pixBuff[1], m_srcWide * m_srcHigh / 4);				//Umemcpy(outputBuff + m_srcWide * m_srcHigh * 5 / 4, pixBuff[2], m_srcWide * m_srcHigh / 4);		//Vreturn 0;
}long ColorConversionFFmpeg::AVPixFmtNV12ToBuff(unsigned char** pixBuff, char* outputBuff)
{memcpy( outputBuff, pixBuff[0], m_srcHigh * m_srcWide);                    //Ymemcpy( outputBuff + m_srcHigh * m_srcWide, pixBuff[1], m_srcHigh * m_srcWide / 2);      //Uvreturn 0;
}long ColorConversionFFmpeg::AVPixFmtNV21ToBuff(unsigned char** pixBuff, char* outputBuff)
{memcpy(outputBuff, pixBuff[0], m_srcHigh * m_srcWide);                    //Ymemcpy(outputBuff + m_srcHigh * m_srcWide, pixBuff[1], m_srcHigh * m_srcWide / 2);      //Uvreturn 0;
}long ColorConversionFFmpeg::AVPixFmtYUV422PToBuff(unsigned char** pixBuff, char* outputBuff)
{memcpy(outputBuff, pixBuff[0], m_srcWide * m_srcHigh);											//Ymemcpy(outputBuff + m_srcWide * m_srcHigh, pixBuff[1], m_srcWide * m_srcHigh / 2);				//Umemcpy(outputBuff + m_srcWide * m_srcHigh * 3 / 2, pixBuff[2], m_srcWide * m_srcHigh / 2);		//Vreturn 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;
}

测试文件:main.cpp

/**
* FFmpeg的颜色空间转换的测试程序
* YUV Transformation
*
* 梁启东 qidong.liang
* 18088708700@163.com
* https://blog.csdn.net/u011645307
*
*
* FFmpeg的颜色空间转换的测试程序
*/#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_YUV422Pinput_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_NV12input_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_I420input_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_NV21input_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_I420input_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_NV12input_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_RGB24input_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_I420input_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_RGB32input_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_I420input_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;#endifint 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";
}

代码路径

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

github:https://github.com/liangqidong/ColorConversion.git

相关文章:

视音频数据处理入门:颜色空间(二)---ffmpeg

目录 概述 流程 相关流程 初始化方法 初始化代码 转换方法 转换代码 释放方法 整体代码介绍 代码路径 概述 本篇简单说一下基于FFmpeg的libswscale的颜色空间转换&#xff1b;Libswscale里面实现了各种图像像素格式的转换&#xff0c;例如&#xff1a;YUV与RGB之间的…...

从零开始:H20服务器上DeepSeek R1 671B大模型部署与压力测试全攻略

前言 最近&#xff0c;我有幸在工作中接触到了DeepSeek R1 671B模型&#xff0c;这是目前中文开源领域参数量最大的高质量模型之一。DeepSeek团队在2024年推出的这款模型&#xff0c;以其惊人的6710亿参数量和出色的推理性能&#xff0c;引起了业界广泛关注。 作为一名AI基础…...

【FAQ】HarmonyOS SDK 闭源开放能力 —Map Kit(5)

1.问题描述&#xff1a; 提供两套标准方案&#xff0c;可根据体验需求选择&#xff1a; 1.地图Picker(地点详情) 用户体验&#xff1a;①展示地图 ②标记地点 ③用户选择已安装地图应用 接入文档&#xff1a;https://developer.huawei.com/consumer/cn/doc/harmonyos-guide…...

Leetcode 3469. Find Minimum Cost to Remove Array Elements

Leetcode 3469. Find Minimum Cost to Remove Array Elements 1. 解题思路2. 代码实现 题目链接&#xff1a;3469. Find Minimum Cost to Remove Array Elements 1. 解题思路 这一题我没啥特别好的思路&#xff0c;就只能动态规划了&#xff0c;倒是也能过&#xff0c;不过总…...

Excel的行高、列宽单位不统一?还是LaTeX靠谱

想要生成田字格、米字格、带拼音标准&#xff0c;方便小学生书法和练字。Word&#xff0c;Excel之类所见即所得是最容易相当的方式。但它们处理带田字格之类背景时&#xff0c;如果没有专用模板、奇奇怪怪的插件&#xff0c;使用起来会碰到各种问题。比如&#xff0c;Word里面用…...

(新版本onenet)stm32+esp8266/01s mqtt连接onenet上报温湿度和远程控制(含小程序)

物联网实践教程&#xff1a;微信小程序结合OneNET平台MQTT实现STM32单片机远程智能控制 远程上报和接收数据——汇总 前言 之前在学校获得了一个新玩意&#xff1a;ESP-01sWIFI模块&#xff0c;去搜了一下这个小东西很有玩点&#xff0c;远程控制LED啥的&#xff0c;然后我就想…...

告别GitHub连不上!一分钟快速访问方案

一、当GitHub抽风时&#xff0c;你是否也这样崩溃过&#xff1f; &#x1f621; npm install卡在node-sass半小时不动&#x1f62d; git clone到90%突然fatal: early EOF&#x1f92c; 改了半天hosts文件&#xff0c;第二天又失效了... 根本原因&#xff1a;传统代理需要复杂…...

迷你世界脚本对象库接口:ObjectLib

对象库接口&#xff1a;ObjectLib 迷你世界 更新时间: 2023-04-26 20:21:09 具体函数名及描述如下: 序号 函数名 函数描述 1 getAreaData(...) 获取区域数据 2 getPositionData(...) 获取位置数据 3 getLivingData(...) 获取生物数据 4 getItemDat…...

数据库事务、乐观锁及悲观锁

参考&#xff1a;node支付宝支付及同步、异步通知、主动查询支付宝订单状态 以下容结合上述链接查看 1. 什么是数据库事务&#xff1f; 1.1. 连续执行数据库操作 在支付成功后&#xff0c;我们在自定义的paidSuccess里&#xff0c;依次更新了订单状态和用户信息。也就说这里…...

蓝桥王国--dij模板

#include <bits/stdc.h> // 万能头 using namespace std; typedef pair<long long ,int> PII; int n,m; long long d[300011]; struct edge///邻接表 {int v;long long w; }; int vis[300011]; vector<edge> mp[300011];///邻接表 void dij(int s)///dij单源…...

Java基础关键_017_集合(一)

目 录 一、概述 二、Collection 关系结构 1.概览 2.说明 三、Collection 接口 1.通用方法 &#xff08;1&#xff09;add(E e) &#xff08;2&#xff09;size() &#xff08;3&#xff09;addAll(Collection c) &#xff08;4&#xff09;contains(Object o) &#…...

Rust编程实战:Rust实现简单的Web服务,单线程性能问题

知识点 tcp 服务多线程处理 实现功能 启动web服务&#xff0c;访问链接获取页面内容。 单线程web服务 TcpListener 使用 TcpListener 开启服务端口 let listener TcpListener::bind("127.0.0.1:7878").unwrap();处理客户端连接&#xff1a; for stream in lis…...

GitLab 密钥详解:如何安全地使用 SSH 密钥进行身份验证

目录 一、什么是 GitLab SSH 密钥&#xff1f;二、为什么要使用 SSH 密钥&#xff1f;三、如何生成 SSH 密钥&#xff1f;1. Linux/macOS2. Windows 四、将公钥添加到 GitLab五、配置 SSH 客户端六、常见问题及解决方案七、总结 GitLab 是一个功能强大的 Git 仓库管理平台&…...

《论数据分片技术及其应用》审题技巧 - 系统架构设计师

论数据分片技术及其应用写作框架 一、考点概述 本论题“论数据分片技术及其应用”主要考察的是软件工程中数据分片技术的理解、应用及其实际效果分析。考点涵盖以下几个方面&#xff1a; 首先&#xff0c;考生需对数据分片的基本概念有清晰的认识&#xff0c;理解数据分片是…...

【C++】当一个类A中没有声明任何成员变量和成员函数,sizeof(A)是多少?

在 C 中&#xff0c;即使一个类没有任何数据成员&#xff08;即空类&#xff09;&#xff0c;它的大小也不会是 0&#xff0c;而是 1。这主要有以下几个原因&#xff1a; 地址唯一性要求 C 标准规定&#xff0c;每个对象都必须有唯一的地址。如果空类的大小为 0&#xff0c;那么…...

Maven 私服的搭建与使用(一)

一、引言 在 Java 项目开发中&#xff0c;Maven 作为强大的项目管理和构建工具&#xff0c;极大地提高了开发效率&#xff0c;而 Maven 私服在开发过程中也扮演着至关重要的角色。私服是一种特殊的远程仓库&#xff0c;架设在局域网内&#xff0c;代理广域网上的远程仓库&…...

Ubuntu20.04双系统安装及软件安装(五):VSCode

Ubuntu20.04双系统安装及软件安装&#xff08;五&#xff09;&#xff1a;VSCode 打开VScode官网&#xff0c;点击中间左侧的deb文件下载&#xff1a; 系统会弹出下载框&#xff0c;确定即可。 在文件夹的**“下载”目录**&#xff0c;可看到下载的安装包&#xff0c;在该目录下…...

linux网络(3)—— socket编程(1)socket基础认识

欢迎来到博主的专栏&#xff1a;linux网络 博主ID&#xff1a;代码小豪 文章目录 IP与端口号socket字节序问题 IP与端口号 我们现在知道了&#xff0c;只要发送的报文的报头包含目的IP地址和源IP地址&#xff0c;就能通过通信设备&#xff0c;是两台主机进行远程通信&#xff…...

【Kubernets】K8S内部nginx访问Service资源原理说明

文章目录 原理概述**一、核心概念****二、Nginx 访问 Service 的流程****1. Service 的作用****2. Endpoint 的作用****3. Nginx Pod 发起请求****(1) DNS 解析****(2) 流量到达 kube-proxy****(3) 后端 Pod 处理请求** **三、不同代理模式的工作原理****1. iptables 模式****2…...

使用Docker搭建Oracle Database 23ai Free并扩展MAX_STRING_SIZE的完整指南

使用Docker搭建Oracle Database 23ai Free并扩展MAX_STRING_SIZE的完整指南 前言环境准备目录创建启动Docker容器 数据库配置修改进入容器启动SQL*PlusPDB操作与字符串扩展设置配置验证 管理员用户创建注意事项总结 前言 本文将详细讲解在Docker环境中配置Oracle Database 23a…...

从零构建:基于YOLOv8/YOLOv10的智能游戏瞄准系统深度解析

从零构建&#xff1a;基于YOLOv8/YOLOv10的智能游戏瞄准系统深度解析 【免费下载链接】yolov8_aimbot Aim-bot based on AI for all FPS games 项目地址: https://gitcode.com/gh_mirrors/yo/yolov8_aimbot 你是否曾经好奇&#xff0c;人工智能技术如何精准识别游戏中的…...

如何掌握Il2CppDumper:Unity逆向工程实战指南与深度解析

如何掌握Il2CppDumper&#xff1a;Unity逆向工程实战指南与深度解析 【免费下载链接】Il2CppDumper Unity il2cpp reverse engineer 项目地址: https://gitcode.com/gh_mirrors/il/Il2CppDumper 你是否曾面对Unity游戏的il2cpp二进制文件感到无从下手&#xff1f;是否在…...

按键精灵PC版和手机版到底怎么选?一篇讲清四大版本区别与核心开发流程

按键精灵四大版本深度解析&#xff1a;从需求匹配到高效开发的完整指南 在自动化工具领域&#xff0c;按键精灵凭借其跨平台支持和易用性&#xff0c;成为许多用户的首选。但面对官网提供的四个不同版本——电脑版、手机助手、安卓版和IOS版&#xff0c;不少新手用户会感到困惑…...

如何让GitHub下载速度提升10倍:免费加速插件完整配置指南

如何让GitHub下载速度提升10倍&#xff1a;免费加速插件完整配置指南 【免费下载链接】Fast-GitHub 国内Github下载很慢&#xff0c;用上了这个插件后&#xff0c;下载速度嗖嗖嗖的~&#xff01; 项目地址: https://gitcode.com/gh_mirrors/fa/Fast-GitHub 你是否曾经因…...

COLMAP稠密点云太稀疏?OpenMVS点云又太密?试试这个‘黄金搭档’配置方案

COLMAP与OpenMVS混合重建&#xff1a;如何实现点云密度与计算效率的黄金平衡 在三维重建领域&#xff0c;我们常常面临一个两难选择&#xff1a;COLMAP生成的稠密点云往往过于稀疏&#xff0c;导致最终网格模型细节不足&#xff1b;而OpenMVS自带的稠密重建又容易产生过度密集的…...

从仿真到真车:如何用CARLA+Autoware搭建你的自动驾驶算法快速迭代工作流?

从仿真到真车&#xff1a;构建CARLAAutoware自动驾驶算法高效迭代体系 自动驾驶算法的开发如同在刀锋上行走——既要保证安全性&#xff0c;又要追求创新速度。当特斯拉的工程师们每天通过影子模式收集数百万英里的真实数据时&#xff0c;大多数团队却受限于路测成本与安全风险…...

IfcOpenShell技术架构深度解析:开源IFC引擎的模块化设计与高性能实现

IfcOpenShell技术架构深度解析&#xff1a;开源IFC引擎的模块化设计与高性能实现 【免费下载链接】IfcOpenShell Open source IFC library and geometry engine 项目地址: https://gitcode.com/gh_mirrors/if/IfcOpenShell IfcOpenShell作为开源建筑信息模型&#xff08…...

云端开发新体验:code-server部署与多场景应用指南

1. 为什么你需要一个云端开发环境&#xff1f; 记得去年我同时参与三个项目时&#xff0c;每天要在办公室台式机、家里笔记本和平板电脑之间来回切换。每次换设备最头疼的就是开发环境不一致——Node.js版本不同、Python包缺失、配置文件没同步...有次紧急修复线上bug时&#x…...

终极MifareOneTool完整指南:Windows平台最简单的一键NFC卡片管理方案

终极MifareOneTool完整指南&#xff1a;Windows平台最简单的一键NFC卡片管理方案 【免费下载链接】MifareOneTool A GUI Mifare Classic tool on Windows&#xff08;停工/最新版v1.7.0&#xff09; 项目地址: https://gitcode.com/gh_mirrors/mi/MifareOneTool 你是否曾…...

从源码到实战:手把手教你自定义一个比StringUtils更强大的Java数字校验工具类

从源码到实战&#xff1a;构建超越StringUtils的Java数字校验工具类 在Java开发中&#xff0c;数字校验是每个开发者都会遇到的常见需求。虽然Apache Commons Lang的StringUtils提供了基础的isNumeric方法&#xff0c;但在实际业务场景中&#xff0c;我们经常需要处理更复杂的…...