NOTICE: The Processors Wiki will End-of-Life on January 15, 2021. It is recommended to download any files or other content you may need that are hosted on processors.wiki.ti.com. The site is now set to read only.

PDK/PDK VPS Capture Driver User Guide

From Texas Instruments Wiki
Jump to: navigation, search

Introduction[edit]

VIP capture driver makes use of VIP hardware block in Tda2xx to capture data from external video source like video decoders (example, TVP5158, SIL9127) or sensors (example OV1063X). The video data is captured from the external video source by the VIP Parser sub-block in the VIP block. The VIP Parser then sends the captured data for further processing in the VIP block which can include colour space conversion, scaling, chroma down sampling and finally writes the video data to external DDR memory or an OCMC buffer.

The data paths supported by the current driver implementation are shown in the below figure:

Important
The 422 secondary path and HDCOMP (RGB) path as shown in the figure below are wired out for Tda2xx.


Vip-capture-paths.png


Features supported[edit]


Features

Supported in Tda2xx
Supported in TI814x
Input Video Source Formats


YUV422 8-bit embedded sync mode
YES
YES
YUV422 16-bit embedded sync mode
NOT TESTED
YES
RGB 24-bit embedded sync mode
NOT TESTED
NOT TESTED
YUV422 8-bit discrete sync mode
YES
NOT TESTED
YUV422 16-bit discrete sync mode
YES
YES
RGB 24-bit discrete sync mode
NOT TESTED
NOT TESTED
YUV422 8-bit 2x/4x pixel multiplxed mode
NO
NO
YUV422 8-bit 4x line multiplexed mode
NO
NO
YUV422 8-bit 4x split-line multiplexed mode
NO
NO
YUV444 24-bit embedded/discrete sync mode
NOT TESTED
NOT TESTED
Output Video formats


YUV422 YUYV interleaved format
YES
YES
YUV420 Semi-planer format
YES
YES
RGB 24-bit interleaved format
YES
YES
YUV422 Semi-planer format
YES
NO
In-line video processing features


Color space conversion
YES
YES
Down-Scaling
YES
YES
Chroma-down sampling
YES
YES
Other features


Multi-instance (VIP1, VIP2, VIP3), multi-slice (S0, S1), multi-port capture (Port A, Port B), with ability to configure each instance, port independently
YES
YES
Interlaced as well as progressive capture
YES
YES
Per frame info to user like - field ID, captured frame width x height, timestamp, logical channel ID
YES
YES
Frame-rate depends on external video source, no limitation in driver as such
YES
YES
For RGB input, optional color space conversion to YUV is supported
NOT TESTED
NOT TESTED
For RGB input with color space conversion to YUV enabled, optional scaling is supported
NOT TESTED
NOT TESTED
For YUV input, optional color space conversion to RGB is supported
YES
NOT TESTED
For YUV input, optional scaling is supported
YES
YES
For YUV input, optional chroma downsampling is supported
YES
YES
Per channel frame-dropping. Example, for a 60fps video source, 30fps, 15fps, 7fps capture
YES
YES
Ability to change scalar parameters while capture is running
NO
NO
Single source (RGB 24-bit or YUV422 8/16-bit), dual output (RGB 24-bit and/or YUV422 and/or YUV420)
support. See table below for support combinations
YES
NO
Raw VBI capture for single/multi channel modes
NO
NO
Non-blocking FVID2 queue, dequeue API support
YES
YES
Possible to configure VIP port for different video input source properties like Hsync polarity, Vsync polarity, PCLK polarity
YES
YES
Tiler memory support when output type is YUV420 semi-planer
NOT TESTED
NOT TESTED
Sub-frame based capture
YES
YES
  • In the table above,
    Support = YES, means feature has been tested with current driver on current platform board/EVM.
    Support = NO, means feature is not supported in current driver and using it will give unpredictable results. Feature is planned to be supported in future releases.
    Support = NOT TESTED, means feature is present in driver but has NOT been tested on due to current platform board/EVM limitations AND/OR is planned to be tested in subsequent releases.


Input to Output Combinations support[edit]

Input Format Output format - 0 Output format - 1 Supoprt in Tda2xx
YUV422 8/16-bit embedded/discrete sync mode










YUV422 YUYV interleaved format (optionally scaled)
NONE
YES
YUV420 Semi-planer format (optionally scaled)
NONE
YES
RGB 24-bit interleaved format (via CSC)
NONE
YES
YUV422 Semi-planer format (optionally scaled)
NONE
YES
YUV422 YUYV interleaved format (one output optionally scaled)
YUV420 Semi-planer format (one output optionally scaled)
YES
YUV422 YUYV interleaved format (optionally scaled)
RGB 24-bit interleaved format (via CSC)
YES
YUV422 YUYV interleaved format (one output MUST BE scaled)
YUV422 YUYV interleaved format (one output MUST be scaled)
YES
YUV422 Semi-planer format (one output optionally scaled)
YUV422 YUYV interleaved format (one output optionally scaled)
YES
YUV420 Semi-planer format (one output MUST be scaled)
YUV420 Semi-planer format (one output MUST be scaled)
YES
YUV420 Semi-planer format (optionally scaled)
RGB 24-bit interleaved format (via CSC)
YES

