音频解码器是干什么用的 解码器的主要功能

1.MediaCodec的工作原理编***类Android提供了访问低级多媒体编***的接口,它是Android低级多媒体架构的一部分。通常与MediaExtractor、MediaMuxer、AudioTrack配合使用,可以对H.2***、H.265、AAC、3gp等常见音视频格式进行编解码。广义来说,MediaCodec的工作原理是处理输入...

1.MediaCodec的工作原理

编***类Android提供了访问低级多媒体编***的接口,它是Android低级多媒体架构的一部分。通常与MediaExtractor、MediaMuxer、AudioTrack配合使用,可以对H.2***、H.265、AAC、3gp等常见音视频格式进行编解码。

广义来说,MediaCodec的工作原理是处理输入数据生成输出数据。具体来说,MediaCodec在编解码过程中使用一组输入/输出缓冲区同步或异步处理数据:首先客户端将待编解码的数据写入获取的Codec的输入缓冲区并提交给codec,codec处理后传输到编码器的输出缓冲区,同时回收客户端对输入缓冲区的所有权;然后,客户端从获得编***输出缓冲区中读取编码后的数据进行处理,处理完成后,编***将客户端的所有权收回到输出缓冲区。重复整个过程,直到编码器停止工作或异常退出。

MEDIC的功能是处理输入数据,生成输出数据。首先,生成输入数据缓冲区,并将数据填充到缓冲区中并提供给编***。编***将异步处理输入数据,然后将填充的输出缓冲区提供给消费者,消费者在消费后将缓冲区返回给编***。

二、MediaCodec编码过程

在整个编解码过程中,MediaCodec的使用会经历配置、启动、数据处理、停止、释放等几个过程,对应的状态可以概括为停止、执行、释放三种状态。停止状态可以细分为未初始化、已配置和异常,执行状态也可以细分为读写数据(刷新)、运行和流结束。

media codec整体状态结构图如下:

从上图可以看出,MediaCodec创建时,会进入未初始化状态。设置好配置信息,调用start()启动后,MediaCodec将进入运行状态,可以读写数据。如果在此过程中出现错误,MediaCodec将进入停止状态。我们只需要使用reset方法重置编***,否则MediaCodec持有的资源最终会被释放。当然,如果正常使用MediaCodec,我们也可以向编***发送EOS指令,调用stop和release方法来终止编***的使用。

三。MediaCodec API描述

MediaCodec可以处理特定的视频流。主要有这些方法:

getInputBuffers:获取需要编码数据的输入流队列,返回的是一个ByteBuffer数组queueInputBuffer:输入流入队列dequeueInputBuffer:从输入流队列中取数据进行编码操作getOutputBuffers:获取编解码之后的数据输出流队列,返回的是一个ByteBuffer数组dequeueOutputBuffer:从输出队列中取出编码操作之后的数据releaseOutputBuffer:处理完成,释放ByteBuffer数据

第四,MediaCodec的基本使用

所有同步模式的MediaCodec API都遵循一种模式:

创建并配置MediaCodec对象
循环,直到完成:
如果输入缓冲区准备好了,读取一个输入块并将其***到输入缓冲区
如果输出缓冲区准备好了,***输出缓冲区的数据
并释放MediaCodec对象。

(1)创建编码器/***

MediaCodec主要提供了createEncoderByType(字符串类型)和createDecoderByType(字符串类型)两种方法来创建编***,这两种方法都需要MIME类型的多媒体格式。常见的MIME多媒体格式如下:
●" video/x-vnd . on2 . vp8 " –VP8视频(即视频输入。webm)
●" video/x-vnd . on2 . vp9 " –VP9视频(即视频输入。webm)
●“视频/***C”–H.2***/***C视频
●“视频/mp4v-es”–MPEG4视频
●“视频/3gpp”–H.263视频
●“音频/3gpp”–AMR窄带音频
●" audio/AMR-WB " –AMR宽带音频
●“音频/mpeg”–MPEG1/2音频层III
●" audio/mp4a-latm " –AAC音频(注意,这是原始的AAC包,没有在LATM包装!)
●" audio/vorbis " –vorbis audio
●" audio/g711-alaw " –g . 711 alaw audio
●" audio/g711-mlaw " –G.711 ulaw audio
当然,MediaCodec还提供了createByCodecName(字符串名称)方法,支持使用特定的组件名称来创建编***。不过这种方法用起来有些麻烦,官方建议最好配合MediaCodecList使用,因为MediaCodecList记录了所有可用的编***。当然,我们也可以使用这个类来判断传入的minmeType参数,以匹配MediaCodec是否支持mineType编***。

