使用MediaCodec在Grafika的“连续捕获”活动中编码之前裁剪视频。

10
我正在学习Grafika的“连续捕获”(Continuous Capture)活动,这是关于使用MediaCodec录制视频的内容。
该活动源代码位于 https://github.com/google/grafika/blob/master/src/com/android/grafika/ContinuousCaptureActivity.java
该程序使用SurfaceTexture对象来接收来自相机的数据,并使用此SurfaceTexture对象创建了两个EGLSurface对象,其中一个EGLSurface对象将数据提供给MediaCodec,另一个将数据提供给用于相机预览的SurfaceView。MediaCodec对数据进行H.264编码,而MediaMuxer对象将H.264数据写入MP4文件。
但是,相机支持的预览大小为横向(宽>高),例如1920*1080、1440*1080、720*480等。通常,在录制视频时我们拿着手机是竖直方向的,因此我们应该使用API:Camera.setDisplayOrientation(90)将图像旋转为竖屏模式,然后就可以录制竖屏视频了。

但我想用手持竖直的手机录制风景视频,我必须从相机中裁剪每一帧。我的方法是将每个画面图片的底部和顶部剪掉,只保留图片中间部分,然后左侧的图片就会变成横向的。

但我不熟悉OpenGL,我不知道如何裁剪SurfaceTexture数据。有谁擅长OpenGL能够给我些帮助吗?

1个回答

16

请查看“相机纹理”活动。请注意,它允许您以多种方式操作图像,特别是“缩放”。这个“缩放”是通过修改纹理坐标来完成的。

ScaledDrawable2D类执行此操作;调用setScale()方法更改“缩放”,而不是缩放矩形本身。纹理坐标范围从0.0到1.0,包括1.0,并且getTexCoordArray()方法修改它们以跨越纹理的一部分。

要裁剪帧,您需要按比例修改纹理坐标。例如,如果输入视频为720x1280纵向拍摄,并且您想要720x720,则需要将纹理坐标从以下坐标更改为:

[0.0, 0.0]  [1.0, 0.0]
[0.0, 1.0]  [1.0, 1.0]

到这个:

[0.0, 280/1280.0]  [1.0, 280/1280.0]
[0.0, 1000/1280.0] [1.0, 1000/1280.0]

然后将其渲染在正方形上而不是矩形上。


1
@dragonfly 我正在处理类似的需求。我需要将一个640x480分辨率的视频处理成480x480。因此,我尝试应用fadden的建议(最初尝试从1280x720获取720x720视频)。我所做的是,将Drawable2d类中的RECTANGLE_TEX_COORDS更改为fadden建议的值。还更改了FullFrameRect类中Drawable2d类初始化时的参数(https://github.com/google/grafika/blob/master/src/com/android/grafika/gles/FullFrameRect.java中的第26行),以便返回一个1280x720的视频。 - human123
2
你应该修改纹理坐标。矩阵与裁剪操作无关。 - dragonfly
1
我猜你在drawFrame操作之前没有改变glViewport。 GLES20.glViewport(0,0,720,720)就可以了。 - dragonfly
1
@fadden 我知道这是很久以前的事情了,但我想试一试。您能否详细说明一下“然后在正方形上呈现而不是矩形上呈现”?我不太明白在哪里以及如何实现这一点。谢谢! - Roberto Artiles Astelarra
1
@RobertoArtilesAstelarra:从Grafika的"texture from camera"类开始。updateGeometry() 函数使用相机的宽度/高度来设置输出矩形的大小,以保持相同的纵横比。这将需要是一个正方形。 - fadden
显示剩余14条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接