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.

[DM365] Can Capture port handle slicing-based capture @ 720p60?

I understand that the driver would need modification to support this, but can the actual hardware support this? My primary concern is whether or not the hardware syncs are in place to support this.

  • Tim,

    Did you get a chance to see this similar post http://e2e.ti.com/support/dsp/davinci_digital_media_processors/int-dm3x/f/102/p/8989/36247.aspx#36247?

    There is a remaining throughput appnote attached to it, this has not been appended to the current dm365 throughput appnote but it contains several hardware support scenarios that provide the video port throughput details. I am not sure if the 'slicing-based' capture was used or not though.

    regards,

    miguel

     

  • Miguel,

    I did not find this before so thank you for pointing it out. I feel confident that the hardware can handle the amount of data, but the concern here is whether or not the hardware (syncs) can support slicing so as to allow us to minimize latency.

  • hi Tim,

    In order to support "slice based" capture HW needs to inform the SW after every "N" number of lines have been captured.

    With this information SW can then trigger subseqeunt video processing blocks.

    In DM365 we have 3 VDINT's which can be programmed independantly to occur after some "X" lines from the start of a frame.

    Also in addition to these 3 interrupts there is resizer EOF interrupt to indicate the end of frame.

    As an example for 1280x720 size input frames we can configure

    VDINT0 to occur after 180 lines

    VINT1 to occur after 360 lines

    VINT2 to occur after 540 lines

    Resizer EOF will occur at 720 lines

     

    Thus you can slice the incoming frame into atmost 4 parts using the DM365 HW.

    Ofcourse this is from hardware point of view, TI doesnt not have SW driver which is capable of doing this.

    But this is relatively straightforward to do once the interrupts are setup

     

    regards

    Kedar

     

  • Hi Kedar, All,

    I am trying to implement the 4 part slicing suggested by Kedar, using VDINT0, VDINT1, VDINT2. I have been looking at the kernel code and the VPFE register guide for DM365 (http://www.ti.com/litv/pdf/sprufg8b) and have some questions on implementation:

     

    1) I already see vdint0, 1 registers configured to 0 and half of number of rows in frame, in ccdc_setwin function in ....\kernels\ti-davinci-psp-2.10.00.14\drivers\media\video\davinci\ccdc_dm365.c

    This confuses me because I also see vdint0 and vdint1 interrupts in INTSEL1 register enabled in

    a) dm365_enable_irq function calls, around line 871 in ...\kernels\ti-davinci-psp-2.10.00.14\arch\arm\mach-davinci\vpss.c
    b) Line 609 of ...\kernels\ti-davinci-psp-2.10.00.14\drivers\media\video\davinci\vpss.c

    Is the capture driver already doing half frame captures today or is there something I am missing?

     

    2) the sample app we have for capture and encode seems to indicate frame level capture by capture thread, fifo put and then fifo get by video thread. This seems to contradict #1 above.

     

    3) Looks like to enable interrupts for vdint0,1,2 I have to enable bits 0,1,2 in INTSEL1 register. This is in addition to programming the row numbers in VDINT0,1,2 registers.

    However, I am not sure whether it is INTSEL1 register or EVTSEL register in this situation that I have to enable bits for (they are identical and the documentation does not indicate the purpose of EVTSEL vs INTSEL1).

     

    4) if the VDINT0,1,2 are programmed to happen at quarter frame spacings, then will each buffer returned by capture driver Capture_get() call have the exact content (of 180 rows in Kedar's example), or will have incremental content (first call returns first 180 rows, then second calls returns first 180 rows and next 180 rows, and so on) ?

    Could someone please help me with suggestions on implementation details (which files in kernel to modify, and which registers to program) ? The VPFE registers description is not clear on how to go about this...


    Thanks in advance.

     

  • hi Vivek,

    1. No driver is not doing half-frame capture.

    In the driver
    - when "half-frame" interrupt is received, new buffer address is written to register but current buffer is not released since only half the buffer is captured.
    - new buffer address is effective only on the next Vsync
    - when the "0-th line" interrupt happens next the current buffer is released since now it captured completely
    - at the same time HW applies the new buffer address and next frame data gets written to new buffer address.

    This was strictly not required. Driver could have used only one interrupt with the interrupt comfigured to happen at line "active data height-1". This way current buffer release and new buffer address change could happen in the same ISR.

    2. See 1 above.

    3. You need to set INTSEL1 register. EVTSEL register is when you want to trigger some EDMA based on the VDINT "event". Typically we dont find the need to use EVTSEL with VPFE so you can ignore it.

    4. VDINTx will just indicate to the SW that Nx lines have been captured. Where Nx is value programmed for VDINTx. After this I think you will basically need to have your own software logic. I dont think it will fit in current driver logic.

    regards
    Kedar

     

     

  • Hi, I'm also attempting to implement the frame slicing as you described, in order to decrease the latency of capture and encode. 

    I'm experiencing an issue when making a call to "platform_get_resource" in vpfe_capture.c.  I added the following code, below VDINT0 and VDINT1, to get an interrupt for VDINT2:

     

        /* Get VINT0 irq resource */
        res1 = platform_get_resource(pdev,IORESOURCE_IRQ, 0);
        if (!res1) {
            v4l2_err(pdev->dev.driver,
                 "Unable to get interrupt for VINT0\n");
            ret = -ENOENT;
            goto probe_disable_clock;
        }
        vpfe_dev->ccdc_irq0 = res1->start;
        v4l2_info(pdev->dev.driver,"Got interrupt for VINT0\n");
        v4l2_info(pdev->dev.driver,"vpfe_dev->ccdc_irq0 = %d \n",vpfe_dev->ccdc_irq0);
     
        /* Get VINT1 irq resource */
        res1 = platform_get_resource(pdev,IORESOURCE_IRQ, 1);
        if (!res1) {
            v4l2_err(pdev->dev.driver,
                 "Unable to get interrupt for VINT1\n");
            ret = -ENOENT;
            goto probe_disable_clock;
        }
        vpfe_dev->ccdc_irq1 = res1->start;
        v4l2_info(pdev->dev.driver,"Got interrupt for VINT1\n");
        v4l2_info(pdev->dev.driver,"vpfe_dev->ccdc_irq1 = %d \n",vpfe_dev->ccdc_irq1);

        /* Get VINT2 irq resource */
        res1 = platform_get_resource(pdev,IORESOURCE_IRQ, 2);
        if (!res1) {
            v4l2_err(pdev->dev.driver,
                 "Unable to get interrupt for VINT2\n");
            ret = -ENOENT;
            goto probe_disable_clock;
        }
        vpfe_dev->ccdc_irq2 = res1->start;
        v4l2_info(pdev->dev.driver,"Got interrupt for VINT2\n");
        v4l2_info(pdev->dev.driver,"vpfe_dev->ccdc_irq2 = %d \n",vpfe_dev->ccdc_irq2);

     

    On boot up, I get the following printout:

    vpfe-capture: Got interrupt for VINT0
    vpfe-capture: vpfe_dev->ccdc_irq0 = 0
    vpfe-capture: Got interrupt for VINT1
    vpfe-capture: vpfe_dev->ccdc_irq1 = 1
    vpfe-capture: Unable to get interrupt for VINT2
    vpfe-capture: vpfe capture clocks disabled
    vpfe-capture: probe of vpfe-capture failed with error -2
    vpfe_register_ccdc_device: DM365 ISIF
    dm365_isif: probe of dm365_isif failed with error -22

     

    It doesn't seem to be able to get an interrupt resource for VDINT2.  I also modified the INTSEL1 register in vpss.c to the following:

        /* INT0, INT1, INT2, AF */
        isp5_write((isp5_read(0x10) | 0x0b020100), 0x10);

    This should set INTSEL2 field within the register to ISIF_INT2. 

    Any ideas why the call to "platform_get_resource" is failing?

    Thanks!

    Derek

  • Hi, I figured out what's causing the issue: pdev->num_resources is set to 2 and so a function call of "res1 = platform_get_resource(pdev,IORESOURCE_IRQ, 2);" would return a NULL pointer in this case.  If I can find where pdev->num_resources is being set to 2 and modify it to 3, then I should be able to get VDINT2 working.

    Thanks
    Derek

  • Hi, I got VDINT2 working.  There was a pre-defined platform device for vpfe-capture located in arch/arm/mach-davinci/dm365.c.  Above it were the resource declarations for VDINT0 and VDINT1.  I added in VDINT2 and it was able to grab the resource from the call in vpfe_capture.c.

    Thanks!

    Derek

  • Hi Kedar/All,

    I'm working on the 4 part slicing and the behavior is slightly different than what's described for item 1.  Can I get a hand to understand what the behavior is doing on my end?

    I'm using a DM368 EVM rev G, DVSDK is 4.2.0.6, linux is 2.6.32.17 and psp is 3.1.1.39.

    I managed to configure the 3 VDINT interrupts to occur at 1/4, 1/2 and 3/4 frame spacing.  I'm now working on enabling the EOF interrupt, however, there is an interrupt already happening, which I'm not really sure when it's occuring.  I'm wondering if I can use it instead of the resize EOF or whether to disable it and use the resize EOF instead.

    In /drivers/media/davinci/vpss.c, there is an interrupt configured in INTSEL2 register, labelled RSZ_INT_DMA:

         isp5_write((isp5_read(0x14) | 0x1f0a0f1f), 0x14);

    The VPFE user guide indicates that it's reserved (section 3.2 Hardware Requests, Event Number 15).  The supporting ISR, vpfe_imp_dma_isr, is found in /drivers/media/video/davinci/vpfe_capture.c. 

    My assumption is that this interrupt triggers once the resizer has finished its dma transfer of the frame back to sdram.  Is that right? 

    It looks like the old behavior was that VDINT0 would trigger at vert_nr_lines or height - 1 (719 lines).  Once it triggered, it would call vpfe_process_buffer_complete, which sets the current frame state to done, releases the current buffer and assigns new buffer to current buffer.

    The RSZ_INT_DMA interrupt calls schedule_next_buffer, which grabs the next frame from the queue and writes the new buffer address to register.  So the behavior of the RSZ_INT_DMA interrupt seems similar to what the "half_frame" interrupt was doing as described above.  It simply happens at a different time interval.

    Any recommendations whether to use this interrupt or the resize EOF? 

    Thanks!

    Derek

  • Hi, found a note about RSZ_INT_DMA hidden in section 4.3.11.5, which indicates that this interrupt is issued at the same time as RSZ_EOF... so it seems either one will work

    Derek

  • Hi Derek,

    Derek Richardson said:

    Hi, found a note about RSZ_INT_DMA hidden in section 4.3.11.5, which indicates that this interrupt is issued at the same time as RSZ_EOF... so it seems either one will work

    Sorry for the delay in replying. You are right, RSZ_INT_DMA is actually the completion interrupt that is triggered when the complete output frame is written to DDR. This is not really related to the actual VSYNC of pixel clock. For all practical purposes you can use this, but this interrupt is different from the EOF interrupt related to the input pixel clock. You can as well use other EOF interrupts listed in the VPFE documentation.

    Regards,

    Anshuman

    PS: Please mark this post as verified, if you think it has answered your question. Thanks.

  • Hi Anshuman, thanks again

    That's a good point, the 3 VDINT interrupts trigger with respect to VSYNC and the RSZ_INT_DMA doesn't.  That's fine, although this most likely means that the number of lines captured and the number lines as output by the resizer are different then. 

    I'm wondering then how to slice vpfe_dev->cur_frame (vpfe_capture.c) into the 4 parts using these 4 interrupts. 

    vpfe_dev->cur_frame->baddr indicates where the frame is in memory.  Resolution we're working with is 1280x720 and vpfe_dev->cur_frame->bsize shows 1382400.  

    When VDINT0 triggers, can I release a slice buffer of size vpfe_dev->cur_frame->bsize/4 with address set to vpfe_dev->cur_frame->baddr?  This would make VDINT1 slice buffer's address vpfe_dev->cur_frame->baddr + 1382400/4,  VDINT2 slice buffer address vpfe_dev->cur_frame->baddr +1382400/2 and finally, RSZ_INT_DMA's slice buffer address would then be vpfe_dev->cur_frame->baddr + 1382400*3/4.

    I guess it depends how the raw frame is stored in memory, whether vpfe_dev->cur_frame->baddr + 1382400/4 gives me a pointer to line 180, vpfe_dev->cur_frame->baddr +1382400/2 a pointer to line 360 and vpfe_dev->cur_frame->baddr + 1382400*3/4 to line 540 in the frame.   Any insights here?

    The other issue would be ensuring that 180 lines have been processed by the resizer before releasing the slice.  As mentioned, VDINT0 doesn't line up with the number of lines processed by the resizer.  Is there any way to tell how many lines have been processed in the current frame, other than RSZ_INT_CYC_RZA?

    If there's any other insights into how to slice the frame using the 4 interrupts, they would be greatly appreciated!

    Thanks alot

    Derek

  • Hi again, a few insights I've gathered so far:

    The colorspace is being set to YUV420PSEMI.  In capture.c for dmai, the image size is computed as bytesperline x height + (bytesperline x (height / 2)), where bytesperline is computed as ((width + 31) & ~31).  So, for 1280x720, bytesperline computes to 1280 and image size to 1382400.  Does that mean one frame of YUV420PSEMI at 1280x720 is exactly 1382400 bytes?  Is it being stored in memory as per 4.3.11.7.2 of the vpfe?

    I'm still wondering how to slice the frame buffer into the 4 parts (vpfe_dev->cur_frame) before releasing it from the capture driver.

    Derek