使用海康摄相机编写的录像和图像抓拍软件(visual studio 2008)

//Global.h

typedef struct tagIMAGEDATA 

 BYTE red; 
 BYTE green; 
 BYTE blue; 
}IMAGEDATA; 

typedef struct VIDEO
{
 long  size;
 char *buffer;
 VIDEO()
 {
  memset(buffer,0, sizeof(buffer));
 }
}VIDEO_SET,*PVIDEO_SET;

typedef struct PIC
{
 long  psize;
 char *pbuffer;
 PIC()
 {
  memset(pbuffer,0, sizeof(pbuffer));
 }
}PIC_SET,*PPIC_SET;

 

 

//Image.cpp
#include "stdafx.h"
#include "Image.h"
#include <stdio.h>
#include <stdlib.h>
using namespace Gdiplus;

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//
// Construction/Destruction
//

CImage::CImage()
{
    Clear();
}
//============================================================================

void CImage::Clear()
{
    memset( &m_img, 0, sizeof(m_img));

    m_memDC = 0;
    m_old = 0;
}
//============================================================================

void CImage::Destroy()
{
    if( m_memDC )
    {
        DeleteObject( SelectObject( m_memDC, m_old ));
        DeleteDC( m_memDC );
    }
    //Clear();
}
//============================================================================

CImage::~CImage()
{
    Destroy();
}
//============================================================================


void CImage::ShowError(){
 LPVOID lpMsgBuf;
 if (!FormatMessage(
  FORMAT_MESSAGE_ALLOCATE_BUFFER |
  FORMAT_MESSAGE_FROM_SYSTEM |
  FORMAT_MESSAGE_IGNORE_INSERTS,
  NULL,
  GetLastError(),
  MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
  (LPTSTR) &lpMsgBuf,
  0,
  NULL ))
 {
  // Handle the error.
  return;
 }

 // Process any inserts in lpMsgBuf.
 // ...

 // Display the string.
 MessageBox( NULL, (LPCTSTR)lpMsgBuf, "Error", MB_OK | MB_ICONINFORMATION );

 // Free the buffer.
 LocalFree( lpMsgBuf );

}
//============================================================================


void  FillBitmapInfo( BITMAPINFO* bmi, int width, int height, int bpp )
{
   
    BITMAPINFOHEADER* bmih = &(bmi->bmiHeader);

    memset( bmih, 0, sizeof(*bmih));
    bmih->biSize   = sizeof(BITMAPINFOHEADER);
    bmih->biWidth  = width;
    bmih->biHeight = -height;
    bmih->biPlanes = 1;
    bmih->biBitCount = bpp;
    bmih->biCompression = BI_RGB;

    if( bpp == 8 )
    {
        RGBQUAD* palette = bmi->bmiColors;
        int i;
        for( i = 0; i < 256; i++ )
        {
            palette[i].rgbBlue = palette[i].rgbGreen = palette[i].rgbRed = (BYTE)i;
            palette[i].rgbReserved = 0;
        }
    }
}

//============================================================================

bool  CImage::Create( int w, int h, int bpp )
{
    char buffer[sizeof(BITMAPINFOHEADER) + 1024];
    BITMAPINFO* bmi = (BITMAPINFO*)buffer;
    void* data = 0;
    int new_step = (w*(bpp/8) + 3) & -4;
   
    if( bpp != 8 && bpp != 24 || w<=0 || h<=0){
  AfxMessageBox("Invalid Parameter.");
  return false;
 }
 
 m_boundary.left=0;
 m_boundary.top=0;
 m_boundary.right=w-1;
 m_boundary.bottom=h-1;

    if( (m_img.depth & 255)*m_img.nChannels == bpp &&
        m_img.width == w && m_img.height == h )
    {
        return true;
    }

    Destroy();
   
    m_memDC = CreateCompatibleDC(0);
 if(!m_memDC){
  ShowError();
 }

    FillBitmapInfo( bmi, w, h, bpp );

    HBITMAP hbmp = CreateDIBSection( m_memDC, bmi, DIB_RGB_COLORS, &data, 0, 0 );
    if( !hbmp )
    {
        DeleteDC( m_memDC );
        m_memDC = 0;
  ShowError();
  return 0;
    }
    else
    {
        BITMAP bmp;
        m_old = SelectObject( m_memDC, hbmp );

        GetObject( hbmp, sizeof(bmp), &bmp );

        /* prepare IPL header */
        memset( &m_img, 0, sizeof(m_img));
        m_img.nSize = sizeof( m_img );
        m_img.nChannels = bpp/8;
        m_img.depth = bpp;
        m_img.align = 4;
        m_img.width = w;
        m_img.height = abs(h);
        m_img.widthStep = (w*(bpp/8) + 3)& -4;
        m_img.imageSize = m_img.widthStep*m_img.height;
        m_img.imageData = m_img.imageDataOrigin = (unsigned char*)bmp.bmBits;
    }
    return 1;
}

