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
Contents
- 1 Introduction
- 2 Software Application Interfaces
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:
The 422 secondary path and HDCOMP (RGB) path as shown in the figure below are wired out for Tda2xx.
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 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.
- 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
- 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.
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"); }