YUV444 24-bit embedded/discrete sync mode
NA
NA
NO
RGB 24-bit discrete sync mode (CSC is used when output format is YUV)




YUV422 YUYV interleaved format (optionally scaled)
NONE
NOT TESTED
YUV420 Semi-planer format (optionally scaled)
NONE
NOT TESTED
RGB 24-bit interleaved format
NONE
NOT TESTED
YUV422 Semi-planer format (optionally scaled)
NONE
NO
YUV422 YUYV interleaved format (one output optionally scaled)






YUV420 Semi-planer format (one output optionally scaled)
NOT TESTED
YUV422 YUYV interleaved format (optionally scaled)
RGB 24-bit interleaved format
NOT TESTED
YUV422 YUYV interleaved format (one output MUST BE scaled)
YUV422 YUYV interleaved format (one output MUST be scaled)
NOT TESTED
YUV422 YUYV interleaved format (one output optionally scaled)
YUV422 Semi-planer format (one output optionally scaled)
NO
YUV420 Semi-planer format (one output MUST be scaled)
YUV420 Semi-planer format (one output MUST be scaled)
NOT TESTED
RGB 24-bit interleaved format
YUV420 Semi-planer format (optionally scaled)
NOT TESTED
YUV420 Semi-planer format (one output optionally scaled)
YUV422 Semi-planer format (one output optionally scaled)
NO

RGB 16-bit discrete sync mode (CSC is used when output format is YUV)




YUV422 YUYV interleaved format (optionally scaled)
NONE
NOT TESTED
YUV420 Semi-planer format (optionally scaled)
NONE
NOT TESTED
RGB 24-bit interleaved format
NONE
NOT TESTED
YUV422 Semi-planer format (optionally scaled)
NONE
NOT TESTED
YUV422 YUYV interleaved format (one output optionally scaled)






YUV420 Semi-planer format (one output optionally scaled)
NOT TESTED
YUV422 YUYV interleaved format (optionally scaled)
RGB 24-bit interleaved format
NOT TESTED
YUV422 YUYV interleaved format (one output MUST BE scaled)
YUV422 YUYV interleaved format (one output MUST be scaled)
NOT TESTED
YUV422 YUYV interleaved format (one output optionally scaled)
YUV422 Semi-planer format (one output optionally scaled)
NOT TESTED
YUV420 Semi-planer format (one output MUST be scaled)
YUV420 Semi-planer format (one output MUST be scaled)
NOT TESTED
YUV420 Semi-planer format (optionally scaled)
RGB 24-bit interleaved format
NOT TESTED
YUV420 Semi-planer format (one output optionally scaled)
YUV422 Semi-planer format (one output optionally scaled)
NOT TESTED

RGB 8-bit discrete sync mode (CSC is used when output format is YUV)




YUV422 YUYV interleaved format (optionally scaled)
NONE
NOT TESTED
YUV420 Semi-planer format (optionally scaled)
NONE
NOT TESTED
RGB 24-bit interleaved format
NONE
NOT TESTED
YUV422 Semi-planer format (optionally scaled)
NONE
NOT TESTED
YUV422 YUYV interleaved format (one output optionally scaled)








YUV420 Semi-planer format (one output optionally scaled)
NOT TESTED
YUV422 YUYV interleaved format (optionally scaled)
RGB 24-bit interleaved format
NOT TESTED
YUV422 YUYV interleaved format (one output MUST BE scaled)
YUV422 YUYV interleaved format (one output MUST be scaled)
NOT TESTED
YUV422 YUYV interleaved format (one output optionally scaled)
YUV422 Semi-planer format (one output optionally scaled)
NOT TESTED
YUV420 Semi-planer format (one output MUST be scaled)
YUV420 Semi-planer format (one output MUST be scaled)
NOT TESTED
YUV420 Semi-planer format (optionally scaled)
RGB 24-bit interleaved format
NOT TESTED
YUV420 Semi-planer format (one output optionally scaled)
YUV422 Semi-planer format (one output optionally scaled)
NOT TESTED

RGB 24-bit embedded sync mode (CSC is used when output format is YUV)
YUV422 YUYV interleaved format (optionally scaled)
NONE
NOT TESTED
YUV420 Semi-planer format (optionally scaled)
NONE
NOT TESTED

