⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 clienth264dlg.cpp

📁 dianzi shuju ,tai badao le ,my tian li a a
💻 CPP
📖 第 1 页 / 共 2 页
字号:
			char *tmp = snippets.RemoveHead();
			free(tmp);
		}

		char *snippet = (char *) malloc(rVal);
		memcpy(snippet, buf, rVal);
		snippets.AddTail(snippet);
		//==================================================================
		LeaveCriticalSection(&lockSnippet);
	}

	closesocket(client);
	WSACleanup();
	
	//AfxMessageBox("finished.");
	return SOCKET_OK;
}

//thread that decodes h264 bit stream to frame
UINT H264DecodingThread(LPVOID param)
{
    AVCodec *codec;
    AVCodecContext *c= NULL;
    AVFrame *picture;
    uint8_t inbuf[INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE], *inbuf_ptr;
    int size, got_picture, len;

	AVFrame *pFrameYUV;
    int numBytes;
    uint8_t *buffer;
	int y_size = FRAME_WIDTH * FRAME_HEIGHT;
	
    // set end of buffer to 0 
    memset(inbuf + INBUF_SIZE, 0, FF_INPUT_BUFFER_PADDING_SIZE);

    // find the h264 video decoder
    codec = avcodec_find_decoder(CODEC_ID_H264);
    if (!codec) {
        fprintf(stderr, "codec not found\n");
        exit(1);
    }

    c= avcodec_alloc_context();
    picture= avcodec_alloc_frame();

	// for continuous data retriving
    if(codec->capabilities&CODEC_CAP_TRUNCATED)
        c->flags|= CODEC_FLAG_TRUNCATED; //uncompleted h264 NAL data

    // open h264 codec
    if (avcodec_open(c, codec) < 0) {
        fprintf(stderr, "could not open codec\n");
        exit(1);
    }

    //buffer to image planes in pFrameRGB
	pFrameYUV=avcodec_alloc_frame();
    //required buffer size and then allocate buffer
    numBytes = avpicture_get_size(PIX_FMT_YUV420P, FRAME_WIDTH, FRAME_HEIGHT);
    buffer = (uint8_t*)malloc(numBytes);
    avpicture_fill((AVPicture *)pFrameYUV, buffer, PIX_FMT_YUV420P, FRAME_WIDTH, FRAME_HEIGHT);

	while (nPlaying)
	{
		if (snippets.GetCount() == 0)
			Sleep(10);
		else
		{
			//get some snippets to decode
			EnterCriticalSection(&lockSnippet);
			//==================================================================
			char *snippet = snippets.RemoveHead();
			size = _msize(snippet);
			memcpy(inbuf, snippet, size);
			//free snippet memory
			free(snippet);
			//==================================================================
			LeaveCriticalSection(&lockSnippet);
			
			//now decode h264 frame
			if (size == 0)
				continue;

			inbuf_ptr = inbuf;

			while (size > 0) {
				int ECode;
				__try
				{
					len = avcodec_decode_video(c, picture, &got_picture, inbuf_ptr, size);
				}
				__except (ECode=GetExceptionCode())
				{
					printf("解码发生异常,Code=%d\n",ECode);
					break;//inner while
				}

				if (len < 0) {
					break;//inner while
				}

				if (got_picture) {
					//convert raw video stream to YUV420 format
					img_convert((AVPicture *)pFrameYUV, PIX_FMT_YUV420P, (AVPicture*)picture,
									c->pix_fmt, FRAME_WIDTH, FRAME_HEIGHT);
					
					//convert YUV420P to RGB frame
					LPBYTE Y, Cb, Cr, RGBbuf;

					RGBbuf = (unsigned char *) malloc(FRAME_WIDTH * FRAME_HEIGHT * 3);
					Y  = pFrameYUV->data[0];
					Cb = pFrameYUV->data[1];
					Cr = pFrameYUV->data[2];

					conv.YV12_to_RGB24(Y, Cb, Cr, RGBbuf, FRAME_WIDTH, FRAME_HEIGHT);

					//put some frames to frame pool
					EnterCriticalSection(&lockFrame);
					//------------------------------------------------------------------
					if (frames.GetCount() > 50) //remove the outdated video frame
					{
						unsigned char *tmp = frames.RemoveHead();
						free(tmp);
					}
					frames.AddTail(RGBbuf);
					//------------------------------------------------------------------
					LeaveCriticalSection(&lockFrame);
				}

				size -= len;
				inbuf_ptr += len;
			}
		}
	}

    avcodec_close(c);
    av_free(c);
    av_free(picture);
	av_free(pFrameYUV);
	free(buffer);

	return 0;
}

