YUV422封包 | width*height+width/2*height*2 |
YUYV Y分量 | width*height |
YUYV U分量 | width/2*height |
YUYV V分量 | width/2*height |
YUV420空间大小计算
YUV420封包 | width*height+width/2*height/2*2 |
Y分量 | width*height |
U分量 | width/2*height/2 |
V分量 | width/2*height/2 |
extern "C" {
#include "libavformat/avformat.h"
#include "libswscale/swscale.h"
#pragma comment(lib, "avformat.lib")
#pragma comment(lib, "avcodec.lib")
#pragma comment(lib, "swscale.lib")
#pragma comment(lib, "avutil.lib")};
YUV422分量实现(YUYV)
static void YUYV422Planes(uint8_t *yuv422, uint8_t *y_ptr, uint8_t *u_ptr, uint8_t *v_ptr, int width, int height)
{//计算出空间大小int numBytes = width*height+width/2*height*2;unsigned int yIndex = 0;unsigned int uIndex = 0;unsigned int vIndex = 0;//分量for (unsigned int i = 0; i < numBytes; i += 4) {memcpy((unsigned char *)y_ptr + yIndex, yuv422+i, 1);yIndex++;memcpy((unsigned char *)u_ptr + uIndex, yuv422+i+1, 1);uIndex++;memcpy((unsigned char *)y_ptr + yIndex, yuv422+i+2, 1);yIndex++;memcpy((unsigned char *)v_ptr + vIndex, yuv422+i+3, 1);vIndex++;}
}
YUV422封包实现(YUYV)
static void YUYV422Packages(uint8_t *yuv422, uint8_t *y_ptr, uint8_t *u_ptr, uint8_t *v_ptr, int width, int height)
{//计算出空间大小int numBytes = width * height + width / 2 * height * 2;unsigned int yIndex = 0;unsigned int uIndex = 0;unsigned int vIndex = 0;//封包for (unsigned int i = 0; i < numBytes; i+=4) {//ymemcpy((unsigned char *)yuv422+i,y_ptr+yIndex,1);yIndex++;//umemcpy((unsigned char *)yuv422+i+1, u_ptr+uIndex, 1);uIndex++;//ymemcpy((unsigned char *)yuv422+i+2, y_ptr+yIndex, 1);yIndex++;//vmemcpy((unsigned char *)yuv422+i+3, v_ptr+vIndex, 1);vIndex++;}
}
YUV420封包实现
static void YUV420PPackages(uint8_t *yuv420, uint8_t *y_ptr, uint8_t *u_ptr,uint8_t *v_ptr, int width, int height)
{//Y分量的长度int yLen = width * height;//U和V分量的长度int uvLen = width / 2 * height / 2;memcpy((unsigned char *)yuv420, y_ptr, yLen);memcpy((unsigned char *)yuv420 + yLen, u_ptr, uvLen);memcpy((unsigned char *)yuv420+yLen+uvLen, v_ptr, uvLen);
}
YUV420分量实现
static void YUV420PPlanes(uint8_t *yuv420, uint8_t *y_ptr, uint8_t *u_ptr,uint8_t *v_ptr, int width, int height)
{//Y分量的长度int yLen = width * height;//U和V分量的长度int uvLen = width / 2 * height / 2;memcpy((unsigned char *)y_ptr, yuv420, yLen);memcpy((unsigned char *)u_ptr, yuv420 + yLen, uvLen);memcpy((unsigned char *)v_ptr, yuv420 + yLen + uvLen, uvLen);
}
YUV420P转YUYV422
static void YUV420P_TO_YUYV422(uint8_t *yuv420p, void *y_ptr, void *u_ptr, void *v_ptr, int width, int height)
{AVFrame *Input_pFrame = nullptr;AVFrame *Output_pFrame = nullptr;struct SwsContext *img_convert_ctx = nullptr; //用于解码后的格式转换/*1. 申请空间*/Input_pFrame = av_frame_alloc();Output_pFrame = av_frame_alloc();/*2.设置转码参数*/img_convert_ctx =sws_getContext(width, height, AV_PIX_FMT_YUV420P, //输入width, height, AV_PIX_FMT_YUYV422, //输出SWS_BICUBIC, nullptr, nullptr, nullptr);int numBytes = avpicture_get_size(AV_PIX_FMT_YUYV422, width, height);//申请空间uint8_t *yuv422 = (uint8_t *)av_malloc(numBytes * sizeof(uint8_t));/*3. 申请转码需要空间*//*4. 设置转码的源数据地址*/avpicture_fill((AVPicture *)Input_pFrame, yuv420p, AV_PIX_FMT_YUV420P,width, height);avpicture_fill((AVPicture *)Output_pFrame, yuv422, AV_PIX_FMT_YUYV422,width, height);//转格式sws_scale(img_convert_ctx, (uint8_t const **)Input_pFrame->data,Input_pFrame->linesize, 0, height, Output_pFrame->data,Output_pFrame->linesize);//yuv422分量YUYV422Planes(yuv422, (uint8_t *)y_ptr, (uint8_t *)u_ptr,(uint8_t *)v_ptr, width, height);//释放空间if (Input_pFrame)av_free(Input_pFrame);if (Output_pFrame)av_free(Output_pFrame);if (yuv422)av_free(yuv422);if (img_convert_ctx)sws_freeContext(img_convert_ctx);
}
YUYV转YUV420P格式
static void YUYV422_TO_YUV420P(uint8_t *yuyv422, uint8_t *yuv420p, int video_width, int video_height)
{AVFrame *Input_pFrame = nullptr;AVFrame *Output_pFrame = nullptr;struct SwsContext *img_convert_ctx = nullptr; //用于解码后的格式转换/*1. 申请空间*/Input_pFrame = av_frame_alloc();Output_pFrame = av_frame_alloc();/*2.设置转码参数*/img_convert_ctx = sws_getContext(video_width, video_height, AV_PIX_FMT_YUYV422, //输入video_width, video_height, AV_PIX_FMT_YUV420P, //输出SWS_BICUBIC, nullptr, nullptr, nullptr);/*3. 申请转码需要空间*//*4. 设置转码的源数据地址*/avpicture_fill((AVPicture *)Input_pFrame, yuyv422, AV_PIX_FMT_YUYV422,video_width, video_height);avpicture_fill((AVPicture *)Output_pFrame, yuv420p, AV_PIX_FMT_YUV420P,video_width, video_height);//转格式sws_scale(img_convert_ctx, (uint8_t const **)Input_pFrame->data,Input_pFrame->linesize, 0, video_height, Output_pFrame->data,Output_pFrame->linesize);//释放空间if (Input_pFrame)av_free(Input_pFrame);if (Output_pFrame)av_free(Output_pFrame);if (img_convert_ctx)sws_freeContext(img_convert_ctx);
}