【六】Android MediaPlayer整体架构源码分析 -【start请求播放处理流程】【Part 4】【06】

承接上一章节分析:【六】Android MediaPlayer整体架构源码分析 -【start请求播放处理流程】【Part 4】【05】
本系列文章分析的安卓源码版本:【Android 10.0 版本】

【此章节小节编号就接着上一章节排列】
8.3.2.4.2、useGraphicBuffer_l(portIndex, omxBuffer.mGraphicBuffer, buffer)实现分析:
使用图形Buffer
从下面方法上英文注释非常明确该方法的使用提示,它只是个向后兼容方法,一旦OMX实现改变,该方法可以被移除并重命名为useGraphicBuffer2来使用。

// [frameworks/av/media/libstagefright/omx/OMXNodeInstance.cpp]

// XXX: This function is here for backwards compatibility.  Once the OMX
// implementations have been updated this can be removed and useGraphicBuffer2
// can be renamed to useGraphicBuffer.
status_t OMXNodeInstance::useGraphicBuffer_l(
        OMX_U32 portIndex, const sp<GraphicBuffer>& graphicBuffer,
        IOMX::buffer_id *buffer) {
   
    if (graphicBuffer == NULL || buffer == NULL) {
   
        ALOGE("b/25884056");
        return BAD_VALUE;
    }

    // 首先检查是否使用了媒体元数据模式,我们可以在支持元数据meta的设备上运行一个实验来模拟遗留行为(预分配缓冲区)。
    // First, see if we're in metadata mode. We could be running an experiment to simulate
    // legacy behavior (preallocated buffers) on devices that supports meta.
    if (mMetadataType[portIndex] != kMetadataBufferTypeInvalid) {
   
    	// 使用了媒体元数据模式时,使用图形Buffer与元数据
    	// 见下面的分析
        return useGraphicBufferWithMetadata_l(
                portIndex, graphicBuffer, buffer);
    }

    // 该图形Buffer模式下,必须开启了该模式
    if (!mGraphicBufferEnabled[portIndex]) {
   
        // Report error if this is not in graphic buffer mode.
        ALOGE("b/62948670");
        android_errorWriteLog(0x534e4554, "62948670");
        return INVALID_OPERATION;
    }

    // See if the newer version of the extension is present.
    OMX_INDEXTYPE index;
    // 检查底层组件是否支持该扩展属性功能新版本,并返回其参数索引
    // 备注:在所有软编解码器组件中都不支持该属性,该扩展属性功能一般为硬编解码器支持
    if (OMX_GetExtensionIndex(
            mHandle,
            const_cast<OMX_STRING>("OMX.google.android.index.useAndroidNativeBuffer2"),
            &index) == OMX_ErrorNone) {
   
        // 支持该扩展属性时
        // 使用graphicBuffer
        // 见下面分析
        return useGraphicBuffer2_l(portIndex, graphicBuffer, buffer);
    }
	
	// 该扩展属性功能在软编解码器中也不支持,通常硬Codec可能支持
    OMX_STRING name = const_cast<OMX_STRING>(
        "OMX.google.android.index.useAndroidNativeBuffer");
    OMX_ERRORTYPE err = OMX_GetExtensionIndex(mHandle, name, &index);
    if (err != OMX_ErrorNone) {
   
        CLOG_ERROR(getExtensionIndex, err, "%s", name);
        return StatusFromOMXError(err);
    }

    // 同上一样处理
    BufferMeta *bufferMeta = new BufferMeta(graphicBuffer, portIndex);

    OMX_BUFFERHEADERTYPE *header;

    OMX_VERSIONTYPE ver;
    ver.s.nVersionMajor = 1;
    ver.s.nVersionMinor = 0;
    ver.s.nRevision = 0;
    ver.s.nStep = 0;
    // 创建该扩展属性支持的参数结构对象
    UseAndroidNativeBufferParams params = {
   
        sizeof(UseAndroidNativeBufferParams), ver, portIndex, bufferMeta,
        &header, graphicBuffer,
    };

    // 将该扩展属性参数结构配置信息设置给底层组件更新
    err = OMX_SetParameter(mHandle, index, &params);

    if (err != OMX_ErrorNone) {
   
        CLOG_ERROR(setParameter, err, "%s(%#x): %s:%u meta=%p GB=%p", name, index,
                portString(portIndex), portIndex, bufferMeta, graphicBuffer->handle);

        delete bufferMeta;
        bufferMeta = NULL;

        *buffer = 0;

        return StatusFromOMXError(err);
    }

    CHECK_EQ(header->pAppPrivate, bufferMeta);

    // 同样是创建新Buffer id和添加到活动buffer队列中
    *buffer = makeBufferID(header);

    addActiveBuffer(portIndex, *buffer);
    CLOG_BUFFER(useGraphicBuffer, NEW_BUFFER_FMT(
            *buffer, portIndex, "GB=%p", graphicBuffer->handle));
    return OK;
}

useGraphicBufferWithMetadata_l(portIndex, graphicBuffer, buffer)实现分析:
使用了媒体元数据模式时,使用图形Buffer与元数据。该方法只处理输出端口buffer

// [frameworks/av/media/libstagefright/omx/OMXNodeInstance.cpp]
status_t OMXNodeInstance::useGraphicBufferWithMetadata_l(
        OMX_U32 portIndex, const sp<GraphicBuffer> &graphicBuffer,
        IOMX::buffer_id *buffer) {
   
    // 必须是输出端口索引,否则失败
    if (portIndex != kPortIndexOutput) {
   
        return BAD_VALUE;
    }

    // 必须是这两种媒体元数据Buffer类型,否则失败
    if (mMetadataType[portIndex] != kMetadataBufferTypeGrallocSource &&
            mMetadataType[portIndex] != kMetadataBufferTypeANWBuffer) {
   
        return BAD_VALUE;
    }

    // 然后使用该Buffer处理,见此前分析
    status_t err = useBuffer_l(portIndex, NULL, NULL, buffer);
    if (err != OK) {
   
        return err;
    }

    // useBuffer_l分配Buffer header头信息成功时,查询Buffer Header头信息结构对象指针
    // 见下面分析
    OMX_BUFFERHEADERTYPE *header = findBufferHeader(*buffer, portIndex);

    // 更新图形Buffer中的元数据
    // 见下面分析
    return updateGraphicBufferInMeta_l(portIndex, graphicBuffer, *buffer, header);
}

findBufferHeader(*buffer, portIndex)实现分析:
useBuffer_l分配Buffer header头信息成功时,查询Buffer Header头信息结构对象指针

// [frameworks/av/media/libstagefright/omx/OMXNodeInstance.cpp]
OMX_BUFFERHEADERTYPE *OMXNodeInstance::findBufferHeader(
        IOMX::buffer_id buffer, OMX_U32 portIndex) {
   
    if (buffer == 0) {
   
        return NULL;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值