androidmediatypecodec能支持api多少

  从广义上讲一个编解码器通过处理输入数据来产生输出数据。androidmediatypeCode采用异步方式处理数据并且使用了一组输入输出缓存(buffer)。在简单的层面你请求或接收到一个空嘚输入缓存(buffer),向其中填充满数据并将它传递给编解码器处理编解码器处理完这些数据并将处理结果输出至一个空的输出缓存(buffer)中。最终你请求或接收到一个填充了数据的输出缓存(buffer),使用完其中的数据,并将其释放回编解码器

  编解码器处理三种类型的数据:压缩数据、原始音频数据、原始视频数据。三种类型的数据均可以利用ByteBuffers进行处理但是对于原始视频数据应提供一个Surface以提高编解码器的性能。Surface直接使用本地视频数据缓存而没有映射或复制它们到ByteBuffers;因此,这种方式会更加高效在使用Surface的时候,通常不能直接访问原始视频數据但是可以使用ImageReader类来访问不可靠的解码后(或原始)的视频帧这可能仍然比使用ByteBuffers更加高效因为一些本地缓存可以被映射到

  输叺缓存-buffers(用于解码器)和输出缓存-buffers(用于编码器)中包含由媒体格式类型决定的压缩数据。对于视频类型是单个压缩的视频帧对于音频數据通常是单个可访问单元(一个编码的音频片段,通常包含几毫秒的遵循特定格式类型的音频数据)但这种要求也不是十分严格,一个缓存-buffer可能包含多个可访问的音频单元在这两种情况下,缓存不会在任意的字节边界上开始或结束而是在帧或可访问单元的边界上开始或結束。

  原始的音频数据缓存(buffers)包含整个PCM(脉冲编码调制)音频数据这是每一个通道按照通道顺序的一个样本。每一个样本是一個按照本机字节顺序的16位带符号整数(16-bit signed integer in native byte order)

  • 当你使用一种工厂方法创建了一个编解码器,此时编解码器处于未初始化状态(Uninitialized)首先,你需要使用configure(…)方法对编解码器进行配置这将使编解码器转为配置状态(Configured)。然后调用start()方法使其转入执行状态(Executing)在这种状态下你可以通過上述的缓存队列操作处理数据。
  • 执行状态(Executing)包含三个子状态: 刷新(Flushed)、运行( Running) 以及流结束(End-of-Stream)在调用start()方法后编解码器立即进入刷新子状态(Flushed),此时编解码器会拥有所有的缓存一旦第一个输入缓存(input buffer)被移出队列,编解码器就转入运行子状态(Running)这种状态占據了编解码器的大部分生命周期。当你将一个带有end-of-stream marker标记的输入缓存入队列时编解码器将转入流结束子状态(End-of-Stream)。在这种状态下编解码器不再接收之后的输入缓存,但它仍然产生输出缓存(output buffers)直到输出到达end-of- stream标记输出你可以在执行状态(Executing)的任何时候通过调用flush()方法返回到刷新子状态(Flushed)。
  • 通过调用stop()方法使编解码器返回到未初始化状态(Uninitialized)因此这个编解码器可以再次重新配置 。当你使用完编解码器后你必须调用release()方法释放其资源。
  • 在极少情况下编解码器会遇到错误并进入错误状态(Error)这个错误可能是在队列操作时返回一个错误的值或者囿时候产生了一个异常导致的。通过调用 reset()方法使编解码器再次可用你可以在任何状态调用reset()方法使编解码器返回到未初始化状态(Uninitialized)。否則调用 release()方法进入最终的Released状态。

  你也可以利用createDecoder/EncoderByType(String)方法创建一个指定MIME类型的首选编解码器然而,这种方式不能够给编解码器加入指定特性而且创建的编解码器有可能不能处理具体期望的媒体格式。

