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

📄 ppf_watermark.c

📁 Sigma SMP8634 Mrua v. 2.8.2.0
💻 C
📖 第 1 页 / 共 2 页
字号:
		RMDBGLOG((ENABLE, "Invalid param address!\n"));		return RM_ERROR;	}	/* 	   Most ppf modules will need to handle play/stop	   commands. We did not add a generic function for	   this because in the near future the aim is to pass	   those commands via the input surfaces.	   So temporarily this is implemented here as a custom	   command of each ppf module.	*/	cmd = *(enum ppf_watermark_cmd *)command_param;	switch(cmd){	case ppf_watermark_cmd_play:		context.state = ppf_watermark_state_play;		break;	case ppf_watermark_cmd_stop:		context.state = ppf_watermark_state_stop;		break;	}	return RM_OK;}/*  Video pictures are relased when the associated carbon pictures  are released by the display.  We cannot release them before because the carbon pictures use  the video pictures' chroma buffers.*/static void free_video_pictures(){	RMuint32 i;	RMuint32 released = 0;	for(i = 0; i < CARBON_PICTURE_COUNT; i++){		struct EMhwlibNewPicture *pic = (struct EMhwlibNewPicture*)context.carbon_pictures[i];		if((context.carbon_pictures_parent[i] != 0) &&		   (gbus_read_uint32(PGBUS, (RMuint32) & (pic->picture_display_status)) == 0)){			struct EMhwlibNewPicture *parent_pic = (struct EMhwlibNewPicture*)context.carbon_pictures_parent[i];			gbus_write_uint32(PGBUS, (RMuint32) & (parent_pic->picture_display_status), 0);			context.carbon_pictures_parent[i] = 0;			released++;		}/* else *//* 			RMDBGLOG((ENABLE, "no because %ld and %ld\n", (context.carbon_pictures_parent[i] != 0),(gbus_read_uint32(PGBUS, (RMuint32) & (pic->picture_display_status)) == 0) )); */	}	}/*    Returns the index of an available carbon picture.   If the return value is CARBON_PICTURE_COUNT, it   means that no pictures are available*/static RMuint32 get_carbon_picture(){	RMuint32 i;	for(i = 0; i < CARBON_PICTURE_COUNT; i++){		struct EMhwlibNewPicture *pic = (struct EMhwlibNewPicture*)context.carbon_pictures[i];				if((context.carbon_pictures_parent[i] == 0) &&		   (gbus_read_uint32(PGBUS, (RMuint32) & (pic->picture_display_status)) == 0)){			break;		}	}	return i;}static void copy_luma(struct EMhwlibNewPicture *src_pic, struct EMhwlibNewPicture *dst_pic){	struct GFXEngine_Surface_type surface_param;	struct GFXEngine_ColorFormat_type format_param;	struct GFXEngine_MoveReplaceRectangle_type move_param;	format_param.MainMode = EMhwlibColorMode_LUT_8BPP;	format_param.SubMode = EMhwlibColorFormat_32BPP;			surface_param.StartAddress = dst_pic->luma_address;	surface_param.TotalWidth = dst_pic->luma_total_width;	surface_param.Tiled = TRUE;	surface_param.SurfaceID = GFX_SURFACE_ID_NX;	format_param.SurfaceID = GFX_SURFACE_ID_NX;	SEND_GFX_COMMAND(RMGFXEnginePropertyID_Surface, &surface_param, sizeof(surface_param));	SEND_GFX_COMMAND(RMGFXEnginePropertyID_ColorFormat, &format_param, sizeof(format_param));	surface_param.StartAddress = src_pic->luma_address;	surface_param.TotalWidth = src_pic->luma_total_width;	surface_param.Tiled = TRUE;	surface_param.SurfaceID = GFX_SURFACE_ID_Y;	format_param.SurfaceID = GFX_SURFACE_ID_Y;	SEND_GFX_COMMAND(RMGFXEnginePropertyID_Surface, &surface_param, sizeof(surface_param));	SEND_GFX_COMMAND(RMGFXEnginePropertyID_ColorFormat, &format_param, sizeof(format_param));	move_param.SrcX = 0;	move_param.SrcY = 0;	move_param.Width = src_pic->luma_position_in_buffer.width;	move_param.Height = src_pic->luma_position_in_buffer.height;	move_param.Width = RMmin(src_pic->luma_position_in_buffer.width, CARBON_MAX_PIC_WIDTH);	move_param.Height = RMmin(src_pic->luma_position_in_buffer.height, CARBON_MAX_PIC_HEIGHT);	move_param.DstX = 0;	move_param.DstY = 0;	move_param.AlphaX = 0;	move_param.AlphaY = 0;	move_param.Merge = FALSE;	SEND_GFX_COMMAND(RMGFXEnginePropertyID_MoveRectangle, &move_param, sizeof(move_param));}/*    1) Get one picture from the video surface   2) Create a picture using a copy of the video picture's luma buffer and the original chroma buffers.   3) Insert that picture into the carbon_output surface*/static RMstatus video_to_carbon(void){	struct GFXEngine_DisplayPicture_type display_pic;	struct EMhwlibPictureInfo video_pic;	struct EMhwlibNewPicture carbon_pic;	RMuint32 carbon_pic_id;	RMstatus err;	err = EMhwlibExchangeProperty((struct EMhwlib *)pEm, DisplayBlock,				      RMDisplayBlockPropertyID_PeekNextPicture,				      &(context.input), sizeof(context.input),				      &video_pic, sizeof(video_pic));	if((err == RM_OK) && video_pic.PictureAddress){		carbon_pic_id = get_carbon_picture();		if(carbon_pic_id < CARBON_PICTURE_COUNT){			carbon_pic = video_pic.Picture;			carbon_pic.luma_address = context.carbon_buffers[carbon_pic_id];			carbon_pic.picture_display_status = 1;			gbus_write_data32(PGBUS, context.carbon_pictures[carbon_pic_id], (RMuint32*)&carbon_pic, sizeof(struct EMhwlibNewPicture)/sizeof(RMuint32));			copy_luma(&video_pic.Picture, &carbon_pic);			context.carbon_pictures_parent[carbon_pic_id] = video_pic.PictureAddress;			display_pic.Surface = context.carbon_output;			display_pic.Picture = context.carbon_pictures[carbon_pic_id];			display_pic.Pts = (RMuint64)video_pic.Picture.first_pts_lo | ((RMuint64) video_pic.Picture.first_pts_hi)<<32;			SEND_GFX_COMMAND(RMGFXEnginePropertyID_DisplayPicture, &display_pic, sizeof(display_pic));			context.input.emhwlibReserved = video_pic.PictureAddress;			err = EMhwlibSetProperty((struct EMhwlib *)pEm, DisplayBlock, RMDisplayBlockPropertyID_AcquirePicture,						 &(context.input), sizeof(context.input));								}		else{			RMDBGLOG((ENABLE, "cant get a carbon picture\n"));			return RM_PENDING;		}	}else{		return RM_PENDING;	}	return RM_OK;}static void watermark_picture(struct EMhwlibNewPicture *Picture){	RMuint32 x,y,x0,y0,w,h;	RMDBGLOG((DISABLE, "luma:%p, luma_width:%08x, frame:%08x, win: %08x:%08x-%08x*%08x\n", 		Picture->luma_address, Picture->luma_total_width, Picture->frame_count,		Picture->luma_position_in_buffer.x, Picture->luma_position_in_buffer.y,		Picture->luma_position_in_buffer.width, Picture->luma_position_in_buffer.height));	w = 256;	h = 128;	x0 = 8;	y0 = 8;	for(y = y0; y < y0+h; y++) {		for(x=x0; x<x0+w; x++) {			RMuint32 addr, luma;			addr = Picture->luma_address + 128*y + x;			addr=Picture->luma_address + (x/128)*4096+(y/32)*Picture->luma_total_width*32+(x%128)+((y%32)*128);			luma = gbus_read_uint8(PGBUS, addr);			luma = (luma < 128) ? ((luma < 64) ? 32 : 96) : ((luma < 192) ? 160: 224);			gbus_write_uint8(PGBUS, addr, luma);		}	}}/*    1) Get one picture from the carbon surface   2) Modify its luma (watermark it)   3) Insert that picture into the marked_output surface*/static RMstatus carbon_to_marked(){	struct EMhwlibPictureInfo carbon_pic_info;	struct EMhwlibSurfaceReader carbon_surface_reader;	struct DisplayBlock_InsertPictureInSurfaceFifo_type insert_pic;	RMstatus err;	carbon_surface_reader.ReaderID = 0;	carbon_surface_reader.SurfaceAddress = context.carbon_output;			err = EMhwlibExchangeProperty((struct EMhwlib *)pEm, DisplayBlock,				      RMDisplayBlockPropertyID_PeekNextPicture,				      &(carbon_surface_reader), sizeof(carbon_surface_reader),				      &carbon_pic_info, sizeof(carbon_pic_info));					if((err == RM_OK) && carbon_pic_info.PictureAddress){		insert_pic.Surface = context.marked_output;		insert_pic.Picture = carbon_pic_info.PictureAddress;		watermark_picture(&carbon_pic_info.Picture);				err = EMhwlibSetProperty((struct EMhwlib *)pEm, DisplayBlock, RMDisplayBlockPropertyID_InsertPictureInSurfaceFifo,					 &insert_pic, sizeof(insert_pic));		if(err == RM_OK){						carbon_surface_reader.emhwlibReserved = carbon_pic_info.PictureAddress;			err = EMhwlibSetProperty((struct EMhwlib *)pEm, DisplayBlock, RMDisplayBlockPropertyID_AcquirePicture,						 &(carbon_surface_reader), sizeof(carbon_surface_reader));		}		else{			RMDBGLOG((ENABLE, "cannot insert yet, try again later\n"));			return RM_PENDING;		}							}else{		return RM_PENDING;	}	return RM_OK;		}RMstatus watermark_run_filter(RMuint32 data){	RMstatus err;	RMuint32 vtc = 0;	if(context.input.SurfaceAddress == 0){		RMDBGLOG((PPFDBG, "Not doing anything because no input\n"));		goto done;	}	if((context.carbon_output == 0) || (context.marked_output == 0)){		RMDBGLOG((PPFDBG, "Not doing anything because no output\n"));		goto done;	}	if(context.state == ppf_watermark_state_stop){		RMDBGLOG((PPFDBG, "Not doing anything because on stop mode\n"));		goto done;	}	free_video_pictures();	do{		err = video_to_carbon();		vtc++;	}while(err == RM_OK);	vtc = 0;	do{		err = carbon_to_marked();		vtc++;	}while(err == RM_OK);		 done:	{		/* hack, this function should get the actual mask that triggered its calling and clear it */				RMuint32 mask = EMHWLIB_DISPLAY_EVENT_ID(DispMainAnalogOut);		err = EMhwlibSetProperty((struct EMhwlib *)pEm, DisplayBlock, RMGenericPropertyID_ClearEventMask,					 &(mask), sizeof(mask));			}		return RM_OK;}static RMstatus watermark_init(void){	struct PPFHandle handle = {NULL,}; /* for forward portability */	RMuint32 i;	RMstatus err;	krua_get_pointers(chip_id, &pE, &pEm);	context.input.SurfaceAddress = 0;	context.carbon_output = 0;	context.gfx_task = 0;	context.state = ppf_watermark_state_stop;	context.on_display_pics = 0;	for(i = 0; i < CARBON_PICTURE_COUNT; i++){		context.carbon_pictures_parent[i] = 0;		context.carbon_pictures[i] = 0;		context.carbon_buffers[i] = 0;	}	handle.get_engine_mem = watermark_get_engine_mem;	handle.set_engine_mem = watermark_set_engine_mem;	handle.get_output_mem = watermark_get_output_mem;	handle.set_output_mem = watermark_set_output_mem;	handle.get_output = watermark_get_output;	handle.set_input = watermark_set_input;	handle.set_command = watermark_set_command;	RMDBGLOG((ENABLE, "calling register filter\n"));	PPFDockRegisterFilter(0, &handle);	/* 	   Here we register the watermark_run_filter as a callback function 	   for event EMHWLIB_DISPLAY_EVENT_ID(DispMainAnalogOut).	   It's possible to register multiple functions to multiple events	   or the same function to multiple events.	   The fifth paramater will be passed to the callback function every	   time it is called.	*/	   	RMDBGLOG((ENABLE, "alive so far\n"));	err = krua_register_event_callback_as_tasklet((void*)pE, DisplayBlock, EMHWLIB_DISPLAY_EVENT_ID(DispMainAnalogOut), watermark_run_filter, 0, &tasklet_id);	if (RMFAILED(err)){		RMDBGLOG((ENABLE, "FAILED to register tasklet\n"));		return err;	}	RMDBGLOG((ENABLE, "alive so far\n"));	return RM_OK;}static RMstatus watermark_deinit(void){	RMstatus err;	RMDBGLOG((ENABLE, "at watermakr deinit now\n"));	err = krua_unregister_event_callback_as_tasklet((void*)pE, tasklet_id);	if (RMFAILED(err)){		RMDBGLOG((ENABLE, "FAILED to unregister callback\n"));		return err;	}	return RM_OK;}int init_module(void){  	watermark_init();	return 0;}void cleanup_module(void){	watermark_deinit();}

⌨️ 快捷键说明

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