前言

好多开发者在调用Android平台RTMP推送或轻量级RTSP服务接口时,采集到的video数据类型多样化,如420sp、I420、yv12、nv21、rgb的,还有的拿到的图像是倒置的,如果开发者在上层转换后,传到底层编码处理,无疑加大了上层处理负担,而且容易因为低效率影响体验,本文以大牛直播SDK的Android平台RTMP推送SDK编码前video数据对接接口为例,看看常用的数据格式有哪些,相关资料,可参考 Github

1. Android摄像头前后camera通过OnPreviewFrame()回调的数据接口:

Android自带的camera摄像头数据对接是最基础的,需要考虑的是摄像头方向问题,比如横屏、竖屏、还有部分定制设备home键在左侧的情况,相对来说处理比较简单,直接上接口,不再赘述。

    @Override
public void onPreviewFrame(byte[] data, Camera camera) {
frameCount++;
if (frameCount % 3000 == 0) {
Log.i("OnPre", "gc+");
System.gc();
Log.i("OnPre", "gc-");
} if (data == null) {
Parameters params = camera.getParameters();
Size size = params.getPreviewSize();
int bufferSize = (((size.width | 0x1f) + 1) * size.height * ImageFormat.getBitsPerPixel(params.getPreviewFormat())) / 8;
camera.addCallbackBuffer(new byte[bufferSize]);
} else {
if (isRTSPPublisherRunning || isPushingRtmp || isRecording || isPushingRtsp) {
libPublisher.SmartPublisherOnCaptureVideoData(publisherHandle, data, data.length, currentCameraType, currentOrigentation);
} camera.addCallbackBuffer(data);
}
}

对应接口定义:

/**
    * Set live video data(no encoded data).
    *
    * @param cameraType: CAMERA_FACING_BACK with 0, CAMERA_FACING_FRONT with 1
    * 
    * @param curOrg:
         * PORTRAIT = 1;    //竖屏
         * LANDSCAPE = 2;    //横屏 home键在右边的情况
         * LANDSCAPE_LEFT_HOME_KEY = 3; //横屏 home键在左边的情况
    *
    * @return {0} if successful
    */
    public native int SmartPublisherOnCaptureVideoData(long handle, byte[] data, int len, int cameraType, int curOrg);

2. 部分定制设备,只支持YV12的数据:

一般用于第三方摄像头对接之用,第三方摄像头,以YV12和NV21居多,部分需要旋转。

    /**
     * YV12数据接口
     *
     * @param data: YV12 data
     *
     * @param width: 图像宽
     *
     * @param height: 图像高
     *
     * @param y_stride:  y面步长
     *
     * @param v_stride: v面步长
     *
     * @param u_stride: u面步长
     *
     * rotation_degree: 顺时针旋转, 必须是0, 90, 180, 270
     *
     * @return {0} if successful
     */
    public native int SmartPublisherOnYV12Data(long handle, byte[] data, int width, int height, int y_stride,  int v_stride, int u_stride, int rotation_degree);

3. 支持NV21数据接口:

nv21数据接口,除了用于常规的camera数据接入外,部分定制摄像头出来的数据发生翻转,这个接口也支持。

    /**
     * NV21数据接口
     *
     * @param data: nv21 data
     *
     * @param len: data length
     *
     * @param width: 图像宽
     *
     * @param height: 图像高
     *
     * @param y_stride:  y面步长
     *
     * @param uv_stride:  uv面步长
     *
     * rotation_degree: 顺时针旋转, 必须是0, 90, 180, 270
     *
     * @return {0} if successful
     */
    public native int SmartPublisherOnNV21Data(long handle, byte[] data, int len, int width, int height, int y_stride,  int uv_stride, int rotation_degree);     /**
     * NV21数据接口
     *
     * @param data: nv21 data
     *
     * @param len: data length
     *
     * @param width: 图像宽
     *
     * @param height: 图像高
     *
     * @param y_stride:  y面步长
     *
     * @param uv_stride:  uv面步长
     *
     * rotation_degree: 顺时针旋转, 必须是0, 90, 180, 270
     *
     * @param  is_vertical_flip: 是否垂直翻转, 0不翻转, 1翻转
     *
     * @param  is_horizontal_flip:是否水平翻转, 0不翻转, 1翻转
     *
     * @return {0} if successful
     */
    public native int SmartPublisherOnNV21DataV2(long handle, byte[] data, int len, int width, int height, int y_stride,  int uv_stride, int rotation_degree,
                                                 int is_vertical_flip, int is_horizontal_flip);

