当前位置:   article > 正文

android 将opengles渲染线程嵌入到exoplayer解码线程内_exoplayer opengl

exoplayer opengl

根据项目需要实现这个功能,所以又开始改exoplayer源码了。我以前也改过修改ExoPlayer源码,获取帧时间,现在我要在这个的基础上进行修改

修改VideoTimeListener.java,添加新的回调函数

  1. public interface VideoTimeListener {
  2. void onVideoTimeChanged(long time);
  3. Surface onSurface(Surface surface);
  4. void onSizeChanged(int width,int height);
  5. void onRelease();
  6. void onStart();
  7. void onStop();
  8. }

接下来修改SimpleExoPlayer.java的ComponentListener内代码,添加上边的函数

  1. @Override
  2. public Surface onSurface(Surface surface) {
  3. for (VideoTimeListener videoTimeListener : videoTimeListeners) {
  4. return videoTimeListener.onSurface(surface);
  5. }
  6. return surface;
  7. }
  8. @Override
  9. public void onSizeChanged(int width, int height) {
  10. for (VideoTimeListener videoTimeListener : videoTimeListeners) {
  11. videoTimeListener.onSizeChanged(width,height);
  12. }
  13. }
  14. @Override
  15. public void onRelease() {
  16. for (VideoTimeListener videoTimeListener : videoTimeListeners) {
  17. videoTimeListener.onRelease();
  18. }
  19. }
  20. @Override
  21. public void onStart() {
  22. for (VideoTimeListener videoTimeListener : videoTimeListeners) {
  23. videoTimeListener.onStart();
  24. }
  25. }
  26. @Override
  27. public void onStop() {
  28. for (VideoTimeListener videoTimeListener : videoTimeListeners) {
  29. videoTimeListener.onStop();
  30. }
  31. }

好了,这样就可以监听exoplayer的解码线程的生命周期了,exoplayer的解码线程我没找到,不过找到了解码调用的类MediaCodecVideoRenderer.java
下面要添加代码的函数都在MediaCodecVideoRenderer.java内

先在setSurface(Surface surface)内添加代码

  1. private void setSurface(Surface surface) throws ExoPlaybackException {
  2. Surface s = null;
  3. if(timeListener != null){
  4. s = timeListener.onSurface(surface);
  5. }
  6. if(s != null){
  7. surface = s;
  8. }
  9. //省略代码
  10. }

在configureCodec(MediaCodecInfo codecInfo, MediaCodec codec, Format format,MediaCrypto crypto)内添加代码

  1. @Override
  2. protected void configureCodec(MediaCodecInfo codecInfo, MediaCodec codec, Format format,
  3. MediaCrypto crypto) throws DecoderQueryException {
  4. //省略代码
  5. if(timeListener != null){
  6. timeListener.onSizeChanged(mediaFormat.getInteger(MediaFormat.KEY_WIDTH),mediaFormat.getInteger(MediaFormat.KEY_HEIGHT));
  7. }
  8. codec.configure(mediaFormat, surface, crypto, 0);
  9. if (Util.SDK_INT >= 23 && tunneling) {
  10. tunnelingOnFrameRenderedListener = new OnFrameRenderedListenerV23(codec);
  11. }
  12. }

这里要注意,正常情况下configureCodec比setSurface先运行,可是我在debug模式下,没打断点的时候是setSurface比configureCodec先运行

在onStarted()和onStopped()内添加代码,这样就可以监听开始播放和停止播放了,需要注意的是在播放时候seekTo会调用onStarted和onStopped,所以要回调的地方判断一下

  1. @Override
  2. protected void onStarted() {
  3. super.onStarted();
  4. droppedFrames = 0;
  5. droppedFrameAccumulationStartTimeMs = SystemClock.elapsedRealtime();
  6. lastRenderTimeUs = SystemClock.elapsedRealtime() * 1000;
  7. if(timeListener != null){
  8. timeListener.onStart();
  9. }
  10. }
  11. @Override
  12. protected void onStopped() {
  13. joiningDeadlineMs = C.TIME_UNSET;
  14. maybeNotifyDroppedFrames();
  15. super.onStopped();
  16. if(timeListener != null){
  17. timeListener.onStop();
  18. }
  19. }

在onDisabled()内添加代码

  1. @Override
  2. protected void onDisabled() {
  3. if (timeListener != null) {
  4. timeListener.onRelease();
  5. }
  6. //省略代码
  7. }

添加属性

  1. private long timeUsIndex;
  2. private long timeIndex;
  3. private long timeUs;

在上面的configureCodec函数内初始化

timeUsIndex = timeIndex = 0;

将在renderOutputBufferV21和renderOutputBuffer内获取帧时间的代码删掉,改成

  1. timeUsIndex++;
  2. timeUs = presentationTimeUs;

重写render(long positionUs, long elapsedRealtimeUs)函数,这个函数是MediaCodecVideoRenderer的父类的,他会每隔几毫秒调用一次,就算不解码也会调用,用它来进行渲染

  1. @Override
  2. public void render(long positionUs, long elapsedRealtimeUs) throws ExoPlaybackException {
  3. while (timeIndex < timeUsIndex){
  4. timeIndex++;
  5. if(surface != null && timeListener != null && timeIndex == timeUsIndex){
  6. timeListener.onVideoTimeChanged(timeUs/1000);
  7. }
  8. }
  9. super.render(positionUs, elapsedRealtimeUs);
  10. }

大致就这样

GitHub

基于这篇写的全景播放器

ExoEditVR

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/秋刀鱼在做梦/article/detail/852510
推荐阅读
相关标签
  

闽ICP备14008679号