RGB 24-bit interleaved format
NONE
NOT TESTED
YUV422 Semi-planer format (optionally scaled)
NONE
NO
YUV422 YUYV interleaved format (one output optionally scaled)
YUV420 Semi-planer format (one output optionally scaled)
NOT TESTED
YUV422 YUYV interleaved format (optionally scaled)
RGB 24-bit interleaved format
NOT TESTED
YUV422 YUYV interleaved format (one output MUST BE scaled)
YUV422 YUYV interleaved format (one output MUST be scaled)
NOT TESTED
YUV422 YUYV interleaved format (one output optionally scaled)
YUV422 Semi-planer format (one output optionally scaled)
NO
YUV420 Semi-planer format (one output MUST be scaled)
YUV420 Semi-planer format (one output MUST be scaled)
NOT TESTED
RGB 24-bit interleaved format
YUV420 Semi-planer format (optionally scaled)
NOT TESTED
YUV420 Semi-planer format (one output optionally scaled)
YUV422 Semi-planer format (one output optionally scaled)
NO
  • In the table above,
    Support = YES, means feature has been tested with current driver on current platform board/EVM.
    Support = NO, means feature is not supported in current driver and using it will give unpredictable results. Feature is planned to be supported in future releases.
    Support = NOT TESTED, means feature is present in driver but has NOT been tested on due to current platform board/EVM limitations AND/OR is planned to be tested in subsequent releases.

Limitations/Issues[edit]

  • There are limiations in capture driver for features like video source cable disconnect/connect, discrete sync mode, VIP parser overflow, Chroma downsampling. These limiations are related to Si issues. Please refer to Si Errata document to get latest update and workarounds for these issues.


Software Application Interfaces[edit]

The driver operation can be partitioned into the below phases:

  • System Init Phase: Here the driver sub-system is initialized
  • Create Phase: Here the driver handle is created or instantiated
  • Control Phase: Control call to set the capture parameters. Here the driver, core and hal is initialized with the instance related setup parameters.
  • Run Phase: Here the driver is used to capture, process and release frames continuously
  • Delete Phase: Here the driver handle or instance is deallocated
  • System De-init Phase: Here the driver sub-system is de-initialized

The subsequent sections describe each phase in detail.

System Init Phase[edit]

The VIP capture driver sub-system initialization happens as part of overall system init. Below code shows the FVID2 API used to initialize the overall Capture subsystem. This API must be the the first API call before making any other FVID2 calls.

An example is shown below. Also shown in the example there is a FVID2 create API call to create the global VIP capture handle. This handle, as shown later, can be used to queue, dequeue frames from all active VIP ports. In the below example, prior to the global VIP capture handle creation, BspUtils_appDefaultInit() routine is called. This function initializes the board, platform, fvid2, i2c, device drivers.

static void CaptApp_init(CaptApp_Obj *appObj)
{
    Int32  retVal;
    UInt32 isI2cInitReq;

    /* System init */
    isI2cInitReq = TRUE;
    retVal       = BspUtils_appDefaultInit(isI2cInitReq);
    if (retVal != FVID2_SOK)
    {
        GT_0trace(BspAppTrace, GT_ERR,
                  APP_NAME ": System Init Failed!!!\n");
        return;
    }

    /* Create global capture handle, used for common driver configuration */
    appObj->fvidHandleAll = Fvid2_create(
        FVID2_VPS_CAPT_VID_DRV,
        VPS_CAPT_INST_ALL,
        NULL,                           /* NULL for VPS_CAPT_INST_ALL */
        NULL,                           /* NULL for VPS_CAPT_INST_ALL */
        NULL);                          /* NULL for VPS_CAPT_INST_ALL */
    if (NULL == appObj->fvidHandleAll)
    {
        GT_0trace(BspAppTrace, GT_ERR,
                  APP_NAME ": Global Handle Create Failed!!!\n");
        return;
    }

    GT_0trace(BspAppTrace, GT_INFO,
              APP_NAME ": CaptApp_init() - DONE !!!\n");

    return;
}

Create Phase[edit]

In this phase user application opens or creates a driver instance. A driver instance is associated with one or more VIP instances, slices and parser ports depending on whether the operation mode is 8-bit or 16-bit or 24-bit. Based on the VIP instance, slice and port information user can use the below routine to compute the instanceId to be passed to the Fvid2_Create() routine.

/**
 *  \brief Macro to generate VIP capture driver instance ID to be passed
 *  during create parameter.
 *
 *  vipId   -   VPS_VIP1, VPS_VIP2 or VPS_VIP3<br>
 *  sliceId -   VPS_VIP_S0 or VPS_VIP_S1<br>
 *  portId  -   VPS_VIP_PORTA or VPS_VIP_PORTB
 */
#define VPS_CAPT_VIP_MAKE_INST_ID(vipId, sliceId, portId) \
    ((portId) +                                           \
     ((sliceId) * (VPS_VIP_PORT_MAX)) +                   \
     ((vipId) * (VPS_VIP_SLICE_MAX * VPS_VIP_PORT_MAX)))

