【问题标题】:TextureView with MediaCodec decoder for H264 streams带有用于 H264 流的 MediaCodec 解码器的 TextureView
【发布时间】:2015-12-26 10:27:57
【问题描述】:

这是this question的后续问题。

这是我的TextureView 代码:

public class VideoTextureView extends TextureView implements SurfaceTextureListener{

    private static final String LOG_TAG = VideoTextureView.class.getSimpleName();
    private MediaCodecDecoder mMediaDecoder;
    private MediaCodecAsyncDecoder mMediaAsyncDecoder;

    public VideoTextureView(Context context, AttributeSet attrs) {
        super(context, attrs);
        setSurfaceTextureListener(this);
        Log.d(LOG_TAG, "Video texture created.");
    }

    @Override
    public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
        Log.d(LOG_TAG, "Surface Available: " + width + " x " + height);
        mMediaDecoder = new MediaCodecDecoder();
        mMediaDecoder.Start();
        mMediaDecoder.SetSurface(new Surface(getSurfaceTexture()));
    }

    @Override
    public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
        // TODO Auto-generated method stub

    }

    @Override
    public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
        mMediaDecoder.Stop();
        return false;
    }

    @Override
    public void onSurfaceTextureUpdated(SurfaceTexture surface) {
        // TODO Auto-generated method stub

    }

}

我的问题 - 我的 TextureView 实现是否可以渲染由 MediaCodec 解码的 H264 流?还是我需要进行 EGL 设置或其他任何事情?

提前致谢!

【问题讨论】:

  • 只有在使用 GLES 进行渲染时才需要设置 EGL。 TextureView 将 SurfaceTexture 与自定义 View 相结合,并为您进行 GLES 渲染。这就是为什么视图必须经过硬件加速才能让 TextureView 工作。
  • @fadden 谢谢!所以,我不需要设置 EGL 上下文 :) 早上,我尝试使用 SurfaceView 并使用 SurfaceHolder.getSurface() 设置 Surface 并发现相同的结果。所以我认为TextureView相关的代码可能不是问题所在。 “这就是为什么 View 必须经过硬件加速才能让 TextureView 工作的原因”——Android 开发者网站也这样说。这是否意味着 - 我必须在清单文件的视图级别将硬件加速设置为 true
  • 我认为它在最新版本的 Android 上默认启用,但您可能需要为旧设备显式启用它。见developer.android.com/guide/topics/graphics/hardware-accel.html
  • @fadden 好的!所以我想我正在使用硬件加速。您对其他线程stackoverflow.com/questions/32723393 有什么建议吗?我会很感激你对此的想法,因为我真的在这个问题上苦苦挣扎。我的编码流 (ffmpeg) 可能与 MediaCodec 解码器不兼容,而由 MediaCodec 编码的流可能与我的解码器正常工作。我的实现中是否存在任何可能的错误?
  • @KrzysztofKansy 发现从 Camera + MediaCodec 编码的流可以毫无问题地播放,因此他的流有些不同。你可能面临同样的情况。我对 H.264 的细节了解不多,无法推测可能性。

标签: android h.264 android-mediacodec android-textureview


【解决方案1】:

我的TextureView 实现没问题,因为我也尝试使用SurfaceView 并发现相同的结果。正如@fadden 所说 -

仅当您使用 GLES 进行渲染时,才需要设置 EGL。纹理视图 将 SurfaceTexture 与自定义视图相结合,并执行 GLES 为你渲染。这就是为什么视图必须是硬件加速的 让 TextureView 工作。

感谢@fadden。

【讨论】:

    【解决方案2】:

    我目前正在使用 TextureView 在一个 Activity 中使用 android 上的集合视图单元渲染多个流(抱歉,这里有 ios 术语)。

    它工作正常,但问题是,例如当您旋转设备时,会出现surface_destroyed,然后是surface_available。我看到你正确地停止和启动你的解码器。

    我在解码器中做的一件事是:

    List<NaluSegment> segments = NaluParser.parseNaluSegments(buffer);
            for (NaluSegment segment : segments) {
                // ignore unspecified NAL units.
                if (segment.getType() != NaluType.UNSPECIFIED) {
    
                    // Hold the parameter set for stop/start initialization speed
                    if (segment.getType() == NaluType.PPS) {
                        lastParameterSet[0] = segment;
                    } else if (segment.getType() == NaluType.SPS) {
                        lastParameterSet[1] = segment;
                    } else if (segment.getType() == NaluType.CODED_SLICE_IDR) {
                        lastParameterSet[2] = segment;
                    }
    
                    // add to input queue
                    naluSegmentQueue.add(segment);
                }
            }
    

    我保留最后一个参数集和最后一个关键帧,并在开始时先用这些填充 naluSegmentQueue 以减少视频渲染的延迟。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-10-17
      • 2020-10-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-27
      • 2014-02-06
      相关资源
      最近更新 更多