• Android平台GB28181设备接入端对接编码前后音视频源类型浅析


    前言

    今天主要对Android平台GB28181设备接入模块支持的接入数据类型,做个简单的汇总:

    1. 编码前数据(目前支持的有YV12/NV21/NV12/I420/RGB24/RGBA32/RGB565等数据类型),其中,Android平台前后摄像头数据,或者屏幕数据,或者Unity拿到的数据,均属编码前数据;
    2. 编码后数据(如无人机等264/HEVC数据,或者本地解析的MP4音视频数据);
    3. 拉取RTSP或RTMP流并接入至GB28181平台(比如其他IPC的RTSP流,可通过Android平台GB28181接入到国标平台)。

    支持的音视频数据类型

    编码前音视频数据

    编码前音视频数据支持的类型接口如下,除了常规的音视频数据外,我们还设计支持了实时动态水印,比如实时文字水印、图片水印,音频这块,我们实现了混音机制,支持2路混音输入:

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

    编码后音视频数据

    像前文所说,如无人机等264/HEVC数据,或者本地解析的MP4音视频数据,均可通过实时流的形式,接入到GB28181平台,设计接口如下:

    1. /**
    2. * 设置编码后视频数据(H.264)
    3. *
    4. * @param codec_id, H.264对应 1
    5. *
    6. * @param data 编码后的video数据
    7. *
    8. * @param size data length
    9. *
    10. * @param is_key_frame 是否I帧, if with key frame, please set 1, otherwise, set 0.
    11. *
    12. * @param timestamp video timestamp
    13. *
    14. * @param pts Presentation Time Stamp, 显示时间戳
    15. *
    16. * @return {0} if successful
    17. */
    18. public native int SmartPublisherPostVideoEncodedData(long handle, int codec_id, ByteBuffer data, int size, int is_key_frame, long timestamp, long pts);
    19. /**
    20. * 设置编码后视频数据(H.264)
    21. *
    22. * @param codec_id, H.264对应 1
    23. *
    24. * @param data 编码后的video数据
    25. *
    26. *@param offset data的偏移
    27. *
    28. * @param size data length
    29. *
    30. * @param is_key_frame 是否I帧, if with key frame, please set 1, otherwise, set 0.
    31. *
    32. * @param timestamp video timestamp
    33. *
    34. * @param pts Presentation Time Stamp, 显示时间戳
    35. *
    36. * @return {0} if successful
    37. */
    38. public native int SmartPublisherPostVideoEncodedDataV2(long handle, int codec_id,
    39. ByteBuffer data, int offset, int size,
    40. int is_key_frame, long timestamp, long pts,
    41. byte[] sps, int sps_len,
    42. byte[] pps, int pps_len);
    43. /**
    44. * 设置编码后视频数据(H.264),如需录制编码后的数据,用此接口,且设置实际宽高
    45. *
    46. * @param codec_id, H.264对应 1
    47. *
    48. * @param data 编码后的video数据
    49. *
    50. *@param offset data的偏移
    51. *
    52. * @param size data length
    53. *
    54. * @param is_key_frame 是否I帧, if with key frame, please set 1, otherwise, set 0.
    55. *
    56. * @param timestamp video timestamp
    57. *
    58. * @param pts Presentation Time Stamp, 显示时间戳
    59. *
    60. * @param width, height: 编码后视频宽高
    61. *
    62. * @return {0} if successful
    63. */
    64. public native int SmartPublisherPostVideoEncodedDataV3(long handle, int codec_id,
    65. ByteBuffer data, int offset, int size,
    66. int is_key_frame, long timestamp, long pts,
    67. byte[] sps, int sps_len,
    68. byte[] pps, int pps_len,
    69. int width, int height);
    70. /**
    71. * 设置音频数据(AAC/PCMA/PCMU/SPEEX)
    72. *
    73. * @param codec_id:
    74. *
    75. * NT_MEDIA_CODEC_ID_AUDIO_BASE = 0x10000,
    76. * NT_MEDIA_CODEC_ID_PCMA = NT_MEDIA_CODEC_ID_AUDIO_BASE,
    77. * NT_MEDIA_CODEC_ID_PCMU,
    78. * NT_MEDIA_CODEC_ID_AAC,
    79. * NT_MEDIA_CODEC_ID_SPEEX,
    80. * NT_MEDIA_CODEC_ID_SPEEX_NB,
    81. * NT_MEDIA_CODEC_ID_SPEEX_WB,
    82. * NT_MEDIA_CODEC_ID_SPEEX_UWB,
    83. *
    84. * @param data audio数据
    85. *
    86. * @param size data length
    87. *
    88. * @param is_key_frame 是否I帧, if with key frame, please set 1, otherwise, set 0, audio忽略
    89. *
    90. * @param timestamp video timestamp
    91. *
    92. * @param parameter_info 用于AAC special config信息填充
    93. *
    94. * @param parameter_info_size parameter info size
    95. *
    96. * @return {0} if successful
    97. */
    98. public native int SmartPublisherPostAudioEncodedData(long handle, int codec_id, ByteBuffer data, int size, int is_key_frame, long timestamp,ByteBuffer parameter_info, int parameter_info_size);
    99. /**
    100. * 设置音频数据(AAC/PCMA/PCMU/SPEEX)
    101. *
    102. * @param codec_id:
    103. *
    104. * NT_MEDIA_CODEC_ID_AUDIO_BASE = 0x10000,
    105. * NT_MEDIA_CODEC_ID_PCMA = NT_MEDIA_CODEC_ID_AUDIO_BASE,
    106. * NT_MEDIA_CODEC_ID_PCMU,
    107. * NT_MEDIA_CODEC_ID_AAC,
    108. * NT_MEDIA_CODEC_ID_SPEEX,
    109. * NT_MEDIA_CODEC_ID_SPEEX_NB,
    110. * NT_MEDIA_CODEC_ID_SPEEX_WB,
    111. * NT_MEDIA_CODEC_ID_SPEEX_UWB,
    112. *
    113. * @param data audio数据
    114. *
    115. * @param offset data的偏移
    116. *
    117. * @param size data length
    118. *
    119. * @param is_key_frame 是否I帧, if with key frame, please set 1, otherwise, set 0, audio忽略
    120. *
    121. * @param timestamp video timestamp
    122. *
    123. * @param parameter_info 用于AAC special config信息填充
    124. *
    125. * @param parameter_info_size parameter info size
    126. *
    127. * @return {0} if successful
    128. */
    129. public native int SmartPublisherPostAudioEncodedDataV2(long handle, int codec_id,
    130. ByteBuffer data, int offset, int size,
    131. int is_key_frame, long timestamp,
    132. byte[] parameter_info, int parameter_info_size);
    133. /**
    134. * 设置音频数据(AAC/PCMA/PCMU/SPEEX)
    135. *
    136. * @param codec_id:
    137. *
    138. * NT_MEDIA_CODEC_ID_AUDIO_BASE = 0x10000,
    139. * NT_MEDIA_CODEC_ID_PCMA = NT_MEDIA_CODEC_ID_AUDIO_BASE,
    140. * NT_MEDIA_CODEC_ID_PCMU,
    141. * NT_MEDIA_CODEC_ID_AAC,
    142. * NT_MEDIA_CODEC_ID_SPEEX,
    143. * NT_MEDIA_CODEC_ID_SPEEX_NB,
    144. * NT_MEDIA_CODEC_ID_SPEEX_WB,
    145. * NT_MEDIA_CODEC_ID_SPEEX_UWB,
    146. *
    147. * @param data audio数据
    148. *
    149. * @param offset data的偏移
    150. *
    151. * @param size data length
    152. *
    153. * @param is_key_frame 是否I帧, if with key frame, please set 1, otherwise, set 0, audio忽略
    154. *
    155. * @param timestamp video timestamp
    156. *
    157. * @param parameter_info 用于AAC special config信息填充
    158. *
    159. * @param parameter_info_size parameter info size
    160. *
    161. * @param sample_rate 采样率,如果需要录像的话必须传正确的值
    162. *
    163. *@param channels 通道数, 如果需要录像的话必须传正确的值, 一般是1或者2
    164. *
    165. * @return {0} if successful
    166. */
    167. public native int SmartPublisherPostAudioEncodedDataV3(long handle, int codec_id,
    168. ByteBuffer data, int offset, int size,
    169. int is_key_frame, long timestamp,
    170. byte[] parameter_info, int parameter_info_size,
    171. int sample_rate, int channels);

    拉取RTSP或RTMP流并接入至GB28181平台

    这块我在之前的blog有专门提过,比如其他IPC的RTSP流,可通过Android平台GB28181接入到国标平台。

    这张图很好的展示了这块,当然如果做的更精细的话,还可以把语音对讲和语音广播的也挪过来。

    这里简单的说一下具体的实现,其实和之前我们做RTSP转RTMP推送一样,无非就是把RTSP或者RTMP流数据拉下来,然后回调编码后的数据到上层,上层根据GB28181数据格式要求,实现PS打包,然后通过对接GB28181平台信令和数据交互,实时推过去即可。

    其中,拉流实现如下:

    1. private boolean StartPull()
    2. {
    3. if ( isPulling )
    4. return false;
    5. if (!OpenPullHandle())
    6. return false;
    7. libPlayer.SmartPlayerSetAudioDataCallback(playerHandle, new PlayerAudioDataCallback());
    8. libPlayer.SmartPlayerSetVideoDataCallback(playerHandle, new PlayerVideoDataCallback());
    9. int is_pull_trans_code = 1;
    10. libPlayer.SmartPlayerSetPullStreamAudioTranscodeAAC(playerHandle, is_pull_trans_code);
    11. int startRet = libPlayer.SmartPlayerStartPullStream(playerHandle);
    12. if (startRet != 0) {
    13. Log.e(TAG, "Failed to start pull stream!");
    14. if(!isPlaying && !isRecording && isPushing && !isRTSPPublisherRunning)
    15. {
    16. libPlayer.SmartPlayerClose(playerHandle);
    17. playerHandle = 0;
    18. }
    19. return false;
    20. }
    21. isPulling = true;
    22. return true;
    23. }
    24. private void StopPull()
    25. {
    26. if ( !isPulling )
    27. return;
    28. libPlayer.SmartPlayerStopPullStream(playerHandle);
    29. if ( !isPlaying && !isRecording && !isPushing && !isRTSPPublisherRunning)
    30. {
    31. libPlayer.SmartPlayerClose(playerHandle);
    32. playerHandle = 0;
    33. }
    34. isPulling = false;
    35. }

    拉到的音视频数据,投递到GB28181接入模块即可:

    1. class PlayerAudioDataCallback implements NTAudioDataCallback
    2. {
    3. private int audio_buffer_size = 0;
    4. private int param_info_size = 0;
    5. private ByteBuffer audio_buffer_ = null;
    6. private ByteBuffer parameter_info_ = null;
    7. @Override
    8. public ByteBuffer getAudioByteBuffer(int size)
    9. {
    10. //Log.i("getAudioByteBuffer", "size: " + size);
    11. if( size < 1 )
    12. {
    13. return null;
    14. }
    15. if ( size <= audio_buffer_size && audio_buffer_ != null )
    16. {
    17. return audio_buffer_;
    18. }
    19. audio_buffer_size = size + 512;
    20. audio_buffer_size = (audio_buffer_size+0xf) & (~0xf);
    21. audio_buffer_ = ByteBuffer.allocateDirect(audio_buffer_size);
    22. // Log.i("getAudioByteBuffer", "size: " + size + " buffer_size:" + audio_buffer_size);
    23. return audio_buffer_;
    24. }
    25. @Override
    26. public ByteBuffer getAudioParameterInfo(int size)
    27. {
    28. //Log.i("getAudioParameterInfo", "size: " + size);
    29. if(size < 1)
    30. {
    31. return null;
    32. }
    33. if ( size <= param_info_size && parameter_info_ != null )
    34. {
    35. return parameter_info_;
    36. }
    37. param_info_size = size + 32;
    38. param_info_size = (param_info_size+0xf) & (~0xf);
    39. parameter_info_ = ByteBuffer.allocateDirect(param_info_size);
    40. //Log.i("getAudioParameterInfo", "size: " + size + " buffer_size:" + param_info_size);
    41. return parameter_info_;
    42. }
    43. public void onAudioDataCallback(int ret, int audio_codec_id, int sample_size, int is_key_frame, long timestamp, int sample_rate, int channel, int parameter_info_size, long reserve)
    44. {
    45. //Log.i("onAudioDataCallback", "ret: " + ret + ", audio_codec_id: " + audio_codec_id + ", sample_size: " + sample_size + ", timestamp: " + timestamp +
    46. // ",sample_rate:" + sample_rate);
    47. if ( audio_buffer_ == null)
    48. return;
    49. audio_buffer_.rewind();
    50. if ( ret == 0 && (isPushing || isRTSPPublisherRunning || isGB28181StreamRunning)) {
    51. libPublisher.SmartPublisherPostAudioEncodedData(publisherHandle, audio_codec_id, audio_buffer_, sample_size, is_key_frame, timestamp, parameter_info_, parameter_info_size);
    52. }
    53. // test
    54. /*
    55. byte[] test_buffer = new byte[16];
    56. pcm_buffer_.get(test_buffer);
    57. Log.i(TAG, "onGetPcmFrame data:" + bytesToHexString(test_buffer));
    58. */
    59. }
    60. }
    61. class PlayerVideoDataCallback implements NTVideoDataCallback
    62. {
    63. private int video_buffer_size = 0;
    64. private ByteBuffer video_buffer_ = null;
    65. @Override
    66. public ByteBuffer getVideoByteBuffer(int size)
    67. {
    68. //Log.i("getVideoByteBuffer", "size: " + size);
    69. if( size < 1 )
    70. {
    71. return null;
    72. }
    73. if ( size <= video_buffer_size && video_buffer_ != null )
    74. {
    75. return video_buffer_;
    76. }
    77. video_buffer_size = size + 1024;
    78. video_buffer_size = (video_buffer_size+0xf) & (~0xf);
    79. video_buffer_ = ByteBuffer.allocateDirect(video_buffer_size);
    80. // Log.i("getVideoByteBuffer", "size: " + size + " buffer_size:" + video_buffer_size);
    81. return video_buffer_;
    82. }
    83. public void onVideoDataCallback(int ret, int video_codec_id, int sample_size, int is_key_frame, long timestamp, int width, int height, long presentation_timestamp)
    84. {
    85. //Log.i("onVideoDataCallback", "ret: " + ret + ", video_codec_id: " + video_codec_id + ", sample_size: " + sample_size + ", is_key_frame: "+ is_key_frame + ", timestamp: " + timestamp +
    86. // ",presentation_timestamp:" + presentation_timestamp);
    87. if ( video_buffer_ == null)
    88. return;
    89. video_buffer_.rewind();
    90. if ( ret == 0 && (isPushing || isRTSPPublisherRunning || isGB28181StreamRunning) ) {
    91. libPublisher.SmartPublisherPostVideoEncodedData(publisherHandle, video_codec_id, video_buffer_, sample_size, is_key_frame, timestamp, presentation_timestamp);
    92. }
    93. }
    94. }

    总结

    通过以上描述,大家可以看到,GB/T 28181音视频数据源接入,无非就是上述类型,有RTSP或RTMP音视频开发经验的开发者来说,实现GB28181数据接入,基本上可以复用之前的设计。

  • 相关阅读:
    读懂Json文件[妈妈再也不用担心我不读懂了]
    rpm包常用命令指南
    一个37岁程序员的逆袭之路
    融云 IM & RTC 能力上新盘点
    论多段图的最短路径问题(我认为本质上还是暴力枚举法)
    Linux下设置网关以及网络相关命令
    基于人脸的常见表情识别(2)——数据获取与整理
    微服务系列:分布式文件存储之 MinIO 入门指南
    16 el-tree 保存树的 选择状态, 展开状态
    IDS与防火墙的区别
  • 原文地址:https://blog.csdn.net/renhui1112/article/details/126692256