• Android native层实现MediaCodec编码H264/HEVC


    Android平台在上层实现mediacodec的编码,资料泛滥,已经不再是难事,今天给大家介绍下,如何在Android native层实现MediaCodec编码H264/HEVC,网上千篇一律的接口说明,这里不再赘述,本文主要介绍下,一些需要注意的点,权当抛砖引玉,相关设计界面如下:

    问题1:有了上层MediaCodec编码方案,为什么还要开发Native层解决方案?

    回答:由于我们的数据流向是编码前YV12/NV21/NV12/I420/RGB24/RGBA32/RGB565等数据类型,底层统一处理后,实现H264、HEVC的编码,减少了上下层之间的交互,效率更高,支持的编码前video数据接口设计如下:

    1. /**
    2. * Set live video data(no encoded data).
    3. *
    4. * @param cameraType: CAMERA_FACING_BACK with 0, CAMERA_FACING_FRONT with 1
    5. *
    6. * @param curOrg:
    7. * PORTRAIT = 1; //竖屏
    8. * LANDSCAPE = 2; //横屏 home键在右边的情况
    9. * LANDSCAPE_LEFT_HOME_KEY = 3; //横屏 home键在左边的情况
    10. *
    11. * @return {0} if successful
    12. */
    13. public native int SmartPublisherOnCaptureVideoData(long handle, byte[] data, int len, int cameraType, int curOrg);
    14. /**
    15. * YV12数据接口
    16. *
    17. * @param data: YV12 data
    18. *
    19. * @param width: 图像宽
    20. *
    21. * @param height: 图像高
    22. *
    23. * @param y_stride: y面步长
    24. *
    25. * @param v_stride: v面步长
    26. *
    27. * @param u_stride: u面步长
    28. *
    29. * rotation_degree: 顺时针旋转, 必须是0, 90, 180, 270
    30. *
    31. * @return {0} if successful
    32. */
    33. public native int SmartPublisherOnYV12Data(long handle, byte[] data, int width, int height, int y_stride, int v_stride, int u_stride, int rotation_degree);
    34. /**
    35. * NV21数据接口
    36. *
    37. * @param data: nv21 data
    38. *
    39. * @param len: data length
    40. *
    41. * @param width: 图像宽
    42. *
    43. * @param height: 图像高
    44. *
    45. * @param y_stride: y面步长
    46. *
    47. * @param uv_stride: uv面步长
    48. *
    49. * rotation_degree: 顺时针旋转, 必须是0, 90, 180, 270
    50. *
    51. * @return {0} if successful
    52. */
    53. public native int SmartPublisherOnNV21Data(long handle, byte[] data, int len, int width, int height, int y_stride, int uv_stride, int rotation_degree);
    54. /**
    55. * NV21数据接口
    56. *
    57. * @param data: nv21 data
    58. *
    59. * @param len: data length
    60. *
    61. * @param width: 图像宽
    62. *
    63. * @param height: 图像高
    64. *
    65. * @param y_stride: y面步长
    66. *
    67. * @param uv_stride: uv面步长
    68. *
    69. * rotation_degree: 顺时针旋转, 必须是0, 90, 180, 270
    70. *
    71. * @param is_vertical_flip: 是否垂直翻转, 0不翻转, 1翻转
    72. *
    73. * @param is_horizontal_flip:是否水平翻转, 0不翻转, 1翻转
    74. *
    75. * @return {0} if successful
    76. */
    77. public native int SmartPublisherOnNV21DataV2(long handle, byte[] data, int len, int width, int height, int y_stride, int uv_stride, int rotation_degree,
    78. int is_vertical_flip, int is_horizontal_flip);
    79. /**
    80. * NV21转换到I420并旋转
    81. *
    82. * @param src: nv21 data
    83. *
    84. * @param dst: 输出I420 data
    85. *
    86. * @param width: 图像宽
    87. *
    88. * @param height: 图像高
    89. *
    90. * rotation_degree: 顺时针旋转, 必须是0, 90, 180, 270
    91. *
    92. * @return {0} if successful
    93. */
    94. public native int SmartPublisherNV21ToI420Rotate(long handle, byte[] src, int src_y_stride, int src_uv_stride, byte[] dst,
    95. int dst_y_stride, int dst_u_stride, int dst_v_stride,
    96. int width, int height,
    97. int rotation_degree);
    98. /**
    99. * Set live video data(no encoded data).
    100. *
    101. * @param data: I420 data
    102. *
    103. * @param len: I420 data length
    104. *
    105. * @param yStride: y stride
    106. *
    107. * @param uStride: u stride
    108. *
    109. * @param vStride: v stride
    110. *
    111. * @return {0} if successful
    112. */
    113. public native int SmartPublisherOnCaptureVideoI420Data(long handle, byte[] data, int len, int yStride, int uStride, int vStride);
    114. /**
    115. * 传I420图像接口
    116. *
    117. * @param data: I420 data
    118. *
    119. * @param width: 图像宽
    120. *
    121. * @param height: 图像高
    122. *
    123. * @param y_stride: y stride
    124. *
    125. * @param u_stride: u stride
    126. *
    127. * @param v_stride: v stride
    128. *
    129. * @return {0} if successful
    130. */
    131. public native int SmartPublisherOnCaptureVideoI420DataV2(long handle, byte[] data, int width, int height, int y_stride, int u_stride, int v_stride);
    132. /**
    133. * Set live video data(no encoded data).
    134. *
    135. * @param buffer: RGB24 data
    136. *
    137. * @param length: data length
    138. *
    139. * @param rowStride: stride information
    140. *
    141. * @param width: width
    142. *
    143. * @param height: height
    144. *
    145. * @param is_vertical_flip: 是否垂直翻转, 0不翻转, 1翻转
    146. *
    147. * @param is_horizontal_flip:是否水平翻转, 0不翻转, 1翻转
    148. *
    149. * @param rotation_degree: 顺时针旋转, 必须是0, 90, 180, 270
    150. *
    151. * @param scale_width: 缩放宽,必须是8的倍数, 0不缩放
    152. *
    153. * @param scale_height: 缩放高, 必须是8的倍数, 0不缩放
    154. *
    155. * @param scale_filter_mode: 缩放质量, 范围必须是[1,3], 传0使用默认质量
    156. *
    157. * @return {0} if successful
    158. */
    159. public native int SmartPublisherOnCaptureVideoRGB24Data(long handle, long buffer, int length, int rowStride, int width, int height,
    160. int is_vertical_flip, int is_horizontal_flip,int rotation_degree,
    161. int scale_width, int scale_height, int scale_filter_mode);
    162. /**
    163. * Set live video data(no encoded data).
    164. *
    165. * @param buffer: RGBA data
    166. *
    167. * @param length: data length
    168. *
    169. * @param rowStride: stride information
    170. *
    171. * @param width: width
    172. *
    173. * @param height: height
    174. *
    175. * @param is_vertical_flip: 是否垂直翻转, 0不翻转, 1翻转
    176. *
    177. * @param is_horizontal_flip:是否水平翻转, 0不翻转, 1翻转
    178. *
    179. * @param rotation_degree: 顺时针旋转, 必须是0, 90, 180, 270
    180. *
    181. * @param scale_width: 缩放宽,必须是8的倍数, 0不缩放
    182. *
    183. * @param scale_height: 缩放高, 必须是8的倍数, 0不缩放
    184. *
    185. * @param scale_filter_mode: 缩放质量, 范围必须是[1,3], 传0使用默认质量
    186. *
    187. * @return {0} if successful
    188. */
    189. public native int SmartPublisherOnCaptureVideoRGBA32Data(long handle, long buffer, int length, int rowStride, int width, int height,
    190. int is_vertical_flip, int is_horizontal_flip,int rotation_degree,
    191. int scale_width, int scale_height, int scale_filter_mode);
    192. /**
    193. * Set live video data(no encoded data).
    194. *
    195. * @param data: RGBA data
    196. *
    197. * @param rowStride: stride information
    198. *
    199. * @param width: width
    200. *
    201. * @param height: height
    202. *
    203. * @return {0} if successful
    204. */
    205. public native int SmartPublisherOnCaptureVideoRGBAData(long handle, ByteBuffer data, int rowStride, int width, int height);
    206. /**
    207. * 投递裁剪过的RGBA数据
    208. *
    209. * @param data: RGBA data
    210. *
    211. * @param rowStride: stride information
    212. *
    213. * @param width: width
    214. *
    215. * @param height: height
    216. *
    217. * @param clipedLeft: 左; clipedTop: 上; clipedwidth: 裁剪后的宽; clipedHeight: 裁剪后的高; 确保传下去裁剪后的宽、高均为偶数
    218. *
    219. * @return {0} if successful
    220. */
    221. public native int SmartPublisherOnCaptureVideoClipedRGBAData(long handle, ByteBuffer data, int rowStride, int width, int height, int clipedLeft, int clipedTop, int clipedWidth, int clipedHeight);
    222. /**
    223. * Set live video data(no encoded data).
    224. *
    225. * @param data: ABGR flip vertical(垂直翻转) data
    226. *
    227. * @param rowStride: stride information
    228. *
    229. * @param width: width
    230. *
    231. * @param height: height
    232. *
    233. * @return {0} if successful
    234. */
    235. public native int SmartPublisherOnCaptureVideoABGRFlipVerticalData(long handle, ByteBuffer data, int rowStride, int width, int height);
    236. /**
    237. * Set live video data(no encoded data).
    238. *
    239. * @param data: RGB565 data
    240. *
    241. * @param row_stride: stride information
    242. *
    243. * @param width: width
    244. *
    245. * @param height: height
    246. *
    247. * @return {0} if successful
    248. */
    249. public native int SmartPublisherOnCaptureVideoRGB565Data(long handle,ByteBuffer data, int row_stride, int width, int height);
    250. /*
    251. * 专门为android.media.Image的android.graphics.ImageFormat.YUV_420_888格式提供的接口
    252. *
    253. * @param width: 必须是8的倍数
    254. *
    255. * @param height: 必须是8的倍数
    256. *
    257. * @param crop_left: 剪切左上角水平坐标, 一般根据android.media.Image.getCropRect() 填充
    258. *
    259. * @param crop_top: 剪切左上角垂直坐标, 一般根据android.media.Image.getCropRect() 填充
    260. *
    261. * @param crop_width: 必须是8的倍数, 填0将忽略这个参数, 一般根据android.media.Image.getCropRect() 填充
    262. *
    263. * @param crop_height: 必须是8的倍数, 填0将忽略这个参数,一般根据android.media.Image.getCropRect() 填充
    264. *
    265. * @param y_plane 对应android.media.Image.Plane[0].getBuffer()
    266. *
    267. * @param y_row_stride 对应android.media.Image.Plane[0].getRowStride()
    268. *
    269. * @param u_plane 对应android.media.Image.Plane[1].getBuffer()
    270. *
    271. * @param v_plane 对应android.media.Image.Plane[2].getBuffer()
    272. *
    273. * @param uv_row_stride 对应android.media.Image.Plane[1].getRowStride()
    274. *
    275. * @param uv_pixel_stride 对应android.media.Image.Plane[1].getPixelStride()
    276. *
    277. * @param rotation_degree: 顺时针旋转, 必须是0, 90, 180, 270
    278. *
    279. * @param is_vertical_flip: 是否垂直翻转, 0不翻转, 1翻转
    280. *
    281. * @param is_horizontal_flip:是否水平翻转, 0不翻转, 1翻转
    282. *
    283. * @param scale_width: 缩放宽,必须是8的倍数, 0不缩放
    284. *
    285. * @param scale_height: 缩放高, 必须是8的倍数, 0不缩放
    286. *
    287. * @param scale_filter_mode: 缩放质量, 范围必须是[1,3], 传0使用默认速度
    288. *
    289. * @return {0} if successful
    290. */
    291. public native int SmartPublisherOnImageYUV420888(long handle, int width, int height,
    292. int crop_left, int crop_top, int crop_width, int crop_height,
    293. ByteBuffer y_plane, int y_row_stride,
    294. ByteBuffer u_plane, ByteBuffer v_plane, int uv_row_stride, int uv_pixel_stride,
    295. int rotation_degree, int is_vertical_flip, int is_horizontal_flip,
    296. int scale_width, int scale_height, int scale_filter_mode);
    297. /**
    298. * 启用或者停用视频层, 这个接口必须在StartXXX之后调用.
    299. *
    300. * @param index: 层索引, 必须大于0, 注意第0层不能停用
    301. *
    302. * @param is_enable: 是否启用, 0停用, 1启用
    303. *
    304. * @return {0} if successful
    305. */
    306. public native int EnableLayer(long handle, int index, int is_enable);
    307. /**
    308. * 移除视频层, 这个接口必须在StartXXX之后调用.
    309. *
    310. * @param index: 层索引, 必须大于0, 注意第0层不能移除
    311. *
    312. * @return {0} if successful
    313. */
    314. public native int RemoveLayer(long handle, int index);
    315. /**
    316. * 投递层RGBA8888图像,如果不需要Aplpha通道的话, 请使用RGBX8888接口, 效率高
    317. *
    318. * @param index: 层索引, 必须大于等于0, 注意:如果index是0的话,将忽略Alpha通道
    319. *
    320. * @param left: 层叠加的左上角坐标, 对于第0层的话传0
    321. *
    322. * @param top: 层叠加的左上角坐标, 对于第0层的话传0
    323. *
    324. * @param rgba_plane: rgba 图像数据
    325. *
    326. * @param offset: 图像偏移, 这个主要目的是用来做clip的, 一般传0
    327. *
    328. * @param row_stride: stride information
    329. *
    330. * @param width: width, 必须大于1, 如果是奇数, 将减1
    331. *
    332. * @param height: height, 必须大于1, 如果是奇数, 将减1
    333. *
    334. * @param is_vertical_flip: 是否垂直翻转, 0不翻转, 1翻转
    335. *
    336. * @param is_horizontal_flip:是否水平翻转, 0不翻转, 1翻转
    337. *
    338. * @param scale_width: 缩放宽,必须是偶数, 0或负数不缩放
    339. *
    340. * @param scale_height: 缩放高, 必须是偶数, 0或负数不缩放
    341. *
    342. * @param scale_filter_mode: 缩放质量, 传0使用默认速度,可选等级范围是:[1,3],值越大缩放质量越好, 但速度越慢
    343. *
    344. * @param rotation_degree: 顺时针旋转, 必须是0, 90, 180, 270, 注意:旋转是在缩放, 垂直/水品反转之后再做, 请留意顺序
    345. *
    346. * @return {0} if successful
    347. */
    348. public native int PostLayerImageRGBA8888ByteBuffer(long handle, int index, int left, int top,
    349. ByteBuffer rgba_plane, int offset, int row_stride, int width, int height,
    350. int is_vertical_flip, int is_horizontal_flip,
    351. int scale_width, int scale_height, int scale_filter_mode,
    352. int rotation_degree);
    353. /**
    354. * 投递层RGBA8888图像, 详细说明请参考PostLayerImageRGBA8888ByteBuffer
    355. *
    356. * @return {0} if successful
    357. */
    358. public native int PostLayerImageRGBA8888ByteArray(long handle, int index, int left, int top,
    359. byte[] rgba_plane, int offset, int row_stride, int width, int height,
    360. int is_vertical_flip, int is_horizontal_flip,
    361. int scale_width, int scale_height, int scale_filter_mode,
    362. int rotation_degree);
    363. /**
    364. * 投递层RGBA8888图像, 详细说明请参考PostLayerImageRGBA8888ByteBuffer
    365. *
    366. * @return {0} if successful
    367. */
    368. public native int PostLayerImageRGBA8888Native(long handle, int index, int left, int top,
    369. long rgba_plane, int offset, int row_stride, int width, int height,
    370. int is_vertical_flip, int is_horizontal_flip,
    371. int scale_width, int scale_height, int scale_filter_mode,
    372. int rotation_degree);
    373. /**
    374. * 投递层RGBX8888图像
    375. *
    376. * @param index: 层索引, 必须大于等于0
    377. *
    378. * @param left: 层叠加的左上角坐标, 对于第0层的话传0
    379. *
    380. * @param top: 层叠加的左上角坐标, 对于第0层的话传0
    381. *
    382. * @param rgbx_plane: rgbx 图像数据
    383. *
    384. * @param offset: 图像偏移, 这个主要目的是用来做clip的,一般传0
    385. *
    386. * @param row_stride: stride information
    387. *
    388. * @param width: width, 必须大于1, 如果是奇数, 将减1
    389. *
    390. * @param height: height, 必须大于1, 如果是奇数, 将减1
    391. *
    392. * @param is_vertical_flip: 是否垂直翻转, 0不翻转, 1翻转
    393. *
    394. * @param is_horizontal_flip:是否水平翻转, 0不翻转, 1翻转
    395. *
    396. * @param scale_width: 缩放宽,必须是偶数, 0或负数不缩放
    397. *
    398. * @param scale_height: 缩放高, 必须是偶数, 0或负数不缩放
    399. *
    400. * @param scale_filter_mode: 缩放质量, 传0使用默认速度,可选等级范围是:[1,3],值越大缩放质量越好, 但速度越慢
    401. *
    402. * @param rotation_degree: 顺时针旋转, 必须是0, 90, 180, 270, 注意:旋转是在缩放, 垂直/水品反转之后再做, 请留意顺序
    403. *
    404. * @return {0} if successful
    405. */
    406. public native int PostLayerImageRGBX8888ByteBuffer(long handle, int index, int left, int top,
    407. ByteBuffer rgbx_plane, int offset, int row_stride, int width, int height,
    408. int is_vertical_flip, int is_horizontal_flip,
    409. int scale_width, int scale_height, int scale_filter_mode,
    410. int rotation_degree);
    411. /**
    412. * 投递层RGBX8888图像, 详细说明请参考PostLayerImageRGBX8888ByteBuffer
    413. *
    414. * @return {0} if successful
    415. */
    416. public native int PostLayerImageRGBX8888ByteArray(long handle, int index, int left, int top,
    417. byte[] rgbx_plane, int offset, int row_stride, int width, int height,
    418. int is_vertical_flip, int is_horizontal_flip,
    419. int scale_width, int scale_height, int scale_filter_mode,
    420. int rotation_degree);
    421. /**
    422. * 投递层RGBX8888图像, 详细说明请参考PostLayerImageRGBX8888ByteBuffer
    423. *
    424. * @return {0} if successful
    425. */
    426. public native int PostLayerImageRGBX8888Native(long handle, int index, int left, int top,
    427. long rgbx_plane, int offset, int row_stride, int width, int height,
    428. int is_vertical_flip, int is_horizontal_flip,
    429. int scale_width, int scale_height, int scale_filter_mode,
    430. int rotation_degree);
    431. /**
    432. * 投递层RGB888图像
    433. *
    434. * @param index: 层索引, 必须大于等于0
    435. *
    436. * @param left: 层叠加的左上角坐标, 对于第0层的话传0
    437. *
    438. * @param top: 层叠加的左上角坐标, 对于第0层的话传0
    439. *
    440. * @param rgb_plane: rgb888 图像数据
    441. *
    442. * @param offset: 图像偏移, 这个主要目的是用来做clip的,一般传0
    443. *
    444. * @param row_stride: stride information
    445. *
    446. * @param width: width, 必须大于1, 如果是奇数, 将减1
    447. *
    448. * @param height: height, 必须大于1, 如果是奇数, 将减1
    449. *
    450. * @param is_vertical_flip: 是否垂直翻转, 0不翻转, 1翻转
    451. *
    452. * @param is_horizontal_flip:是否水平翻转, 0不翻转, 1翻转
    453. *
    454. * @param scale_width: 缩放宽,必须是偶数, 0或负数不缩放
    455. *
    456. * @param scale_height: 缩放高, 必须是偶数, 0或负数不缩放
    457. *
    458. * @param scale_filter_mode: 缩放质量, 传0使用默认速度,可选等级范围是:[1,3],值越大缩放质量越好, 但速度越慢
    459. *
    460. * @param rotation_degree: 顺时针旋转, 必须是0, 90, 180, 270, 注意:旋转是在缩放, 垂直/水品反转之后再做, 请留意顺序
    461. *
    462. * @return {0} if successful
    463. */
    464. public native int PostLayerImageRGB888Native(long handle, int index, int left, int top,
    465. long rgb_plane, int offset, int row_stride, int width, int height,
    466. int is_vertical_flip, int is_horizontal_flip,
    467. int scale_width, int scale_height, int scale_filter_mode,
    468. int rotation_degree);
    469. /**
    470. * 投递层NV21图像
    471. *
    472. * @param index: 层索引, 必须大于等于0
    473. *
    474. * @param left: 层叠加的左上角坐标, 对于第0层的话传0
    475. *
    476. * @param top: 层叠加的左上角坐标, 对于第0层的话传0
    477. *
    478. * @param y_plane: y平面图像数据
    479. *
    480. * @param y_offset: 图像偏移, 这个主要目的是用来做clip的,一般传0
    481. *
    482. * @param y_row_stride: stride information
    483. *
    484. * @param uv_plane: uv平面图像数据
    485. *
    486. * @param uv_offset: 图像偏移, 这个主要目的是用来做clip的,一般传0
    487. *
    488. * @param uv_row_stride: stride information
    489. *
    490. * @param width: width, 必须大于1, 且必须是偶数
    491. *
    492. * @param height: height, 必须大于1, 且必须是偶数
    493. *
    494. * @param is_vertical_flip: 是否垂直翻转, 0不翻转, 1翻转
    495. *
    496. * @param is_horizontal_flip:是否水平翻转, 0不翻转, 1翻转
    497. *
    498. * @param scale_width: 缩放宽,必须是偶数, 0或负数不缩放
    499. *
    500. * @param scale_height: 缩放高, 必须是偶数, 0或负数不缩放
    501. *
    502. * @param scale_filter_mode: 缩放质量, 传0使用默认速度,可选等级范围是:[1,3],值越大缩放质量越好, 但速度越慢
    503. *
    504. * @param rotation_degree: 顺时针旋转, 必须是0, 90, 180, 270, 注意:旋转是在缩放, 垂直/水品反转之后再做, 请留意顺序
    505. *
    506. * @return {0} if successful
    507. */
    508. public native int PostLayerImageNV21ByteBuffer(long handle, int index, int left, int top,
    509. ByteBuffer y_plane, int y_offset, int y_row_stride,
    510. ByteBuffer uv_plane, int uv_offset, int uv_row_stride,
    511. int width, int height, int is_vertical_flip, int is_horizontal_flip,
    512. int scale_width, int scale_height, int scale_filter_mode,
    513. int rotation_degree);
    514. /**
    515. * 投递层NV21图像, 详细说明请参考PostLayerImageNV21ByteBuffer
    516. *
    517. * @return {0} if successful
    518. */
    519. public native int PostLayerImageNV21ByteArray(long handle, int index, int left, int top,
    520. byte[] y_plane, int y_offset, int y_row_stride,
    521. byte[] uv_plane, int uv_offset, int uv_row_stride,
    522. int width, int height, int is_vertical_flip, int is_horizontal_flip,
    523. int scale_width, int scale_height, int scale_filter_mode,
    524. int rotation_degree);
    525. /**
    526. * 投递层NV12图像, 详细说明请参考PostLayerImageNV21ByteBuffer
    527. *
    528. * @return {0} if successful
    529. */
    530. public native int PostLayerImageNV12ByteBuffer(long handle, int index, int left, int top,
    531. ByteBuffer y_plane, int y_offset, int y_row_stride,
    532. ByteBuffer uv_plane, int uv_offset, int uv_row_stride,
    533. int width, int height, int is_vertical_flip, int is_horizontal_flip,
    534. int scale_width, int scale_height, int scale_filter_mode,
    535. int rotation_degree);
    536. /**
    537. * 投递层NV12图像, 详细说明请参考PostLayerImageNV21ByteBuffer
    538. *
    539. * @return {0} if successful
    540. */
    541. public native int PostLayerImageNV12ByteArray(long handle, int index, int left, int top,
    542. byte[] y_plane, int y_offset, int y_row_stride,
    543. byte[] uv_plane, int uv_offset, int uv_row_stride,
    544. int width, int height, int is_vertical_flip, int is_horizontal_flip,
    545. int scale_width, int scale_height, int scale_filter_mode,
    546. int rotation_degree);
    547. /**
    548. * 投递层I420图像
    549. *
    550. * @param index: 层索引, 必须大于等于0
    551. *
    552. * @param left: 层叠加的左上角坐标, 对于第0层的话传0
    553. *
    554. * @param top: 层叠加的左上角坐标, 对于第0层的话传0
    555. *
    556. * @param y_plane: y平面图像数据
    557. *
    558. * @param y_offset: 图像偏移, 这个主要目的是用来做clip的,一般传0
    559. *
    560. * @param y_row_stride: stride information
    561. *
    562. * @param u_plane: u平面图像数据
    563. *
    564. * @param u_offset: 图像偏移, 这个主要目的是用来做clip的,一般传0
    565. *
    566. * @param u_row_stride: stride information
    567. * *
    568. * @param v_plane: v平面图像数据
    569. *
    570. * @param v_offset: 图像偏移, 这个主要目的是用来做clip的,一般传0
    571. *
    572. * @param v_row_stride: stride information
    573. *
    574. * @param width: width, 必须大于1, 且必须是偶数
    575. *
    576. * @param height: height, 必须大于1, 且必须是偶数
    577. *
    578. * @param is_vertical_flip: 是否垂直翻转, 0不翻转, 1翻转
    579. *
    580. * @param is_horizontal_flip:是否水平翻转, 0不翻转, 1翻转
    581. *
    582. * @param scale_width: 缩放宽,必须是偶数, 0或负数不缩放
    583. *
    584. * @param scale_height: 缩放高, 必须是偶数, 0或负数不缩放
    585. *
    586. * @param scale_filter_mode: 缩放质量, 传0使用默认速度,可选等级范围是:[1,3],值越大缩放质量越好, 但速度越慢
    587. *
    588. * @param rotation_degree: 顺时针旋转, 必须是0, 90, 180, 270, 注意:旋转是在缩放, 垂直/水品反转之后再做, 请留意顺序
    589. *
    590. * @return {0} if successful
    591. */
    592. public native int PostLayerImageI420ByteBuffer(long handle, int index, int left, int top,
    593. ByteBuffer y_plane, int y_offset, int y_row_stride,
    594. ByteBuffer u_plane, int u_offset, int u_row_stride,
    595. ByteBuffer v_plane, int v_offset, int v_row_stride,
    596. int width, int height, int is_vertical_flip, int is_horizontal_flip,
    597. int scale_width, int scale_height, int scale_filter_mode,
    598. int rotation_degree);
    599. /**
    600. * 投递层I420图像, 详细说明请参考PostLayerImageI420ByteBuffer
    601. *
    602. * @return {0} if successful
    603. */
    604. public native int PostLayerImageI420ByteArray(long handle, int index, int left, int top,
    605. byte[] y_plane, int y_offset, int y_row_stride,
    606. byte[] u_plane, int u_offset, int u_row_stride,
    607. byte[] v_plane, int v_offset, int v_row_stride,
    608. int width, int height, int is_vertical_flip, int is_horizontal_flip,
    609. int scale_width, int scale_height, int scale_filter_mode,
    610. int rotation_degree);
    611. /**
    612. * 投递层YUV420888图像, 专门为android.media.Image的android.graphics.ImageFormat.YUV_420_888格式提供的接口
    613. *
    614. * @param index: 层索引, 必须大于等于0
    615. *
    616. * @param left: 层叠加的左上角坐标, 对于第0层的话传0
    617. *
    618. * @param top: 层叠加的左上角坐标, 对于第0层的话传0
    619. *
    620. * @param y_plane: 对应android.media.Image.Plane[0].getBuffer()
    621. *
    622. * @param y_offset: 图像偏移, 这个主要目的是用来做clip的,一般传0
    623. *
    624. * @param y_row_stride: 对应android.media.Image.Plane[0].getRowStride()
    625. *
    626. * @param u_plane: android.media.Image.Plane[1].getBuffer()
    627. *
    628. * @param u_offset: 图像偏移, 这个主要目的是用来做clip的,一般传0
    629. *
    630. * @param u_row_stride: android.media.Image.Plane[1].getRowStride()
    631. *
    632. * @param v_plane: 对应android.media.Image.Plane[2].getBuffer()
    633. *
    634. * @param v_offset: 图像偏移, 这个主要目的是用来做clip的,一般传0
    635. *
    636. * @param v_row_stride: 对应android.media.Image.Plane[2].getRowStride()
    637. *
    638. * @param uv_pixel_stride: 对应android.media.Image.Plane[1].getPixelStride()
    639. *
    640. * @param width: width, 必须大于1, 且必须是偶数
    641. *
    642. * @param height: height, 必须大于1, 且必须是偶数
    643. *
    644. * @param is_vertical_flip: 是否垂直翻转, 0不翻转, 1翻转
    645. *
    646. * @param is_horizontal_flip:是否水平翻转, 0不翻转, 1翻转
    647. *
    648. * @param scale_width: 缩放宽,必须是偶数, 0或负数不缩放
    649. *
    650. * @param scale_height: 缩放高, 必须是偶数, 0或负数不缩放
    651. *
    652. * @param scale_filter_mode: 缩放质量, 传0使用默认速度,可选等级范围是:[1,3],值越大缩放质量越好, 但速度越慢
    653. *
    654. * @param rotation_degree: 顺时针旋转, 必须是0, 90, 180, 270, 注意:旋转是在缩放, 垂直/水品反转之后再做, 请留意顺序
    655. *
    656. * @return {0} if successful
    657. */
    658. public native int PostLayerImageYUV420888ByteBuffer(long handle, int index, int left, int top,
    659. ByteBuffer y_plane, int y_offset, int y_row_stride,
    660. ByteBuffer u_plane, int u_offset, int u_row_stride,
    661. ByteBuffer v_plane, int v_offset, int v_row_stride, int uv_pixel_stride,
    662. int width, int height, int is_vertical_flip, int is_horizontal_flip,
    663. int scale_width, int scale_height, int scale_filter_mode,
    664. int rotation_degree);

    问题2:Android Native层MediaCodec编码,从什么版本开始支持的,支持什么架构?

    回答:从5.0开始,armv8,如果像我们一样,想支持armv7也未尝不可,需要底层动态加载lib so,然后接口再做一层封装即可,设置MediaCodec Native硬编码时,底层需要判断下系统版本,相关设计接口如下:

    1. /**
    2. * 设置视频硬编码是否使用 Native Media NDK, 默认是不使用, 安卓5.0以下设备不支持
    3. * @param handle
    4. * @param is_native: 0表示不使用, 1表示使用, sdk默认是0.
    5. * @return {0} if successful
    6. */
    7. 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?

    回答:和上层类似,参考以下代码:

    1. if (info.flags & AMEDIACODEC_BUFFER_FLAG_CODEC_CONFIG) {
    2. config_info.clear();
    3. config_info.insert(config_info_.end(), output_buffer + info.offset, output_buffer + info.offset + info.size);
    4. }

    问题6:创建MediaFormat有什么特别之处吗?

    回答:没啥特别之处,设置下如mine_type、width、height,编码码率、fps、关键帧间隔等信息即可。

    问题7:编码过程中,比如发生横竖屏切换等,导致分辨率变化怎么办?

    回答:重启encoder即可。

    问题8:我想比较下到底native层编码效率高,还是上层高?

    回答:可以快速写代码尝试,也可私信我,试试我们的,从我们测试来看,由于本身我们上层调用的,也做的非常优异了,native层相对来说,更多地是调用效率的提高,后续扩展更方便。

    问题9:Android Native层编码后的数据,可以用在什么场景下?

    回答:编码后的H264、HEVC数据,按照协议栈要求,用于需要视频传输的场景都可以,比如RTMP推送、GB28181设备接入,轻量级RTSP服务,甚至私有协议传输都OK。

     

  • 相关阅读:
    OpenEuler22.03安装PostgreSQL15.5并配置一主二从
    密码学 | 密码学简介及Base64编码
    AD单片机九齐单片机NY8B062D SOP16九齐
    Qt编写视频监控管理平台(支持海康/大华/宇视/华为/天地伟业/H264/H265等)
    使用Python绘制二元函数图像
    专业/户籍不限!腾讯/华为招聘提到的PMP证书!多行业适用
    IP证书怎么申请,如何实现加密保护
    马六甲海峡对海运的重要性
    逆序对专题
    提升团队能力的真正利器不是培训而是复盘,
  • 原文地址:https://blog.csdn.net/renhui1112/article/details/126579779