//============================================================================

void  CImage::CopyOf( CImage* image, int desired_color ,int th)
{
    image_header* img = image->GetImage();
    if( img )
    {
        CopyOf( img, desired_color,th);
    }
}
//============================================================================

void  CImage::CopyOf( image_header* img, int desired_color,int th)
{
    if( img )
    {
        Create( img->width, img->height, desired_color>0?24:img->depth );
        unsigned char* src=(unsigned char*)img->imageData;
  unsigned char* dst=(unsigned char*)m_img.imageData;
  int step=img->widthStep-img->width;
  int step2=m_img.widthStep-m_img.width*m_img.nChannels;
   
  if( src == dst ) return;
  if(th==0){
   if(img->depth==m_img.depth)
    memcpy(m_img.imageDataOrigin,
     img->imageDataOrigin,
     img->imageSize);
   else{
    if(desired_color>0&&img->depth==8){
     for( int y = 0; y < img->height; y++,src+=step,dst+=step2 )
      for(int x=0;x<img->width;x++){
       dst[0]=*(src);
       dst[1]=*(src);
       dst[2]=*(src++);
       dst+=3;
      }
    }
    else if(desired_color>0&&img->depth==24){
     for( int y = 0; y < img->height; y++,src+=step,dst+=step2 )
      memcpy(dst,src,m_img.widthStep);
    }
   }

  }
  
  else{ 
   for( int y = 0; y < img->height; y++,src+=step,dst+=step )
    for(int x=0;x<img->width;x++)
     *(dst++)=(th-*(src++))>>8;
  }
  
    }
}

//============================================================================

bool  CImage::Load( const char* filename, int desired_color )
{
    BITMAPFILEHEADER fileHeader;
 BITMAPINFOHEADER infoHeader;
 FILE* file=fopen(filename,"rb");
 if(file==NULL) return false;
 fread(&fileHeader,1,sizeof(BITMAPFILEHEADER),file);
    fread(&infoHeader,1,sizeof(BITMAPINFOHEADER),file);
   
 Create( infoHeader.biWidth, infoHeader.biHeight,infoHeader.biBitCount);
 //Create( fromUint32(infoHeader.biWidth), fromUint32(infoHeader.biHeight),
 //  fromUint16(infoHeader.biBitCount));
    fseek(file,fileHeader.bfOffBits,SEEK_SET);
 int step=m_img.widthStep;
 unsigned char* ptr=m_img.imageData+(m_img.height-1)*step;
 for(;ptr>=m_img.imageData;ptr-=step){
  fread(ptr,1,step,file);
 }
    //FOR MOT
 fclose(file);
 return true;

}

//============================================================================
int CImage::GetEncoderClsid(const WCHAR* format, CLSID* pClsid)
{
   UINT  num = 0;          // number of image encoders
   UINT  size = 0;         // size of the image encoder array in bytes

   ImageCodecInfo* pImageCodecInfo = NULL;

   GetImageEncodersSize(&num, &size);
   if(size == 0)
      return -1;  // Failure

   pImageCodecInfo = (ImageCodecInfo*)(malloc(size));
   if(pImageCodecInfo == NULL)
      return -1;  // Failure

   GetImageEncoders(num, size, pImageCodecInfo);

   for(UINT j = 0; j < num; ++j)
   {
      if( wcscmp(pImageCodecInfo[j].MimeType, format) == 0 )
      {
         *pClsid = pImageCodecInfo[j].Clsid;
         free(pImageCodecInfo);
         return j;  // Success
      }   
   }

   free(pImageCodecInfo);
   return -1;  // Failure
}
//============================================================================

