[RK3288][Android6.0] 视频编码方式MediaRecorder和MediaCodec

Platform: Rockchip
OS: Android 6.0
Kernel: 3.10.92

目录

    • MediaRecorder
      • 状态机控制
      • 编码例子
    • MediaCodec
      • 工作流
      • 使用例子同步
      • 参考

系统视频编码有两种方式,使用MediaCodec和MediaRecorder。

MediaRecorder:

  • 相对MediaCodec封装得更上层,因此使用相对更简单,但是不能直接处理原始视频数据流了。
  • 从Android5.0后可以从除了Camera的其他surface去拿数据,比如屏幕录制视频。

状态机控制:

[RK3288][Android6.0] 视频编码方式MediaRecorder和MediaCodec_第1张图片

编码例子:

*frameworks/base/media/tests/mediaframeworktest/src/om/android/
mediaframeworktest/functional/mediarecorder/MediaRecorderTest.java*

private boolean recordVideoFromSurface(
            int frameRate, int captureRate, int width, int height,
            int videoFormat, int outFormat, String outFile, boolean videoOnly,
            Surface persistentSurface) {
        MediaRecorder recorder = new MediaRecorder();
......
        recorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
        recorder.setOutputFormat(outFormat);
        recorder.setOutputFile(outFile);
        recorder.setVideoFrameRate(frameRate);
        if (captureRate > 0) {
            recorder.setCaptureRate(captureRate);
        }
        recorder.setVideoSize(width, height);
        recorder.setVideoEncoder(videoFormat);
......
        recorder.prepare();
......
        recorder.start();
......
        recorder.stop();

        return true;
}

MediaCodec:

  • 偏向更底层使用
  • Android4.3以后支持

工作流:

[RK3288][Android6.0] 视频编码方式MediaRecorder和MediaCodec_第2张图片

使用例子(同步):

 MediaCodec codec = MediaCodec.createByCodecName(name);
 codec.configure(format, …);
 MediaFormat outputFormat = codec.getOutputFormat(); // option B
 codec.start();
 for (;;) {
   int inputBufferId = codec.dequeueInputBuffer(timeoutUs);
   if (inputBufferId >= 0) {
     ByteBuffer inputBuffer = codec.getInputBuffer(…);
     // fill inputBuffer with valid data
     …
     codec.queueInputBuffer(inputBufferId, …);
   }
   int outputBufferId = codec.dequeueOutputBuffer(…);
   if (outputBufferId >= 0) {
     ByteBuffer outputBuffer = codec.getOutputBuffer(outputBufferId);
     MediaFormat bufferFormat = codec.getOutputFormat(outputBufferId); // option A
     // bufferFormat is identical to outputFormat
     // outputBuffer is ready to be processed or rendered.
     …
     codec.releaseOutputBuffer(outputBufferId, …);
   } else if (outputBufferId == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
     // Subsequent data will conform to new format.
     // Can ignore if using getOutputFormat(outputBufferId)
     outputFormat = codec.getOutputFormat(); // option B
   }
 }
 codec.stop();
 codec.release();

参考:

MeidaRecorder
MediaCodec
mediacodec-vs-mediaplayer-and-mediarecorder
mediarecorder-mediacodec-and-ffmpeg

你可能感兴趣的:(子类__Codec)