From 017b7eb736ccc53c52f81486be8196d7fafc3289 Mon Sep 17 00:00:00 2001
From: houxiao <houxiao@454eff88-639b-444f-9e54-f578c98de674>
Date: 星期三, 28 十二月 2016 10:31:42 +0800
Subject: [PATCH] add MaterialBuffer

---
 RtspFace/PL_H264Encoder.cpp |  113 +++++++++++++++++++++++++++++++++++++++++++++-----------
 1 files changed, 90 insertions(+), 23 deletions(-)

diff --git a/RtspFace/PL_H264Encoder.cpp b/RtspFace/PL_H264Encoder.cpp
index e2fcdf2..5547256 100644
--- a/RtspFace/PL_H264Encoder.cpp
+++ b/RtspFace/PL_H264Encoder.cpp
@@ -1,11 +1,14 @@
 #include "PL_H264Encoder.h"
+#include "MaterialBuffer.h"
 
 extern "C"
 {
 	#include <libavcodec/avcodec.h>
 	#include <libavutil/frame.h>
 	#include <libavformat/avformat.h>
-	#include "libavutil/imgutils.h"
+	#include <libavutil/imgutils.h>
+	
+	#include <libyuv.h>
 }
 
 struct H264Encoder_Internal
@@ -16,6 +19,7 @@
 	bool payError;
 	bool ffmpegInited;
 	size_t frameCount;
+	MB_Frame lastFrame;
 
 	AVCodecContext* pAVCodecContext;
 	AVFrame* pAVFrame;//#todo delete
@@ -25,8 +29,8 @@
 	H264Encoder_Internal() : 
 		buffSize(0), buffSizeMax(sizeof(buffer)), 
 		payError(true), ffmpegInited(false), frameCount(0), 
-		pAVCodecContext(nullptr), pAVFrame(nullptr), pAVStream(nullptr), pAVFormatContext(nullptr)
-		
+		pAVCodecContext(nullptr), pAVFrame(nullptr), pAVStream(nullptr), pAVFormatContext(nullptr), 
+		lastFrame()
 	{
 	}
 	
@@ -40,6 +44,9 @@
 		payError = true;
 		ffmpegInited = false;
 		frameCount = 0;
+		
+		MB_Frame _lastFrame;
+		lastFrame = _lastFrame;
 		
 		pAVCodecContext = nullptr;
 		pAVFrame = nullptr;
@@ -93,11 +100,11 @@
 	in->pAVCodecContext = avcodec_alloc_context3(avCodec);
 
 	in->pAVCodecContext->bit_rate = 1*1024*1024*8; // 3MB
-    in->pAVCodecContext->width = 1920;
-    in->pAVCodecContext->height = 1080;//#todo from config
+    in->pAVCodecContext->width = 800;//#todo test
+    in->pAVCodecContext->height = 600;//#todo from config
     in->pAVCodecContext->time_base.num=1;
     in->pAVCodecContext->time_base.den=25;
-    in->pAVCodecContext->gop_size = 20;
+    in->pAVCodecContext->gop_size = 25;
     in->pAVCodecContext->max_b_frames = 0;
     in->pAVCodecContext->pix_fmt = AV_PIX_FMT_YUV420P;
 	
@@ -144,11 +151,39 @@
 	return true;
 }
 
+#define SUBSAMPLE(v, a) ((((v) + (a) - 1)) / (a))
+
 void copyAVFrame(AVFrame* dest, AVFrame* src)
 {
-	dest->data[0] = src->data[0];
-	dest->data[1] = src->data[1];
-	dest->data[2] = src->data[2];
+int src_width = src->width;
+int src_height = src->height;
+int dst_width = dest->width;
+int dst_height = dest->height;
+printf("I420Scale sw=%d, sh=%d, dw=%d, dh=%d\n", src_width,src_height,dst_width, dst_height);
+
+libyuv::I420Scale(src->data[0], src_width, 	
+				  src->data[1], SUBSAMPLE(src_width, 2), 
+				  src->data[2], SUBSAMPLE(src_width, 2), 
+				  src_width, src_height, 
+				  dest->data[0], dst_width, 	
+				  dest->data[1], SUBSAMPLE(dst_width, 2), 
+				  dest->data[2], SUBSAMPLE(dst_width, 2), 
+				  dst_width, dst_height, 
+				  libyuv::kFilterNone );
+	
+	//#test
+	//static size_t f=0;
+	//char fname[50];
+	//sprintf(fname, "%u.yuv420", ++f);
+	//FILE * pFile = fopen (fname,"wb");
+	//fwrite (dest->data[0] , sizeof(char), dst_width * dst_height, pFile);
+	//fwrite (dest->data[1] , sizeof(char), dst_width * dst_height / 4, pFile);
+	//fwrite (dest->data[2] , sizeof(char), dst_width * dst_height / 4, pFile);
+	//fclose(pFile);
+	
+	//dest->data[0] = src->data[0];
+	//dest->data[1] = src->data[1];
+	//dest->data[2] = src->data[2];
 	
 	//int height = dest->height;
 	//int width = dest->width;
@@ -158,15 +193,19 @@
 	//memcpy(dest->data[2], src->data[2], height * width / 4); // V
 }
 
