基于android4.4系统行车记录应用黑屏问题分析及对策

基于android4.4系统行车记录应用黑屏问题分析及对策

 

        笔者最近遇到一个棘手的问题,那就是行车记录应用出现黑屏的问题,现象就是进入行车记录应用surface是黑的,录像文件几分钟一个的那种,每个文件的大小都是零。看到这个大家都非常重视,对于车载产品来说,行车记录功能需要保持长时间正常工作,出现这种问题肯定是不能接受的,必须解决!那这个问题是怎么出现的呢?

       跟了很长时间,同时动用了8台相同的机器来单独做行车记录的拷机测试,12个小时内都不会出问题,但是超过24小时,就有那么2-3台机器会出现黑屏的问题,时间越长出问题的机器会增多,当然笔者在连续测试3X24小时的情况下,还有那么1-2台机器是毫发无损的正常工作!不是短时间就能出来,不是每台都能遇到,遇到这样的问题,大家可能都会觉得很棘手吧!那怎么解决呢?

/*****************************************************************************************************/
声明:本博内容均由http://blog.csdn.net/edsam49原创,转载请注明出处,谢谢!
/*****************************************************************************************************/

       要解决问题,我们也只能多做实验了,加一些测试代码用于调试,另外必须增加一个持续抓取系统打印信息的功能,否则这么长时间,不可能都拿一台机器在旁边抓打印吧!即使可以,也很不方便是不是,也没那么多电脑做到一机配一PC吧!持续抓打印这个功能相对比较简单,笔者在一年多前写过类似这方面的博文,有需要的可以去翻阅一下。

  首先来看一下出问题时的打印是个什么样的状态吧!

10-09 01:10:32.670 E/V4L2CameraDevice( 1205): select timeout
10-09 01:10:32.670 W/V4L2CameraDevice( 1205): wait v4l2 buffer time out
10-09 01:10:32.670 W/V4L2CameraDevice( 1205): nmCurAvailBufferCnt: 2 
10-09 01:10:32.670 W/V4L2CameraDevice( 1205): buffer: 0 ( refCnt:0 index:0 )
10-09 01:10:32.670 W/V4L2CameraDevice( 1205): buffer: 1 ( refCnt:1 index:1 )
10-09 01:10:32.670 W/V4L2CameraDevice( 1205): buffer: 2 ( refCnt:1 index:2 )
10-09 01:10:32.670 W/V4L2CameraDevice( 1205): buffer: 3 ( refCnt:1 index:3 )
10-09 01:10:32.670 W/V4L2CameraDevice( 1205): buffer: 4 ( refCnt:1 index:4 )
10-09 01:10:32.670 W/V4L2CameraDevice( 1205): buffer: 5 ( refCnt:0 index:5 )
10-09 01:10:32.670 W/V4L2CameraDevice( 1205): buffer: 6 ( refCnt:1 index:6 )
10-09 01:10:32.670 W/V4L2CameraDevice( 1205): preview_num: 0, picture_num: 0
10-09 01:10:33.110 D/dalvikvm( 2011): GC_FOR_ALLOC freed 1603K, 40% free 4102K/6796K, paused 51ms, total 51ms
10-09 01:10:34.690 E/V4L2CameraDevice( 1205): select timeout
10-09 01:10:34.690 W/V4L2CameraDevice( 1205): wait v4l2 buffer time out
10-09 01:10:34.690 W/V4L2CameraDevice( 1205): nmCurAvailBufferCnt: 2 
10-09 01:10:34.690 W/V4L2CameraDevice( 1205): buffer: 0 ( refCnt:0 index:0 )
10-09 01:10:34.690 W/V4L2CameraDevice( 1205): buffer: 1 ( refCnt:1 index:1 )
10-09 01:10:34.690 W/V4L2CameraDevice( 1205): buffer: 2 ( refCnt:1 index:2 )
10-09 01:10:34.690 W/V4L2CameraDevice( 1205): buffer: 3 ( refCnt:1 index:3 )
10-09 01:10:34.690 W/V4L2CameraDevice( 1205): buffer: 4 ( refCnt:1 index:4 )
10-09 01:10:34.690 W/V4L2CameraDevice( 1205): buffer: 5 ( refCnt:0 index:5 )
10-09 01:10:34.690 W/V4L2CameraDevice( 1205): buffer: 6 ( refCnt:1 index:6 )
10-09 01:10:34.690 W/V4L2CameraDevice( 1205): preview_num: 0, picture_num: 0
10-09 01:10:35.500 D/dalvikvm( 2011): GC_FOR_ALLOC freed 1392K, 40% free 4102K/6796K, paused 44ms, total 44ms
10-09 01:10:36.700 E/V4L2CameraDevice( 1205): select timeout
10-09 01:10:36.700 W/V4L2CameraDevice( 1205): wait v4l2 buffer time out
10-09 01:10:36.700 W/V4L2CameraDevice( 1205): nmCurAvailBufferCnt: 2 
10-09 01:10:36.700 W/V4L2CameraDevice( 1205): buffer: 0 ( refCnt:0 index:0 )
10-09 01:10:36.700 W/V4L2CameraDevice( 1205): buffer: 1 ( refCnt:1 index:1 )
10-09 01:10:36.700 W/V4L2CameraDevice( 1205): buffer: 2 ( refCnt:1 index:2 )
10-09 01:10:36.700 W/V4L2CameraDevice( 1205): buffer: 3 ( refCnt:1 index:3 )
10-09 01:10:36.700 W/V4L2CameraDevice( 1205): buffer: 4 ( refCnt:1 index:4 )
10-09 01:10:36.700 W/V4L2CameraDevice( 1205): buffer: 5 ( refCnt:0 index:5 )
10-09 01:10:36.700 W/V4L2CameraDevice( 1205): buffer: 6 ( refCnt:1 index:6 )
10-09 01:10:36.700 W/V4L2CameraDevice( 1205): preview_num: 0, picture_num: 0
10-09 01:10:37.050 D/MXNavi-JNI( 2726): send_Msg_to_control onUpdateGuidePointInfo pturninfo HighSpeedFlag:1,ulDistance370,destinationDistance:796,ulTurnid:5----EEyeGuideInfo{0-0-0}
10-09 01:10:37.080 D/MXNavi-JNI( 2726): send_Msg_to_control onUpdateGuidePointInfo pturninfo HighSpeedFlag:1,ulDistance370,destinationDistance:796,ulTurnid:5----EEyeGuideInfo{0-0-0}
10-09 01:10:37.190 D/MXNavi-JNI( 2726): snd_start_play_sound
10-09 01:10:37.190 V/jeavox  ( 1657): MiddleWareService onNaviInfoSpecialStatusChanged####1 1
10-09 01:10:37.190 I/jeavox  ( 1657): MiddleWareService NaviAudiowillPlay##1NAVI_RADAR_Coming 0
10-09 01:10:37.920 D/dalvikvm( 2011): GC_FOR_ALLOC freed 1430K, 40% free 4102K/6796K, paused 47ms, total 48ms
10-09 01:10:38.710 E/V4L2CameraDevice( 1205): select timeout
10-09 01:10:38.710 W/V4L2CameraDevice( 1205): wait v4l2 buffer time out
10-09 01:10:38.710 W/V4L2CameraDevice( 1205): nmCurAvailBufferCnt: 2 
10-09 01:10:38.710 W/V4L2CameraDevice( 1205): buffer: 0 ( refCnt:0 index:0 )
10-09 01:10:38.710 W/V4L2CameraDevice( 1205): buffer: 1 ( refCnt:1 index:1 )
10-09 01:10:38.710 W/V4L2CameraDevice( 1205): buffer: 2 ( refCnt:1 index:2 )
10-09 01:10:38.710 W/V4L2CameraDevice( 1205): buffer: 3 ( refCnt:1 index:3 )
10-09 01:10:38.710 W/V4L2CameraDevice( 1205): buffer: 4 ( refCnt:1 index:4 )
10-09 01:10:38.710 W/V4L2CameraDevice( 1205): buffer: 5 ( refCnt:0 index:5 )
10-09 01:10:38.710 W/V4L2CameraDevice( 1205): buffer: 6 ( refCnt:1 index:6 )
10-09 01:10:38.710 W/V4L2CameraDevice( 1205): preview_num: 0, picture_num: 0
10-09 01:10:40.180 D/Clock_Component( 1205): ----adjust ratio:1 ,precise_adjust_ratio:1, ref:2703668109 sys:2703728392 diff:-60283 diff-percent:-1 ----
10-09 01:10:40.230 D/dalvikvm( 2011): GC_FOR_ALLOC freed 1409K, 40% free 4102K/6796K, paused 54ms, total 55ms
10-09 01:10:40.720 E/V4L2CameraDevice( 1205): select timeout
10-09 01:10:40.720 W/V4L2CameraDevice( 1205): wait v4l2 buffer time out
10-09 01:10:40.720 W/V4L2CameraDevice( 1205): nmCurAvailBufferCnt: 2 
10-09 01:10:40.720 W/V4L2CameraDevice( 1205): buffer: 0 ( refCnt:0 index:0 )
10-09 01:10:40.720 W/V4L2CameraDevice( 1205): buffer: 1 ( refCnt:1 index:1 )
10-09 01:10:40.720 W/V4L2CameraDevice( 1205): buffer: 2 ( refCnt:1 index:2 )
10-09 01:10:40.720 W/V4L2CameraDevice( 1205): buffer: 3 ( refCnt:1 index:3 )
10-09 01:10:40.720 W/V4L2CameraDevice( 1205): buffer: 4 ( refCnt:1 index:4 )
10-09 01:10:40.720 W/V4L2CameraDevice( 1205): buffer: 5 ( refCnt:0 index:5 )
10-09 01:10:40.720 W/V4L2CameraDevice( 1205): buffer: 6 ( refCnt:1 index:6 )

     很明显是select超时了,为什么超时了呢?是由于buffer的问题!没有足够的空buffer!上面的打印有每个bufferrefCnt,从打印上分析一个是录像编码那边可能没正常释放,造成没释放的原因可能有系统任务多比较忙,也可能是SD卡读写速度跟不上,造成短时堵车,buffer没正常处理,总的来说我还是怀疑录像编码模块出的问题。但是有一个很现实的问题,就是这种问题在原厂那边不是很重视,也是公司地位不门当户对,也因为这个行业还不是贡献他们GDP的拳头。人家不投入那么多精力帮你,你能怎么办?跟老板说,原厂不解决,我们没办法!这样当然不行,很多客观的条件我们短时解决平衡不了的。那总得有招吧!

     笔者在测试发现,每次黑屏以后,该应用需要全部退出,再开启,又能正常工作。在HAL层出问题了,一旦出现这种select超时的问题,它是不会自愈的,多长时间都一样,那我想总可以想办法让应用知道这个事吧!上面知道这个事,不就有办法解决了嘛!虽然这不是最佳的解决办法,但是是合符目前各种现状的!停止再重新开启,大概需要1秒钟,也就是说会丢一秒钟的数据。这个在我看来这还属于可以接受的一个范围吧!

    那怎么上报呢?其实camera里面有现成的一套,只要利用起来就好了!在camera.java里面有一个重要的接口如下:

    /**
     * Registers a callback to be invoked when an error occurs.
     * @param cb The callback to run
     */
    public final void setErrorCallback(ErrorCallback cb)
    {
        mErrorCallback = cb;
    }

      通过这个接口注册可能作监听错误,注册了就相当于有一个钩子在那等了!那诱饵怎么抛出呢?还是得看看V4L2CameraDevice.cpp,这里面已经有一个现成的mCallbackNotifier,并且mCallbackNotifier它还有一个onCameraDeviceError()这样一个现成的接口,那不就简单了嘛!

      因此,在select超时的地方,直接通过mCallbackNotifiercall onCameraDeviceError,顺带一个特殊的错误号,这样行车记录应用监听到错误,对比一下错误码,不就可以做处理了嘛!

     笔者通过8台机器,连续测试了将近110个小时,发现8台机器都还在正常工作,没有出现黑屏的问题!同时,我也看了一下其中5台的系统打印,确实都曾出现过select超时的问题!那说明我们的处理方法手段还是有效的。虽然不是什么很高明的方法,但是还是一条切合实际的路!

     很多时候,我们没有那么多的资源,又要干一些事情,当然需要想一些办法了!

 

 

上一篇:Facebook是怎么做到每秒索引数百万条记录的?


下一篇:CentOS 6.5下Redis安装记录