以指定为“video/avc”的MIME类型为例,代码如下:

private static MediaCodecInfo selectCodec(String mimeType) { // 获取所有支持编***数量 int numCodecs = MediaCodecList.getCodecCount(); for (int i = 0; i < numCodecs; i++) { // 编***相关性信息存储在MediaCodecInfo中 MediaCodecInfo codecInfo = MediaCodecList.getCodecInfoAt(i); // 判断是否为编码器 if (!codecInfo.isEncoder()) { continue; } // 获取编码器支持的MIME类型,并进行匹配 String[] types = codecInfo.getSupportedTypes(); for (int j = 0; j < types.length; j++) { if (types[j].equalsIgnoreCase(mimeType)) { return codecInfo; } } } return null; }

(2)配置并启动编码器/***。

编***配置使用MediaCodec的configure方法,该方法首先提取以MediaFor***t存储的数据映射,然后调用本地方法native-configure来配置编***。配置时,configure方法需要传入for***t、su***ce、crypto、flags等参数,其中for***t是MediaFor***t的一个实例,以“key-value”键值对的形式存储多媒体数据格式信息;Su***ce用来表示***的数据源来自这个面;Crypto用于指定MediaCrypto对象以安全地解密媒体数据;Flags表示编码器(CONFIGURE_FLAG_ENCODE)已配置。

MediaFor***t mFor***t = MediaFor***t.createVideoFor***t("video/avc", ***0 ,480); // 创建MediaFor***tmFor***t.setInteger(MediaFor***t.KEY_BIT_RATE,600); // 指定比特率mFor***t.setInteger(MediaFor***t.KEY_FRAME_RATE,30); // 指定帧率mFor***t.setInteger(MediaFor***t.KEY_COLOR_FORMAT,mColorFor***t); // 指定编码器颜色格式 mFor***t.setInteger(MediaFor***t.KEY_I_FRAME_INTERVAL,10); // 指定关键帧时间间隔mVideoEncodec.configure(mFor***t,null,null,MediaCodec.CONFIGURE_FLAG_ENCODE);

以上代码是H.2***编码时的配置方法,CreateVideoFor***t ("video/avc ",***0,480)是“video/avc”类型(即H.2***)编码器的MediaFor***t对象,需要指定视频数据的宽度和高度。如果对音频数据进行编码和解码,则调用MediaFor***t的createaudiofor***t (string mime,int sample rate,int channel count)方法。除了一些配置参数,例如视频帧速率、音频采样率等。,这里我们需要重点关注
media for***t . key _ color _ for***t配置属性,该属性用于指示视频编码器的颜色格式。所选择的特定颜色格式与输入视频数据源的颜色格式相关。比如我们都知道相机预览捕捉到的图像流通常是NV21或者YV12,所以编码器需要指定相应的颜色格式;否则,编码后的数据可能会出现花屏、重叠、颜色失真等现象。Mediacinfo。代码能力。存储编码器支持的所有颜色格式。常见的颜色格式映射如下:

原始数据 编码器 NV12(YUV420sp) ———> COLOR_For***tYUV420PackedSemiPlanar NV21 ———-> COLOR_For***tYUV420SemiPlanar YV12(I420) ———-> COLOR_For***tYUV420Planar

配置好编***后,可以调用MediaCodec的start()方法,该方***调用低级native_start()方法启动编码器,调用低级ByteBuffer[] getBuffers(input)方法打开一系列输入输出缓冲区。

start()方法的源代码如下:

public final void start() { native_start(); synchronized(mBufferLock) { cacheBuffers(true /* input */); cacheBuffers(false /* input */); } }