Control Phase[edit]

In this phase, user application provides the detailed set of capture VIP parameters to the driver.

       retVal = Fvid2_control(
            instObj->drvHandle,
            IOCTL_VPS_CAPT_SET_VIP_PARAMS,
            &instObj->vipPrms,
            NULL);

Driver Instance to hardware port mapping for different bus-widths[edit]

The mapping of driver instance to VIP parser ports in HDVPSS is shown below:

VIP Instance
Slice Id
Port Id
8-bit interface
16-bit interface
24-bit interface
VIP 1
Slice 0
Port A
VIP1 S0 PortA
VIP1 S0 PortA
VIP1 S0 PortA
VIP 1
Slice 0
Port B
VIP1 S0 PortB
NOT USED
NOT USED
VIP 1
Slice 1
Port A
VIP1 S1 PortA
VIP1 S1 PortA
VIP1 S1 PortA
VIP 1
Slice 1
Port B
VIP1 S1 PortB
NOT USED
NOT USED
VIP 2
Slice 0
Port A
VIP2 S0 PortA
VIP2 S0 PortA
VIP2 S0 PortA
VIP 2
Slice 0
Port B
VIP2 S0 PortB
NOT USED
NOT USED
VIP 2
Slice 1
Port A
VIP2 S1 PortA
VIP2 S1 PortA
VIP2 S1 PortA
VIP 2
Slice 1
Port B
VIP2 S1 PortB
NOT USED
NOT USED
VIP 3
Slice 0
Port A
VIP3 S0 PortA
VIP3 S0 PortA
VIP3 S0 PortA
VIP 3
Slice 0
Port B
VIP3 S0 PortB
NOT USED
NOT USED
VIP 3
Slice 1
Port A
VIP3 S1 PortA
VIP3 S1 PortA
VIP3 S1 PortA
VIP 3
Slice 1
Port B
VIP3 S1 PortB
NOT USED
NOT USED


Output streams[edit]

A maximum of four output streams (including VBI capture) are possible from the capture driver in non-multiplexed modes of capture. Data from each stream can be independently queued/dequeued when capture data streaming is enabled using Fvid2_start().

Refer to table in previous section for valid supported input / output combinations for different input source formats.

Example of streams are:

  • Single source dual format capture - YUV420 capture (stream 0) + RGB capture (stream 1)
  • Ancillary data capture - YUV422 capture (stream 0) + VBI capture (stream 1)

NOTE
Channel is different from stream in the sense that channel is associated with a distinct input source. For different output streams the input source (or channel) is the same, however the final output format - data format (RGB, YUV422, YUV420), or resolution, or data type (VBI, active data) - is different for each output stream. Thus when capturing 4CH D1 through one VIP port, number of valid channels will be four and output streams would be one (YUV422 format). However when capturing single channel 24-bit RGB, number of output streams can be three - YUV420 (stream 0), RGB 24-bit (stream 1), Ancillary data (stream 3).  Currently multi-channel or muxed mode capture is not supported by the VIP driver.


NOTE
If FVID2_DF_YUV422SP_UV is used as output format, it must be the first output format (output format at the index 0 in outStreamInfo of Vps_CaptVipParams). 


Run Phase[edit]

In this phase the driver can be used to start capture and continuously capture (dequeue) frame buffers from the driver and then process them and release (queue) them back to the driver.

Start and stop[edit]

Below API is used to start the capture. Once capture is started other FVID2 APIs can be used to dequeue and queue frame's continuously from the capture driver.

    /* Start driver */
    for (instCnt = 0u; instCnt < appObj->testPrms.numHandles; instCnt++)
    {
        instObj = &appObj->instObj[instCnt];

        retVal = Fvid2_start(instObj->drvHandle, NULL);
        if (retVal != FVID2_SOK)
        {
            GT_0trace(BspAppTrace, GT_ERR,
                      APP_NAME ": Capture Start Failed!!!\n");
            return;
        }
    }

Below API is used to stop the capture. Capture can be started once again by using the FVID2 start API without having to create the driver once again.

    /* Stop driver */
    for (instCnt = 0u; instCnt < appObj->testPrms.numHandles; instCnt++)
    {
        instObj = &appObj->instObj[instCnt];
        retVal  = Fvid2_stop(instObj->drvHandle, NULL);
        if (retVal != FVID2_SOK)
        {
            GT_0trace(BspAppTrace, GT_ERR,
                      APP_NAME ": Capture Stop Failed!!!\n");
            return;
        }
    }

Dequeueing-Queuing frames[edit]

Once the capture is started as described above, below API can be used to dequeue captured frames from the capture driver. Once capture is started it starts capturing data in the frame buffer's allocated and queued during create phase. Once a frame is captured completely, it queue's the captured frame to its "completed" frame queue. Now when user calls dequeue the captured frames are given to the user application.

