#include "PL_AVFrameBGRA.h" #include "MaterialBuffer.h" #include "logger.h" extern "C" { #include #include #include } #include struct PL_AVFrameBGRA_Internal { 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)), lastFrame(), payError(true), config() { } ~PL_AVFrameBGRA_Internal() { } void reset() { buffSize = 0; payError = true; MB_Frame _lastFrame; lastFrame = _lastFrame; PL_AVFrameBGRA_Config _config; config = _config; } }; PipeLineElem* create_PL_AVFrameBGRA() { return new PL_AVFrameBGRA; } PL_AVFrameBGRA::PL_AVFrameBGRA() : internal(new PL_AVFrameBGRA_Internal) { } PL_AVFrameBGRA::~PL_AVFrameBGRA() { delete (PL_AVFrameBGRA_Internal*)internal; internal= nullptr; } bool PL_AVFrameBGRA::init(void* args) { 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; } void PL_AVFrameBGRA::finit() { PL_AVFrameBGRA_Internal* in = (PL_AVFrameBGRA_Internal*)internal; } bool PL_AVFrameBGRA::pay(const PipeMaterial& pm) { #define SUBSAMPLE(v, a) ((((v) + (a) - 1)) / (a)) PL_AVFrameBGRA_Internal* in = (PL_AVFrameBGRA_Internal*)internal; if (pm.type != PipeMaterial::PMT_FRAME) { LOG_ERROR << "Only support PMT_FRAME" << std::endl; return false; } 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 src_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 = 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.rgba", ++f); FILE * pFile = fopen (fname,"wb"); fwrite (in->buffer , sizeof(char), in->buffSize, pFile); fclose(pFile); return true; } bool PL_AVFrameBGRA::gain(PipeMaterial& pm) { PL_AVFrameBGRA_Internal* in = (PL_AVFrameBGRA_Internal*)internal; pm.type = PipeMaterial::PMT_FRAME; pm.buffer = &(in->lastFrame); pm.buffSize = 0; pm.former = this; return true; }