scrcpy 为什么要在旋转停止发送视频流

问题

我自己写了电脑控制手机协同(借鉴Scrcpy),但是自己偶尔会出现花屏(屏幕会出现残影)

排查

1:通过错误我找到无效数据包,但不知道为什么会无效,我把pc c++代码看了一下与sdl官方代码对比一下修复几个地方可能导致丢包的逻辑。

2:我发现屏幕旋转后,然后回到桌面,很容易出现花屏,因为我看过scrcpy代码,我发现他旋转时候会停止发送数据包,而我是没有处理

while (!consumeRotationChange() && !eof) {
            //这里是一直等待,所以这里很容易出现卡住,然后buffeer
            //是之前的surface的,旋转就导致宽度和高度不一样,导致前后不对
            int outputBufferId = codec.dequeueOutputBuffer(bufferInfo, -1);
            eof = (bufferInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0;
            try {
                if (consumeRotationChange()) {
                    // must restart encoding with new size
                    //这里跳出来,
                    break;
                }
                if (outputBufferId >= 0) {
                    ByteBuffer codecBuffer = codec.getOutputBuffer(outputBufferId);

                    if (sendFrameMeta) {
                        writeFrameMeta(fd, bufferInfo, codecBuffer.remaining());
                    }

                    IO.writeFully(fd, codecBuffer);
                    if ((bufferInfo.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) == 0) {
                        // If this is not a config packet, then it contains a frame
                        firstFrameSent = true;
                    }
                }
            } finally {
                if (outputBufferId >= 0) {
                    codec.releaseOutputBuffer(outputBufferId, false);
                }
            }
        }

旋转会重新创建surface,这样子采集的数据不一样,所以会出现数据包错误。。。

总结

很多时候有现成的产品作为参考,可以避免很多坑,但如果自己不写,为什么这么是不知道真正的原因的。