| /******************************************************************************* |
| * |
| * Copyright (C) 2017 Xilinx, Inc. All rights reserved. |
| * |
| * Permission is hereby granted, free of charge, to any person obtaining a copy |
| * of this software and associated documentation files (the "Software"), to deal |
| * in the Software without restriction, including without limitation the rights |
| * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
| * copies of the Software, and to permit persons to whom the Software is |
| * furnished to do so, subject to the following conditions: |
| * |
| * The above copyright notice and this permission notice shall be included in |
| * all copies or substantial portions of the Software. |
| * |
| * Use of the Software is limited solely to applications: |
| * (a) running on a Xilinx device, or |
| * (b) that interact with a Xilinx device through a bus or interconnect. |
| * |
| * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
| * XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
| * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF |
| * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
| * SOFTWARE. |
| * |
| * Except as contained in this notice, the name of the Xilinx shall not be used |
| * in advertising or otherwise to promote the sale, use or other dealings in |
| * this Software without prior written authorization from Xilinx. |
| * |
| *******************************************************************************/ |
| /******************************************************************************/ |
| /** |
| * |
| * @file xvidc.c |
| * @addtogroup video_common_v4_3 |
| * @{ |
| * |
| * Contains common utility functions that are typically used by video-related |
| * drivers and applications. |
| * |
| * @note None. |
| * |
| * <pre> |
| * MODIFICATION HISTORY: |
| * |
| * Ver Who Date Changes |
| * ----- ---- -------- ----------------------------------------------- |
| * 1.0 rc, 01/10/15 Initial release. |
| * als |
| * 2.2 als 02/01/16 Functions with pointer arguments that don't modify |
| * contents now const. |
| * Added ability to insert a custom video timing table. |
| * yh Added 3D support. |
| * 3.0 aad 05/13/16 Added API to search for RB video modes. |
| * 3.1 rco 07/26/16 Added extern definition for timing table array |
| * Added video-in-memory color formats |
| * Updated XVidC_RegisterCustomTimingModes API signature |
| * 4.1 rco 11/23/16 Added new memory formats |
| * Added new API to get video mode id that matches exactly |
| * with provided timing information |
| * Fix c++ warnings |
| * 4.2 jsr 07/22/17 Added new framerates and color formats to support SDI |
| * Reordered YCBCR422 colorforamt and removed other formats |
| * that are not needed for SDI which were added earlier. |
| * vyc 10/04/17 Added new streaming alpha formats and new memory formats |
| * 4.3 eb 26/01/18 Added API XVidC_GetVideoModeIdExtensive |
| * jsr 02/22/18 Added XVIDC_CSF_YCBCR_420 color space format |
| * vyc 04/04/18 Added BGR8 memory format |
| * </pre> |
| * |
| *******************************************************************************/ |
| |
| /******************************* Include Files ********************************/ |
| |
| #include "xil_assert.h" |
| #include "xstatus.h" |
| #include "xvidc.h" |
| |
| /*************************** Variable Declarations ****************************/ |
| extern const XVidC_VideoTimingMode XVidC_VideoTimingModes[XVIDC_VM_NUM_SUPPORTED]; |
| |
| const XVidC_VideoTimingMode *XVidC_CustomTimingModes = NULL; |
| int XVidC_NumCustomModes = 0; |
| |
| /**************************** Function Prototypes *****************************/ |
| |
| static const XVidC_VideoTimingMode *XVidC_GetCustomVideoModeData( |
| XVidC_VideoMode VmId); |
| static u8 XVidC_IsVtmRb(const char *VideoModeStr, u8 RbN); |
| |
| /*************************** Function Definitions *****************************/ |
| |
| /******************************************************************************/ |
| /** |
| * This function registers a user-defined custom video mode timing table with |
| * video_common. Functions which search the available video modes, or take VmId |
| * as an input, will operate on or check the custom video mode timing table in |
| * addition to the pre-defined video mode timing table (XVidC_VideoTimingModes). |
| * |
| * @param CustomTable is a pointer to the user-defined custom vide mode |
| * timing table to register. |
| * @param NumElems is the number of video modes supported by CustomTable. |
| * |
| * @return |
| * - XST_SUCCESS if the custom table was successfully registered. |
| * - XST_FAILURE if an existing custom table is already present. |
| * |
| * @note IDs in the custom table may not conflict with IDs reserved by |
| * the XVidC_VideoMode enum. |
| * |
| *******************************************************************************/ |
| u32 XVidC_RegisterCustomTimingModes(const XVidC_VideoTimingMode *CustomTable, |
| u16 NumElems) |
| { |
| u16 Index; |
| |
| /* Verify arguments. */ |
| Xil_AssertNonvoid(CustomTable != NULL); |
| for (Index = 0; Index < NumElems; Index++) { |
| Xil_AssertNonvoid((CustomTable[Index].VmId > XVIDC_VM_CUSTOM)); |
| /* The IDs of each video mode in the custom table must not |
| * conflict with IDs reserved by video_common. */ |
| } |
| |
| /* Fail if a custom table is currently already registered. */ |
| if (XVidC_CustomTimingModes) { |
| return XST_FAILURE; |
| } |
| |
| XVidC_CustomTimingModes = CustomTable; |
| XVidC_NumCustomModes = NumElems; |
| |
| return XST_SUCCESS; |
| } |
| |
| /******************************************************************************/ |
| /** |
| * This function unregisters the user-defined custom video mode timing table |
| * previously registered by XVidC_RegisterCustomTimingModes(). |
| * |
| * @return None. |
| * |
| * @note None. |
| * |
| *******************************************************************************/ |
| void XVidC_UnregisterCustomTimingModes(void) |
| { |
| XVidC_CustomTimingModes = NULL; |
| XVidC_NumCustomModes = 0; |
| } |
| |
| /******************************************************************************/ |
| /** |
| * This function calculates pixel clock based on the inputs. |
| * |
| * @param HTotal specifies horizontal total. |
| * @param VTotal specifies vertical total. |
| * @param FrameRate specifies rate at which frames are generated. |
| * |
| * @return Pixel clock in Hz. |
| * |
| * @note None. |
| * |
| *******************************************************************************/ |
| u32 XVidC_GetPixelClockHzByHVFr(u32 HTotal, u32 VTotal, u8 FrameRate) |
| { |
| return (HTotal * VTotal * FrameRate); |
| } |
| |
| /******************************************************************************/ |
| /** |
| * This function calculates pixel clock from video mode. |
| * |
| * @param VmId specifies the resolution id. |
| * |
| * @return Pixel clock in Hz. |
| * |
| * @note None. |
| * |
| *******************************************************************************/ |
| u32 XVidC_GetPixelClockHzByVmId(XVidC_VideoMode VmId) |
| { |
| u32 ClkHz; |
| const XVidC_VideoTimingMode *VmPtr; |
| |
| VmPtr = XVidC_GetVideoModeData(VmId); |
| if (!VmPtr) { |
| return 0; |
| } |
| |
| if (XVidC_IsInterlaced(VmId)) { |
| /* For interlaced mode, use both frame 0 and frame 1 vertical |
| * totals. */ |
| ClkHz = VmPtr->Timing.F0PVTotal + VmPtr->Timing.F1VTotal; |
| |
| /* Multiply the number of pixels by the frame rate of each |
| * individual frame (half of the total frame rate). */ |
| ClkHz *= VmPtr->FrameRate / 2; |
| } |
| else { |
| /* For progressive mode, use only frame 0 vertical total. */ |
| ClkHz = VmPtr->Timing.F0PVTotal; |
| |
| /* Multiply the number of pixels by the frame rate. */ |
| ClkHz *= VmPtr->FrameRate; |
| } |
| |
| /* Multiply the vertical total by the horizontal total for number of |
| * pixels. */ |
| ClkHz *= VmPtr->Timing.HTotal; |
| |
| return ClkHz; |
| } |
| |
| /******************************************************************************/ |
| /** |
| * This function checks if the input video mode is interlaced/progressive based |
| * on its ID from the video timings table. |
| * |
| * @param VmId specifies the resolution ID from the video timings table. |
| * |
| * @return Video format. |
| * - XVIDC_VF_PROGRESSIVE |
| * - XVIDC_VF_INTERLACED |
| * |
| * @note None. |
| * |
| *******************************************************************************/ |
| XVidC_VideoFormat XVidC_GetVideoFormat(XVidC_VideoMode VmId) |
| { |
| const XVidC_VideoTimingMode *VmPtr; |
| |
| VmPtr = XVidC_GetVideoModeData(VmId); |
| if (!VmPtr) { |
| return XVIDC_VF_UNKNOWN; |
| } |
| |
| if (VmPtr->Timing.F1VTotal == 0) { |
| return (XVIDC_VF_PROGRESSIVE); |
| } |
| |
| return (XVIDC_VF_INTERLACED); |
| } |
| |
| /******************************************************************************/ |
| /** |
| * This function checks if the input video mode is interlaced based on its ID |
| * from the video timings table. |
| * |
| * @param VmId specifies the resolution ID from the video timings table. |
| * |
| * @return |
| * - 1 if the video timing with the supplied table ID is |
| * interlaced. |
| * - 0 if the video timing is progressive. |
| * |
| * @note None. |
| * |
| *******************************************************************************/ |
| u8 XVidC_IsInterlaced(XVidC_VideoMode VmId) |
| { |
| if (XVidC_GetVideoFormat(VmId) == XVIDC_VF_INTERLACED) { |
| return 1; |
| } |
| |
| return 0; |
| } |
| |
| /******************************************************************************/ |
| /** |
| * This function returns the Video Mode ID that matches the detected input |
| * timing, frame rate and I/P flag |
| * |
| * @param Timing is the pointer to timing parameters to match |
| * @param FrameRate specifies refresh rate in HZ |
| * @param IsInterlaced is flag. |
| * - 0 = Progressive |
| * - 1 = Interlaced. |
| * |
| * @return Id of a supported video mode. |
| * |
| * @note This is an extension of XVidC_GetVideoModeId API to include |
| * blanking information in match process. No attempt is made to |
| * search for reduced blanking entries, if any. |
| * |
| *******************************************************************************/ |
| XVidC_VideoMode XVidC_GetVideoModeIdWBlanking(const XVidC_VideoTiming *Timing, |
| u32 FrameRate, u8 IsInterlaced) |
| { |
| XVidC_VideoMode VmId; |
| XVidC_VideoTiming const *StdTiming = NULL; |
| |
| /* First search for ID with matching Width & Height */ |
| VmId = XVidC_GetVideoModeId(Timing->HActive, Timing->VActive, FrameRate, |
| IsInterlaced); |
| |
| if(VmId == XVIDC_VM_NOT_SUPPORTED) { |
| return(VmId); |
| } else { |
| |
| /* Get standard timing info from default timing table */ |
| StdTiming = XVidC_GetTimingInfo(VmId); |
| |
| /* Match against detected timing parameters */ |
| if((Timing->HActive == StdTiming->HActive) && |
| (Timing->VActive == StdTiming->VActive) && |
| (Timing->HTotal == StdTiming->HTotal) && |
| (Timing->F0PVTotal == StdTiming->F0PVTotal) && |
| (Timing->HFrontPorch == StdTiming->HFrontPorch) && |
| (Timing->HSyncWidth == StdTiming->HSyncWidth) && |
| (Timing->HBackPorch == StdTiming->HBackPorch) && |
| (Timing->F0PVFrontPorch == StdTiming->F0PVFrontPorch) && |
| (Timing->F0PVSyncWidth == StdTiming->F0PVSyncWidth) && |
| (Timing->F0PVBackPorch == StdTiming->F0PVBackPorch)) { |
| return(VmId); |
| } else { |
| return(XVIDC_VM_NOT_SUPPORTED); |
| } |
| } |
| } |
| |
| /******************************************************************************/ |
| /** |
| * This function returns the Video Mode ID that matches the detected input |
| * width, height, frame rate and I/P flag |
| * |
| * @param Width specifies the number pixels per scanline. |
| * @param Height specifies the number of scanline's. |
| * @param FrameRate specifies refresh rate in HZ |
| * @param IsInterlaced is flag. |
| * - 0 = Progressive |
| * - 1 = Interlaced. |
| * |
| * @return Id of a supported video mode. |
| * |
| * @note None. |
| * |
| *******************************************************************************/ |
| XVidC_VideoMode XVidC_GetVideoModeId(u32 Width, u32 Height, u32 FrameRate, |
| u8 IsInterlaced) |
| { |
| u32 Low; |
| u32 High; |
| u32 Mid; |
| u32 HActive; |
| u32 VActive; |
| u32 Rate; |
| u32 ResFound = (FALSE); |
| XVidC_VideoMode Mode; |
| u16 Index; |
| |
| /* First, attempt a linear search on the custom video timing table. */ |
| if(XVidC_CustomTimingModes) { |
| for (Index = 0; Index < XVidC_NumCustomModes; Index++) { |
| HActive = XVidC_CustomTimingModes[Index].Timing.HActive; |
| VActive = XVidC_CustomTimingModes[Index].Timing.VActive; |
| Rate = XVidC_CustomTimingModes[Index].FrameRate; |
| if ((Width == HActive) && |
| (Height == VActive) && |
| (FrameRate == Rate)) { |
| return XVidC_CustomTimingModes[Index].VmId; |
| } |
| } |
| } |
| |
| if (IsInterlaced) { |
| Low = (XVIDC_VM_INTL_START); |
| High = (XVIDC_VM_INTL_END); |
| } |
| else { |
| Low = (XVIDC_VM_PROG_START); |
| High = (XVIDC_VM_PROG_END); |
| } |
| |
| HActive = VActive = Rate = 0; |
| |
| /* Binary search finds item in sorted array. |
| * And returns index (zero based) of item |
| * If item is not found returns flag remains |
| * FALSE. Search key is "width or HActive" |
| */ |
| while (Low <= High) { |
| Mid = (Low + High) / 2; |
| HActive = XVidC_VideoTimingModes[Mid].Timing.HActive; |
| if (Width == HActive) { |
| ResFound = (TRUE); |
| break; |
| } |
| else if (Width < HActive) { |
| if (Mid == 0) { |
| break; |
| } |
| else { |
| High = Mid - 1; |
| } |
| } |
| else { |
| Low = Mid + 1; |
| } |
| } |
| |
| /* HActive matched at middle */ |
| if (ResFound) { |
| /* Rewind to start index of mode with matching width */ |
| while ((Mid > 0) && |
| (XVidC_VideoTimingModes[Mid - 1].Timing.HActive == |
| Width)) { |
| --Mid; |
| } |
| |
| ResFound = (FALSE); |
| VActive = XVidC_VideoTimingModes[Mid].Timing.VActive; |
| Rate = XVidC_VideoTimingModes[Mid].FrameRate; |
| |
| /* Now do a linear search for matching VActive and Frame |
| * Rate |
| */ |
| while (HActive == Width) { |
| /* check current entry */ |
| if ((VActive == Height) && (Rate == FrameRate)) { |
| ResFound = (TRUE); |
| break; |
| } |
| /* Check next entry */ |
| else { |
| Mid = Mid + 1; |
| HActive = |
| XVidC_VideoTimingModes[Mid].Timing.HActive; |
| VActive = |
| XVidC_VideoTimingModes[Mid].Timing.VActive; |
| Rate = XVidC_VideoTimingModes[Mid].FrameRate; |
| } |
| } |
| Mode = |
| (ResFound) ? (XVidC_VideoMode)Mid : (XVIDC_VM_NOT_SUPPORTED); |
| } |
| else { |
| Mode = (XVIDC_VM_NOT_SUPPORTED); |
| } |
| |
| return (Mode); |
| } |
| |
| /******************************************************************************/ |
| /** |
| * This function returns the Video Mode ID that matches the detected input |
| * timing, frame rate and I/P flag |
| * |
| * @param Timing is the pointer to timing parameters to match |
| * @param FrameRate specifies refresh rate in HZ |
| * @param IsInterlaced is flag. |
| * - 0 = Progressive |
| * - 1 = Interlaced. |
| * @param IsExtensive is flag. |
| * - 0 = Basic matching of timing parameters |
| * - 1 = Extensive matching of timing parameters |
| * |
| * @return Id of a supported video mode. |
| * |
| * @note This function attempts to search for reduced blanking entries, if |
| * any. |
| * |
| *******************************************************************************/ |
| XVidC_VideoMode XVidC_GetVideoModeIdExtensive(XVidC_VideoTiming *Timing, |
| u32 FrameRate, |
| u8 IsInterlaced, |
| u8 IsExtensive) |
| { |
| u32 Low; |
| u32 High; |
| u32 Mid; |
| u32 HActive; |
| u32 VActive; |
| u32 Rate; |
| u32 ResFound = (FALSE); |
| XVidC_VideoMode Mode; |
| u16 Index; |
| |
| /* First, attempt a linear search on the custom video timing table. */ |
| if(XVidC_CustomTimingModes) { |
| for (Index = 0; Index < XVidC_NumCustomModes; Index++) { |
| HActive = XVidC_CustomTimingModes[Index].Timing.HActive; |
| VActive = XVidC_CustomTimingModes[Index].Timing.VActive; |
| Rate = XVidC_CustomTimingModes[Index].FrameRate; |
| if ((HActive == Timing->HActive) && (VActive == Timing->VActive) && |
| (Rate == FrameRate) && (IsExtensive == 0 || ( |
| XVidC_CustomTimingModes[Index].Timing.HTotal == Timing->HTotal && |
| XVidC_CustomTimingModes[Index].Timing.F0PVTotal == |
| Timing->F0PVTotal && |
| XVidC_CustomTimingModes[Index].Timing.HFrontPorch == |
| Timing->HFrontPorch && |
| XVidC_CustomTimingModes[Index].Timing.F0PVFrontPorch == |
| Timing->F0PVFrontPorch && |
| XVidC_CustomTimingModes[Index].Timing.HSyncWidth == |
| Timing->HSyncWidth && |
| XVidC_CustomTimingModes[Index].Timing.F0PVSyncWidth == |
| Timing->F0PVSyncWidth && |
| XVidC_CustomTimingModes[Index].Timing.VSyncPolarity == |
| Timing->VSyncPolarity))) { |
| if (!IsInterlaced || IsExtensive == 0 || ( |
| XVidC_CustomTimingModes[Index].Timing.F1VTotal == |
| Timing->F1VTotal && |
| XVidC_CustomTimingModes[Index].Timing.F1VFrontPorch == |
| Timing->F1VFrontPorch && |
| XVidC_CustomTimingModes[Index].Timing.F1VSyncWidth == |
| Timing->F1VSyncWidth)) { |
| return XVidC_CustomTimingModes[Index].VmId; |
| } |
| } |
| } |
| } |
| |
| if (IsInterlaced) { |
| Low = (XVIDC_VM_INTL_START); |
| High = (XVIDC_VM_INTL_END); |
| } |
| else { |
| Low = (XVIDC_VM_PROG_START); |
| High = (XVIDC_VM_PROG_END); |
| } |
| |
| HActive = VActive = Rate = 0; |
| |
| /* Binary search finds item in sorted array. |
| * And returns index (zero based) of item |
| * If item is not found returns flag remains |
| * FALSE. Search key is "Timing->HActive or HActive" |
| */ |
| while (Low <= High) { |
| Mid = (Low + High) / 2; |
| HActive = XVidC_VideoTimingModes[Mid].Timing.HActive; |
| if (Timing->HActive == HActive) { |
| ResFound = (TRUE); |
| break; |
| } |
| else if (Timing->HActive < HActive) { |
| if (Mid == 0) { |
| break; |
| } |
| else { |
| High = Mid - 1; |
| } |
| } |
| else { |
| Low = Mid + 1; |
| } |
| } |
| |
| /* HActive matched at middle */ |
| if (ResFound) { |
| /* Rewind to start index of mode with matching Timing->HActive */ |
| while ((Mid > 0) && |
| (XVidC_VideoTimingModes[Mid - 1].Timing.HActive == |
| Timing->HActive)) { |
| --Mid; |
| } |
| |
| ResFound = (FALSE); |
| VActive = XVidC_VideoTimingModes[Mid].Timing.VActive; |
| Rate = XVidC_VideoTimingModes[Mid].FrameRate; |
| |
| /* Now do a linear search for matching VActive and Frame |
| * Rate |
| */ |
| while (HActive == Timing->HActive) { |
| /* check current entry */ |
| if ((VActive == Timing->VActive) && (Rate == FrameRate) && |
| (IsExtensive == 0 || |
| (XVidC_VideoTimingModes[Mid].Timing.HTotal == |
| Timing->HTotal && |
| XVidC_VideoTimingModes[Mid].Timing.F0PVTotal == |
| Timing->F0PVTotal && |
| XVidC_VideoTimingModes[Mid].Timing.HFrontPorch == |
| Timing->HFrontPorch && |
| XVidC_VideoTimingModes[Mid].Timing.F0PVFrontPorch == |
| Timing->F0PVFrontPorch && |
| XVidC_VideoTimingModes[Mid].Timing.HSyncWidth == |
| Timing->HSyncWidth && |
| XVidC_VideoTimingModes[Mid].Timing.F0PVSyncWidth == |
| Timing->F0PVSyncWidth && |
| XVidC_VideoTimingModes[Mid].Timing.VSyncPolarity == |
| Timing->VSyncPolarity))) { |
| if (!IsInterlaced || IsExtensive == 0 || ( |
| XVidC_VideoTimingModes[Mid].Timing.F1VTotal == |
| Timing->F1VTotal && |
| XVidC_VideoTimingModes[Mid].Timing.F1VFrontPorch == |
| Timing->F1VFrontPorch && |
| XVidC_VideoTimingModes[Mid].Timing.F1VSyncWidth == |
| Timing->F1VSyncWidth)) { |
| ResFound = (TRUE); |
| break; |
| } |
| } |
| /* Check next entry */ |
| else { |
| Mid = Mid + 1; |
| HActive = |
| XVidC_VideoTimingModes[Mid].Timing.HActive; |
| VActive = |
| XVidC_VideoTimingModes[Mid].Timing.VActive; |
| Rate = XVidC_VideoTimingModes[Mid].FrameRate; |
| } |
| } |
| Mode = |
| (ResFound) ? (XVidC_VideoMode)Mid : (XVIDC_VM_NOT_SUPPORTED); |
| } |
| else { |
| Mode = (XVIDC_VM_NOT_SUPPORTED); |
| } |
| |
| return (Mode); |
| } |
| |
| /******************************************************************************/ |
| /** |
| * This function returns the video mode ID that matches the detected input |
| * width, height, frame rate, interlaced or progressive, and reduced blanking. |
| * |
| * @param Width specifies the number pixels per scanline. |
| * @param Height specifies the number of scanline's. |
| * @param FrameRate specifies refresh rate in HZ |
| * @param IsInterlaced specifies interlaced or progressive mode: |
| * - 0 = Progressive |
| * - 1 = Interlaced. |
| * @param RbN specifies the type of reduced blanking: |
| * - 0 = No reduced blanking |
| * - 1 = RB |
| * - 2 = RB2 |
| * |
| * @return ID of a supported video mode. |
| * |
| * @note None. |
| * |
| *******************************************************************************/ |
| XVidC_VideoMode XVidC_GetVideoModeIdRb(u32 Width, u32 Height, |
| u32 FrameRate, u8 IsInterlaced, u8 RbN) |
| { |
| XVidC_VideoMode VmId; |
| const XVidC_VideoTimingMode *VtmPtr; |
| u8 Found = 0; |
| |
| VmId = XVidC_GetVideoModeId(Width, Height, FrameRate, |
| IsInterlaced); |
| |
| VtmPtr = XVidC_GetVideoModeData(VmId); |
| if (!VtmPtr) { |
| return XVIDC_VM_NOT_SUPPORTED; |
| } |
| |
| while (!Found) { |
| VtmPtr = XVidC_GetVideoModeData(VmId); |
| if ((Height != VtmPtr->Timing.VActive) || |
| (Width != VtmPtr->Timing.HActive) || |
| (FrameRate != VtmPtr->FrameRate) || |
| (IsInterlaced && !XVidC_IsInterlaced(VmId))) { |
| VmId = XVIDC_VM_NOT_SUPPORTED; |
| break; |
| } |
| Found = XVidC_IsVtmRb(XVidC_GetVideoModeStr(VmId), RbN); |
| if (Found) { |
| break; |
| } |
| VmId = (XVidC_VideoMode)((int)VmId + 1); |
| } |
| |
| return VmId; |
| } |
| |
| /******************************************************************************/ |
| /** |
| * This function returns the pointer to video mode data at index provided. |
| * |
| * @param VmId specifies the resolution id. |
| * |
| * @return Pointer to XVidC_VideoTimingMode structure based on the given |
| * video mode. |
| * |
| * @note None. |
| * |
| *******************************************************************************/ |
| const XVidC_VideoTimingMode *XVidC_GetVideoModeData(XVidC_VideoMode VmId) |
| { |
| if (VmId < XVIDC_VM_NUM_SUPPORTED) { |
| return &XVidC_VideoTimingModes[VmId]; |
| } |
| |
| return XVidC_GetCustomVideoModeData(VmId); |
| } |
| |
| /******************************************************************************/ |
| /** |
| * |
| * This function returns the resolution name for index specified. |
| * |
| * @param VmId specifies the resolution id. |
| * |
| * @return Pointer to a resolution name string. |
| * |
| * @note None. |
| * |
| *******************************************************************************/ |
| const char *XVidC_GetVideoModeStr(XVidC_VideoMode VmId) |
| { |
| const XVidC_VideoTimingMode *VmPtr; |
| |
| if (VmId == XVIDC_VM_CUSTOM) { |
| return ("Custom video mode"); |
| } |
| |
| VmPtr = XVidC_GetVideoModeData(VmId); |
| if (!VmPtr) { |
| return ("Video mode not supported"); |
| } |
| |
| return VmPtr->Name; |
| } |
| |
| /******************************************************************************/ |
| /** |
| * This function returns the frame rate name for index specified. |
| * |
| * @param VmId specifies the resolution id. |
| * |
| * @return Pointer to a frame rate name string. |
| * |
| * @note None. |
| * |
| *******************************************************************************/ |
| const char *XVidC_GetFrameRateStr(XVidC_VideoMode VmId) |
| { |
| const XVidC_VideoTimingMode *VmPtr; |
| |
| VmPtr = XVidC_GetVideoModeData(VmId); |
| if (!VmPtr) { |
| return ("Video mode not supported"); |
| } |
| |
| switch (VmPtr->FrameRate) { |
| case (XVIDC_FR_24HZ): return ("24Hz"); |
| case (XVIDC_FR_25HZ): return ("25Hz"); |
| case (XVIDC_FR_30HZ): return ("30Hz"); |
| case (XVIDC_FR_48HZ): return ("48Hz"); |
| case (XVIDC_FR_50HZ): return ("50Hz"); |
| case (XVIDC_FR_56HZ): return ("56Hz"); |
| case (XVIDC_FR_60HZ): return ("60Hz"); |
| case (XVIDC_FR_65HZ): return ("65Hz"); |
| case (XVIDC_FR_67HZ): return ("67Hz"); |
| case (XVIDC_FR_70HZ): return ("70Hz"); |
| case (XVIDC_FR_72HZ): return ("72Hz"); |
| case (XVIDC_FR_75HZ): return ("75Hz"); |
| case (XVIDC_FR_85HZ): return ("85Hz"); |
| case (XVIDC_FR_87HZ): return ("87Hz"); |
| case (XVIDC_FR_88HZ): return ("88Hz"); |
| case (XVIDC_FR_96HZ): return ("96Hz"); |
| case (XVIDC_FR_100HZ): return ("100Hz"); |
| case (XVIDC_FR_120HZ): return ("120Hz"); |
| |
| default: |
| return ("Frame rate not supported"); |
| } |
| } |
| |
| /******************************************************************************/ |
| /** |
| * This function returns a string representation of the enumerated type, |
| * XVidC_3DFormat. |
| * |
| * @param Format specifies the value to convert. |
| * |
| * @return Pointer to the converted string. |
| * |
| * @note None. |
| * |
| *******************************************************************************/ |
| const char *XVidC_Get3DFormatStr(XVidC_3DFormat Format) |
| { |
| switch (Format) { |
| case XVIDC_3D_FRAME_PACKING: |
| return ("Frame Packing"); |
| |
| case XVIDC_3D_FIELD_ALTERNATIVE: |
| return ("Field Alternative"); |
| |
| case XVIDC_3D_LINE_ALTERNATIVE: |
| return ("Line Alternative"); |
| |
| case XVIDC_3D_SIDE_BY_SIDE_FULL: |
| return ("Side-by-Side(full)"); |
| |
| case XVIDC_3D_TOP_AND_BOTTOM_HALF: |
| return ("Top-and-Bottom(half)"); |
| |
| case XVIDC_3D_SIDE_BY_SIDE_HALF: |
| return ("Side-by-Side(half)"); |
| |
| default: |
| return ("Unknown"); |
| } |
| } |
| |
| /******************************************************************************/ |
| /** |
| * This function returns the color format name for index specified. |
| * |
| * @param ColorFormatId specifies the index of color format space. |
| * |
| * @return Pointer to a color space name string. |
| * |
| * @note None. |
| * |
| *******************************************************************************/ |
| const char *XVidC_GetColorFormatStr(XVidC_ColorFormat ColorFormatId) |
| { |
| switch (ColorFormatId) { |
| case XVIDC_CSF_RGB: return ("RGB"); |
| case XVIDC_CSF_YCRCB_444: return ("YUV_444"); |
| case XVIDC_CSF_YCRCB_422: return ("YUV_422"); |
| case XVIDC_CSF_YCRCB_420: return ("YUV_420"); |
| case XVIDC_CSF_YONLY: return ("Y_ONLY"); |
| case XVIDC_CSF_RGBA: return ("RGBA"); |
| case XVIDC_CSF_YCRCBA_444: return ("YUVA_444"); |
| case XVIDC_CSF_MEM_RGBX8: return ("RGBX8"); |
| case XVIDC_CSF_MEM_YUVX8: return ("YUVX8"); |
| case XVIDC_CSF_MEM_YUYV8: return ("YUYV8"); |
| case XVIDC_CSF_MEM_RGBA8: return ("RGBA8"); |
| case XVIDC_CSF_MEM_YUVA8: return ("YUVA8"); |
| case XVIDC_CSF_MEM_RGBX10: return ("RGBX10"); |
| case XVIDC_CSF_MEM_YUVX10: return ("YUVX10"); |
| case XVIDC_CSF_MEM_RGB565: return ("RGB565"); |
| case XVIDC_CSF_MEM_Y_UV8: return ("Y_UV8"); |
| case XVIDC_CSF_MEM_Y_UV8_420: return ("Y_UV8_420"); |
| case XVIDC_CSF_MEM_RGB8: return ("RGB8"); |
| case XVIDC_CSF_MEM_YUV8: return ("YUV8"); |
| case XVIDC_CSF_MEM_Y_UV10: return ("Y_UV10"); |
| case XVIDC_CSF_MEM_Y_UV10_420: return ("Y_UV10_420"); |
| case XVIDC_CSF_MEM_Y8: return ("Y8"); |
| case XVIDC_CSF_MEM_Y10: return ("Y10"); |
| case XVIDC_CSF_MEM_BGRA8: return ("BGRA8"); |
| case XVIDC_CSF_MEM_BGRX8: return ("BGRX8"); |
| case XVIDC_CSF_MEM_UYVY8: return ("UYVY8"); |
| case XVIDC_CSF_MEM_BGR8: return ("BGR8"); |
| case XVIDC_CSF_YCBCR_422: return ("YCBCR_422"); |
| case XVIDC_CSF_YCBCR_420: return ("YCBCR_420"); |
| default: |
| return ("Color space format not supported"); |
| } |
| } |
| |
| /******************************************************************************/ |
| /** |
| * This function returns the frame rate for index specified. |
| * |
| * @param VmId specifies the resolution id. |
| * |
| * @return Frame rate in Hz. |
| * |
| * @note None. |
| * |
| *******************************************************************************/ |
| XVidC_FrameRate XVidC_GetFrameRate(XVidC_VideoMode VmId) |
| { |
| const XVidC_VideoTimingMode *VmPtr; |
| |
| VmPtr = XVidC_GetVideoModeData(VmId); |
| if (!VmPtr) { |
| return XVIDC_FR_NUM_SUPPORTED; |
| } |
| |
| return VmPtr->FrameRate; |
| } |
| |
| /******************************************************************************/ |
| /** |
| * This function returns the timing parameters for specified resolution. |
| * |
| * @param VmId specifies the resolution id. |
| * |
| * @return Pointer to a XVidC_VideoTiming structure. |
| * |
| * @note None. |
| * |
| *******************************************************************************/ |
| const XVidC_VideoTiming *XVidC_GetTimingInfo(XVidC_VideoMode VmId) |
| { |
| const XVidC_VideoTimingMode *VmPtr; |
| |
| VmPtr = XVidC_GetVideoModeData(VmId); |
| if (!VmPtr) { |
| return NULL; |
| } |
| |
| return &VmPtr->Timing; |
| } |
| |
| /******************************************************************************/ |
| /** |
| * This function sets the VideoStream structure for the specified video format. |
| * |
| * @param VidStrmPtr is a pointer to the XVidC_VideoStream structure to be |
| * set. |
| * @param VmId specifies the resolution ID. |
| * @param ColorFormat specifies the color format type. |
| * @param Bpc specifies the color depth/bits per color component. |
| * @param Ppc specifies the pixels per clock. |
| * |
| * @return |
| * - XST_SUCCESS if the timing for the supplied ID was found. |
| * - XST_FAILURE, otherwise. |
| * |
| * @note None. |
| * |
| *******************************************************************************/ |
| u32 XVidC_SetVideoStream(XVidC_VideoStream *VidStrmPtr, XVidC_VideoMode VmId, |
| XVidC_ColorFormat ColorFormat, XVidC_ColorDepth Bpc, |
| XVidC_PixelsPerClock Ppc) |
| { |
| const XVidC_VideoTiming *TimingPtr; |
| |
| /* Verify arguments. */ |
| Xil_AssertNonvoid(VidStrmPtr != NULL); |
| Xil_AssertNonvoid(ColorFormat < XVIDC_CSF_NUM_SUPPORTED); |
| Xil_AssertNonvoid((Bpc == XVIDC_BPC_6) || |
| (Bpc == XVIDC_BPC_8) || |
| (Bpc == XVIDC_BPC_10) || |
| (Bpc == XVIDC_BPC_12) || |
| (Bpc == XVIDC_BPC_14) || |
| (Bpc == XVIDC_BPC_16) || |
| (Bpc == XVIDC_BPC_UNKNOWN)); |
| Xil_AssertNonvoid((Ppc == XVIDC_PPC_1) || |
| (Ppc == XVIDC_PPC_2) || |
| (Ppc == XVIDC_PPC_4)); |
| |
| /* Get the timing from the video timing table. */ |
| TimingPtr = XVidC_GetTimingInfo(VmId); |
| if (!TimingPtr) { |
| return XST_FAILURE; |
| } |
| VidStrmPtr->VmId = VmId; |
| VidStrmPtr->Timing = *TimingPtr; |
| VidStrmPtr->FrameRate = XVidC_GetFrameRate(VmId); |
| VidStrmPtr->IsInterlaced = XVidC_IsInterlaced(VmId); |
| VidStrmPtr->ColorFormatId = ColorFormat; |
| VidStrmPtr->ColorDepth = Bpc; |
| VidStrmPtr->PixPerClk = Ppc; |
| |
| /* Set stream to 2D. */ |
| VidStrmPtr->Is3D = FALSE; |
| VidStrmPtr->Info_3D.Format = XVIDC_3D_UNKNOWN; |
| VidStrmPtr->Info_3D.Sampling.Method = XVIDC_3D_SAMPLING_UNKNOWN; |
| VidStrmPtr->Info_3D.Sampling.Position = XVIDC_3D_SAMPPOS_UNKNOWN; |
| |
| return XST_SUCCESS; |
| } |
| |
| /******************************************************************************/ |
| /** |
| * This function sets the VideoStream structure for the specified 3D video |
| * format. |
| * |
| * @param VidStrmPtr is a pointer to the XVidC_VideoStream structure to be |
| * set. |
| * @param VmId specifies the resolution ID. |
| * @param ColorFormat specifies the color format type. |
| * @param Bpc specifies the color depth/bits per color component. |
| * @param Ppc specifies the pixels per clock. |
| * @param Info3DPtr is a pointer to a XVidC_3DInfo structure. |
| * |
| * @return |
| * - XST_SUCCESS if the timing for the supplied ID was found. |
| * - XST_FAILURE, otherwise. |
| * |
| * @return |
| * - XST_SUCCESS |
| * - XST_FAILURE |
| * |
| * @note None. |
| * |
| *******************************************************************************/ |
| u32 XVidC_Set3DVideoStream(XVidC_VideoStream *VidStrmPtr, XVidC_VideoMode VmId, |
| XVidC_ColorFormat ColorFormat, XVidC_ColorDepth Bpc, |
| XVidC_PixelsPerClock Ppc, XVidC_3DInfo *Info3DPtr) |
| { |
| u32 Status; |
| u16 Vblank0; |
| u16 Vblank1; |
| |
| /* Verify arguments */ |
| Xil_AssertNonvoid(Info3DPtr != NULL); |
| |
| /* Initialize with info for 2D frame. */ |
| Status = XVidC_SetVideoStream(VidStrmPtr, VmId, ColorFormat, Bpc, Ppc); |
| if (Status != XST_SUCCESS) { |
| return XST_FAILURE; |
| } |
| |
| /* Set stream to 3D. */ |
| VidStrmPtr->Is3D = TRUE; |
| VidStrmPtr->Info_3D = *Info3DPtr; |
| |
| /* Only 3D format supported is frame packing. */ |
| if (Info3DPtr->Format != XVIDC_3D_FRAME_PACKING) { |
| return XST_FAILURE; |
| } |
| |
| /* Update the timing based on the 3D format. */ |
| |
| /* An interlaced format is converted to a progressive frame: */ |
| /* 3D VActive = (2D VActive * 4) + (2D VBlank field0) + |
| (2D Vblank field1 * 2) */ |
| if (VidStrmPtr->IsInterlaced) { |
| Vblank0 = VidStrmPtr->Timing.F0PVTotal - |
| VidStrmPtr->Timing.VActive; |
| Vblank1 = VidStrmPtr->Timing.F1VTotal - |
| VidStrmPtr->Timing.VActive; |
| VidStrmPtr->Timing.VActive = (VidStrmPtr->Timing.VActive * 4) + |
| Vblank0 + (Vblank1 * 2); |
| |
| /* Set VTotal */ |
| VidStrmPtr->Timing.F0PVTotal *= 2; |
| VidStrmPtr->Timing.F0PVTotal += VidStrmPtr->Timing.F1VTotal * 2; |
| |
| /* Clear field 1 values. */ |
| VidStrmPtr->Timing.F1VFrontPorch = 0; |
| VidStrmPtr->Timing.F1VSyncWidth = 0; |
| VidStrmPtr->Timing.F1VBackPorch = 0; |
| VidStrmPtr->Timing.F1VTotal = 0; |
| |
| /* Set format to progressive */ |
| VidStrmPtr->IsInterlaced = FALSE; |
| } |
| /* Progressive */ |
| else { |
| /* 3D Vactive = (2D VActive * 2) + (2D VBlank) */ |
| Vblank0 = VidStrmPtr->Timing.F0PVTotal - |
| VidStrmPtr->Timing.VActive; |
| VidStrmPtr->Timing.VActive = (VidStrmPtr->Timing.VActive * 2) + |
| Vblank0; |
| |
| /* Set VTotal. */ |
| VidStrmPtr->Timing.F0PVTotal = VidStrmPtr->Timing.F0PVTotal * 2; |
| } |
| |
| return XST_SUCCESS; |
| } |
| |
| /******************************************************************************/ |
| /** |
| * This function prints the stream information on STDIO/UART console. |
| * |
| * @param Stream is a pointer to video stream. |
| * |
| * @return None. |
| * |
| * @note None. |
| * |
| *******************************************************************************/ |
| void XVidC_ReportStreamInfo(const XVidC_VideoStream *Stream) |
| { |
| if (!XVidC_GetVideoModeData(Stream->VmId) && |
| (Stream->VmId != XVIDC_VM_CUSTOM)) { |
| xil_printf("\tThe stream ID (%d) is not supported.\r\n", |
| Stream->VmId); |
| return; |
| } |
| |
| xil_printf("\tColor Format: %s\r\n", |
| XVidC_GetColorFormatStr(Stream->ColorFormatId)); |
| xil_printf("\tColor Depth: %d\r\n", Stream->ColorDepth); |
| xil_printf("\tPixels Per Clock: %d\r\n", Stream->PixPerClk); |
| xil_printf("\tMode: %s\r\n", |
| Stream->IsInterlaced ? "Interlaced" : "Progressive"); |
| |
| if (Stream->Is3D) { |
| xil_printf("\t3D Format: %s\r\n", |
| XVidC_Get3DFormatStr(Stream->Info_3D.Format)); |
| } |
| |
| if (Stream->VmId == XVIDC_VM_CUSTOM) { |
| xil_printf("\tFrame Rate: %dHz\r\n", |
| Stream->FrameRate); |
| xil_printf("\tResolution: %dx%d [Custom Mode]\r\n", |
| Stream->Timing.HActive, Stream->Timing.VActive); |
| xil_printf("\tPixel Clock: %d\r\n", |
| XVidC_GetPixelClockHzByHVFr( |
| Stream->Timing.HTotal, |
| Stream->Timing.F0PVTotal, |
| Stream->FrameRate)); |
| } |
| else { |
| xil_printf("\tFrame Rate: %s\r\n", |
| XVidC_GetFrameRateStr(Stream->VmId)); |
| xil_printf("\tResolution: %s\r\n", |
| XVidC_GetVideoModeStr(Stream->VmId)); |
| xil_printf("\tPixel Clock: %d\r\n", |
| XVidC_GetPixelClockHzByVmId(Stream->VmId)); |
| } |
| } |
| |
| /******************************************************************************/ |
| /** |
| * This function prints timing information on STDIO/Uart console. |
| * |
| * @param Timing is a pointer to Video Timing structure of the stream. |
| * @param IsInterlaced is a TRUE/FALSE flag that denotes the timing |
| * parameter is for interlaced/progressive stream. |
| * |
| * @return None. |
| * |
| * @note None. |
| * |
| *******************************************************************************/ |
| void XVidC_ReportTiming(const XVidC_VideoTiming *Timing, u8 IsInterlaced) |
| { |
| xil_printf("\r\n\tHSYNC Timing: hav=%04d, hfp=%02d, hsw=%02d(hsp=%d), " |
| "hbp=%03d, htot=%04d \n\r", Timing->HActive, |
| Timing->HFrontPorch, Timing->HSyncWidth, |
| Timing->HSyncPolarity, |
| Timing->HBackPorch, Timing->HTotal); |
| |
| /* Interlaced */ |
| if (IsInterlaced) { |
| xil_printf("\tVSYNC Timing (Field 0): vav=%04d, vfp=%02d, " |
| "vsw=%02d(vsp=%d), vbp=%03d, vtot=%04d\n\r", |
| Timing->VActive, Timing->F0PVFrontPorch, |
| Timing->F0PVSyncWidth, Timing->VSyncPolarity, |
| Timing->F0PVBackPorch, Timing->F0PVTotal); |
| xil_printf("\tVSYNC Timing (Field 1): vav=%04d, vfp=%02d, " |
| "vsw=%02d(vsp=%d), vbp=%03d, vtot=%04d\n\r", |
| Timing->VActive, Timing->F1VFrontPorch, |
| Timing->F1VSyncWidth, Timing->VSyncPolarity, |
| Timing->F1VBackPorch, Timing->F1VTotal); |
| } |
| /* Progressive */ |
| else { |
| xil_printf("\tVSYNC Timing: vav=%04d, vfp=%02d, " |
| "vsw=%02d(vsp=%d), vbp=%03d, vtot=%04d\n\r", |
| Timing->VActive, Timing->F0PVFrontPorch, |
| Timing->F0PVSyncWidth, Timing->VSyncPolarity, |
| Timing->F0PVBackPorch, Timing->F0PVTotal); |
| } |
| } |
| |
| /******************************************************************************/ |
| /** |
| * This function returns the pointer to video mode data at the provided index |
| * of the custom video mode table. |
| * |
| * @param VmId specifies the resolution ID. |
| * |
| * @return Pointer to XVidC_VideoTimingMode structure based on the given |
| * video mode. |
| * |
| * @note None. |
| * |
| *******************************************************************************/ |
| static const XVidC_VideoTimingMode *XVidC_GetCustomVideoModeData( |
| XVidC_VideoMode VmId) |
| { |
| u16 Index; |
| |
| for (Index = 0; Index < XVidC_NumCustomModes; Index++) { |
| if (VmId == (XVidC_CustomTimingModes[Index].VmId)) { |
| return &(XVidC_CustomTimingModes[Index]); |
| } |
| } |
| |
| /* ID not found within the custom video mode table. */ |
| return NULL; |
| } |
| |
| /******************************************************************************/ |
| /** |
| * This function returns whether or not the video timing mode is a reduced |
| * blanking mode or not. |
| * |
| * @param VideoModeStr specifies the resolution name string. |
| * @param RbN specifies the type of reduced blanking: |
| * - 0 = No Reduced Blanking |
| * - 1 = RB |
| * - 2 = RB2 |
| * |
| * @return If the reduced blanking type is compatible with the video mode: |
| * - 0 = Not supported |
| * - 1 = Video mode supports the RB type |
| * |
| * @note None. |
| * |
| *******************************************************************************/ |
| static u8 XVidC_IsVtmRb(const char *VideoModeStr, u8 RbN) |
| { |
| while ((*VideoModeStr !='\0') && (*VideoModeStr != 'R')) { |
| VideoModeStr++; |
| } |
| |
| if (*(VideoModeStr + 2) == ')') { |
| return RbN == 1; |
| } |
| if (*(VideoModeStr + 2) == '2') { |
| return RbN == 2; |
| } |
| return 0; |
| } |
| /** @} */ |