ldvr-dlg-flow

了解程式流程及GUI生成


更新記錄

item note
20161212 第一版

目錄


program flow

main flow

[ldvr-flow]

ldvr_load_sys_configs

<system.ini>

  • limit_max_camera_num
  • enable_check_disk
    ldvr_hdd_headthy_check(),ldvr_rootdisk_serial_check()
  • looprecord
    ldvr_disk_manage() 每分鐘檢測空間,若不足則刪除最舊的
  • language
    stringtable.c
    0: english,1: cn,2: tw, 3:Russian(俄文)
  • sync_times
  • io_alarm_times
    camera i/o輸入alarm, timeout時間
  • restart (自動重開機)
    • restart_hour
    • restart_minute
    • restart_day(0:每天,1:每週,2:每月)
  • chunnel[i].camera.schedule.enable (啟動錄影排程)
    • chunnel[i].camera.schedule:
      NO_RECORD(不錄影),FULLY_RECORD(全錄影),MOTION_SENSOR_RECORD(移動偵測錄影)

ldvr_schedule_manage

  • restart (自動重開機)
    restart_hour, restart_minute
    restart_day(0:每天,1:每週,2:每月)

  • chunnel[i].camera.schedule.enable (啟動錄影排程)
    chunnel[i].camera.schedule:
    NO_RECORD(不錄影),FULLY_RECORD(全錄影),MOTION_SENSOR_RECORD(移動偵測錄影)

[ldvr_schedule_manage]

ldvr_video_save

每30分1個檔案
.h264記錄raw data
.log記錄相關的flag

1
2
3
4
5
6
7
8
[root@localhost 2016-12-13]# pwd
/disks/1/2016-12-13
[root@localhost 2016-12-13]# ls -l
total 209584
-rw-r--r-- 1 root root 28405484 Dec 13 14:29 4-2016-12-13-14-00.264
-rw-r--r-- 1 root root 15120 Dec 13 14:29 4-2016-12-13-14-00.log
-rw-r--r-- 1 root root 186171749 Dec 13 14:42 4-2016-12-13-14-30.264
-rw-r--r-- 1 root root 15120 Dec 13 14:42 4-2016-12-13-14-30.log

[ldvr_video_save]

GUI

gui_start

設定相關訊號動作