4. 支持YUV数据接入:

支持标准的I420数据接口对接。

    /**
    * Set live video data(no encoded data).
    *
    * @param data: I420 data
    * 
    * @param len: I420 data length
    * 
    * @param yStride: y stride
    * 
    * @param uStride: u stride
    * 
    * @param vStride: v stride
    *
    * @return {0} if successful
    */
    public native int SmartPublisherOnCaptureVideoI420Data(long handle,  byte[] data, int len, int yStride, int uStride, int vStride);

5. 支持RGBA数据接入(支持裁剪后数据接入,主要用于同屏场景):

RGBA的主要用于屏幕共享场景下,为了便于推送屏幕部分区域,我们友好的加了裁剪参数。

    /**
    * Set live video data(no encoded data).
    *
    * @param data: RGBA data
    * 
    * @param rowStride: stride information
    * 
    * @param width: width
    * 
    * @param height: height
    *
    * @return {0} if successful
    */
    public native int SmartPublisherOnCaptureVideoRGBAData(long handle,  ByteBuffer data, int rowStride, int width, int height);     /**
     * 投递裁剪过的RGBA数据
     *
     * @param data: RGBA data
     *
     * @param rowStride: stride information
     *
     * @param width: width
     *
     * @param height: height
     *
     * @param clipedLeft: 左;  clipedTop: 上; clipedwidth: 裁剪后的宽; clipedHeight: 裁剪后的高; 确保传下去裁剪后的宽、高均为偶数
     *
     * @return {0} if successful
     */
    public native int SmartPublisherOnCaptureVideoClipedRGBAData(long handle,  ByteBuffer data, int rowStride, int width, int height, int clipedLeft, int clipedTop, int clipedWidth, int clipedHeight);     /**
     * Set live video data(no encoded data).
     *
     * @param data: ABGR flip vertical(垂直翻转) data
     *
     * @param rowStride: stride information
     *
     * @param width: width
     *
     * @param height: height
     *
     * @return {0} if successful
     */
    public native int SmartPublisherOnCaptureVideoABGRFlipVerticalData(long handle,  ByteBuffer data, int rowStride, int width, int height);

6. 支持RGB565数据接入(主要用于同屏场景):

同屏场景居多。

    /**
     * Set live video data(no encoded data).
     *
     * @param data: RGB565 data
     *
     * @param row_stride: stride information
     *
     * @param width: width
     *
     * @param height: height
     *
     * @return {0} if successful
     */
    public native int SmartPublisherOnCaptureVideoRGB565Data(long handle,ByteBuffer data, int row_stride, int width, int height);

7. 支持camera数据接入(主要用于camera2接口对接):
    为了更高效率的兼容camera2数据采集模式。

