【问题标题】:Android MediaCodec encoding + camera2 how to create a black screen for pause and resumeAndroid MediaCodec编码+camera2如何为暂停和恢复创建黑屏
【发布时间】:2022-01-25 12:49:08
【问题描述】:

我已经使用 MediaCodec 创建了一个表面并将其作为目标添加到 camera2 api。现在我想暂停 MediaCodec 编码,然后恢复它。我期望的是编码的视频在我暂停时变黑并在我恢复时继续。使用MediaCodec.PARAMETER_KEY_SUSPEND 不起作用,因为输出是一个冻结的帧,如果在编码开始时发生暂停,则时间在我恢复时开始。所以我想给编码器提供黑色图像,但我怎样才能在表面上画画呢?谢谢!

编辑:这是我用来使 camera2 与 MediaCodec 一起工作的一些代码。

  1. 我创建了一个简单的 MediaCodec:

    try {
        mediaCodec =
            MediaCodec.createEncoderByType(mime)
        Logger.d(TAG, "MediaCodec info " + mediaCodec.codecInfo.name)
    
    
    } catch (e: IOException) {
        e.printStackTrace()
    }
    mediaCodec.configure(mediaFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE)
    
    val inputSurface = mediaCodec.createInputSurface() //<-- this is passed to the camera2
    
  2. 我将表面添加到相机:

    captureRequestBuilder.addTarget(inputSurface);
    List<Surface> surfaceList = new ArrayList<>();
            surfaceList.add(cameraFrame.getSurface());
            surfaceList.add(inputSurface);
    
            camera.createCaptureSession(
                    surfaceList,
                    captureSessionObserver,
                    cameraThreadHandler
            );
    

然后在循环中我读取 mediaCodec 输出缓冲区并将它们写入多路复用器。

【问题讨论】:

    标签: android android-mediacodec glsurfaceview


    【解决方案1】:

    我会在 SurfaceView 上绘制黑色图像,如下所示:

    val surface = getSurfaceFromSomething()
    val canvas = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) surface.lockHardwareCanvas()
    else surface.lockCanvas(null)
    canvas.drawColor(Color.BLACK)
    surface.unlockCanvasAndPost(canvas)
    

    或者你也可以试试这个 MediaCodec 功能: https://developer.android.com/reference/android/media/MediaFormat#KEY_PUSH_BLANK_BUFFERS_ON_STOP

    【讨论】:

    • 测试了 KEY_PUSH_BLANK_BUFFERS_ON_STOP - 没有工作。您认为什么时候该做表面的事情?
    • 您可以在调用一些 mediaCodec 方法暂停它之后立即尝试在表面上绘制。如果它不起作用,您可以尝试检测 BUFFER_FLAG_END_OF_STREAM 并在获得此标志后立即绘制黑框。还有一些肮脏的技巧,您可以将黑色背景颜色设置为表面所属的 SurfaceView (surfaceView.setBackgroundColor(Color.BLACK)),或者您可以创建一个黑色背景的 ImageView 并将其放置在屏幕上的 surfaceView 下并在您恢复 mediaCodec 时隐藏它,并在您暂停时显示它。
    • 这听起来像是可能在 1 台设备上运行但不适用于其他设备的 hack。
    • 前两件事可能会发生,但至于最后两件事,我想指出它们适用于所有设备
    • 我尝试了surfaceview.setBackgroundColor,它没有做任何事情。 camera2 有它写入的表面列表。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-07
    • 2014-05-06
    • 1970-01-01
    相关资源
    最近更新 更多