ffmpeg实现YUV420缩放

读取YUV文件,然后实现将YUV视频缩小,直接上code:


#include <stdio.h>
#include <unistd.h>
#include <libswscale/swscale.h>
#include <libavutil/frame.h>
#include <libavcodec/avcodec.h>

typedef struct{  
	unsigned int height;  
	unsigned int width;  
	unsigned long bufferSize;  
	unsigned char *bufferPtr;  
}ImgInfo;

int scale_one_img(ImgInfo *rawData, ImgInfo *resizedYuvData, uint8_t * m_pVideoOutput_ZoomBuf, int m_pVideoOutput_Zoomsize){
	int nSrcH = rawData->height;
	int nSrcW = rawData->width;

	int nDstH = resizedYuvData->height;
	int nDstW = resizedYuvData->width;

	AVFrame *p_input_frame = av_frame_alloc();
	AVFrame *p_output_frame = av_frame_alloc();

	avpicture_fill((AVPicture *)p_output_frame, (unsigned char *)m_pVideoOutput_ZoomBuf, AV_PIX_FMT_YUV420P, nDstW, nDstH);

	struct SwsContext* m_pSwsContext;
	m_pSwsContext = sws_getContext(nSrcW, nSrcH, AV_PIX_FMT_YUV420P, nDstW, nDstH, AV_PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL);  
	if (NULL == m_pSwsContext)   
	{  
		printf("ffmpeg get context error!\n");  
		return -1;  
	}

	avpicture_fill((AVPicture *)p_input_frame, rawData->bufferPtr, AV_PIX_FMT_YUV420P, nSrcW, nSrcH);
	sws_scale(m_pSwsContext, p_input_frame->data, p_input_frame->linesize, 0, nSrcH, p_output_frame->data, p_output_frame->linesize);  
	memcpy(resizedYuvData->bufferPtr, m_pVideoOutput_ZoomBuf, m_pVideoOutput_Zoomsize);
	sws_freeContext(m_pSwsContext);

	return m_pVideoOutput_Zoomsize;
}

FILE *init_file(char *file_name, char *mod){
	FILE *fp = fopen(file_name, mod);
	if(fp == NULL){
		printf("error when open file %s\n", file_name);
		exit(1);
	}
	return fp;
}

void close_file(FILE *fp){
	fclose(fp);
}

ImgInfo *img_init(int w, int h){
	ImgInfo *img = (ImgInfo *)malloc(sizeof(ImgInfo));
	img->height = h;
	img->width = w;
	img->bufferSize = w * h * 3 / 2;
	img->bufferPtr = (unsigned char *)malloc(img->bufferSize * 2);
	if(img->bufferPtr == NULL){
		printf("error when malloc for bufferPtr\n");
		exit(1);
	}
	return img;
}

void img_release(ImgInfo *img){
	free(img->bufferPtr);
	free(img);
}

int deal_one_file(){
	int nSrcW = 1280, nSrcH = 720;
	FILE *fp_input = init_file("input.yuv", "rb");
	ImgInfo *src_img = img_init(nSrcW, nSrcH);
	
	int nDstW = 320, nDstH = 240;
	FILE *fp_output = init_file("output.yuv", "wb");
	ImgInfo *dst_img = img_init(nDstW, nDstH);

	int num = 0;
	int ret;
	uint8_t * m_pVideoOutput_ZoomBuf = NULL;  
	int m_pVideoOutput_Zoomsize = 0;
	m_pVideoOutput_Zoomsize = avpicture_get_size(AV_PIX_FMT_YUV420P, nDstW, nDstH);  
	m_pVideoOutput_ZoomBuf =( uint8_t *)calloc(1, m_pVideoOutput_Zoomsize * 3 * sizeof(char)); //最大分配的空间,能满足yuv的各种格式  
	
	while(!feof(fp_input)){
		ret = fread(src_img->bufferPtr, 1, src_img->bufferSize, fp_input);
		if(ret < src_img->bufferSize){
			printf("read data over\n");
			break;
		}
		printf("read one frame num = %d\n", num++);
		ret = scale_one_img(src_img, dst_img, m_pVideoOutput_ZoomBuf, m_pVideoOutput_Zoomsize);
		fwrite(dst_img->bufferPtr, 1, ret, fp_output);
		if(num > 500){
			break;
		}
	}

	free(m_pVideoOutput_ZoomBuf);
	fclose(fp_input);
	fclose(fp_output);
	img_release(src_img);
	img_release(dst_img);
	return 1;
}

int main(){
	deal_one_file();
	return 1;
}


  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值