From 109ffe9a777658936a38d0c146579a67c60a0d17 Mon Sep 17 00:00:00 2001 From: xuxiuxi <xuxiuxi@454eff88-639b-444f-9e54-f578c98de674> Date: 星期四, 11 五月 2017 17:48:48 +0800 Subject: [PATCH] --- RtspFace/PL_AVFrameBGRA.cpp | 144 ++++++++++++++++++++++++++++++++++++++++------- 1 files changed, 122 insertions(+), 22 deletions(-) diff --git a/RtspFace/PL_AVFrameBGRA.cpp b/RtspFace/PL_AVFrameBGRA.cpp index 9329f14..8e333ce 100644 --- a/RtspFace/PL_AVFrameBGRA.cpp +++ b/RtspFace/PL_AVFrameBGRA.cpp @@ -1,25 +1,31 @@ #include "PL_AVFrameBGRA.h" +#include "MaterialBuffer.h" +#include "logger.h" extern "C" { #include <libavcodec/avcodec.h> #include <libavutil/frame.h> #include <libavformat/avformat.h> - - #include <libyuv.h> } + +#include <libyuv.h> struct PL_AVFrameBGRA_Internal { - uint8_t buffer[1920*1080*4]; + uint8_t buffer[1920*1080*4];//#todo from config size_t buffSize; size_t buffSizeMax; + MB_Frame lastFrame; bool payError; + PL_AVFrameBGRA_Config config; + PL_AVFrameBGRA_Internal() : - buffSize(0), buffSizeMax(sizeof(buffer)), - payError(true) + buffSize(0), buffSizeMax(sizeof(buffer)), lastFrame(), + payError(true), + config() { } @@ -31,6 +37,12 @@ { buffSize = 0; payError = true; + + MB_Frame _lastFrame; + lastFrame = _lastFrame; + + PL_AVFrameBGRA_Config _config; + config = _config; } }; @@ -53,6 +65,12 @@ { PL_AVFrameBGRA_Internal* in = (PL_AVFrameBGRA_Internal*)internal; in->reset(); + + if (args != nullptr) + { + PL_AVFrameBGRA_Config* _config = (PL_AVFrameBGRA_Config*)args; + in->config = *_config; + } return true; } @@ -63,37 +81,118 @@ } -#define SUBSAMPLE(v, a) ((((v) + (a) - 1)) / (a)) - bool PL_AVFrameBGRA::pay(const PipeMaterial& pm) { +#define SUBSAMPLE(v, a) ((((v) + (a) - 1)) / (a)) + PL_AVFrameBGRA_Internal* in = (PL_AVFrameBGRA_Internal*)internal; - AVFrame* pAVFrame = (AVFrame*)pm.buffer; - if (pAVFrame == nullptr) + if (pm.type != PipeMaterial::PMT_FRAME) + { + LOG_ERROR << "Only support PMT_FRAME" << std::endl; return false; - - int height = pAVFrame->height; - int width = pAVFrame->width; + } + + if (pm.buffer == nullptr) + return false; + + int src_height = 0; + int src_width = 0; + const uint8* src_y = nullptr; + const uint8* src_u = nullptr; + const uint8* src_v = nullptr; + + MB_Frame* frame = (MB_Frame*)pm.buffer; + if (frame->type == MB_Frame::MBFT_PTR_AVFRAME) + { + AVFrame* pAVFrame = (AVFrame*)frame->buffer; + if (pAVFrame == nullptr) + return false; + + src_height = pAVFrame->height; + src_width = pAVFrame->width; + + src_y = pAVFrame->data[0]; + src_u = pAVFrame->data[1]; + src_v = pAVFrame->data[2]; + } + if (frame->type == MB_Frame::MBFT_YUV420) + { + if (frame->buffer == nullptr) + return false; + + src_height = frame->height; + src_width = frame->width; + + src_y = (const uint8*)(frame->buffer); + src_u = (const uint8*)(src_y + (src_height * src_width)); + src_v = (const uint8*)(src_u + (src_height * src_width / 4)); + } + else + { + LOG_ERROR << "Only support MBFT_PTR_AVFRAME" << std::endl; + return false; + } //int I420ToBGRA(const uint8* src_y, int src_stride_y, // const uint8* src_u, int src_stride_u, // const uint8* src_v, int src_stride_v, // uint8* dst_argb, int dst_stride_argb, -// int width, int height); +// int width, int src_height); - libyuv::I420ToBGRA(pAVFrame->data[0], width, - pAVFrame->data[1], SUBSAMPLE(width, 2), - pAVFrame->data[2], SUBSAMPLE(width, 2), - in->buffer, 4 * width, - width, height); + if (in->config.convertTo == PL_AVFrameBGRA_Config::I420_TO_BGRA8888) + { + libyuv::I420ToBGRA(src_y, src_width, + src_u, SUBSAMPLE(src_width, 2), + src_v, SUBSAMPLE(src_width, 2), + in->buffer, 4 * src_width, + src_width, src_height); - in->buffSize = in->buffSizeMax; + in->buffSize = src_width * src_height * 4; // #todo use ret value? + } + else if (in->config.convertTo == PL_AVFrameBGRA_Config::I420_TO_ARGB8888) + { + libyuv::I420ToARGB(src_y, src_width, + src_u, SUBSAMPLE(src_width, 2), + src_v, SUBSAMPLE(src_width, 2), + in->buffer, 4 * src_width, + src_width, src_height); + + in->buffSize = src_width * src_height * 4; // #todo use ret value? + } + else if (in->config.convertTo == PL_AVFrameBGRA_Config::I420_TO_RGBA8888) + { + libyuv::I420ToRGBA(src_y, src_width, + src_u, SUBSAMPLE(src_width, 2), + src_v, SUBSAMPLE(src_width, 2), + in->buffer, 4 * src_width, + src_width, src_height); + + in->buffSize = src_width * src_height * 4; // #todo use ret value? + } + else if (in->config.convertTo == PL_AVFrameBGRA_Config::I420_TO_ARGB4444) + { + + } + else + { + LOG_ERROR << "PL_AVFrameBGRA_Config.convertTo not support" << std::endl; + return false; + } + //in->buffer readly + + in->lastFrame.type = MB_Frame::MBFT_BGRA; + in->lastFrame.buffer = in->buffer; + in->lastFrame.buffSize = in->buffSize; + in->lastFrame.width = src_width; + in->lastFrame.height = src_height; + in->lastFrame.pts = frame->pts; + //#test static size_t f=0; char fname[50]; - sprintf(fname, "%u.bgra", ++f); + sprintf(fname, "%u.rgba", ++f); FILE * pFile = fopen (fname,"wb"); fwrite (in->buffer , sizeof(char), in->buffSize, pFile); fclose(pFile); @@ -105,8 +204,9 @@ { PL_AVFrameBGRA_Internal* in = (PL_AVFrameBGRA_Internal*)internal; - pm.buffer = in->buffer; - pm.buffSize = in->buffSize; + pm.type = PipeMaterial::PMT_FRAME; + pm.buffer = &(in->lastFrame); + pm.buffSize = 0; pm.former = this; return true; } -- Gitblit v1.8.0