(3)数据处理

MediaCodec支持两种模式的编***,即同步同步和异步。所谓同步模式是指编***数据的输入和输出是同步的,编***只有在处理完输出后才会再次接收输入的数据。但是,异步编***数据的输入和输出是异步的,编***不会等待输出数据被处理后再接收输入数据。这里,我们主要介绍同步编码和解码,因为我们大量使用这种方法。我们知道,当编***启动时,每个编***都会有一组输入输出缓冲区,但这些缓冲区暂时无法使用。只有通过MediaCodec的
dequeue input buffer/dequeue output buffer方法,才能对输入输出缓冲区进行授权,并且这些缓冲区可以通过返回的ID进行操作。让我们通过官方提供的代码进行扩展分析:

MediaCodec codec = MediaCodec.createByCodecName(name); codec.configure(for***t, …); MediaFor***t outputFor***t = codec.getOutputFor***t(); // 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); MediaFor***t bufferFor***t = codec.getOutputFor***t(outputBufferId); // option A // bufferFor***t is identical to outputFor***t // 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 for***t. // Can ignore if using getOutputFor***t(outputBufferId) outputFor***t = codec.getOutputFor***t(); // option B } } codec.stop(); codec.release();

从上面的代码来看,当编***启动时,它会输入一个for(;;)循环,这是一个无限循环,以便从编***的输入缓冲池中连续获得包含数据的缓冲区,然后从输出缓冲池中获得编***的输出数据。

本文来自笑醉生梦投稿,不代表舒华文档立场,如若转载,请注明出处:https://www.chinashuhua.cn/24/549013.html

打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
() 0
上一篇 05-16
下一篇 05-16

相关推荐

  • 超级解码器是什么 完美解码播放器安装步骤

    织女星G1定位个人第一次接触AURALiC(音韵学)的产品是在2015年左右。当时因为我的工作,一个VEGA***长期驻扎在Hi-Fi杂志的试听室,很长一段时间成为我们写评测文章的参***。AURALiC创始人王先生认为,VEGA应该是全球获奖最多的音频***产品。它不仅是一款有音有韵的名牌产品,也

    2023-07-28 19:33:01
    637 0
  • 耳放和解码器的区别有什么 解码耳放一体机推荐

    山M30可以算是最近推出的最特别最有创意的“DAP”了。之所以用DAP,是因为M30虽然是内置电池的“便携”设计,但主要是用稳定的线性电源来提升音质,3kg的重量级尺寸更适合桌面作为解码放大器。最特别的是模块化的机身设计。DAC,电子管(真空管/胆管)甚至安卓主机和电源都可以

    2023-07-16 01:00:01
    285 0
  • 音视频解码器哪个牌子好 音频解码器品牌排行

    音频“***”中最核心、重要的器件,无非就是“解码”(DAC,数模转换)芯片了,大家常常很关注音频DAC芯片的选用,也热衷于对其优劣的讨论。本文尝试对当前最优秀的高端音频DAC芯片的结构、技术和性能等做简单介绍,作一个排名,以供大家参考。尽管如此,任何一个优质的音频D

    2023-07-06 14:00:01
    757 0
  • 终极解码器怎么用 解码器的使用方法步骤

    在3000以内的价位,应该是唯一搭载AK4499芯片的***。而且用HD800也很少看到这样的有声解码。自从玩了HD800,感觉森海旗舰真的很难伺候:一方面是出了名的难开,不容易发出好的声音。另一方面,能匹配HD800,操控和音质都不错的前端设备投入太多;在折腾HD800的过程中,我先后换

    2023-06-15 12:54:01
    518 0

评论列表

联系我们

在线咨询: QQ交谈

邮件:admin@qq.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信