/*
    *  专门为android.media.Image的android.graphics.ImageFormat.YUV_420_888格式提供的接口
    *
    * @param  width: 必须是8的倍数
    *
    * @param  height: 必须是8的倍数
    *
    * @param  crop_left: 剪切左上角水平坐标, 一般根据android.media.Image.getCropRect() 填充
    *
    * @param  crop_top: 剪切左上角垂直坐标, 一般根据android.media.Image.getCropRect() 填充
    *
    * @param  crop_width: 必须是8的倍数, 填0将忽略这个参数, 一般根据android.media.Image.getCropRect() 填充
    *
    * @param  crop_height: 必须是8的倍数, 填0将忽略这个参数,一般根据android.media.Image.getCropRect() 填充
    *
    * @param y_plane 对应android.media.Image.Plane[0].getBuffer()
    *
    * @param y_row_stride 对应android.media.Image.Plane[0].getRowStride()
    *
    * @param u_plane 对应android.media.Image.Plane[1].getBuffer()
    *
    * @param v_plane 对应android.media.Image.Plane[2].getBuffer()
    *
    * @param uv_row_stride 对应android.media.Image.Plane[1].getRowStride()
    *
    * @param uv_pixel_stride 对应android.media.Image.Plane[1].getPixelStride()
    *
    * @param  rotation_degree: 顺时针旋转, 必须是0, 90, 180, 270
    *
    * @param  is_vertical_flip: 是否垂直翻转, 0不翻转, 1翻转
    *
    * @param  is_horizontal_flip:是否水平翻转, 0不翻转, 1翻转
    *
    * @param  scale_width: 缩放宽,必须是8的倍数, 0不缩放
    *
    * @param  scale_height: 缩放高, 必须是8的倍数, 0不缩放
    *
    * @param  scale_filter_mode: 缩放质量, 范围必须是[1,3], 传0使用默认速度
    *
    * @return {0} if successful
    */
    public native int SmartPublisherOnImageYUV420888(long handle, int width, int height,
                                                     int crop_left, int crop_top, int crop_width, int crop_height,
                                                     ByteBuffer y_plane, int y_row_stride,
                                                     ByteBuffer u_plane, ByteBuffer v_plane, int uv_row_stride, int uv_pixel_stride,
                                                     int rotation_degree, int is_vertical_flip, int is_horizontal_flip,
                                                     int scale_width, int scale_height, int scale_filter_mode);

总结:

以上仅是Android编码前video数据接口对接分享,感兴趣的开发者可酌情参考,由此可见,部分公司或开发者提到,一个Android平台的RTMP推送模块只要几个接口,化繁为简几乎是不可能的,除非。。

