使用aidl传递音视频数据

65 阅读1分钟

虽然但是,有时候就是会有这种需求,这种时候一般有两种传输方式,

一种是把数据转成byte[],然后当基础类型一样传过去,这种方式有大小的要求,byte不能超过一定大小,可以分批次传,但是这种方式会影响帧率性能,不是很推荐。

二种是把数据存文件,传句柄过去,这里着重介绍这种方式。

先定义服务端的aidl接口。

interface ITestResultListener {
    //TestResult是自己定义的类 也要实现Parcelable接口
    void onTestResultListener(in TestResult result, in ParcelFileDescriptor pfd);
}

接下来服务端拿到了bitmap数据,将其转化为句柄传输

private fun updatePrivacyMaskingResult(testResult: TestResult, originBitmap: Bitmap) {
        val fileCount = originBitmap.byteCount

        var mf: MemoryFile? = null
        var fd: ParcelFileDescriptor? = null
        try {
            mf = MemoryFile("mosaicImg", fileCount)
            fd = ParcelFileDescriptor.dup(getFileDescriptor(mf))

            val buffer = ByteBuffer.allocate(fileCount)
            originBitmap.copyPixelsToBuffer(buffer)

            val data = buffer.array()
            mf.writeBytes(data, 0, 0, data.size)

            val size = mTestResultListenerList.beginBroadcast()
            for (i in 0 until size) {
                mTestResultListenerList.getBroadcastItem(i)                    .onTestResultListener(testResult, fd)            }
            mPrivacyMaskingListenerList.finishBroadcast()

            buffer.clear()
        } catch (e: Throwable) {
            Log.e(TAG, "updatePrivacyMaskingResult :${e.message} ", e)
        } finally {
            kotlin.runCatching { fd?.close() }
            kotlin.runCatching { mf?.close() }
        }
    }

客户端也要定义一样的aidl接口,这里就直接略过了,直接看还原bitmap的过程。

override fun onTestResultListener(result: TestResult, pfd: ParcelFileDescriptor?) {
            try {
                pfd?.let {
                    val buffer = SharedMemory.fromFileDescriptor(it).mapReadWrite()
                    val bytes = ByteArray(buffer.limit())
                    buffer.get(bytes)
                    val bitmap = reconstructBitmap(bytes, result.height, result.width)
                }
            } catch (e: Throwable) {
                Log.e(TAG, "onPrivacyMaskingResultListener: ", e)
            }
        }

private fun reconstructBitmap(data: ByteArray, height: Int, width: Int): Bitmap {
        val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
        // 直接使用 ByteBuffer 包装字节数组
        val buffer = ByteBuffer.wrap(data)
        bitmap.copyPixelsFromBuffer(buffer)
        return bitmap
    }

至此结束。