obj event function
window destroy window_ondestroy(): gtk_main_quit()
window key_press_event key_press_event()
drawing_area configure_even configure_event()
drawing_area expose_event expose_event()
drawing_area motion_notify_event motion_notify_event()
drawing_area button_press_event button_press_event()
drawing_area button_release_event button_release_event()
  • gtk_widget_set_events(drawing_area
    GDK_EXPOSURE_MASK
    GDK_LEAVE_NOTIFY_MASK
    GDK_BUTTON_PRESS_MASK
    GDK_BUTTON_RELEASE_MASK
    GDK_BUTTON1_MASK
    GDK_BUTTON2_MASK
    GDK_BUTTON3_MASK
    GDK_KEY_PRESS_MASK
    GDK_POINTER_MOTION_MASK
    GDK_POINTER_MOTION_HINT_MASK

  • ui layout

    1
    2
    3
    window
    + vbox
    + drawing_area
[gui_start]

xv_image_init

取得 gui->im_port (即xv的port id, visualID 0x21?)
取得 gui->im_formats[] (即跟程式相容的模式YUYV)

顯示卡支援: YUY2, YV12, I420, UYVY
程式支援:VIDEO_YUYV, VIDEO_UYVY, VIDEO_YUV420P

gui->im_formats[VIDEO_UYVY] = FMT_VIDEO_UYVY

  • pc200
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    [root@localhost nvr]# xvinfo
    X-Video Extension version 2.2
    screen #0
    Adaptor #0: "NX Texture Video"
    number of ports: 16
    port base: 63
    operations supported: PutImage
    supported visuals:
    depth 24, visualID 0x21
    no port attributes defined
    maximum XvImage size: 2048 x 2048
    Number of image formats: 4
    id: 0x32595559 (YUY2)
    guid: 59555932-0000-0010-8000-00aa00389b71
    bits per pixel: 16
    number of planes: 1
    type: YUV (packed)
    id: 0x32315659 (YV12)
    guid: 59563132-0000-0010-8000-00aa00389b71
    bits per pixel: 12
    number of planes: 3
    type: YUV (planar)
    id: 0x30323449 (I420)
    guid: 49343230-0000-0010-8000-00aa00389b71
    bits per pixel: 12
    number of planes: 3
    type: YUV (planar)
    id: 0x59565955 (UYVY)
    guid: 55595659-0000-0010-8000-00aa00389b71
    bits per pixel: 16
    number of planes: 1
    type: YUV (packed)
    [root@localhost nvr]#

general_init

  • general_init
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    -frame (GtkFixed)
    - label(20,20) , entry(285,20) => Video Loss Alarm continues(S)
    - label(20,20 + 35) , combo(285,20 +35) => V-Loss Send Mail
    - label(20,20 + 35*2) , entry(285,20 +35*2) => IO Alarm Continus(S)
    - label(20,20 + 35*3) , entry(285,20 +35*3) => Motin Alarm continues(S)
    - label(20,20 + 35*4) , entry(285,20 +35*4) => Siren continues(S)
    - label(20,20 + 35*5) , entry(285,20 +35*5) => Auto Scan interval(S)
    - label(20,20 + 35*6) , combo(285,20 +35*6) => Language
    - label(20,20 + 35*7) , button(285,20 +35*7) => Max Cameras
    - check_button(20,20 + 35*8) => Overwrite
    - check_button(20,20 + 35*9) => Auto Reboot
    - label(20,20 + 35*10), combo(285,20 +35*10), button(), button() => Reboot At
    - check_button(20,20 + 35*11) => Auto Lougout
    - label(20,20 + 35*12) , entry(285,20 +35*12) => Idle Time (Min) [30]
    - label(20,20 + 35*13) , combo(285,20 +35*13) => Num of main stream display
    - label(20,20 + 35*14) , combo(285,20 +35*14) => Max num of play
    - label(20,20 + 35*15) , combo(285,20 +35*15) => Auto synchronize with NVR time
    - check_button(20,20 + 35*16) => Check disk err

video decode

程序如下:

  • thread: ldvr_video_recv
    將收到的碼流存在play_buf
  • thead: ldvr_video_decode
    取出play_buf解碼儲到(video_display_buf, cap_buf)
  • thead: ldvr_pre_displayvideo
    取出video_display_buf,覆製到pre_display_buf
    畫出record_mark
    設定prepare = 1 (表示pre_display_buf資料準備好了)
    等待displayed
  • time: diplayvideo (每40ms,做一次)
    等得prepare == 1
    取出predisplay_buf覆製到xvimage->data
    設定輸出畫面大小

ldvr_video_decode

  • avcodec_decode_video2 對packet中的幀進行解碼
  • 解碼得到圖像後,很有可能不是我們想要的格式,因此需要使用 swscale 來做轉換,調用sws_getCachedContext 得到轉換上下文

  • sws_getCachedContext()
    輸入原本width,height,format
    設定輸出width,height,format(PIX_FMT_YUV420P)

  • avcodec_open2() 解出h264資料之後
    送到sws_xx,做轉換(轉成預計大小及YUV格式)
    並且資料存在video_display_buf

[ldvr_video_decode]

ldvr_pre_displayvideo

  • 先設定prepare為0,表示pre_display_buf準備好
  • 先設定display為0,來等待display ready
[ldvr_pre_displayvideo]

displayvideo

[displayvideo]

libxv

X Window System video extension

xv - Linux man page

Xv - X Window System video extension

  • The X Video Extension (Xv) extension provides support for video adaptors attached to an X display.
  • xvqueryextension(): to determine the status of the extension
  • xvqueryadaptors(): to get a description of what video adaptors exist,
  • XvImage formats supported by the port may be queried with xvlistimageformats()
  • XvImages may be displayed with: xvputimage()

在X11下有几种可以显示图像的方式

  • 视频回放
    常见图像接口列表:
    X11: 一般性的使用共享内存的X11输出。
    XVideo: 一种X11接口扩展,支持任何X11图像的可拖拉。
    SDL: 简单直接媒体层。
    DGA: 直接图片存取。
    SVGAlib: 低层次掌控图片层
  • X11下几种显示图像的方式
  • XVideo
    Xorg 有种扩展叫做 XVideo (或称Xvideo, Xv, xv)
    xv使用X的XVideo扩展来作为硬件加速
    一般可以使用xvinfo指令来查看你的显卡是否支持xv输出

  • SDL
    無使用到顯示卡硬体
    SDL 表示Simple Directmedia Layer,简单的直接媒体层。这个SDL提供了一个统一的视频和音频接口,一般的电脑游戏经常辉调用这个接口,因为这个接口使得程序在不知道视频设备的 情况下,通过这个接口来访问底层的视频设备

  • DGA
    DGA 表示Direct Graphics Access,直接图形访问。它允许程序跳过X服务器直接写入framebuffer内存区

  • Framebuffer选项
    前提是你的内核必须支持framebuffer(fbdev)

XFree86 延伸的 X 用戶端支援

  • xgamma
    透過 XF86VidMode 延伸改變顯示器之 Gamma 系數的校正

    1
    2
    $ xgamma
    -> Red 1.000, Green 1.000, Blue 1.000
  • xrandr
    透過 RandR 延伸調整螢幕大小或旋轉螢幕

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    $ xrandr
    Screen 0: minimum 8 x 8, current 3840 x 1080, maximum 32767 x 32767
    DP1 disconnected (normal left inverted right x axis y axis)
    DP2 disconnected (normal left inverted right x axis y axis)
    DP3 disconnected (normal left inverted right x axis y axis)
    HDMI1 disconnected (normal left inverted right x axis y axis)
    HDMI2 disconnected (normal left inverted right x axis y axis)
    HDMI3 connected primary 1920x1080+1920+0 (normal left inverted right x axis y axis) 476mm x 267mm
    1920x1080 60.0*+
    1280x1024 75.0 60.0
    1152x864 75.0
    1024x768 75.1 60.0
    800x600 75.0 60.3
    640x480 75.0 60.0
    720x400 70.1
    VGA1 connected 1920x1080+0+0 (normal left inverted right x axis y axis) 527mm x 296mm
    1920x1080 60.0*+
    1680x1050 60.0
    1280x1024 75.0 60.0
    1440x900 59.9
    1280x960 60.0
    1280x800 59.8
    1152x864 75.0
    1280x720 60.0
    1024x768 75.1 70.1 60.0
    832x624 74.6
    800x600 72.2 75.0 60.3 56.2
    640x480 75.0 66.7 60.0
    720x400 70.1
    VIRTUAL1 disconnected (normal left inverted right x axis y axis)
  • xvidtune
    透過 XF86VidMode 延伸提供 Xorg 的視訊模式調校器

    1
    2
    3
    $ xvidtune
    Vendor: (null), Model: (null)
    Num hsync: 0, Num vsync: 0
  • xvinfo
    列印 X Video 延伸配接卡資訊

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    [root@localhost nvr]# xvinfo
    X-Video Extension version 2.2
    screen #0
    Adaptor #0: "NX Texture Video"
    number of ports: 16
    port base: 63
    operations supported: PutImage
    supported visuals:
    depth 24, visualID 0x21
    no port attributes defined
    maximum XvImage size: 2048 x 2048
    Number of image formats: 4
    id: 0x32595559 (YUY2)
    guid: 59555932-0000-0010-8000-00aa00389b71
    bits per pixel: 16
    number of planes: 1
    type: YUV (packed)
    id: 0x32315659 (YV12)
    guid: 59563132-0000-0010-8000-00aa00389b71
    bits per pixel: 12
    number of planes: 3
    type: YUV (planar)
    id: 0x30323449 (I420)
    guid: 49343230-0000-0010-8000-00aa00389b71
    bits per pixel: 12
    number of planes: 3
    type: YUV (planar)
    id: 0x59565955 (UYVY)
    guid: 55595659-0000-0010-8000-00aa00389b71
    bits per pixel: 16
    number of planes: 1
    type: YUV (packed)
  • 進階使用者可以使用這些應用程式在執行階段調校 Xorg 伺服器的設定。此程序提供有關目前系統硬體功能的更多資訊。

  • 一般影幕顯示為RGB,但H264輸出為YUV
    因此需要做轉換YUV -> RGB,
    由於是浮點的轉換會吃CPU的能力,有些顯示卡有支援自已轉換
    如上例所示GPU可以吃YUY2,YV12,I420,UYVY等4種

xorg 架构 将来 以及一些基本常识浅析

  • 一般现在的显卡,比如ati的driver,第一个port是overlay,剩下的15个port都是用tuxture来实现的
  • xvideo这边就目前来说,好像很多接口都已经没有人用了,用的就是XvPutImage,因为Video本身来说解码完成之后就是一帧一帧的数据
  • 格式转换,比如yuv->rgb,因为我们的屏幕是rgb的,但是mpeg4或者h264等等解开一般都是yuv格式的,当然yuv格式又分成很多种,硬件不一定都支持,这个时候就需要软件转换,这个就是copyplanerdata或者copypackedata的工作了

XvPutImage

linux下Qt+Xv显示视频总结

  • Xv中的显示图片的函数--XvPutImage,和Xlib提供的显示图片函数XPutImage只相差一个字母,但是这个函数功能确强大了许多
  • XvPutImage(Display , XvPortID, Window, GC , XvImage *, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int dst_w, int dst_h);
    针对此函数,我们来看怎么使用此函数,会用了此函数,就可以显示YUV数据了;
    此函数需要结合一个QWidget才能够显示图片;
    第一个参数,可以通过QWidget的x11Display()函数得到;
    第二个,可以通过XvQueryAdaptors得到;
    第三个,通过QWidget的winId()得到;
    第四个,通过XvCreateImage得到;

    1
    2
    3
    4
    5
    6
    XvPutImage(gui->dpy, gui->im_port, gui->win, gui->gc, gui->xvimage, 0, 0,
    MAX_XV_WIDTH,MAX_XV_HEIGHT, 0, 0, gui->screen_width, gui->screen_height);

    gui->dpy = gdk_x11_display_get_xdisplay()
    gui->gc = XCreateGC()
    gui->xvimage = XvCreateImage(,FMT_VIDEO_YUV420P)
  • XPutImage不支持yuv格式的数据,常用的就是rgb格式

  • 基于X Video Extension库的,XvPutImage则可能支持yuv格式的数据,这个显卡有关

其它功能

video_scan

cur_video: 設定要顯示的最小ch
video_coun: 設定這個畫面有幾CH(2x2,3x3,4x4..)
selected: 設定這個分割畫面,那ch輸出聲音

[video_scan]
  • XvStopVideo(dpy, port, draw)

    • XvStopVideo − stop active video
    • XvStopVideo(3) stops active video for the specified port and drawable
      1
      2
      3
      4
       XvStopVideo(gui->dpy, gui->im_port, gui->win);
      //gui->win = gdk_x11_drawable_get_xid(drawing_area->window);
      //gui->dpy = gdk_x11_display_get_xdisplay(gtk_widget_get_display(drawing_area));
      //gui->gc = XCreateGC(gui->dpy, gui->win, 0, NULL);
  • dpy
    Specifies the connection to the X server.

  • port
    Specifies the port for which video is to be stopped.
  • draw
    Specifies the drawable associated with the named port

tty_debug方式

  • 先使用ssh登入,查看登入的(/dev/ptsx)
    -查看登入的ptsx: env | grep pts
  • 設定/config/system.ini內的(tty_debug=1)
  • 開啟程式輸入要導出的/dev/ptsx
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    [root@localhost config]# env | grep pts
    SSH_TTY=/dev/pts/3
    [root@localhost config]# main<line:9916> ============>>>============== start mount disk

    getrootdisk<line:206> cmd:df > rootdisk.tmp res=0 errno=11
    mount_disks<line:379> rootdisk:sda
    mount_disks<line:392> readline1: major minor #blocks name
    mount_disks<line:392> readline2:
    mount_disks<line:392> readline3: 8 0 3917592 sda
    mount_disks<line:402> part len=4 sda
    do_mount<line:289> start mount ----->>>-----[mount -t ext4 /dev/sda2 /disks/1] step=4 res=0 errno=22
    do_mount<line:d> res=292 errno=0
    do_mount<line:317> end mount -----<<<----- res=0
    do_umount<line:271> umount /disks/1 res=0 errno=2 step=5
    mount_disks<line:392> readline4: 8 1 131072 sda1

gdk function


參考

其它