This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Need help with Resizer and UYVY to 420SEMIP conversion

I'm capturing 720x480 UYVY on the DM368.  I'm using the resizer to convert from UYVY to 420SP to feed the h.264 encoder.  The Y data looks like it's encoder correctly, but the UV is offset in the picture.  Questions....

1) The captured source has an imageWidth of 720, not 736 like the 420.  Is this going to mess up the resizer feeding it a source that's not 32 byte aligned?  When the dest buffer was 720 the resizer refused to config.  But with the source being 720 it completed ok.

2) If the source image buffer must be 736 in width, is there an easy way to tell the DMAI capture to use 736 instead of 720?  When using 420SP it automatically was 736.

Here's the code I use to configure the resizer.  Maybe somebody can see something wrong....

    //-------------------------------------------------------------------------
    // First set up the resizer
    //-------------------------------------------------------------------------
    hResize =  Resize_create(&rszAttrs);

    // Set up a UYVY buffer for configuring the resizer
    bufSize = BufferGfx_calcSize(VideoStd_D1_NTSC,ColorSpace_UYVY);
    BufferGfx_calcDimensions(VideoStd_D1_NTSC,
                             ColorSpace_UYVY,
                             &gfxAttrs.dim);
    gfxAttrs.colorSpace = ColorSpace_UYVY;
    hUYVYBuf = Buffer_create(bufSize, (Buffer_Attrs*)&gfxAttrs);
    if (hUYVYBuf == NULL)
    {
      eprintf(eLOG_WARNING,"Failed to create UYVY buffer\n");
      goto error_exit;
    }
    BufferGfx_setColorSpace(hUYVYBuf,ColorSpace_UYVY);

    // Set up a 420SP buffer for resize config and to be used as buffer
    // for input to the encoder
    bufSize = BufferGfx_calcSize(VideoStd_D1_NTSC,ColorSpace_YUV420PSEMI);
    BufferGfx_calcDimensions(VideoStd_D1_NTSC,
                             ColorSpace_YUV420P,
                             &gfxAttrs.dim);
    gfxAttrs.dim.width = 736;
    gfxAttrs.dim.lineLength = 736;
    gfxAttrs.colorSpace = ColorSpace_YUV420P;
    h420Buf = Buffer_create(bufSize, (Buffer_Attrs*)&gfxAttrs);
    if (hUYVYBuf == NULL)
    {
      eprintf(eLOG_WARNING,"Failed to create 420SP buffer\n");
      goto error_exit;
    }
    p420_user_buf = Buffer_getUserPtr(h420Buf);
    BufferGfx_setColorSpace(h420Buf,ColorSpace_YUV420PSEMI);

    if(Resize_config(hResize,hUYVYBuf, h420Buf)<0)
    {
      eprintf(eLOG_WARNING,"Failed to config resizer\n");
      goto error_exit;
    }

  • This code is clearly not working correctly.  After I call Resize_execute the User Size of the h420Buf is 691200 bytes, which is the size of a UYVY 720x480 buffer.  The Orig Size of the h420Buf is only 529920.

    John A

  • John Anderson said:
    BufferGfx_calcDimensions(VideoStd_D1_NTSC,
                                 ColorSpace_YUV420P,
                                 &gfxAttrs.dim);
        gfxAttrs.dim.width = 736;
        gfxAttrs.dim.lineLength = 736;

     

    John,

    I am not very familiar with the DMAI layer for the resizer configuration, but i can check if nobody else picks up this thread. One thing that i would suggest you to do in the above code is that you use output width as 720 where as lineLength is still 736. This will take care of the requirement of multiple of 32 for the SDRAM address of each output line for RSZ. The valid data can still be 720 pixels.

        gfxAttrs.dim.width = 720;
        gfxAttrs.dim.lineLength = 736;

    Now, the question is whether the resizer is really getting configured to YUV420 output or not. I can tell you exact registers to look at but it should get configured from DMAI layer as well.

    Regards,

    Anshuman

  • I am able to get a picture out of the resizer and encoded now.  I'm not sure but it might have been this statement causing the problem.

    gfxAttrs.colorSpace = ColorSpace_YUV420P;

    The definition for ColorSpace_YUV420P and ColorSpace_420SEMIP are not the same.

    However, the resizer is putting a troubling number in the size of the output 420 buffer.  It's saying that it put 691200 bytes in the 420 buffer, whereras the buffer is only 529920 bytes.  In addition it appears that the video has been deinterlaced.  Since I have written the 420 buffers to a file and looked at them I'm not sure if it's the resizer deinterlacing the buffer when it performs the 420 conversion of if the deinterlacing occurs during encoding.

    The switch to using 720 for the width produced a bad picture.  Another strange thing that occured is when I made the 420 buffer bigger (i.e. 691200 bytes instead of 529920) the resulting encoded video had errors in the chroma (luma was fine).  I changed nothing except the size of the buffer.  This makes no sense to me because the resizer and the encoder shouldn't care if the buffer size is bigger.

    Unfortunately, I can't find much info on using the resizer.  The DMAI seems to do very little other than set up a few parameters and then call a driver with IOCTL calls.  But I can't find any documentation on the driver.  So I can't even tell if the DMAI is deficit.

    John A

  • John Anderson said:
    The switch to using 720 for the width produced a bad picture.  Another strange thing that occured is when I made the 420 buffer bigger (i.e. 691200 bytes instead of 529920) the resulting encoded video had errors in the chroma (luma was fine). 

    John,

    Can you share the YUV frame with us? Also, when you say you got bad picture with using width as 720, where did you check it? I mean, the bad picture was YUV data or was it the encoded stream? How did the bad picture look like (as wrong line offset calculation)? Can you share that bad picture also in case that is YUV data?

     

    Regards,

    Anshuman

  • Here is a sample of the 420 buffer from the output of the resizer.  It does appear to be interlaced as it should be.  However the resizer is scaling the 720x480 buffer to 736x480.  Obviously if you are correct about using 720 for the 420 width instead of 736, this will be fixed.  I'll try 720 as the output width and post a copy of the resulting 420 buffer.

  • More good news.  Setting the width to 720 did work.  Turns out that I had set the captureWidth to (2 x width) instead of (2 x linelength).  I'm still getting what appears to be non-interlaced video.  I get a good encoded video, but poor resolution.

    It appears that my second encode process isn't looking at the second field.  I move the user pointer down one line in the buffer before I call the second encode.  However, I made a mistake and moved it down 720 bytes, not 736.  This should have screwed up the image but it didn't.  I'm thinking that either the second encode is doing nothing *or* the second encode isn't looking at the user buffer pointer.

    John

  • The only info I'm giving the encoder about interlaced operation is I'm setting inputContentType to IVIDEO_INTERLACED in the dynamic parameters.  Is there any other information it needs?  Does the encoder keep track of the field by how many times it's been called?  I set the height to 480, so I'm guessing that the fact it's interlaced it knows that it's only 240 fields per call.

    I looked the Buffer routines and the encoder must have to use the user or phyical pointer and both are updated on a Buffer_setUsrPtr call.

    The other possibility is that I packaging up the coded output wrong when I stream it to the network with RTP packets.  My next step is to write the raw data stream to a file and view it with VLC.  If it's still non-interlaced I will post the file.

    John A

     

  • Here is the raw h264 video.  It's clearly deinterlaced.  The frame being fed to it is just like the jpeg image I posted.  I call Venc1_process twice for each frame, but the second call seems to do nothing even though it's outputting approx the same amount of data as the first call.  It seems like the deocder (VLC in this case) is ignoring the second field of data.

    The file wouldn't upload here so here's the link...

    http://dl.dropbox.com/u/3345452/test.h264

    John A

  • I decided to get radical and created another 420 buffer that I fed to the encoder as the second field.  I found that indeed the image is interlaced as the alternating lines were blank.  It turns out that because the buffer is not a reference buffer that the routine to set the new pointer location is rejected.  I guess this just shows the need for error checking even on the simplist of routines.

    John A

  • That was it.  I have interlaced video encoding now. Whew!

    Thank you Anshuman for your help.

    John A

  • Great to know that your problem is solved.

    Regards,

    Anshuman

  • Now I need to figure out if the DMAI supports getting two outputs from the resizer.  I'd like to get another resolution output to be encoded simultaneously as a separate stream.

    John A