Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/230.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 用于RTMP流的MediaCodec编码器输出缓冲区的扩展客户端所有权_Android_Ffmpeg_Rtmp_Android Mediacodec_Mediamuxer - Fatal编程技术网

Android 用于RTMP流的MediaCodec编码器输出缓冲区的扩展客户端所有权

Android 用于RTMP流的MediaCodec编码器输出缓冲区的扩展客户端所有权,android,ffmpeg,rtmp,android-mediacodec,mediamuxer,Android,Ffmpeg,Rtmp,Android Mediacodec,Mediamuxer,背景: 我已将Android的MediaCodec连接到FFmpeg,以对MediaMuxer不支持的多种格式进行多路复用,包括通过.flv容器输出的rtmp://。这种流式多路复用器需要更长、不可预测的MediaCodec输出缓冲区所有权,因为它们可以在任何数据包处理步骤上执行网络I/O。对于我的视频流,我使用为Surface输入配置的MediaCodec。为了将多路复用与编码分离,我通过处理程序将MediaCodec的ByteBuffer输出缓冲区排队到多路复用器 如果我将.flv输出多路复

背景:

我已将Android的MediaCodec连接到FFmpeg,以对MediaMuxer不支持的多种格式进行多路复用,包括通过
.flv
容器输出的
rtmp://
。这种流式多路复用器需要更长、不可预测的MediaCodec输出缓冲区所有权,因为它们可以在任何数据包处理步骤上执行网络I/O。对于我的视频流,我使用为Surface输入配置的MediaCodec。为了将多路复用与编码分离,我通过处理程序将MediaCodec的ByteBuffer输出缓冲区排队到多路复用器

如果我将
.flv
输出多路复用到文件,而不是rtmp端点,那么所有这些都可以出色地工作

问题:

当muxing到
rtmp://...
endpoint我注意到我的流媒体应用程序在调用
eglSwapBuffers(mEGLDisplay,mEncodingEGLSurface)
at
dequeueOutputBuffer()
时开始阻塞,

有什么技巧可以避免复制由
MediaCodec#dequeueoutputbuffer
返回的所有编码器输出,并立即调用
releaseOutputBuffer(…)

我的项目的完整来源可以在上找到。具体见:

  • :抽象编码器类,在音频和视频编码器之间具有共享行为:主要是DraineCoder()。将数据写入
    Muxer
    实例
  • :实现
    Muxer
  • 。将相机帧发送到为视频编码配置的AndroidnCoder子类
Systrace

这里有一些systrace输出流720p@2Mbps视频到Zencoder

已解决


复制MediaCodec编码器输出,然后在缓冲区可用时立即释放,这样可以在不显著影响性能的情况下解决问题。我在
ArrayDeque
中为每个muxer磁道循环使用ByteBuffer副本,这限制了分配的数量。

不幸的是,大多数Android手机不支持这种用例。MediaCodec只是编解码器供应商在设备上使用的OMX IL API的抽象。对于给定的配置,供应商编解码器需要一定数量的输入和输出缓冲区

虽然从理论上讲,有一个输出缓冲区与编码器排队应该足够了,但很多时候这是供应商编解码器不支持的,因为这会导致较低的编码性能;因此编解码器暂停。这在输入缓冲区中更为普遍


对于为MediaCodec实例分配的输入/输出缓冲区数量没有应用程序控制-Android尝试分配所需的最小缓冲区数量以节省内存。因此,您唯一的选择是复制输出缓冲区。虽然这并不理想,但编码的缓冲区往往相当小。

感谢您的全面回答!