張文興,孫慶鵬
(沈陽美行科技有限公司,沈陽 110000)
隨著車輛的普及,各類汽車電子產品層出不窮,行車錄影作為車載電子領域眾多產品中的一項重要功能,在交通事故責任認定中發揮著不可替代的作用.眾所周知,車機或是行車記錄儀中的錄影視頻為3-5 分鐘的分段視頻,數量眾多.在事故發生時,人們往往需要的是事故發生時間點前后十幾秒的視頻,并且應對該視頻進行安全備份,便于檢索.因此,對視頻的抓拍以及處理顯得尤為重要.黃凱奇[1]等人對智能視頻監控技術進行分類,對目標檢測與跟蹤、特征提取與分析等經典算法給出了比較全面的綜述.胡博[2]等人設計了一種對監控視頻中的行人進行檢測和抓拍的系統.王崇海[3]利用多維視頻偵查系統檢測和抓拍車輛以及人臉,提取車型、車牌、人臉特征等信息并保存.吳細老[4]提出了一種智能交通視頻抓拍框架,對視頻圖像進行陰影處理與抖動消除,對違章行為進行判定與抓拍.高奎賀[5]提出了采用機動車視頻測速進行輔助超速抓拍的技術.呂正榮[6]提出了一種對變焦的運動目標進行預測抓拍的方法,并利用此方法構建了一種交通違法車輛智能跟蹤抓拍系統.目前對視頻技術的研究與應用要么立足于利用圖像處理與模式識別手段對視頻圖像進行目標檢測、信息提取、恢復、重建等[7-10];要么立足于對視頻監控或抓拍系統的設計與開發[11-14],而對于視頻抓拍本身并沒有過多或深入的研究,涉及到的視頻抓拍都是以抓拍時間點為起始時間點,所拍攝視頻包含的信息缺乏完整性,進而會影響進一步的分析與處理.由此,引出一個問題:當抓拍條件觸發時,能否以抓拍時間點為基準,保存其之前到之后一定時間段內的視頻,研究目的就是以此展開的.
在眾多的智能操作系統中,Android[15,16]系統以其開放性,支持硬件多樣性,強大的SDK 等優勢,迅速成為視頻監控、車載電子、移動終端設備中的主流系統.首先通過定義時間窗口并利用緩存技術,闡述抓拍的基本原理,然后簡要介紹一下Android 系統中音視頻子系統框架,接著提出一種基于Android 系統的視頻抓拍方案的設計與實現,最終給出測試分析以及應用場景.
抓拍所要達到的目標為:當有事件觸發抓拍時,將當前時間點前M秒到后N秒的音視頻數據寫入文件,其中M和N為設定好的預期時間.其基本思路為:預設一個時間窗口M+N,假設當前時間點為時間0 點,對時間段-(M+N)到0 之間的音視頻數據進行緩存,如圖1所示.當觸發抓拍時,創建抓拍文件,等待N秒,從緩存中取出-M到N秒時間段內的音視頻數據,對其進行封裝并寫入文件,如圖2所示.

圖2 觸發抓拍N 秒后的時間窗口
抓拍方案基于Android 原生系統實現,所以在闡述抓拍方案之前,有必要先對Android 的音視頻子系統框架以及其錄制過程做一簡單介紹.
Android 的音視頻子系統(錄制部分)如圖3所示.攝像頭服務(CameraService)和音頻核心服務(Audio Flinger)通過硬件抽象層(HAL)從攝像頭驅動(Camera Driver)、音頻驅動(Audio Driver)中采集音視頻數據.視頻錄制的核心服務(MediaPlayerService)負責音視頻數據的編碼以及封裝.其中,錄制組件(StagefrightRecorder)根據設定的媒體格式類型(MP4、3GP、…)創建組合器(Writer),視頻編碼器(VideoEncoder)以及音頻編碼器(AudioEncoder) 通過共享內存(Shared Memory)從CameraService 和AudioFlinger 服務中獲取音視頻數據并進行編碼,Writer 將編碼后的音視頻數據封裝成設定的媒體格式,并將其寫入文件.應用程序(Applications)調用框架層(Framework)的媒體錄制組件(MediaRecorder)通過Java 本地接口(JNI)與庫層(Libraries)的MediaRecorder組件進行交互.Libraries 層的MediaRecorder 通過Android獨有的綁定(Binder)機制與MediaPlayerService 服務進行進程間通信(IPC).

圖3 Android 音視頻子系統框架(錄制部分)
編碼后的音視頻數據的處理以及封裝由組合器完成,其內部包含兩種線程,一種是獲取并處理編碼后的音視頻數據的軌跡線程,一種是負責將處理后的音視頻數據按照預先設定好的媒體格式封裝并寫入文件的寫線程.軌跡線程一般有兩個,分別對應音頻數據和視頻數據,寫線程只有一個,負責對處理后的音視頻數據進行封裝并寫入文件.
以錄制MP4 文件為例,對音視頻數據的處理和封裝過程如圖4虛線上半部分所示.軌跡線程以幀為單位獲取編碼后的音視頻數據,每幀數據會先進入一個緩存隊列(FIFO,隊列個數與軌跡線程個數相同),當幀的數量達到一定值時,軌跡線程會將這些數據幀打包成固定的數據結構(Chunk),并通知寫線程有新的Chunk 已準備好.同時,軌跡線程將數據幀中的信息及系統環境信息提取匯總存儲在一個被稱為track 的表中,其包含的信息有Chunk 寫入文件的偏移地址stco(sample to chunk offset)、Sample 與Chunk 的映射關系stsc (sample to chunk box)、關鍵幀stss (sync sample box),每一幀的持續時間stts (time to sample box)等.當錄制開始時,寫線程創建文件并封裝文件頭ftyp (file type box)字段,當寫線程接收到Chunk 已準備好的通知后搜索緩存隊列,將對應的Chunk 寫入文件,并將文件的偏移地址更新到相應track 表的stco 項(track 表中其它數據是由軌跡線程維護).當錄像結束時,track表會被寫入到文件尾moov (movie box)字段.

圖4 音視頻數據的處理與封裝過程
抓拍方案的核心思路為:為音頻和視頻分別建立音頻緩存隊列和視頻緩存隊列,并創建一個緩存線程,按照時間從音頻軌跡線程和視頻軌跡線程中獲取打包后的音視頻數據,同時緩存-(N+M)~0 秒的音視頻數據,并實時更新緩存數據的track 表.當有抓拍請求到來時,創建并執行抓拍寫線程,創建文件并封裝文件頭ftyp字段,以抓拍時間點為時間0 點,根據預先設定好的M和N(見圖2)將從-M秒開始的緩存數據寫入文件,執行N秒后,抓拍過程結束,將緩存的音視頻數據的track 表寫入文件尾moov 字段,過程如圖4虛線下半部分所示.抓拍流程如圖5所示.
該方案實現于Android 系統核心服務MediaPlayer Service 中的StagefrightRecorder 組件和Writer 組件中,并為MediaRecorder 提供了抓拍接口,以便對人機接口(HMI)支持.

圖5 抓拍流程圖
為了測試抓拍的時間精度以及對系統性能的影響,將其移植進Android 系統中,硬件配置為主芯片:MTK6735,4 core,1.3 G;CPU:ARM Cortex-A53;內存:2 GB;攝像頭分辨率:1280×800.該方案實現所在進程為Android 媒體服務(mediaserver)進程,設置M、N為不同值(M,N>=5;M+N<20),多次測試抓拍時長,mediaserver進程的CPU 占用率以及內存使用情況,取平均值,結果如表1所示(第一行為無抓拍方案的CPU 占用率與內存使用情況).
實驗結果表明,抓拍時長與預期時長相比誤差范圍在500 ms 以內;CPU 占用率與無抓拍相比,增加范圍在6%以下,不同預期時長下CPU 占用率變化可以忽略不計;對內存的占用根據預期時長趨于線性變化,時長每增加1 s,內存占用增加約1 MB.
抓拍的觸發條件可以為車輛發生碰撞或是用戶通過HMI 手動觸發等,抓拍方案在車聯網系統中的應用場景如圖6所示.
通過定義時間窗口并利用緩存技術,提出了一種基于Android 系統的視頻抓拍方案的設計與實現,并將其應用于車載電子系統中.從測試結果可以看出,該方案具有較小的抓拍時間誤差,引起的CPU 占用率變化幾乎可以忽略不計,并且在高清攝像頭(1280×800)下,對內存的影響隨抓拍時長呈線性變化,并且在可接受的范圍內.該方案已被集成進量產并投入市場的Android 智能輕車機中,從用戶反饋來看,該方案所實現的功能能夠提供抓拍時間點之前一定時間段內的視頻,及時有效,在事故認定過程中發揮了關鍵作用.抓拍方案基于Android 系統實現,應用于車載電子系統中,但并不局限于此,可以應用于任何有此類需要的智能視頻監控系統當中.

表1 預設不同時間下的抓拍測試結果

圖6 抓拍方案在車聯網系統中的應用