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

📄 play_capture.c

📁 Sample code for use on smp 863x processor.
💻 C
📖 第 1 页 / 共 5 页
字号:
	EMhwlibTVStandard_HDMI_1080p50, // 31	EMhwlibTVStandard_HDMI_1080p24, // 32	EMhwlibTVStandard_HDMI_1080p25, // 33	EMhwlibTVStandard_HDMI_1080p30, // 34	EMhwlibTVStandard_HDMI_2880x480p60, // 35	EMhwlibTVStandard_HDMI_2880x480p60, // 36	EMhwlibTVStandard_HDMI_2880x576p50, // 37	EMhwlibTVStandard_HDMI_2880x576p50, // 38	EMhwlibTVStandard_HDMI_1080i50_1250, // 39	EMhwlibTVStandard_HDMI_1080i100, // 40	EMhwlibTVStandard_HDMI_720p100, // 41	EMhwlibTVStandard_HDMI_576p100, // 42	EMhwlibTVStandard_HDMI_576p100, // 43	EMhwlibTVStandard_HDMI_576i100, // 44	EMhwlibTVStandard_HDMI_576i100, // 45	EMhwlibTVStandard_HDMI_1080i120, // 46	EMhwlibTVStandard_HDMI_720p120, // 47	EMhwlibTVStandard_HDMI_480p120, // 48	EMhwlibTVStandard_HDMI_480p120, // 49	EMhwlibTVStandard_HDMI_480i120, // 50	EMhwlibTVStandard_HDMI_480i120, // 51	EMhwlibTVStandard_HDMI_576p200, // 52	EMhwlibTVStandard_HDMI_576p200, // 53	EMhwlibTVStandard_HDMI_576i200, // 54	EMhwlibTVStandard_HDMI_576i200, // 55	EMhwlibTVStandard_HDMI_480p240, // 56	EMhwlibTVStandard_HDMI_480p240, // 57	EMhwlibTVStandard_HDMI_480i240, // 58	EMhwlibTVStandard_HDMI_480i240, // 59};/* Compare two values and return a weighted match value.    Return value is 'weight' if both values are equal,    or 50% of 'weight' minus the percentage points 'a' is away from 'b'. */static inline RMuint32 comp_weight(RMuint32 a, RMuint32 b, RMuint32 weight) {	RMuint32 dist;	if (a == b) return weight;	dist = (a > b) ? a - b : b - a;//	weight /= 2;	dist = (dist * 100) / b;	return (weight > dist) ? weight - dist : 0;}static RMascii *CEA861_ShortDescriptorVideoResolutions[] = {	"Unknown",	"VGA 640x480 60Hz",  // 1	"480p 60Hz (4:3)",   // 2	"480p 60Hz (16:9)",  // 3	"720p 60Hz",         // 4	"1080i 60Hz",        // 5	"480i 60Hz (4:3)",   // 6	"480i 60Hz (16:9)",  // 7	"240p 60Hz (4:3)",   // 8	"240p 60Hz (16:9)",  // 9	"480i 60Hz (4:3)",   // 10	"480i 60Hz (16:9)",  // 11	"240p 60Hz (4:3)",   // 12	"240p 60Hz (16:9)",  // 13	"480p 60Hz (4:3)",   // 14	"480p 60Hz (16:9)",  // 15	"1080p 60Hz",        // 16	"576p 50Hz (4:3)",   // 17	"576p 50Hz (16:9)",  // 18	"720p 50Hz",         // 19	"1080i 50Hz",        // 20	"576i 50Hz (4:3)",   // 21	"576i 50Hz (16:9)",  // 22	"288p 50Hz (4:3)",   // 23	"288p 50Hz (16:9)",  // 24	"576i 50Hz (4:3)",   // 25	"576i 50Hz (16:9)",  // 26	"288p 50Hz (4:3)",   // 27	"288p 50Hz (16:9)",  // 28	"576p 50Hz (4:3)",   // 29	"576p 50Hz (16:9)",  // 30	"1080p 50Hz",        // 31	"1080p 24Hz",        // 32	"1080p 25Hz",        // 33	"1080p 30Hz",        // 34	"480p 60Hz (4:3)",   // 35	"480p 60Hz (16:9)",  // 36	"576p 50Hz (4:3)",   // 37	"576p 50Hz (16:9)",  // 38	"1080i 50Hz",        // 39	"1080i 100Hz",       // 40	"720p 100Hz",        // 41	"576p 100Hz (4:3)",  // 42	"576p 100Hz (16:9)", // 43	"576i 100Hz (4:3)",  // 44	"576i 100Hz (16:9)", // 45	"1080i 120Hz",       // 46	"720p 120Hz",        // 47	"480p 120Hz (4:3)",  // 48	"480p 120Hz (16:9)", // 49	"480i 120Hz (4:3)",  // 50	"480i 120Hz (16:9)", // 51	"576p 200Hz (4:3)",  // 52	"576p 200Hz (16:9)", // 53	"576i 200Hz (4:3)",  // 54	"576i 200Hz (16:9)", // 55	"480p 240Hz (4:3)",  // 56	"480p 240Hz (16:9)", // 57	"480i 240Hz (4:3)",  // 58	"480i 240Hz (16:9)", // 59};/* Detect video format from the line and pixel counter in the SiI9031 */static RMstatus get_format_SiI9031(	struct dcc_context *dcc_info, 	struct capture_cmdline *options, 	struct local_cmdline *local_opt, 	RMuint8 dev, 	RMuint8 delay, 	RMbool *update){	RMstatus err;	RMuint32 reg;	RMuint8 data[17];	RMuint32 h_res, v_res, de_pix, de_lin, vid_vtavl, vid_vfp, vid_hfp, vid_hswidth, vid_xpcnt, pixel_rep, h_shift;	RMbool intrl, vspol, hspol;	RMuint32 i, best_match;	enum EMhwlibTVStandard mode, old;	RMascii *StandardName;	RMbool limit861 = FALSE;  /* whether to limit to CEA 861 modes */		if (update) *update = FALSE;	old = options->TVStandard;		/* read measurement registers from SiI9031 */	err = read_i2c(dcc_info->pRUA, delay, dev, 0x06, &reg); if (RMFAILED(err)) return err; 	if ((reg & 0x03) != 0x03) {		fprintf(stderr, "no %s%s%s!\n", 			(reg & 0x08) ? "" : "power", 			(reg & 0x02) ? "" : (reg & 0x08) ? "clock" : (reg & 0x01) ? " or clock" : ", clock", 			(reg & 0x01) ? "" : ((reg & 0x02) && (reg & 0x08)) ? "sync" : " or sync");		return RM_ERROR;	}		err = read_i2c(dcc_info->pRUA, delay, dev, 0x08, &pixel_rep); if (RMFAILED(err)) return err; 	pixel_rep = RMunshiftBits(pixel_rep, 2, 6);	h_shift = (pixel_rep > 1) ? 2 : pixel_rep;		err = read_i2c_data(dcc_info->pRUA, delay, dev, 0x3A, &data[0], 4); if (RMFAILED(err)) return err; 	err = read_i2c_data(dcc_info->pRUA, delay, dev, 0x4E, &data[4], 8); if (RMFAILED(err)) return err; 	err = read_i2c_data(dcc_info->pRUA, delay, dev, 0x59, &data[12], 4); if (RMFAILED(err)) return err; 	err = read_i2c_data(dcc_info->pRUA, delay, dev, 0x6F, &data[16], 1); if (RMFAILED(err)) return err; 	h_res = (data[0] & 0xFF);	h_res |= ((data[1] & 0x1F) << 8);	v_res = (data[2] & 0xFF);	v_res |= ((data[3] & 0x07) << 8);	de_pix = (data[4] & 0xFF);	de_pix |= ((data[5] & 0x1F) << 8);	de_lin = (data[6] & 0xFF);	de_lin |= ((data[7] & 0x07) << 8);	vid_vtavl = (data[8] & 0x3F);	vid_vfp = (data[9] & 0x3F);	intrl = (data[11] & 0x04) ? TRUE : FALSE;	vspol = (data[11] & 0x02) ? TRUE : FALSE;	hspol = (data[11] & 0x01) ? TRUE : FALSE;	vid_hfp = (data[12] & 0xFF);	vid_hswidth = (data[14] & 0xFF);	vid_hswidth |= ((data[15] & 0x03) << 8);	vid_xpcnt = (data[16] & 0xFF);		if (pixel_rep) {		h_res >>= h_shift;		de_pix >>= h_shift;		vid_hfp >>= h_shift;		vid_hswidth >>= h_shift;		vid_xpcnt >>= h_shift;	}		fprintf(stderr, "SiI9031 - %lux%lu%c, total:%lux%lu, vsync:%lu-%lu-x-%s., hsync:%lu-%lu-%lu-%s., xpcnt:%lu\n", 		de_pix, de_lin * (intrl ? 2 : 1), intrl ? 'i' : 'p', 		h_res, intrl ? v_res * 2 + 1 : v_res, 		vid_vfp, vid_vtavl, vspol ? "pos" : "neg", 		vid_hfp, vid_hswidth, h_res - de_pix - vid_hfp - vid_hswidth, hspol ? "pos" : "neg", 		vid_xpcnt);		if (! update) return RM_OK;		best_match = 0;	i = limit861 ? 0 : 1;	while (limit861 ? (i < (sizeof(cea861c) / sizeof(enum EMhwlibTVStandard))) : RMSUCCEEDED(GetTVStandardName((enum EMhwlibTVStandard)i, &StandardName))) {		struct EMhwlibTVFormatDigital dig;		RMuint32 match;		RMbool dig_Intrl, dig_1001;				// skip dual-aspect-ratio modes, checking for one is enough		if (limit861 && (i > 0) && (cea861c[i - 1] == cea861c[i])) {			i++;			continue;		}		mode = limit861 ? cea861c[i] : (enum EMhwlibTVStandard)i;		err = RUAExchangeProperty(dcc_info->pRUA, DisplayBlock, 			RMDisplayBlockPropertyID_TVFormatDigital, 			&mode, sizeof(mode), 			&dig, sizeof(dig));		if RMFAILED(err) {			fprintf(stderr, "Could not get format!\n");			return err;		}		dig_1001 = (			(dig.PixelClock == 25174825) || 			(dig.PixelClock == 74175824) || 			(dig.PixelClock == 148351648) || 			((				(dig.ActiveHeight == 240) || 				(dig.ActiveHeight == 480)			) && (				(dig.PixelClock == 27000000) || 				(dig.PixelClock == 54000000) || 				(dig.PixelClock == 108000000) 			))		);		// skip X*1000/1001 frame rate modes, capture does not discriminate between those and X*1 modes		if (dig_1001) {			i++;			continue;		}		dig_Intrl = (dig.TopFieldHeight != 0);		if (dig_Intrl) dig.VTotalSize = (dig.VTotalSize + 1) / 2;		/*if (mode == EMhwlibTVStandard_HDMI_1080i60) {	fprintf(stderr, "1080i60 video format: \nh_res = %lu\nv_res = %lu\nde_pix = %lu\nde_lin = %lu\nvid_vtavl = %lu\nvid_vfp = %lu\nvid_hfp = %lu\nvid_hswidth = %lu\nvid_xpcnt = %lu\nintrl = %u\nvspol = %u\nhspol = %u\n", 		dig.HTotalSize, dig.VTotalSize, dig.ActiveWidth, dig.ActiveHeight, dig.YOffsetTop, 		dig.VTotalSize - dig.ActiveHeight - dig.YOffsetTop, 		dig.HTotalSize - dig.ActiveWidth - dig.XOffset, 		dig.HSyncWidth, (RMuint32)(28322000LL * 128LL / dig.PixelClock), dig_Intrl, ! dig.VSyncActiveLow, ! dig.HSyncActiveLow);}*/		match = 0;		match += comp_weight(h_res, dig.HTotalSize, 20);		match += comp_weight(v_res, dig.VTotalSize, 20);		match += comp_weight(de_pix, dig.ActiveWidth, 20);		match += comp_weight(de_lin, dig.ActiveHeight, 20);		//match += comp_weight(vid_vtavl, dig.YOffsetTop, 12);		//match += comp_weight(vid_vfp, dig.VTotalSize - dig.ActiveHeight - dig.YOffsetTop, 12);		//match += comp_weight(vid_hfp, dig.HTotalSize - dig.ActiveWidth - dig.XOffset, 12);		//match += comp_weight(vid_hswidth, dig.HSyncWidth, 12);		match += comp_weight(vid_xpcnt, RM64mult32div32(28322000, 128, dig.PixelClock), 20);		if (intrl == dig_Intrl) match += 32;		if (vspol == ! dig.VSyncActiveLow) match += 20;		if (hspol == ! dig.HSyncActiveLow) match += 20;				if (match > best_match) {			best_match = match;			options->TVStandard = mode;			//GetTVStandardName(mode, &StandardName);			//fprintf(stderr, "%s scores %lu\n", StandardName, match);		}		i++;	}		if (options->TVStandard != old) {		GetTVStandardName(options->TVStandard, &StandardName);		fprintf(stderr, "Detected new mode from timing: %s\n", StandardName);		*update = TRUE;	}		err = read_i2c_data(dcc_info->pRUA, delay, dev + 4, 0x2A, &data[0], 3); if (RMFAILED(err)) return err; 	err = read_i2c_data(dcc_info->pRUA, delay, dev + 4, 0x30, &data[3], 2); if (RMFAILED(err)) return err; 	fprintf(stderr, "SiI9031 audio channel status [39:0]: %02X %02X %02X %02X %02X\n", data[4], data[3], data[2], data[1], data[0]);		return RM_OK;}static RMstatus get_spdif_status(	struct dcc_context *dcc_info, 	struct audio_cmdline *audio_opt){	RMstatus err;	struct AudioEngine_InputSPDIFStatus_type stat;		err = RUAGetProperty(dcc_info->pRUA, 		EMHWLIB_MODULE(AudioEngine, audio_opt->AudioEngineID), 		RMAudioEnginePropertyID_InputSPDIFStatus, 		&stat, sizeof(stat));	if (RMSUCCEEDED(err)) {		fprintf(stderr, "Audio Input channel status [18:0]: 0x%05lX Pc:%04X Pd:%04X Pe:%04X Pf:%04X\n", stat.ChannelStatus, stat.Pc, stat.Pd, stat.Pe, stat.Pf);	}		return err;}// Set up local and capture options (zoom, aspect ratio etc.) based on capture_opt->TVStandardstatic RMstatus setup_format_options(	struct dcc_context *dcc_info, 	struct capture_cmdline *capture_opt, 	struct display_cmdline *disp_opt, 	struct local_cmdline *local_opt, 	RMuint32 input){	struct EMhwlibActiveFormatDescription afd;		afd.ActiveFormat = local_opt->active_format;	afd.ActiveFormatValid = TRUE;	afd.FrameAspectRatio.X = 4;	afd.FrameAspectRatio.Y = 3;		switch (capture_opt->TVStandard) {	case EMhwlibTVStandard_Custom:		fprintf(stderr, "No sync or video detected!\n");		break;	case EMhwlibTVStandard_ITU_Bt656_525:	case EMhwlibTVStandard_ITU_Bt656_240p:		{  // NTSC only part			capture_opt->PixelAspectRatio.X = 8;			capture_opt->PixelAspectRatio.Y = 9;			if (local_opt->parse_anc) {				capture_opt->vbianc_w = 12;				capture_opt->vbianc_h = 3;				capture_opt->vbianc_ytop = 16;				capture_opt->vbianc_ybot = 17;				capture_opt->vbianc_enable = TRUE;				//capture_opt->vbi_dma = FALSE;				fprintf(stderr, "*** NTSC ClosedCaption, setting up capture window w=%lu, h=%lu, ytop=%lu, ybot=%lu ***\n", 					capture_opt->vbianc_w, capture_opt->vbianc_h, capture_opt->vbianc_ytop, capture_opt->vbianc_ybot);			} else {				capture_opt->vbianc_enable = FALSE;			}			// full screen minus top 4 and bottom 3 lines of each frame			if (! local_opt->zoom_force) {				local_opt->zoom_x = 0;				local_opt->zoom_y = 4;  // discard top 2 lines of each field, containing VBI data in ITU656-525 mode				local_opt->zoom_w = 720;				local_opt->zoom_h = 480;  // discard bottom 3 lines of each frame to match standard picture size			}			if (capture_opt->TVStandard == EMhwlibTVStandard_ITU_Bt656_240p) {				capture_opt->PixelAspectRatio.Y *= 2;				if (! local_opt->zoom_force) {					local_opt->zoom_h /= 2;				}			}		}		if (0) 	case EMhwlibTVStandard_ITU_Bt656_625:	case EMhwlibTVStandard_ITU_Bt656_288p:		{  // PAL only part			capture_opt->PixelAspectRatio.X = 16;			capture_opt->PixelAspectRatio.Y = 15;			if (local_opt->parse_anc) {				capture_opt->vbianc_w = 52;				capture_opt->vbianc_h = 18;				capture_opt->vbianc_ytop = 5;				capture_opt->vbianc_ybot = 5;				capture_opt->vbianc_enable = TRUE;				//capture_opt->vbi_dma = TRUE;				fprintf(stderr, "*** PAL TeleText, setting up capture window w=%lu, h=%lu, ytop=%lu, ybot=%lu ***\n", 					capture_opt->vbianc_w, capture_opt->vbianc_h, capture_opt->vbianc_ytop, capture_opt->vbianc_ybot);			} else {				capture_opt->vbianc_enable = FALSE;			}			// full screen capture			if (! local_opt->zoom_force) {				local_opt->zoom_x = 0;				local_opt->zoom_y = 0;				local_opt->zoom_w = 720;				local_opt->zoom_h = 576;			}			if (capture_opt->TVStandard == EMhwlibTVStandard_ITU_Bt656_288p) {				capture_opt->PixelAspectRatio.Y *= 2;				if (! local_opt->zoom_force) {					local_opt->zoom_h /= 2;				}			}		}				{  // PAL/NTSC common part			// disable picture aspect ratio, using pixel aspect ratio			capture_opt->PictureAspectRatio.X  = 0;			capture_opt->PictureAspectRatio.Y  = 0;						// Set up wide and clipping mode			if (local_opt->wide_screen) {  // 16:9 output				capture_opt->PixelAspectRatio.X *= 4;				capture_opt->PixelAspectRatio.Y *= 3;				afd.FrameAspectRatio.X *= 4;				afd.FrameAspectRatio.Y *= 3;			}			if (! local_opt->zoom_force) {				RMstatus err;				struct EMhwlibAspectRatio scaler_ar;				RMbool output_variable_ar, variable_output;				struct EMhwlibActiveFormatDescription output_afd;				RMuint32 w = local_opt->zoom_w, h = local_opt->zoom_h, adj;								err = get_scaler_output_aspect_ra

⌨️ 快捷键说明

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