最近已经在solo6010上实现了精确的单帧播放和播放状态快速切换。当然,各种速度的快进、快退是早已实现的。由于solo芯片是公司目前使用的芯片,因此我只能提示一些框架性的内容以其达到抛砖引玉的效果。希望同在使用solo芯片做开发的兄弟能和我一起探讨。
关于播放状态,我实现了如下几种:
PLAY
FFX2,FFX4,FFX8,FFX16,FFX32
REWX1,REWX2,REWX4,REWX8,REWX16,REWX32
STEP_F
STEP_B
PAUSE
STOP
其中快进、快退的速度还可以做提升。理论上是没有限制,但实际上限制是一个录像文件至少需要播放几帧。
连续播放部分控制是通过STC((System Time Clock))和DTS(Decoding Time Stamp)/PTS组实现控制,非连续播放是通过APP层按键控制。这部分实现需要APP与driver层互动,通过ioctl实现是个不错的选择。
关于精确的单帧播放是由于solo的decoder有一个16片的decoder buffer造成的。当然,任何解码器应该都会有decoder buffer以实现相对连续的播放。但是,正是这个decoder buffer的存在导致APP层很难精确控制单帧播放。特别是播放的方向转向时,这个“惯性”非常明显。再加上快速播放与STC和PTS组的控制,要从高速的快速播放切换到正常速度播放的切换时间非常长(如果不能理解请在实现了STC/PTS组控制快进、快退后再次体会),用户是不可能接收这么长时间的状态切换等待,因此,该问题也必须解决。
解决这两个问题的第一步是清decoder buffer。每次状态切换后都做清decoder buffer的操作(部分切换无需做此操作,如PLAY->STEP_F),经过这样的操作之后即可解决转向时的“惯性”和高速播放到低速播放是长时间等待。但是,清decoder buffer之后打破了视频的GOP结构,清deocder buffer之后解码会出现短暂的花屏,直到第一个I帧到来才会恢复该通道画面。这正是需要解决的第二个问题。
如果想不花屏,那么最简单的解决办法是在清decoder buffer之后第一次送帧从I帧开始。这样就解决了花屏的问题。同时又引入了个怪异的问题:因为不是从当前解码帧开始寻找的I帧,而是从当前feed decoder处的文件处开始寻找,在播放转向时会有个短暂折返的现像。用户也很难接收这样的产品,因此必须解决这个折返问题。
解决这个折返问题的关键是要获取当前解码帧的PTS,然后通过这个PTS到录像文件中寻找与该PTS相等的
视频帧,最后从该视频帧开始移动到当前帧的前一个I帧。从这个位置开始送帧便不会出现明显的折返现像。
当然,最理想的送帧处是与当前解码帧PTS相等的文件位置。但是由于GOP机制,这个位置很可能是个P帧,很遗憾,对不?哈哈……所以,折中一下也是可以的,等到解码器能够,或者算法实现了单P帧解码时再修改吧:)
阅读(879) | 评论(0) | 转发(0) |