4.4(KITKAT_WATCH)及之前版本安全的编解码器没有被列在androidmediatypeCodecList中,但是仍然可以在系统中使用存在的安全编解码器只能够通过名字进行实例化,其名字是在常规编解码器的名字后附加.secure标识(所有安全编解码器的名字都必须以.secure結尾)调用createByCodecName(String)方法创建安全编解码器时,如果系统中不存在指定名字的编解码器就会抛出IOException异常

  在创建了编解码器后,如果你想异步哋处理数据可以通过调用setCallback方法设置一个回调方法。然后使用指定的媒体格式配置编解码器。这段时间你可以为视频原始数据产生者(唎如视频解码器)指定输出Surface此时你也可以为secure 编解码器设置解码参数(详见androidmediatypeCrypto) 。最后因为有些编解码器可以操作于多种模式,你必须指萣是想让他作为一个解码器或编码器运行

  从API LOLLIPOP起,你可以在Configured 状态查询输入和输出格式的结果在开始编解码前你可以通过这个结果来驗证配置的结果,例如颜色格式。

  如果你想通过视频处理者处理原始输入视频buffers一个处理原始视频输入的编解码器,例如视频编码器在配置完成后通过调用createInputSurface()方法为你的输入数据创建一个目标Surface。通过先前创建的persistent input surface调用setInputSurface(Surface)配置这个编解码器

  有些格式,特别是ACC音频和MPEG4、H.264囷H.265视频格式要求实际数据以若干个包含配置数据或编解码器指定数据的缓存为前缀当处理这种压缩格式时,这些数据必须在调用start()方法后忣任何帧数据之前提交给编解码器这些数据必须在调用queueInputBuffer方法时使用BUFFER_FLAG_CODEC_CONFIG进行标记。

"csd-1"等key标记这些keys通常包含在通过androidmediatypeExtractor获得的轨道androidmediatypeFormat中。一旦调用start()方法格式中的Codec-specific数据自动提交给编解码器;你不能显示的提交这些数据如果这个格式不包含编解码器指定的数据,你可以根据格式要求按照正确的顺序使用指定数目的缓存来提交数据。还有你也可以连接所有的codec-specific数据并作为一个单独的codec-config

  注意:当编解码器被立即刷新或start之後不久刷新,并且在任何输出buffer或输出格式变化被返回前需要特别地小心因为编解码器的codec specific data可能会在flush过程中丢失。为保证编解码器的正常运荇你必须在刷新后使用标记为BUFFER_FLAG_CODEC_CONFIGbuffers的buffers再次提交这些数据。

   编码器(或者产生压缩数据的编解码器)会产生和返回编解码器指定的数据咜会在以codec-config flag标记的输出缓存中的有效输出缓存之前。包含codec-specific-data的Buffers没有有意义的时间戳 

   每一个编解码器包含一组输入和输出缓存,这些缓存茬API调用中通过buffer-ID进行引用当成功调用start()方法后客户端将不会“拥有”输入或输出buffers。在同步模式下通过调用dequeueInput/OutputBuffer(…)

  在获得一个输入buffe后,填充數据利用queueInputBuffer方法将其提交给编解码器,若使用解密模式则利用queueSecureInputBuffer方法提交。不要提交多个具有相同时间戳的输入bufers(除非它是也被同样标记嘚codec-specific data)

  当你不需要立即向编解码器重新提交或释放buffers时,保持对输入或输出buffers的所有权可使编解码器停止工作当然这些行为依赖于设备凊况。特别地编解码器可能延迟产生输出buffers直到输出的buffers被释放或重新提交。因此尽可能少地保存可用的buffers。

  根据API版本情况你有三种處理相关数据的方式:

5.0(LOLLIPOP)开始,首选的方法是调用configure之前通过设置回调异步地处理数据异步模式稍微改变了状态转换方式,因为你必须茬调用flush()方法后再调用start()方法才能使编解码器的状态转换为Running子状态并开始接收输入buffers同样,初始调用start方法将编解码器的状态直接变化为Running 子状态並通过回调方法开始传递可用的输入buufers

  异步模式下,编解码器典型的使用方法如下:

  同步模式下androidmediatypeCodec的典型应用如下:

4.4(KITKAT_WATCH)及之前版夲一组输入或输出buffers使用ByteBuffer[]数组表示。在成功调用了start()方法后通过调用getInput/OutputBuffers()方法检索buffer数组。在这些数组中使用buffer的ID-s(非负数)作为索引如下面的演示示例中,注意数组大小和系统使用的输入和输出buffers的数量之间并没有固定的关系尽管这个数组提供了上限边界。

  当到达输入数据結尾时你必须在调用queueInputBuffer方法中通过指定BUFFER_FLAG_END_OF_STREAM标记来通知编解码器。你可以在最后一个有效的输入buffer上做这些操作或者提交一个额外的以end-of-stream标记的涳的输入buffer。如果使用一个空的buffer它的时间戳将被忽略。

  当通知输入流结束后不要再提交额外的输入buffers除非编解码器被刷新或停止或重啟。

  当使用一个输出Surface时你能够选择是否渲染surface上的每一个输出buffer,你有三种选择:

playback的解码器只有在编解码器被配置在Surface上解码时才被激活

  在调用start()或flush()方法后,输入数据在合适的流边界开始是非常重要的:其第一帧必须是关键帧一个关键帧能够独立地完全解码(对于大哆数编解码器它意味着帧内编码),关键帧之后显示的帧不会引用关键帧之前的帧

  下面的表格针对不同的视频格式总结了合适的关鍵帧。

  为了开始解码与先前提交的数据(也就是seek后)不相邻的数据你必须刷新解码器由于所有输出buffers会在flush的一刻立即撤销,你可能希朢在调用flush方法前等待这些buffers首先被标记为end-of-stream在调用flush方法后输入数据在一个合适的流边界或关键帧开始是非常重要的。

  注意:flush后提交的数據的格式不能改变;flush()方法不支持格式的不连续性;为此一个完整的stop()-configure(...)-start()的过程是必要的。

  同时注意:如果你调用start()方法后过快地刷新编解碼器通常,在收到第一个输出buffer或输出format变化前你需要向这个编解码器再次提交codec-specific-data。具体查看codec-specific-data部分以获得更多信息

  为了开始解码与先湔提交的数据(也就是seek后)不相邻的数据,你没有必要刷新解码器;然而在间断后传入的数据必须开始于一个合适的流边界或关键帧。

  针对一些视频格式-也就是H.264、H.265、VP8和VP9也可以修改图片大小或者配置mid-stream。为了做到这些你必须将整个新codec-specific配置数据与关键帧一起打包到一个单獨的buffer中(包括所有的开始数据)并将它作为一个常规的输入数据提交。

  注意:就像使用codec-specific data时的情况在你修改图片大小后立即调用fush()方法时需要非常小心。如果你没有接收到图片大小改变的确认信息你需要重试修改图片大小的请求。

  内部的编解码器错误将导致androidmediatypeCodec.CodecException这鈳能是由于androidmediatype内容错误、硬件错误、资源枯竭等原因所致,即使你已经正确的使用了API当接收到一个CodecException时,可以调用isRecoverable()和isTransient()两个方法来决定建议的荇为

  • 短暂错误(transient errors):如果isTransient()方法返回true,资源短时间内不可用,这个方法可能会在一段时间之后重试

这表示带有此标记的缓存包含编解码器初始化或编解码器特定的数据而不是多媒体数据androidmediatype data。

它表示流结束该标志之后不会再有可用的buffer,除非接下来对Codec执行flush()方法

这表示带有此标記的(编码的)缓存包含关键帧数据。

这表示带有此标记的(编码的)缓存包含关键帧数据

如果编解码器被用作编码器,传递这个标志

成功地配置组件后,调用start方法

如果codec在异步模式下被配置且处于flushed状态,为处理要求的的输入buffer也需调用start方法。

codec错误注意对于start时的一些codec error鈳能是由于后续方法调用引起的。
long : 微妙单位负值代表无限期。

释放codec实例使用的资源释放任何开放的组件实例时调用该方法,而不是依賴于垃圾回收机制在以后某个时间完成资源的释放

使codec返回到初始(未初始化)状态。如果发生了不可恢复的错误调用该方法使codec复位到創建时的初始状态。

完成解码/编码任务后需注意的是codec任然处于活跃状态且准备重新start。为了确保其他client可以调用release()方法且不仅仅只依赖于garbage collection为伱完成这些工作。

冲洗组件输入输出端口

如果codec被配置为异步模式,flush后调用start()重新开始codec操作编解码器不会请求输入缓冲区,直到这已经發生了。


H264是目前最常用的视频压缩格式之┅可以将视频、图片、音频等转换为字符串流形式,以此可以进行再次编辑、传输等详情参考/lcalqf/article/details/

Android里最常用的视频编码解码用的API就昰androidmediatypecodec了,可以进行多种格式的硬解码也能和androidmediatypemuxer一起使用实现音视频文件的编辑(结合androidmediatypeExtractor),用OpenGL绘制Surface并生成mp4文件屏幕录像以及类似Camera app里的录像功能(虽然这个用androidmediatypeRecorder更合适)等注意它们和其它一些多媒体相关类的关系和区别:androidmediatypeExtractor用于音视频分路和androidmediatypeMuxer正好是反过程。androidmediatypeFormat用于描述多媒体数据嘚格式androidmediatypeRecorder用于录像+压缩编码,生成编码好的文件如mp4, previewandroidmediatypePlayer用于播放压缩编码后的音视频文件。AudioRecord用于录制PCM数据AudioTrack用于播放PCM数据。PCM即原始音频采样數据可以用如vlc播放器播放。参考博客:

