?? gtk_cam.c
字號:
#include <strings.h>#include <stdio.h>#include <unistd.h>#include <sys/types.h>#include <sys/mman.h>#include <sys/stat.h>#include <fcntl.h>#include <sys/ioctl.h>#include <time.h>#include <gtk/gtk.h>#include <errno.h>#include <stdlib.h>#include "grab-ng.h"#include "dh-ioctl.h"//#define __YUV422_CAP__ //采用YUV格式采集int TOP = 0, LEFT = 0; //窗體起始坐標int COLS = 768, ROWS = 288; //采集窗體的大小int frame = 0;int send_num = 0;int bt8x8_handle = 0; //設備句柄unsigned char *card0_buf = NULL; //硬件采集到的原始圖像數據指針unsigned char *card0_dest_buf = NULL; //經過格式轉換后的圖像數據指針char title[256];int g_err_num = 0;int global_frames = 0; //用來計算FPSint capture_flag = 0; //preview采集控制參數int overlay_flag = 0; //overlay采集控制參數int b_current = 0, c_current = 0, s_current = 0, h_current = 0; //用來存取圖像亮度對比度等參數GtkObject *b_adj, *c_adj, *s_adj, *h_adj;time_t stTime;GtkWidget *main_win;GtkWidget *status;GtkWidget *darea;GtkWidget *label;gdouble gtk_adjustment_get_value (GtkAdjustment * adjustment);int send_expose (void);void on_darea_expose (GtkWidget * widget);gint configure_event (GtkWidget * widget);static void overlay_display (void);//打開設備void open_dev (void){ int rc; card0_dest_buf = (unsigned char *) malloc (768 * 576 * 3); //申請存放處理后圖像數據的內存空間 bt8x8_handle = dh_OpenVideo (0); //打開設備 if (bt8x8_handle < 0) { printf (dh_GetErrInfo ()); free (card0_dest_buf); exit (-1); }#ifdef __YUV422_CAP__ rc = dh_MSetCaptureNorm (bt8x8_handle, COLS, ROWS, VIDEO_YUYV); //YUV格式采集#else rc = dh_MSetCaptureNorm (bt8x8_handle, COLS, ROWS, VIDEO_BGR24); //BGR格式采集#endif if (rc < 0) { printf (dh_GetErrInfo ()); } if (dh_SetVideoSource (bt8x8_handle, VIDEO_SOURCE_COMPOSITE0) < 0) //設置源路為復合視頻1 { printf (dh_GetErrInfo ()); } if (dh_SetVideoStandard (bt8x8_handle, VIDEO_MODE_PAL) < 0) //設置源路制式為PAL制 { printf (dh_GetErrInfo ()); }//default value dh_SetBrightness (bt8x8_handle, 65535 / 2); dh_SetContrast (bt8x8_handle, 65535 / 2); dh_SetSaturation (bt8x8_handle, 65535 / 2); dh_SetHue (bt8x8_handle, 65535 / 2);}/*---------------------------菜單要調用的函數(callback)---------------------------------*///菜單項preview要調用的函數static void preview_display (void){ time (&stTime); g_err_num = 0; //采集之前判斷是否有視頻信號輸入 if (!dh_IsVideoOn (bt8x8_handle)) { printf ("Video source not ready.\n"); return; } //如果正在overlay采集,先停止overlay采集 if (overlay_flag) overlay_display (); //由capture_flag判斷開始采集還是停止采集 if (capture_flag == 0) { capture_flag = 1; //如果窗體大小變化,每次采集前得重新設置采集參數#ifdef __YUV422_CAP__ dh_MSetCaptureNorm (bt8x8_handle, COLS, ROWS, VIDEO_YUYV);#else dh_MSetCaptureNorm (bt8x8_handle, COLS, ROWS, VIDEO_BGR24);#endif dh_MStartCapture (bt8x8_handle, 4); //發往內存循環采集命令,使用4個緩沖區 gtk_timeout_add (10, (GtkFunction) send_expose, NULL); //每10秒調用一次函數send_expose() } else { capture_flag = 0; dh_MStopCapture (bt8x8_handle); //停止往內存循環采集 }}//定時器調用的函數,實現連續采集顯示int send_expose (void){ if (capture_flag == 1) { //返回采集完成當前幀的指針,同時發出采集下幀的命令 card0_buf = dh_MGetNextFrame (bt8x8_handle); if (NULL == card0_buf) { printf ("card0_buf is NULL.\n"); //如果采集錯誤,重啟采集 dh_MStopCapture (bt8x8_handle); dh_MStartCapture (bt8x8_handle, 4); g_err_num++; } else { on_darea_expose (darea); //調用此函數實現圖像顯示 //釋放內存,否則循環采集無法進行下去 if (dh_MReleaseBuf (bt8x8_handle) < 0) { printf (dh_GetErrInfo ()); } } } return 1;}//菜單項overlay調用的函數:往屏幕采集static voidoverlay_display (void){ int wx, wy; wx = TOP + 4; wy = LEFT + 56; //采集之前判斷是否有視頻信號輸入 if (!dh_IsVideoOn (bt8x8_handle)) { printf ("Video source not ready.\n"); return; } gtk_widget_set_uposition (main_win, TOP, LEFT); if (overlay_flag == 0) { //如果正在preview采集,先停下來 if(capture_flag) { capture_flag = 0; dh_MStopCapture (bt8x8_handle); } //開始overlay采集 dh_OStartCapture (bt8x8_handle, COLS, ROWS, wx, wy); overlay_flag = 1; } else { //停止overlay采集 dh_OStopCapture (bt8x8_handle); overlay_flag = 0; }}//菜單項grab調用的的函數抓單幀static void grab_one_display (void){ int i; time (&stTime); g_err_num = 0; //如果正在preview采集,先停下來 if (capture_flag == 1) preview_display (); //stop capture //如果正在overlay采集,先停下來 if (overlay_flag) overlay_display (); //采集之前判斷是否有視頻信號輸入 if (!dh_IsVideoOn (bt8x8_handle)) { printf ("Video source not ready.\n"); return; }//for(;;) //死循環抓單幀采集,用來測試性能 { card0_buf = dh_MCaptureOne (bt8x8_handle); //正常抓單幀或單場采集,FPS最高8幀/秒 //card0_buf = dh_MFastCaptureOne(bt8x8_handle); //快速抓單幀或單場采集,FPS可達到16幀/秒 //dh_MSnapOne(bt8x8_handle); //card0_buf = dh_MGetSnapOneStatus(bt8x8_handle); if (NULL == card0_buf) { printf (dh_GetErrInfo ()); g_err_num++; } else { on_darea_expose (darea); //調用此函數實現圖像顯示 //釋放內存,否則循環采集無法進行下去,如果是快速采集則無需調用此函數 if (dh_MReleaseBuf (bt8x8_handle) < 0) { printf (dh_GetErrInfo ()); } } } gtk_statusbar_push (GTK_STATUSBAR (status), 1, "Grab a picture"); g_message ("Grab a picture!\n");}//此函數用來顯示圖像和計算FPSvoid on_darea_expose (GtkWidget * widget){ static time_t init, end; static int frames; if (!frames) { time (&init); } if (!card0_buf) { return; } gdk_threads_enter (); //轉換成24位RGB#ifdef __YUV422_CAP__ yuv422_to_rgb24 (card0_dest_buf, card0_buf, COLS * ROWS);#else redblue_swap (card0_dest_buf, card0_buf, COLS * ROWS);#endif //顯示圖像 gdk_draw_rgb_image (widget->window, widget->style->white_gc, 0, 0, COLS, ROWS, GDK_RGB_DITHER_NORMAL, card0_dest_buf, COLS * 3); gdk_threads_leave (); frames++; time (&end); if (end - init >= 1) { global_frames = frames; frames = 0; sprintf (title, "RTime=%d,FPS %d,Err=%d", (int) (end - stTime), global_frames, g_err_num); gtk_statusbar_push (GTK_STATUSBAR (status), 1, title); fprintf (stderr, "%s\n", title); }}//退出程序static void exit_program (void){ int rc = 0; capture_flag = 0; //退出程序前先釋放buf if (NULL != card0_buf) { rc = dh_MReleaseBuf (bt8x8_handle); if (rc == 0) card0_buf = NULL; } free (card0_dest_buf); dh_CloseVideo (bt8x8_handle);//關閉設備句柄 gtk_main_quit ();}//菜單項option->SourceInput調用下列函數static void set_ch_video0 (){ dh_SetVideoSource (bt8x8_handle, VIDEO_SOURCE_COMPOSITE0); g_message ("use VIDEO_SOURCE_COMPOSITE0.\n");}static voidset_ch_video1 (void){ dh_SetVideoSource (bt8x8_handle, VIDEO_SOURCE_COMPOSITE1); g_message ("use VIDEO_SOURCE_COMPOSITE1.\n");}static voidset_ch_video2 (void){ dh_SetVideoSource (bt8x8_handle, VIDEO_SOURCE_COMPOSITE2); g_message ("use VIDEO_SOURCE_COMPOSITE2.\n");}static voidset_ch_video3 (void){ dh_SetVideoSource (bt8x8_handle, VIDEO_SOURCE_SVIDEO); g_message ("use VIDEO_SOURCE_SVIDEO.\n");}//菜單項option->SourceNorm調用下列函數static voidset_norm_pal (void){ dh_SetVideoStandard (bt8x8_handle, VIDEO_MODE_PAL); g_message ("change source norm to PAL.\n");}static voidset_norm_ntsc (void){ dh_SetVideoStandard (bt8x8_handle, VIDEO_MODE_NTSC); g_message ("change source norm to NTSC.\n");}static voidset_norm_secam (void){ dh_SetVideoStandard (bt8x8_handle, VIDEO_MODE_SECAM); g_message ("change source norm to SECAM.\n");}static voidclick_ok (GtkWidget * widget, gpointer window){ dh_GetBrightness (bt8x8_handle, &b_current); dh_GetContrast (bt8x8_handle, &c_current); dh_GetSaturation (bt8x8_handle, &s_current);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -