add pl emements
git-svn-id: http://192.168.1.226/svn/proxy@28 454eff88-639b-444f-9e54-f578c98de674
New file |
| | |
| | | #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;
|
| | | }
|
New file |
| | |
| | | #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
|
| | |
| | | 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))
|
| | | {
|
| | | }
|
| | |
|
| | |
| | | void reset()
|
| | | {
|
| | | buffSize = 0;
|
| | | payError = false;
|
| | | }
|
| | | };
|
| | |
|
| | |
| | | {
|
| | | 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;
|
| | | }
|
| | |
| | |
|
| | | 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)
|
| | | {
|
| | | }
|
| | |
| | |
|
| | | void reset()
|
| | | {
|
| | | buffSize = 0;
|
| | | //buffSize = 0;
|
| | | fmtp_set_to_context = false;
|
| | | payError = false;
|
| | | payError = true;
|
| | | }
|
| | | };
|
| | |
|
| | |
| | | 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)
|
| | | {
|
| | |
| | | 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)
|
| | |
| | |
|
| | | 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;
|
| | | }
|
| | |
| | | uint8_t pmPlacement[sizeof(PipeMaterial)];
|
| | | if (pm == nullptr)
|
| | | pm = new (pmPlacement) PipeMaterial;
|
| | | |
| | |
|
| | | if (elems.size() == 1)
|
| | | {
|
| | | elem_begin->gain(*pm);
|
| | |
| | | }
|
| | | 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;
|
| | | }
|
| | |
|
| | |
| | | #include "PipeLine.h"
|
| | | #include "PL_RTSPClient.h"
|
| | | #include "PL_H264Decoder.h"
|
| | | #include "PL_AVFrameYUV420.h"
|
| | | #include "PL_AVFrameBGRA.h"
|
| | |
|
| | | #include <iostream>
|
| | | using namespace std;
|
| | |
| | |
|
| | | 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;
|
| | |
| | | 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)
|
| | | {
|
| | |
| | | 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" |
| | | |
| | |
| | | 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 |