bool  CImage::Save( const char* filename )
{
  
 if( !m_memDC || (m_img.nChannels != 3 && m_img.nChannels != 1)) return false;

 Bitmap bmp(m_img.width,
  m_img.height,
  m_img.widthStep,
  m_img.depth==8?PixelFormat8bppIndexed:PixelFormat24bppRGB ,
  m_img.imageData);
 
 if(m_img.depth==8){
  ColorPalette* palette =
  (ColorPalette*)malloc(sizeof(ColorPalette) + 255 * sizeof(ARGB));
  palette->Flags = PaletteFlagsGrayScale;
  palette->Count = 256;
  for(int i=0;i<palette->Count;i++)palette->Entries[i]=Color::MakeARGB(0,i,i,i);
  bmp.SetPalette(palette);
  free(palette);
 }

 WCHAR wname[256];
 MultiByteToWideChar(
  CP_ACP,0,        
  filename,strlen(filename)+1,      
  wname,sizeof(wname)/sizeof(wname[0])    
 );

 CLSID  encoderClsid;
 if(strstr(filename,".jpg"))
  GetEncoderClsid(L"image/jpeg", &encoderClsid);
 else if(strstr(filename,".bmp"))
  GetEncoderClsid(L"image/bmp", &encoderClsid);
 else if(strstr(filename,".gif"))
  GetEncoderClsid(L"image/gif", &encoderClsid);
 else if(strstr(filename,".png"))
  GetEncoderClsid(L"image/png", &encoderClsid);
 int result= bmp.Save(wname,&encoderClsid);
 return result;

}

//============================================================================

image_header* CImage::GetImage()
{
    return m_memDC != 0 ? &m_img : 0;
}
//============================================================================


HDC  CImage::GetDC()
{
    return m_memDC;
}

//============================================================================

void  CImage::Fill( COLORREF color )
{
    if( m_memDC )
    {
        HBRUSH br = CreateSolidBrush( color );
        RECT rect;
        GetClipBox( m_memDC, &rect );
        FillRect( m_memDC, &rect, br );
        DeleteObject( br );
    }
}
//============================================================================

void  CImage::DrawStr( char* str,RECT pos,COLORREF color )
{
    if( m_memDC )
    {
  SetTextColor(m_memDC,color);
  DrawText(m_memDC,
   str,
   strlen(str),
   &pos,
   DT_NOCLIP
  );
    }
}

//============================================================================

void  CImage::DrawToWnd( CWnd* wnd)
{
    CRect dest;
 if(!wnd) return;
 CClientDC cdc(wnd);
 if(!cdc) return;
 HDC hDCDst=cdc.m_hDC;
 
 wnd->GetClientRect(&dest);
 
 HDC hDCSrc = GetDC();
 if( hDCSrc == NULL ) return;
    if( hDCDst == NULL ) return;

 if( m_img.width > dest.Width() )
    {
        SetStretchBltMode(
               hDCDst,           // handle to device context
               HALFTONE );
    }
    else
    {
        SetStretchBltMode(
               hDCDst,           // handle to device context
               COLORONCOLOR );
    }

    ::StretchBlt(
        hDCDst,
        dest.left,dest.top,
  dest.Width(),dest.Height(),
        hDCSrc,
        0 ,
        0,
  m_img.width,
  m_img.height,
        SRCCOPY );

}

//============================================================================

void CImage::DrawPixel(int x, int y, BYTE r, BYTE g, BYTE b)
{
 int offset=x*m_img.depth/8+y*m_img.widthStep;
 if(x<0||x>=m_img.width||y<0||y>=m_img.height) return;

 unsigned char* dst=m_img.imageDataOrigin+offset;
 dst[0]=b;
 if(m_img.depth>=24){
  dst[1]=g;
  dst[2]=r;
 }
}
//============================================================================
void CImage::DrawLine(float rm,float rb, BYTE r, BYTE g, BYTE b){

 int w=m_img.width;
 for(int x=0;x<w;x++){
  int y=rm*x+rb;
  DrawPixel(x,y,r,g,b);
 }

}
//============================================================================
void CImage::DrawLineSeg(int x0,int x1, int y0,int y1, BYTE r, BYTE g, BYTE b){
 int x,y;
 if(x0!=x1){
  for(x=max(0,x0);x<min(m_img.width-1,x1);x++){
   y=y0+(y1-y0)*(x-x0)/(x1-x0);
   DrawPixel(x, y, r, g, b);
  }
 }
 else{
  for(y=max(0,y0);y<min(m_img.height-1,y1);y++){
   DrawPixel(x0, y, r, g, b);
  }
 }

}
//============================================================================

