ppf_watermark.c
来自「SigmDesign SMP8634 media decode chip dev」· C语言 代码 · 共 772 行 · 第 1/2 页
C
772 行
gbus_read_uint32(PGBUS, (RMuint32)&s->tiled) )); } return RM_OK;}RMstatus watermark_set_command(void *command_param, RMuint32 param_size, void *command_result, RMuint32 result_size){ enum ppf_watermark_cmd cmd; RMDBGLOG((ENABLE, "at command param\n")); if(param_size != sizeof(enum ppf_watermark_cmd)){ RMDBGLOG((ENABLE, "Invalid param size!\n")); return RM_ERROR; } if(command_param == NULL){ 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 dummy){ 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;}RMstatus watermark_init(void){ struct PPFHandle handle = {NULL,}; /* for forward portability */ RMuint32 i; 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); /* this should probably not be done here but let's wait until we cleanup the regiset_event_callback mechanism */ krua_register_event_callback((void*)pE, DisplayBlock, EMHWLIB_DISPLAY_EVENT_ID(DispMainAnalogOut), ppf_schedule_filter); return RM_OK;}RMstatus watermark_deinit(void){ /* register within the emhwlib */ krua_unregister_event_callback((void*)pE, DisplayBlock, ppf_schedule_filter); return RM_OK;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?