但为什么在模拟器里播放不出来,只有声音,没图象。(我是将.264后缀的文件与AAC音频封装到3gp容器中,生成.3gp文件)
但论坛上看到有人又在搞h.264解码库的移植,向android。
解码器整体设计
解码器的整体设计可以分成两部分,一部分是视频数据的解码部分,主要用C语言来实现,采用Android NDK+C的实现机制。另外一部分是视频的显示部分,主要采用Android提供的组件来实现,采用Android SDK+java的实现机制。而这两部分的集合,则是通过java提供的jni机制来实现Java和C语言之间的通信。
解码流程
整个解码的流程可以分成三个功能模块:前端码流处理,H.264解码和后端视频显示。
前端码流处理:主要负责文件的读取,从码流中分割出NAL然后交给底层进行解码处理。
H.264解码:整个解码的核心部分,通过本地C语言的实现和解码库对码流数据进行处理,完成H.264解码实现图像重建
后端视频显示:接收H.264解码模块解码后的视频数据,在Android客户端进行显示。
通过分析三个模块的功能可知,H.264解码模块是最耗费资源的。本模块通过移植的H.264解码库来实现解码。另外两个模块则是Android的java层进行实现。
完成Nal的分割后,将数据交给底层解码器处理,对于具体视频数据,解码流程如下:
1.打开解码器
2.为解码帧分配内存
3.不停的从码流中提取帧数据
4、对于视频帧调用
5.解码完成,释放解码器
视频显示
YUV到RGB565色彩转换
本文的视频显示采用的是Android提供的Bitmap类显示BMP图像,模拟器实现视频接口。H.264标准支持4:2:0的逐行和隔行的视频采样格式。因此,H.264码流解码出来的是4:2:0的YUV格式。为了能够在应用层完整的显示图像,需要完成色彩空间从YUV到RGB的转换。
RGB数据显示
颜色空间转换后的数据,传给Java层。视频的显示功能是通过android.graphics.Bitmap类,完成RGB空间到Bitmap的映射,然后在android。view。View里面,重载onDraw()方法,然后用canvasdrawBitmap()方法,将图片花在屏幕上。
@Override
protected void onDraw(Canvas canvas){
super.onDraw(canvas);
VideoBit.copyPixelLSFromBuffer(buffer);
canvas.drawBitmap(VideoBit,0,0,null);
为了方便的显示视频图像,自己编写视频显示空间VideoPlayer类,实现视频的解码显示功能。该类继承自android.view.View并实现了接口Runnable来实现多线程。对外提供void PlayVideeo(String file),void stopVideo()和void PauseVideo()三个简单的接口,实现基本的视频播放功能。给类构造如下:
public class VideoPlayer extends View implements Runnable{
//重载构造方法
public VideoPlayer(Context context,Attru bitsatu){}
//重写Ondraw()函数,实现视频显示
@Override protected void onDraw(Canvas canvas){
super.onDraw(cnavas);
VideoBit.copyPixelsFromBuffer(buffer);
canvas.drawBitmap(VideoBit,0,0,null);
}
//播放
public void PlayVideo(String file){
}
//暂停
public void PauseVideo(){
}
//public void StopVideo(){
}
}
解码器测试结果
本文完成