Android平台在上层实现mediacodec的编码,资料泛滥,已经不再是难事,今天给大家介绍下,如何在Android native层实现MediaCodec编码H264/HEVC,网上千篇一律的接口说明,这里不再赘述,本文主要介绍下,一些需要注意的点,权当抛砖引玉,相关设计界面如下:
问题1:有了上层MediaCodec编码方案,为什么还要开发Native层解决方案?
回答:由于我们的数据流向是编码前YV12/NV21/NV12/I420/RGB24/RGBA32/RGB565等数据类型,底层统一处理后,实现H264、HEVC的编码,减少了上下层之间的交互,效率更高,支持的编码前video数据接口设计如下:
- /**
- * 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);
-
-
- /**
- * 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);
-
-
- /**
- * 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);
-
-
- /**
- * NV21转换到I420并旋转
- *
- * @param src: nv21 data
- *
- * @param dst: 输出I420 data
- *
- * @param width: 图像宽
- *
- * @param height: 图像高
- *
- * rotation_degree: 顺时针旋转, 必须是0, 90, 180, 270
- *
- * @return {0} if successful
- */
- public native int SmartPublisherNV21ToI420Rotate(long handle, byte[] src, int src_y_stride, int src_uv_stride, byte[] dst,
- int dst_y_stride, int dst_u_stride, int dst_v_stride,
- int width, int height,
- int rotation_degree);
-
-
- /**
- * 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);
-
-
- /**
- * 传I420图像接口
- *
- * @param data: I420 data
- *
- * @param width: 图像宽
- *
- * @param height: 图像高
- *
- * @param y_stride: y stride
- *
- * @param u_stride: u stride
- *
- * @param v_stride: v stride
- *
- * @return {0} if successful
- */
- public native int SmartPublisherOnCaptureVideoI420DataV2(long handle, byte[] data, int width, int height, int y_stride, int u_stride, int v_stride);
-
-
- /**
- * Set live video data(no encoded data).
- *
- * @param buffer: RGB24 data
- *
- * @param length: data length
- *
- * @param rowStride: stride information
- *
- * @param width: width
- *
- * @param height: height
- *
- * @param is_vertical_flip: 是否垂直翻转, 0不翻转, 1翻转
- *
- * @param is_horizontal_flip:是否水平翻转, 0不翻转, 1翻转
- *
- * @param rotation_degree: 顺时针旋转, 必须是0, 90, 180, 270
- *
- * @param scale_width: 缩放宽,必须是8的倍数, 0不缩放
- *
- * @param scale_height: 缩放高, 必须是8的倍数, 0不缩放
- *
- * @param scale_filter_mode: 缩放质量, 范围必须是[1,3], 传0使用默认质量
- *
- * @return {0} if successful
- */
- public native int SmartPublisherOnCaptureVideoRGB24Data(long handle, long buffer, int length, int rowStride, int width, int height,
- int is_vertical_flip, int is_horizontal_flip,int rotation_degree,
- int scale_width, int scale_height, int scale_filter_mode);
-
- /**
- * Set live video data(no encoded data).
- *
- * @param buffer: RGBA data
- *
- * @param length: data length
- *
- * @param rowStride: stride information
- *
- * @param width: width
- *
- * @param height: height
- *
- * @param is_vertical_flip: 是否垂直翻转, 0不翻转, 1翻转
- *
- * @param is_horizontal_flip:是否水平翻转, 0不翻转, 1翻转
- *
- * @param rotation_degree: 顺时针旋转, 必须是0, 90, 180, 270
- *
- * @param scale_width: 缩放宽,必须是8的倍数, 0不缩放
- *
- * @param scale_height: 缩放高, 必须是8的倍数, 0不缩放
- *
- * @param scale_filter_mode: 缩放质量, 范围必须是[1,3], 传0使用默认质量
- *
- * @return {0} if successful
- */
- public native int SmartPublisherOnCaptureVideoRGBA32Data(long handle, long buffer, int length, int rowStride, int width, int height,
- int is_vertical_flip, int is_horizontal_flip,int rotation_degree,
- int scale_width, int scale_height, int scale_filter_mode);
-
- /**
- * 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);
-
-
- /**
- * 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);
-
-
- /*
- * 专门为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);
-
-
- /**
- * 启用或者停用视频层, 这个接口必须在StartXXX之后调用.
- *
- * @param index: 层索引, 必须大于0, 注意第0层不能停用
- *
- * @param is_enable: 是否启用, 0停用, 1启用
- *
- * @return {0} if successful
- */
- public native int EnableLayer(long handle, int index, int is_enable);
-
-
- /**
- * 移除视频层, 这个接口必须在StartXXX之后调用.
- *
- * @param index: 层索引, 必须大于0, 注意第0层不能移除
- *
- * @return {0} if successful
- */
- public native int RemoveLayer(long handle, int index);
-
-
- /**
- * 投递层RGBA8888图像,如果不需要Aplpha通道的话, 请使用RGBX8888接口, 效率高
- *
- * @param index: 层索引, 必须大于等于0, 注意:如果index是0的话,将忽略Alpha通道
- *
- * @param left: 层叠加的左上角坐标, 对于第0层的话传0
- *
- * @param top: 层叠加的左上角坐标, 对于第0层的话传0
- *
- * @param rgba_plane: rgba 图像数据
- *
- * @param offset: 图像偏移, 这个主要目的是用来做clip的, 一般传0
- *
- * @param row_stride: stride information
- *
- * @param width: width, 必须大于1, 如果是奇数, 将减1
- *
- * @param height: height, 必须大于1, 如果是奇数, 将减1
- *
- * @param is_vertical_flip: 是否垂直翻转, 0不翻转, 1翻转
- *
- * @param is_horizontal_flip:是否水平翻转, 0不翻转, 1翻转
- *
- * @param scale_width: 缩放宽,必须是偶数, 0或负数不缩放
- *
- * @param scale_height: 缩放高, 必须是偶数, 0或负数不缩放
- *
- * @param scale_filter_mode: 缩放质量, 传0使用默认速度,可选等级范围是:[1,3],值越大缩放质量越好, 但速度越慢
- *
- * @param rotation_degree: 顺时针旋转, 必须是0, 90, 180, 270, 注意:旋转是在缩放, 垂直/水品反转之后再做, 请留意顺序
- *
- * @return {0} if successful
- */
- public native int PostLayerImageRGBA8888ByteBuffer(long handle, int index, int left, int top,
- ByteBuffer rgba_plane, int offset, int row_stride, int width, int height,
- int is_vertical_flip, int is_horizontal_flip,
- int scale_width, int scale_height, int scale_filter_mode,
- int rotation_degree);
-
-
- /**
- * 投递层RGBA8888图像, 详细说明请参考PostLayerImageRGBA8888ByteBuffer
- *
- * @return {0} if successful
- */
- public native int PostLayerImageRGBA8888ByteArray(long handle, int index, int left, int top,
- byte[] rgba_plane, int offset, int row_stride, int width, int height,
- int is_vertical_flip, int is_horizontal_flip,
- int scale_width, int scale_height, int scale_filter_mode,
- int rotation_degree);
-
-
- /**
- * 投递层RGBA8888图像, 详细说明请参考PostLayerImageRGBA8888ByteBuffer
- *
- * @return {0} if successful
- */
- public native int PostLayerImageRGBA8888Native(long handle, int index, int left, int top,
- long rgba_plane, int offset, int row_stride, int width, int height,
- int is_vertical_flip, int is_horizontal_flip,
- int scale_width, int scale_height, int scale_filter_mode,
- int rotation_degree);
-
-
- /**
- * 投递层RGBX8888图像
- *
- * @param index: 层索引, 必须大于等于0
- *
- * @param left: 层叠加的左上角坐标, 对于第0层的话传0
- *
- * @param top: 层叠加的左上角坐标, 对于第0层的话传0
- *
- * @param rgbx_plane: rgbx 图像数据
- *
- * @param offset: 图像偏移, 这个主要目的是用来做clip的,一般传0
- *
- * @param row_stride: stride information
- *
- * @param width: width, 必须大于1, 如果是奇数, 将减1
- *
- * @param height: height, 必须大于1, 如果是奇数, 将减1
- *
- * @param is_vertical_flip: 是否垂直翻转, 0不翻转, 1翻转
- *
- * @param is_horizontal_flip:是否水平翻转, 0不翻转, 1翻转
- *
- * @param scale_width: 缩放宽,必须是偶数, 0或负数不缩放
- *
- * @param scale_height: 缩放高, 必须是偶数, 0或负数不缩放
- *
- * @param scale_filter_mode: 缩放质量, 传0使用默认速度,可选等级范围是:[1,3],值越大缩放质量越好, 但速度越慢
- *
- * @param rotation_degree: 顺时针旋转, 必须是0, 90, 180, 270, 注意:旋转是在缩放, 垂直/水品反转之后再做, 请留意顺序
- *
- * @return {0} if successful
- */
- public native int PostLayerImageRGBX8888ByteBuffer(long handle, int index, int left, int top,
- ByteBuffer rgbx_plane, int offset, int row_stride, int width, int height,
- int is_vertical_flip, int is_horizontal_flip,
- int scale_width, int scale_height, int scale_filter_mode,
- int rotation_degree);
-
-
- /**
- * 投递层RGBX8888图像, 详细说明请参考PostLayerImageRGBX8888ByteBuffer
- *
- * @return {0} if successful
- */
- public native int PostLayerImageRGBX8888ByteArray(long handle, int index, int left, int top,
- byte[] rgbx_plane, int offset, int row_stride, int width, int height,
- int is_vertical_flip, int is_horizontal_flip,
- int scale_width, int scale_height, int scale_filter_mode,
- int rotation_degree);
-
-
- /**
- * 投递层RGBX8888图像, 详细说明请参考PostLayerImageRGBX8888ByteBuffer
- *
- * @return {0} if successful
- */
- public native int PostLayerImageRGBX8888Native(long handle, int index, int left, int top,
- long rgbx_plane, int offset, int row_stride, int width, int height,
- int is_vertical_flip, int is_horizontal_flip,
- int scale_width, int scale_height, int scale_filter_mode,
- int rotation_degree);
-
-
- /**
- * 投递层RGB888图像
- *
- * @param index: 层索引, 必须大于等于0
- *
- * @param left: 层叠加的左上角坐标, 对于第0层的话传0
- *
- * @param top: 层叠加的左上角坐标, 对于第0层的话传0
- *
- * @param rgb_plane: rgb888 图像数据
- *
- * @param offset: 图像偏移, 这个主要目的是用来做clip的,一般传0
- *
- * @param row_stride: stride information
- *
- * @param width: width, 必须大于1, 如果是奇数, 将减1
- *
- * @param height: height, 必须大于1, 如果是奇数, 将减1
- *
- * @param is_vertical_flip: 是否垂直翻转, 0不翻转, 1翻转
- *
- * @param is_horizontal_flip:是否水平翻转, 0不翻转, 1翻转
- *
- * @param scale_width: 缩放宽,必须是偶数, 0或负数不缩放
- *
- * @param scale_height: 缩放高, 必须是偶数, 0或负数不缩放
- *
- * @param scale_filter_mode: 缩放质量, 传0使用默认速度,可选等级范围是:[1,3],值越大缩放质量越好, 但速度越慢
- *
- * @param rotation_degree: 顺时针旋转, 必须是0, 90, 180, 270, 注意:旋转是在缩放, 垂直/水品反转之后再做, 请留意顺序
- *
- * @return {0} if successful
- */
- public native int PostLayerImageRGB888Native(long handle, int index, int left, int top,
- long rgb_plane, int offset, int row_stride, int width, int height,
- int is_vertical_flip, int is_horizontal_flip,
- int scale_width, int scale_height, int scale_filter_mode,
- int rotation_degree);
-
-
- /**
- * 投递层NV21图像
- *
- * @param index: 层索引, 必须大于等于0
- *
- * @param left: 层叠加的左上角坐标, 对于第0层的话传0
- *
- * @param top: 层叠加的左上角坐标, 对于第0层的话传0
- *
- * @param y_plane: y平面图像数据
- *
- * @param y_offset: 图像偏移, 这个主要目的是用来做clip的,一般传0
- *
- * @param y_row_stride: stride information
- *
- * @param uv_plane: uv平面图像数据
- *
- * @param uv_offset: 图像偏移, 这个主要目的是用来做clip的,一般传0
- *
- * @param uv_row_stride: stride information
- *
- * @param width: width, 必须大于1, 且必须是偶数
- *
- * @param height: height, 必须大于1, 且必须是偶数
- *
- * @param is_vertical_flip: 是否垂直翻转, 0不翻转, 1翻转
- *
- * @param is_horizontal_flip:是否水平翻转, 0不翻转, 1翻转
- *
- * @param scale_width: 缩放宽,必须是偶数, 0或负数不缩放
- *
- * @param scale_height: 缩放高, 必须是偶数, 0或负数不缩放
- *
- * @param scale_filter_mode: 缩放质量, 传0使用默认速度,可选等级范围是:[1,3],值越大缩放质量越好, 但速度越慢
- *
- * @param rotation_degree: 顺时针旋转, 必须是0, 90, 180, 270, 注意:旋转是在缩放, 垂直/水品反转之后再做, 请留意顺序
- *
- * @return {0} if successful
- */
- public native int PostLayerImageNV21ByteBuffer(long handle, int index, int left, int top,
- ByteBuffer y_plane, int y_offset, int y_row_stride,
- ByteBuffer uv_plane, int uv_offset, int uv_row_stride,
- int width, int height, int is_vertical_flip, int is_horizontal_flip,
- int scale_width, int scale_height, int scale_filter_mode,
- int rotation_degree);
-
-
- /**
- * 投递层NV21图像, 详细说明请参考PostLayerImageNV21ByteBuffer
- *
- * @return {0} if successful
- */
- public native int PostLayerImageNV21ByteArray(long handle, int index, int left, int top,
- byte[] y_plane, int y_offset, int y_row_stride,
- byte[] uv_plane, int uv_offset, int uv_row_stride,
- int width, int height, int is_vertical_flip, int is_horizontal_flip,
- int scale_width, int scale_height, int scale_filter_mode,
- int rotation_degree);
-
-
- /**
- * 投递层NV12图像, 详细说明请参考PostLayerImageNV21ByteBuffer
- *
- * @return {0} if successful
- */
- public native int PostLayerImageNV12ByteBuffer(long handle, int index, int left, int top,
- ByteBuffer y_plane, int y_offset, int y_row_stride,
- ByteBuffer uv_plane, int uv_offset, int uv_row_stride,
- int width, int height, int is_vertical_flip, int is_horizontal_flip,
- int scale_width, int scale_height, int scale_filter_mode,
- int rotation_degree);
-
-
- /**
- * 投递层NV12图像, 详细说明请参考PostLayerImageNV21ByteBuffer
- *
- * @return {0} if successful
- */
- public native int PostLayerImageNV12ByteArray(long handle, int index, int left, int top,
- byte[] y_plane, int y_offset, int y_row_stride,
- byte[] uv_plane, int uv_offset, int uv_row_stride,
- int width, int height, int is_vertical_flip, int is_horizontal_flip,
- int scale_width, int scale_height, int scale_filter_mode,
- int rotation_degree);
-
-
- /**
- * 投递层I420图像
- *
- * @param index: 层索引, 必须大于等于0
- *
- * @param left: 层叠加的左上角坐标, 对于第0层的话传0
- *
- * @param top: 层叠加的左上角坐标, 对于第0层的话传0
- *
- * @param y_plane: y平面图像数据
- *
- * @param y_offset: 图像偏移, 这个主要目的是用来做clip的,一般传0
- *
- * @param y_row_stride: stride information
- *
- * @param u_plane: u平面图像数据
- *
- * @param u_offset: 图像偏移, 这个主要目的是用来做clip的,一般传0
- *
- * @param u_row_stride: stride information
- * *
- * @param v_plane: v平面图像数据
- *
- * @param v_offset: 图像偏移, 这个主要目的是用来做clip的,一般传0
- *
- * @param v_row_stride: stride information
- *
- * @param width: width, 必须大于1, 且必须是偶数
- *
- * @param height: height, 必须大于1, 且必须是偶数
- *
- * @param is_vertical_flip: 是否垂直翻转, 0不翻转, 1翻转
- *
- * @param is_horizontal_flip:是否水平翻转, 0不翻转, 1翻转
- *
- * @param scale_width: 缩放宽,必须是偶数, 0或负数不缩放
- *
- * @param scale_height: 缩放高, 必须是偶数, 0或负数不缩放
- *
- * @param scale_filter_mode: 缩放质量, 传0使用默认速度,可选等级范围是:[1,3],值越大缩放质量越好, 但速度越慢
- *
- * @param rotation_degree: 顺时针旋转, 必须是0, 90, 180, 270, 注意:旋转是在缩放, 垂直/水品反转之后再做, 请留意顺序
- *
- * @return {0} if successful
- */
- public native int PostLayerImageI420ByteBuffer(long handle, int index, int left, int top,
- ByteBuffer y_plane, int y_offset, int y_row_stride,
- ByteBuffer u_plane, int u_offset, int u_row_stride,
- ByteBuffer v_plane, int v_offset, int v_row_stride,
- int width, int height, int is_vertical_flip, int is_horizontal_flip,
- int scale_width, int scale_height, int scale_filter_mode,
- int rotation_degree);
-
-
- /**
- * 投递层I420图像, 详细说明请参考PostLayerImageI420ByteBuffer
- *
- * @return {0} if successful
- */
- public native int PostLayerImageI420ByteArray(long handle, int index, int left, int top,
- byte[] y_plane, int y_offset, int y_row_stride,
- byte[] u_plane, int u_offset, int u_row_stride,
- byte[] v_plane, int v_offset, int v_row_stride,
- int width, int height, int is_vertical_flip, int is_horizontal_flip,
- int scale_width, int scale_height, int scale_filter_mode,
- int rotation_degree);
-
-
- /**
- * 投递层YUV420888图像, 专门为android.media.Image的android.graphics.ImageFormat.YUV_420_888格式提供的接口
- *
- * @param index: 层索引, 必须大于等于0
- *
- * @param left: 层叠加的左上角坐标, 对于第0层的话传0
- *
- * @param top: 层叠加的左上角坐标, 对于第0层的话传0
- *
- * @param y_plane: 对应android.media.Image.Plane[0].getBuffer()
- *
- * @param y_offset: 图像偏移, 这个主要目的是用来做clip的,一般传0
- *
- * @param y_row_stride: 对应android.media.Image.Plane[0].getRowStride()
- *
- * @param u_plane: android.media.Image.Plane[1].getBuffer()
- *
- * @param u_offset: 图像偏移, 这个主要目的是用来做clip的,一般传0
- *
- * @param u_row_stride: android.media.Image.Plane[1].getRowStride()
- *
- * @param v_plane: 对应android.media.Image.Plane[2].getBuffer()
- *
- * @param v_offset: 图像偏移, 这个主要目的是用来做clip的,一般传0
- *
- * @param v_row_stride: 对应android.media.Image.Plane[2].getRowStride()
- *
- * @param uv_pixel_stride: 对应android.media.Image.Plane[1].getPixelStride()
- *
- * @param width: width, 必须大于1, 且必须是偶数
- *
- * @param height: height, 必须大于1, 且必须是偶数
- *
- * @param is_vertical_flip: 是否垂直翻转, 0不翻转, 1翻转
- *
- * @param is_horizontal_flip:是否水平翻转, 0不翻转, 1翻转
- *
- * @param scale_width: 缩放宽,必须是偶数, 0或负数不缩放
- *
- * @param scale_height: 缩放高, 必须是偶数, 0或负数不缩放
- *
- * @param scale_filter_mode: 缩放质量, 传0使用默认速度,可选等级范围是:[1,3],值越大缩放质量越好, 但速度越慢
- *
- * @param rotation_degree: 顺时针旋转, 必须是0, 90, 180, 270, 注意:旋转是在缩放, 垂直/水品反转之后再做, 请留意顺序
- *
- * @return {0} if successful
- */
- public native int PostLayerImageYUV420888ByteBuffer(long handle, int index, int left, int top,
- ByteBuffer y_plane, int y_offset, int y_row_stride,
- ByteBuffer u_plane, int u_offset, int u_row_stride,
- ByteBuffer v_plane, int v_offset, int v_row_stride, int uv_pixel_stride,
- int width, int height, int is_vertical_flip, int is_horizontal_flip,
- int scale_width, int scale_height, int scale_filter_mode,
- int rotation_degree);
问题2:Android Native层MediaCodec编码,从什么版本开始支持的,支持什么架构?
回答:从5.0开始,armv8,如果像我们一样,想支持armv7也未尝不可,需要底层动态加载lib so,然后接口再做一层封装即可,设置MediaCodec Native硬编码时,底层需要判断下系统版本,相关设计接口如下:
- /**
- * 设置视频硬编码是否使用 Native Media NDK, 默认是不使用, 安卓5.0以下设备不支持
- * @param handle
- * @param is_native: 0表示不使用, 1表示使用, sdk默认是0.
- * @return {0} if successful
- */
- public native int SetNativeMediaNDK(long handle, int is_native);
问题3:看了下MediaCodec的接口,底层接口好像不像上层的那么全,是不是会导致编码效果大打折扣?
回答:MediaCodec的native接口的调用,确实不如上层的那么方便,比如,判断系统是否支持特定编码类型硬编或支持的color format等信息,可以采用上下层结合的形式。
问题4:底层如何判断关键帧?
回答:和上层一样,参考以下代码:
bool is_key_frame = info.flags & AMEDIACODEC_BUFFER_FLAG_KEY_FRAME;
问题5:如何获取codec config?
回答:和上层类似,参考以下代码:
- if (info.flags & AMEDIACODEC_BUFFER_FLAG_CODEC_CONFIG) {
- config_info.clear();
- config_info.insert(config_info_.end(), output_buffer + info.offset, output_buffer + info.offset + info.size);
- }
问题6:创建MediaFormat有什么特别之处吗?
回答:没啥特别之处,设置下如mine_type、width、height,编码码率、fps、关键帧间隔等信息即可。
问题7:编码过程中,比如发生横竖屏切换等,导致分辨率变化怎么办?
回答:重启encoder即可。
问题8:我想比较下到底native层编码效率高,还是上层高?
回答:可以快速写代码尝试,也可私信我,试试我们的,从我们测试来看,由于本身我们上层调用的,也做的非常优异了,native层相对来说,更多地是调用效率的提高,后续扩展更方便。
问题9:Android Native层编码后的数据,可以用在什么场景下?
回答:编码后的H264、HEVC数据,按照协议栈要求,用于需要视频传输的场景都可以,比如RTMP推送、GB28181设备接入,轻量级RTSP服务,甚至私有协议传输都OK。