1、使用MediaCodec目的
MediaCodec是Android底层多媒体框架的一部分,通常与MediaExtractor、MediaMuxer、AudioTrack结合使用,可以编码H264、H265、AAC、3gp等常见的音视频格式
MediaCodec工作原理是处理输入数据以产生输出数据
1.1 MediaCodec工作流程
MediaCodec的数据流分为input和output流,并通过异步的方式处理两路数据流,直到手动释放output缓冲区,MediaCodec才将数据处理完毕
-
input流:客户端输入待解码或者待编码的数据
-
output流:客户端输出的已解码或者已编码的数据
1.2 MediaCodec API说明
-
getInputBuffers:获取需要输入流队列,返回ByteBuffer数组
-
queueInputBuffer:输入流入队
-
dequeueInputBuffer: 从输入流队列中取数据进行编码操作
-
getOutputBuffers:获取已经编解码之后的数据输出流队列,返回ByteBuffer数组
-
dequeueOutputBuffer:从输出队列中取出已经编码操作之后的数据
-
releaseOutputBuffer: 处理完成,释放output缓冲区
1.3 基本流程
-
MediaCodec的基本使用遵循上图所示,它的生命周期如下所示:
-
Stoped:创建好MediaCodec,进行配置,或者出现错误
-
Uninitialized: 当创建了一个MediaCodec对象,此时MediaCodec处于Uninitialized,在任何状态调用reset()方法使MediaCodec返回到Uninitialized状态
-
Configured: 使用configure(…)方法对MediaCodec进行配置转为Configured状态
-
Error: 出现错误
-
Executing:可以在Executing状态的任何时候通过调用flush()方法返回到Flushed状态
-
Flushed:调用start()方法后MediaCodec立即进入Flushed状态
-
Running:调用dequeueInputBuffer后,MediaCodec就转入Running状态
-
End-of-Stream:编解码结束后,MediaCodec将转入End-of-Stream子状态
-
Released:当使用完MediaCodec后,必须调用release()方法释放其资源
1.4 基本使用
//解码器 val mVideoDecoder = MediaCodec.createDecoderByType("video/avc") //编码器 val mVideoEncoder = MediaCodec.createEncoderByType("video/avc")
2、MediaCodec 解码H264/H265
使用MediaCodec 解码H264/H265码流视频,那必须谈下MediaCodec这个神器。附官网数据流程图如下:
input:ByteBuffer输入方;
output:ByteBuffer输出方;
-
使用者从MediaCodec请求一个空的输入buffer(ByteBuffer),填充满数据后将它传递给MediaCodec处理。
-
MediaCodec处理完这些数据并将处理结果输出至一个空的输出buffer(ByteBuffer)中。
-
使用者从MediaCodec获取输出buffer的数据,消耗掉里面的数据,使用完输出buffer的数据之后,将其释放回编解码。
【学习地址】:FFmpeg/WebRTC/RTMP/NDK/Android音视频流媒体高级开发
【文章福利】:免费领取更多音视频学习资料包、大厂面试题、技术视频和学习路线图,资料包括(C/C++,Linux,FFmpeg webRTC rtmp hls rtsp ffplay srs 等等)有需要的可以点击1079654574加群领取哦~
2.1 H264码流解码示例代码如下(基本都做了注释)
package com.zqfdev.h264decodedemo;
import android.media.MediaCodec;
import android.media.MediaFormat;
import android.util.Log;
import android.view.Surface;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOExc