Select H264 Profile when encoding with MediaCodec and MTK Codec

后端 未结 3 1937
囚心锁ツ
囚心锁ツ 2021-01-02 22:06

We have an Android app that encodes video into H264. On all previously tried Android devices this encodes to Baseline profile which is what I need.

On the Lenovo Yog

相关标签:
3条回答
  • 2021-01-02 22:28

    Here's a snippet of what I did in my app :

    mediaFormat.setInteger("profile", 8); // Profile HIGH
    mediaFormat.setInteger("level", 0x200); // Level 3.1
    

    And here are the profile values you can choose from :

    OMX_VIDEO_AVCProfileBaseline = 0x01,   /**< Baseline profile */
    OMX_VIDEO_AVCProfileMain     = 0x02,   /**< Main profile */
    OMX_VIDEO_AVCProfileExtended = 0x04,   /**< Extended profile */
    OMX_VIDEO_AVCProfileHigh     = 0x08,   /**< High profile */
    OMX_VIDEO_AVCProfileHigh10   = 0x10,   /**< High 10 profile */
    OMX_VIDEO_AVCProfileHigh422  = 0x20,   /**< High 4:2:2 profile */
    OMX_VIDEO_AVCProfileHigh444  = 0x40,   /**< High 4:4:4 profile */
    OMX_VIDEO_AVCProfileKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
    OMX_VIDEO_AVCProfileVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
    OMX_VIDEO_AVCProfileMax      = 0x7FFFFFFF  
    

    And the levels :

    OMX_VIDEO_AVCLevel1   = 0x01,     /**< Level 1 */
    OMX_VIDEO_AVCLevel1b  = 0x02,     /**< Level 1b */
    OMX_VIDEO_AVCLevel11  = 0x04,     /**< Level 1.1 */
    OMX_VIDEO_AVCLevel12  = 0x08,     /**< Level 1.2 */
    OMX_VIDEO_AVCLevel13  = 0x10,     /**< Level 1.3 */
    OMX_VIDEO_AVCLevel2   = 0x20,     /**< Level 2 */
    OMX_VIDEO_AVCLevel21  = 0x40,     /**< Level 2.1 */
    OMX_VIDEO_AVCLevel22  = 0x80,     /**< Level 2.2 */
    OMX_VIDEO_AVCLevel3   = 0x100,    /**< Level 3 */
    OMX_VIDEO_AVCLevel31  = 0x200,    /**< Level 3.1 */
    OMX_VIDEO_AVCLevel32  = 0x400,    /**< Level 3.2 */
    OMX_VIDEO_AVCLevel4   = 0x800,    /**< Level 4 */
    OMX_VIDEO_AVCLevel41  = 0x1000,   /**< Level 4.1 */
    OMX_VIDEO_AVCLevel42  = 0x2000,   /**< Level 4.2 */
    OMX_VIDEO_AVCLevel5   = 0x4000,   /**< Level 5 */
    OMX_VIDEO_AVCLevel51  = 0x8000,   /**< Level 5.1 */
    OMX_VIDEO_AVCLevelKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
    OMX_VIDEO_AVCLevelVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
    OMX_VIDEO_AVCLevelMax = 0x7FFFFFFF  
    

    It's important to set both.

    0 讨论(0)
  • 2021-01-02 22:33

    What you could try is to add the key profile to your MediaFormat, with a value of 1 (OMX_VIDEO_AVCProfileBaseline). If you do this, you probably also need to add the key level with a level value matching your resolution as well (with a value from the OMX AVC level constants).

    I'm not sure if this codec actually honors the requested value though, but it might be worth a try.

    See the setupAVCEncoderParameters function in https://android.googlesource.com/platform/frameworks/av/+/6ade04174/media/libstagefright/ACodec.cpp for an example on the setup procedure. It looks for the profile key in the input parameters (which are copied from the MediaFormat that you've provided), but if this is present you also need to provide a level parameter, and what level to use depends on your resolution. See https://android.googlesource.com/platform/frameworks/native/+/cde4b13a/include/media/openmax/OMX_Video.h for constant values you can use for the parameters.

    But after checking for the profile and level parameters, it also seems to override the profile to baseline regardless of what was set. So either these lines have been removed from your device, or the encoder disregards the h264type.eProfile field altogether.

    If someone has got a source tree closer to what actually is used on the devices, it would be even better to inspect that.

    As an example on how to pick a suitable level for your resolution, have a look at x264_validate_levels in http://git.videolan.org/?p=x264.git;a=blob;f=encoder/set.c;h=1a40b71284 (but the level passed to MediaFormat needs to be expressed using the OMX_VIDEO_AVCLEVELTYPE constants).

    Not sure if anything of this helps, but it's at least worth a try.

    0 讨论(0)
  • 2021-01-02 22:37

    I have tried this on Nexus 9 with Nvidia HW encoder. Only thing that works for me is to select the encoder by name. I am able to set the profile to chosen value for encoder level is always set to 13.

    Please note that if you select encoder by type, it selects google encoder and as mentioned above, it forces profile to baseline.

    0 讨论(0)
提交回复
热议问题