OnPreviewCallback方法下摄像头90度竖屏方向异常问题
解决NV21格式视频90度旋转方向问题
我看到你在做IP流媒体开发时碰到了竖屏模式下视频翻转、方向不正确的问题,而且已经尝试了nv21Converter和一段旋转NV21的代码,咱们来一步步拆解问题,找到靠谱的解决办法。
首先要明确,NV21是Android场景下常用的YUV格式,它的存储顺序是Y亮度分量平面在前,接着是V和U色度分量交替排列的平面。旋转这类格式时,必须同时正确处理Y和UV分量的位置,否则很容易出现画面方向错、颜色失真的情况。
你给出的rotateNV21代码框架是对的,但可能存在UV分量处理不到位的情况,我给你完善这段代码,确保90度旋转时Y和UV分量都能正确转换:
public static byte[] rotateNV21(final byte[] yuv, final int width, final int height, final int rotation) { if (rotation == 0) return yuv; if (rotation % 90 != 0 || rotation < 0 || rotation > 270) { throw new IllegalArgumentException("Rotation must be 0, 90, 180 or 270 degrees"); } // 90/270度旋转时,宽高需要互换 final int rotatedWidth = rotation % 180 == 0 ? width : height; final int rotatedHeight = rotation % 180 == 0 ? height : width; byte[] rotatedData = new byte[yuv.length]; int ySize = width * height; int uvSize = ySize / 2; switch (rotation) { case 90: // 处理Y亮度分量 for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { rotatedData[x * height + height - y - 1] = yuv[y * width + x]; } } // 处理UV色度分量 for (int y = 0; y < height / 2; y++) { for (int x = 0; x < width; x++) { rotatedData[ySize + x * height + height - y - 1] = yuv[ySize + y * width + x]; } } break; case 180: // 补充180度旋转逻辑(按需使用) int i = ySize - 1; for (int j = 0; j < ySize; j++) { rotatedData[i] = yuv[j]; i--; } i = yuv.length - 1; for (int j = ySize; j < yuv.length; j++) { rotatedData[i] = yuv[j]; i--; } break; case 270: // 补充270度旋转逻辑(按需使用) for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { rotatedData[(width - x - 1) * height + y] = yuv[y * width + x]; } } for (int y = 0; y < height / 2; y++) { for (int x = 0; x < width; x++) { rotatedData[ySize + (width - x - 1) * height + y] = yuv[ySize + y * width + x]; } } break; } return rotatedData; }
额外注意点:
- 调用代码时,记得传入正确的原始宽高和旋转角度(竖屏场景传90),代码里已经自动处理了旋转后的宽高互换,后续渲染时要用
rotatedWidth和rotatedHeight来设置画面尺寸 - 还要检查流媒体传输的元数据:有些播放器会依赖SDP或协议头里的旋转标记来自动调整方向,如果只处理了原始数据旋转但没同步元数据,可能还是会出现显示异常
内容的提问来源于stack exchange,提问作者Hardy
相关产品推荐
相关产品推荐

