视音频数据处理入门:颜色空间(二)---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的颜色空间转换;Libswscale里面实现了各种图像像素格式的转换,例如:YUV与RGB之间的…...

从零开始:H20服务器上DeepSeek R1 671B大模型部署与压力测试全攻略
前言 最近,我有幸在工作中接触到了DeepSeek R1 671B模型,这是目前中文开源领域参数量最大的高质量模型之一。DeepSeek团队在2024年推出的这款模型,以其惊人的6710亿参数量和出色的推理性能,引起了业界广泛关注。 作为一名AI基础…...
【FAQ】HarmonyOS SDK 闭源开放能力 —Map Kit(5)
1.问题描述: 提供两套标准方案,可根据体验需求选择: 1.地图Picker(地点详情) 用户体验:①展示地图 ②标记地点 ③用户选择已安装地图应用 接入文档: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. 代码实现 题目链接:3469. Find Minimum Cost to Remove Array Elements 1. 解题思路 这一题我没啥特别好的思路,就只能动态规划了,倒是也能过,不过总…...

Excel的行高、列宽单位不统一?还是LaTeX靠谱
想要生成田字格、米字格、带拼音标准,方便小学生书法和练字。Word,Excel之类所见即所得是最容易相当的方式。但它们处理带田字格之类背景时,如果没有专用模板、奇奇怪怪的插件,使用起来会碰到各种问题。比如,Word里面用…...

(新版本onenet)stm32+esp8266/01s mqtt连接onenet上报温湿度和远程控制(含小程序)
物联网实践教程:微信小程序结合OneNET平台MQTT实现STM32单片机远程智能控制 远程上报和接收数据——汇总 前言 之前在学校获得了一个新玩意:ESP-01sWIFI模块,去搜了一下这个小东西很有玩点,远程控制LED啥的,然后我就想…...

告别GitHub连不上!一分钟快速访问方案
一、当GitHub抽风时,你是否也这样崩溃过? 😡 npm install卡在node-sass半小时不动😭 git clone到90%突然fatal: early EOF🤬 改了半天hosts文件,第二天又失效了... 根本原因:传统代理需要复杂…...
迷你世界脚本对象库接口:ObjectLib
对象库接口:ObjectLib 迷你世界 更新时间: 2023-04-26 20:21:09 具体函数名及描述如下: 序号 函数名 函数描述 1 getAreaData(...) 获取区域数据 2 getPositionData(...) 获取位置数据 3 getLivingData(...) 获取生物数据 4 getItemDat…...

数据库事务、乐观锁及悲观锁
参考:node支付宝支付及同步、异步通知、主动查询支付宝订单状态 以下容结合上述链接查看 1. 什么是数据库事务? 1.1. 连续执行数据库操作 在支付成功后,我们在自定义的paidSuccess里,依次更新了订单状态和用户信息。也就说这里…...
蓝桥王国--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.通用方法 (1)add(E e) (2)size() (3)addAll(Collection c) (4)contains(Object o) &#…...

Rust编程实战:Rust实现简单的Web服务,单线程性能问题
知识点 tcp 服务多线程处理 实现功能 启动web服务,访问链接获取页面内容。 单线程web服务 TcpListener 使用 TcpListener 开启服务端口 let listener TcpListener::bind("127.0.0.1:7878").unwrap();处理客户端连接: for stream in lis…...
GitLab 密钥详解:如何安全地使用 SSH 密钥进行身份验证
目录 一、什么是 GitLab SSH 密钥?二、为什么要使用 SSH 密钥?三、如何生成 SSH 密钥?1. Linux/macOS2. Windows 四、将公钥添加到 GitLab五、配置 SSH 客户端六、常见问题及解决方案七、总结 GitLab 是一个功能强大的 Git 仓库管理平台&…...
《论数据分片技术及其应用》审题技巧 - 系统架构设计师
论数据分片技术及其应用写作框架 一、考点概述 本论题“论数据分片技术及其应用”主要考察的是软件工程中数据分片技术的理解、应用及其实际效果分析。考点涵盖以下几个方面: 首先,考生需对数据分片的基本概念有清晰的认识,理解数据分片是…...
【C++】当一个类A中没有声明任何成员变量和成员函数,sizeof(A)是多少?
在 C 中,即使一个类没有任何数据成员(即空类),它的大小也不会是 0,而是 1。这主要有以下几个原因: 地址唯一性要求 C 标准规定,每个对象都必须有唯一的地址。如果空类的大小为 0,那么…...
Maven 私服的搭建与使用(一)
一、引言 在 Java 项目开发中,Maven 作为强大的项目管理和构建工具,极大地提高了开发效率,而 Maven 私服在开发过程中也扮演着至关重要的角色。私服是一种特殊的远程仓库,架设在局域网内,代理广域网上的远程仓库&…...

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