A single dequeue call can be used to dequeue multiple captured frames from multiple channels associated with that handle. Similarly a single queue can used to return multiple frames from different channels associated with that handle back to driver.

Example: Non-blocking dequeue from stream 0 for a capture handle

The API used is a non-blocking API, i.e. API will return immediately with zero or more captured buffers. 

#include "ti/psp/vps/vps_capture.h"

Fvid2_FrameList       frameList;

status = Fvid2_dequeue(fvidHandle, & frameList, 0, BIOS_NO_WAIT);
if(status!=FVID_SOK) {
  // error in dequeue-ing frames from capture handle
} else {
  // success, received 0 or more frames
  printf(" Received %d frames\n", frameList.numFrames);
}

Example: Dequeue from all active handles using a single API

The global VIP handle, fvidHandleVipAll, is created by user during system init and can be used to dequeue/queue frames from all active (created) capture handles. 

#include "ti/psp/vps/vps_capture.h"

Fvid2_FrameList       frameList;

status = Fvid2_dequeue(fvidHandleVipAll, & frameList, 0, BIOS_NO_WAIT);
if(status!=FVID_SOK) {
  // error in dequeue-ing frames from capture handle
} else {
  // success, received 0 or more frames
  printf(" Received %d frames\n", frameList.numFrames);
}

Example: Queue captured (dequeued) frames back to the driver

The frame dequeued would typically be processed by user application like encoding, scaling etc and once user is done with the frame, user application should queue the frames back to the driver as shown below. Instead of instance specifc handle shown below, the global VIP capture driver handle can also be used to queue the frame back to the correct driver instance without the user having to worry about which handle the frames belong to.

#include "ti/psp/vps/vps_capture.h"

Fvid2_FrameList       frameList;

status = Fvid2_queue(fvidHandle, & frameList, 0);
if(status!=FVID_SOK) {
  // error in queue-ing frames to capture handle
} else {
  // success
}

TIP
User should make sure to dequeue / queue frames from the capture handle at the required rate (frame-rate), else the capture driver may not have frames internally to write video data and it will then be forced to drop frames until a buffer is available.

Callback[edit]

A user callback can be registered during driver create which is then called by the driver whenever data is available at any of the channels, streams associated with the driver. User would typicall set a semaphore to wake up a task. The woken up task will then call dequeue API to get the newly captured frames. Dequeue should be called for every stream associated with the driver to get the captured frames, since the callback just indicates there is data but the data could be in any of the streams that are valid for the driver instance.

NOTE
The callback itself could be called from interrupt or SWI context, so user should use only APIs that are allowed in interrupt or SWI context inside the callback.

Understanding captured frame information[edit]

Once a frame is captured the FVID2 frame structure contains information about the captured frame. The captured information can retrieved as shown below. The example below assumes "chNum" was created using the utility API Vps_captMakeChannelNum() during create.

#include "ti/psp/vps/vps_capture.h"

Fvid2_FrameList       frameList;
Fvid2_Frame          *pCurFrame;
Vps_CaptRtParams     *pCaptureRtParams;

Int32 frameId;

Fvid2_dequeue(fvidHandleVipAll, & frameList, 0, BIOS_WAIT_FOREVER);

System_printf(" CAPTUREAPP: Received %d frame(s) \n", frameList.numFrames);

for(frameId=0; frameId < frameList.numFrames; frameId++)
{
  pCurFrame = frameList.frames[frameId];

  pCaptureRtParams = (Vps_CaptRtParams*)pCurFrame->perFrameCfg;

  System_printf(" CAPTUREAPP: %d: time %d: ch %d:%d:%d: fid %d: %dx%d: addr 0x%08x\n",
    frameId,
    pCurFrame->timeStamp,                      // timestamp in msecs
    Vps_captGetInstId(pCurFrame->chNum),       // VIP instance ID
    Vps_captGetStreamId(pCurFrame->chNum),// Stream ID
    Vps_captGetChId(pCurFrame->chNum),    // channel ID
    pCurFrame->fid,                            // Even or Odd field
    pCaptureRtParams->captureOutWidth,      // captured frame width
    pCaptureRtParams->captureOutHeight,     // captured frame height
    pCurFrame->addr[0][0]                      // captured buffer address for YUV422P format
               );
}

// process captured frames ...

...


Fvid2_queue(fvidHandleVipAll, & frameList, 0);

TIP
Be careful to not modify the "Fvid2_Frame.perFrameCfg" from the received (dequeued) frame when returning (queuing) the frame back to the driver. If Fvid2_Frame.perFrameCfg has to be modified make sure user application sets it to a valid pointer in order to get captured frame width, height information from the driver, else set it to NULL.

Understanding Fvid2_Frame.chNum

