📄 play_capture_hdmi.c
字号:
/* * * Copyright (c) 2001-2007 Sigma Designs, Inc. * All Rights Reserved. Proprietary and Confidential. * *//** @file play_capture_hdmi.c @brief Interface to access an HDMI capture port @author Christian Wolff, Sean.Sekwon.Choi @date 2007-07-16*/// to enable or disable the debug messages of this source file, put 1 or 0 below#if 1#define LOCALDBG ENABLE#else#define LOCALDBG DISABLE#endif#include "sample_os.h"#define ALLOW_OS_CODE 1#include "../rua/include/rua.h"#include "../rua/include/rua_property.h"#include "../dcc/include/dcc.h"#include "../rmcore/include/rmstatustostring.h"#include "../rmlibcw/include/rmlibcw.h"#include "dvi_hdmi_update.h"#include "dvi_hdmi.h"#include "play_capture_common.h"#include "play_capture_hdmi.h"#include "play_capture_SiI9031.h"#include "play_capture_AD9380.h"static const RMascii *CEA861VICNames[] = { "Custom", // 0 "VGA 640x480 60Hz 1X", // 1 " 480p 60Hz 1X 4:3", // 2 " 480p 60Hz 1X 16:9", // 3 " 720p 60Hz 1X 16:9", // 4 "1080i 60Hz 1X 16:9", // 5 " 480i 60Hz 2X 4:3", // 6 " 480i 60Hz 2X 16:9", // 7 " 240p 60Hz 2X 4:3", // 8 " 240p 60Hz 2X 16:9", // 9 " 480i 60Hz 4X 4:3", // 10 " 480i 60Hz 4X 16:9", // 11 " 240p 60Hz 4X 4:3", // 12 " 240p 60Hz 4X 16:9", // 13 " 480p 60Hz 2X 4:3", // 14 " 480p 60Hz 2X 16:9", // 15 "1080p 60Hz 1X 16:9", // 16 " 576p 50Hz 1X 4:3", // 17 " 576p 50Hz 1X 16:9", // 18 " 720p 50Hz 1X 16:9", // 19 "1080i 50Hz 1X 16:9", // 20 " 576i 50Hz 2X 4:3", // 21 " 576i 50Hz 2X 16:9", // 22 " 288p 50Hz 2X 4:3", // 23 " 288p 50Hz 2X 16:9", // 24 " 576i 50Hz 4X 4:3", // 25 " 576i 50Hz 4X 16:9", // 26 " 288p 50Hz 4X 4:3", // 27 " 288p 50Hz 4X 16:9", // 28 " 576p 50Hz 2X 4:3", // 29 " 576p 50Hz 2X 16:9", // 30 "1080p 50Hz 1X 16:9", // 31 "1080p 24Hz 1X 16:9", // 32 "1080p 25Hz 1X 16:9", // 33 "1080p 30Hz 1X 16:9", // 34 " 480p 60Hz 4X 4:3", // 35 " 480p 60Hz 4X 16:9", // 36 " 576p 50Hz 4X 4:3", // 37 " 576p 50Hz 4X 16:9", // 38 "1080i 50Hz 1X 16:9", // 39 "1080i 100Hz 1X 16:9", // 40 " 720p 100Hz 1X 16:9", // 41 " 576p 100Hz 1X 4:3", // 42 " 576p 100Hz 1X 16:9", // 43 " 576i 100Hz 2X 4:3", // 44 " 576i 100Hz 2X 16:9", // 45 "1080i 120Hz 1X 16:9", // 46 " 720p 120Hz 1X 16:9", // 47 " 480p 120Hz 1X 4:3", // 48 " 480p 120Hz 1X 16:9", // 49 " 480i 120Hz 2X 4:3", // 50 " 480i 120Hz 2X 16:9", // 51 " 576p 200Hz 1X 4:3", // 52 " 576p 200Hz 1X 16:9", // 53 " 576i 200Hz 2X 4:3", // 54 " 576i 200Hz 2X 16:9", // 55 " 480p 240Hz 1X 4:3", // 56 " 480p 240Hz 1X 16:9", // 57 " 480i 240Hz 2X 4:3", // 58 " 480i 240Hz 2X 16:9", // 59};/* CEA 861-C/D subset of all EMhwlib video modes *//* translates VIC to enum EMhwlibTVStandard */const enum EMhwlibTVStandard capsam_hdmi_cea861_modes[HDMI_CEA861_VIDEOMODES_N] = HDMI_CEA861_VIDEOMODES;// VESA/CVT subset of all EMhwlib video modesconst enum EMhwlibTVStandard capsam_hdmi_it_modes[] = HDMI_VESA_CVT_VIDEOMODES;RMuint32 capsam_hdmi_it_modes_n;// internal state of the HDMI capture portstruct capsam_hdmi_instance { // Access struct RUA *pRUA; RMuint32 I2CModuleID; // emhwlib Module ID of the I2C bus access struct EMhwlibI2CDeviceParameter I2CDevice; RMuint8 BaseDevice; // base device address of the device enum capsam_chip chip; struct capsam_SiI9031_instance *pSiI9031; struct capsam_AD9380_instance *pAD9380; // State enum capsam_hdmi_mode hdmi_mode; RMbool upsample_from_422; struct capsam_hdmi_avi_info last_avi; RMuint8 last_isrc[32]; RMuint8 last_isrc_header; RMbool last_isrc2; enum EMhwlibTVStandard TVStandard; enum EMhwlibColorSpace InputColorSpace; enum EMhwlibInputColorFormat InputColorFormat; struct EMhwlibAspectRatio PictureAspectRatio; struct capsam_hdmi_update UpdateHDMI;};#if 0RMstatus capsam_hdmi_open( struct RUA *pRUA, struct capsam_hdmi_instance **ppHDMI, enum capsam_chip hdmi_chip, RMuint32 I2CModuleID, // emhwlib Module ID of the I2C bus access struct EMhwlibI2CDeviceParameter *pI2CDevice){ RMstatus err = RM_OK; struct capsam_hdmi_instance *pHDMI; // Sanity checks if (ppHDMI == NULL) return RM_FATALINVALIDPOINTER; *ppHDMI = NULL; if (pRUA == NULL) return RM_FATALINVALIDPOINTER; // Allocate and clear local instance pHDMI = (struct capsam_hdmi_instance *)RMMalloc(sizeof(struct capsam_hdmi_instance)); if (pHDMI == NULL) { fprintf(stderr, "FATAL! Not enough memory for struct capsam_hdmi_instance!\n"); return RM_FATALOUTOFMEMORY; } RMMemset(pHDMI, 0, sizeof(struct capsam_hdmi_instance)); *ppHDMI = pHDMI; capsam_hdmi_it_modes_n = sizeof(capsam_hdmi_it_modes) / sizeof(capsam_hdmi_it_modes[0]); // Set default and non-zero startup values pHDMI->pRUA = pRUA; pHDMI->chip = hdmi_chip; if (pI2CDevice != NULL) { pHDMI->I2CModuleID = I2CModuleID; pHDMI->I2CDevice = *pI2CDevice; pHDMI->BaseDevice = pI2CDevice->DevAddr; } pHDMI->hdmi_mode = capsam_hdmi_mode_unknown; pHDMI->UpdateHDMI.APIVersion = 1; // Open selected chip switch (pHDMI->chip) { case capsam_chip_none: err = RM_NOT_SUPPORTED; // no "direct" hdmi input break; case capsam_chip_SiI9031: err = capsam_SiI9031_open(pRUA, &(pHDMI->pSiI9031), I2CModuleID, pI2CDevice); break; case capsam_chip_AD9380: err = capsam_AD9380_open(pRUA, &(pHDMI->pAD9380), I2CModuleID, pI2CDevice); break; default: err = RM_INVALID_PARAMETER; } if (RMFAILED(err)) { RMFree(pHDMI); *ppHDMI = NULL; } return err;}#elseRMstatus capsam_hdmi_open( struct RUA *pRUA, struct capsam_hdmi_instance **ppHDMI, enum capsam_chip hdmi_chip, void* p_chip_handle){ RMstatus err = RM_OK; struct capsam_hdmi_instance *pHDMI; // Sanity checks if (ppHDMI == NULL) return RM_FATALINVALIDPOINTER; *ppHDMI = NULL; if (pRUA == NULL) return RM_FATALINVALIDPOINTER; // Allocate and clear local instance pHDMI = (struct capsam_hdmi_instance *)RMMalloc(sizeof(struct capsam_hdmi_instance)); if (pHDMI == NULL) { fprintf(stderr, "FATAL! Not enough memory for struct capsam_hdmi_instance!\n"); return RM_FATALOUTOFMEMORY; } RMMemset(pHDMI, 0, sizeof(struct capsam_hdmi_instance)); *ppHDMI = pHDMI; // Set default and non-zero startup values pHDMI->pRUA = pRUA; pHDMI->chip = hdmi_chip; pHDMI->hdmi_mode = capsam_hdmi_mode_unknown; pHDMI->UpdateHDMI.APIVersion = 1; if(p_chip_handle){ // connect selected chip to hdmi object switch (pHDMI->chip) { case capsam_chip_none: err = RM_NOT_SUPPORTED; // no "direct" hdmi input break; case capsam_chip_SiI9031: pHDMI->pSiI9031 = (struct capsam_SiI9031_instance *)p_chip_handle; break; case capsam_chip_AD9380: pHDMI->pAD9380 = (struct capsam_AD9380_instance *)p_chip_handle; break; default: err = RM_INVALID_PARAMETER; break; } }else{ RMFree(pHDMI); *ppHDMI = NULL; err = RM_INVALID_PARAMETER; } return err;}#endif#if 0RMstatus capsam_hdmi_close( struct capsam_hdmi_instance *pHDMI){ RMstatus err = RM_OK; // Sanity checks if (pHDMI == NULL) return RM_OK; // already closed // Free all ressources switch (pHDMI->chip) { case capsam_chip_SiI9031: err = capsam_SiI9031_close(pHDMI->pSiI9031); break; case capsam_chip_AD9380: err = capsam_AD9380_close(pHDMI->pAD9380); break; default: err = RM_ERROR; } RMFree(pHDMI); return err;}#elseRMstatus capsam_hdmi_close( struct capsam_hdmi_instance *pHDMI){ RMstatus err = RM_OK; RMDBGLOG((FUNCNAME, "%s\n",__func__)); // Sanity checks if (pHDMI == NULL) return RM_OK; // already closed // Free all ressources switch (pHDMI->chip) { case capsam_chip_SiI9031: pHDMI->pSiI9031 = NULL; break; case capsam_chip_AD9380: pHDMI->pAD9380 = NULL; break; default: err = RM_ERROR; } RMFree(pHDMI); return err;}#endif/*** Chip Setup functions ***//* tri-state all outputs and power down the selected chip */RMstatus capsam_hdmi_tristate( struct capsam_hdmi_instance *pHDMI){ // Sanity checks if (pHDMI == NULL) return RM_FATALINVALIDPOINTER; switch (pHDMI->chip) { case capsam_chip_SiI9031: return capsam_SiI9031_tristate(pHDMI->pSiI9031); case capsam_chip_AD9380: return capsam_AD9380_tristate(pHDMI->pAD9380); default: return RM_ERROR; }}/* prepares the selected input for capture (initializes the chip) */RMstatus capsam_hdmi_select_input( struct capsam_hdmi_instance *pHDMI, RMuint32 input){ RMstatus err =RM_OK; switch (pHDMI->chip) { case capsam_chip_SiI9031: err = capsam_SiI9031_init_capture(pHDMI->pSiI9031, input, FALSE); break; case capsam_chip_AD9380: err = capsam_AD9380_init_HDMI_capture(pHDMI->pAD9380, input); break; default: err = RM_ERROR; break; } if (RMFAILED(err)) { fprintf(stderr, "error in capsam_hdmi_select_input\n"); return err; } return err;}/* set the pixel repetition value announced in the AVI info frame. This reduces the pixel clock and all horizontal timing values accordingly. */RMstatus capsam_hdmi_apply_pixelrep( struct capsam_hdmi_instance *pHDMI, RMuint32 pixel_rep){ switch (pHDMI->chip) { case capsam_chip_SiI9031: return capsam_SiI9031_apply_pixelrep(pHDMI->pSiI9031, pixel_rep); case capsam_chip_AD9380: return RM_NOTIMPLEMENTED; // TODO default: return RM_ERROR; }}/** Initializes audio section of HDMI chip Reads channel status from HDMI chip Returns current sample frequency, or 0 if no audio, in *pSamplingRate*/RMstatus capsam_hdmi_setup_audio( struct capsam_hdmi_instance *pHDMI, RMuint32 MClkFactor, RMuint32 *pSamplingRate){ RMstatus err; RMuint32 pclk, n, cts, fs_n_cts, prev_fs; RMuint8 ch_stat[5]; RMbool obey_hdmi = TRUE; // choice: only use valid HDMI fs, or all SPDIF fs static const RMuint32 fs_tab[16] = { 44100, 0, 48000, 32000, 22050, 11025, 24000, 16000,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -