Android提供了一种查询支持的编码配置文件的方法。但是在设置编码器时,我找不到指定要使用的所需配置文件的方法。
查找支持的个人资料/关卡对
在Android中使用MediaCodec
API,一旦选择了编码器组件,就可以调用getCodecInfo()
。这将返回一个MediaCodecInfo
对象,该对象提供有关正在使用的编解码器组件的详细信息。 getCapabilitiesForType()
返回一个CodecCapabilities
对象,详细说明了编解码器的功能。它包含一个CodecProfileLevel数组,详细说明了支持的配置文件和支持的级别。
尝试设置个人资料
我无法看到一个字段来设置MedieCodec
或MediaFormat
的个人资料。
KEY_AAC_PROFILE
有MediaFormat
,但在参考文献中明确指出这仅适用于aac音频。
在MediaCodec
中,有一种方法可以使用Bundle
将setParameters()
个额外参数传递给编解码器。这似乎没有通用文档,并且接受的参数在编解码器(不同设备)之间会有所不同。
背景
配置文件指定要使用的一组编码功能。简单的配置文件计算量较小,但通常牺牲了给定比特率的质量。级别指定给定配置文件支持的最大分辨率/比特率。我希望水平通常与解码能力相关联,但由于它描述的是必须实时运行的硬件编码器,因此具有最大设置对我来说很有意义。
META :(我最初有更多关于我提到的每个课程+功能的链接,但我不得不删除它们,因为我还没有让代表发布超过2个链接。)
答案 0 :(得分:4)
对于Android Kitkat设备,我们可以根据下面的代码片段将所需的AVC配置文件和级别设置为媒体格式(设置基准级别为1.3)。请在启动MediaCodec之前设置此项。
format.setInteger("profile",MediaCodecInfo.CodecProfileLevel.AVCProfileBaseline);
format.setInteger("level", MediaCodecInfo.CodecProfileLevel.AVCLevel13);
答案 1 :(得分:3)
MediaCodec API中没有明确的配置文件选择。 Codec将自行选择一个配置文件。它还将根据输入宽度/高度和帧速率数选择一个级别,但它可以选择一个高于配置所需最小级别的级别。
您可以在编码器编解码器中查询支持的级别,以查看它可能生成的配置文件,但您将无法选择首选的配置文件。编解码器很可能会选择它可以处理给定级别的最高配置文件,但不能保证。
答案 2 :(得分:2)
从Android 5.0开始,可以设置配置文件(SDK级别21)和级别(SDK级别23)。
http://developer.android.com/reference/android/media/MediaFormat.html#KEY_PROFILE http://developer.android.com/reference/android/media/MediaFormat.html#KEY_LEVEL
Haven尚未尝试过这些在实践中的效果。
答案 3 :(得分:0)
给定的AVC编码器可以忽略配置文件和级别提示。
为了确保AVC编码器选择了哪个配置文件和级别,您可以在启动后从其MediaFormat实时查询SPS(如初始格式更改事件期间)。
参见spec的第7节。
这张海报展示了从这些base64字符串中提取个人资料和关卡(请注意他!):
Can profile-level-id and sprop-parameter-sets be extracted from an RTP stream?
以下是Base64编码的SPS和PPS:
...
mIndex = mMediaEncoder.dequeueOutputBuffer(mBufferInfo, TIMEOUT);
// First buffer encoded is the NAL frame metadata
if (mIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED)
{
Log.i("PPS: "+getParameterSetAsString(mMediaEncoder, "csd-0");
Log.i("SPS: "+getParameterSetAsString(mMediaEncoder, "csd-1");
}
...
private String getParameterSetAsString(MediaCodec encoder, String csd)
{
MediaFormat mMediaFormat = encoder.getOutputFormat();
ByteBuffer ps = mMediaFormat.getByteBuffer(csd);
// The actual SPS and PPS byte codes
byte[] mPS = new byte[ps.capacity()-4];
ps.position(4);
ps.get(mPS,0,mPS.length);
//Covert to String
return Base64.encodeToString(mPS, 0, mPS.length, Base64.NO_WRAP);
}