欢迎访问我的blog:http://blog.thinkinside.me
关于android中openmax中hardware decoder的调用中,整合过程比较简单。主要是对OMXCodec的封装进行调用。
这里记录一下碰到的主要的问题:
1 现象:开关几次后程序出现crash。
几台设备都有此现象,内存大的机器可以开关的次数多些,内存小的机器开关次数少。video尺寸小的可开关的次数多些,video尺寸小的可开关次数少。典型的内存泄露,而且与video decoder的解码buffer有关。经过痛苦万分的无数次打log,发现GraphicBuffer没有释放。
解决方案也简单的可以,从surface中申请的ANativewindow没有被释放。也就是
ANativeWindow_fromSurface()........ANativeWindow_release()
没有成对调用。
2 现象:播放某些流或者DTV时出现解码错误且不再恢复
由于我们的framework和OMXCodec的调用方式,导致过早decoder退出。具体些讲,由于我们的封装接口调用OMXCodec的解码是通过read函数调用实现的。read内部会去调用tracksource->read.如果出现数据不足或者错误太多,容易导致tracksource的buffer不够。我们这时候会在tracksource的read给出数据不足的返回值。OMXcodec的封装认为收到这个错误返回值把自己的状态设置为Endofstream,之后就不再解码了。
解决方案:参考AnotherPacketSource。在tracksource read阻塞住,等新的数据填入。
3 现象:解码时卡死
这个是由于调用OMXCodec的调用为阻塞导致的。我们往codec塞数据和decode的调用都是在一个线程中。先塞数据,再decode。如果decode中出现错误数据过多或者数据不足时,按照上一个问题的解决方案,会出现等待新数据输入的过程。可是这时候在framework中decode函数无法返回,也就没有办法输入更多数据了。典型的死锁过程。
解决方案:放弃上一个方案中的阻塞方法。出现数据不足时,给OMXCodec返回一个空的MediaBuffer,并且告知没有错误发生。上面两个问题完美解决。
4 现象:无法使用overlay
使用系统默认播放器时,会有Log表明在SurfaceFlinger做doComposeSurfaces函数时使用的是HWC_OVERLAY。而我们的framework只能使用到HWC_FRAMEBUFFER。对比awesome player对OMXCodec的调用,发现调用的OMXCodec的接口,以及nativewindow的操作并没有太大区别。
最后只好从Java层开始review,终于在 MediaPlayerService::Client::setVideoSurfaceTexture中发现了native_window_api_connect(anw.get(), NATIVE_WINDOW_API_MEDIA);调用。
解决方案: 在申请好nativewindow后调用native_window_api_connect,在release nativewindow前调用native_window_api_disconnect。