在这篇文章中,我使用H.264
作为一个例子,但解决方案可以扩展以支持其他编解码器,例如MPEG-4
, VC-1
, VP8
等等。有两种可能的解决方案可以解决您的问题,我在下面列出了它们,每种方案都有自己的优点和缺点,可以帮助您做出明智的决定。
解决方案1:扩展编解码器以支持新模式
In JellyBean
,可以注册相同的OMX
具有相同的组件MIME
类型为 2 个不同的组件名称,即,OMX.ABC.XYZ
and OMX.ABC.XYZ.secure
。前者用于正常播放,是更常用的组件。当解析器即使用后者时MediaExtractor
表明存在安全内容. In OMXCodec::Create
, after findMatchingCodecs
返回一个编解码器列表,我们可以观察选择的选项.secure
组件为here.
应遵循的步骤:
在您的平台中,使用一些新扩展注册另一个组件,例如OMX.H264.DECODER.decrypt
或类似的东西。仅需要更改media_codecs.xml
。是注册一个新的工厂方法还是拥有一个通用的工厂方法是你的选择。
从解析器中,当您遇到特定用例时,设置一个新标志,例如kKeyDecryptionRequired
。为此,您必须在中定义一个新标志Metadata.h以及相应的怪癖OMXCodec.h.
修改OMXCodec::create
方法附加一个.decrypt
后缀类似于.secure
后缀如上图。
随着所有的变化OMXCodec
, Metadata
, MediaExtractor
模块,您只需重建libstagefright.so
并在您的平台上替换相同的内容。
瞧!您的集成应该已完成。现在是组件内部的主要挑战。作为组件实现的一部分,您应该能够区分普通组件创建和.decrypt
组件创建。
从运行时的角度来看,假设您的组件知道它是一个.decrypt
组件与否,你可以处理decryption
作为OMX_EmptyThisBuffer
调用,您可以在其中解密数据,然后将其传递给底层编解码器。
Pros:易于集成、Android 框架变化最小、可扩展到其他编解码器、无新内容MIME
需要类型注册。
Cons:您需要跟踪 Android 的未来修订,特别是新的怪癖、标志和选择.decrypt
扩大。如果谷歌决定采用类似的东西,你将不得不相应地调整/修改你的解决方案。
解决方案 2:注册新的 MIME 类型
从您的问题来看,尚不清楚您是否能够定义MIME
无论是否键入,因此,为了清楚起见,我将捕获这些步骤。
应遵循的步骤:
注册一个新的MIME
键入MediaDefs
如图所示here。例如,您可以雇用一个新的MIME
输入为const char *MEDIA_MIMETYPE_VIDEO_AVC_ENCRYPT = "video/avc-encrypt";
使用此更新注册您的新组件MIME
输入media_codecs.xml
。请注意,您必须确保组件的怪癖也得到相应的处理。
In OMXCodec::setVideoOutputFormat
方法实现,您将必须引入处理新方法的支持MIME
键入如图所示H.264
here。请注意,您将必须处理类似的更改OMXCodec
以支持新的MIME
type.
In MediaExtractor
,你必须发出信号MIME
类型为video
使用新定义的类型进行跟踪。通过这些更改,您的组件将被选择并创建。
However,挑战仍然存在:在哪里执行解密?为此,您也可以采用与上一节中描述的相同的解决方案,即处理相同的部分OMX_EmptyThisBuffer
call.
Pros:没有我能想到的..
Cons:首先,解决方案不可扩展。您将不得不不断添加新的MIME
类型并不断修改Stagefright
框架。接下来,变化OMXCodec
将需要相应的改变MediaExtractor
。因此,即使您最初的重点是MP4
extractor,如果您希望将解决方案扩展到其他容器格式,例如AVI
, MKV
,您将必须包括对新的支持MIME
这些提取器中的类型。
Lastly,一些笔记。
作为首选解决方案,我推荐解决方案 1,因为它简单易行。
我没接触过ACodec
基于编解码器的实现。然而,我确实认为解决方案 1 将是一个更容易实施的解决方案,即使将来需要这样的支持。
如果您不修改OMX
核心,你不应该要求修改libstagefrighthw.so
。仅供参考,这通常由供应商作为其供应商特定模块的一部分来实现,如下所示vendor/<xyz>/hardware/...
。您需要向您的平台提供商核实其来源libstagefrighthw.so
.