You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rockchip设备Camera2+MediaRecorder竖屏WYSIWYG录像裁剪方案问询

解决方案:Camera2 + MediaRecorder 实现竖屏所见即所得录制(Rockchip设备适配)

问题分析

核心矛盾是Rockchip设备的Camera HAL不支持硬件级裁剪,导致MediaRecorder只能录制完整传感器帧,无法直接和竖屏预览对齐。现有setOrientationHint、预览变换仅做视觉调整,未真正改变录制帧内容。


针对问题的解答

1. Camera2+MediaRecorder实时裁剪的正确方式

由于Rockchip HAL不支持Camera2直接裁剪,无法通过MediaRecorder直接实现实时裁剪——MediaRecorder的Surface直接绑定相机输出,只能接收完整传感器帧。必须在相机输出到MediaRecorder之间添加帧处理环节,对帧裁剪后再传给编码器。

2. Surface层(OpenGL/SurfaceTexture)裁剪的可行性

完全可行,这是实时处理的最优方案,无需后期重编码。具体流程:

  • 相机输出帧到SurfaceTexture(绑定OpenGL上下文)
  • 在OpenGL中对帧做中心裁剪(从16:9帧截取中间9:16区域)
  • 将裁剪后的帧同时渲染到预览TextureView和MediaRecorder的Surface,保证所见即所得

该方案依托硬件加速,在RK3568/RK3399上可轻松实现1080p@30fps的实时性能。

3. Rockchip专属API/HAL级裁剪支持

Rockchip Camera HAL默认仅输出完整传感器帧,但可尝试两种硬件级裁剪途径:

  • RK Camera扩展参数:部分设备提供非标准Camera2参数(如com.rockchip.camera.param.CROP_REGION),可在CaptureRequest中设置裁剪区域,需联系Rockchip获取适配文档。
  • RK MPP媒体处理框架:若用MPP替代MediaRecorder,可在编码前通过MPP硬件裁剪模块处理帧,性能比OpenGL更优,但需适配Native层代码,Java层需通过JNI调用。

4. 后期处理的高效方案(避免重编码)

若必须采用后期处理,需避免全帧重编码,最优方式是用FFmpeg流拷贝模式结合裁剪滤镜,仅修改容器元数据和裁剪帧,不重新编码视频流:

ffmpeg -i input.mp4 -filter:v "crop=ih*9/16:ih:(iw-ih*9/16)/2:0" -c:v copy -c:a copy output.mp4

该方式几乎实时,无重编码性能损耗。注意录制时需设置较小的关键帧间隔(如1秒),避免裁剪后播放卡顿。


示例代码:OpenGL实时裁剪实现(Java层)

核心流程代码

  1. 初始化SurfaceTexture与MediaRecorder Surface:
// 初始化SurfaceTexture接收相机帧
SurfaceTexture surfaceTexture = new SurfaceTexture(textureId);
surfaceTexture.setOnFrameAvailableListener(this);

// 配置MediaRecorder
MediaRecorder mediaRecorder = new MediaRecorder();
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
mediaRecorder.setVideoSize(1080, 1920); // 目标竖屏分辨率
mediaRecorder.setOrientationHint(0); // 裁剪后已是竖屏,无需旋转
Surface recorderSurface = mediaRecorder.getSurface();
  1. OpenGL帧裁剪渲染逻辑(onFrameAvailable回调):
@Override
public void onFrameAvailable(SurfaceTexture surfaceTexture) {
    surfaceTexture.updateTexImage();
    float[] transformMatrix = new float[16];
    surfaceTexture.getTransformMatrix(transformMatrix);

    // 相机输出为1920x1080横屏,目标为1080x1920竖屏
    float inputAspect = 1920f / 1080f;
    float targetAspect = 9f / 16f;
    float scaleX = targetAspect / inputAspect; // 横向裁剪比例

    // 渲染到预览TextureView
    previewEglSurface.makeCurrent();
    glViewport(0, 0, 1080, 1920);
    glClear(GL_COLOR_BUFFER_BIT);
    drawCroppedFrame(transformMatrix, scaleX, 1f); // 执行裁剪渲染
    previewEglSurface.swapBuffers();

    // 渲染到MediaRecorder Surface
    recorderEglSurface.makeCurrent();
    glViewport(0, 0, 1080, 1920);
    glClear(GL_COLOR_BUFFER_BIT);
    drawCroppedFrame(transformMatrix, scaleX, 1f);
    recorderEglSurface.swapBuffers();
}

关键注意事项

  • 初始化EGL上下文时需添加EGL_RECORDABLE_ANDROID属性,确保渲染Surface可被MediaRecorder正常编码。
  • 相机CaptureRequest需设置与预览/录制一致的输出分辨率(如1920x1080),避免额外缩放损耗。

Rockchip设备专属优化建议

  1. 优先尝试RK Camera扩展参数:若设备支持,直接在CaptureRequest中设置裁剪区域,性能最优且无需额外处理。
  2. 适配RK MPP框架:追求极致性能时,通过JNI调用MPP硬件裁剪接口,编码前完成帧裁剪,比OpenGL更节省资源。
  3. 规避软件裁剪:嵌入式设备上软件帧处理会大幅降低性能,尽量采用硬件加速方案。

内容的提问来源于stack exchange,提问作者Nityam Tiwari

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.01 15:47:26