zoukankan      html  css  js  c++  java
  • 【流媒体】 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录制 ” 


    核心代码

    ① 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

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

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

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

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

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

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

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

  • 相关阅读:
    xml ui
    xml ui
    xml ui
    debug
    centOS7 mini配置linux服务器(一)安装centOs7
    数据结构之__链表
    数据结构之__队列
    数据结构之__栈
    在树莓派上使用 SSD1306 OLED 屏幕
    git官方手册
  • 原文地址:https://www.cnblogs.com/GarfieldEr007/p/5459638.html
Copyright © 2011-2022 走看看