Enable High Profile settings for i.MX8MMini Hantro H1 H.264 encoder

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Enable High Profile settings for i.MX8MMini Hantro H1 H.264 encoder

1,077 Views
vincentz63
Contributor IV

By default the Hantro H1 H.264 encoder of the i.MX8MMini is configured for Baseline profile. I am trying to enable the features corresponding to the High profile (CABAC, 8x8 transform) which the Ref manual advertises page 4807.

I have found SWREG18 in the Ref. Manual and have inserted the following code in hx280enc.c, function hx280enc_init().

However, these changes seem to have no effect in the H.264 produced. I know my code is executed as I can see the printk() on the debug console, but I suspect this is not the right location to place the code.

Could you let me know where should I place the code such that the settings are applied to the encoder and not overwritten by existing code?

Are there other registers I need to configure?

Have you tested those features? Can you confirm they work?

if (1) {
/* Enable 8x8 transform. */
u32 vpu_h1_reg18;
pr_info("hx280enc: enable 8x8 transform\n");
vpu_h1_reg18 = readl(hx280enc_data.hwregs + 0x48);
pr_info("hx280enc: vpu_h1_reg18 <%x>\n", vpu_h1_reg18);
vpu_h1_reg18 |= (1 << 21);
pr_info("hx280enc: vpu_h1_reg18 <%x>\n", vpu_h1_reg18);
writel(vpu_h1_reg18, hx280enc_data.hwregs + 0x48); /* SWREG18 */
}

if (1) {
/* Enable CABAC. */
u32 vpu_h1_reg18;
pr_info("hx280enc: enable CABAC\n");
vpu_h1_reg18 = readl(hx280enc_data.hwregs + 0x48);
pr_info("hx280enc: vpu_h1_reg18 <%x>\n", vpu_h1_reg18);
vpu_h1_reg18 |= (1 << 18);
pr_info("hx280enc: vpu_h1_reg18 <%x>\n", vpu_h1_reg18);
writel(vpu_h1_reg18, hx280enc_data.hwregs + 0x48); /* SWREG18 */
}

I have also updated vpu_wrapper_hantro_encoder.c (in imx-vpuwrap) as below. I cannot see how those settings are used later-on, could you shine some light?

