简体   繁体   English

让QualComm编码器通过MediaCodec API工作

[英]Getting QualComm encoders to work via MediaCodec API

I am trying to do hardware encoding (avc) of NV12 stream using Android MediaCodec API. 我正在尝试使用Android MediaCodec API对NV12流进行硬件编码(avc)。

When using OMX.qcom.video.encoder.avc, resolutions 1280x720 and 640x480 work fine, while the others (ie 640x360, 320x240, 800x480) produce output where chroma component seems shifted (please see snapshot ). 使用OMX.qcom.video.encoder.avc时,分辨率1280x720和640x480工作正常,而其他(即640x360,320x240,800x480)产生输出,其中色度分量似乎移位(请参阅快照 )。

I have double-checked that the input image is correct by saving it to a jpeg file. 我通过将输入图像保存到jpeg文件来仔细检查输入图像是否正确。 This problem only occurs on QualComm devices (ie Samsung Galaxy S4). 此问题仅发生在QualComm设备(即三星Galaxy S4)上。

Anyone has this working properly? 任何人都有这个正常工作? Any additional setup / quirks necessary? 还需要任何额外的设置/怪癖吗?

Decoder(MediaCodec) has its MediaFormat, it can be received using getOutputFormat . 解码器(MediaCodec)有它的MediaFormat,它可以使用getOutputFormat接收。 Returned instance can be printed to log. 返回的实例可以打印到日志。 And there you can see some useful information. 在那里你可以看到一些有用的信息。 For example in your case value like "slice-height" could be useful. 例如,在您的情况下,像“slice-height”这样的值可能很有用。 I suspect that it is equal to height for 1280x720 and 640x480 and differs for other resolutions. 我怀疑它等于1280x720和640x480的高度,并且与其他分辨率不同。 Probably you should use this value to get chroma offset. 可能你应该使用这个值来获得色度偏移。

Yep, the OMX.qcom.video.encoder.avc does that but not on all devices/android version. 是的,OMX.qcom.video.encoder.avc可以做到这一点但不是在所有设备/ android版本上。 On my Nexus 4 with Android 4.3 the encoder works fine, but not on my S3 (running 4.1) 在我的带有Android 4.3的Nexus 4上,编码器工作正常,但不在我的S3上(运行4.1)

The solution for an S3 running 4.1 with the OMX.qcom.video.encoder.avc (it seems that some S3 have another encoder) is to add 1024 bytes just before the Chroma pane. 使用OMX.qcom.video.encoder.avc(似乎某些S3有另一个编码器)运行4.1的S3的解决方案是在Chroma窗格之前添加1024个字节。

// The encoder may need some padding before the Chroma pane
int padding = 1024;                     
if ((mWidth==640 && mHeight==480) || mWidth==1280 && mHeight==720) padding = 0;

// Interleave the U and V channel
System.arraycopy(buffer, 0, tmp, 0, mYSize); // Y
for (i = 0; i < mUVSize; i++) {
   tmp[mYSize + i*2 + padding] = buffer[mYSize + i + mUVSize]; // Cb (U)
   tmp[mYSize + i*2+1 + padding] = buffer[mYSize + i]; // Cr (V)
}
return tmp;

The camera is using YV12 and the encoder COLOR_FormatYUV420SemiPlanar. 相机正在使用YV12和编码器COLOR_FormatYUV420SemiPlanar。

Your snapshot shows the same kind of artefacts I had, you may need a similar hack for some resolutions, maybe with another padding length 你的快照显示了我所拥有的相同类型的文物,你可能需要类似的黑客攻击某些分辨率,可能需要另一个填充长度

You should also avoid resolutions that are not a multiple of 16, even on 4.3 apparently ( http://code.google.com/p/android/issues/detail?id=37769 ) ! 您还应该避免使用不是16的倍数的分辨率,即使在4.3上也是如此( http://code.google.com/p/android/issues/detail?id=37769 )!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM