zoukankan      html  css  js  c++  java
  • GRAY8、YUV420P、YUV422P、YUV444P、YUYV422、RGB24间任意两个互转算法

    写在前面:本文参考雷神(雷霄骅)博文及资源,做部分修改,非常感谢雷神为图形图像、视频处理方面做出的杰出贡献!!!

    项目资源:https://download.csdn.net/download/y601500359/10585464 

    首先:需要初始化:sws_getContext。

    其次:1、当作为源数据src时,需要根据不同格式做相应处理:

    switch(src_pixfmt){
    		case AV_PIX_FMT_GRAY8:{
    			memcpy(src_data[0],temp_buffer,src_w*src_h);
    			break;
    							  }
    		case AV_PIX_FMT_YUV420P:{
    			memcpy(src_data[0],temp_buffer,src_w*src_h);                    //Y
    			memcpy(src_data[1],temp_buffer+src_w*src_h,src_w*src_h/4);      //U
    			memcpy(src_data[2],temp_buffer+src_w*src_h*5/4,src_w*src_h/4);  //V
    			break;
    								}
    		case AV_PIX_FMT_YUV422P:{
    			memcpy(src_data[0],temp_buffer,src_w*src_h);                    //Y
    			memcpy(src_data[1],temp_buffer+src_w*src_h,src_w*src_h/2);      //U
    			memcpy(src_data[2],temp_buffer+src_w*src_h*3/2,src_w*src_h/2);  //V
    			break;
    								}
    		case AV_PIX_FMT_YUV444P:{
    			memcpy(src_data[0],temp_buffer,src_w*src_h);                    //Y
    			memcpy(src_data[1],temp_buffer+src_w*src_h,src_w*src_h);        //U
    			memcpy(src_data[2],temp_buffer+src_w*src_h*2,src_w*src_h);      //V
    			break;
    								}
    		case AV_PIX_FMT_YUYV422:{
    			memcpy(src_data[0],temp_buffer,src_w*src_h*2);                  //Packed
    			break;
    								}
    		case AV_PIX_FMT_RGB24:{
    			memcpy(src_data[0],temp_buffer,src_w*src_h*3);                  //Packed
    			break;
    								}
    		default:{
    			printf("Not Support Input Pixel Format.
    ");
    			break;
    							  }
    		}

    再次:开始转换:sws_scale

    最后:当作为目的数据时dst时:

    switch(dst_pixfmt){
    		case AV_PIX_FMT_GRAY8:{
    			fwrite(dst_data[0],1,dst_w*dst_h,dst_file);	
    			break;
    							  }
    		case AV_PIX_FMT_YUV420P:{
    			fwrite(dst_data[0],1,dst_w*dst_h,dst_file);                 //Y
    			fwrite(dst_data[1],1,dst_w*dst_h/4,dst_file);               //U
    			fwrite(dst_data[2],1,dst_w*dst_h/4,dst_file);               //V
    			break;
    								}
    		case AV_PIX_FMT_YUV422P:{
    			fwrite(dst_data[0],1,dst_w*dst_h,dst_file);					//Y
    			fwrite(dst_data[1],1,dst_w*dst_h/2,dst_file);				//U
    			fwrite(dst_data[2],1,dst_w*dst_h/2,dst_file);				//V
    			break;
    								}
    		case AV_PIX_FMT_YUV444P:{
    			fwrite(dst_data[0],1,dst_w*dst_h,dst_file);                 //Y
    			fwrite(dst_data[1],1,dst_w*dst_h,dst_file);                 //U
    			fwrite(dst_data[2],1,dst_w*dst_h,dst_file);                 //V
    			break;
    								}
    		case AV_PIX_FMT_YUYV422:{
    			fwrite(dst_data[0],1,dst_w*dst_h*2,dst_file);               //Packed
    			break;
    								}
    		case AV_PIX_FMT_RGB24:{
    			fwrite(dst_data[0],1,dst_w*dst_h*3,dst_file);               //Packed
    			break;
    							  }
    		default:{
    			printf("Not Support Output Pixel Format.
    ");
    			break;
    							}
    		}

    完整代码:

    /**
     * 最简单的基于FFmpeg的Swscale示例
     * Simplest FFmpeg Swscale
     *
     * 雷霄骅 Lei Xiaohua
     * leixiaohua1020@126.com
     * 中国传媒大学/数字电视技术
     * Communication University of China / Digital TV Technology
     * http://blog.csdn.net/leixiaohua1020
     *
     * 本程序使用libswscale对像素数据进行缩放转换等处理。
     * 它中实现了YUV420P格式转换为RGB24格式,
     * 同时将分辨率从480x272拉伸为1280x720
     * 它是最简单的libswscale的教程。
     *
     * This software uses libswscale to scale / convert pixels.
     * It convert YUV420P format to RGB24 format,
     * and changes resolution from 480x272 to 1280x720.
     * It's the simplest tutorial about libswscale.
     */
    
    #include <stdio.h>
    
    #define __STDC_CONSTANT_MACROS
    
    #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 <libswscale/swscale.h>
    #include <libavutil/opt.h>
    #include <libavutil/imgutils.h>
    #ifdef __cplusplus
    };
    #endif
    #endif
    
    
    #include<Windows.h>
    int main(int argc, char* argv[])
    {
    	//Parameters	
    // 	FILE *src_file =fopen("sintel_480x272_yuv420p.yuv", "rb");
    // 	const int src_w = 480, src_h = 272;
    //	AVPixelFormat src_pixfmt = AV_PIX_FMT_YUV420P;
    	FILE *src_file = fopen("sintel_1280x720_rgb24.rgb", "rb");
    	const int src_w=1280,src_h=720;
    	AVPixelFormat src_pixfmt= AV_PIX_FMT_RGB24;
    
    	int src_bpp=av_get_bits_per_pixel(av_pix_fmt_desc_get(src_pixfmt));
    
    // 	FILE *dst_file = fopen("sintel_1280x720_rgb24.rgb", "wb");
    // 	const int dst_w = 1280, dst_h = 720;
    //	AVPixelFormat dst_pixfmt = AV_PIX_FMT_RGB24;
    	FILE *dst_file = fopen("sintel000_1280x720_yuv420p.yuv", "wb");
    	const int dst_w=1280,dst_h=720;
    	AVPixelFormat dst_pixfmt = AV_PIX_FMT_YUV420P;
    	int dst_bpp=av_get_bits_per_pixel(av_pix_fmt_desc_get(dst_pixfmt));
    
    	//Structures
    	uint8_t *src_data[4];
    	int src_linesize[4];
    
    	uint8_t *dst_data[4];
    	int dst_linesize[4];
    
    	int rescale_method=SWS_BICUBIC;
    	struct SwsContext *img_convert_ctx;
    	uint8_t *temp_buffer=(uint8_t *)malloc(src_w*src_h*src_bpp/8);
    	
    	int frame_idx=0;
    	int ret=0;
    	ret= av_image_alloc(src_data, src_linesize,src_w, src_h, src_pixfmt, 1);
    	if (ret< 0) {
    		printf( "Could not allocate source image
    ");
    		return -1;
    	}
    	ret = av_image_alloc(dst_data, dst_linesize,dst_w, dst_h, dst_pixfmt, 1);
    	if (ret< 0) {
    		printf( "Could not allocate destination image
    ");
    		return -1;
    	}
    	//-----------------------------	
    	//Init Method 1
    // 	img_convert_ctx =sws_alloc_context();
    // 	//Show AVOption
    // 	av_opt_show2(img_convert_ctx,stdout,AV_OPT_FLAG_VIDEO_PARAM,0);
    // 	//Set Value
    // 	av_opt_set_int(img_convert_ctx,"sws_flags",SWS_BICUBIC|SWS_PRINT_INFO,0);
    // 	av_opt_set_int(img_convert_ctx,"srcw",src_w,0);
    // 	av_opt_set_int(img_convert_ctx,"srch",src_h,0);
    // 	av_opt_set_int(img_convert_ctx,"src_format",src_pixfmt,0);
    // 	//'0' for MPEG (Y:0-235);'1' for JPEG (Y:0-255)
    // 	av_opt_set_int(img_convert_ctx,"src_range",1,0);
    // 	av_opt_set_int(img_convert_ctx,"dstw",dst_w,0);
    // 	av_opt_set_int(img_convert_ctx,"dsth",dst_h,0);
    // 	av_opt_set_int(img_convert_ctx,"dst_format",dst_pixfmt,0);
    // 	av_opt_set_int(img_convert_ctx,"dst_range",1,0);
    // 	sws_init_context(img_convert_ctx,NULL,NULL);
    
    	//Init Method 2
    	img_convert_ctx = sws_getContext(src_w, src_h,src_pixfmt, dst_w, dst_h, dst_pixfmt, 
    		rescale_method, NULL, NULL, NULL); 
    	//-----------------------------
    	/*
    	//Colorspace
    	ret=sws_setColorspaceDetails(img_convert_ctx,sws_getCoefficients(SWS_CS_ITU601),0,
    		sws_getCoefficients(SWS_CS_ITU709),0,
    		 0, 1 << 16, 1 << 16);
    	if (ret==-1) {
    		printf( "Colorspace not support.
    ");
    		return -1;
    	}
    	*/
    
    	DWORD start_time = GetTickCount();
    	DWORD end_time = GetTickCount();
    	DWORD dCount = 0;
    	char str[512];
    
    	while(1)
    	{
    		if (fread(temp_buffer, 1, src_w*src_h*src_bpp/8, src_file) != src_w*src_h*src_bpp/8){
    			break;
    		}
    		
    		switch(src_pixfmt){
    		case AV_PIX_FMT_GRAY8:{
    			memcpy(src_data[0],temp_buffer,src_w*src_h);
    			break;
    							  }
    		case AV_PIX_FMT_YUV420P:{
    			memcpy(src_data[0],temp_buffer,src_w*src_h);                    //Y
    			memcpy(src_data[1],temp_buffer+src_w*src_h,src_w*src_h/4);      //U
    			memcpy(src_data[2],temp_buffer+src_w*src_h*5/4,src_w*src_h/4);  //V
    			break;
    								}
    		case AV_PIX_FMT_YUV422P:{
    			memcpy(src_data[0],temp_buffer,src_w*src_h);                    //Y
    			memcpy(src_data[1],temp_buffer+src_w*src_h,src_w*src_h/2);      //U
    			memcpy(src_data[2],temp_buffer+src_w*src_h*3/2,src_w*src_h/2);  //V
    			break;
    								}
    		case AV_PIX_FMT_YUV444P:{
    			memcpy(src_data[0],temp_buffer,src_w*src_h);                    //Y
    			memcpy(src_data[1],temp_buffer+src_w*src_h,src_w*src_h);        //U
    			memcpy(src_data[2],temp_buffer+src_w*src_h*2,src_w*src_h);      //V
    			break;
    								}
    		case AV_PIX_FMT_YUYV422:{
    			memcpy(src_data[0],temp_buffer,src_w*src_h*2);                  //Packed
    			break;
    								}
    		case AV_PIX_FMT_RGB24:{
    			memcpy(src_data[0],temp_buffer,src_w*src_h*3);                  //Packed
    			break;
    								}
    		default:{
    			printf("Not Support Input Pixel Format.
    ");
    			break;
    							  }
    		}
    		start_time = GetTickCount();
    		sws_scale(img_convert_ctx, src_data, src_linesize, 0, src_h, dst_data, dst_linesize);
    
    		end_time = GetTickCount();
    		dCount = end_time - start_time;
    		sprintf_s(str, "********ImageProcessing********1111111**********************the run time is: %d 
    ", dCount);
    		OutputDebugStringA(str);
    		start_time = GetTickCount();
    
    		printf("Finish process frame %5d
    ",frame_idx);
    		frame_idx++;
    
    		switch(dst_pixfmt){
    		case AV_PIX_FMT_GRAY8:{
    			fwrite(dst_data[0],1,dst_w*dst_h,dst_file);	
    			break;
    							  }
    		case AV_PIX_FMT_YUV420P:{
    			fwrite(dst_data[0],1,dst_w*dst_h,dst_file);                 //Y
    			fwrite(dst_data[1],1,dst_w*dst_h/4,dst_file);               //U
    			fwrite(dst_data[2],1,dst_w*dst_h/4,dst_file);               //V
    			break;
    								}
    		case AV_PIX_FMT_YUV422P:{
    			fwrite(dst_data[0],1,dst_w*dst_h,dst_file);					//Y
    			fwrite(dst_data[1],1,dst_w*dst_h/2,dst_file);				//U
    			fwrite(dst_data[2],1,dst_w*dst_h/2,dst_file);				//V
    			break;
    								}
    		case AV_PIX_FMT_YUV444P:{
    			fwrite(dst_data[0],1,dst_w*dst_h,dst_file);                 //Y
    			fwrite(dst_data[1],1,dst_w*dst_h,dst_file);                 //U
    			fwrite(dst_data[2],1,dst_w*dst_h,dst_file);                 //V
    			break;
    								}
    		case AV_PIX_FMT_YUYV422:{
    			fwrite(dst_data[0],1,dst_w*dst_h*2,dst_file);               //Packed
    			break;
    								}
    		case AV_PIX_FMT_RGB24:{
    			fwrite(dst_data[0],1,dst_w*dst_h*3,dst_file);               //Packed
    			break;
    							  }
    		default:{
    			printf("Not Support Output Pixel Format.
    ");
    			break;
    							}
    		}
    	}
    
    	sws_freeContext(img_convert_ctx);
    
    	free(temp_buffer);
    	fclose(dst_file);
    	av_freep(&src_data[0]);
    	av_freep(&dst_data[0]);
    
    	return 0;
    }
    
    
  • 相关阅读:
    如何对Web Part进行调试 cloud
    相见恨晚的68句话,来给大家分享分享……(转载) cloud
    基于python的邮件地址提取小程序
    php.ini 核心配置选项说明
    Snort2.8.1在Windows上的简单使用
    在Visual Studio 2008中编译snort2.8.6.1.tar.gz
    PyDev for Eclipse 简介
    Python中*和**的用法
    Python实现类似switch...case功能
    ubuntu安装mysql多实例
  • 原文地址:https://www.cnblogs.com/SunkingYang/p/11049110.html
Copyright © 2011-2022 走看看