Important
Be careful to not modify the "Fvid2_Frame.chNum" from the received (dequeued) frame when returning (queuing) the frame back to the driver. The FVID2 queue API uses "chNum" to identify the VIP instance, stream and channel that the frame belongs to, in order to return it to the correct channel "free" queue.

The below description is valid only when during create, channel number was made using the utility API Vps_captMakeChannelNum(). In case user had created channel number using their own logic they need to apply a inverse logic in order to know the instance, stream, channel associated with the received frame .

The capture driver assigns a unique channel number to every video channel, stream that is being captured via any of the VIP ports. User application needs to be aware of this assignment when handling frames from different VIP ports .

"Fvid2_Frame.chNum" identifies the channel associated with a given frame. Given "Fvid2_Frame.chNum" user application can find out the VIP instance, stream and channel ID using the APIs shown in above example.

The table below shows the channel number assignment for different VIP ports:

VIP port channel number assignment
VIP Instance Output Stream 0 Output Stream 1 Output Stream 2 Output Stream 3
VIP0 Port A CH00 .. CH15 CH16 .. CH31 CH32 .. CH47 CH48 .. CH63
VIP0 Port B CH64 .. CH79 CH80 .. CH95 CH96 .. CH111 CH112 .. CH127
VIP1 Port A CH128 .. CH143 CH144 .. CH159 CH160 .. CH175 CH176 .. CH191
VIP1 Port B CH192 .. CH207 CH208 .. CH223 CH224 .. CH239 CH240 .. CH255


Buffer Capture Mode (BCM)[edit]

The section explains the design of the capture driver for various buffer capture mode. The decision of queuing and de-queuing a buffer to the core happens at the frame completion callback from the core which in turn is equivalent to VSYNC of the capture hardware.

  • Frame drop mode

In this mode the driver will stop capturing data when there are no more buffers at the input queue. The driver will not hold any buffer with it and the last buffer will be returned to the application through de-queue call. For this mode, the driver makes use of the VPDMA drop data feature.


Frame Drop Mode Buffer Flow (2).png


Frame Drop Mode ISR Flow Diagram.png


  • Last frame repeat mode

In this mode the driver will keep capturing the data to the last queued buffer when there are no more buffers at the input queue. The driver will hold the last buffer with it till the application queues any new buffer or the capture is stopped

Last Frame Repeat Mode Buffer Flow.png

Last Frame Repeat Mode ISR Flow Diagram.png

  • Circular frame repeat mode

In this mode the driver will keep reusing all the sets of buffer with it in a circular fashion. Application cannot get back any buffer from the driver when streaming is on and dequeue call will result in error.

Circular Frame Repeat Mode Buffer Flow.png


Circular Frame Repeat Mode ISR Flow Diagram.png

Control IOCTLs supported[edit]

Frame skip control IOCTL_VPS_CAPT_SET_FRAME_SKIP[edit]

User can program a frame skip mask per channel to selectively skip frames. In this way user can control the frame-rate at which they want the data to be captured. When a frame is skipped, it is not written to DDR so that will also result in DDR bandwidth reduction.

This IOCTL can be called even while capture is running and frame-skip mask can be changed dynamically while capture is running.

An example is given below:

#include "ti/psp/vps/vps_capture.h"

Vps_CaptFrameSkip frameSkip;

// chNum is the one that was specified by user during create in chNumMap[][]
frameSkip.chNum = createArgs.chNumMap[streamId][chId];

// Example: for full frame-rate
frameSkip.frameSkipMask = 0;

// Example: for 1/2 frame-rate
frameSkip.frameSkipMask = 0x2AAAAAAA;

status = Fvid2_control(
            fvidHandle,
            IOCTL_VPS_CAPT_SET_FRAME_SKIP,
            & frameSkip,
            NULL
          );

Get Channel Status IOCTL_VPS_CAPT_GET_CH_STATUS[edit]

This IOCTL allows user to get channel related information as detected by the hardware, like channel data width, height, video detect.

Width and height that is returned is the width and height of the last captured frame that hardware has detected.

Video detect status is calculated based on last received frame timestamp and expected frame interval. If a frame is not received in the given frame interval, then its considered as video is not detected.

Typically usage of this would be to periodically call this API from user context, say every 10ms or 30ms. User could then use this API to know detected video width and height and then allocate and queue buffers to the driver.

An example is shown below:

#include "ti/psp/vps/vps_capture.h"

/*
  Check video detect status using IOCTL
*/
int status, chId, streamId;
Vps_CaptChGetStatusArgs chStatusArgs;
Vps_CaptChStatus chStatus

