⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hdmi.c

📁 1. 8623L平台
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * * Copyright (c) 2001-2007 Sigma Designs, Inc.  * All Rights Reserved. Proprietary and Confidential. * *//**  @file   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 "common.h"#include "hdmi.h"#include "SiI9031.h"#include "AD9380.h"#include "../../samples/dvi_hdmi_update.h"#include "../../samples/dvi_hdmi.h"#ifdef _DEBUGstatic 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};#endif/* CEA 861-C/D subset of all EMhwlib video modes *//* translates VIC to enum EMhwlibTVStandard */const enum EMhwlibTVStandard cap_hdmi_cea861_modes[HDMI_CEA861_VIDEOMODES_N] = HDMI_CEA861_VIDEOMODES;// VESA/CVT subset of all EMhwlib video modesconst enum EMhwlibTVStandard cap_hdmi_it_modes[] = HDMI_VESA_CVT_VIDEOMODES;RMuint32 cap_hdmi_it_modes_n;// internal state of the HDMI capture portstruct cap_hdmi_instance {	// Access	struct RUA *pRUA;	struct cap_chip_instance *pChip;		// State	enum cap_hdmi_mode hdmi_mode;	RMbool upsample_from_422;	struct cap_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 cap_hdmi_update UpdateHDMI;};RMstatus cap_hdmi_open(	struct RUA *pRUA, 	struct cap_chip_instance *pChip, 	struct cap_hdmi_instance **ppHDMI){	RMstatus err = RM_OK;	struct cap_hdmi_instance *pHDMI;		// Sanity checks	if (ppHDMI == NULL) return RM_FATALINVALIDPOINTER;	*ppHDMI = NULL;	if (pRUA == NULL) return RM_FATALINVALIDPOINTER;	if (pChip == NULL) return RM_FATALINVALIDPOINTER;		// Allocate and clear local instance	pHDMI = (struct cap_hdmi_instance *)RMMalloc(sizeof(struct cap_hdmi_instance));	if (pHDMI == NULL) {		RMDBGLOG((ENABLE, "FATAL! Not enough memory for struct cap_hdmi_instance!\n"));		return RM_FATALOUTOFMEMORY;	}	RMMemset(pHDMI, 0, sizeof(struct cap_hdmi_instance));	*ppHDMI = pHDMI;		cap_hdmi_it_modes_n = sizeof(cap_hdmi_it_modes) / sizeof(cap_hdmi_it_modes[0]);		// Set default and non-zero startup values	pHDMI->pRUA = pRUA;	pHDMI->pChip = pChip;	pHDMI->hdmi_mode = cap_hdmi_mode_unknown;	pHDMI->UpdateHDMI.APIVersion = 1;		// Open selected chip	err = RM_OK;	switch (pHDMI->pChip->chip) {	case cap_chip_none:		err = RM_NOT_SUPPORTED;  // no "direct" hdmi input		break;	case cap_chip_SiI9031:		err = RM_OK;		break;	case cap_chip_AD9380:		err = RM_OK;		break;	default:		err = RM_INVALID_PARAMETER;	}		if (RMFAILED(err)) {		RMFree(pHDMI);		*ppHDMI = NULL;	}	return err;}RMstatus cap_hdmi_close(	struct cap_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->pChip->chip) {	case cap_chip_SiI9031:		err = RM_OK;		break;	case cap_chip_AD9380:		err = RM_OK;		break;	default:		err = RM_ERROR;	}		RMFree(pHDMI);		return err;}/*** Chip Setup functions ***//* tri-state all outputs and power down the selected chip */RMstatus cap_hdmi_tristate(	struct cap_hdmi_instance *pHDMI){	// Sanity checks	if (pHDMI == NULL) return RM_FATALINVALIDPOINTER;		switch (pHDMI->pChip->chip) {	case cap_chip_SiI9031:		return cap_SiI9031_tristate(pHDMI->pChip->instance.pSiI9031);	case cap_chip_AD9380:		return cap_AD9380_tristate(pHDMI->pChip->instance.pAD9380);	default:		return RM_ERROR;	}}/* prepares the selected input for capture (initializes the chip) */RMstatus cap_hdmi_select_input(	struct cap_hdmi_instance *pHDMI, 	RMuint32 input){	RMstatus err =RM_OK;	switch (pHDMI->pChip->chip) {	case cap_chip_SiI9031:		err = cap_SiI9031_init_capture(pHDMI->pChip->instance.pSiI9031, input, FALSE);		break;	case cap_chip_AD9380:		err = cap_AD9380_init_HDMI_capture(pHDMI->pChip->instance.pAD9380, input);		break;	default:		err = RM_ERROR;		break;	}	if (RMFAILED(err)) {		RMDBGLOG((ENABLE, "error in cap_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 cap_hdmi_apply_pixelrep(	struct cap_hdmi_instance *pHDMI, 	RMuint32 pixel_rep){	switch (pHDMI->pChip->chip) {	case cap_chip_SiI9031:		return cap_SiI9031_apply_pixelrep(pHDMI->pChip->instance.pSiI9031, pixel_rep);	case cap_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 cap_hdmi_setup_audio(	struct cap_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, 		 88200, 768000,  96000,      0, 		 176400, 12000, 192000,      0	};	static const RMuint32 fs_tab_hdmi[16] = {		 44100,      0,  48000,  32000, 		     0,      0,      0,      0, 		 88200, 768000,  96000,      0, 		 176400,     0, 192000,      0	};	RMDBGLOG((FUNCNAME, "%s\n",__func__));		// Sanity checks	if (pHDMI == NULL) return RM_FATALINVALIDPOINTER;	if (pSamplingRate == NULL) return RM_FATALINVALIDPOINTER;		// remember previous SamplingRate	prev_fs = *pSamplingRate;		// default SamplingRate to 0	*pSamplingRate = 0;		// transmission is not in HDMI mode, no audio expected	if (pHDMI->hdmi_mode != cap_hdmi_mode_HDMI){		RMDBGLOG((ENABLE, "XXXXXXXXXXX not HDMI mode\n"));		return RM_OK;	}	// chip specific processing	switch (pHDMI->pChip->chip) {	case cap_chip_SiI9031:		// start audio procesing		err = cap_SiI9031_init_audio_clock(pHDMI->pChip->instance.pSiI9031, TRUE, 256);  // TODO		if (RMFAILED(err)) return err;				// read channel status		err = cap_SiI9031_get_audio_channel_status(pHDMI->pChip->instance.pSiI9031, ch_stat);		if (RMFAILED(err)) return err;		RMDBGLOG((ENABLE, "[hdmi] audio channel status [39:0]: %02X.%02X.%02X.%02X.%02X\n", ch_stat[4], ch_stat[3], ch_stat[2], ch_stat[1], ch_stat[0]));				// read N/CTS pair, CTS = (f(TMDS clk) * N) / (128 * f(s))		err = cap_SiI9031_get_audio_n_cts(pHDMI->pChip->instance.pSiI9031, &n, &cts, &fs_n_cts);		if (RMFAILED(err)) return err;		RMDBGLOG((ENABLE, "[hdmi] N/CTS: %lu/%lu\n", n, cts));				break;	case cap_chip_AD9380:		RMDBGLOG((ENABLE, "XXXXXXXXXXXXXXXXXXXXXXX %s\n",__func__));		err = cap_AD9380_get_audio_channel_status(pHDMI->pChip->instance.pAD9380, ch_stat);		break;	default:		return RM_ERROR;	}		// not consumer use, or not mode 00	if ((ch_stat[0] & 0xC1) != 0x00) return RM_OK;		// extract fs tag from channel status	pclk = ch_stat[3] & 0x0F;		// no audio present	if (pclk == 1) return RM_OK;		if (n && cts) {		// match approximate SamplingRate from pixel clock and N/CTS to nearest valid sample rate		if (fs_n_cts) {			RMuint32 i, fs, fs_mult, fs_mod;			static const RMuint32 fs_base[] = {8000, 11025, 12000, 32000, 44100, 48000};						RMDBGLOG((ENABLE, "[hdmi] Audio fs from N/CTS: %lu (Approx.)\n", fs_n_cts));			fs = fs_n_cts;			for (i = (obey_hdmi ? 3 : 0); i < sizeof(fs_base) / sizeof(RMuint32); i++) {				fs_mult = fs / fs_base[i];				fs_mod = fs % fs_base[i];				if (fs_mod < (fs_base[i] / 8)) {					fs_n_cts = fs_base[i] * fs_mult;					break;				} else if (fs_mod > (fs_base[i] * 7 / 8)) {					fs_mult++;					fs_n_cts = fs_base[i] * fs_mult;					break;				}			}			RMDBGLOG((ENABLE, "[hdmi] Audio fs from N/CTS: %lu\n", fs_n_cts));		}				// SamplingRate from fs tag		*pSamplingRate = obey_hdmi ? fs_tab_hdmi[pclk] : fs_tab[pclk];		if (*pSamplingRate != prev_fs) {			RMDBGLOG((ENABLE, "[hdmi] Audio fs from tag: %s, tag=0x%01lX\n", 				(pclk == 0) ? "44.1 kHz" : 				(pclk == 1) ? "<not indicated>" : 				(pclk == 2) ? "48 kHz" : 				(pclk == 3) ? "32 kHz" : 				(pclk == 4) ? "22.05 kHz <invalid>" : 				(pclk == 5) ? "11.025 kHz <invalid>" : 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -