Skip to content

Commit 2075581

Browse files
committed
update
1 parent e17d620 commit 2075581

File tree

2 files changed

+178
-8
lines changed

2 files changed

+178
-8
lines changed

VideoDevelopment/OpenGL/10.GLSurfaceView+MediaPlayer播放视频.md

Lines changed: 177 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -58,13 +58,8 @@ public class VideoPlayerActivity extends Activity {
5858
@Override
5959
protected void onCreate(@Nullable Bundle savedInstanceState) {
6060
super.onCreate(savedInstanceState);
61-
mGLSurfaceView = new GLSurfaceView(this);
62-
Display display = getWindowManager().getDefaultDisplay();
63-
int width = display.getWidth();
64-
int height = (int) ((width) * (9 / 16f));
65-
ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(width, height);
66-
mGLSurfaceView.setLayoutParams(layoutParams);
67-
setContentView(mGLSurfaceView);
61+
setContentView(R.layout.activity_video_player);
62+
mGLSurfaceView = findViewById(R.id.mGLSurfaceView);
6863
mGLSurfaceView.setEGLContextClientVersion(3);
6964
VideoPlayerRender videoPlayerRender = new VideoPlayerRender(mGLSurfaceView);
7065
videoPlayerRender.setIVideoTextureRenderListener(new VideoPlayerRender.IVideoTextureRenderListener() {
@@ -149,9 +144,184 @@ public class VideoPlayerActivity extends Activity {
149144

150145
### 修复变形
151146

147+
我们要根据视频的宽高和Render中Surface的宽高来计算缩放的比例,让高度或者宽度进行缩放,这样就不会变形了。主要修改的地方就是通过换算这个比例然后根据这个比例来改变顶点渲染器中的点的坐标值,从而让其在换算后的坐标内开始画面,这样就不会变形了。
148+
149+
下面是改动后的VideoPlayerRender类:
150+
151+
```java
152+
public class VideoPlayerRender extends BaseGLSurfaceViewRenderer {
153+
private int mTextureId;
154+
private SurfaceTexture mSurfaceTexture;
155+
private GLSurfaceView mGLSurfaceView;
156+
private boolean mUpdateSurfaceTexture;
157+
private FloatBuffer mVertextBuffer;
158+
private FloatBuffer mTextureBuffer;
159+
private int vertexPosition;
160+
private int texturePosition;
161+
private int samplerTexturePosition;
162+
/**
163+
* 视频的宽高
164+
*/
165+
private int mVideoWidth;
166+
private int mVideoHeight;
167+
/**
168+
* 需改更改渲染的大小
169+
*/
170+
private boolean mNeedUpdateSize;
171+
/**
172+
* Surface的宽高
173+
*/
174+
private int mSurfaceWidth;
175+
private int mSurfaceHeight;
176+
177+
/**
178+
* 坐标占用的向量个数
179+
*/
180+
private static final int POSITION_COMPONENT_COUNT = 2;
181+
// 逆时针顺序排列
182+
private static final float[] POINT_DATA = {
183+
-1f, -1f,
184+
1f, -1f,
185+
-1f, 1f,
186+
1f, 1f,
187+
};
188+
/**
189+
* 颜色占用的向量个数
190+
*/
191+
private static final int TEXTURE_COMPONENT_COUNT = 2;
192+
// 纹理坐标(s, t),t坐标方向和顶点y坐标反着
193+
private static final float[] TEXTURE_DATA = {
194+
0.0f, 1.0f,
195+
1.0f, 1.0f,
196+
0.0f, 0.0f,
197+
1.0f, 0.0f
198+
};
199+
200+
public VideoPlayerRender(GLSurfaceView surfaceView) {
201+
mGLSurfaceView = surfaceView;
202+
mVertextBuffer = BufferUtil.getFloatBuffer(POINT_DATA);
203+
mTextureBuffer = BufferUtil.getFloatBuffer(TEXTURE_DATA);
204+
}
205+
206+
@Override
207+
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
208+
glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
209+
handleProgram(MyApplication.getInstance(), R.raw.video_vertex_shader, R.raw.video_fragment_shader);
210+
vertexPosition = glGetAttribLocation("vPosition");
211+
texturePosition = glGetAttribLocation("vCoordPosition");
212+
samplerTexturePosition = glGetUniformLocation("uSamplerTexture");
213+
mTextureId = TextureUtil.createOESTextureId();
214+
mSurfaceTexture = new SurfaceTexture(mTextureId);
215+
mSurfaceTexture.setDefaultBufferSize(mGLSurfaceView.getWidth(), mGLSurfaceView.getHeight());
216+
mSurfaceTexture.setOnFrameAvailableListener(new SurfaceTexture.OnFrameAvailableListener() {
217+
@Override
218+
public void onFrameAvailable(SurfaceTexture surfaceTexture) {
219+
mUpdateSurfaceTexture = true;
220+
if (mGLSurfaceView != null) {
221+
mGLSurfaceView.requestRender();
222+
}
223+
}
224+
});
225+
if (mTextureRenderListener != null) {
226+
mTextureRenderListener.onCreate(mSurfaceTexture);
227+
}
228+
}
229+
230+
@Override
231+
public void onSurfaceChanged(GL10 gl, int width, int height) {
232+
mSurfaceWidth = width;
233+
mSurfaceHeight = height;
234+
adjustVideoSize();
235+
Log.e("@@@", "onSurfaceChanged width: " + width + "...height.." + height);
236+
glViewport(0, 0, width, height);
237+
}
238+
239+
@Override
240+
public void onDrawFrame(GL10 gl) {
241+
glClear(GLES30.GL_DEPTH_BUFFER_BIT | GLES30.GL_COLOR_BUFFER_BIT);
242+
adjustVideoSize();
243+
glVertexAttribPointer(vertexPosition, POSITION_COMPONENT_COUNT, GLES30.GL_FLOAT, false, 0, mVertextBuffer);
244+
glVertexAttribPointer(texturePosition, TEXTURE_COMPONENT_COUNT, GLES30.GL_FLOAT, false, 0, mTextureBuffer);
245+
synchronized (this) {
246+
if (mUpdateSurfaceTexture) {
247+
mSurfaceTexture.updateTexImage();
248+
mUpdateSurfaceTexture = false;
249+
}
250+
}
251+
GLES30.glEnableVertexAttribArray(vertexPosition);
252+
GLES30.glEnableVertexAttribArray(texturePosition);
253+
GLES30.glUniform1i(samplerTexturePosition, 0);
254+
// 绘制
255+
GLES30.glDrawArrays(GLES30.GL_TRIANGLE_STRIP, 0, 4);
256+
GLES30.glFlush();
257+
GLES30.glDisableVertexAttribArray(vertexPosition);
258+
GLES30.glDisableVertexAttribArray(texturePosition);
259+
}
260+
261+
public void setVideoSize(int width, int height) {
262+
if (mVideoWidth == width && mVideoHeight == height) {
263+
return;
264+
}
265+
// videoWidth 272
266+
// videoHeight 480
267+
mVideoWidth = width;
268+
mVideoHeight = height;
269+
mNeedUpdateSize = true;
270+
}
271+
272+
private void adjustVideoSize() {
273+
if (mVideoWidth == 0 || mVideoHeight == 0 || mSurfaceHeight == 0 || mSurfaceWidth == 0) {
274+
return;
275+
}
276+
if (!mNeedUpdateSize) {
277+
return;
278+
}
279+
mNeedUpdateSize = false;
280+
float widthRation = (float) mSurfaceWidth / mVideoWidth;
281+
float heightRation = (float) mSurfaceHeight / mVideoHeight;
282+
float ration = Math.max(widthRation, heightRation);
283+
// 把视频宽高最小的一个扩大到Surface的大小
284+
int targetVideoWidth = Math.round(mVideoWidth * ration);
285+
int targetVideoHeight = Math.round(mVideoHeight * ration);
286+
// 扩大之后的宽高除以目前surface的宽高,来算错各自要xy的比例,这俩里面有一个肯定是1
287+
288+
float rationX = (float) targetVideoWidth / mSurfaceWidth;
289+
float rationY = (float) targetVideoHeight / mSurfaceHeight;
290+
291+
float[] targetPositionData = new float[]{
292+
POINT_DATA[0] / rationY, POINT_DATA[1] / rationX,
293+
POINT_DATA[2] / rationY, POINT_DATA[3] / rationX,
294+
POINT_DATA[4] / rationY, POINT_DATA[5] / rationX,
295+
POINT_DATA[6] / rationY, POINT_DATA[7] / rationX,
296+
297+
};
298+
// 换算缩放后的顶点坐标。后面在onDraw()方法中会有这个值设置给顶点着色器
299+
mVertextBuffer.clear();
300+
mVertextBuffer.put(targetPositionData);
301+
mVertextBuffer.position(0);
302+
}
303+
304+
private IVideoTextureRenderListener mTextureRenderListener;
305+
306+
public void setIVideoTextureRenderListener(IVideoTextureRenderListener render) {
307+
mTextureRenderListener = render;
308+
}
309+
310+
public interface IVideoTextureRenderListener {
311+
void onCreate(SurfaceTexture surfaceTexture);
312+
}
313+
}
314+
```
315+
316+
317+
318+
下面是具体的效果分别是填充宽和填充高的效果:
319+
320+
<img src="https://raw.githubusercontent.com/CharonChui/Pictures/master/opengl_es_video_player1.jpeg" style="zoom:40%;" />
152321

153322

154323

324+
<img src="https://raw.githubusercontent.com/CharonChui/Pictures/master/opengl_es_video_player_2.jpeg" style="zoom:33%;" />
155325

156326

157327

VideoDevelopment/OpenGL/11.OpenGL ES滤镜.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ RGB三个通道的颜色取反,而alpha通道不变。
7474

7575
## 视频播放滤镜实现
7676

77-
滤镜的编写主要是靠基类
77+
首先需要在GLSurfaceView.Renderer的实现类中提供一个setFilter()的方法,然后在onDrawFrame()的时候再去调用这个Filter的onDraw()方法,所以滤镜的编写主要是靠基类
7878

7979
- 先抽取BaseFilter类,封装好每个滤镜的着色器及onDraw等方法。
8080
- 不同的滤镜都继承该BaseFilter类,然后实现有区别的部分。其实每个不同滤镜的区别就是着色器的不同。

0 commit comments

Comments
 (0)