/* for all streams and channels */
for(streamId=0; streamId < createArgs.numStream; streamId++)
{
  for(chId=0; chId < createArgs.numCh; chId++)
  {

    chStatusArgs.chNum = createArgs.chNumMap[streamId][chId];

    /* expected frame capture interval between two frames/field in msecs  */
    chStatusArgs.frameInterval = 16;

    /* get video detect status  */
    status = Fvid2_control(
                fvidHandle,
                IOCTL_VPS_CAPT_GET_CH_STATUS,
                & chStatusArgs,
                & chStatus
              );

    if(chStatus.isVideoDetected)
    {
      /* video detect, print video info */
      System_printf(" DETECT = %d: %dx%d\n",
                  chStatus.isVideoDetected,
                  chStatus.captureOutWidth,
                  chStatus.captureOutHeight
               );
    }
  }
}


Max Size IOCTL_VPS_CAPT_SET_VIP_MAX_SIZE[edit]

User can program the three MAX_SIZE registers (MAX_SIZE_REG1, MAX_SIZE_REG2, MAX_SIZE_REG3) for each VPDMA associated with VIP1, VIP2, and VIP3 using this IOCTL. This IOCTL is valid only for Tda2xx. The Centaurus hardware does not have these registers present. The user application can program these registers using the global VIP capture handle before even creating the driver handle for the actual capture instance.

An example is given below:

   
/**
 * There are 3 32-bit MAX_SIZE registers supported for Tda2xx platform family.
 * These registers provide two parameters width[31:16] and height[15:0].
 * The VPDMA transmits to external buffer the maximum out width number of
 * pixels and maximum out height number of pixel lines.
 * If the VIP receives data exceeding the maximum out width/height then it
 * continues to capture the data. VPDMA will not transfer it to the
 * external buffer.
 * This register (if used) should have valid range of values.
 * The valid range for maximum out width shall be [1, 4096]
 * The valid range for maximum out height shall be [1, 2048]
 * Example: For a YUV420SP capture,
 * For luma, the maximum out [width, height] can go up to [2048, 2048].
 * For chroma, the maximum out [width, height] can go up to [2048, 1024].
 * Example: For a YUV422I capture,
 * For luma, the maximum out [width, height] can go up to [4096, 2048].
 */
/* MAX SIZE Register Width and Height configurations */
#define CAPT_APP_MAXSIZE_1_WIDTH        (1920u)
#define CAPT_APP_MAXSIZE_2_WIDTH        (1920u)
#define CAPT_APP_MAXSIZE_3_WIDTH        (1280u)
#define CAPT_APP_MAXSIZE_1_HEIGHT       (1080u)
#define CAPT_APP_MAXSIZE_2_HEIGHT       (540u)
#define CAPT_APP_MAXSIZE_3_HEIGHT       (800u)
     
        instObj->maxOutWidth[0u]  = CAPT_APP_MAXSIZE_1_WIDTH;
        instObj->maxOutHeight[0u] = CAPT_APP_MAXSIZE_1_HEIGHT;
        instObj->maxOutWidth[1u]  = CAPT_APP_MAXSIZE_2_WIDTH;
        instObj->maxOutHeight[1u] = CAPT_APP_MAXSIZE_2_HEIGHT;
        instObj->maxOutWidth[2u]  = CAPT_APP_MAXSIZE_3_WIDTH;
        instObj->maxOutHeight[2u] = CAPT_APP_MAXSIZE_3_HEIGHT;

        if (Bsp_platformIsTda2xxFamilyBuild())
        {
            VpsVpdmaMaxSizeParams_init(&vipMaxSizePrms);
            vipMaxSizePrms.instId =
                Vps_captGetVipId(appObj->testPrms.instId[instCnt]);
            vipMaxSizePrms.maxOutWidth[0u]  = instObj->maxOutWidth[0u];
            vipMaxSizePrms.maxOutHeight[0u] = instObj->maxOutHeight[0u];
            vipMaxSizePrms.maxOutWidth[1u]  = instObj->maxOutWidth[1u];
            vipMaxSizePrms.maxOutHeight[1u] = instObj->maxOutHeight[1u];
            vipMaxSizePrms.maxOutWidth[2u]  = instObj->maxOutWidth[2u];
            vipMaxSizePrms.maxOutHeight[2u] = instObj->maxOutHeight[2u];

            retVal = Fvid2_control(
                appObj->fvidHandleAll,
                IOCTL_VPS_CAPT_SET_VIP_MAX_SIZE,
                &vipMaxSizePrms,
                NULL);
            if (retVal != FVID2_SOK)
            {
                GT_0trace(
                    BspAppTrace, GT_ERR,
                    APP_NAME
                    ": VIP Set Max Frame Size Params IOCTL Failed!!!\n");
                return;
            }
        }

Set VIP Parameters IOCTL_VPS_CAPT_SET_VIP_PARAMS[edit]

The application user after creating the instance handle shall need to make a control call with VIP specific parameters to configure the VIP blocks.

