【流媒體】 Android 实时视频编码—H.264硬编码

SkySeraph Apr4th 2012

Email:skyseraph00@163.com


1 硬编码 & 软编码

硬编码:通过调用Android系统自带的Camera录制视频,实际上是调用了底层的高清编码硬件模块,也即显卡,不使用CPU,速度快

软编码:使用CPU进行编码,如常见C/C++代码,一般编译生成的二进制都是的,速度相对较慢。例如使用Android NDK编译H264生成so库,编写jni接口,再使用java调用so库。


2 原理

① 过程:通过MediaRecoder采集视频,再将视频流映射到LocalSocket实现收发

② 原理:详见【流媒體】H264—MP4格式及在MP4文件中提取H264的SPS、PPS及码流 和 “【流媒體】Android 实时视频采集—MediaRecoder录制 ”


3 核心代码

MediaRecoder视频采集

视频采集采用了MediaRecorde录制方式,详见 “【流媒體】Android 实时视频采集—MediaRecoder录制 ”

② 在initiativeVideosetOutputFile设置以流方式输出

            // 设置输出文件方式: 直接本地存储   or LocalSocket远程输出        
if (bIfNativeORRemote == true) // Native
{
lVideoFileFullPath = strRecVideoFilePath + String.valueOf(System.currentTimeMillis())
+ lVideoFileFullPath;
mRecVideoFile = new File(lVideoFileFullPath);
// mMediaRecorder.setOutputFile(mRecVideoFile.getAbsolutePath());
mMediaRecorder.setOutputFile(mRecVideoFile.getPath()); // called after set**Source before prepare
Log.i(TAG, "start write into file~");
}
else // Remote
{
mMediaRecorder.setOutputFile(sender.getFileDescriptor()); // 设置以流方式输出
Log.i(TAG, "start send into sender~");
}

startRecording

功能:通过这个函数启动线程实现视频流映射到LocalSocket,同时实现编码

    private void startRecording()
{
Log.i(TAG, "##startRecording....");
new Thread(this).start();
}

run:

@Override
public void run()
{
Log.i(TAG, "##run....");

// defines
DataInputStream dataInputStream = null;
int offSet=0,tmp=0,beLeft=0;

try
{
dataInputStream = new DataInputStream(receiver.getInputStream());
} catch (IOException e2)
{
// TODO Auto-generated catch block
e2.printStackTrace();
}
try
{
Thread.currentThread().sleep(500);
} catch (InterruptedException e1)
{
e1.printStackTrace();
}

// ①方式一:通过查看预先录制的视频,需要跳过mdat前面32个字节(不同硬件平台不同!)
try
{
dataInputStream.read(h264frame, 0, 32);
Log.i(TAG, "read mdat from");
} catch (IOException e1)
{
// TODO Auto-generated catch block
e1.printStackTrace();
}
// ②方式二:自动化查找(待补充)


try
{
h264FileOutputStream = new FileOutputStream("/sdcard/avss/h264.264");//264码流
Log.i(TAG, "h264FileOutputStream");
} catch (FileNotFoundException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
try
{
h264FileOutputStream.write(h264head);
h264FileOutputStream.write(h264sps);
h264FileOutputStream.write(h264head);
h264FileOutputStream.write(h264pps);
Log.i(TAG, "run-write SPS/PPS to file");
} catch (IOException e1)
{
// TODO Auto-generated catch block
e1.printStackTrace();
}

while (bIfRecInProcess && (!bIfNativeORRemote))
{
try
{
Log.i(TAG, "**while...");
int h264length = dataInputStream.readInt();
Log.i(TAG, "h264length:"+h264length);
tmp=0; offSet = 0; beLeft = 0;

h264FileOutputStream.write(h264head);
while (offSet < h264length)
{
beLeft = h264length - offSet;
tmp = dataInputStream.read(h264frame, 0, READ_SIZE < beLeft ? READ_SIZE : beLeft);
Log.i(TAG, String.format("H264 %d,%d,%d", h264length, offSet, tmp));
offSet += tmp;
h264FileOutputStream.write(h264frame, 0, tmp);
}

} catch (Exception e)
{
// TODO: handle exception
e.printStackTrace();
}
}
//
}


4 Ref/Related

1http://blog.csdn.net/zblue78/article/details/6078040

2 http://blog.csdn.net/zblue78/article/details/6083374

3 http://www.docin.com/p-282454756.html

4 http://blog.csdn.net/qwertyuj/article/details/7029836

5 http://www.cnblogs.com/skyseraph/archive/2012/03/31/2427593.html

6 http://www.cnblogs.com/skyseraph/archive/2012/03/23/2415018.html

7 http://www.cnblogs.com/skyseraph/archive/2012/04/01/2429384.html

更多相关文章

  1. 使用Vitamio打造自己的Android万能播放器(1)——准备
  2. Android中的几种网络请求方式详解
  3. Android的四种存储方式: sharedpreference,file,SQlite,contentpr
  4. Android重力感应实现方式简介
  5. 二维码的生成细节和原理
  6. 使用浏览器查看Android(安卓)SQLite数据库-Android(安卓)Debug D
  7. Android(安卓)TabHost两种实现方式
  8. Android(安卓)自动编译、打包生成apk文件 、命令行方式
  9. Android之从网络中获取数据并返回客户端的两种方式:XML格式返回

随机推荐

  1. [置顶] 【通知】▁▂▃ Himi 著作《Andro
  2. Android网络收音机--使用Vitamio解码(二)
  3. Linux笔记(固定USB摄像头硬件端口,绑定前后
  4. Android(安卓)开发解决APP在18:9,18.5:9,19
  5. Android(安卓)拍照声音问题(声音大小不可
  6. Milestone解决耳机拔掉后音乐继续响的办
  7. 阿里云与Android
  8. [Android(安卓)基础系列]Service、Intent
  9. Android(安卓)实现圆角按钮(selector和sha
  10. android 懒人教程:一步步开发android stud