void CImage::DrawRect(CRect rect, BYTE r, BYTE g, BYTE b)
{
 for(int i=rect.left;i<=rect.right;i++){
  DrawPixel(i, rect.top, r, g, b);
  DrawPixel(i, rect.bottom, r, g, b);
 }
 for(int i=rect.top;i<=rect.bottom;i++){
  DrawPixel(rect.left, i, r, g, b);
  DrawPixel(rect.right, i, r, g, b);
 }
}
//============================================================================

void CImage::DrawRectFilled(CRect rect, BYTE r, BYTE g, BYTE b)
{
 for(int y=rect.top;y<=rect.bottom;y++)
 for(int x=rect.left;x<=rect.right;x++){
  DrawPixel(x, y, r, g, b);
 }
}
//============================================================================

bool CImage::CopyRect(CImage*img, CRect r)
{
 
    if( r.Width() <=0 || r.Height() <=0 ) return false;
 int width=img->Width();
 int height=img->Height();
   
 CRect bound(0,0,width-1,height-1);
 r&=bound;
   
    if(!Create( r.Width()+1, r.Height()+1, 8)) return false;

 unsigned char* src=img->Data();
 unsigned char* dst=Data();

 if( src != dst )
    {
        for( int y = 0; y <=r.Height(); y++ )
        {
            if(img->GetImage()->depth==8)
    memcpy( dst + y*Step(),
     src + (r.top + y)*img->Step() + r.left,
                    (r.Width()+1) );
   else{
    unsigned char* src_line=src+(r.top+y)*img->Step()+ r.left*3;
    unsigned char* dst_line=dst+y*Step();

    for(int x=0;x<=r.Width();x++){
     dst_line[x]=src_line[3*x+1];
    }
   }
        }
    }
   
 return true;
}


//============================================================================
int CImage::LoadPictureFile(CDC* cdc, LPCTSTR szFile,int color)
{
 // open file
 HANDLE hFile = CreateFile(szFile, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
 _ASSERTE(INVALID_HANDLE_VALUE != hFile);

 // get file size
 DWORD dwFileSize = GetFileSize(hFile, NULL);
 if(dwFileSize==0) return 0;
 _ASSERTE(-1 != dwFileSize);

 LPVOID pvData = NULL;
 // alloc memory based on file size
 HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, dwFileSize);
 _ASSERTE(NULL != hGlobal);

 pvData = GlobalLock(hGlobal);
 _ASSERTE(NULL != pvData);

 DWORD dwBytesRead = 0;
 // read file and store in global memory
 BOOL bRead = ReadFile(hFile, pvData, dwFileSize, &dwBytesRead, NULL);
 _ASSERTE(FALSE != bRead);
 GlobalUnlock(hGlobal);
 CloseHandle(hFile);

 LPSTREAM pstm = NULL;
 // create IStream* from global memory
 HRESULT hr = CreateStreamOnHGlobal(hGlobal, TRUE, &pstm);
 _ASSERTE(SUCCEEDED(hr) && pstm);

 // Create IPicture from image file
 LPPICTURE gpPicture;

 hr = ::OleLoadPicture(pstm, dwFileSize, FALSE, IID_IPicture, (LPVOID *)&gpPicture);
 _ASSERTE(SUCCEEDED(hr) && gpPicture);
 pstm->Release();

 OLE_HANDLE m_picHandle;

 gpPicture->get_Handle(&m_picHandle);
 //pBitmap->DeleteObject();
 CBitmap tempBMP;
 tempBMP.Attach((HGDIOBJ) m_picHandle);
 BITMAP bm;
 GetObject(tempBMP.m_hObject, sizeof(bm), &bm);
 
 unsigned char* tempBuffer=new unsigned char[bm.bmWidthBytes*bm.bmHeight];
 
 int w=bm.bmWidth;
 int h=bm.bmHeight;
 Create(w,h,color?24:8);
 unsigned char* ptr=m_img.imageData;
 int step=m_img.widthStep;
 if(color){
  tempBMP.GetBitmapBits(m_img.imageSize,tempBuffer);
  unsigned char*src=tempBuffer;
  for(int y=0;y<h;y++){
   memcpy(ptr,src,w*3);
   ptr+=step;
   src+=bm.bmWidthBytes;
  }
 }
 else{
  if(bm.bmBitsPixel==8){
   tempBMP.GetBitmapBits(m_img.imageSize,tempBuffer);
   unsigned char*src=tempBuffer;
   for(int y=0;y<h;y++){
    memcpy(ptr,src,w);
    ptr+=step;
    src+=bm.bmWidthBytes;
   }
  }
  else{
   tempBMP.GetBitmapBits(bm.bmWidthBytes*bm.bmHeight,tempBuffer);
   unsigned char*src=tempBuffer;
   for(int y=0;y<h;y++){
    for(int x=0;x<w;x++){
     ptr[x]=src[3*x+1];
    }
    ptr+=step;
    src+=bm.bmWidthBytes;
    
   }
  }
 }
 delete tempBuffer;
 return 1;
}
//============================================================================
void CImage::Resize(CImage*in,int ratio,int inverse){
 int w=in->Width()/ratio;
 int h=in->Height()/ratio;
 Create( w,h, 8 );
 unsigned char* ptr=m_img.imageData;
 int step=m_img.widthStep;
 int pixel_step=ratio*in->GetImage()->depth/8;
 unsigned char*src=in->GetImage()->imageData;
 for(int y=0;y<h;y++){
  for(int x=0;x<w;x++){
   ptr[x]=src[pixel_step*x];
   if(inverse)ptr[x]=0xff-ptr[x];
  }
  ptr+=step;
  src+=in->Step()*ratio;
 }
}
//============================================================================
void CImage::Invert(){

 unsigned char* ptr=m_img.imageData;
 for(int y=0;y<m_img.height;y++){
  for(int x=0;x<m_img.width;x++){
   ptr[x]=0xff-ptr[x];
  }
  ptr+=m_img.widthStep;
 }
}
//============================================================================


