📄 osdlib.c
字号:
RMuint32 get_osd_color_mode(RMascii *m_osd_color_mode_string, RMuint32 *osd_color_mode){ RMuint32 i; for (i=1;i<=EMhwlibColorMode_TrueColorWithKey;i++) if (strcmp(m_osd_color_mode_string,osd_color_mode_string[i].name) == 0){ *osd_color_mode=i; return 1; //found } return 0; //not found}RMuint32 get_osd_csc(RMascii *m_csc_string, RMuint32 *osd_csc_index){ RMuint32 i; for (i=1;i<=EMhwlibColorSpace_YUV_709;i++) if (strcmp(m_csc_string,osd_csc[i].name) == 0){ *osd_csc_index=i; return 1; //found } return 0; //not found}RMuint32 get_osd_color_format(RMascii *m_osd_color_format_string, RMuint32 *osd_color_format){ RMuint32 i; for (i=0;i<=EMhwlibColorFormat_16BPP_4444;i++) if (strcmp(m_osd_color_format_string,osd_color_format_string[i].name) == 0){ *osd_color_format=i; return 1; //found } return 0; //not found}#if 1/** Set palette entry for OSD to 0xaarrggbb * @param p_osd - osd descriptor, should be initialized * @param i - palette entry index * @param r,g,b * @param alpha * @return RM_OK upon success */RMstatus set_osdbuf_palette(struct osd_descriptor *p_osd, RMuint32 i, RMascii r, RMascii g, RMascii b, RMascii alpha){ RMstatus status; struct ScalerLUT p_lut; RMuint32 PropertyID = RMGenericPropertyID_8BPP_LUT; switch(p_osd->profile.ColorMode) { case EMhwlibColorMode_LUT_1BPP: PropertyID = RMGenericPropertyID_1BPP_LUT; p_lut.Size = 2; break; case EMhwlibColorMode_LUT_2BPP: PropertyID = RMGenericPropertyID_2BPP_LUT; p_lut.Size = 4; break; case EMhwlibColorMode_LUT_4BPP: PropertyID = RMGenericPropertyID_4BPP_LUT; p_lut.Size = 16; break; case EMhwlibColorMode_LUT_8BPP: PropertyID = RMGenericPropertyID_8BPP_LUT; p_lut.Size = 256; break; default: DEB(fprintf(stderr,"I don't know wha to do here ...\n")); break; } RUAGP(p_osd->dcc_info.pRUA, p_osd->dcc_info.disp_info->osd_scaler[0], PropertyID, &p_lut.Data, sizeof(p_lut.Data)); if ( i < p_lut.Size ) { p_lut.Data[i] = 0; if (p_osd->profile.ColorFormat <= EMhwlibColorFormat_32BPP) { RMinsShiftBits(&(p_lut.Data[i]), alpha, 8, 24); RMinsShiftBits(&(p_lut.Data[i]), r, 8, 16); RMinsShiftBits(&(p_lut.Data[i]), g, 8, 8); RMinsShiftBits(&(p_lut.Data[i]), b, 8, 0); } else { switch(p_osd->profile.ColorFormat) { case EMhwlibColorFormat_16BPP_565: RMinsShiftBits(&(p_lut.Data[i]), r, 5, 11); RMinsShiftBits(&(p_lut.Data[i]), g, 6, 5); RMinsShiftBits(&(p_lut.Data[i]), b, 5, 0); break; case EMhwlibColorFormat_16BPP_1555: RMinsShiftBits(&(p_lut.Data[i]), alpha, 1, 15); RMinsShiftBits(&(p_lut.Data[i]), r, 5, 10); RMinsShiftBits(&(p_lut.Data[i]), g, 5, 5); RMinsShiftBits(&(p_lut.Data[i]), b, 5, 0); break; case EMhwlibColorFormat_16BPP_4444: RMinsShiftBits(&(p_lut.Data[i]), alpha, 4, 12); RMinsShiftBits(&(p_lut.Data[i]), r, 4, 8); RMinsShiftBits(&(p_lut.Data[i]), g, 4, 4); RMinsShiftBits(&(p_lut.Data[i]), b, 4, 0); break; default: fprintf(stderr,"Error setting LUT : unknown submode : %ld\n", (long int)p_osd->profile.ColorFormat); break; } } DEB(fprintf(stderr,"LUT %ld = 0x%08lx\n",i,p_lut.Data[i])); } RMuint32ToLeBuf(p_lut.Data[i], (RMuint8 *) &(p_lut.Data[i])); RUASP(p_osd->dcc_info.pRUA, p_osd->dcc_info.disp_info->osd_scaler[0], PropertyID, &p_lut.Data, sizeof(p_lut.Data)); RUASP(p_osd->dcc_info.pRUA, p_osd->dcc_info.disp_info->osd_scaler[0], RMGenericPropertyID_Validate, NULL, 0); return RM_OK;}#endif/** Clear a non mapped OSD buffer * @param p_osd - osd descriptor * @return RMstatus, RM_OK upon success */#if 1RMstatus clear_osdbuf(struct osd_descriptor *p_osd){ if(p_osd == NULL) return RM_ERROR; return DCCClearOSDVideoSource(p_osd->dcc_info.pOSDSource[0]);}#endif/** Set a pixel on the OSD * @param p_osd - osd descriptor, should be initialized (at least widht, height, bpp) * @param base_addr - user space addr where osd buffer is mapped * @param x,y - pixel position * @param data - data to write (lut index if lut mode, pixel data otherwise) */#if 1void osdbuf_set_pixel(struct osd_descriptor *p_osd, RMuint8 *base_addr, RMuint32 x, RMuint32 y, RMuint32 data){ RMuint32 width = 0, height = 0; if ( p_osd == NULL || p_osd->bpp == 0 || p_osd->profile.Width == 0 || p_osd->profile.Height == 0 ) return; width = p_osd->profile.Width; height = p_osd->profile.Height; if ( x >= width || y >= height ) return; //We keep only the lower part of data, user has to take care of the mode he is using; switch (p_osd->bpp){ case 32: { RMuint32 *addr= (RMuint32 *)base_addr+(y*width+x); RMuint32ToLeBuf(data, (RMuint8 *) addr); } break; case 24: { RMuint32 *addr= (RMuint32 *)base_addr+(y*width+x); RMuint32ToLeBuf((0x00FFFFFF) & data, (RMuint8 *) addr); } break; case 16: { RMuint16 *addr = (RMuint16 *) base_addr+(y*width+x); RMuint16ToLeBuf((RMuint16) data, (RMuint8 *) addr); } break; case 8: { RMuint8 *addr = (RMuint8 *)base_addr+(y*width+x); *addr = (RMuint8) data; } break; case 4: { RMuint8 *addr = (RMuint8 *)base_addr+(y*width+x) / 2; RMuint32 bit = (RMuint32) ((RMuint8 *)base_addr+(y*width+x) % 2); RMuint8 pixel = *addr; pixel = pixel & ( 0x0F << bit * 4 ); data = ( data & 0x0000000F ) << 4; *addr = pixel | ( (RMuint8) data >> bit * 4 ); } break; case 2: { RMuint8 *addr = (RMuint8 *)base_addr+(y*width+x) / 4; RMuint32 bit = (RMuint32) ((RMuint8 *)base_addr+(y*width+x) % 4); RMuint8 pixel = *addr; pixel = pixel & ( 0xFF ^ ( 0x3 << bit * 2)); data = data & 0x00000003; *addr = pixel | ( (RMuint8) data << bit * 2 ); } break; case 1: { RMuint8 *addr = (RMuint8 *)base_addr+(y*width+x) / 8; RMuint32 bit = (RMuint32) ((RMuint8 *)base_addr+(y*width+x) % 8); RMuint8 pixel = *addr; pixel = pixel & ( 0xFF ^ ( 0x1 << bit )); data = data & 0x00000001; *addr = pixel | ( (RMuint8) data << bit ); } break; default: fprintf(stderr,"Unknown bpp : %ld\n",p_osd->bpp); break; }}#endif/** Get a pixel on the OSD * @param p_osd - osd descriptor, should be initialized (at least widht, height, bpp) * @param base_addr - user space addr where osd buffer is mapped * @param x,y - pixel position * @return RMuint32 - pixel value */#if 1RMuint32 osdbuf_get_pixel(struct osd_descriptor *p_osd, RMuint8 *base_addr, RMuint32 x, RMuint32 y){ RMuint32 width = 0, height = 0; if ( p_osd == NULL || p_osd->bpp == 0 || p_osd->profile.Width == 0 || p_osd->profile.Height == 0 ) return 0; width = p_osd->profile.Width; height = p_osd->profile.Height; if ( x >= width || y >= height ) return 0; switch (p_osd->bpp){ case 32: { RMuint32 *addr= (RMuint32 *)base_addr+(y*width+x); return (*addr); } break; case 24: { RMuint32 *addr= (RMuint32 *)base_addr+(y*width+x); return (*addr); } break; case 16: { RMuint16 *addr = (RMuint16 *) base_addr+(y*width+x); return (RMuint32)(*addr); } break; case 8: { RMuint8 *addr = (RMuint8 *)base_addr+(y*width+x); return (RMuint32)(*addr); } break; case 4: { RMuint8 *addr = (RMuint8 *)base_addr+(y*width+x) / 2; RMuint32 bit = (RMuint32) ((RMuint8 *)base_addr+(y*width+x) % 2); RMuint8 pixel = *addr; pixel = pixel & ( 0x0F << bit * 4 ); return (RMuint32) pixel; } break; case 2: { RMuint8 *addr = (RMuint8 *)base_addr+(y*width+x) / 4; RMuint32 bit = (RMuint32) ((RMuint8 *)base_addr+(y*width+x) % 4); RMuint8 pixel = *addr; pixel = pixel & ( 0xFF ^ ( 0x3 << bit * 2)); return (RMuint32) pixel; } break; case 1: { RMuint8 *addr = (RMuint8 *)base_addr+(y*width+x) / 8; RMuint32 bit = (RMuint32) ((RMuint8 *)base_addr+(y*width+x) % 8); RMuint8 pixel = *addr; pixel = pixel & ( 0xFF ^ ( 0x1 << bit )); return (RMuint32) pixel; } break; default: fprintf(stderr,"Unknown bpp : %ld\n",p_osd->bpp); return 0; break; } return 0;}#endif#if 0void osd_draw_horizontal_line(struct osd_descriptor *p_osd, RMuint8 *base_addr, RMuint32 x, RMuint32 y, RMuint32 size, RMuint32 data){ RMuint32 i, j; // lines need to be 2 pixels large for(j=0; j<2; j++) for (i=0;i<size;i++) osd_set_pixel(p_osd, base_addr, (x+i), (y+j), data);}void osd_draw_vertical_line(struct osd_descriptor *p_osd, RMuint8 *base_addr, RMuint32 x, RMuint32 y, RMuint32 size, RMuint32 data){ RMuint32 i, j; // lines need to be 2 pixels large for(j=0; j<2; j++) for (i=0;i<size;i++) osd_set_pixel(p_osd, base_addr, (x+j), (y+i), data);}void osd_draw_rectangle(struct osd_descriptor *p_osd, RMuint8 *base_addr, struct osd_rectangle *rect, RMuint32 data, RMbool fill){ RMuint32 i; if((rect->x > p_osd->width) || (rect->y > p_osd->height) || (rect->x+rect->width > p_osd->width) || (rect->y+rect->height > p_osd->height)){ return; } if(fill != 0) for(i=0;i<rect->width; i++) osd_draw_vertical_line(p_osd, base_addr, rect->x+i, rect->y, rect->height, data); else { osd_draw_vertical_line(p_osd, base_addr, rect->x, rect->y, rect->height, data); osd_draw_vertical_line(p_osd, base_addr, rect->x+rect->width, rect->y, rect->height, data); osd_draw_horizontal_line(p_osd, base_addr, rect->x, rect->y, rect->width, data); osd_draw_horizontal_line(p_osd, base_addr, rect->x, rect->y+rect->height, rect->width, data); }}void osd_change_rectangle_size(struct osd_descriptor *p_osd, RMuint8 *base_addr, struct osd_rectangle *old_rect, struct osd_rectangle *new_rect, RMuint8 erase_data){ RMuint32 i,j; RMuint32 data; if(new_rect->height == 0){ osd_draw_rectangle(p_osd, base_addr, old_rect, erase_data, TRUE); return; } if((old_rect->x > p_osd->width) || (old_rect->y > p_osd->height) || (old_rect->x+old_rect->width > p_osd->width) || (old_rect->y+old_rect->height > p_osd->height)) return; if((new_rect->x > p_osd->width) || (new_rect->y > p_osd->height) || (new_rect->x+new_rect->width > p_osd->width) || (new_rect->y+new_rect->height > p_osd->height)) return; if(((old_rect->x+old_rect->width) < new_rect->x) || ((old_rect->y+old_rect->height) < new_rect->y)) { fprintf(stderr, "Error, old rectangle and new rectangles are in 2 differents places !!\n"); return; } data = osd_get_pixel(p_osd, base_addr, old_rect->x, old_rect->y); // width+1 and height+1 because writeVerticalLine and writeHorizontalLine draw 2 lines // write new rectangle for(i=0;i<(new_rect->width+1);i++) { for(j=0;j<(new_rect->height+1);j++){ if((((new_rect->x+i) < old_rect->x) || ((new_rect->x+i) > (old_rect->x+(old_rect->width+1)))) || (((new_rect->y+j) < old_rect->y) || ((new_rect->y+j) > (old_rect->y+(old_rect->height+1))))){ osd_set_pixel(p_osd, base_addr, (new_rect->x+i), (new_rect->y+j), data); } } } // erase old rectangle for(i=0;i<(old_rect->width+1);i++) { for(j=0;j<(old_rect->height+1);j++){ if((((old_rect->x+i) < new_rect->x) || ((old_rect->x+i) > (new_rect->x+(new_rect->width+1)))) || (((old_rect->y+j) < new_rect->y) || ((old_rect->y+j) > (new_rect->y+(new_rect->height+1))))){ osd_set_pixel(p_osd, base_addr, (old_rect->x+i), (old_rect->y+j), erase_data); } } }}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -