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

📄 spu.c

📁 1. 8623L平台
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <stdio.h>#include <stdlib.h>#include <string.h>#define ALLOW_OS_CODE 1#include <sys/types.h>#include "../samples/common.h"#include "../samples/command_ids.h"#include "rmlocalremote.h"#include "../rmremoteapi/include/rmremoteapi.h"#include "../rmrtk/include/rmrtk.h"/* #### Begin CARDEA code #### */#include "rmupnp/rmlibwmdrmnd/include/ms_cardea.h"/* #### End CARDEA code #### */#include "mono.h"/* proof of concept, the implementation of subtitles may change */#define MAX_COLS 30#define MAX_ROWS 3#define SUBTITLEDBG DISABLEvoid clear_subtitles(void);void show_subtitles(RMuint8 *string);RMstatus init_subtitle_engine(void);RMstatus insert_string_into_subtitle_buffer(RMuint8 *string);void clear_subtitle_buffer(void);extern struct dcc_context dcc_info;extern struct mono_context mono_opt;extern RMbool osd_enabled;RMbool popWordfromString(RMuint8 *string, RMuint32 sLen, RMuint8 *word, RMuint32 *index);void pushWordintoString(RMuint8 **string, RMuint8 *word);struct subtitles_context{	RMuint32 maxCharsPerRow;	RtkPoint cursor;  	RtkPoint top_left;	RtkRect char_size; 	RtkRect active_area;	RtkProp text_props;	RMuint8 text_buffer[MAX_ROWS][MAX_COLS];	RMuint32 lastValidRowIndex;	RMbool subtitles_initialised;	RMbool disable_subtitles;	RtkRect last_rect;};static struct subtitles_context subTContext = {0,}; /* in order for this init to work, the first element of the 						       structure shall not be another structure, but a RMuint32						       for example (otherwise gcc complains) *//* this is the Subtitle callback */void RMSubtitleCallback(RMuint8 *string, RMuint64 pts, RMbool usePTS){	if (subTContext.disable_subtitles)		return;	if (!osd_enabled) {		osd_enabled = TRUE;		if (mono_opt.osd_source) {#if 0			RMstatus err;			err = DCCSetSurfaceSource(dcc_info.pDCC, mono_opt.osd_scaler, mono_opt.osd_source);			if (RMFAILED(err)) {				RMDBGLOG((ENABLE, "Cannot set the surface source %d\n", err));				return;			}#else			DCCEnableVideoSource(mono_opt.osd_source, TRUE);#endif		}		else {			subTContext.disable_subtitles = TRUE;			return;		}	}	if (!subTContext.subtitles_initialised) {		RMstatus status;		status = init_subtitle_engine();		if (status != RM_OK) {			subTContext.disable_subtitles = TRUE;			return;		}		subTContext.subtitles_initialised = TRUE;				}	if (!usePTS) {                          // for now, only this case is treated		if (strlen((const char *)string) == 0)			clear_subtitles();		else			show_subtitles(string);	} 	return;}void clear_subtitles(void){	RMFRTKClearScreen(mono_opt.rtk);	clear_subtitle_buffer();	RMDBGLOG((SUBTITLEDBG, ">> clear subtitles\n"));	return;}void show_subtitles(RMuint8 *string){	RMuint32 i;	insert_string_into_subtitle_buffer(string);	for (i = 0; i <= subTContext.lastValidRowIndex; i++) {		RtkPoint cursor;		RMuint32 y;		y = subTContext.top_left.y + ((MAX_ROWS - 1 - subTContext.lastValidRowIndex) * subTContext.char_size.height);		cursor.x = subTContext.top_left.x;		cursor.y = y + (i * subTContext.char_size.height);		RMFRTKDrawString(mono_opt.rtk, (RMascii *)subTContext.text_buffer[i], &cursor, &(subTContext.text_props), &(subTContext.last_rect));	}	RMDBGLOG((SUBTITLEDBG, ">>> show: '%s'\n", string));	return;}RMstatus init_subtitle_engine(void){	if (!mono_opt.rtk)		return RM_ERROR;	subTContext.active_area.x = 0;	subTContext.active_area.y = 0;	RMFRTKGetOsdDimension(mono_opt.rtk, &(subTContext.active_area.width), &(subTContext.active_area.height), NULL);	RMFRTKClearScreen(mono_opt.rtk);	{		// reload font, use a monospaced font for subtitles		RMnonAscii *naname = RMnonAsciiFromAscii("VeraMono.ttf");		RMFRTKLoadFontFile( mono_opt.rtk, naname);		RMFreeNonAscii(naname);	}	subTContext.text_props.fgColor = 0xffffffff;	subTContext.text_props.bgColor = 0x80000000;	subTContext.text_props.scale = subTContext.active_area.width / 30;           // ??	RMFRTKGetCharSize(mono_opt.rtk, 'M', &(subTContext.text_props), &(subTContext.char_size));	if((subTContext.active_area.width < MAX_COLS * subTContext.char_size.width) ||	   (subTContext.active_area.height < MAX_ROWS * subTContext.char_size.height)) {		RMDBGLOG((ENABLE, "decrease the size of the font or the number of chars\n"			  "\tarea(%lu x %lu), char(%lu x %lu), textarea(%lu x %lu)\n",			  subTContext.active_area.width,			  subTContext.active_area.height,			  subTContext.char_size.width,			  subTContext.char_size.height,			  MAX_COLS,			  MAX_ROWS));		return RM_ERROR;	}	subTContext.top_left.x = (subTContext.active_area.width - MAX_COLS * subTContext.char_size.width) / 2;	subTContext.top_left.y = ((subTContext.active_area.height * 0.8) - (MAX_ROWS - 1) * subTContext.char_size.height);	subTContext.maxCharsPerRow = subTContext.active_area.width / subTContext.char_size.width;	RMDBGLOG((ENABLE, "\t>>> OSDArea(%lu x %lu), charArea(%lu x %lu), textArea(%lu x %lu), maxChars %lu, topleft(%lu, %lu)\n",		  subTContext.active_area.width,		  subTContext.active_area.height,		  subTContext.char_size.width,		  subTContext.char_size.height,		  MAX_COLS,		  MAX_ROWS,		  subTContext.maxCharsPerRow,		  subTContext.top_left.x,		  subTContext.top_left.y));	return RM_OK;}RMstatus insert_string_into_subtitle_buffer(RMuint8 *string){	RMuint32 sLen = strlen((const char *)string);	RMuint32 i = 0, j = 0;	RMuint8 word[32];	RMuint32 partialLen;	RMuint32 wLen;	RMuint8 *buffer;	RMbool lastWord = FALSE;	while (1) {		lastWord = popWordfromString(string, sLen, word, &i);		i++;		partialLen = strlen((const char *)subTContext.text_buffer[j]);		wLen = strlen((const char *)word);		if (partialLen + wLen + 1 > (MAX_COLS-1))			j++;		buffer = subTContext.text_buffer[j];		pushWordintoString(&buffer, word);		if ((lastWord) || (j > MAX_ROWS))			break;	}	for(i = 0; i <= j; i++)		RMDBGLOG((SUBTITLEDBG, "*********** '%s'\n", subTContext.text_buffer[i]));	subTContext.lastValidRowIndex = j;	return RM_OK;}void clear_subtitle_buffer(void){	RMuint32 i, j;	for (i = 0; i < MAX_ROWS; i++)		for (j = 0; j < MAX_COLS; j++)			subTContext.text_buffer[i][j] = '\0';	return;}RMbool popWordfromString(RMuint8 *string, RMuint32 sLen, RMuint8 *word, RMuint32 *index){	RMuint32 i = *index, j = 0;	RMuint32 wLen;	RMbool wordEnd = FALSE;	while (1) {		word[j] = string[i+j];		j++;		if (string[i+j] == ' ') {			wordEnd = TRUE;			break;		}		if (i+j > sLen)			break;	};	word[j] = '\0';		wLen = strlen((const char *)word);	*index = i + wLen;		RMDBGLOG((SUBTITLEDBG, "pop: word '%s' from string '%s', slen %lu, wlen %lu, new string '%s'\n",		  word,		  string,		  sLen,		  wLen,		  (string + *index)));	if (wordEnd)		return FALSE;	return TRUE;}void pushWordintoString(RMuint8 **string, RMuint8 *word){	RMuint32 sLen = strlen((const char *)*string);	RMuint32 wLen = strlen((const char *)word);	RMuint32 i = 0;	RMuint8 *buffer = *string;	if (sLen != 0) {		buffer[sLen] = ' ';		sLen++;	}	for (i = 0; i < wLen; i++)		buffer[i+sLen] = word[i];	buffer[i+sLen] = '\0';	*string = *string + wLen;	RMDBGLOG((SUBTITLEDBG, "push: word '%s', new string '%s', slen %lu, wlen %lu\n",		  word,		  buffer,		  sLen,		  wLen));	return;}/* END subtitle implementation *//* begin SPU implementation */RMstatus RMInitDoubleBufferOSD(RMuint32 *moduleID, struct DCCOSDProfile osdProfile, struct OSDdoubleBuffer *doubleBuffer){	enum EMhwlibMixerSourceState state;	RMuint32 mixer, scaler, src_index, mixer_src;	struct EMhwlibDisplayWindow window;	RMuint32 val;	RMuint32 pic_luma_addr[2], pic_addr[2], pic_luma_size[2], surface_addr;			RMuint8 *buf_map;	RMuint32 buf_addr, buf_size;	RMstatus err;	RMDBGLOG((ENABLE, "init doubleBuffer OSD, size %lu x %lu\n", osdProfile.Width, osdProfile.Height));	mixer = EMHWLIB_MODULE(DispMainMixer, 0);	scaler = EMHWLIB_MODULE(DispGFXMultiScaler,0);	/* set a NULL surface, this will force a full register update when next surface is set */	err = DCCSetSurfaceSource(dcc_info.pDCC, scaler, NULL);	if (RMFAILED(err)) {		fprintf(stderr, "Cannot unset gfx scaler's surface\n");		return err;	}	err = RUAExchangeProperty(dcc_info.pRUA, mixer, RMGenericPropertyID_MixerSourceIndex, &scaler, sizeof(scaler), &src_index, sizeof(src_index));	if (RMFAILED(err)) {		RMDBGLOG((ENABLE, "Cannot get scaler index\n"));		return err;	}	mixer_src = EMHWLIB_TARGET_MODULE(mixer, 0 , src_index);	state = EMhwlibMixerSourceState_Master;	window.X = 0;	window.Y = 0;	window.Width = 4096;	window.Height = 4096;	window.XPositionMode = EMhwlibDisplayWindowPositionMode_FrontEdgeToBorder;	window.YPositionMode = EMhwlibDisplayWindowPositionMode_FrontEdgeToBorder;	window.XMode = EMhwlibDisplayWindowValueMode_Relative;	window.YMode = EMhwlibDisplayWindowValueMode_Relative;	window.WidthMode = EMhwlibDisplayWindowValueMode_Relative;	window.HeightMode = EMhwlibDisplayWindowValueMode_Relative;	RUASetProperty(dcc_info.pRUA, mixer_src, RMGenericPropertyID_MixerSourceWindow, &window, sizeof(window), 0);			window.X = 0;	window.Y = 0;	window.Width = 4096;	window.Height = 4096;	window.XPositionMode = EMhwlibDisplayWindowPositionMode_FrontEdgeToBorder;	window.YPositionMode = EMhwlibDisplayWindowPositionMode_FrontEdgeToBorder;	window.XMode = EMhwlibDisplayWindowValueMode_Relative;	window.YMode = EMhwlibDisplayWindowValueMode_Relative;	window.WidthMode = EMhwlibDisplayWindowValueMode_Relative;	window.HeightMode = EMhwlibDisplayWindowValueMode_Relative;	RUASetProperty(dcc_info.pRUA, scaler, RMGenericPropertyID_ScalerInputWindow, &window, sizeof(window), 0);	while((err =  RUASetProperty(dcc_info.pRUA, mixer_src, RMGenericPropertyID_MixerSourceState, &state, sizeof(state), 0))==RM_PENDING);	if (RMFAILED(err)) {		RMDBGLOG((ENABLE, "Cannot set scaler's state on mixer\n"));		return err;	}	while ((err = RUASetProperty(dcc_info.pRUA, mixer, RMGenericPropertyID_Validate, NULL, 0, 0)) == RM_PENDING);	if (RMFAILED(err)) {		fprintf(stderr, "Cannot validate mixer\n");		return err;	}	while ((err = RUASetProperty(dcc_info.pRUA, scaler, RMGenericPropertyID_Validate, NULL, 0, 0)) == RM_PENDING);	if (RMFAILED(err)) {		fprintf(stderr, "Cannot validate mixer\n");		return err;	}		

⌨️ 快捷键说明

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