//SdkTest.cpp

// SdkTest.cpp : 定义应用程序的类行为。
//

#include "stdafx.h"
#include "SdkTest.h"
#include "include/HCNetSDK.h"
#include "VideoView.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

//#param comment(lib, "HCNetSDK.lib")
//#param comment(lib, "PlayCtrl.lib")
// CSdkTestApp

BEGIN_MESSAGE_MAP(CSdkTestApp, CWinApp)
 ON_COMMAND(ID_HELP, &CWinApp::OnHelp)
END_MESSAGE_MAP()


// CSdkTestApp 构造

CSdkTestApp::CSdkTestApp()
{
 // TODO: 在此处添加构造代码,
 // 将所有重要的初始化放置在 InitInstance 中
}


// 唯一的一个 CSdkTestApp 对象

CSdkTestApp theApp;


// CSdkTestApp 初始化

BOOL CSdkTestApp::InitInstance()
{
 // 如果一个运行在 Windows XP 上的应用程序清单指定要
 // 使用 ComCtl32.dll 版本 6 或更高版本来启用可视化方式,
 //则需要 InitCommonControlsEx()。否则,将无法创建窗口。
 INITCOMMONCONTROLSEX InitCtrls;
 InitCtrls.dwSize = sizeof(InitCtrls);
 // 将它设置为包括所有要在应用程序中使用的
 // 公共控件类。
 InitCtrls.dwICC = ICC_WIN95_CLASSES;
 InitCommonControlsEx(&InitCtrls);

 CWinApp::InitInstance();

 AfxEnableControlContainer();

 // 标准初始化
 // 如果未使用这些功能并希望减小
 // 最终可执行文件的大小,则应移除下列
 // 不需要的特定初始化例程
 // 更改用于存储设置的注册表项
 // TODO: 应适当修改该字符串,
 // 例如修改为公司或组织名
 SetRegistryKey(_T("应用程序向导生成的本地应用程序"));

 BOOL bRet = NET_DVR_Init(); //wuyang, 初始化SDK

 CVIDEOVIEW dlg;
 m_pMainWnd = &dlg;
 INT_PTR nResponse = dlg.DoModal();
 if (nResponse == IDOK)
 {
  // TODO: 在此放置处理何时用
  //  “确定”来关闭对话框的代码
 }
 else if (nResponse == IDCANCEL)
 {
  // TODO: 在此放置处理何时用
  //  “取消”来关闭对话框的代码
 }

 // 由于对话框已关闭,所以将返回 FALSE 以便退出应用程序,
 //  而不是启动应用程序的消息泵。
 return FALSE;
}

 

// video.cpp : 定义应用程序的类行为。
//

#include "stdafx.h"
#include "video.h"
#include "videoDlg.h"
#include "VideoView.h"
#include <string>
using namespace std;

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// CvideoApp

BEGIN_MESSAGE_MAP(CvideoApp, CWinApp)
 ON_COMMAND(ID_HELP, &CWinApp::OnHelp)
END_MESSAGE_MAP()


// CvideoApp 构造

CvideoApp::CvideoApp()
{
 // TODO: 在此处添加构造代码,
 // 将所有重要的初始化放置在 InitInstance 中

}


