How can I resize a 352x288 frame into a 800x600 one?

How can I resize a 352x288 frame into a 800x600 one?

Dear members,

at the moment I am bounded to the IPP 7.0.2. I decode a 352x288 MPEG2 video. With GetFrame() of the IPP I get a decoded 352x288 frame in UYVY format.

Then I use a ippiCbYCr422ToYcbCr422_8u_C2R call to do a conversion from UYVY to YUY2.

The next call is a resize call ippiResizeYUV422_8u_C2R.

At last a conversion from YUY2 to UYVY with ippiYCbCr422ToCbYCr422_8u_C2R.

This works as far as the boundaries of the 352x288 frame is used as source and destination. If I try to use the resize call to scale my 352x288 to a 800x600 frame it does not work.

I guess I have to put my decoded 352x288 frame without scaling into a 800x600 one so that the decoded frame is the upper left corner of the 800x600 frame. After this I can use my resize call above to scale my little frame to the full size of a 800x600 one.

But how can I put my 352x288 frame into a 800x600 one?

Best regards

Detlev

 

 

 

25 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.

Hi Detlev,

Could you provided some details on the error you get when calling the ippiResizeYUV422_8u_C2R function? One simple test code may help to root the problem.

Regards,
Chao

Citation :

Detlev Petersen a écrit :

But how can I put my 352x288 frame into a 800x600 one?

Hi Detlev,

Since UYVY is 16 bits-per-pixel format you can use ippiCopy_16u_C1R. I.e. <in pseudo-code>

   pDst=ippiMalloc_16u_C1(800, 600, &dstStep);
   ippiCopy_8u_C1R( pSrc, srcStep, pDst, dstStep, { 352, 288} );

Regards,
Sergey 

Regards, Sergey

Dear all,

please find attached my test video as ZIP archive. It is a 352x288 video, but you have to note which it is marked in a wrong way as interlaced one. I took regard to this fact, so that the decoder works with a non-interlaced one.

I have to clean-up my code to provide you a sample code cause I did various tests and experiments with different call parameters just to see what works and what does not work.

I try to implement the hint of Sergey. From my point of view this can help to solve my problem. Nevertheless I have to verify it at first.

In addition to that I try to upload one screenshot so that you see the result if the IPP resize function is set up to resize the small 352x288 frame to a bigger 800x600. As I written it before the resize works as long as source and destination frame are of the same size.

By the way I try to copy each line of the 352x288 frame to the beginning of a 800x600 frame. This didn't work but I do not know why. My idea was that I just have to copy 352x2 bytes for one line into one 800x2 line for the bigger frame. The result was a something like a green 352x288 image in the upper left corner of an black 800x600.

Best regards

Detlev

 

 

 

Fichiers joints: 

Dear all,

please find attached one screenshot. This is the result if I use the resize call to scale the 352x288 source frame to a 800x600 target frame. As far as I use 352x288 the resize works and the frame looks like a frame out of my test video.

Sample code and further test results will follow.

Best regards

Detlev

Fichiers joints: 

>>...please find attached one screenshot. This is the result if I use the resize call to scale the 352x288 source frame to
>>a 800x600 target frame...

Could you attach a simple test-case?

I saw on your screensot how the problem looks like and this is due to wrong image formats you've selected.

>>pDst = ippiMalloc_16u_C1(800, 600, &dstStep);
>>ippiCopy_8u_C1R( pSrc, srcStep, pDst, dstStep, { 352, 288} );

I'm not sure that it will work since pDst is declared as Ipp8u *pDst:

...
IPPAPI ( IppStatus, ippiCopy_8u_C1R,
( const Ipp8u* pSrc, int srcStep,
Ipp8u* pDst, int dstStep,IppiSize roiSize ))
...

and I think ippiConvert_8u16u_C1R has to be used instead.

Yes, you right. Of course, ippiCopy_16u should be used, this is a typo. We must not convert it from 8u to 16u, Otherwise, we get image with black dots between real pixels. In this case ippiCopy_16u is just a simple way to place smaller array into bugger one without any conversion.

Regarding Detlev's snapshot, this is exactly how frame looks when wrong width and/or height is select during playback.

I will try to check this ippiYCbCr422ToCbYCr422_8u_C2R function in small test.

Regards,
Sergey 

Regards, Sergey

Hi Detlev,

I have attached test file, Isn't it what you want?

Regards,
Sergey 

Fichiers joints: 

Fichier attachéTaille
Télécharger test.c1.63 Ko
Regards, Sergey

Hi Sergey,

I tested your first tip yesterday. The result was not as good as I expected. Please see my attached screen shot.

I did some further tests to see what does work or not. My problem is that I change a little bit and that the result turns to a bad one.

Now I have some further screenshots so that I can show you what runs with my software. Here I have to write a new comment so that you can get these screenshots.

At the moment I clean-up my software so that I can provide my InitScaling() method to you. After GetFrame() there follows converting and scaling stuff before the frame is copied to the screen with Blt().

I will try to do something with your last sample after the mentioned task above.

In addition to that I try to copy the 352x288 frame into a 800x600 one. I used a loop over the heigth of the little frame and copied 352*2 byte into the row of each row of the 800x600 frame. As result I get a 800x600 frame with a 352x288 rectangle in the upper left corner but the video frames cannot be identified anymore. I expected that the next row follows the previous one in the frame buffer. I didn't see a swap of bytes. Nevertheless my copy routine doesn't work.

Best regards

Detlev

Fichiers joints: 

Hi Chao, Sergey and Sergey,

please find attached my InitScaling() method and some screenshots.

My resize works with factors 0.5, 2.0 and 1.0 as long as the source frame is left unchanged as 352x288 one.

I managed it only to use the last re-conversion back to UYVY to put the 352x288 frame into a 800x600 one.

It seems to be that the resize call needs a 800x600 frame as input so that I can get my wished 800x600 frame with the scaled small frame as result.

First trials to put the 352x288 frame into a 800x600 without scaling failed.

Now I can try to do something with the sample from Sergey.

I hope my sample will be helpful for you. Maybe you can see the root cause of my problem just faster than myself.

Best regards

Detlev

 

Fichiers joints: 

Hi everybody,

>>...I have attached test file, Isn't it what you want?
>>
>>Attached: test.c

It is a good example but it has two extra dependencies on Intel IPL ( Image Processing Library / predecessor of IPP ) and OpenCV ( Computer Vision ) libraries.

Citation :

Sergey Kostrov a écrit :

It is a good example but it has two extra dependencies on Intel IPL ( Image Processing Library / predecessor of IPP ) and OpenCV ( Computer Vision ) libraries.

This (OpenCV render) is for visual check only. It can be commented away.

Regards,
Sergey 

Regards, Sergey

Hi all,

in Sergey sample I cannot see other values than the ones which I use. Ok, I have a video frame as input and Serge uses an RGB bitmap. The resize call is the same.

Now I have added another screenshot. As you see there is something destroyed from the genuine video frame in the upper left corner as 352x288 rectangle. I tried to use ippiCbYCr422ToYCbCr422_8u_C2R() to put the 352x288 video frame from GetFrame() in a bigger 800x600 one including the necessary color conversion for the following resize call.

I do not see any fault in my resolution values 352x288 and 800x600. From my point of view the step values with 352x2 and 800x2 bytes per row seems to be alright. The pitch values are 704 and 1600. Something goes wrong but I cannot see what. I seems to be that bigger rows are copied into a too small rectangle.

Best regards

Detlev

Fichiers joints: 

Dear all,

if I use ippiCbYCr422ToYCbCr422_8u_C2R() with sizeDst instead of the source size as in my last test sample I get an exception. This means that this color conversion can work with the source size 352x288 only. With 800x600 as destination size were will be a memory exception cause of the source frame and its smaller size. This conversion function seems to iterate over 600 rows for an input frame of 288 rows.

This explains two things. At first that the frame of my last sample must be look like something which is destroyed. On the second the conversion call above cannot be used to put the 352x288 frame into a bigger 800x600 one.

In my experience the used resize call seems to have the same problem.

Only the last re-conversion back to UYVY can port a 352x288 frame to a 800x600, but this comes too late for me.

Now I can find two or three points for a solution:

1) It is possible to use the resize call in the wished or planned way

2) I copy the 352x288 frame into a 800x600 before the resize call by an extra function or by an iteration on my own. Both trials failed in the past.

3) I do some more conversion stuff to get the input frame for the resize call bigger. On the other hand it seems to be much overhead to reach this aim for the expected performance load of the player.

Best regards

Detlev

// converting UYVY to YUY2
    // accessing pDecodeBuffer
    // using new in buffer for YUY2
    stateUYVYtoYUY2=ippiCbYCr422ToYCbCr422_8u_C2R(
     // active if unscaled one have to be shown
     // (const Ipp8u*)pDecodeBuffer,
     // active if scaled one have to be shown
     (const Ipp8u*)p_frame_YUY2_in,
     m_videostreaminfo.clip_info.width*2,
     (Ipp8u*)p_frame_YUY2_4conv,
     sizeDst.width*2, // converts an make input frame bigger
     sizeDst
     );

 

Hi Detlev,

1) Your CbYCr -> YCbCr conversion is not quite correct. You need to do this in small frame. So, 352x288 -> 352x288
2) Resize (in YCbCr colors) from small frame to large frame
3) Convert YCbCr -> CbYCr in large frame. 

Regards,
Sergey
P.S. I updated the sample to have your conversions as test core. Note: I used RGBs only as temporary pictures to generate source image and to check destination image, so you can skip this RGB stuff. Note 2: in my updated test case I got result picture with somehow twisted colors. It can be another problem in the future after you win resizing.

Fichiers joints: 

Fichier attachéTaille
Télécharger test.c2.2 Ko
Regards, Sergey

Hi Sergey,

I checked the call parameters just in the way how they were used by yourself in your sample.

I didn't manage it to get the wished result.

Then I did some further tests. After decoding one frame my software creates and overwrites the complete decoded frame. I used a pattern of rows in a sequence where the odd and even ones have different colors.

Now I see, that Blt() as Windows call interprets 352x288 and 800x600 input frames as 352x288 frames for output. The green margin on the right site and on the bottom are generated by Blt() but are not out of the framebuffer 800x600, which were processed by the IPP calls.

I haven't found the root cause for this until yet. There must be a hidden command for my eyes which sets 352x288 as window output. My target window is set to 800x600 and the maximum size for the DirectDraw interface is 1280x720.

I think, I have to solve this DirectDraw problem at first before I can go on with the IPP's resize call. I guess all will work much better then and I will see on the screen what I want to see.

Best regards
Detlev

Hi Sergey,

do you know an IPP function to convert my YUY2 and UYVY frame into a RGB one. 8bit per color R, G and B would be nice cause it is easier then to save it under Windows as bitmap without an extra header and color table.

Then I can verify that the IPP functions are okay and I can set my focus on the DirectDraw initialisation only.

Best regards

Detlev

Hi Detlev,

Aren't YUV2 and UYVY the synonyms of YCbCr422 ? If yes, then ippiYCbCr422ToRGB could be used.

Regards,
Sergey 

Regards, Sergey

Hi Sergey,

I used the call ippiCbYCr422ToRGB_8u_C2C3R() and the code lines below to get my UYVY frame into a RGB bitmap. The colors are twisted somehow but I read that YUY uses another value for 0 and has a different value range in comparison with RGB which uses the values from 0 up to 255 of each byte. I guess this is the reason for the change colors. In addition to that I have something like a mirror effect within my bitmap. It was faster for me to use a copy of another 800x600 bitmap than to set up a genuine Windows bitmap header. It can be that this is the rootcause for the mirror effect. Please see attached frame 240 of my test video as bitmap which was saved in the way below after calling the resize and the last color conversion from YUY2 to UYVY and before calling Windows' Blt().

My current IPP sample for the resize after GetFrame will follow.

Best regards

Detlev

// just to control the result before Blt() copies it to the screen

// UYVY to RGB

if(m_dwDecodedFramesCount%10==0)

{

// do this every 10 frames

BYTE* pDstBmp;

inti_sizeBmp=sizeDst.height*sizeDst.width*3;

pDstBmp=

newBYTE[i_sizeBmp];

if(pDstBmp!=NULL)

{

// allocating the memor was successful

ippiCbYCr422ToRGB_8u_C2C3R(

(

constIpp8u*)pDecodeBuffer,

sizeDst.width*2,

(Ipp8u*)pDstBmp,

sizeDst.width*3,

sizeDst);

// copy the bitmap to file

FILE* hFile;

charfilename[1024];

charheader[54];

// set filename

sprintf(&filename[0],

"frame_%ld.bmp",m_dwDecodedFramesCount);

// set bitmap header

header[0]=0x42;

header[1]=0x4D;

header[2]=0x36;

header[3]=0xF9;

header[4]=0x15;

header[5]=0x00;

header[6]=0x00;

header[7]=0x00;

header[8]=0x00;

header[9]=0x00;

header[10]=0x36;

header[11]=0x00;

header[12]=0x00;

header[13]=0x00;

header[14]=0x28;

header[15]=0x00;

header[16]=0x00;

header[17]=0x00;

header[18]=0x20;

header[19]=0x03;

header[20]=0x00;

header[21]=0x00;

header[22]=0x58;

header[23]=0x02;

header[24]=0x00;

header[25]=0x00;

header[26]=0x01;

header[27]=0x00;

header[28]=0x18;

header[29]=0x00;

header[30]=0x00;

header[31]=0x00;

header[32]=0x00;

header[33]=0x00;

header[34]=0x00;

header[35]=0xF9;

header[36]=0x15;

header[37]=0x00;

header[38]=0x00;

header[39]=0x00;

header[40]=0x00;

header[41]=0x00;

header[42]=0x00;

header[43]=0x00;

header[44]=0x00;

header[45]=0x00;

header[46]=0x00;

header[47]=0x00;

header[48]=0x00;

header[49]=0x00;

header[50]=0x00;

header[51]=0x00;

header[52]=0x00;

header[53]=0x00;

if((hFile = _fsopen(&filename[0],"wb",_SH_DENYNO)) != NULL)

{

// size_t fwrite( const void *buffer, size_t size, size_t count, FILE *stream );

fwrite(&header[0],

sizeof(char),54,hFile);

fwrite(pDstBmp,

sizeof(BYTE),i_sizeBmp,hFile);

fclose(hFile);

}

deletepDstBmp;

}

}

Fichiers joints: 

Hi Detlev,

It can be not a mirror. BMP files ares stored in bottom-up order, i.e. lowest raster line first.

Regards,
Sergey 

Regards, Sergey

Hi Sergey,

now my saved frame has no turn/mirror effect. The last row comes first within the saved bitmap. Please see the attached bitmap.

The colors are wrong. They are blue instead of read and grey instead of black. I saw that are some functions to correct the saturation after a UYVY->RGB conversion. What can I do to get the correct colors?

For the community I attached my new sample of my InitScaling() call. This are the lines of code which scale the 352x288 video into 800x600 frames.

Ok, my last open issues are to chose the right color for the save frame as bitmap and to find the set-up error within the DirectDraw interface of my windows application.

Best regards,

Detlev

Fichiers joints: 

Hi Detlev,

In my test one conversion is wrong. Look at the text below and correct your application accordingly. Hope it will help.

#if 0
    ippiYCbCr422ToCbYCr422_8u_C2R(dstYUV, dstYUVstep, dstYCbCr, dstYCbCrstep, largeSize);
/* Visual check */
    ippiCbYCr422ToYCbCr422_8u_C2R(dstYCbCr, dstYCbCrstep, dstYCbCr, dstYCbCrstep, largeSize);
    ippiYCbCr422ToRGB_8u_C2C3R(dstYCbCr, dstYCbCrstep, dstRGB, dstRGBstep, largeSize);
#else
    ippiYUV422ToRGB_8u_C2C3R(dstYUV, dstYUVstep, dstRGB, dstRGBstep, largeSize);
#endif

Regards,
Sergey 

Regards, Sergey

Hi Sergey,

before writing one row to the bitmap file I swap the bytes for R and B in the RGB triple byte set. Then the colors are okay in my bitmap. I saw with help of a tool, that the values for R and B were changed. White and black colors were okay in the bitmap with the wrong colors before. This swap fixes in wrong colores in my saved bitmap for one frame.

Currently I am looking for the bug in the set-up of my DirectDraw interface. All resolutions for the created parent in client windows are on 800x600. At the moment and in the past I see and saw no reason for the 352x288 output. It seems to be a hidden setting that destroys my screen output.

Best regards,

Detlev

Hi all,

please find attached some save frames as bitmap file. The frames were scaled by the IPP and different scaling methods like nearest neighbor, linear and cubic were used.

Yesterday I found the reason why the scaling via IPP were ok and the frame on the screen were limited to 352x288 instead of 800x600. After scaling by the IPP I found the code segment where the scaled frame is copied to the buffer which is used by Blt(). Due to the foreign code for me I supposed the buffer with the scaled frame as the one which is used by Blt(). This was wrong. Our player SW have to copy each video frame into the frame buffer for the DirectDraw interface. For example DirectDraw can be set up to 1280x720 frames as maximum and each 352x288 or 800x600 frame must be copied into the DirectDraw buffer before Blt() is called. A lack of comments made it difficult to understand this code segment faster in the right way.

I thank you very much for all support.

Best regards,

Detlev

Fichiers joints: 

Connectez-vous pour laisser un commentaire.