-bool encodeH264(H264Encoder_Internal* in, AVFrame* pAVFrame, size_t buffSize)  
+bool encodeH264(H264Encoder_Internal* in, AVFrame* pAVFrame, timeval pts)  
 {
 	in->buffSize = 0;
-	in->frameCount++;
 
 	copyAVFrame(in->pAVFrame, pAVFrame);
 
 	//in->pAVFrame->pts = (1.0 / 25) * 90000 * in->frameCount;
-	in->pAVFrame->pts = time(nullptr);
+	//in->pAVFrame->pts = time(nullptr);
+	//in->pAVFrame->pts = (pts.tv_sec * 1000 * 1000 + pts.tv_usec) / 90000 + in->frameCount;
+	//in->pAVFrame->pts = (pts.tv_sec * 1000 * 1000 + pts.tv_usec) / 90000 + ((1.0 / 25) * 90000 * in->frameCount);
+	in->pAVFrame->pts = (pts.tv_sec * 1000 * 1000 + pts.tv_usec) / 90000;
+	//in->pAVFrame->pts = pAVFrame->pkt_pts;
+	//in->pAVFrame->pts = (1.0 / 25) * 90000 * in->frameCount;
 
 	AVPacket pAVPacket = {0};
 	av_init_packet(&pAVPacket);
@@ -183,6 +222,7 @@
 	
 	if (gotPacket > 0)
 	{
+		in->frameCount++;
 		printf("Succeed to encode (1) frame=%d, size=%d\n", in->frameCount, pAVPacket.size);
 		memcpy(in->buffer, pAVPacket.data, pAVPacket.size);
 		in->buffSize = pAVPacket.size;
@@ -190,7 +230,7 @@
 	}
 	
 	//#todo finit
-	//Flush Encoder  
+	//Flush Encoder, when stop encoder
 	//while (gotPacket > 0)
 	//{  
 	//	ret = avcodec_encode_video2(in->pAVCodecContext, &pAVPacket, NULL, &gotPacket);
@@ -210,12 +250,12 @@
 	
 	
 	//#test
-	if (in->buffSize > 0)
-	{
-		static FILE * pFile = fopen("out.h264","wba+");
-		fwrite (in->buffer , sizeof(char), in->buffSize, pFile);
-		fflush(pFile);
-	}
+	//if (in->buffSize > 0)
+	//{
+	//	static FILE * pFile = fopen("out.h264","wba+");
+	//	fwrite (in->buffer , sizeof(char), in->buffSize, pFile);
+	//	fflush(pFile);
+	//}
 
 	in->payError = (in->buffSize == 0);
 	return !(in->payError);
@@ -232,15 +272,40 @@
 		bool ret = initH264EncoderEnv(in);
 		if (!ret)
 		{
-			printf("initH264EncoderEnv error");
+			printf("initH264EncoderEnv error\n");
 			return false;
 		}
 		else
 			in->ffmpegInited = true;
 	}
 	
-	bool ret = encodeH264(in, (AVFrame*)pm.buffer, pm.buffSize);
+	if (pm.type != PipeMaterial::PMT_FRAME)
+	{
+		printf("PL_H264Encoder::pay only support PMT_FRAME\n");
+		return false;
+	}
+	
+	if (pm.buffer == nullptr)
+		return false;
+	
+	MB_Frame* frame = (MB_Frame*)pm.buffer;
+	if (frame->type != MB_Frame::MBFT_PTR_AVFRAME)
+	{
+		printf("PL_H264Encoder::pay only support MBFT_PTR_AVFRAME\n");
+		return false;
+	}
+	
+	bool ret = encodeH264(in, (AVFrame*)(frame->buffer), frame->pts);
 	in->payError = !ret;
+	
+	if (ret)
+	{
+		in->lastFrame.type = MB_Frame::MBFT_H264_NALU;
+		in->lastFrame.buffer = in->buffer;
+		in->lastFrame.buffSize = in->buffSize;
+		in->lastFrame.pts = frame->pts;
+	}
+	
 	return ret;
 }
 
@@ -250,8 +315,10 @@
 
 	if (!in->payError)
 	{
-		pm.buffer = in->buffer;
-		pm.buffSize = in->buffSize;
+		pm.type = PipeMaterial::PMT_FRAME;
+		pm.buffer = (uint8_t*)(&(in->lastFrame));
+		pm.buffSize = sizeof(in->lastFrame);
+		pm.former = this;
 	}
 	pm.former = this;
 	return !in->payError;

--
Gitblit v1.8.0