An example is given below:

        
        retVal = Fvid2_control(
            instObj->drvHandle,
            IOCTL_VPS_CAPT_SET_VIP_PARAMS,
            &instObj->vipPrms,
            NULL);
        if (retVal != FVID2_SOK)
        {
            GT_0trace(BspAppTrace, GT_ERR,
                      APP_NAME ": VIP Set Params IOCTL Failed!!!\n");
            return;
        }

Get VIP Parameters IOCTL_VPS_CAPT_GET_VIP_PARAMS[edit]

The application user after creating the instance handle shall need to make a control call to get the default VIP parameters.

An example is given below:

        
        retVal = Fvid2_control(
            instObj->drvHandle,
            IOCTL_VPS_CAPT_GET_VIP_PARAMS,
            &instObj->vipPrms,
            NULL);
        if (retVal != FVID2_SOK)
        {
            GT_0trace(BspAppTrace, GT_ERR,
                      APP_NAME ": VIP Get Params IOCTL Failed!!!\n");
            return;
        }


Delete Phase
[edit]

In this phase FVID2 delete API is called to free all resources allocated during capture. Make sure capture is stopped using Fvid2_stop() before deleting a capture instance. Once a capture handle is deleted the resources free'ed by that capture handle could be used when another capture driver or other related driver is opened.

The FVID2 delete API call is shown below:

        retVal = Fvid2_delete(instObj->drvHandle, NULL);
        if (FVID2_SOK != retVal)
        {
            GT_0trace(BspAppTrace, GT_ERR,
                      APP_NAME ": Capture Delete Failed!!!\n");
            return;
        }

System De-init Phase[edit]

In this phase VIP capture sub-system is de-initialized. Here all resources acquired during system initialization are free'ed. Make sure all capture handles are deleted before calling this API. VIP sub-system de-init happens as part of overall FVID2 system de-init. Typically this is done during system shutdown.

The global VIP capture handle, if opened earlier, should also be deleted before called FVID2 de-init

static void CaptApp_deInit(CaptApp_Obj *appObj)
{
    Int32  retVal;
    UInt32 isI2cDeInitReq;

    /* Delete global VIP capture handle */
    retVal = Fvid2_delete(appObj->fvidHandleAll, NULL);
    if (retVal != FVID2_SOK)
    {
        GT_0trace(BspAppTrace, GT_ERR,
                  APP_NAME ": Global handle delete failed!!!\n");
        return;
    }

    /* System de-init */
    isI2cDeInitReq = TRUE;
    retVal         = BspUtils_appDefaultDeInit(isI2cDeInitReq);
    if (retVal != FVID2_SOK)
    {
        GT_0trace(BspAppTrace, GT_ERR,
                  APP_NAME ": System De-Init Failed!!!\n");
        return;
    }

    GT_0trace(BspAppTrace, GT_INFO,
              APP_NAME ": CaptApp_deInit() - DONE !!!\n");
}


E2e.jpg {{
  1. switchcategory:MultiCore=
  • For technical support on MultiCore devices, please post your questions in the C6000 MultiCore Forum
  • For questions related to the BIOS MultiCore SDK (MCSDK), please use the BIOS Forum

Please post only comments related to the article PDK/PDK VPS Capture Driver User Guide here.

Keystone=
  • For technical support on MultiCore devices, please post your questions in the C6000 MultiCore Forum
  • For questions related to the BIOS MultiCore SDK (MCSDK), please use the BIOS Forum

Please post only comments related to the article PDK/PDK VPS Capture Driver User Guide here.

C2000=For technical support on the C2000 please post your questions on The C2000 Forum. Please post only comments about the article PDK/PDK VPS Capture Driver User Guide here. DaVinci=For technical support on DaVincoplease post your questions on The DaVinci Forum. Please post only comments about the article PDK/PDK VPS Capture Driver User Guide here. MSP430=For technical support on MSP430 please post your questions on The MSP430 Forum. Please post only comments about the article PDK/PDK VPS Capture Driver User Guide here. OMAP35x=For technical support on OMAP please post your questions on The OMAP Forum. Please post only comments about the article PDK/PDK VPS Capture Driver User Guide here. OMAPL1=For technical support on OMAP please post your questions on The OMAP Forum. Please post only comments about the article PDK/PDK VPS Capture Driver User Guide here. MAVRK=For technical support on MAVRK please post your questions on The MAVRK Toolbox Forum. Please post only comments about the article PDK/PDK VPS Capture Driver User Guide here. For technical support please post your questions at http://e2e.ti.com. Please post only comments about the article PDK/PDK VPS Capture Driver User Guide here.

}}

Hyperlink blue.png Links

Amplifiers & Linear
Audio
Broadband RF/IF & Digital Radio
Clocks & Timers
Data Converters

DLP & MEMS
High-Reliability
Interface
Logic
Power Management

Processors

Switches & Multiplexers
Temperature Sensors & Control ICs
Wireless Connectivity