【问题标题】:Android MediaCodec: how to request a key frame when encodingAndroid MediaCodec:编码时如何请求关键帧
【发布时间】:2012-11-21 20:12:42
【问题描述】:

在 Android4.1 中,实时编码应用程序中经常需要一个关键帧。但是如何使用 MediaCodec 对象呢?目前的Android4.2 SDK好像不支持。

【问题讨论】:

    标签: encode android-4.2-jelly-bean


    【解决方案1】:

    MediaCodec 有一个名为setParameters 的方法来救援。 在 Kotlin 中,您可以这样做:

    fun yieldKeyFrame(): Boolean {
        val param = Bundle()
        param.putInt(MediaCodec.PARAMETER_KEY_REQUEST_SYNC_FRAME, 0)
        try {
            videoEncoder.setParameters(param)
            return true
        } catch (e: IllegalStateException) {
            return false
        }
    }
    

    在上面的 sn-p 中,videoEncoder 是配置为进行编码的 MediaCodec 的一个实例。

    【讨论】:

      【解决方案2】:

      可以在输入缓冲区排队时通过指定 MediaCodec.BUFFER_FLAG_SYNC_FRAME 生成随机关键帧:

      MediaCodec codec = MediaCodec.createDecoderByType(type);
      codec.configure(format, ...);
      codec.start();
      ByteBuffer[] inputBuffers = codec.getInputBuffers();
      for (;;) {
        int inputBufferIndex = codec.dequeueInputBuffer(timeoutUs);
        if (inputBufferIndex >= 0) {
          // fill inputBuffers[inputBufferIndex] with valid data
          ...
          codec.queueInputBuffer(inputBufferIndex, 0, inputBuffers[inputBufferIndex].limit(), presentationTime,
              isKeyFrame ? MediaCodec.BUFFER_FLAG_SYNC_FRAME : 0);
        }
      
      }
      

      在 Galaxy Nexus 上编码视频时,偶然发现需要插入随机关键帧。 在它上面,MediaCodec 不会在视频开始时自动生成关键帧。

      【讨论】:

        【解决方案3】:

        您可以在配置编码器时通过设置 KEY_I_FRAME_INTERVAL 键来请求周期性关键帧。在下面的示例中,我每两秒请求一个。为清楚起见,我省略了帧速率或颜色格式等其他键,但您仍需要包含它们。

            encoder = MediaCodec.createByCodecName(codecInfo.getName());
            MediaFormat inputFormat = MediaFormat.createVideoFormat(mimeType, width, height);
        
            /* ..... set various format options here ..... */
            inputFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 2);
        
            encoder.configure(inputFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
            encoder.start();
        

        不过,我怀疑您真正要问的是如何在编码时请求随机关键帧,例如在过场动画开始时。不幸的是,我还没有看到这个界面。停止和重新启动编码器可能会在重新启动时创建一个新的关键帧。当我有机会尝试时,我会在这里发布结果。

        我希望这会有所帮助。

        Thad Phetteplace - GLACI, Inc.

        【讨论】:

          猜你喜欢
          • 2017-04-12
          • 1970-01-01
          • 1970-01-01
          • 2014-02-06
          • 2021-11-07
          • 1970-01-01
          • 1970-01-01
          • 2013-02-22
          • 2021-08-30
          相关资源
          最近更新 更多