Android同屏、摄像头RTMP推送常用的数据接口设计探讨的更多相关文章

  1. EasyPusher进行Android UVC外接摄像头直播推送实现方法

    最近EasyPusher针对UVC摄像头做了适配.我们结合了UVCCamera与EasyPusher,支持将UVC摄像头的视频推送到RTSP服务器上.在此特别感谢UVCCamera这个牛逼的项目! 来 ...

  2. Android平台摄像头/屏幕/外部数据采集及RTMP推送接口设计描述

    好多开发者提到,为什么大牛直播SDK的Android平台RTMP推送接口怎么这么多?不像一些开源或者商业RTMP推送一样,就几个接口,简单明了. 不解释,以Android平台RTMP推送模块常用接口, ...

  3. Windows平台摄像头或屏幕RTMP推送介绍:OBS VS SmartPublisher

    好多开发者问道,既然有了OBS,你们为什么还要开发SmartPublisher? 的确,在我们进行Windows平台RTMP推送模块开发之前,市面上为数不多的Windows平台RTMP推流工具当属OB ...

  4. 最简单的基于Flash的流媒体示例:RTMP推送和接收(ActionScript)

    ===================================================== Flash流媒体文章列表: 最简单的基于Flash的流媒体示例:RTMP推送和接收(Acti ...

  5. 解决RTMP推送时间戳问题引起HLS切片不均匀导致手机浏览器播放卡顿的问题

    本文转自EasyDarwin开源团队成员Kim的博客:http://blog.csdn.net/jinlong0603/article/details/74161115 引言 最近在测试EasyNVR ...

  6. EasyRTMP推送扩展支持HEVC(H265) RTMP推送之Metadata结构填写详解

    我们在<EasyNVR摄像机网页直播中,推流组件EasyRTMP推送RTMP扩展支持HEVC(H.265)的方案>中描述了关于EasyRTMP进行RTMP HEVC(H.265)推流的概括 ...

  7. Android 基于Netty的消息推送方案之对象的传递(四)

    在上一篇文章中<Android 基于Netty的消息推送方案之字符串的接收和发送(三)>我们介绍了Netty的字符串传递,我们知道了Netty的消息传递都是基于流,通过ChannelBuf ...

  8. Android 基于Netty的消息推送方案之字符串的接收和发送(三)

    在上一篇文章中<Android 基于Netty的消息推送方案之概念和工作原理(二)> ,我们介绍过一些关于Netty的概念和工作原理的内容,今天我们先来介绍一个叫做ChannelBuffe ...

  9. Android 基于Netty的消息推送方案之概念和工作原理(二)

    上一篇文章中我讲述了关于消息推送的方案以及一个基于Netty实现的一个简单的Hello World,为了更好的理解Hello World中的代码,今天我来讲解一下关于Netty中一些概念和工作原理的内 ...

随机推荐

  1. 手把手教你实现一个Vue无限级联树形表格(增删改)

    前言平时我们可能在做项目时,会遇到一个业务逻辑.实现一个无限级联树形表格,什么叫做无限级联树形表格呢?就是下图所展示的内容,有一个祖元素,然后下面可能有很多子孙元素,你可以实现添加.编辑.删除这样几个 ...

  2. 设计模式-策略模式前端应用校验vue写法

    1.定义:定义一系列算法,把它们一个个封装起来,并且它们可以相互替换 2.实际应用:减少if else的使用,在有多种算法相似的情况下,使用 if-else 所带来的复杂和难以维护,提高维护和可读性, ...

  3. 使用MySqlBulkLoader批量插入数据

    最近在项目中遇到插入几万.几十万.几百万的数据到MYSQL数据库,使用EF插入会发现插入速度非常慢的场景, 数据量非常大时EF插入需要几十分钟,甚至几个小时,这样子的速度肯定不是我们所期望的. 后面经 ...

  4. sql-sql优化

    SQL执行流程 a. 编写过程: select dinstinct .. from .. join .. on .. where .. group by .. having .. order by . ...

  5. 【Java面试】简单说一下你对序列化和反序列化的理解

    Hi,大家好,我是Mic 一个工作4年的粉丝,投了很多简历 好不容易接到一个互联网公司的面试邀约. 在面试第一轮就被干掉了,原因是对主流互联网技术理解太浅了. 其中就有一个这样的问题:"简单 ...

  6. C#请求HTTPS地址的故障分析和TLS知识点总结

    背景介绍 近期收到同事反馈,在C#程序中通过HTTPClient请求一个HTTPS的地址时,在本地开发环境和测试环境均能正常执行,而部署到生产环境后发生异常且稳定复现,异常提示为:[请求被中止: 未能 ...

  7. mongodb 数据块迁移的源码分析

    1. 简介 上一篇我们聊到了mongodb数据块的基本概念,和数据块迁移的主要流程,这篇文章我们聊聊源码实现部分. 2. 迁移序列图 数据块迁移的请求是从配置服务器(config server)发给( ...

  8. 阈值PSI代码

    阈值PSI 若交集数量超过某个给定阈值时,允许分布式的各个参与方在自己集合中找到交集,且除了交集外,得不到其他额外信息. 实现论文: Multi-Party Threshold Private Set ...

  9. 千万不要把Request传递到异步线程里面!有坑!

    你好哇,我是歪歪. 前几天在网上冲浪的时候看到一篇技术文章,讲的是他把一个 request 请求传递到了线程池里面,然后遇到了一个匪夷所思的情况. 他写了这篇文章,把自己针对这个问题的探索过程分享了出 ...

  10. Unity3D学习笔记10——纹理数组

    目录 1. 概述 2. 详论 2.1. 实现 2.2. 注意 3. 参考 1. 概述 个人认为,纹理数组是一个非常有用的图形特性.纹理本质上是一个二维的图形数据:通过纹理数组,给图形数据再加上了一个维 ...