当前位置: 首页 > 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…...

k8s从入门到放弃之Ingress七层负载

k8s从入门到放弃之Ingress七层负载 在Kubernetes&#xff08;简称K8s&#xff09;中&#xff0c;Ingress是一个API对象&#xff0c;它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress&#xff0c;你可…...

Spring Boot 实现流式响应(兼容 2.7.x)

在实际开发中&#xff0c;我们可能会遇到一些流式数据处理的场景&#xff0c;比如接收来自上游接口的 Server-Sent Events&#xff08;SSE&#xff09; 或 流式 JSON 内容&#xff0c;并将其原样中转给前端页面或客户端。这种情况下&#xff0c;传统的 RestTemplate 缓存机制会…...

基于ASP.NET+ SQL Server实现(Web)医院信息管理系统

医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上&#xff0c;开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识&#xff0c;在 vs 2017 平台上&#xff0c;进行 ASP.NET 应用程序和简易网站的开发&#xff1b;初步熟悉开发一…...

Ascend NPU上适配Step-Audio模型

1 概述 1.1 简述 Step-Audio 是业界首个集语音理解与生成控制一体化的产品级开源实时语音对话系统&#xff0c;支持多语言对话&#xff08;如 中文&#xff0c;英文&#xff0c;日语&#xff09;&#xff0c;语音情感&#xff08;如 开心&#xff0c;悲伤&#xff09;&#x…...

关于 WASM:1. WASM 基础原理

一、WASM 简介 1.1 WebAssembly 是什么&#xff1f; WebAssembly&#xff08;WASM&#xff09; 是一种能在现代浏览器中高效运行的二进制指令格式&#xff0c;它不是传统的编程语言&#xff0c;而是一种 低级字节码格式&#xff0c;可由高级语言&#xff08;如 C、C、Rust&am…...

【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分

一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计&#xff0c;提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合&#xff1a;各模块职责清晰&#xff0c;便于独立开发…...

Spring数据访问模块设计

前面我们已经完成了IoC和web模块的设计&#xff0c;聪明的码友立马就知道了&#xff0c;该到数据访问模块了&#xff0c;要不就这俩玩个6啊&#xff0c;查库势在必行&#xff0c;至此&#xff0c;它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据&#xff08;数据库、No…...

【开发技术】.Net使用FFmpeg视频特定帧上绘制内容

目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法&#xff0c;当前调用一个医疗行业的AI识别算法后返回…...

Unsafe Fileupload篇补充-木马的详细教程与木马分享(中国蚁剑方式)

在之前的皮卡丘靶场第九期Unsafe Fileupload篇中我们学习了木马的原理并且学了一个简单的木马文件 本期内容是为了更好的为大家解释木马&#xff08;服务器方面的&#xff09;的原理&#xff0c;连接&#xff0c;以及各种木马及连接工具的分享 文件木马&#xff1a;https://w…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...