Media (Intel® Video Processing Library, Intel Media SDK)
Access community support with transcoding, decoding, and encoding in applications using media tools like Intel® oneAPI Video Processing Library and Intel® Media SDK
Announcements
The Intel Media SDK project is no longer active. For continued support and access to new features, Intel Media SDK users are encouraged to read the transition guide on upgrading from Intel® Media SDK to Intel® Video Processing Library (VPL), and to move to VPL as soon as possible.
For more information, see the VPL website.

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

froueint
Beginner
557 Views

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

0 Kudos
1 Solution
celli4
New Contributor I
557 Views
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

View solution in original post

0 Kudos
4 Replies
celli4
New Contributor I
558 Views
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
0 Kudos
froueint
Beginner
557 Views
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
0 Kudos
Vassili_Yakovlev
Beginner
557 Views
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.
0 Kudos
froueint
Beginner
557 Views
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.
0 Kudos
Reply