H.264 video corrupted if width is not multiple of 32

H.264 video corrupted if width is not multiple of 32

Portrait de froueint

Hi,

We have noticed that if the width of the input frames is not a multiple of 32 the generated video is corrupt. For example 1280x720 works but 1296x720 doesn't. The documentation says "Width must be a multiple of 16. Height must be a multiple of 16 for progressive frame sequence and a multiple of 32 otherwise." (we use MFX_PICSTRUCT_PROGRESSIVE).

Is this a bug or is there some other setting we're missing.

Thanks,

Farhad

5 posts / 0 nouveau(x)
Dernière contribution
Reportez-vous à notre Notice d'optimisation pour plus d'informations sur les choix et l'optimisation des performances dans les produits logiciels Intel.
Portrait de camkego
Best Reply

You know, I ran into this exact same problem, well at least symptomatically.

You may be seeing the same underlying cause.

In my situation, it turned out that I had a bug where I was copying raw NV12 to the mfxFrameSurface1->Data planes.

I was not correctly handling the situation where: ( mfxFrameSurface1->Data.Pitch != myframe_width ).

Normally, I copied the Y/CrCb planes into the mfxFrameSurface1 planes with two copies, one for Y, one for CrCB.

That works great when the mfxFrameSurface1->Data.Pitch is equal to myframe_width.

But, when you allocate system memory surfaces using MSDK (and maybe D3D surfs),
you will not get the surface pitch equal to your source frame width, where (myframe_width/16%2==1).

Everything works fine, where (myframe_width/16%2==0).

In this case, I copied, line by line, the Y and CrCb source frame to the mfxFrameSurface1.

Basically:

if ( mfxFrameSurface1->Data.Pitch != myframe_width ) {
// copy line by line Y, CrCb to surface
}else{
// copy the whole darn Y and CrCb to surface
}

I suspect you have the same problem I had, please let me if that is the case.

Regards,
Cameron Elliott

Portrait de froueint

Hi Cameron,

That was indeed my problem. I just had to copy my RGB data row by row when the width of the allocated frame wasn't the same as my frame width.

Thank you very much for your help.

Regards,
Farhad

Portrait de Vassili Yakovlev

Hi,

You don't have to do the check wether width multiplied by number of bytes per pixel equals to the pitch.
Accurate approach is to copy each line with length which is equals to the width multiplied by number of bytes per pixel, and to do shift to the next line with the offset which is equals to the pitch.

Let say you have 3 bytes per pixel image, pSrc - pointer to the source, pDst - pointer to the destination, and pitch - pitch of the destination. So you have to do the following:

for (i=0; i < height; i++)
{
copy(pDst, pSrc, width*3);
pSrc += width*3;
pDst += pitch;
}

And this is in case if you source has pitch which is equals to the width*"number of bytes per pixel", otherwise you have also to use the pitch of the source picture.

Portrait de froueint

While you're correct that it's not required to check whether the pitch of the buffer equals the pitch of the frame, I still do the check so that in cases where they do match (i.e. width is a multiple of 32), then I can just do one single memcpy which is more efficient than copying row by row; so it's a minor optimization.

Connectez-vous pour laisser un commentaire.