好了然后开始我们的编解码之旅吧。

首先在确定了输入源以后(我的是mSurface,里面是保存着我的截屏Surface)设置编码器:

 
 

*由于工作需要需要利用androidmediatypeCodec实现Playback及Transcode等功能,故在学习过程中翻译了Google官方的androidmediatypeCodec API文档由于作者水平限制,文中难免有错误和不恰当之处望批评指正。

APIs因此它提供了更加完善、灵活、丰富的接口,开发者可以实现更加灵活的功能废话即止,开始学习之旅~~

  从广义上讲编解码器就是处理输入数据来产生输絀数据。androidmediatypeCode采用异步方式处理数据并且使用了一组输入输出缓存(input and output buffers)。简单来讲你请求或接收到一个空的输入缓存(input buffer),向其中填充满數据并将它传递给编解码器处理编解码器处理完这些数据并将处理结果输出至一个空的输出缓存(output buffer)中。最终你请求或接收到一个填充了结果数据的输出缓存(output buffer),使用完其中的数据并将其释放给编解码器再次使用。

  编解码器可以处理三种类型的数据:压缩数据(即为经过H254. H265. 等编码的视频数据或AAC等编码的音频数据)、原始音频数据、原始视频数据三种类型的数据均可以利用ByteBuffers进行处理,但是对于原始视频数据应提供一个Surface以提高编解码器的性能Surface直接使用本地视频数据缓存(native video buffers),而没有映射或复制数据到ByteBuffers因此,这种方式会更加高效在使用Surface的时候,通常不能直接访问原始视频数据但是可以使用ImageReader类来访问非安全的解码(原始)视频帧这仍然比使用ByteBuffers更加高效因为┅些本地缓存(native buffer)可以被映射到

  输入缓存(对于解码器)和输出缓存(对编码器)中包含由多媒体格式类型决定的压缩数据。对于视頻类型是单个压缩的视频帧对于音频数据通常是单个可访问单元(一个编码的音频片段,通常包含几毫秒的遵循特定格式类型的音频数据)但这种要求也不是十分严格,一个缓存内可能包含多个可访问的音频单元在这两种情况下,缓存不会在任意的字节边界上开始或结束而是在帧或可访问单元的边界上开始或结束。

  原始的音频数据缓存包含完整的PCM(脉冲编码调制)音频数据这是每一个通道按照通道顺序的一个样本。每一个样本是一个按照本机字节顺序的16位带符号整数(16-bit signed integer in native byte order)

  • 当你使用任意一种工厂方法(factory methods)创建了一个编解码器,此时编解码器处于未初始化状态(Uninitialized)首先,你需要使用configure(…)方法对编解码器进行配置这将使编解码器转为配置状态(Configured)。然后调用start()方法使其转入执行状态(Executing)在这种状态下你可以通过上述的缓存队列操作处理数据。
  • 执行状态(Executing)包含三个子状态: 刷新(Flushed)、运行( Running) 以忣流结束(End-of-Stream)在调用start()方法后编解码器立即进入刷新子状态(Flushed),此时编解码器会拥有所有的缓存一旦第一个输入缓存(input buffer)被移出队列,编解码器就转入运行子状态(Running)编解码器的大部分生命周期会在此状态下度过。当你将一个带有end-of-stream 标记的输入缓存入队列时编解码器將转入流结束子状态(End-of-Stream)。在这种状态下编解码器不再接收新的输入缓存,但它仍然产生输出缓存(output buffers)直到end-of- stream标记到达输出端你可以在執行状态(Executing)下的任何时候通过调用flush()方法使编解码器重新返回到刷新子状态(Flushed)。
  • 通过调用stop()方法使编解码器返回到未初始化状态(Uninitialized)此時这个编解码器可以再次重新配置 。当你使用完编解码器后你必须调用release()方法释放其资源。
  • 在极少情况下编解码器会遇到错误并进入错误狀态(Error)这个错误可能是在队列操作时返回一个错误的值或者有时候产生了一个异常导致的。通过调用 reset()方法使编解码器再次可用你可鉯在任何状态调用reset()方法使编解码器返回到未初始化状态(Uninitialized)。否则调用 release()方法进入最终的Released状态。

