视音频数据处理入门:颜色空间(二)---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之间的…...
240 Vocabulary Words Kids Need to Know
《240 Vocabulary Words Kids Need to Know》是美国学乐出版社(Scholastic)推出的词汇学习系列练习册,专为美国小学阶段(G1-G6)设计,基于CCSS(美国共同核心州立标准)编写,…...
AI-Deepseek + PPT
01--Deepseek提问 首先去Deepseek问一个问题: Deepseek的回答: 在汽车CAN总线通信中,DBC文件里的信号处理(如初始值、系数、偏移)主要是为了 将原始二进制数据转换为实际物理值,确保不同电子控制单元&…...
【五.LangChain技术与应用】【8.LangChain提示词模板基础:从入门到精通】
早上八点,你端着咖啡打开IDE,老板刚甩来需求:“做个能自动生成产品描述的AI工具”。你自信满满地打开ChatGPT的API文档,结果半小时后对着满屏的"输出结果不稳定"、"格式总出错"抓耳挠腮——这时候你真需要好好认识下LangChain里的提示词模板了。 一、…...
pnpm add和pnpm install指定包名安装的区别
1. pnpm add 包名 行为: 安装包到 node_modules。自动将包添加到 package.json 的 dependencies 中(默认)。支持通过参数指定依赖类型(如 -D 表示 devDependencies,-O 表示 optionalDependencies)。更新 p…...
LeetCode 718.最长重复子数组(动态规划,Python)
给两个整数数组 nums1 和 nums2 ,返回 两个数组中 公共的 、长度最长的子数组的长度 。 示例 1: 输入:nums1 [1,2,3,2,1], nums2 [3,2,1,4,7] 输出:3 解释:长度最长的公共子数组是 [3,2,1] 。 示例 2: 输…...
XML布局文件与常用View组件
XML布局文件与常用View组件 一、基础知识 1.1 XML布局简介 Android应用的用户界面是由View和ViewGroup对象的层次结构组成的。每个ViewGroup都是一个可以包含View对象的容器。XML布局文件提供了一种类似HTML的方式来描述这种视图层次结构。 1.2 常用布局属性 <!-- 常用…...
C# | 委托 | 事件 | 异步
委托(Delegate)和事件(Event) 在C#和C中,委托(Delegate)与事件(Event)以及函数对象(Function Object)是实现回调机制或传递行为的重要工具。虽然…...
android .rc文件
Android .rc 文件的用途 在 Android 系统中,.rc 文件主要是 init 脚本,用于定义和配置 Android 系统的启动过程。.rc 文件的扩展名通常为 .rc,例如 init.rc、init.vendor.rc、init.hardware.rc 等。这些文件是 Android 的 init 进程…...
python-leetcode-零钱兑换 II
518. 零钱兑换 II - 力扣(LeetCode) 这个问题是 完全背包问题 的一个变体,可以使用 动态规划 来解决。我们定义 dp[i] 为凑成金额 i 的硬币组合数。 思路: 定义 DP 数组 设 dp[i] 表示凑成金额 i 的组合数,初始化 dp[…...
Sass 模块化革命:深入解析 @use 语法,打造高效 CSS 架构
文章目录 前言use 用法1. 模块化与命名空间2. use 中 as 语法的使用3. as * 语法的使用4. 私有成员的访问5. use 中with默认值6. use 导入问题总结下一篇预告: 前言 在上一篇中,我们深入探讨了 Sass 中 import 语法的局限性,正是因为这些问题…...
Kotlin中的数字
1、整数类型 Kotlin 提供了一组表示数字的内置类型。 对于整数,有四种不同大小的类型,因此值的范围也不同: 类型大小(比特数)最小值最大值Byte8-128127Short16-3276832767Int32-2,147,483,648 (-231)2,147,483,647 (…...
利用Postman和Apipost进行API测试的实践与优化-动态参数
在实际的开发和测试工作中,完成一个API后对其进行简单的测试是一项至关重要的任务。在测试过程中,确保API返回的数据符合预期,不仅可以提高开发效率,还能帮助我们快速发现可能存在的问题。对于简单的API测试,诸如验证响…...
【前端基础】Day 9 PC端品优购项目
目录 1. 品优购项目规划 1.1 网站制作流程 1.2 品优购项目整体介绍 1.3 学习目的 1.4 开发工具以及技术栈 1.5 项目搭建工作 1.6 网站favicon图标 1.7 网站TDK三大标签SEO优化 2. 品优购首页制作 2.1 常见模块类命名 2.2 快捷导航shortcut制作 2.3 header制作 2.4…...
FFMPEG利用H264+AAC合成TS文件
本次的DEMO是利用FFMPEG框架把H264文件和AAC文件合并成一个TS文件。这个DEMO很重要,因为在后面的推流项目中用到了这方面的技术。所以,大家最好把这个项目好好了解。 下面这个是流程图 从这个图我们能看出来,在main函数中我们主要做了这几步&…...
Linux搭建个人大模型RAG-(ollama+deepseek+anythingLLM)
本文是远程安装ollama deepseek,本地笔记本电脑安装anythingLLM,并上传本地文件作为知识库。 1.安装ollama 安装可以非常简单,一行命令完事。(有没有GPU,都没有关系,自动下载合适的版本) cd 到…...
Docker 学习(二)——基于Registry、Harbor搭建私有仓库
Docker仓库是集中存储和管理Docker镜像的平台,支持镜像的上传、下载、版本管理等功能。 一、Docker仓库分类 1.公有仓库 Docker Hub:官方默认公共仓库,提供超过10万镜像,支持用户上传和管理镜像。 第三方平台:如阿里…...
PHP之变量
在你有别的编程语言的基础下,你想学习PHP,可能要了解的一些关于变量的信息。 PHP中的变量不用指定数据类型,同时必须用$开头。 全局变量 可以在除函数外任意地方访问,如果需要在函数中访问要先获取 $x 111; function tt() {gl…...
centos和ubuntu下安装redis
1,判断环境是否有gcc gcc --version 如果未安装则执行 yum install -y gcc tcl 2,安装包下载,编译安装 cd /usr/local mkdir redis wget https://download.redis.io/releases/redis-4.0.11.tar.gz tar -xvf redis-4.0.11.tar.gz cd redis-4.0.11 编译 m…...
韩国互联网巨头 NAVER 如何借助 StarRocks 实现实时数据洞察
作者: Youngjin Kim Team Leader, NAVER Moweon Lee Data Engineer, NAVER 导读:开源无国界,在“StarRocks 全球用户精选案例”专栏中,我们将介绍韩国互联网巨头 NAVER 的 StarRocks 实践案例。 NAVER 成立于 1999 年࿰…...
K8s 1.27.1 实战系列(二)安装集群并初始化
一、安装 kubeadm、kubelet 和 kubectl(所有节点) 1、配置k8s的yum源地址 cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo [kubernetes] name=Kubernetes baseurl=http://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64 enabled=1 gpgchec…...
生命周期总结(uni-app、vue2、vue3生命周期讲解)
一、vue2生命周期 Vue2 的生命周期钩子函数分为 4 个阶段:创建、挂载、更新、销毁。 1. 创建阶段 beforeCreate:实例初始化之后,数据观测和事件配置之前。 created:实例创建完成,数据观测和事件配置已完成,…...
十一、Redis Sentinel(哨兵)—— 高可用架构与配置指南
Redis Sentinel(哨兵)—— 高可用架构与配置指南 在分布式应用中,Redis 主从复制(Master-Slave)虽然能提供读写分离的能力,但它 无法自动故障转移(failover)。如果主节点(Master)发生故障,系统管理员需要手动将某个从节点(Slave)提升为主节点,并重新配置所有从节…...
java8中young gc的垃圾回收器选型,您了解嘛
在 Java 8 的 Young GC(新生代垃圾回收)场景中,对于 ToC的场景,即需要尽可能减少垃圾回收停顿时间以满足业务响应要求的场景,以下几种收集器各有特点,通常 Parnew和 G1 young表现较为出色,下面详…...
C语言学习笔记-初阶(30)深入理解指针2
1. 数组名的理解 在上一个章节我们在使用指针访问数组的内容时,有这样的代码: int arr[10] {1,2,3,4,5,6,7,8,9,10}; int *p &arr[0]; 这里我们使用 &arr[0] 的方式拿到了数组第⼀个元素的地址,但是其实数组名本来就是地址&…...
【Wireshark 02】抓包过滤方法
一、官方教程 Wireshark 官网文档 : Wireshark User’s Guide 二、显示过滤器 2.1、 “数据包列表”窗格的弹出过滤菜单 例如,源ip地址作为过滤选项,右击源ip->prepare as filter-> 选中 点击选中完,显示过滤器&#…...
MySQL基础四(JDBC)
JDBC(重点) 数据库驱动 程序会通过数据库驱动,和数据库打交道。 sun公司为了简化开发人员对数据库的统一操作,提供了一个Java操作数据库的规范。这个规范由具体的厂商去完成。对应开发人员来说,只需要掌握JDBC接口。 熟悉java.sql与javax.s…...
基于CURL命令封装的JAVA通用HTTP工具
文章目录 一、简要概述二、封装过程1. 引入依赖2. 定义脚本执行类 三、单元测试四、其他资源 一、简要概述 在Linux中curl是一个利用URL规则在命令行下工作的文件传输工具,可以说是一款很强大的http命令行工具。它支持文件的上传和下载,是综合传输工具&…...
cenos7网络安全检查
很多网络爱好者都知道,在Windows 2000和Windows 9x的命令提示符下可使用Windows系统自带的多种命令行网络故障检测工具,比如说我们最常用的ping。但大家在具体应用时,可能对这些命令行工具的具体含义,以及命令行后面可以使用的种…...
FastGPT 引申:混合检索完整实例
文章目录 FastGPT 引申:混合检索完整实例1. 各检索方式的初始结果2. RRF合并过程3. 合并后的结果4. Rerank重排序后5. 最终RRF合并6. 内容总结 FastGPT 引申:混合检索完整实例 下边通过一个简单的例子说明不同检索方式的分值变化过程,假设我…...