// 唯一的一个 CvideoApp 对象

//CvideoApp theApp;


// CvideoApp 初始化

BOOL CvideoApp::InitInstance()
{
 // 如果一个运行在 Windows XP 上的应用程序清单指定要
 // 使用 ComCtl32.dll 版本 6 或更高版本来启用可视化方式,
 //则需要 InitCommonControlsEx()。否则,将无法创建窗口。
 INITCOMMONCONTROLSEX InitCtrls;
 InitCtrls.dwSize = sizeof(InitCtrls);
 // 将它设置为包括所有要在应用程序中使用的
 // 公共控件类。
 InitCtrls.dwICC = ICC_WIN95_CLASSES;
 InitCommonControlsEx(&InitCtrls);

 CWinApp::InitInstance();

 AfxEnableControlContainer();

 // 标准初始化
 // 如果未使用这些功能并希望减小
 // 最终可执行文件的大小,则应移除下列
 // 不需要的特定初始化例程
 // 更改用于存储设置的注册表项
 // TODO: 应适当修改该字符串,
 // 例如修改为公司或组织名
 SetRegistryKey(_T("应用程序向导生成的本地应用程序"));

 CVIDEOVIEW dlg;
 m_pMainWnd = &dlg;
 INT_PTR nResponse = dlg.DoModal();
 if (nResponse == IDOK)
 {
  // TODO: 在此放置处理何时用
  //  “确定”来关闭对话框的代码
 }
 else if (nResponse == IDCANCEL)
 {
  // TODO: 在此放置处理何时用
  //  “取消”来关闭对话框的代码
 }

 // 由于对话框已关闭,所以将返回 FALSE 以便退出应用程序,
 //  而不是启动应用程序的消息泵。
 return FALSE;
}

 

// VIDEOVIEW.cpp : 实现文件
//

#include "stdafx.h"
#include "video.h"
#include "VIDEOVIEW.h"
#include "SdkTest.h"
#include "include/HCNetSDK.h"
#include "include/plaympeg4.h"
#include "stdio.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

 

LONG g_iPort = -1;      //用于保存软解码的播放库port号
LONG lUserID = -1;      //相机登录的ID

 

PVIDEO_SET PData = (PVIDEO_SET)malloc(sizeof(PVIDEO_SET)); //用于接收回调函数返回的视频图片信息,在写入视频的文件中使用
PPIC_SET PData1 = (PPIC_SET)malloc(sizeof(PPIC_SET)); //用于接收回调函数返回的视频图片信息,在写入图片的文件中使用


/*********************************************************************************************************
写入文件的全局变量定义
*********************************************************************************************************/
FILE* file1 = NULL;        //用于保存视频文件
FILE* file2 = NULL;       //用于保存抓拍图片的文件
static unsigned int Pic_filenm = 1;     //用于写入的图片的文件名后缀
static unsigned int Pic_filedir = 1;   //用于写入的图片的文件目录后缀
static int n_byte = 1;        //用于测试videosave()函数
static int p_byte =1;          //用于测试PicSave()函数
CString Pic_prefileDir = "D:\\test\\pic\\";
CString Pic_fnm,Pic_fnmdir,Pic_filename;
CVIDEOVIEW a,b;


/*********************************************************************************************************
函数功能:保存视频,写入1.yuv文件
*********************************************************************************************************/
 void CVIDEOVIEW:: VideoSave(PVIDEO_SET lpParam)
{

 PData = lpParam;
 if ((file1 = fopen("D:\\test\\video\\1.yuv","ab+")) == NULL)
 {
  TRACE("file1 cannot open!\n");
 }
 else
 {
  fwrite(PData->buffer,1,PData->size,file1);
  TRACE("the video function is preducted for %d\n",n_byte++);
  if (file1)
  {
   fclose(file1);
   file1 = NULL;
  }
 }
 
}


