读取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;
}