我是靠谱客的博主 勤奋长颈鹿,最近开发中收集的这篇文章主要介绍安卓硬解MediaCodec主要api,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

文章目录

        • 1,获得输入数据inIndex
        • 2,获取当期buffer,然后往buffer里填充数据
        • 3,通知MediaCodec开始解码,这个执行之后,通过dequeueInputBuffer获取解码成功返回的数据
        • 4,从MediaCodec取解码后的数据(实际拿到的是一个Index),超时单位是微秒
        • 5,渲染到界面上

1,获得输入数据inIndex

/**
* Returns the index of an input buffer to be filled with valid data
* or -1 if no such buffer is currently available.
* This method will return immediately if timeoutUs == 0, wait indefinitely
* for the availability of an input buffer if timeoutUs < 0 or wait up
* to "timeoutUs" microseconds if timeoutUs > 0.
* @param timeoutUs The timeout in microseconds, a negative timeout indicates "infinite".
* @throws IllegalStateException if not in the Executing state,
*
or codec is configured in asynchronous mode.
* @throws MediaCodec.CodecException upon codec error.
*/
public final int dequeueInputBuffer(long timeoutUs)

2,获取当期buffer,然后往buffer里填充数据

/**
* Returns a {@link java.nio.Buffer#clear cleared}, writable ByteBuffer
* object for a dequeued input buffer index to contain the input data.
*
* After calling this method any ByteBuffer or Image object
* previously returned for the same input index MUST no longer
* be used.
*
* @param index The index of a client-owned input buffer previously
*
returned from a call to {@link #dequeueInputBuffer},
*
or received via an onInputBufferAvailable callback.
*
* @return the input buffer, or null if the index is not a dequeued
* input buffer, or if the codec is configured for surface input.
*
* @throws IllegalStateException if not in the Executing state.
* @throws MediaCodec.CodecException upon codec error.
*/
@Nullable
public ByteBuffer getInputBuffer(int index)

3,通知MediaCodec开始解码,这个执行之后,通过dequeueInputBuffer获取解码成功返回的数据

/**
* @param index The index of a client-owned input buffer previously returned
*
in a call to {@link #dequeueInputBuffer}.
* @param offset The byte offset into the input buffer at which the data starts.
* @param size The number of bytes of valid input data.
* @param presentationTimeUs The presentation timestamp in microseconds for this
*
buffer. This is normally the media time at which this
*
buffer should be presented (rendered). When using an output
*
surface, this will be propagated as the {@link
*
SurfaceTexture#getTimestamp timestamp} for the frame (after
*
conversion to nanoseconds).
* @param flags A bitmask of flags
*
{@link #BUFFER_FLAG_CODEC_CONFIG} and {@link #BUFFER_FLAG_END_OF_STREAM}.
*
While not prohibited, most codecs do not use the
*
{@link #BUFFER_FLAG_KEY_FRAME} flag for input buffers.
* @throws IllegalStateException if not in the Executing state.
* @throws MediaCodec.CodecException upon codec error.
* @throws CryptoException if a crypto object has been specified in
*
{@link #configure}
*/
public final void queueInputBuffer(
int index,
int offset, int size, long presentationTimeUs, int flags)
throws CryptoException 

4,从MediaCodec取解码后的数据(实际拿到的是一个Index),超时单位是微秒

/**
* Dequeue an output buffer, block at most "timeoutUs" microseconds.
* Returns the index of an output buffer that has been successfully
* decoded or one of the INFO_* constants.
* @param info Will be filled with buffer meta data.
* @param timeoutUs The timeout in microseconds, a negative timeout indicates "infinite".
* @throws IllegalStateException if not in the Executing state,
*
or codec is configured in asynchronous mode.
* @throws MediaCodec.CodecException upon codec error.
*/
@OutputBufferInfo
public final int dequeueOutputBuffer(
@NonNull BufferInfo info, long timeoutUs) 

这里返回的index可能有如下值:

int outIndex = codec.dequeueOutputBuffer(info, 10000);
//从MediaCodec取解码后的数据(实际拿到的是一个Index),超时单位是微秒
//
switch (outIndex) {
/**
* The output format has changed, subsequent data will follow the new
* format. {@link #getOutputFormat()} returns the new format.
Note, that
* you can also use the new {@link #getOutputFormat(int)} method to
* get the format for a specific output buffer.
*/
case MediaCodec.INFO_OUTPUT_FORMAT_CHANGED:
//视频格式MediaFormat发生变化了
Log.i(TAG, "run: new format: "+codec.getOutputFormat());
break;
/**
* If a non-negative timeout had been specified in the call
* to {@link #dequeueOutputBuffer}, indicates that the call timed out.
*/
case MediaCodec.INFO_TRY_AGAIN_LATER:
//解码数据未准备好等原因导致dequeueOutputBuffer执行超时
Log.i(TAG, "run: try later");
break;
case MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED:
//@deprecated This return value can be ignored as {@link #getOutputBuffers} has been deprecated.
Log.i(TAG, "run: output buffer changed");
break;
default:
codec.releaseOutputBuffer(outIndex, true);
//让MediaCodec将这一帧输出到Surface上
break;
}

5,渲染到界面上

/**
* If you are done with a buffer, use this call to return the buffer to the codec
* or to render it on the output surface. If you configured the codec with an
* output surface, setting {@code render} to {@code true} will first send the buffer
* to that output surface. The surface will release the buffer back to the codec once
* it is no longer used/displayed.
*
* Once an output buffer is released to the codec, it MUST NOT
* be used until it is later retrieved by {@link #getOutputBuffer} in response
* to a {@link #dequeueOutputBuffer} return value or a
* {@link Callback#onOutputBufferAvailable} callback.
*
* @param index The index of a client-owned output buffer previously returned
*
from a call to {@link #dequeueOutputBuffer}.
* @param render If a valid surface was specified when configuring the codec,
*
passing true renders this output buffer to the surface.
* @throws IllegalStateException if not in the Executing state.
* @throws MediaCodec.CodecException upon codec error.
*/
public final void releaseOutputBuffer(int index, boolean render)

最后

以上就是勤奋长颈鹿为你收集整理的安卓硬解MediaCodec主要api的全部内容,希望文章能够帮你解决安卓硬解MediaCodec主要api所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(44)

评论列表共有 0 条评论

立即
投稿
返回
顶部