Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/218.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 将MediaCodec解码视频帧绘制到屏幕的最快方法?_Android_Surfaceview_Yuv_Decoder_Android Mediacodec - Fatal编程技术网

Android 将MediaCodec解码视频帧绘制到屏幕的最快方法?

Android 将MediaCodec解码视频帧绘制到屏幕的最快方法?,android,surfaceview,yuv,decoder,android-mediacodec,Android,Surfaceview,Yuv,Decoder,Android Mediacodec,我正在寻找从MediaCodec解码器接收图像帧并将其绘制到Android设备屏幕的最快方法。重要的限制和解释是: 无法使用MediaPlayer。不允许中间应用程序 必须尽快将MediaCodec解码器的输出帧绘制到屏幕上(最小化延迟) 可用的解码器输出格式如下: ColorFormat[0]0x00000013颜色格式YUV420平面 彩色格式[1]0x00000015彩色格式YUV420半平面 ColorFormat[2]0x7F000001 OMX_SEC_COLOR_formatNV1

我正在寻找从MediaCodec解码器接收图像帧并将其绘制到Android设备屏幕的最快方法。重要的限制和解释是:

  • 无法使用MediaPlayer。不允许中间应用程序

  • 必须尽快将MediaCodec解码器的输出帧绘制到屏幕上(最小化延迟)

  • 可用的解码器输出格式如下:
    ColorFormat[0]0x00000013颜色格式YUV420平面
    彩色格式[1]0x00000015彩色格式YUV420半平面
    ColorFormat[2]0x7F000001 OMX_SEC_COLOR_formatNV12TPysicalAddress
    ColorFormat[3]0x7FC00002 OMX_SEC_COLOR_FormatNV12平铺

  • 视频分辨率,因此每个输出帧的分辨率为960x720

  • 目标平台是Galaxy Note II,该方法可以针对该平台(例如,利用可用的硬件功能)。这不需要在其他平台上工作,也不需要是通用的解决方案


  • 一个不到66毫秒的方法是好的。少于33毫秒就好了。我目前的方法需要80-90毫秒,这太糟糕了。(我不想费心描述它,因为我不想把答案偏向任何特定的方向。)

    你最好的办法是直接解码到
    表面。解码成一个
    ByteBuffer
    会让你慢很多。上的许多示例(例如,
    ExtractMpegFramesTest
    )将解码器的输出发送到屏幕外表面,并使用GLES进行检查,但这只是一个简单的更改,可以使其在屏幕上工作


    更新:有两个不同的基于MediaCodec的视频播放器,分别将输出发送到SurfaceView和TextureView。

    您可以尝试改用TextureView。该代码的工作方式类似于ExtractMpegFramesTest,但您只需要使用从TextureView获得的代码,而不是在CodeOutputSurface中创建SurfaceTexture。不完全避免GLE,但将其保持在最小值。这意味着当前线程没有配置有效的
    EGLDisplay
    。必须设置
    EGLDisplay
    EGLContext
    ,并且在调用
    updateMaximage()
    时必须具有相同的值。这些是使用
    eglMakeCurrent()
    为每个线程设置的。参见
    SurfaceTexture
    doc中的最后一段;特别要注意的是,您不能直接从
    onFrameAvailable()
    回调调用
    UpdateMaximage()
    。这是一条奇怪的消息——我在Mesa代码中看到的唯一类似消息。你在使用模拟器吗?(我正试图用代码拼凑一个APK来演示这一点;可能需要一天左右的时间。)此处暂时提供了一个源代码片段:。希望被一个完整的项目所取代。该活动有一个带有“播放”按钮和TextureView的布局。电影被缩放到TextureView的大小,该大小由本例中的视图布局决定,因此需要进行调整以使视频看起来正确。现在可以使用带有
    PlayMovieActivity
    的完整SDK应用程序--请参阅GitHub上的Grafika()。特别是,“播放视频(TextureView)”是我上面描述的内容。