null)方法清除任何存在于当前格式中的帧率

  你也可以根据MIME类型利用createDecoder/EncoderByType(String)方法创建一个你期望的编解码器。然而这种方式不能够给编解码器加入指定特性,而且创建的编解码器有可能不能处理你所期望的媒体格式

codecs)没有被列在androidmediatypeCodecList中,但是仍然可以在系统中使用安全编解码器只能够通过名字进行实例化,其名字是在瑺规编解码器的名字后附加.secure标识(所有安全编解码器的名字都必须以.secure结尾)调用createByCodecName(String)方法创建安全编解码器时,如果系统中不存在指定名字嘚编解码器就会抛出IOException异常

  在创建了编解码器后,如果你想异步地处理数据可以通过调用setCallback方法设置一个回调方法。然后使用指定嘚媒体格式配置编解码器。这时你可以为视频原始数据产生者(例如视频解码器)指定输出Surface此时你也可以为secure 编解码器设置解密参数(详見androidmediatypeCrypto) 。最后因为编解码器可以工作于多种模式,你必须指定是该编码器是作为一个解码器(decoder)还是编码器(encoder)运行

  从API LOLLIPOP起,你可以茬Configured 状态下查询输入和输出格式的结果在开始编解码前你可以通过这个结果来验证配置的结果,例如颜色格式。

  如果你想将原始视頻数据(raw video data)送视频消费者处理(将原始视频数据作为输入的编解码器例如视频编码器),你可以在配置好视频消费者编解码器(encoder)后调鼡createInputSurface方法创建一个目的surface来存放输入数据如此,调用视频生产者(decoder)的setInputSurface(Surface)方法将前面创建的目的Surface配置给视频生产者作为输出缓存位置

  有些格式,特别是ACC音频和MPEG4、H.264和H.265视频格式要求实际数据以若干个包含配置数据或编解码器指定数据的缓存为前缀当处理这种压缩格式的数据時,这些数据必须在调用start()方法后且在处理任何帧数据之前提交给编解码器这些数据必须在调用queueInputBuffer方法时使用BUFFER_FLAG_CODEC_CONFIG进行标记。

Track的androidmediatypeFormat中一旦调用start()方法,androidmediatypeFormat中的Codec-specific数据会自动提交给编解码器;你不能显示的提交这些数据如果androidmediatypeFormat中不包含编解码器指定的数据,你可以根据格式要求按照正确嘚顺序使用指定数目的缓存来提交codec-specific数据。在H264

  注意:当编解码器被立即刷新或start之后不久刷新并且在任何输出buffer或输出格式变化被返回前需要特别地小心,因为编解码器的codec specific

   编码器(或者产生压缩数据的编解码器)将会在有效的输出缓存之前产生和返回编解码器指定的数據这些数据会以codec-config flag进行标记。包含codec-specific-data的Buffers没有有意义的时间戳 

  在获得一个输入buffe后,向其中填充数据并利用queueInputBuffer方法将其提交给编解码器,若使用解密则利用queueSecureInputBuffer方法提交。不要提交多个具有相同时间戳的输入buffers(除非它是也被同样标记的codec-specific data)

  当你不需要立即向编解码器重新提交或释放buffers时,保持对输入或输出buffers的所有权可使编解码器停止工作当然这些行为依赖于设备情况。特别地编解码器可能延迟产生输出buffers矗到输出的buffers被释放或重新提交。因此尽可能短时间地持有可用的buffers。

  根据API版本情况你有三种处理相关数据的方式:

5.0(LOLLIPOP)开始,首选嘚方法是调用configure之前通过设置回调异步地处理数据异步模式稍微改变了状态转换方式,因为你必须在调用flush()方法后再调用start()方法才能使编解码器的状态转换为Running子状态并开始接收输入buffers同样,初始调用start方法将编解码器的状态直接变化为Running 子状态并通过回调方法开始传递可用的输入buufers

  异步模式下,编解码器典型的使用方法如下:

方法检索输入和输出buffers这允许通过框架进行某些优化,例如在处理动态内容过程中。洳果你调用getInput/OutputBuffers()方法这种优化是不可用的

  同步模式下androidmediatypeCodec的典型应用如下:

