Qt 集成 FFmpeg 实现颜色格式转换( 二 )


在.cpp 中调用了的逻辑:
#include "qtffmpegutils.h"#include #include QtFFmpegUtils::QtFFmpegUtils(){}int QtFFmpegUtils::convertRawVideo(RawVideoFile &in, RawVideoFile &out){int ret = APP_SUCCESS;SwsContext *ctx = nullptr;uint8_t *inData[4], *outData[4];int inStrides[4], outStrides[4];int inFrameSize, outFrameSize;QFile inFile(in.filename);QFile outFile(out.filename);ret = av_image_alloc(inData, inStrides, in.width, in.height, in.format, 1);if(ret < 0){char errbuf[1024];av_strerror(ret,errbuf,sizeof (errbuf));qDebug() << "av_image_alloc inData error:" << errbuf;ret = APP_FFMPEG_ALLOC_FAILED;goto alloc_failed_1;}ret = av_image_alloc(outData, outStrides, out.width, out.height, out.format, 1);if (ret < 0) {char errbuf[1024];av_strerror(ret, errbuf, sizeof (errbuf));qDebug() << "av_image_alloc outData error:" << errbuf;ret = APP_FFMPEG_ALLOC_FAILED;goto alloc_failed_2;}ret = APP_SUCCESS;ctx = sws_getContext(in.width, in.height, in.format,out.width, out.height, out.format,SWS_BILINEAR, nullptr, nullptr, nullptr);if (!ctx) {qDebug() << "sws_getContext error";ret = APP_FFMPEG_SWS_GETCTX_FAILED;goto get_ctx_failed;}if (!inFile.open(QFile::ReadOnly)) {qDebug() << "open in file failure";ret = APP_OPENFILE_FAILED;goto in_file_open_falied;}if (!outFile.open(QFile::WriteOnly)) {qDebug() << "open out file failure";ret = APP_OPENFILE_FAILED;goto out_file_open_failed;}inFrameSize= av_image_get_buffer_size(in.format, in.width, in.height, 1);outFrameSize = av_image_get_buffer_size(out.format, out.width, out.height, 1);while (inFile.read((char *)inData[0], inFrameSize) == inFrameSize) {sws_scale(ctx, inData, inStrides, 0, in.height, outData, outStrides);outFile.write((char *)outData[0], outFrameSize);}outFile.close();out_file_open_failed:inFile.close();in_file_open_falied:sws_freeContext(ctx);get_ctx_failed:av_freep(&outData[0]);alloc_failed_2:av_freep(&inData[0]);alloc_failed_1:return ret;}int QtFFmpegUtils::convertToRGB888(RawVideoFile &in, uint8_t *rgb888_data){int ret = APP_SUCCESS;SwsContext *ctx = nullptr;uint8_t *inData[4], *outData[4];int inStrides[4], outStrides[4];int inFrameSize, outFrameSize;QFile inFile(in.filename);ret = av_image_alloc(inData, inStrides, in.width, in.height, in.format, 1);if(ret < 0){char errbuf[1024];av_strerror(ret,errbuf,sizeof (errbuf));qDebug() << "av_image_alloc inData error:" << errbuf;ret = APP_FFMPEG_ALLOC_FAILED;goto alloc_failed_1;}ret = av_image_alloc(outData, outStrides, in.width, in.height, AV_PIX_FMT_RGB24, 1);if (ret < 0) {char errbuf[1024];av_strerror(ret, errbuf, sizeof (errbuf));qDebug() << "av_image_alloc outData error:" << errbuf;ret = APP_FFMPEG_ALLOC_FAILED;goto alloc_failed_2;}ret = APP_SUCCESS;ctx = sws_getContext(in.width, in.height, in.format,in.width, in.height, AV_PIX_FMT_RGB24,SWS_BILINEAR, nullptr, nullptr, nullptr);if (!ctx) {qDebug() << "sws_getContext error";ret = APP_FFMPEG_SWS_GETCTX_FAILED;goto get_ctx_failed;}if (!inFile.open(QFile::ReadOnly)) {qDebug() << "open in file failure";ret = APP_OPENFILE_FAILED;goto in_file_open_falied;}inFrameSize= av_image_get_buffer_size(in.format, in.width, in.height, 1);outFrameSize = av_image_get_buffer_size(AV_PIX_FMT_RGB24, in.width, in.height, 1);if (inFile.read((char *)inData[0], inFrameSize) == inFrameSize) {sws_scale(ctx, inData, inStrides, 0, in.height, outData, outStrides);memcpy(rgb888_data, outData[0], outFrameSize);}else {qDebug("Read not finished");ret = APP_READ_FILE_NOT_FINISHED;}inFile.close();in_file_open_falied:sws_freeContext(ctx);get_ctx_failed:av_freep(&outData[0]);alloc_failed_2:av_freep(&inData[0]);alloc_failed_1:return ret;}int QtFFmpegUtils::getBufferSize(AVPixelFormat pix_fmt, int width, int height){return av_image_get_buffer_size(pix_fmt, width, height, 1);}
3. 预览
代码中,使用一个作为预览输入输出的图片,.h 定义如下:
#ifndef MAINWINDOW_H#define MAINWINDOW_H#include #include // ffmpeg headerextern "C" {#include