/*********************************************************************************************************
函数功能:保存图片,写入2.yuv文件
*********************************************************************************************************/
void CVIDEOVIEW::PicSave(PPIC_SET lpParam)
{
  if (Pic_filenm == 50)
  { 
   Pic_filenm =1;    //用于对文件名称记录大小,做出记录
   Pic_filedir++;    //控制文件分层存储在多个路径名称下
  }

  Pic_fnmdir.Format("%d",Pic_filedir);   //要创建文件的目录,用于叠加出绝对文件名
  Pic_fnm.Format("%d",Pic_filenm++);    //要创建的文件名,不带后缀,用于叠加出绝对文件名
  CString Pic_towardDir = Pic_fnmdir + "\\";  //要创建的文件目录,用于在创建目录的函数中创建新的目录
  int sign = this->Createfiledir(Pic_towardDir);
  Pic_filename =  Pic_fnm +".yuv";    //要创建的文件名,用于在创建目录的函数中查找文件是否存在
  CString Pic_name =Pic_prefileDir + Pic_towardDir + Pic_filename; //要创建的文件绝对路径及名称
  PData1 = lpParam;
  if ((file2 = fopen((const char*)Pic_name,"wb+")) == NULL)
  {
   TRACE("file2 cannot open!\n");
  }
  else
  {
   fwrite(PData1->pbuffer,1,PData1->psize,file2);
   TRACE("the pic function is preducted for %d\n",p_byte++);
   if (file2)
   {
    fclose(file2);
    file2 = NULL;
   }
  }
   
}


/*********************************************************************************************************
函数名称:CALLBACK DecCBFun
函数功能:g_RealDataCallBack的回调函数,用于返回相机的视频参数,可以对相机的视频文件内容进行相应处理
*********************************************************************************************************/
void CALLBACK DecCBFun(long nPort,char * pBuf,long nSize,
  FRAME_INFO * pFrameInfo,  long nReserved1,long /*nReserved2*/)
{
 LONG lFrameType = pFrameInfo->nType;
  if(lFrameType ==T_YV12)
 {
  PVIDEO_SET m_video = (PVIDEO_SET)malloc(sizeof(PVIDEO_SET));
  PPIC_SET m_pic = (PPIC_SET)malloc(sizeof(PPIC_SET));
  TRACE("Video nStamp:%d\n",pFrameInfo->nStamp);
  m_video->size = nSize;
  m_video->buffer= pBuf;
  m_pic->pbuffer = pBuf;
  m_pic->psize = nSize;
  a.VideoSave(m_video);
  a.PicSave(m_pic);
  } 
}

 


/*********************************************************************************************************
函数名称:g_RealDataCallBack
函数功能:NET_DVR_RealPlay_V30的回调函数,用于视频实时播放的设置
*********************************************************************************************************/
void CALLBACK g_RealDataCallBack(LONG lRealHandle, DWORD dwDataType, BYTE *pBuffer, DWORD dwBufSize, void *pUser)
{
 LONG lPort = g_iPort; //全局的播放库port号
 BOOL bRet = FALSE;
 switch (dwDataType)
 {
 case NET_DVR_SYSHEAD: //系统头

  if (!PlayM4_GetPort(&lPort))  //获取播放库未使用的通道号
  {
   break;
  }
  g_iPort = lPort; //第一次回调的是系统头,将获取的播放库port号赋值给全局port,下次回调数据时即使用此port号播放
  if (dwBufSize > 0)
  {
   if (!PlayM4_SetStreamOpenMode(lPort, STREAME_REALTIME))  //设置实时流播放模式
   {
    break;
   }

   if (!PlayM4_OpenStream(lPort, pBuffer, dwBufSize, 1024*1024)) //打开流接口
   {
    break;
   }
   if (!PlayM4_SetDecCallBack(lPort,DecCBFun))
   {
    break;
   }
   if (!PlayM4_Play(lPort, NULL)) //播放开始
   {
    break;
   }
  }
 case NET_DVR_STREAMDATA:   //码流数据
  if (dwBufSize > 0 && lPort != -1)
  {
   if (!PlayM4_InputData(lPort, pBuffer, dwBufSize))
   {
    break;
   }
  }
 }
}

 

/*********************************************************************************************************
函数名称: g_ExceptionCallBack
函数功能:NET_DVR_SetExceptionCallBack_V30的回调函数,用于异常处理
*********************************************************************************************************/
void CALLBACK g_ExceptionCallBack(DWORD dwType, LONG lUserID, LONG lHandle, void *pUser)
{
 char tempbuf[256] = {0};
 switch(dwType)
 {
 case EXCEPTION_RECONNECT:    //预览时重连
  printf("----------reconnect--------%d\n", time(NULL));
  break;
 default:
  break;
 }
}

 

 

// CVIDEOVIEW 对话框
IMPLEMENT_DYNAMIC(CVIDEOVIEW, CDialog)

CVIDEOVIEW::CVIDEOVIEW(CWnd* pParent /*=NULL*/)
 : CDialog(CVIDEOVIEW::IDD, pParent)
{
}