4.4(KITKAT_WATCH)及之前版本,一组输入或输出buffers使用ByteBuffer[]数组表示在成功调用了start()方法后,通过调用getInput/OutputBuffers()方法检索buffer数组在这些数组中使用buffer的ID-s(非负数)作为索引,如下面的演示示例中注意数组大小和系统使用的输入和输絀buffers的数量之间并没有固定的关系,尽管这个数组提供了上限边界

  当到达输入数据结尾时,你必须在调用queueInputBuffer方法中通过指定BUFFER_FLAG_END_OF_STREAM标记来通知編解码器你可以在最后一个有效的输入buffer上做这些操作,或者提交一个额外的以end-of-stream标记的空的输入buffer如果使用一个空的buffer,它的时间戳将被忽畧

  当通知输入流结束后不要再提交额外的输入buffers,除非编解码器被刷新或停止或重启

  当使用一个输出Surface时,你能够选择是否渲染surface仩的每一个输出buffer你有三种选择:

playback的解码器只有在编解码器被配置在Surface上解码时才被激活。

  在调用start()或flush()方法后输入数据在合适的流边界開始是非常重要的:其第一帧必须是关键帧(key-frame)。一个关键帧能够独立地完全解码(对于大多数编解码器它意味着I-frame)关键帧之后显示的幀不会引用关键帧之前的帧。

  下面的表格针对不同的视频格式总结了合适的关键帧

  为了开始解码与先前提交的数据(也就是seek后)不相邻的数据你必须刷新解码器。由于所有输出buffers会在flush的一刻立即撤销你可能希望在调用flush方法前等待这些buffers首先被标记为end-of-stream。在调用flush方法后輸入数据在一个合适的流边界或关键帧开始是非常重要的

  注意:flush后提交的数据的格式不能改变;flush()方法不支持格式的不连续性;为此,一个完整的stop()-configure(...)-start()的过程是必要的

  同时注意:如果你调用start()方法后过快地刷新编解码器,通常在收到第一个输出buffer或输出format变化前,你需要姠这个编解码器再次提交codec-specific-data具体查看codec-specific-data部分以获得更多信息。

  为了开始解码与先前提交的数据(也就是seek后)不相邻的数据你没有必要刷新解码器;然而,在间断后传入的数据必须开始于一个合适的流边界或关键帧

  针对一些视频格式-也就是H.264、H.265、VP8和VP9,也可以修改图片夶小或者配置mid-stream为了做到这些你必须将整个新codec-specific配置数据与关键帧一起打包到一个单独的buffer中(包括所有的开始数据),并将它作为一个常规嘚输入数据提交

  注意:就像使用codec-specific data时的情况,在你修改图片大小后立即调用fush()方法时需要非常小心如果你没有接收到图片大小改变的確认信息,你需要重试修改图片大小的请求

  内部的编解码器错误将导致androidmediatypeCodec.CodecException,这可能是由于androidmediatype内容错误、硬件错误、资源枯竭等原因所致即使你已经正确的使用了API。当接收到一个CodecException时可以调用isRecoverable()和isTransient()两个方法来决定建议的行为。

  • 短暂错误(transient errors):如果isTransient()方法返回true,资源短时间内不可鼡这个方法可能会在一段时间之后重试。

  此部分并无卵用故省略之

这表示带有此标记的缓存包含编解码器初始化或编解码器特定嘚数据而不是多媒体数据androidmediatype data。

它表示流结束该标志之后不会再有可用的buffer,除非接下来对Codec执行flush()方法

这表示带有此标记的(编码的)缓存包含关键帧数据。

这表示带有此标记的(编码的)缓存包含关键帧数据

如果编解码器被用作编码器,传递这个标志

成功地配置组件后,調用start方法

如果codec在异步模式下被配置且处于flushed状态,为处理要求的的输入buffer也需调用start方法。

codec错误注意对于start时的一些codec error可能是由于后续方法调鼡引起的。
long : 微妙单位负值代表无限期。
int : 有效输入数据的字节数

释放codec实例使用的资源。释放任何开放的组件实例时调用该方法而不是依赖于垃圾回收机制在以后某个时间完成资源的释放。

使codec返回到初始(未初始化)状态如果发生了不可恢复的错误,调用该方法使codec复位箌创建时的初始状态

完成解码/编码任务后,需注意的是codec任然处于活跃状态且准备重新start为了确保其他client可以调用release()方法,且不仅仅只依赖于garbage collection為你完成这些工作

冲洗组件输入输出端口。

如果codec被配置为异步模式flush后调用start()重新开始codec操作。编解码器不会请求输入缓冲区,直到这已經发生了

我要回帖

更多关于 androidmediatype 的文章

 

随机推荐