Android软解码与硬解码流程概述

最近整理了下Android端项目里硬解码与软解码的大致流程,做个笔记,方便以后review。如有错误,欢迎指正。
硬解码:
1.创建MediaCodec:如 MediaCodec.createDecoderByType(keyMime);
2.configure codec:配置format,surface等参数
3.start codec
4.从codec的inputBuffer缓冲区获取一个索引,用于传递解码前的数据(比如h264数据):dequeueInputBuffer,注意如果返回-1说明当前inputBuffer缓冲区已满了,不接收新的数据输入
5.如果获取的inputBufferIndex大于0,说明有可用的输入缓冲区,通过以下接口获取一个空的inputBuffer:
api 21以下:mediaCodec.getInputBuffers()[inputBufferIndex]
api 21以上:mCodec.getInputBuffers(inputBufferIndex);
6.从视频容器(如MP4)demux一个数据,填充到inputBuffer,如:mExtractor.readSampleData(inputBuffer, 0);
7.现在inputBuffer已经填充了数据了,通过queueInputBuffer接口将inputBuffer送入decode队列

8.接下来调用dequeueOutputBuffer,获取解码器的输出。注意,这个函数传递以下参数:

8.1 MediaCodec.BufferInfo:这个是我们作为入参传入的,传入的时候是一个空的BufferInfo。当解码器dequeueOutputBuffer获取到输出的时候,会将解码器输出数据的metadata填充到这个对象里面
meatadata结构(bufferInfo类的定义)如下:

8.2 timeoutUs自然就是等待解码器输出的超时时间了
8.3 这个函数的返回值是:成功解码的output buffer的index,可以根据这个index获取到output buffer
9.根据outputBufferIndex,从解码器输出缓冲区中获取一个outputBuffer
api 21以下:mediaCodec.getOutputBuffers()[outputBufferIndex]
api 21以上:mCodec.getOutputBuffer(outputBufferIndex);
10.有了解码的输出数据outputBuffer和数据的metadata(包括offset,pts等信息),就得到了完整的解码数据了

软解码:(FFMPEG解码)
1.创建ffmpeg codec:调用avcodec_find_decoder:在ffmpeg中是根据codecid(aac,h264等注册的id)寻找合适的decoder,返回AVCodec对象
2.创建decode的context:avcodec_alloc_context3,这函数返回的codecContext包含解码器所需要的各种配置信息,比如
对于aac decode,context可以用来设置sample_rate,channels,profile等
对于h264 decode,context可以用来设置width,height等、
3.调用avcodec_open2:用已经配置好的decoder的context,来configure解码器codec
4.调用av_init_packet(AVPacket *pkt);初始化一个pkt用于接收待解码的数据
5.用demux输出的数据,填充pkt的data,设置pkt的flag(是否包含key frame等)
6.调用avcodec_send_packet将填充满的pkt,发送给解码器
7.调用avcodec_receive_frame(AVCodecContext *avctx, AVFrame *frame);从解码器接收decode后的数据,填充到AVFrame中。

通过以上函数就能够得到解码后的数据了,之后根据需要,还可以继续处理:

8.对于video数据,从AVFrame中,拷贝decoded的数据成YUV格式(I420),到uint8_t数组

9.通过OpenGL的shader可以将YUV420数据画到SurfaceView的output surface上,进行渲染


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值