Android 实时视频编码—H.264硬编码

阳光穿透心脏的1/2处 2022-07-14 19:10 661阅读 0赞

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


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

SkySeraph Apr 4th 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录制 ”

② 在initiativeVideo中setOutputFile设置以流方式输出

复制代码

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

复制代码

③ startRecording

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

  1. private void startRecording()
  2. {
  3. Log.i(TAG, "##startRecording....");
  4. new Thread(this).start();
  5. }

run:

复制代码

  1. @Override
  2. public void run()
  3. {
  4. Log.i(TAG, "##run....");
  5. // defines
  6. DataInputStream dataInputStream = null;
  7. int offSet=0,tmp=0,beLeft=0;
  8. try
  9. {
  10. dataInputStream = new DataInputStream(receiver.getInputStream());
  11. } catch (IOException e2)
  12. {
  13. // TODO Auto-generated catch block
  14. e2.printStackTrace();
  15. }
  16. try
  17. {
  18. Thread.currentThread().sleep(500);
  19. } catch (InterruptedException e1)
  20. {
  21. e1.printStackTrace();
  22. }
  23. // ①方式一:通过查看预先录制的视频,需要跳过mdat前面32个字节(不同硬件平台不同!)
  24. try
  25. {
  26. dataInputStream.read(h264frame, 0, 32);
  27. Log.i(TAG, "read mdat from");
  28. } catch (IOException e1)
  29. {
  30. // TODO Auto-generated catch block
  31. e1.printStackTrace();
  32. }
  33. // ②方式二:自动化查找(待补充)
  34. try
  35. {
  36. h264FileOutputStream = new FileOutputStream("/sdcard/avss/h264.264");//264码流
  37. Log.i(TAG, "h264FileOutputStream");
  38. } catch (FileNotFoundException e)
  39. {
  40. // TODO Auto-generated catch block
  41. e.printStackTrace();
  42. }
  43. try
  44. {
  45. h264FileOutputStream.write(h264head);
  46. h264FileOutputStream.write(h264sps);
  47. h264FileOutputStream.write(h264head);
  48. h264FileOutputStream.write(h264pps);
  49. Log.i(TAG, "run-write SPS/PPS to file");
  50. } catch (IOException e1)
  51. {
  52. // TODO Auto-generated catch block
  53. e1.printStackTrace();
  54. }
  55. while (bIfRecInProcess && (!bIfNativeORRemote))
  56. {
  57. try
  58. {
  59. Log.i(TAG, "**while...");
  60. int h264length = dataInputStream.readInt();
  61. Log.i(TAG, "h264length:"+h264length);
  62. tmp=0; offSet = 0; beLeft = 0;
  63. h264FileOutputStream.write(h264head);
  64. while (offSet < h264length)
  65. {
  66. beLeft = h264length - offSet;
  67. tmp = dataInputStream.read(h264frame, 0, READ_SIZE < beLeft ? READ_SIZE : beLeft);
  68. Log.i(TAG, String.format("H264 %d,%d,%d", h264length, offSet, tmp));
  69. offSet += tmp;
  70. h264FileOutputStream.write(h264frame, 0, tmp);
  71. }
  72. } catch (Exception e)
  73. {
  74. // TODO: handle exception
  75. e.printStackTrace();
  76. }
  77. }
  78. //
  79. }

复制代码

#


1 http://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

发表评论

表情:
评论列表 (有 0 条评论,661人围观)

还没有评论,来说两句吧...

相关阅读

    相关 【音视频H264编码基础

    H264编码基础 0x1 基本介绍 视频是由一帧帧图像组成,视频为了不卡顿,一秒钟至少要16帧画面,但是图片内容太大,传输不现实。因此需要对他们编码。 官方文档:

    相关 H.264编码

    1.为什么要对视频进行编码 视频是连续的图像序列,由连续的帧构成,一帧即为一幅图像,由于人眼的视觉暂留效应,当帧序列以一定的速率播放时,我们看到的就是动作连续的视频,这么