Question

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);
Was it helpful?

Solution

In Android ICS 4.0.4, the codec registration was static i.e. all codecs were registered as part of an array KEncoderInfo as can be found here.

The methodology to differentiate between hardware and software codecs is pretty simple. If the component name doesn't start with OMX, then it is construed to be a software codec as shown in theIsSoftwareCodec method.

Since you are trying an AVC encoder, the software codec if created would be AVCEncoder as can be found from it's Factory 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 build libstagefright.so which could be used to generate the logs on logcat screen.

EDIT:

In case of rtsp streaming, one needs to enable the logs in ACodec.cpp .

One needs to ascertain if libstagefrighthw.so is present in /system/lib which will register the OMX core with the Stagefright framework.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top