linux网络(3)—— socket编程(1)socket基础认识
欢迎来到博主的专栏:linux网络 博主ID:代码小豪 文章目录 IP与端口号socket字节序问题 IP与端口号 我们现在知道了,只要发送的报文的报头包含目的IP地址和源IP地址,就能通过通信设备,是两台主机进行远程通信ÿ…...
【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…...

网络编程(Modbus进阶)
思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...

简易版抽奖活动的设计技术方案
1.前言 本技术方案旨在设计一套完整且可靠的抽奖活动逻辑,确保抽奖活动能够公平、公正、公开地进行,同时满足高并发访问、数据安全存储与高效处理等需求,为用户提供流畅的抽奖体验,助力业务顺利开展。本方案将涵盖抽奖活动的整体架构设计、核心流程逻辑、关键功能实现以及…...

【JVM】- 内存结构
引言 JVM:Java Virtual Machine 定义:Java虚拟机,Java二进制字节码的运行环境好处: 一次编写,到处运行自动内存管理,垃圾回收的功能数组下标越界检查(会抛异常,不会覆盖到其他代码…...

select、poll、epoll 与 Reactor 模式
在高并发网络编程领域,高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表,以及基于它们实现的 Reactor 模式,为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。 一、I…...
大数据学习(132)-HIve数据分析
🍋🍋大数据学习🍋🍋 🔥系列专栏: 👑哲学语录: 用力所能及,改变世界。 💖如果觉得博主的文章还不错的话,请点赞👍收藏⭐️留言Ǵ…...
基于matlab策略迭代和值迭代法的动态规划
经典的基于策略迭代和值迭代法的动态规划matlab代码,实现机器人的最优运输 Dynamic-Programming-master/Environment.pdf , 104724 Dynamic-Programming-master/README.md , 506 Dynamic-Programming-master/generalizedPolicyIteration.m , 1970 Dynamic-Programm…...

C++使用 new 来创建动态数组
问题: 不能使用变量定义数组大小 原因: 这是因为数组在内存中是连续存储的,编译器需要在编译阶段就确定数组的大小,以便正确地分配内存空间。如果允许使用变量来定义数组的大小,那么编译器就无法在编译时确定数组的大…...

JVM虚拟机:内存结构、垃圾回收、性能优化
1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...

人机融合智能 | “人智交互”跨学科新领域
本文系统地提出基于“以人为中心AI(HCAI)”理念的人-人工智能交互(人智交互)这一跨学科新领域及框架,定义人智交互领域的理念、基本理论和关键问题、方法、开发流程和参与团队等,阐述提出人智交互新领域的意义。然后,提出人智交互研究的三种新范式取向以及它们的意义。最后,总结…...

招商蛇口 | 执笔CID,启幕低密生活新境
作为中国城市生长的力量,招商蛇口以“美好生活承载者”为使命,深耕全球111座城市,以央企担当匠造时代理想人居。从深圳湾的开拓基因到西安高新CID的战略落子,招商蛇口始终与城市发展同频共振,以建筑诠释对土地与生活的…...