From f04b2e05a32f810ebe66b7b3a15f37b532ce2dc0 Mon Sep 17 00:00:00 2001 From: houxiao <houxiao@454eff88-639b-444f-9e54-f578c98de674> Date: 星期四, 22 十二月 2016 17:27:31 +0800 Subject: [PATCH] add pl emements --- RtspFace/PL_AVFrameBGRA.h | 24 ++++ RtspFace/make.sh | 12 + RtspFace/PL_H264Decoder.cpp | 67 +++------- RtspFace/main.cpp | 8 RtspFace/PL_AVFrameBGRA.cpp | 115 +++++++++++++++++++ RtspFace/PL_AVFrameYUV420.cpp | 96 ++++++++------- RtspFace/PipeLine.cpp | 24 ++- 7 files changed, 243 insertions(+), 103 deletions(-) diff --git a/RtspFace/PL_AVFrameBGRA.cpp b/RtspFace/PL_AVFrameBGRA.cpp new file mode 100644 index 0000000..e59a8a7 --- /dev/null +++ b/RtspFace/PL_AVFrameBGRA.cpp @@ -0,0 +1,115 @@ +#include "PL_AVFrameBGRA.h" + +extern "C" +{ + #include <libavcodec/avcodec.h> + #include <libavutil/frame.h> + #include <libavformat/avformat.h> + + #include <libyuv.h> +} + +struct PL_AVFrameBGRA_Internal +{ + uint8_t buffer[1920*1080*4]; + size_t buffSize; + size_t buffSizeMax; + + AVFormatContext* pAVFormatContext;//#todo delete + bool payError; + + PL_AVFrameBGRA_Internal() : + buffSize(0), buffSizeMax(sizeof(buffer)), + pAVFormatContext(nullptr), payError(true) + { + } + + ~PL_AVFrameBGRA_Internal() + { + } + + void reset() + { + buffSize = 0; + payError = true; + } +}; + +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(); + + in->pAVFormatContext = avformat_alloc_context(); + + return true; +} + +void PL_AVFrameBGRA::finit() +{ + PL_AVFrameBGRA_Internal* in = (PL_AVFrameBGRA_Internal*)internal; + +} + +#define SUBSAMPLE(v, a) ((((v) + (a) - 1)) / (a)) + +bool PL_AVFrameBGRA::pay(const PipeMaterial& pm) +{ + PL_AVFrameBGRA_Internal* in = (PL_AVFrameBGRA_Internal*)internal; + + AVFrame* pAVFrame = (AVFrame*)pm.buffer; + if (pAVFrame == nullptr) + return false; + + int height = pAVFrame->height; + int width = pAVFrame->width; + +//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); + + libyuv::I420ToBGRA(pAVFrame->data[0], width, + pAVFrame->data[1], SUBSAMPLE(width, 2), + pAVFrame->data[2], SUBSAMPLE(width, 2), + in->buffer, 4 * width, + width, height); + + in->buffSize = in->buffSizeMax; + //in->buffer readly + + static size_t f=0; + char fname[50]; + sprintf(fname, "%u.bgra", ++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.buffer = in->buffer; + pm.buffSize = in->buffSize; + pm.former = this; + return true; +} diff --git a/RtspFace/PL_AVFrameBGRA.h b/RtspFace/PL_AVFrameBGRA.h new file mode 100644 index 0000000..19c1381 --- /dev/null +++ b/RtspFace/PL_AVFrameBGRA.h @@ -0,0 +1,24 @@ +#ifndef _PL_PL_AVFrameBGRA_H_ +#define _PL_PL_AVFrameBGRA_H_ + +#include "PipeLine.h" + +class PL_AVFrameBGRA : public PipeLineElem +{ +public: + PL_AVFrameBGRA(); + virtual ~PL_AVFrameBGRA(); + + virtual bool init(void* args); + virtual void finit(); + + virtual bool pay(const PipeMaterial& pm); + virtual bool gain(PipeMaterial& pm); + +private: + void* internal; +}; + +PipeLineElem* create_PL_AVFrameBGRA(); + +#endif diff --git a/RtspFace/PL_AVFrameYUV420.cpp b/RtspFace/PL_AVFrameYUV420.cpp index 5927ce5..1384218 100644 --- a/RtspFace/PL_AVFrameYUV420.cpp +++ b/RtspFace/PL_AVFrameYUV420.cpp @@ -12,11 +12,9 @@ uint8_t buffer[1920*1080*3]; size_t buffSize; size_t buffSizeMax; - bool payError; AVFrameYUV420_Internal() : - buffSize(0), buffSizeMax(sizeof(buffer)), - payError(false) + buffSize(0), buffSizeMax(sizeof(buffer)) { } @@ -27,7 +25,6 @@ void reset() { buffSize = 0; - payError = false; } }; @@ -64,52 +61,65 @@ { AVFrameYUV420_Internal* in = (AVFrameYUV420_Internal*)internal; - int picSize = in->pAVCodecContext->height * in->pAVCodecContext->width; - in->buffSize = picSize * 1.5; - - int height = in->pAVFrame->height; - int width = in->pAVFrame->width; - - // write yuv420 - int a=0; - for (int i = 0; i < height; i++) - { - memcpy(in->buffer + a, in->pAVFrame->data[0] + i * in->pAVFrame->linesize[0], width); - a += width; - } - for (int i=0; i<height/2; i++) - { - memcpy(in->buffer + a, in->pAVFrame->data[1] + i * in->pAVFrame->linesize[1], width / 2); - a += width / 2; - } - for (int i=0; i<height/2; i++) - { - memcpy(in->buffer + a, in->pAVFrame->data[2] + i * in->pAVFrame->linesize[2], width / 2); - a += width / 2; - } - - //in->buffer readly - - //static size_t f=0; - //char fname[50]; - //sprintf(fname, "%u.yuv420", ++f); - //FILE * pFile = fopen (fname,"wb"); - //fwrite (in->buffer , sizeof(char), in->buffSize, pFile); - //fclose(pFile); + AVFrame* pAVFrame = (AVFrame*)pm.buffer; + if (pAVFrame == nullptr) + return false; + int picSize = pAVFrame->height * pAVFrame->width; + in->buffSize = picSize * 1.5; + + int height = pAVFrame->height; + int width = pAVFrame->width; + + uint8_t* pBuff = in->buffer; - return in->payError; + memcpy(pBuff, pAVFrame->data[0], height * width); + pBuff += height * width; + + memcpy(pBuff, pAVFrame->data[1], height * width / 4); + pBuff += height * width / 4; + + memcpy(pBuff, pAVFrame->data[2], height * width / 4); + pBuff += height * width / 4; + + in->buffSize = pBuff - in->buffer; + + // write yuv420 + //int a=0; + //for (int i = 0; i < height; i++) + //{ + // memcpy(in->buffer + a, pAVFrame->data[0] + i * pAVFrame->linesize[0], width); + // a += width; + //} + //for (int i=0; i<height/2; i++) + //{ + // memcpy(in->buffer + a, pAVFrame->data[1] + i * pAVFrame->linesize[1], width / 2); + // a += width / 2;//#todo 4 + //} + //for (int i=0; i<height/2; i++) + //{ + // memcpy(in->buffer + a, pAVFrame->data[2] + i * pAVFrame->linesize[2], width / 2); + // a += width / 2; + //} + + //in->buffer readly + + //static size_t f=0; + //char fname[50]; + //sprintf(fname, "%u.yuv420", ++f); + //FILE * pFile = fopen (fname,"wb"); + //fwrite (in->buffer , sizeof(char), in->buffSize, pFile); + //fclose(pFile); + + return true; } bool PL_AVFrameYUV420::gain(PipeMaterial& pm) { AVFrameYUV420_Internal* in = (AVFrameYUV420_Internal*)internal; - if (!in->payError) - { - pm.buffer = in->buffer; - pm.buffSize = in->buffSize; - } + pm.buffer = in->buffer; + pm.buffSize = in->buffSize; pm.former = this; - return in->payError; + return true; } diff --git a/RtspFace/PL_H264Decoder.cpp b/RtspFace/PL_H264Decoder.cpp index b27918c..9f51b43 100644 --- a/RtspFace/PL_H264Decoder.cpp +++ b/RtspFace/PL_H264Decoder.cpp @@ -12,18 +12,19 @@ struct H264Decoder_Internal { - uint8_t buffer[1920*1080*3]; - size_t buffSize; - size_t buffSizeMax; + //uint8_t buffer[1920*1080*3]; + //size_t buffSize; + //size_t buffSizeMax; bool fmtp_set_to_context; bool payError; AVCodecContext* pAVCodecContext; - AVFrame* pAVFrame; + AVFrame* pAVFrame;//#todo delete H264Decoder_Internal() : - buffSize(0), buffSizeMax(sizeof(buffer)), fmtp_set_to_context(false), - payError(false), + //buffSize(0), buffSizeMax(sizeof(buffer)), + fmtp_set_to_context(false), + payError(true), pAVCodecContext(nullptr), pAVFrame(nullptr) { } @@ -34,9 +35,9 @@ void reset() { - buffSize = 0; + //buffSize = 0; fmtp_set_to_context = false; - payError = false; + payError = true; } }; @@ -171,47 +172,20 @@ if(frameFinished) { // decode ok - - int picSize = in->pAVCodecContext->height * in->pAVCodecContext->width; - in->buffSize = picSize * 1.5; - - int height = in->pAVFrame->height; - int width = in->pAVFrame->width; - - // write yuv420 - int a=0; - for (int i = 0; i < height; i++) - { - memcpy(in->buffer + a, in->pAVFrame->data[0] + i * in->pAVFrame->linesize[0], width); - a += width; - } - for (int i=0; i<height/2; i++) - { - memcpy(in->buffer + a, in->pAVFrame->data[1] + i * in->pAVFrame->linesize[1], width / 2); - a += width / 2; - } - for (int i=0; i<height/2; i++) - { - memcpy(in->buffer + a, in->pAVFrame->data[2] + i * in->pAVFrame->linesize[2], width / 2); - a += width / 2; - } - - //in->buffer readly - - //static size_t f=0; - //char fname[50]; - //sprintf(fname, "%u.yuv420", ++f); - //FILE * pFile = fopen (fname,"wb"); - //fwrite (in->buffer , sizeof(char), in->buffSize, pFile); - //fclose(pFile); + return true; } else + { printf("incomplete frame\n"); + return false; + } } bool PL_H264Decoder::pay(const PipeMaterial& pm) { H264Decoder_Internal* in = (H264Decoder_Internal*)internal; + + in->payError = true; if (!in->fmtp_set_to_context) { @@ -237,8 +211,9 @@ in->fmtp_set_to_context = true; } - in->payError = decodeH264(in, pm.buffer, pm.buffSize); - return in->payError; + bool ret = decodeH264(in, pm.buffer, pm.buffSize); + in->payError = !ret; + return ret; } bool PL_H264Decoder::gain(PipeMaterial& pm) @@ -247,9 +222,9 @@ if (!in->payError) { - pm.buffer = in->buffer; - pm.buffSize = in->buffSize; + pm.buffer = (uint8_t*)in->pAVFrame;//in->buffer; + pm.buffSize = sizeof(uint8_t*);//in->buffSize; } pm.former = this; - return in->payError; + return !in->payError; } diff --git a/RtspFace/PipeLine.cpp b/RtspFace/PipeLine.cpp index 6f53b19..16f5ee1 100644 --- a/RtspFace/PipeLine.cpp +++ b/RtspFace/PipeLine.cpp @@ -77,7 +77,7 @@ uint8_t pmPlacement[sizeof(PipeMaterial)]; if (pm == nullptr) pm = new (pmPlacement) PipeMaterial; - + if (elems.size() == 1) { elem_begin->gain(*pm); @@ -85,24 +85,34 @@ } else if (elems.size() == 2) { - elem_begin->gain(*pm); - elem_last->pay(*pm); + if (elem_begin->gain(*pm)) + elem_last->pay(*pm); + else + return elem_begin; return elem_last; } else { - elem_begin->gain(*pm); + if (!elem_begin->gain(*pm)) + return elem_begin; + bool lastRet = true; elem_vec_t::iterator iter = elems.begin(); + ++iter; + elem_begin = *iter; while (elem_begin != elem_last) { + if (lastRet && (lastRet = elem_begin->pay(*pm)) ) + lastRet = elem_begin->gain(*pm); + else + return elem_begin; + ++iter; elem_begin = *iter; - elem_begin->pay(*pm); - elem_begin->gain(*pm); } - elem_last->pay(*pm); + if (lastRet) + elem_last->pay(*pm); return elem_last; } diff --git a/RtspFace/main.cpp b/RtspFace/main.cpp index e9c6a48..f8e9875 100644 --- a/RtspFace/main.cpp +++ b/RtspFace/main.cpp @@ -1,7 +1,7 @@ #include "PipeLine.h" #include "PL_RTSPClient.h" #include "PL_H264Decoder.h" -#include "PL_AVFrameYUV420.h" +#include "PL_AVFrameBGRA.h" #include <iostream> using namespace std; @@ -12,7 +12,7 @@ pipeLine.register_elem_creator("PL_RTSPClient", create_PL_RTSPClient); pipeLine.register_elem_creator("PL_H264Decoder", create_PL_H264Decoder); - pipeLine.register_elem_creator("PL_AVFrameYUV420", create_PL_H264Decoder); + pipeLine.register_elem_creator("PL_AVFrameBGRA", create_PL_AVFrameBGRA); PL_RTSPClient* rtspClient = (PL_RTSPClient*)pipeLine.push_elem("PL_RTSPClient"); RTSPConfig rtspConfig; @@ -28,8 +28,8 @@ PL_H264Decoder* h264Decoder = (PL_H264Decoder*)pipeLine.push_elem("PL_H264Decoder"); h264Decoder->init(nullptr); - PL_AVFrameYUV420* AVFrameYUV420 = (PL_AVFrameYUV420*)pipeLine.push_elem("PL_AVFrameYUV420"); - AVFrameYUV420->init(nullptr); + PL_AVFrameBGRA* avFrameBGRA = (PL_AVFrameBGRA*)pipeLine.push_elem("PL_AVFrameBGRA"); + avFrameBGRA->init(nullptr); while(true) { diff --git a/RtspFace/make.sh b/RtspFace/make.sh index 3568267..4749d56 100644 --- a/RtspFace/make.sh +++ b/RtspFace/make.sh @@ -10,8 +10,12 @@ LIBBASE64_INC="-I$LIBBASE64_BASE/include" LIBBASE64_LIB="$LIBBASE64_BASE/lib/libbase64.o" -CPPFLAGS+="-pthread $LIVEMEDIA_INC $FFMPEG_INC $LIBBASE64_INC" -LDFLAGS+="-pthread $LIVEMEDIA_LIB $FFMPEG_LIB $LIBBASE64_LIB" +LIBYUV_BASE=/opt/libyuv +LIBYUV_INC="-I$LIBYUV_BASE/include" +LIBYUV_LIB="-L$LIBYUV_BASE -lyuv" + +CPPFLAGS+="-pthread $LIVEMEDIA_INC $FFMPEG_INC $LIBBASE64_INC $LIBYUV_INC" +LDFLAGS+="-pthread $LIVEMEDIA_LIB $FFMPEG_LIB $LIBBASE64_LIB $LIBYUV_LIB" CFLAGS+="-D__STDC_CONSTANT_MACROS" @@ -21,8 +25,10 @@ g++ -g -c -std=c++11 main.cpp $CFLAGS $CPPFLAGS g++ -g -c -std=c++11 PL_RTSPClient.cpp $CFLAGS $CPPFLAGS g++ -g -c -std=c++11 PL_H264Decoder.cpp $CFLAGS $CPPFLAGS +g++ -g -c -std=c++11 PL_AVFrameYUV420.cpp $CFLAGS $CPPFLAGS +g++ -g -c -std=c++11 PL_AVFrameBGRA.cpp $CFLAGS $CPPFLAGS g++ -g -c -std=c++11 PipeLine.cpp $CFLAGS $CPPFLAGS -g++ -g -std=c++11 main.o PL_RTSPClient.o PL_H264Decoder.o PipeLine.o $LDFLAGS -o rtsp_face +g++ -g -std=c++11 main.o PL_RTSPClient.o PL_H264Decoder.o PL_AVFrameYUV420.o PL_AVFrameBGRA.o PipeLine.o $LDFLAGS -o rtsp_face #export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$FFMPEG_BASE/lib #./rtsp_face rtsp://admin:admin12345@192.168.1.63:554/h264/ch1/main/av_stream -- Gitblit v1.8.0