基于大华SDK及c++的标准H264裸码封装MP4文件+保存.h264文件+实时预览

最近本人在学习大华相机的二次开发时遇到一个问题:大华SDK开发文档并没有说明如何获取相机H264裸码流及其如何封装成mp4文件。在研究了海康的相关代码之后,才明白如何操作。

main.cpp

#include 
#include "dhnetsdk.h"
#include "MP4Encoder.h"
using namespace std;
LLONG g_lRealHandle;
MP4Encoder* pMP4;
void CALLBACK RealDataCallBackEx2(LLONG lRealHandle, DWORD dwDataType, BYTE*pBuffer, DWORD dwBufSize, tagVideoFrameParam param, LDWORD dwUser)
{
	// 若多个实时监视使用相同的数据回调函数,则用户可通过 lRealHandle 进行一一对应
	if (lRealHandle == g_lRealHandle)
	{
		int type = param.frametype;
		switch (type)
		{
		case 0: // I 帧 
			pMP4->getConvertMP4File(pBuffer, dwBufSize, type);
			break;
		case 1: // P 帧
			pMP4->getConvertMP4File(pBuffer, dwBufSize, type);
			break;
		default:
			break;
		}	
	}
}


int main()
{
	BOOL g_bNetSDKInitFlag = FALSE;
	// 初始化 SDK
	g_bNetSDKInitFlag = CLIENT_Init(NULL, 0);
	if (FALSE == g_bNetSDKInitFlag)
	{
		cout << "Initialize client SDK fail;" << endl;
		return 0;
	}
	else
		cout << "Initialize client SDK done; " << endl;

	NET_DEVICEINFO_Ex deviceInfo = { 0 };
	int nError = 0;
	LLONG login_handle = CLIENT_LoginEx2("192.168.1.64", 37777, "admin", "admin", EM_LOGIN_SPEC_CAP_TCP, nullptr, &deviceInfo, &nError);
	/*登录失败*/
	if (login_handle != 0)
	{
		cout << "登录成功" << endl;
		//开启实时监视
		int nChannelID = 0; // 预览通道号
		DH_RealPlayType emRealPlayType = DH_RType_Realplay; // 实时监视
		HWND hWnd = GetConsoleWindow();
		g_lRealHandle = CLIENT_RealPlayEx(login_handle, nChannelID, hWnd, emRealPlayType);
		pMP4 = new MP4Encoder;
		if (0 == g_lRealHandle)
		{
			cout << "CLIENT_RealPlayEx: failed! Error code:" << CLIENT_GetLastError() << endl;
			system("pause");
			return 0;
		}
		else
		{
			//DWORD dwFlag = 0x00000001;
			if (FALSE == CLIENT_SetRealDataCallBackEx2(g_lRealHandle, &RealDataCallBackEx2, NULL, REALDATA_FLAG_DATA_WITH_FRAME_INFO))
			{
				cout << "CLIENT_SetRealDataCallBackEx: failed! Error code: " << CLIENT_GetLastError() << endl;
				return 0;
			}
			Sleep(10000);		
		}	
	}
	pMP4->getMP4FileClose();
	delete pMP4;
	//关闭预览
	if (CLIENT_StopRealPlayEx(g_lRealHandle))
	{
		g_lRealHandle = 0;
	};

	// 退出设备
	if (0 != login_handle)
	{
		if (FALSE == CLIENT_Logout(login_handle))
		{
			cout << "CLIENT_Logout Failed!Last Error \n" << CLIENT_GetLastError() << endl;
		}
		else
		{
			login_handle = 0;
		}
	}
	// 清理初始化资源
	if (TRUE == g_bNetSDKInitFlag)
	{
		CLIENT_Cleanup();
		g_bNetSDKInitFlag = FALSE;
	}
	return 0;
}

MP4Encoder.cpp,通过libmp4V2实现MP4写封装生成MP4视频文件

#include "MP4Encoder.h"

void MP4Encoder::getMP4FileClose()
{
	MP4Close(mFile);
}

bool MP4Encoder::getConvertMP4File(BYTE *pBuffer, DWORD dwBufSize, int dwDataType)
{
	
	CreateMP4File();
	WriteH264Data(mFile, pBuffer, dwBufSize, dwDataType);
	return true;
}

MP4Encoder::MP4Encoder()
{	
	mFile = MP4_INVALID_FILE_HANDLE;
	mVideoId = MP4_INVALID_TRACK_ID;
}


MP4Encoder::~MP4Encoder()
{
	
}


string MP4Encoder::GetSystemTime()
{
	SYSTEMTIME m_time;
	GetLocalTime(&m_time);
	char szDateTime[100] = { 0 };
	sprintf_s(szDateTime, "%02d%02d%02d%02d%02d%02d", m_time.wYear, m_time.wMonth,
		m_time.wDay, m_time.wHour, m_time.wMinute, m_time.wSecond);
	string time(szDateTime);
	return time;
}

MP4FileHandle MP4Encoder::CreateMP4File()
{
	if (mFile == NULL)
	{
		string s = GetSystemTime() + ".mp4";
		const char* FileName = s.c_str();
		mFile = MP4Create(FileName);
		if (mFile == MP4_INVALID_FILE_HANDLE)
		{
			cout << "Open file failed!\n";
			return 0;
		}

		if (mFile == NULL)
		{
			printf("ERROR:Create file failed!");
			return false;
		}	
		// 设置时间片
		MP4SetTimeScale(mFile, VIDEO_TIME_SCALE);
	}	
	return mFile;
}


int MP4Encoder::ReadOneNaluFromBuf(const unsigned char *pBuffer, unsigned int nBufferSize, unsigned int offSet, MP4ENC_NaluUnit &nalu)
{
	unsigned int i = offSet;
	int j = 0;
	while (i> 24;
			data[1] = nalu.size >> 16;
			data[2] = nalu.size >> 8;
			data[3] = nalu.size & 0xff;
			memcpy(data + 4, nalu.data, nalu.size);
			if (dwDataType == 0)
			{
				MP4WriteSample(MP4File, mVideoId, data, datalen, MP4_INVALID_DURATION, 0, 1);
			}
			if (dwDataType == 1)
			{
				MP4WriteSample(MP4File, mVideoId, data, datalen, MP4_INVALID_DURATION, 0, 0);
			}
			delete[] data;
		}

		pos += len;
	}
	return pos;
}




整个项目(VS2015-X64)下载链接:https://download.csdn.net/download/qq_35135771/12526926

你可能感兴趣的:(大华,c++)