static VpuEncRetCode VPU_EncSetAvcDefaults(VpuEncObj* pEncObj)
{
OMX_VIDEO_PARAM_AVCTYPE* config = 0;
config = &pEncObj->encConfig.avc;
config->nPortIndex = 1;
config->eProfile = OMX_VIDEO_AVCProfileHigh;//OMX_VIDEO_AVCProfileBaseline;
config->eLevel = OMX_VIDEO_AVCLevel42;//OMX_VIDEO_AVCLevel1;
config->eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
config->nRefFrames = 1;
config->nAllowedPictureTypes &= OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
config->nPFrames = 150;
config->nSliceHeaderSpacing = 0 ;
config->nBFrames = 0;
config->bUseHadamard = OMX_FALSE;
config->nRefIdx10ActiveMinus1 = 0;
config->nRefIdx11ActiveMinus1 = 0;
config->bEnableUEP = OMX_FALSE;
config->bEnableFMO = OMX_FALSE;
config->bEnableASO = OMX_FALSE;
config->bEnableRS = OMX_FALSE;
config->bFrameMBsOnly = OMX_FALSE;
config->bMBAFF = OMX_FALSE;
config->bEntropyCodingCABAC = OMX_TRUE;//OMX_FALSE;
config->bWeightedPPrediction = OMX_FALSE;
config->nWeightedBipredicitonMode = OMX_FALSE;
config->bconstIpred = OMX_FALSE;
config->bDirect8x8Inference = OMX_TRUE;//OMX_FALSE;
config->bDirectSpatialTemporal = OMX_FALSE;
config->nCabacInitIdc = OMX_FALSE;
config->eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
#ifdef CONFORMANCE
config->eLevel = OMX_VIDEO_AVCLevel42;//OMX_VIDEO_AVCLevel1;
...

Labels (1)
0 Kudos
4 Replies

1,046 Views
vincentz63
Contributor IV

Update.

Driver file hx280enc.c is not the right place to make such settings changes. The settings are set in VPU_EncSetAvcDefaults() in vpu_wrapper_hantro_encoder.c.

Having enabled CABAC and 8x8 transform, I've been able to verify that those features are indeed used by the encoder and I can see modest improvements in video quality.

For ref, below the code I have used to enable High profile (CABAC + 8x8 transform).

#if HIGH_PROFILE
config->eProfile = OMX_VIDEO_AVCProfileHigh;
config->eLevel = OMX_VIDEO_AVCLevel42;
#else
config->eProfile = OMX_VIDEO_AVCProfileBaseline;
config->eLevel = OMX_VIDEO_AVCLevel1;
#endif

...
#if HIGH_PROFILE
config->nRefFrames = 2;
#else
config->nRefFrames = 1;
#endif
...

#if HIGH_PROFILE
config->bEntropyCodingCABAC = OMX_TRUE;
#else
config->bEntropyCodingCABAC = OMX_FALSE;
#endif
...

#if HIGH_PROFILE
config->bDirect8x8Inference = OMX_TRUE;
#else
config->bDirect8x8Inference = OMX_FALSE;
#endif
...

#ifdef CONFORMANCE
#if HIGH_PROFILE
config->eLevel = OMX_VIDEO_AVCLevel42;
#else
config->eLevel = OMX_VIDEO_AVCLevel1;
#endif
config->bUseHadamard = OMX_TRUE;
#endif

As I stated above, the improvement in video quality is very modest with the High profile features enabled, compared to Baselne profile and I wonder if there's anything else that could be done?

I noticed that the encoder only ever seems to use 1 reference frame even it is advertised as being capable of using two. I have set config->nRefFrames = 2; but it does not seem to have any effect. Any idea why not?

In my use case, I'm trying to get the best video quality for a given bitrate. So for example: quant=-1, bitrate=5000, gop=15.

The doc states that quant=-1 is for automatic; what does that mean exactly? Is the encoder allowed to vary the Qp between 1 and 51 freely to try and achieve the bitrate specified?

The video being compressed comprises of live footage coming from a camera combined with overlays that are added programmatially (text and drawings). Does the Hantro H1 encoder have any features that could be used to improve coding efficiency / quality for the overlays?

0 Kudos

1,076 Views
vincentz63
Contributor IV

I should add that I placed the code above AFTER the call to ResetAsic()...

I also tried to enable image rotation in SWREG15 with the following code, but to no avail... which seems to confirm I'm either not placing the code in the right place or I'm missing something...

if (1) {
/* Input image rotation. */
u32 vpu_h1_reg15;
vpu_h1_reg15 = readl(hx280enc_data.hwregs + 0x3C);
pr_info("hx280enc: vpu_h1_reg15 <%x>\n", vpu_h1_reg15);
vpu_h1_reg15 |= (1 << 1);
pr_info("hx280enc: vpu_h1_reg15 <%x>\n", vpu_h1_reg15);
writel(vpu_h1_reg15, hx280enc_data.hwregs + 0x3C); /* SWREG15 */
}

0 Kudos

366 Views
joanxie
NXP TechSupport
NXP TechSupport

VPU wrapper includes this options, I didn't test this, maybe you can try it, but I got reply from internal team:

""Currently there is no option as part of the VPU wrapper to configure the profile levels. The reason being, the Encoder can only be configured against constant bitrate  (or) variable bit rate. The bitrate algorithm that is part of the Encoder completely hides the user from selecting the various encoding options, as bitrate is what finally everyone will look to when configuring the encoder.""

0 Kudos

1,021 Views
joanxie
NXP TechSupport
NXP TechSupport

for setting the high profile, I suggest that you can refer to the option level in the h264_testenc under /unit_test/VPU/hantro

0 Kudos