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層編碼效率高,還是上層高?