//thread that plays decoded frame
UINT H264PlayingThread(LPVOID param)
{
	CClientH264Dlg *dlg = (CClientH264Dlg *)AfxGetApp()->m_pMainWnd;
	CStatic *screen = (CStatic *) dlg->GetDlgItem(IDC_STATIC_SCREEN);
	CDC *pDC = screen->GetDC();
	BYTE RGBbuf[FRAME_WIDTH * FRAME_HEIGHT * 3];

	RECT rect;
	screen->GetClientRect(&rect);

	int iWidth = FRAME_WIDTH;
	int iHeight = FRAME_HEIGHT;
	float m_xZoom = (rect.right - rect.left) / (float)iWidth;
	float m_yZoom = (rect.bottom - rect.top) / (float)iHeight;

	//allocate bmp memory to attach playing window
	HANDLE hloc = GlobalAlloc(GMEM_ZEROINIT | GMEM_MOVEABLE,
   						sizeof(BITMAPINFOHEADER) + (sizeof(RGBQUAD) * 256));
	LPBITMAPINFO BmpInfo = (LPBITMAPINFO) GlobalLock(hloc);
	BmpInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
	BmpInfo->bmiHeader.biPlanes = 1;
	BmpInfo->bmiHeader.biBitCount = 24;
	BmpInfo->bmiHeader.biCompression = BI_RGB;
	BmpInfo->bmiHeader.biWidth = iWidth;
	BmpInfo->bmiHeader.biHeight = iHeight;

	//============================
	CDXSurfaceManager_NBP dxMgr_;
	dxMgr_.Initialise(screen->m_hWnd);

	pDC->SetStretchBltMode(STRETCH_DELETESCANS);
	CBrush brush1;   // Must initialize!
	brush1.CreateSolidBrush(RGB(0,0,0));   // Black brush.

	while (nPlaying)
	{
		//playing video as fast as possible
		if (frames.GetCount() > 0)
		{
			//get decoded frame
			EnterCriticalSection(&lockFrame);
			BYTE *frame = frames.RemoveHead();
			LeaveCriticalSection(&lockFrame);

			//free frame memory
			memcpy(RGBbuf, frame, FRAME_WIDTH * FRAME_HEIGHT * 3);
			free(frame);

			nFrames ++;

			//now playing the frame
			HDC& hdc = dxMgr_.BeginPaint(GetSysColor(COLOR_3DFACE));
			if(NULL !=hdc)
			{
				CDC* cdc = CDC::FromHandle(hdc);
				//------------------------------
				if (nZoom)
				{
					StretchDIBits(hdc, 0, 0, (int)(m_xZoom*iWidth), (int)(m_yZoom*iHeight),
							 0, 0, iWidth, iHeight,
							 RGBbuf, BmpInfo, DIB_RGB_COLORS, SRCCOPY);
				}
				else
				{
					StretchDIBits(hdc, 0, 0, iWidth, iHeight,
					  0, 0, iWidth, iHeight,
					  RGBbuf, BmpInfo, DIB_RGB_COLORS, SRCCOPY);
				}
				//------------------------------
				dxMgr_.EndPaint();
			}

		}
		else
			Sleep(1);
	}

	GlobalUnlock(hloc);
	GlobalFree(hloc);  

	return 0;
}

void CClientH264Dlg::OnButtonConnect() 
{
	// TODO: Add your control notification handler code here
	InitializeCriticalSection(&lockSnippet);
	InitializeCriticalSection(&lockFrame);

	UpdateData(TRUE);
	strcpy(strIP, m_strServerIP);

	AfxBeginThread(H264ReceivingThread, (LPVOID)NULL, 0, 0, NULL);

	//init h264 codec
    avcodec_init();
    avcodec_register_all();

	AfxBeginThread(H264DecodingThread, (LPVOID)NULL, 0, 0, NULL);
	AfxBeginThread(H264PlayingThread, (LPVOID)NULL, 0, 0, NULL);

	GetDlgItem(IDC_BUTTON_CONNECT)->EnableWindow(FALSE);
}

void CClientH264Dlg::OnClose() 
{
	// TODO: Add your message handler code here and/or call default
	KillTimer(SPEED_REFRESH);
	WSACleanup();
	nPlaying = 0;
	Sleep(150);
	
	CDialog::OnClose();
}

void CClientH264Dlg::OnDestroy() 
{
	CDialog::OnDestroy();
	
	// TODO: Add your message handler code here
	while (! snippets.IsEmpty())
	{
		char *buf = snippets.RemoveHead();
		free(buf);
	}
	
	while (! frames.IsEmpty())
	{
		unsigned char *buf = frames.RemoveHead();
		free(buf);
	}
}

void CClientH264Dlg::OnTimer(UINT nIDEvent) 
{
	// TODO: Add your message handler code here and/or call default
	switch (nIDEvent)
	{
	case SPEED_REFRESH:
		{
			if (nData == 0)//has no data received
				return;

			nTicks ++;

			m_strTimer.Format("计时时间: %d s", nTicks);
			m_strTotalReceive.Format("累计接收: %.1f KB", nData/1024.0);
			m_strTotalFrames.Format("累计帧数: %d", nFrames);
			m_strAveFrames.Format("平均帧率: %.1f fps", nFrames/(1.0*nTicks));
			UpdateData(FALSE);

			CString s;
			s.Format("平均速度:%.1fkbps Snippets:%d-Frames:%d", nData*8/(1024.0 * nTicks), snippets.GetCount(), frames.GetCount());
			SetWindowText(s);

			break;
		}
	default:
		break;
	}
	
	CDialog::OnTimer(nIDEvent);
}

void CClientH264Dlg::OnStaticScreen() 
{
	// TODO: Add your control notification handler code here
	nZoom = (nZoom==0) ? 1 : 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -