• 
    

    
    

      99热精品在线国产_美女午夜性视频免费_国产精品国产高清国产av_av欧美777_自拍偷自拍亚洲精品老妇_亚洲熟女精品中文字幕_www日本黄色视频网_国产精品野战在线观看

      ?

      Android應(yīng)用中即時(shí)視頻圖像放大顯示方法

      2013-10-15 05:08:02何志堅(jiān)宋占偉
      關(guān)鍵詞:線程調(diào)用內(nèi)存

      陳 捷, 何志堅(jiān), 宋占偉

      (吉林大學(xué) 電子科學(xué)與工程學(xué)院, 長春 130012)

      0 引 言

      Android系統(tǒng)以其開放、 免費(fèi)、 功能強(qiáng)大等多個(gè)特性已經(jīng)逐漸占據(jù)了智能手機(jī)操作系統(tǒng)和平板電腦操作系統(tǒng)的市場[1], 憑借其強(qiáng)大的API(Application Programming Interface)控件和高端ARM(Advanced RISC Machines)處理器的強(qiáng)大處理能力逐漸在可視通訊領(lǐng)域中發(fā)揮其巨大潛力[2]。筆者目前正在研究開發(fā)基于Android系統(tǒng)的視訊終端, 在開發(fā)過程中需要重寫Android的View控件中onDraw方法[3]繪制解碼完成的視頻圖像并放大到全屏顯示, 然而使用文獻(xiàn)[4,5]或網(wǎng)絡(luò)文檔[6]中常見的創(chuàng)建放大圖片的方式時(shí)出現(xiàn)效率低、 消耗大量內(nèi)存的問題, 不能滿足較大屏幕的即時(shí)播放需求。因此, 筆者在分析效率低下的原因后, 研究了Android下其他幾種可行的圖像放大的方法, 分別進(jìn)行了實(shí)驗(yàn)測試, 得到其執(zhí)行效率和放大效果。并對(duì)各種實(shí)現(xiàn)方法在即時(shí)視頻播放應(yīng)用中的可行性進(jìn)行了系統(tǒng)分析, 最終從源代碼中獲得啟發(fā), 得到一個(gè)兼顧放大效果和效率以及刷新可控性的最佳方案。

      1 硬件與編輯器的測試平臺(tái)

      測試用平板電腦使用基于Cortex-A8核心, 頻率為1.0 GHz處理器, 內(nèi)存為512 MByte。Android版本為4.0.3, Linux內(nèi)核版本為3.0.8+。使用Eclipse indigo作為編程環(huán)境[7], 從視頻解碼器中獲得的視頻圖像為RGB565形式320×240像素的圖像, 使用Byte型數(shù)組順序存儲(chǔ)所有像素點(diǎn)的顏色信息。播放窗口默認(rèn)為480×360像素。

      2 常見放大圖像的方法存在的問題

      文獻(xiàn)[4,5]與網(wǎng)絡(luò)文檔[6]中提到對(duì)圖像進(jìn)行拉伸的方法, 即首先創(chuàng)建一個(gè)原始圖像的Bitmap對(duì)象, 其大小為視頻解碼的原始尺寸, 再調(diào)用createBitmap方法結(jié)合放大矩陣Matrix創(chuàng)建一個(gè)放大的新Bitmap對(duì)象。其主要實(shí)現(xiàn)代碼如下:

      Matrix matrix=new Matrix();

      Matrix.postScale((float)480/320,(float)360/240);

      NewBMP=Bitmap.createBitmap(OldBMP,0,0,320,240,matrix,true)

      其中使用Matrix定義放大倍數(shù), 放大倍數(shù)是一個(gè)浮點(diǎn)型的小數(shù)。View及其繼承類可以在子線程里調(diào)用postInvalidate方法刷新圖像, 重寫onDraw方法將Bitmap對(duì)象直接繪制到View的畫板中即可顯示放大后的圖像。該方法可以由線程主動(dòng)控制刷新圖像, 其拉伸方式由系統(tǒng)決定。

      使用該方法, 每次處理一張解碼后圖片都必須創(chuàng)建一個(gè)新Bitmap對(duì)象, 舊Bitmap圖像占用的內(nèi)存變?yōu)榭苫厥諣顟B(tài)。由于Android不存在主動(dòng)釋放內(nèi)存資源的方法, 必須靠虛擬機(jī)自動(dòng)回收資源。因?yàn)锽itmap對(duì)象占用的內(nèi)存資源量很大, 一張480×360像素的圖像使用565格式存放需要的內(nèi)存空間為345 600 Byte, Android下為每個(gè)應(yīng)用程序分配的堆空間有限, 內(nèi)存損耗過大時(shí)dalvikvm虛擬機(jī)會(huì)立刻進(jìn)行內(nèi)存回收[8], 并產(chǎn)生一定的時(shí)間延遲?;厥諆?nèi)存資源時(shí), 在開發(fā)環(huán)境Eclipse的消息窗口LogCat[9]中會(huì)出現(xiàn)如表1所示的消息。

      上面是一個(gè)使用這種方式解壓播放9.5幀/s視頻圖像的測試代碼執(zhí)行時(shí)得到的系統(tǒng)消息, 在這里, 放大處理時(shí)間并不包括解碼所需的時(shí)間, 每播放一幅畫面, 虛擬機(jī)就需要立刻釋放338 kByte的空間, 此外還能看見釋放這些數(shù)據(jù)需要的時(shí)間, 為17~30 ms不等。刷新頻率越高, 圖片越大, 導(dǎo)致內(nèi)存的消耗也越大, 虛擬機(jī)疲于釋放內(nèi)存空間, 處理效率嚴(yán)重下降[8]。在測試函數(shù)兩端添加了使用System.currentTimemillis方法得到的每幅圖片放大所需大致時(shí)間, 顯示在Logcat中, 后文中得到的圖片處理時(shí)間也是基于此方法。從結(jié)果中可以看出, 每幅圖片間隔在33~92 ms之間不等, 加上釋放內(nèi)存需要的時(shí)間, 根據(jù)時(shí)間戳, 播放一幀畫面對(duì)圖像的處理時(shí)間有時(shí)已經(jīng)超過110 ms, 這也意味著已經(jīng)不能保證視頻的刷新率在9.5幀/s, 雖然能得到圖像放大的效果, 但由于效率的低下, 這種圖像放大方式不適合在即時(shí)視頻刷新中使用。必須在Android的API中尋找其他放大方法。

      3 Android中使用的其他放大圖像方法

      3.1 在本地或Java層實(shí)現(xiàn)軟件算法放大圖像

      研究Bitmap類的各種創(chuàng)建圖片方法后發(fā)現(xiàn), 使用Bitmap類的copyPixelFromBuffer方法可以將一個(gè)表示像素顏色的字節(jié)數(shù)組數(shù)據(jù)寫入一個(gè)現(xiàn)存的Bitmap中, 不需要重新創(chuàng)建Bitmap對(duì)象。該方法支持使用565格式的16位圖片數(shù)據(jù), 也支持A8888格式的32位圖片數(shù)據(jù)。因此可以編寫軟件算法直接處理解碼器得到的顏色數(shù)組數(shù)據(jù)進(jìn)行圖像放大, 結(jié)果存入一個(gè)預(yù)先創(chuàng)建可重用且大小為放大后圖像尺寸兩倍的Byte數(shù)組(假設(shè)使用16位圖片數(shù)據(jù)), 再使用copyPixelFromBuffer方法將數(shù)組內(nèi)容讀入一個(gè)現(xiàn)有的Bitmap對(duì)象, 顯示方式采用重寫onDraw方法。使用該方式, 能做到內(nèi)存空間的重復(fù)利用, 但算法的復(fù)雜度和處理器性能是提高播放器刷新率的關(guān)鍵[10]。

      由于需要保證刷新的實(shí)時(shí)性, 考慮到設(shè)備處理器性能有限, 使用軟件線性插值算法[11]或邊緣銳化增強(qiáng)放大算法[12]都無法在有限的刷新周期(在測試平臺(tái)上為110 ms)內(nèi)完成所有處理。因?yàn)檫@些算法基本都要對(duì)每個(gè)目標(biāo)像素點(diǎn)進(jìn)行對(duì)應(yīng)位置計(jì)算[13], 對(duì)于480×360像素的圖像, 需執(zhí)行172 800次變換。如果變換過程中涉及浮點(diǎn)運(yùn)算, 則消耗的時(shí)間更多[14]。一個(gè)將目標(biāo)圖像坐標(biāo)按放大比例變換為源圖像坐標(biāo), 將源圖像坐標(biāo)對(duì)應(yīng)的值作為目標(biāo)圖像對(duì)應(yīng)坐標(biāo)值的示例算法如下:

      int*x=(int*)malloc(width2*sizeof(int));

      int*y=(int*)malloc(height2*sizeof(int));

      for (i=0;i

      *(x+i)=(int)(i*width1/width2);

      for(i=0;i

      *(y+i)=(int)(i*height1/height2);

      for (j=0;j

      for (i=0;i

      {

      *(out+i+j*width2)=*(in+x[i]+y[j]*width1);

      }

      釋放空間部分代碼沒有包含在內(nèi), 其中width1和height1為原始圖像的長寬, width2和height2為拉伸后圖像長寬。

      算法中已采用了一些優(yōu)化方式, 由于目標(biāo)圖像每個(gè)橫坐標(biāo)像素對(duì)應(yīng)的源圖像橫坐標(biāo)位置是相同的, 縱坐標(biāo)的位置同理。為減少除法運(yùn)算, 預(yù)先定義了兩個(gè)坐標(biāo)對(duì)應(yīng)關(guān)系表, 省略了對(duì)每個(gè)坐標(biāo)都要進(jìn)行的兩次除法運(yùn)算, 使用二重循環(huán)而不是使用一重循環(huán)的目的在于: 省略一重循環(huán)中為得到目標(biāo)所在的行列位置所要進(jìn)行的除法和取模運(yùn)算, 因?yàn)槎鄶?shù)處理器對(duì)取模運(yùn)算需要很多時(shí)間周期, 如果條件允許盡量不使用取模運(yùn)算。該算法使用JNI方式編譯, 使用C代碼能方便地將Byte數(shù)組轉(zhuǎn)換為short指針取數(shù)運(yùn)算。

      3.2 使用ImageView類的設(shè)置圖片方法

      考慮到項(xiàng)目前期完成的網(wǎng)絡(luò)圖片傳輸顯示中使用的ImageView顯示窗口, 在使用setImageBitmap方法設(shè)置顯示圖片且scaleType設(shè)置參數(shù)為FIT_CENTER的情況下, 能自動(dòng)將圖片拉伸后顯示, 但該方法只能用在主線程中調(diào)用, 在子線程調(diào)用將拋出異常。由于View及其繼承類在子線程里調(diào)用postInvalidate方法實(shí)際上是通知主線程調(diào)用onDraw方法刷新圖像, 因而可通過在onDraw方法中添加setImageBitmap過程, 使主線程自動(dòng)調(diào)用刷新, 實(shí)現(xiàn)圖像放大播放, 其拉伸方式由系統(tǒng)決定。

      4 放大圖像測試代碼執(zhí)行結(jié)果分析

      4.1 使用軟件算法放大圖像的測試代碼結(jié)果

      在3.1中使用的copyPixelFromBuffer能重用數(shù)據(jù)緩沖區(qū)和Bitmap對(duì)象, 起到了節(jié)約內(nèi)存資源的作用, 減少因?yàn)樘摂M機(jī)頻繁自動(dòng)回收內(nèi)存空間造成的延遲, 最終得到的每幅放大處理時(shí)間如表2所示。

      同樣采用在拉伸函數(shù)兩端添加System.currentTimeMillis方法得到函數(shù)執(zhí)行時(shí)間的方式, 從LogCat中的結(jié)果可見, 這種放大方式的效率較高, 每幀需要的放大時(shí)間基本上只有4 ms, 能保證前面提到的9.5幀/s的幀率, 在實(shí)驗(yàn)中有時(shí)會(huì)有一幀10~20 ms的突發(fā)情況, 這與系統(tǒng)的其他進(jìn)程調(diào)度有關(guān)[15]。該方式不需要耗費(fèi)系統(tǒng)頻繁執(zhí)行回收方法的延遲時(shí)間, 已經(jīng)大大減少了時(shí)間開支, 以每幅視頻解壓需要平均10 ms時(shí)間計(jì)算, 該方式播放視頻的刷新率比較容易達(dá)到60 Hz。但如果圖像放大比例較大, 會(huì)出現(xiàn)鋸齒現(xiàn)象, 這是因?yàn)闆]有使用插值算法柔化邊緣的緣故。如果能使用插值算法, 或使用硬件對(duì)底層圖像進(jìn)行處理, 則圖像效果會(huì)更佳。然而從算法的復(fù)雜度考慮, 對(duì)于銳化和反鋸齒插值算法中需要的大量浮點(diǎn)運(yùn)算, 以及色彩565形式變換成RGB888形式進(jìn)行處理的過程, 測試平臺(tái)使用軟件方式無法在可接受的時(shí)間間隔內(nèi)達(dá)到目標(biāo), 需要使用性能更高的處理器。

      4.2 使用ImageView類放大圖像的測試代碼結(jié)果

      使用ImageView類放大圖像的測試如表3所示。

      表3 使用ImageView方法放大圖片的效率

      觀察實(shí)驗(yàn)結(jié)果中的時(shí)間戳發(fā)現(xiàn), 使用該方式在解碼開始前也在不斷進(jìn)行刷新, 雖然該方式放大效率很高, 一般在1 ms以內(nèi), 與3.1節(jié)方法一樣偶爾會(huì)有10~20 ms的突發(fā)情況, 但由于自動(dòng)刷新的刷新率太高, 在播放幀率較低的即時(shí)采集傳輸視頻, 如前面提到的9.5幀/s的視頻時(shí), 把每110 ms刷新需要的時(shí)間相加, 與前一種方式每幀刷新時(shí)使用的時(shí)間非常接近, 理論上有許多次處理時(shí)間是可以省略的。該方式不能做到隨子線程調(diào)用postInvalidate方法刷新這種可控刷新方法, 也間接導(dǎo)致其他線程處理速度受到影響。這種放大方式得到的圖像經(jīng)過平滑處理, 圖像邊緣放大后比較模糊, 鋸齒現(xiàn)象不明顯, 然而該方式的放大算法不可修改, 不能對(duì)圖像進(jìn)行銳化等特殊處理, 只能按系統(tǒng)定義的默認(rèn)放大方式放大。對(duì)于非特殊要求的應(yīng)用, 該放大方式比較理想, 只需要研究一下如何將多余的刷新時(shí)間去除即可。

      5 從源碼中研究改進(jìn)方式

      基于ImageView類的圖像放大方法單幀圖像放大效率比使用軟件算法的方式高, 但缺乏3.1節(jié)方法中擁有的刷新時(shí)間的可控性, 存在多余的刷新時(shí)間使其效率下降的問題, 由于Android的API提供了源代碼, 可以從源代碼中進(jìn)行分析。

      從Android SDK的Android-15源代碼包資源中找到ImageView的源代碼, 研究源碼后發(fā)現(xiàn)了方法2中出現(xiàn)無法控制的高刷新率的原因。ImageView的setImageBitmap方法針對(duì)圖像大小和視窗邊界作了一些比例運(yùn)算, 并根據(jù)ImageView類中名為ScaleType的設(shè)置參數(shù)調(diào)整比例矩陣mDrawMatrix, 最終得到一個(gè)源圖像尺寸和顯示尺寸相關(guān)的矩陣作為全局變量。setImageBitmap函數(shù)最后調(diào)用了invalidate方法使當(dāng)前畫板失效, 通知主線程調(diào)用onDraw方法重畫, 如果把setImageBitmap寫在onDraw中用于放大圖像, 則相當(dāng)于在onDraw方法中調(diào)用invalidate方法循環(huán)不斷地使畫面失效, 主線程不斷得到通知刷新畫面重調(diào)用onDraw方法, 因此, 界面刷新過于頻繁, 影響到其他線程的執(zhí)行效率。

      ImageView重寫了View的onDraw方法, 根據(jù)已得到的全局比例矩陣mDrawMatrix和一些設(shè)置參數(shù)在onDraw中調(diào)用canvas的本地方法concat和translate等方式設(shè)置比例矩陣并放大圖像。根據(jù)相同的原理, 3.1節(jié)中的View或SurfaceView的onDraw方法中直接加入同樣一段代碼canvas.concat(mMatrix), 將其他處理設(shè)置參數(shù)的過程可省略, 以達(dá)到最快速最簡化效果。

      該本地方法的官方解釋為使用當(dāng)前mMatrix作為繪制圖形用的放大矩陣[15]。mMatrix可以在播放窗口建立時(shí)根據(jù)視頻大小和播放窗口大小的比例預(yù)先創(chuàng)建, 其余解碼和顯示圖像部分和3.1節(jié)或3.2節(jié)的方法相同, 即能得到放大后的圖像。值得注意的是, 在每次調(diào)用onDraw方法時(shí)都需要調(diào)用該函數(shù), 否則只對(duì)一次刷新有效。最終得到每張圖片放大時(shí)間幾乎都為0, 且能保證每110 ms刷新一次。

      使用該方式避免了3.2節(jié)中不斷重復(fù)的刷新過程, 同時(shí)也消除了該方法每次調(diào)用ImageView類的setImageBitmap方法時(shí)放大比例矩陣的計(jì)算時(shí)間和onDraw函數(shù)中判斷過程, 在最大程度上提高了性能。如果對(duì)放大后的圖像清晰度效果沒有特殊要求, 這是測試平臺(tái)上最為合適的即時(shí)視頻放大手段。

      6 結(jié) 語

      根據(jù)實(shí)驗(yàn)和分析的結(jié)果表明, 基于軟件算法實(shí)現(xiàn)拉伸圖像的3.1節(jié)方法刷新時(shí)間可控制, 且能根據(jù)具體需要使用邊緣銳化、 線性插值等特殊算法, 但實(shí)現(xiàn)的可行性受具體算法的復(fù)雜度和硬件處理器性能限制; 基于ImageView設(shè)置圖片的方法存在自動(dòng)刷新率太高影響其他線程的處理性能, 缺乏刷新時(shí)間可控性的缺點(diǎn), 但這種方式效率較高。研究源代碼發(fā)現(xiàn), 如果對(duì)放大清晰度效果沒有要求, 可以使用canvas的一些本地方法結(jié)合縮放矩陣達(dá)到目標(biāo)效果。該方式結(jié)合了3.1節(jié)的刷新可控性和3.2節(jié)效率高的優(yōu)點(diǎn), 目前已經(jīng)在項(xiàng)目的視頻解碼應(yīng)用中得到使用。筆者從研究中體會(huì)到, Android圖形化界面的編程由于資料分散, 官方文檔比較簡略缺少范例, 某些尚未被普遍使用的實(shí)用API還需要繼續(xù)探索和普及。通過閱讀控件源代碼發(fā)現(xiàn)這些新功能是一種很好的學(xué)習(xí)方法。

      參考文獻(xiàn):

      [1]陳木生. Google Android手機(jī)推出市場分析 [J]. 電子與電腦, 2008(12): 10-14.

      CHEN Mu-sheng. Market Analysis When Google Android Phone Release [J]. Compotech China, 2008(12): 10-14.

      [2]楊明極, 畢晶. 基于Android視頻客戶端的設(shè)計(jì) [J]. 電視技術(shù), 2012(3): 43-47.

      YANG Ming-ji, BI Jing. Design of Video Client Based on Android [J]. Video Engieering, 2012(3): 43-47.

      [3]宋強(qiáng), 齊貴寶, 宋占偉. 基于Android系統(tǒng)的H.264視頻監(jiān)控設(shè)計(jì) [J]. 吉林大學(xué)學(xué)報(bào): 信息科學(xué)版, 2012, 30(3): 272-277.

      SONG Qiang, QI Gui-bao, SONG Zhan-wei. Design of H.264 Video Monitoring Based on Android System [J]. Journal of Jilin University: Information Science Edition, 2012, 30(3): 272-277.

      [4]汪永松. Android開發(fā)平臺(tái)之旅 [M]. 北京: 機(jī)械工業(yè)出版社, 2012.

      WANG Yong-song. Travel of Android Development Platform [M]. Beijing: China Machine Press, 2012.

      [5]楊豐盛. Android應(yīng)用開發(fā)揭秘 [M]. 北京: 機(jī)械工業(yè)出版社, 2010.

      YANG Feng-sheng. Android Unleashed [M]. Beijing: China Machine Press, 2010.

      [6]XPSHARP. Android圖片放大縮小 [EB/OL]. [2011-12-21]. http://www.linuxidc.com/Linux/2011-12/49926.htm.

      XPSHARP. Enlarge or Shrink Images in Android [EB/OL]. [2011-12-21]. http://www.linuxidc.com/Linux/2011-12/49926.htm.

      [7]JEROME DIMARZIO. Android: A Programmer’s Guide [M]. New Youk: Osborne/McGraw-Hill, 2008.

      [8]宋小倩, 周東升. 基于Android平臺(tái)的應(yīng)用開發(fā)研究 [J]. 軟件導(dǎo)刊, 2011(2): 104-106.

      SONG Xiao-qian, ZHOU Dong-sheng. Development and Researh of Application Based on Android Platform [J]. Software Guide, 2011(2): 104-106.

      [9]尹文剛, 楊斌. Android應(yīng)用程序中的內(nèi)存泄漏與規(guī)避方法 [J]. 單片機(jī)與嵌入式系統(tǒng)應(yīng)用, 2012(6): 4-6.

      YIN Wen-gang, YANG Bin. Memory Leak and Avoiding Method of Android Application Program [J]. Microcontrollers & Embedded Systems, 2012(6): 4-6.

      [10]孫杰. 基于Android平臺(tái)圖像處理算法的研究與實(shí)現(xiàn) [D]. 北京: 北京郵電大學(xué)軟件學(xué)院, 2011.

      SUN Jie. Research and Implementation of Algorithms for Image Processing Based on Android [D]. Beijing: Software Institute, Beijing University of Posts and Telecommunications, 2011.

      [11]江銘炎, 李興江, 袁東風(fēng). 2*圖像插值放大處理的方法 [J]. 山東大學(xué)學(xué)報(bào): 理學(xué)版, 2003, 38(3): 79-81.

      JIANG Ming-yan, LI Xing-jiang, YUAN Dong-feng. The Method of 2*Image Enlarging with Interpolation [J]. Journal of Shandong University: Natural Science,2003, 38(3): 79-81.

      [12]曾生達(dá). 幾種圖像放大算法原理比較與分析 [J]. 金華職業(yè)技術(shù)學(xué)院學(xué)報(bào), 2012(3): 66-71.

      ZENG Sheng-da. The Comparision and Analyisis of Several Manification of Image Magnification [J]. Journal of Jinhua Polytechnic, 2012(3): 66-71.

      [13]WU X, ZHANG X, WANG X. Low Bit-rate Image Compression via Adaptive Down-sampling and Constrained Least Squares Upconversion [J]. IEEE Transactions on Image Processing, 2009, 8(3): 552-561.

      [14]NIU Yi, SHI Guang-ming, WANG Xiao-tian, et al. JPEG Stream Soft-Decoding Technique Based on Autoregressive Modeling [J]. The Journal of China Universities of Posts and Telecommunications, 2012, 19(5): 115-123.

      [15]Google Company. Android Developers [EB/OL]. [2012-10]. http://developer.android.com/.

      猜你喜歡
      線程調(diào)用內(nèi)存
      核電項(xiàng)目物項(xiàng)調(diào)用管理的應(yīng)用研究
      “春夏秋冬”的內(nèi)存
      LabWindows/CVI下基于ActiveX技術(shù)的Excel調(diào)用
      淺談linux多線程協(xié)作
      基于系統(tǒng)調(diào)用的惡意軟件檢測技術(shù)研究
      基于內(nèi)存的地理信息訪問技術(shù)
      利用RFC技術(shù)實(shí)現(xiàn)SAP系統(tǒng)接口通信
      Linux線程實(shí)現(xiàn)技術(shù)研究
      么移動(dòng)中間件線程池并發(fā)機(jī)制優(yōu)化改進(jìn)
      上網(wǎng)本為什么只有1GB?
      磐安县| 天长市| 讷河市| 泾阳县| 博客| 安陆市| 屏东市| 临汾市| 邓州市| 正宁县| 双牌县| 江永县| 仙居县| 丰台区| 扬州市| 南宫市| 城固县| 南皮县| 峨山| 固原市| 准格尔旗| 芮城县| 花莲市| 达尔| 新乡县| 镇坪县| 喀喇| 太仆寺旗| 建始县| 南城县| 鹤庆县| 循化| 丹阳市| 泗阳县| 靖州| 湘乡市| 清丰县| 泰宁县| 陵水| 临泽县| 松原市|