CVIDEOVIEW::~CVIDEOVIEW()
{
 NET_DVR_Cleanup();
}


void CVIDEOVIEW::DoDataExchange(CDataExchange* pDX)
{
 CDialog::DoDataExchange(pDX);
}


BEGIN_MESSAGE_MAP(CVIDEOVIEW, CDialog)
 ON_BN_CLICKED(IDC_OPEN_VIDEO, &CVIDEOVIEW::OnBnClickedOpenVideo)
 ON_BN_CLICKED(IDC_SHUTDOWN, &CVIDEOVIEW::OnBnClickedShutdown)
END_MESSAGE_MAP()

 

 

// CVIDEOVIEW 消息处理程序
BOOL CVIDEOVIEW::OnInitDialog()
{
 CDialog::OnInitDialog();
 // 将“关于...”菜单项添加到系统菜单中。
 // IDM_ABOUTBOX 必须在系统命令范围内。
 ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
 ASSERT(IDM_ABOUTBOX < 0xF000);
 CMenu* pSysMenu = GetSystemMenu(FALSE);
 if (pSysMenu != NULL)
 {
  CString strAboutMenu;
  strAboutMenu.LoadString(IDS_ABOUTBOX);
  if (!strAboutMenu.IsEmpty())
  {
   pSysMenu->AppendMenu(MF_SEPARATOR);
   pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
  }
 }
 ShowWindow(SW_MINIMIZE);
 NET_DVR_Init();
 return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}

 

/*********************************************************************************************************
函数功能:打开视频按钮的实现函数,在界面上显示视频,并调用海康相机的接口实现视频的二次回调
*********************************************************************************************************/
void CVIDEOVIEW::OnBnClickedOpenVideo()
{
 NET_DVR_DEVICEINFO_V30 struDeviceInfo;
 memset(&struDeviceInfo, 0, sizeof(NET_DVR_DEVICEINFO_V30));//存放设备参数的结构体
 lUserID = NET_DVR_Login_V30("192.168.1.1", 8000, "admin", "12345", &struDeviceInfo);
 if (lUserID < 0)
 {
  if (NET_DVR_GetLastError() == NET_DVR_PASSWORD_ERROR)//用户名密码错误
  {
   //处理错误信息
  }
  else if(NET_DVR_GetLastError() == NET_DVR_OVER_MAXLINK)//连接到DVR的客户端达到最大
  {    
   //处理错误信息
  }
 }
 _CrtSetBreakAlloc(98500);
 NET_DVR_SetExceptionCallBack_V30(0, NULL,g_ExceptionCallBack, NULL); //异常回调的结构体,用于异常判断
 LONG m_lPlayHandle = -1 ; 
 NET_DVR_CLIENTINFO struPlayInfo;  
 this->GetDlgItem(IDC_VIDEOSHOW, &struPlayInfo.hPlayWnd);//设置播放句柄为有效句柄
 struPlayInfo.lChannel =5;        //预览通道号
 struPlayInfo.lLinkMode = 0;      //最高位(31)为0表示主码流,为1表示子码流0~30位表示连接方式:0-TCP方式;1-UDP方式;2-多播方式;3-RTP方式;
 struPlayInfo.sMultiCastIP = NULL;
 //软解码实现过程
 m_lPlayHandle = NET_DVR_RealPlay_V30(lUserID, &struPlayInfo, g_RealDataCallBack, NULL, 0);//视频二次回调,进入回调的线程
 if (m_lPlayHandle < 0)
 {
  printf("NET_DVR_RealPlay_V30 error\n");
  NET_DVR_Logout(lUserID);
  NET_DVR_Cleanup();
  return;
 }
}

 

/*********************************************************************************************************
函数功能:暂停视频播放按钮的实现函数,在界面上暂停视频的播放,写入文件中止
*********************************************************************************************************/
void CVIDEOVIEW::OnBnClickedShutdown()
{
 // TODO: 在此添加控件通知处理程序代码
 NET_DVR_Logout_V30(lUserID);
}


int CVIDEOVIEW::Createfiledir( CString Picfiledir)
{
 memset(filedir,0,sizeof(filedir));
 strcpy(filedir,"D:\\test\\pic\\");

 if ( _access(filedir,0)!=0)
 {
  CreateDirectory(filedir,NULL);
 }
 strcat(filedir,Picfiledir);
 if ( _access(filedir,0)!=0)
 {
  CreateDirectory(filedir,NULL);
 }
 return 0;
}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值