I'm trying to implement HW-accelrated H264 video encoding on Android ICS 4.0.4. Since MediaCodec class is not available I have to use stagefright API. But when I put HardwareCodecsOnly flag, OMXCodec::Create always returns NULL.
If I call OMXCodec::findMatchingCodecs() with flag kHardwareCodecsOnly, I got following list:
- OMX.TI.DUCATI1.VIDEO.H264E
- OMX.qcom.7x30.video.encoder.avc
- OMX.qcom.video.encoder.avc
- OMX.TI.Video.encoder
- OMX.Nvidia.h264.encoder
- OMX.SEC.AVC.Encoder
so I guess it means that HW-encoding supported by hardware.
When I put no flags in OMXCodec::Create - codec created well, but I guess it is in software mode (btw, how can I check- which codec exactly was created?)
Browsing OMXCodec sources I've found interesting lines:
if (createEncoder) {
sp<MediaSource> softwareCodec =
InstantiateSoftwareEncoder(componentName, source, meta);
if (softwareCodec != NULL) {
LOGV("Successfully allocated software codec '%s'", componentName);
return softwareCodec;
}
}
it looks like for Encoder it always tries to instance Software codec first. What am I doing wrong? Any help wil be greatly appreciated. Thanks
Here's a code of OMXCodec creation:
mClient = new OMXClient();
mClient->connect();
logger->log("mClient.connect();");
enc_meta = new MetaData;
// frame size of target video file
int width = 640; //720;
int height = 480;
int kFramerate = 15;
int kVideoBitRate = 500000;
int kIFramesIntervalSec = 5;
int32_t colorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
enc_meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC); //MEDIA_MIMETYPE_VIDEO_MPEG4); //MEDIA_MIMETYPE_VIDEO_H263);//MEDIA_MIMETYPE_VIDEO_AVC);
enc_meta->setInt32(kKeyWidth, width);
enc_meta->setInt32(kKeyHeight, height);
enc_meta->setInt32(kKeyFrameRate, kFramerate);
enc_meta->setInt32(kKeySampleRate, 44100);
enc_meta->setInt32(kKeyBitRate, kVideoBitRate);
enc_meta->setInt32(kKeyStride, width);
enc_meta->setInt32(kKeySliceHeight, height);
enc_meta->setInt32(kKeyIFramesInterval, kIFramesIntervalSec);
enc_meta->setInt32(kKeyColorFormat, colorFormat);
mVideoSource = OMXCodec::Create(
mClient->interface(),
enc_meta,
true,
mSrc,
NULL,
OMXCodec::kHardwareCodecsOnly );
logger->log("OMXCodec_CREATED result: %d", (mVideoSource!=NULL) ? 1 : 0);
In
Android
ICS 4.0.4
, the codec registration was static i.e. all codecs were registered as part of an arrayKEncoderInfo
as can be found here.The methodology to differentiate between
hardware
andsoftware
codecs is pretty simple. If the component name doesn't start withOMX
, then it is construed to be asoftware
codec as shown in theIsSoftwareCodec
method.Since you are trying an
AVC
encoder, the software codec if created would beAVCEncoder
as can be found from it'sFactory
reference.To check which codec was created, you can enable logs in
OMXCodec.cpp
file by removing the comment as#define LOG_NDEBUG 0
in this line, save and recompile to buildlibstagefright.so
which could be used to generate the logs onlogcat
screen.EDIT:
In case of
rtsp
streaming, one needs to enable the logs inACodec.cpp
.One needs to ascertain if
libstagefrighthw.so
is present in/system/lib
which will register theOMX
core with theStagefright
framework.