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