1. 程式人生 > >FFmpeg 4.0.2 實現YUV檔案scale大小變換

FFmpeg 4.0.2 實現YUV檔案scale大小變換

/*
 * 功能:實現YUV檔案scale大小變換
 * FFmpeg:4.0.2
*/
#include <iostream>
extern "C"
{
#include <libswscale/swscale.h>
#include <libavutil/frame.h>
#include <libavcodec/avcodec.h>
#include <libavutil/imgutils.h>
};
using namespace std;

int YUVFileScale(const char *srcYUV, int nSrcW, int
nSrcH, const char *dstYUV, int nDstW, int nDstH) { // 初始化輸入原始檔 FILE *fp_input = NULL; fopen_s(&fp_input, srcYUV, "rb"); if (fp_input == NULL) { cout << "error when open file input.yuv" << endl; return -1; } // 初始化輸出目標檔案 FILE *fp_output = NULL; fopen_s(&fp_output, dstYUV, "wb"
); if (fp_output == NULL) { cout << "error when open file output.yuv" << endl; return -1; } // 源緩衝區 int src_bufferSize = nSrcW * nSrcH * 3 / 2; uint8_t *src_bufferPtr = (uint8_t *)malloc(src_bufferSize * 2); if (src_bufferPtr == NULL) { cout
<< "error when malloc for src_bufferPtr" << endl; return -1; } // 目標緩衝區 int dst_bufferSize = nDstW * nDstH * 3 / 2; uint8_t *dst_bufferPtr = (uint8_t *)malloc(dst_bufferSize * 2); if (dst_bufferPtr == NULL) { cout << "error when malloc for dst_bufferPtr" << endl; return -1; } // 分配空間 int m_pVideoOutput_Zoomsize = av_image_get_buffer_size(AV_PIX_FMT_YUV420P, nDstW, nDstH, 1); uint8_t *m_pVideoOutput_ZoomBuf = (uint8_t *)malloc(m_pVideoOutput_Zoomsize * 3 * sizeof(char)); //最大分配的空間,能滿足yuv的各種格式 // 迴圈讀取YUV檔案中的每一幀 // YUV scale大小變換 int num = 1; while (!feof(fp_input)) { int ret = fread(src_bufferPtr, 1, src_bufferSize, fp_input); if (ret < src_bufferSize) { cout << "read data over" << endl; break; } cout << "read one frame num = " << num++ << endl; //------------ scale變換 ------------------------------------------------------------------------------------------------------------------------------ AVFrame *p_input_frame = av_frame_alloc(); av_image_fill_arrays(p_input_frame->data, p_input_frame->linesize, src_bufferPtr, AV_PIX_FMT_YUV420P, nSrcW, nSrcH, 1); AVFrame *p_output_frame = av_frame_alloc(); av_image_fill_arrays(p_output_frame->data, p_output_frame->linesize, m_pVideoOutput_ZoomBuf, AV_PIX_FMT_YUV420P, nDstW, nDstH, 1); struct SwsContext* 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) { cout << "ffmpeg get context error!" << endl; return -1; } sws_scale(m_pSwsContext, p_input_frame->data, p_input_frame->linesize, 0, nSrcH, p_output_frame->data, p_output_frame->linesize); sws_freeContext(m_pSwsContext); memcpy(dst_bufferPtr, m_pVideoOutput_ZoomBuf, m_pVideoOutput_Zoomsize); //----------------------------------------------------------------------------------------------------------------------------------------------------- fwrite(dst_bufferPtr, 1, m_pVideoOutput_Zoomsize, fp_output); if (num > 500) break; } // 釋放記憶體 free(m_pVideoOutput_ZoomBuf); fclose(fp_input); fclose(fp_output); free(src_bufferPtr); free(dst_bufferPtr); return 1; } int main() { const char *srcYUV = "input.yuv"; int nSrcW = 352, nSrcH = 288; const char *dstYUV = "output.yuv"; int nDstW = 640, nDstH = 480; YUVFileScale(srcYUV, nSrcW, nSrcH, dstYUV, nDstW, nDstH); return getchar(); }