在Android中,如何将预定义的Surface传递给MediaCodec进行编码?

我有一个pipe理自己的GLSurfaceView的应用程序,现在我想使用Android 4.3的新的MediaCodecfunction,将Surface作为input。

在所有我见过的例子中,使用MediaCodec.createInputSurface()创buildSurface,然后为这个Surface创buildGL上下文。 这感觉是单一的,并且令人难以置信的破坏性,以改造成已经稳定的代码库。

是否可以使用MediaCodec.configure(format,a_predefined_Surface,null,MediaCodec.CONFIGURE_FLAG_ENCODE)? 这允许我以即插即用和按需的方式使用MediaCodec。 MediaCodec.configure()采用Surface参数的事实表明这应该是可能的。 但是,API指出“指定一个表面,以渲染此解码器的输出” http://developer.android.com/reference/android/media/MediaCodec.html#configure(android.media.MediaFormat,android 。 view.Surface,android.media.MediaCrypto,int)这是否意味着这只是为了解码而不是编码 ? 如果是的话,有没有办法让MediaCodec使用预定义的Surface进行编码?

我传入的Surface已经创build,EGL_RECORDABLE_ANDROID设置为true,并且返回的GL上下文被validation为包含所需的EGL_RECORDABLE_ANDROID属性。 尽pipe如此,MediaCodec.configure()失败,并带来无用的exception“native_window_api_connect返回错误:无效参数(-22)”:

I/ACodec(32383): Now uninitialized I/OMXClient(32383): Using client-side OMX mux. I/ACodec(32383): [OMX.qcom.video.encoder.avc] Now Loaded E/MediaCodec(32383): native_window_api_connect returned an error: Invalid argument (-22) W/System.err(32383): java.lang.IllegalStateException W/System.err(32383): at android.media.MediaCodec.native_configure(Native Method) W/System.err(32383): at android.media.MediaCodec.configure(MediaCodec.java:259) [...] W/System.err(32383): at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1520) W/System.err(32383): at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1248) 

这是来自Android 4.3的三星Galaxy S4。

  • MediaExtractor,带原始/资产文件的MediaMetadataRetriever
  • Android MediaCodec解码h264原始帧
  • MediaCodec getInputImage在某些设备上返回null
  • 在android:4.3的MediaMuxer或ffmpeg中通过video添加水印位图
  • 不可能使用MediaMuxer混合audio文件和video文件?
  • 使用MediaCodec和MediaMuxer的图像到video
  • Android MediaCodec AAC编码器
  • 使用MediaMuxer无法混合音频文件和video文件?
  • 不,这不行。 input表面必须使用createInputSurface()创build。

    请记住,“表面”不是数据的缓冲区,而是生产者和消费者端点经常处于不同进程的缓冲区队列。 有很多移动件需要设置。 还要注意SurfaceEGLSurface是两个不同的东西,虽然经常一起使用,但是并不紧密相关。

    这个API看起来很怪异,很奇怪,因为它是。 Surface的实现过去几年已经发生了很大变化 – 过去的基础并不普遍,所以大部分改变端点的API都没有公开。 (未指定的) MediaCodec API仍在不断发展。

    有一个向GLSurfaceViewMediaCodec展示相同内容(相机预览)的例子 。 这听起来像你正在尝试做类似的事情。 (如果没有,更新你的问题,我会更新答案。)

    看起来在API 23+中有一个名为setInputSurface(Surface)的API:

    具有setInputSurface(Surface)的API 23+