📄 qsdlwidget.cpp
字号:
#include <qwidget.h>#include <qtimer.h>#include <qdatetime.h>#include <qfile.h>#include <qnamespace.h>#include <qpainter.h> #include <qnamespace.h> #include <qevent.h> #include <errno.h>#include <X11/Xlib.h>#include <qapplication.h>#include "QSDLWidget.h"#include "exvideo.h"extern void *_XLockMutex_fn;extern void *_XUnlockMutex_fn;extern void *_XCreateMutex_fn;extern void *_XFreeMutex_fn;extern void *_XInitDisplayLock_fn;extern void *_XFreeDisplayLock_fn;extern void *_Xthread_self_fn;#define DSCLASSDEMO(i) (dsdemoclass[i]->dsdemo)extern int fsWidth;extern int fsHeight;QSDLWidget::QSDLWidget(QWidget* parent, const char* name) : QWidget( parent, name, 0){ int totalcard, totalport; FullArea = FALSE; AllArea = FALSE; _XLockMutex_fn = NULL; if(InitDSPs() == 0) { OutputErrorString("Initial DSP failed.error code is 0x%x\n", GetLastErrorNum()); exit(1); } totalcard = GetTotalDSPs(); totalport = GetTotalChannels(); SelectPort = 0; LastPort = 0; pm = NULL; OutputDebugString("total cards = %d, total ports = %d\n", totalcard, totalport); dsdemoclass = (Dsclass **)malloc(totalport * sizeof(Dsclass *)); memset(dsdemoclass, 0x0, totalport * sizeof(Dsclass *)); checkpass = (short int *)malloc(totalport * sizeof(short int)); memset(checkpass, 0x0, totalport * sizeof(short int)); if ( !(QIm.load("motion.bmp", 0)) ) // .... { OutputErrorString("can't load motion.bmp\n"); pm = NULL; } else pm = new QPixmap(QIm); }video_info* QSDLWidget::GetVideoParam(){ return &(DSCLASSDEMO(SelectPort)->v_info);}void QSDLWidget::SetSelectPort(int port){ if (port <= GetTotalChannels()) { LastPort = SelectPort; SelectPort = port; } }void QSDLWidget::ChangeFullPort() //都是全屏的情况下切换不同通道{ QRect qr( 0, 0, WIN_W, WIN_H); QPaintEvent Qp(qr, TRUE); int chan; chan = GetChanNum(); if (SelectPort == LastPort) return; else { memcpy(&(DSCLASSDEMO(SelectPort)->dstRect), &(DSCLASSDEMO(LastPort)->dstRect), sizeof(SDL_Rect)); memcpy(&(DSCLASSDEMO(SelectPort)->motion_list), &(DSCLASSDEMO(LastPort)->motion_list), sizeof(RECT)); dsdemoclass[LastPort]->DestoryMotion(); dsdemoclass[LastPort]->StopPreview(); dsdemoclass[LastPort]->SetdstRect(chan); dsdemoclass[LastPort]->SetMotion(chan); erase(); paintEvent( &Qp ); #ifdef USE_PREVIEW_TIMER dsdemoclass[SelectPort]->SetPreview(0);#else dsdemoclass[SelectPort]->SetPreview(1);#endif if (DSCLASSDEMO(SelectPort)->motion_flag) dsdemoclass[SelectPort]->SetupMotion(); }}video_info* QSDLWidget::GetVideoDefault(int port){ return &(DSCLASSDEMO(port)->videoDefault);}void QSDLWidget::SetDsclassDefault(){ int port; int LastPort = SelectPort; int totalport = GetTotalChannels(); for (port = 0; port < totalport; port++) { if (!(DSCLASSDEMO(port)->bPreviewOpen)) {#ifdef USE_PREVIEW_TIMER dsdemoclass[port]->SetPreview(0);#else dsdemoclass[port]->SetPreview(1);#endif } if (DSCLASSDEMO(port)-> record_flag) { SelectPort = port; RecordSet(FALSE); } if (DSCLASSDEMO(port)-> cifqcif_flag ) { SelectPort = port; RecordSubSet(FALSE); } DSCLASSDEMO(port)-> cifqcif_flag = 0; DSCLASSDEMO(port)->pictureFormat = ENC_CIF_FORMAT; SetEncoderPictureFormat(DSCLASSDEMO(port)->ChannelHandle, ENC_CIF_FORMAT); (DSCLASSDEMO(port)->frameinfo).IQuantVal = 12; (DSCLASSDEMO(port)->frameinfo).PQuantVal = 12; (DSCLASSDEMO(port)->frameinfo).BQuantVal = 17; (DSCLASSDEMO(port)->frameinfo).KeyFrameIntervals = 25; (DSCLASSDEMO(port)->frameinfo).BFrames = 2; (DSCLASSDEMO(port)->frameinfo).PFrames = 0; (DSCLASSDEMO(port)->frameinfo).FrameRate = 25; SetDefaultQuant(DSCLASSDEMO(port)->ChannelHandle,12, 12, 17); SetIBPMode(DSCLASSDEMO(port)->ChannelHandle, 25, 2, 0, 25); DSCLASSDEMO(port)->brc = brVBR; DSCLASSDEMO(port)->MaxBps = 768000; SetBitrateControlMode(DSCLASSDEMO(port)->ChannelHandle, brVBR); SetupBitrateControl(DSCLASSDEMO(port)->ChannelHandle, 768000); memcpy(&(DSCLASSDEMO(port)->v_info), &(DSCLASSDEMO(port)->videoDefault), sizeof(video_info)); (DSCLASSDEMO(port)->osdinfo).Translucent = 1; (DSCLASSDEMO(port)->osdinfo).Brightness = 255; (DSCLASSDEMO(port)->osdinfo).PosX = 76; (DSCLASSDEMO(port)->osdinfo).PosY = 240; dsdemoclass[port]->SetOsddemo(); if( !(DSCLASSDEMO(port)->osd_flag) ) { SetOsd(DSCLASSDEMO(port)->ChannelHandle, TRUE); DSCLASSDEMO(port)->osd_flag = 1; } (DSCLASSDEMO(port)->logoinfo).Translucent = 0; (DSCLASSDEMO(port)->logoinfo).PosX = 576; (DSCLASSDEMO(port)->logoinfo).PosY = (dsdemoclass[port]->GetVideoHeight()) - 32; if( !(DSCLASSDEMO(port)->logo_flag) ) { dsdemoclass[port]->SetDsLogo(); DSCLASSDEMO(port)->logo_flag = 1; } memset(DSCLASSDEMO(port)->maskRect, 0, 5*sizeof(RECT)); dsdemoclass[port]-> SetMask(); if ( DSCLASSDEMO(port)-> audio_flag ) { SetAudioPreview(DSCLASSDEMO(port)->ChannelHandle, TRUE); DSCLASSDEMO(port)->audio_flag = TRUE; } if ( DSCLASSDEMO(port)-> motion_flag ) { dsdemoclass[port]->DestoryMotion(); DSCLASSDEMO(port)->motion_flag = 0; } if ( DSCLASSDEMO(port)-> imagefile_flag ) { SelectPort = port; ImageStreamSet(0, DSCLASSDEMO(port)->imagewidth, DSCLASSDEMO(port)->imageheight); DSCLASSDEMO(port)-> imagefile_flag = 0; } } SelectPort = LastPort;}DSDEMO* QSDLWidget::GetDsinfo(int port){ return DSCLASSDEMO(port);}void QSDLWidget::SetFullEnable(bool on){ if (FullArea == on) { if ( on ) { OutputDebugString("<><><>in function SetFullEnable \n"); ChangeFullPort(); } return; } mouseDoubleClickEvent(NULL);}void QSDLWidget::ImageStreamCallback(unsigned int channelNumber, void* context){ int width = DSCLASSDEMO(channelNumber)->imagewidth; int height = DSCLASSDEMO(channelNumber)->imageheight; pthread_mutex_lock(&(DSCLASSDEMO(channelNumber)->imagefile_fd_start)); if(DSCLASSDEMO(channelNumber)->imagefile_fd) (DSCLASSDEMO(channelNumber)->imagefile_fd) -> writeBlock((char *)(DSCLASSDEMO(channelNumber)->imageBuf), (width * height * 3)/2); pthread_mutex_unlock(&(DSCLASSDEMO(channelNumber)->imagefile_fd_start)); }void QSDLWidget::ImageStreamSet(int start, unsigned width, unsigned height){ if (start && (!(DSCLASSDEMO(SelectPort)->imageBuf))) { DSCLASSDEMO(SelectPort)->imageBuf = (unsigned char *)malloc((width * height * 3)/2 * sizeof(char)); memset(DSCLASSDEMO(SelectPort)->imageBuf, 0x0, (width * height * 3)/2 * sizeof(char)); dsdemoclass[SelectPort]->CreateImageStreamFiles(); } else if ( (!start) && (DSCLASSDEMO(SelectPort)->imageBuf)) { free(DSCLASSDEMO(SelectPort)->imageBuf); DSCLASSDEMO(SelectPort)->imageBuf = NULL; dsdemoclass[SelectPort]->end_imagestream(); // 注意文件大小不能超过2G } DSCLASSDEMO(SelectPort)->imagefile_flag = start; DSCLASSDEMO(SelectPort)->imagewidth = width; DSCLASSDEMO(SelectPort)->imageheight = height; SetImageStream(DSCLASSDEMO(SelectPort)->ChannelHandle, start, 5, width, height, DSCLASSDEMO(SelectPort)->imageBuf);}void QSDLWidget::ImageStreamAllSet(int start, unsigned width, unsigned height){ int temp = SelectPort; int port; for (port = 0; port < GetTotalChannels(); port++) { SelectPort = port; ImageStreamSet(start, width, height); } SelectPort = temp;}void QSDLWidget::Createdsclass(){ int i, totalport; char SDL_windowhack[32]; int ChannelHandle; int chan; QsStruct QsTemp; QsTemp.qsclass = this; QsTemp.pmf = &QSDLWidget::StreamRead_callback; QsTemp.Startpmf = &QSDLWidget::start_capture_callback; QsTemp.Stoppmf = &QSDLWidget::stop_capture_callback; QsTemp.Messagepmf = &QSDLWidget::message_callback; QsTemp.IPpmf = &QSDLWidget::check_IP_callback; QsTemp.Passwordpmf= &QSDLWidget::check_password_callback; QsTemp.Checkpmf = &QSDLWidget::checkIpAndPass; QsTemp.Disconnectpmf= &QSDLWidget::disconnect_callback; QsTemp.ImageStreamCallbackpmf = &QSDLWidget::ImageStreamCallback; SetsQstruct(&QsTemp); totalport = GetTotalChannels(); chan = GetChanNum(); if(!XInitThreads()) { OutputErrorString("X init error!\n"); } /** Init SDL **/ sprintf(SDL_windowhack, "SDL_WINDOWID=%ld", winId()); OutputDebugString("%ld \n", winId()); putenv(SDL_windowhack); putenv("SDL_VIDEO_YUV_HWACCEL=0"); fprintf(stderr,"Init the sdl...\n"); if(SDL_Init(SDL_INIT_VIDEO) < 0) { OutputErrorString("<sdk_error> init sdl failed!%s\n",SDL_GetError()); exit(0); } pOverlayScreen = SDL_SetVideoMode(fsWidth, fsHeight, 0, SDL_HWSURFACE); // here it is freed by SDL_Quit(); if(pOverlayScreen == NULL) { OutputErrorString("<sdk_error> create the sdl screen failed! for %s!\n", SDL_GetError()); SDL_Quit(); exit(0); } for ( i=0; i<totalport; i++ ) { if ( (ChannelHandle = ChannelOpen( i,InterStream )) < 0 ) { OutputErrorString("open port %d failed\n", i); } dsdemoclass[i] = new Dsclass(i, ChannelHandle, pOverlayScreen); dsdemoclass[i]-> SetdstRect(chan);#ifdef USE_PREVIEW_TIMER dsdemoclass[i]-> SetPreview(0);#else dsdemoclass[i]-> SetPreview(1);#endif dsdemoclass[i]-> CreateThread(); dsdemoclass[i]-> SetMotion(chan); dsdemoclass[i]-> MotionEnable(); } SetDsclassDefault(); RegisterImageStreamCallback((IMAGE_STREAM_CALLBACK)InterImageStreamCallback, NULL); timer = (QTimer **)malloc(totalport *sizeof(QTimer *)); memset(timer, 0x0, totalport *sizeof(QTimer *)); Qtloop = (QTimer **)malloc(totalport *sizeof(QTimer *)); memset(Qtloop, 0x0, totalport *sizeof(QTimer *)); time = (QTime **)malloc( totalport *sizeof(QTime *)); memset(time, 0x0, totalport *sizeof(QTime *)); for (i = 0; i<totalport; i++ ) { char temp[3]; sprintf(temp, "%2d", i); temp[3] = '\0'; timer[i] = new QTimer(this, temp); connect (timer[i], SIGNAL( timeout() ), SLOT(process_time())); Qtloop[i] = new QTimer(this, temp); connect (Qtloop[i], SIGNAL( timeout() ), SLOT(process_time_loop())); time[i] = new QTime(); time[i]->start(); } //需要在板卡初始化化之后才调用的么? }QSDLWidget::~QSDLWidget(){ OutputDebugString("Enter into delete QSDLWidget\n"); int port; int totalport; totalport = GetTotalChannels(); RecordAllSet(FALSE); RecordSubAllSet(FALSE); ImageStreamAllSet(0, 704, 576); if (DSCLASSDEMO(SelectPort)->net_flag) //考虑到网传是统一设置的,所以可以只需考虑一个flag NetTransferSet(FALSE); for(port = 0; port < totalport; port++) { dsdemoclass[port]-> DestoryThread(); pthread_join(DSCLASSDEMO(port)->hPreviewThread, NULL); OutputErrorString("*****************close port%d******************\n", port); // 借用一下OutputErrorString } OutputErrorString("ending threads <<<<<<<<<<<<<<<<<<<<\n"); MotionAllSet(FALSE); if(pm) { delete pm; pm = NULL; } for (port = 0; port < totalport; port++) { if ( DSCLASSDEMO(port)->audio_flag ) break; } if (port != totalport) { SetAudioPreview(DSCLASSDEMO(port)->ChannelHandle, 0); DSCLASSDEMO(port)->audio_flag = 0; } for ( port=0; port<totalport; port++) { ChannelClose(DSCLASSDEMO(port)->ChannelHandle); dsdemoclass[port]->end_record(); dsdemoclass[port]->end_subrecord(); dsdemoclass[port]->end_imagestream(); delete dsdemoclass[port]; delete time[port]; delete timer[port]; delete Qtloop[port]; } if (dsdemoclass) { free(dsdemoclass); dsdemoclass = NULL; } if (checkpass) { free(checkpass); checkpass = NULL; } if (time) { free(time); time = NULL; } if (timer) { free(timer); timer = NULL; } if (Qtloop) { free(Qtloop); Qtloop = NULL; } OutputDebugString("Before DeInitDSPs\n"); DeInitDSPs(); SDL_Quit(); _XLockMutex_fn = NULL; _XUnlockMutex_fn = NULL; _XCreateMutex_fn = NULL; _XFreeMutex_fn = NULL; _XInitDisplayLock_fn = NULL; _XFreeDisplayLock_fn = NULL; _Xthread_self_fn = NULL;}void QSDLWidget::process_time(){ int temp; int Nowport = 0; int timepassed; unsigned int elapseTime; FRAMES_STATISTICS frame_statistics, sub_frame_statistics; float audioframerate,videoframerate; //int bitRate; int totalFrame; int userCount; int LostFrame; for (temp = 0; temp < GetTotalChannels(); temp++) { QTimer* Qtemp = (QTimer*)(this->sender()); if( atoi(Qtemp->name()) == temp) { Nowport = temp; break; } } timepassed = time[Nowport]->elapsed(); elapseTime = (unsigned int)timepassed + (unsigned int)(TIMEDAYS * (DSCLASSDEMO(Nowport)->countdays)); //注意这里,QTime24小时,计数器会自动转换为0 if (timepassed > TIMEDAYS) //49天的问题 DSCLASSDEMO(Nowport)->countdays++; GetFramesStatistics(DSCLASSDEMO(Nowport)->ChannelHandle, &frame_statistics);#if 0 SetupSubChannel(DSCLASSDEMO(Nowport)->ChannelHandle, 1); GetFramesStatistics(DSCLASSDEMO(Nowport)->ChannelHandle, &sub_frame_statistics); SetupSubChannel(DSCLASSDEMO(Nowport)->ChannelHandle, 0);#endif audioframerate = ((float)frame_statistics.AudioFrames)/((float)elapseTime/(float)1000); emit audioChange(Nowport, audioframerate); videoframerate = ((float)frame_statistics.VideoFrames)/((float)elapseTime/(float)1000); emit videoChange(Nowport, videoframerate); totalFrame = frame_statistics.VideoFrames + frame_statistics.AudioFrames; emit totalChange(Nowport, totalFrame); LostFrame = sub_frame_statistics.FramesLost; //bitRate= (int)(float(DSCLASSDEMO(SelectPort)->bit_rate_size)/((float)elapseTime/(float)8000)); emit bitRateChange(Nowport, frame_statistics.CurBps); if( Nowport == 4 ) OutputDebugString("frame_statistics: %d,%d,%d\n", frame_statistics.AudioFrames, frame_statistics.VideoFrames, frame_statistics.CurBps); userCount = MP4_ServerGetState(); if (userCount <= 0) userCount = 0; emit countChange(userCount); }void QSDLWidget::process_time_loop(){ int totalport; char savepath[10]="."; struct statfs bbuf; int Nowport = 0; int temp; int ImageLength = 0; int width; int height; int fps = 5; //在函数SetImageStream中用到 totalport = GetTotalChannels(); for (temp = 0; temp < totalport; temp++) { QTimer* Qtemp = (QTimer*)(this->sender()); if( atoi(Qtemp->name()) == temp) { Nowport = temp; break; } } for (temp = 0; temp < totalport; temp++) { if (DSCLASSDEMO(temp)->imagefile_flag) { width = DSCLASSDEMO(temp)->imagewidth; height = DSCLASSDEMO(temp)->imageheight; ImageLength += (fps * ( width * height * 3/2 ) * TIMECONST )/(8 * 1024); } } if(statfs(savepath, &bbuf) < 0) { OutputErrorString("statsfs() faied, error: %d\n", errno); } else { if((int)(bbuf.f_bavail * (bbuf.f_bsize/1024)) <= (int)((TIMECONST * (totalport * FIXSIZE) + ImageLength) + LastSpace)) // If no enough space, reset count
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -