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.

resizer on DM6437

Hi,

I'm working with my evaluation module for the DM6437.  I'm not using any RTOS and writing everything in plain C and inlined assembler.  I currently have a video camera that streams NTSC video into the evaluation module and I output to composite video which is then displayed on a monitor.  I setup the video to "loopback" on video window 0.  Video window 0 is, not surprisingly, 720 x 480.  I use video window 1 for picture in picture video.  I've setup video window 1 to be exactly half the size of video window 0 (360 x 240).  I've then offset video window 1 to be in the upper right corner of the entire frame.  So far so good.  When I dump synthetic data to DDR2  (eg via some for loop that just fills the buffer) at the video buffer for video window 1 I indeed see what I expect to see and in the "background" (eg video window 0) I see my camera feed.  

What I'd like to do now is utilize the resizer hardware to display the camera feed sized at .5x in video window 1.  In other words I'll see the camera feed in the video window 0 and the exact same camera feed (scaled by .5x and delayed slightly) in video window 1.  I've setup the resizer to use input data from ddr (exactly where the CCDC module dumps the data in ddr).  I've written a function which writes all the resizer configuration registers.  Finally I wrote a silly polling loop which looks something like this:

 

while(1){

if(VPFE_RESZ_PCR == 0)  //poll the busy bit

    VPFE_RESZ_PCR = 1; //enable the resizer

else

  asm("NOP");

}

 

What I see in video window 1 is just junk.  Eg some bizarre pattern of color bars which I suppose is simply whatever happens to reside at the address of the resizer output/video window 1 input.  I've tried playing with the configuration registers, but cannot seem to get the resizer to output the video I'd like to see.  Of perhaps meaningful significance: the pattern I see in video window 1 does not appear to change.  It's the same pattern no matter what I attempt to do...

Before I post exactly what I've written to every configuration register etc, can somebody tell me if what I'm trying to do here is fundamentally flawed?  Thanks for your time,

Dave

  • So a few more observations and some info:  it does not appear as though the resizer is dumping data to DDR.  After writing a few loops to dump a pattern into the video buffer for window 1 I realized that the patterns never change (eg nothing overwrites the data in the video buffer).

    Some info about my setup.  Data comes into the DSP from the video ADC in YUV 4:2:2 8 bit format.  This data is sent to DDR in 8 bit packed mode.  It's not totally clear to me whether or not the resizer can accept 8 bit YUV data (if not it's not clear to me how to solve this problem elegantly...).  In one of the documents I read it indicates in one paragraph that 8 bit YUV data is acceptable, but in 3.3 of Understanding the DaVinvi Resizer it states that it can only accept interleaved YUV (or color separate data).  In all cases here are the values I'm using to initialize the resizer's registers:

     hrsz = 510, vrsz = 509, iw = 723, ih = 480, oh = 240, ow = 360, and input source being ddr.  I copied these values (as well as corresponding filter coefficients) directly out of an example given that utilized the calccoef utility.

    I write the following resizer registers:

    VPFE_RESZ_RSZ_CNT
    VPFE_RESZ_OUT_SIZE
    VPFE_RESZ_IN_START
    VPFE_SDR_INADD
    VPFE_SDR_INOFF
    VPFE_SDR_OUTADD
    VPFE_RESZ_SDR_OUTOF
    VPFE_RESZ_YENH
    All filter coefficient registers

    Then I enable/poll as shown in the above post.

    Am I missing something here?  Even if I didn't get perfect values for filter ceofs/hrsz/vrsz I'd imagine that the video buffer should be modified even if it's with junk/bad data.  Any help would be much appreciated.  Thanks,

    Dave

  • What you are trying to do sounds reasonable and the registers you have seem ok, I suspect there is just an incorrect register setting somewhere with the resizing operation, as it seems you have already validated the display side.

    DG said:
    Even if I didn't get perfect values for filter ceofs/hrsz/vrsz I'd imagine that the video buffer should be modified even if it's with junk/bad data.

    I would agree, and expect at least something out in the viewable video output, one thing to keep in mind is that the cache on the DM6437 is not aware of operations being done by external accessors like the resizer or EDMA, so if you are just viewing data with CCS you need to invalidate the cache region your resizer output is going to. Beyond this I would check how you are initializing the resizer, and perhaps look at some existing resizer code for an example, in particular C:\dvsdk_1_11_00_00\pspdrivers_1_10_00\packages\ti\sdo\pspdrivers\drivers\resizer has code in it for setting up and running the resizer, though it is in the form of a BIOS driver it may still be of some help in your OS-less case.

  • Thanks for the reply.  I'll post my register settings come monday.  I've stared at them for a day or so now and am not seeing anything that's missing (but after a day of staring at the same thing it's totally possible it's just been over looked).  I'll take a peak at that directory as well.  Regarding the cache/how I "watch" the video buffer - I observe the video buffer via live view on a monitor.  Basically what I see is camera feed in three quarters of the screen and a box in the upper right quarter of the screen filled with whatever memory pattern resides in its video buffer space (I currently preload via a for loop 0x5555 - some midtone gray luminance -  to that address space).  One other observation I had was that the PCR register for the VPSS always seems to show an overflow on on bit 23 (CCDC overflow).  For fun I tried to poll/clear it, I've even tried to initialize it cleared (even though the datasheets say it should default to cleared).  No matter what I seem to do though it's stuck at 1.  I put in a software breakpoint right after initializing it (before initializing/running anything else) and it's still stuck at 1.  Is it at all possible that this is playing an effect on the resizer functionality?  Thanks,


    Dave

  • Apologies for taking so long in responding - I have been out of the office.

    I played around a bit more with the resizer and I cannot get it to function.  As mentioned above no matter what register settings I utilize I cannot get the resizer to even modify the buffer data which seems to me an indication that it never actually gets "turned on."  A question about the implementation of the resizer in hardware - if improper register values are used does the resizer disable itself?  This seems like a silly thing to implement in hardware so I'd be surprised to hear that the extra silicon was used for this feature, but it's the only explanation I can think of for why I cannot get a modified buffer.

    In all cases here is the code that is currently attempting to utilize the resizer.  I would greatly appreciate any help with this.  Thanks,

     

    Dave

     

    ps if there is a better way to attach code, please let me know...
    pps  If other code would be helpful/relevant (eg how I setup the VPBE/VPFE etc please let me know) 

    This is the segment of code that polls/enables the resizer in an infinite loop.  Note that I call a resizer initialization function (see below) before this.

     

     if((VPFE_RESZ_PCR & 0x00000003) == 0){

       _waitusec(10000);

       //printf("Got PCR not Busy!\n");

        VPFE_RESZ_PCR = 1;

     }

     else{

       _waitusec(10000);

     }

    This is the resizer init function that gets called.  It writes all the relevant registers, but does not enable the resizer.  For now i've hard coded the values for hrsz, iw, ih, vrsz, etc.  I based them off a simple excel spread sheet that given a "scaling factor" (in my case .5) will generate these values based off of the equations in the datasheet.

     

    /* C file for resizer */

     

    #include "resizer.h" //contains filter coefs

    #include "video_functions.h" //contains some defines used in this file

    /* Registers we need to play with:

       RSZ_CNT - resizer control parmas

       OUT_SIZE

       IN_START

       IN_SIZE

       SDR_INADD

       SDR_INOFF

       SDR_OUTADD

       SDR_OUTOFF

       HFILT[31:0]

       VFILT[31:0]

       YENH.ALG (edge enhancement)

     

       PCR.ENABLE - enables resizer after everythign else is written */

     

    void write_filter_regs(void)

    {

     

      VPFE_RESZ_HFILT10 |= horz_filter_coefs[0];

      VPFE_RESZ_HFILT10 |= horz_filter_coefs[1] << 16;

      VPFE_RESZ_HFILT32 |= horz_filter_coefs[2];

      VPFE_RESZ_HFILT32 |= horz_filter_coefs[3] << 16;

      VPFE_RESZ_HFILT54 |= horz_filter_coefs[4];

      VPFE_RESZ_HFILT54 |= horz_filter_coefs[5] << 16;

      VPFE_RESZ_HFILT76 |= horz_filter_coefs[6];

      VPFE_RESZ_HFILT76 |= horz_filter_coefs[7] << 16;

      VPFE_RESZ_HFILT98 |= horz_filter_coefs[8];

      VPFE_RESZ_HFILT98 |= horz_filter_coefs[9] << 16;

      VPFE_RESZ_HFILT1110 |= horz_filter_coefs[10];

      VPFE_RESZ_HFILT1110 |= horz_filter_coefs[11] << 16;

      VPFE_RESZ_HFILT1312 |= horz_filter_coefs[12];

      VPFE_RESZ_HFILT1312 |= horz_filter_coefs[13] << 16;

      VPFE_RESZ_HFILT1514 |= horz_filter_coefs[14];

      VPFE_RESZ_HFILT1514 |= horz_filter_coefs[15] << 16;

      VPFE_RESZ_HFILT1716 |= horz_filter_coefs[16];

      VPFE_RESZ_HFILT1716 |= horz_filter_coefs[17] << 16;

      VPFE_RESZ_HFILT1918 |= horz_filter_coefs[18];

      VPFE_RESZ_HFILT1918 |= horz_filter_coefs[19] << 16;

      VPFE_RESZ_HFILT2120 |= horz_filter_coefs[20];

      VPFE_RESZ_HFILT2120 |= horz_filter_coefs[21] << 16;

      VPFE_RESZ_HFILT2322 |= horz_filter_coefs[22];

      VPFE_RESZ_HFILT2322 |= horz_filter_coefs[23] << 16;

      VPFE_RESZ_HFILT2524 |= horz_filter_coefs[24];

      VPFE_RESZ_HFILT2524 |= horz_filter_coefs[25] << 16;

      VPFE_RESZ_HFILT2726 |= horz_filter_coefs[26];

      VPFE_RESZ_HFILT2726 |= horz_filter_coefs[27] << 16;

      VPFE_RESZ_HFILT2928 |= horz_filter_coefs[28];

      VPFE_RESZ_HFILT2928 |= horz_filter_coefs[29] << 16;

      VPFE_RESZ_HFILT3130 |= horz_filter_coefs[30];

      VPFE_RESZ_HFILT3130 |= horz_filter_coefs[31] << 16;

     

      VPFE_RESZ_VFILT10 |= vert_filter_coefs[0];

      VPFE_RESZ_VFILT10 |= vert_filter_coefs[1] << 16;

      VPFE_RESZ_VFILT32 |= vert_filter_coefs[2];

      VPFE_RESZ_VFILT32 |= vert_filter_coefs[3] << 16;

      VPFE_RESZ_VFILT54 |= vert_filter_coefs[4];

      VPFE_RESZ_VFILT54 |= vert_filter_coefs[5] << 16;

      VPFE_RESZ_VFILT76 |= vert_filter_coefs[6];

      VPFE_RESZ_VFILT76 |= vert_filter_coefs[7] << 16;

      VPFE_RESZ_VFILT98 |= vert_filter_coefs[8];

      VPFE_RESZ_VFILT98 |= vert_filter_coefs[9] << 16;

      VPFE_RESZ_VFILT1110 |= vert_filter_coefs[10];

      VPFE_RESZ_VFILT1110 |= vert_filter_coefs[11] << 16;

      VPFE_RESZ_VFILT1312 |= vert_filter_coefs[12];

      VPFE_RESZ_VFILT1312 |= vert_filter_coefs[13] << 16;

      VPFE_RESZ_VFILT1514 |= vert_filter_coefs[14];

      VPFE_RESZ_VFILT1514 |= vert_filter_coefs[15] << 16;

      VPFE_RESZ_VFILT1716 |= vert_filter_coefs[16];

      VPFE_RESZ_VFILT1716 |= vert_filter_coefs[17] << 16;

      VPFE_RESZ_VFILT1918 |= vert_filter_coefs[18];

      VPFE_RESZ_VFILT1918 |= vert_filter_coefs[19] << 16;

      VPFE_RESZ_VFILT2120 |= vert_filter_coefs[20];

      VPFE_RESZ_VFILT2120 |= vert_filter_coefs[21] << 16;

      VPFE_RESZ_VFILT2322 |= vert_filter_coefs[22];

      VPFE_RESZ_VFILT2322 |= vert_filter_coefs[23] << 16;

      VPFE_RESZ_VFILT2524 |= vert_filter_coefs[24];

      VPFE_RESZ_VFILT2524 |= vert_filter_coefs[25] << 16;

      VPFE_RESZ_VFILT2726 |= vert_filter_coefs[26];

      VPFE_RESZ_VFILT2726 |= vert_filter_coefs[27] << 16;

      VPFE_RESZ_VFILT2928 |= vert_filter_coefs[28];

      VPFE_RESZ_VFILT2928 |= vert_filter_coefs[29] << 16;

      VPFE_RESZ_VFILT3130 |= vert_filter_coefs[30];

      VPFE_RESZ_VFILT3130 |= vert_filter_coefs[31] << 16;

     

      printf("Finished Writing Filter Regs\n");

    }

     

    /* Calculate hrsz, vrsz, iw, and ih */

    void rsz_val_calc(float hscale, float vscale, Uint32 *vfactor, Uint32 *hfactor, Uint32 *iw, Uint32 *ih, Uint32 *ow, Uint32 *oh)

    {

      Uint32 hrsz, vrsz;

      hrsz = 510;//(WIDTH0 - 4)*256/(hscale*WIDTH0 - 1);

      vrsz = 509;//(HEIGHT0 - 4)*256/(vscale*HEIGHT0 - 1);

     

      printf("hrz = %d, vrz = %d\n", hrsz, vrsz);

     

        *iw = 723;//(((Uint32)(hscale*WIDTH0 - 1)*hrsz + 16) >> 8) + 7;

        *ih = 480;//(((Uint32)(vscale*HEIGHT0 - 1)*vrsz + 16) >> 8) + 4;

     

      printf("iw = %d, ih = %d\n", *iw, *ih);

     

      *vfactor = vrsz;

      *hfactor = hrsz;

     

      *oh = 240;

      *ow = 360;

    }

     

    /* Setup the resizer registers */

    void init_resizer(float hscale, float vscale)

    {

      Uint32 vfactor, hfactor, iw, ih, ow, oh;

      Uint8 upper_bits;

     

      /* RSZ_CNT Register Init */

      rsz_val_calc(hscale, vscale, &vfactor, &hfactor, &iw, &ih, &ow, &oh);

     

      upper_bits = 0x04; //use SDRAM as the input source to the resizer

     

      printf("hscale = %f, vscale = %f, hfactor = %d, vfactor = %d\n", hscale, vscale, hfactor, vfactor);

     

      VPFE_RESZ_RSZ_CNT = 0;

      VPFE_RESZ_RSZ_CNT |= hfactor;

      VPFE_RESZ_RSZ_CNT |= (vfactor << 10);

      VPFE_RESZ_RSZ_CNT |= (upper_bits << 26);

     

      /* VPFE_OUT_SIZE Register Init */

      VPFE_RESZ_OUT_SIZE = 0;

      VPFE_RESZ_OUT_SIZE |= ow;//(int)(hscale * WIDTH0);

      VPFE_RESZ_OUT_SIZE |= oh << 16;//((int)(vscale * HEIGHT0)) << 16;

     

      /* IN_START Register Init */

      VPFE_RESZ_IN_START = 0;

     

      /* IN_SIZE Register Init */

      VPFE_RESZ_IN_SIZE = 0;

      VPFE_RESZ_IN_SIZE |= iw;//WIDTH0;

      VPFE_RESZ_IN_SIZE |= (ih << 16);//HEIGHT0 << 16;

     

      /* SDR_INADD Register Init */

      VPFE_RESZ_SDR_INADD = VIDEO_BUFFER0;

     

      /* SDR_INOFF Register Init */

      VPFE_RESZ_SDR_INOFF = 0;

     

      /* SDR_OUTADD Register Init */

      VPFE_RESZ_SDR_OUTADD = RESIZER_OUT_BUFFER;

     

      /* SDR_OUT_OFF Reg */

      VPFE_RESZ_SDR_OUTOFF = 0;

     

      /* Filter Coefs */

      write_filter_regs();

     

      /* Luminance Enhancer */

      VPFE_RESZ_YENH = 0;

     

      printf("PCR = %x\n", VPFE_RESZ_PCR);

      printf("RSZ_CNT = %X\n", VPFE_RESZ_RSZ_CNT);

      printf("RSZ_OUT_SIZE = %X\n", VPFE_RESZ_OUT_SIZE);

      printf("RSZ_IN_SIZE = %x\n", VPFE_RESZ_IN_SIZE);

    }

     

     

     

     

     

  • A bit more about the excel sheet I made to fill in the iw/ih, hrsz/vrsz registers based on input image width/height and desired image width/hight.  I based the calculations on the equations found in the datasheet.  If I understand correctly then I am to choose an input/output frame size based on whatever sits around the resizer (eg in my case in = 720 x 480 and out is arbitrarily 360 x 240).  I plug these into equations 10/11 in SPRAAI7B (page 17).  I then take hrsz and vrsz and plug them into equations 9/10 in order to get the value of iw/ih that I should actually put into the resizer registers.  Anyway the excel sheet solves the equations for me based on actual input image width/height and desired output image width/height.

    Again, thanks for your help...much appreciated.

    Dave

    0268.resizer.xls