📄 em85xx.cpp
字号:
#include "em85xx.h"#include "realmagichwl_userland_api.h"#if 0static void debug_break (void){}#define ASSERT(exp) ((void)((exp)?1:(printf ("ASSERT failed: line %d, file %s\n", __LINE__,__FILE__), debug_break(), 0)))#define DEBUGMSG(cond,printf_exp) ((void)((cond)?(printf printf_exp),1:0))#else#define ASSERT(exp)#define DEBUGMSG(cond,printf_exp)#endif#define MAX_FEEDPACKETS 8192static feedpacket FeedPacketsArray[MAX_FEEDPACKETS];//////////////////////typedef RMuint16 MWIMAGEBITS;// builtin C-based proportional/fixed font structuretypedef struct { RMint8 *name; // font name RMint32 maxwidth; // max width in pixels RMint32 height; // height in pixels RMint32 ascent; // ascent (baseline) height RMint32 firstchar; // first character in bitmap RMint32 size; // font size in characters RMuint16 *bits; // 16-bit right-padded bitmap data RMuint16 *offset; // 256 offsets into bitmap data RMuint8 *width; // 256 character widths or 0 if fixed} MWCFONT, *PMWCFONT;typedef struct _tagsdPOINT{ RMuint32 x; RMuint32 y; RMuint32 x2; RMuint32 y2;} sdPOINT;#include "myfont.c"static RMuint8 pixel_value = 1;static void SetPixel (RMuint32 x, RMuint32 y, RMuint32 colour, RMuint8 *pOsd, RMuint32 w, RMuint32 h){ if (pixel_value == 3) pOsd[(y * w) + x] = 1; else pOsd[(y * w) + x] = pixel_value;}static void ClearPixel (RMuint32 x, RMuint32 y, RMuint8 *pOsd, RMuint32 w, RMuint32 h){ if (pixel_value == 3) pOsd[(y * w) + x] = 3; else pOsd[(y * w) + x] = 0;}static void DrawCharacter (PMWCFONT pFont, RMint8 ch, RMuint32 colour, RMuint32 xOff, RMuint32 yOff, RMuint8 *pOsd, RMuint32 w, RMuint32 h){ RMuint16 *bits; bits = pFont->bits + pFont->offset[ch - pFont->firstchar]; RMuint32 width, height, y, x; height = pFont->height; width = (pFont->width) ? pFont->width[ch - pFont->firstchar] : pFont->maxwidth; for (y = 0; y < height; y++) { RMuint16 row = bits[y], mask; for (mask = 0x8000, x = 0; x < width; (mask >>= 1), x++) { if (row & mask) SetPixel (x + xOff, y + yOff, colour, pOsd, w, h); else ClearPixel (x + xOff, y + yOff, pOsd, w, h); } }}static RMuint32 mystrlen (PMWCFONT pFont, RMint8 *text){ RMuint32 length = 0; if (text) { while ((*text != 0) && (*text != ' ')) { length += (pFont->width) ? pFont->width[*text - pFont->firstchar] : pFont->maxwidth; text++; } } return length;}static void DrawText (PMWCFONT pFont, RMint8 *text, sdPOINT *pLoc, RMuint32 color, RMuint8 *pOsd, RMuint32 w, RMuint32 h){ RMuint32 xOffset = pLoc->x, width, wordlen, spacelen; RMint8 *str = text; spacelen = (pFont->width) ? pFont->width[' ' - pFont->firstchar] : pFont->maxwidth; while (*str != 0) { if (*str == ' ') { wordlen = mystrlen (pFont, str+1) + spacelen; if (wordlen <= (pLoc->x2 - pLoc->x)) { if ((xOffset + wordlen) > pLoc->x2) { str++; xOffset = pLoc->x; pLoc->y += pFont->height; if ((pLoc->y + pFont->height) > pLoc->y2) break; } } } if ((*str < pFont->firstchar) || (*str >= (pFont->firstchar + pFont->size))) *str = 0x3f; // '?' DrawCharacter (pFont, *str, color, xOffset, pLoc->y, pOsd, w, h); xOffset += (pFont->width) ? pFont->width[*str - pFont->firstchar] : pFont->maxwidth; str++; if (xOffset > pLoc->x2) { xOffset = pLoc->x; pLoc->y += pFont->height; if ((pLoc->y + pFont->height) > pLoc->y2) break; } }}//////////////////////// rgb 2 yuv:// Y = 0.257r + 0.504g + 0.098b + 16// Cb = -0.148r - 0.291g + 0.439b + 128// Cr = 0.439r + 0.368g + 0.071b + 128static RMuint8 rgb2y (RMuint8 r, RMuint8 g, RMuint8 b){ RMint32 f = 257*(RMint32)r + 504*(RMint32)g + 98*(RMint32)b + 16000; if (f > 255000) f = 255000; f = f / 1000; return (RMuint8)f;}static RMuint8 rgb2u (RMuint8 r, RMuint8 g, RMuint8 b){ RMint32 f = -148*(RMint32)r - 291*(RMint32)g + 439*(RMint32)b + 128000; if (f > 255000) f = 255000; if (f < 0) f = 0; f = f / 1000; return (RMuint8)f;}static RMuint8 rgb2v (RMuint8 r, RMuint8 g, RMuint8 b){ RMint32 f = 439*(RMint32)r - 368*(RMint32)g - 71*(RMint32)b + 128000; if (f > 255000) f = 255000; if (f < 0) f = 0; f = f / 1000; return (RMuint8)f;}MpegDecoder::MpegDecoder (){}MpegDecoder::~MpegDecoder (){}MPEG_DECODER_ERROR MpegDecoder::Init (){ DEBUGMSG (1, ("MpegDecoder::Init\n")); m_handle = open ("/dev/realmagichwl0", O_RDONLY); ASSERT (m_handle != -1); if (m_handle == -1) return MPEG_DECODER_ERROR_NO_DECODER; m_yuvWidth = 0; m_yuvHeight = 0; m_osdWidth = 0; m_osdHeight = 0; m_isMPEG4 = 0; FeedPacketQueuesInit (FeedPacketsArray, MAX_FEEDPACKETS); // make the osd buffer is 320x240 RMuint32 i; RMuint8 *pOSDHeader, *pPalette, *pBits; m_osdWidth = 320; m_osdHeight = 240; asm ("mcr p15, 0, r0, c7, c10, 0\n"); ioctl (m_handle, REALMAGICHWL_IOCTL_OSDFB_REFRESH, &m_OsdBuffer); ASSERT (m_OsdBuffer.framebuffer); pOSDHeader = (RMuint8 *)(m_OsdBuffer.framebuffer); pPalette = pOSDHeader + 8; pBits = pPalette + 1024; pOSDHeader[0] = 0x3e; pOSDHeader[1] = ((m_osdWidth*m_osdHeight+1024+8) >> 16) & 0xff; pOSDHeader[2] = ((m_osdWidth*m_osdHeight+1024+8) >> 8) & 0xff; pOSDHeader[3] = ((m_osdWidth*m_osdHeight+1024+8) >> 0) & 0xff; pOSDHeader[4] = (m_osdWidth >> 8) & 0xff; pOSDHeader[5] = (m_osdWidth >> 0) & 0xff; pOSDHeader[6] = (m_osdHeight >> 8) & 0xff; pOSDHeader[7] = (m_osdHeight >> 0) & 0xff; // init palette for (i=0; i<256; i++) { pPalette[0] = 0x00; // alpha (0x00 = transparent, 0xff = opaque) if (i) pPalette[0] = 0xff; pPalette[1] = rgb2y (0, 0, 0); // y pPalette[2] = rgb2u (0, 0, 0); // u pPalette[3] = rgb2v (0, 0, 0); // v pPalette += 4; } // some pre-defined colours pPalette = pOSDHeader + 8; pPalette += 4; pPalette[0] = 0xff; pPalette[1] = rgb2y (0, 0, 0); // y pPalette[2] = rgb2u (0, 0, 0); // u pPalette[3] = rgb2v (0, 0, 0); // v pPalette += 4; pPalette[0] = 0xff; pPalette[1] = rgb2y (0xff, 0xff, 0); // y pPalette[2] = rgb2u (0xff, 0xff, 0); // u pPalette[3] = rgb2v (0xff, 0xff, 0); // v pPalette += 4; pPalette[0] = 0xff; pPalette[1] = rgb2y (0xff, 0xff, 0xff); // y pPalette[2] = rgb2u (0xff, 0xff, 0xff); // u pPalette[3] = rgb2v (0xff, 0xff, 0xff); // v for (i=0; i<m_osdWidth*m_osdHeight;i++) pBits[i] = 0; return MPEG_DECODER_ERROR_NO_ERROR;}MPEG_DECODER_ERROR MpegDecoder::GetMaxDisplayModes (RMint32 *pMode){ ASSERT (pMode); *pMode = 2; return MPEG_DECODER_ERROR_NO_ERROR;}MPEG_DECODER_ERROR MpegDecoder::SetupDisplay (RMint32 Mode){ ASSERT (m_handle); ASSERT (Mode < 2); DEBUGMSG (1, ("MpegDecoder::SetupDisplay (%d)\n", Mode)); // refresh osd buffer asm ("mcr p15, 0, r0, c7, c10, 0\n"); ioctl (m_handle, REALMAGICHWL_IOCTL_OSDFB_REFRESH, 0); Wnd_type Wnd; evOutputDevice_type OutputDevice; evTvStandard_type TvStandard; evTvOutputFormat_type TvOutputFormat; evDigOvOnlyParams_type DVIParameters; if (Mode == 0) { // go to digital output Wnd.x = 0; Wnd.y = 0; Wnd.w = 320; Wnd.h = 240; m_numeratorPixelAspectRatio = 675; m_denominatorPixelAspectRatio = 639; TvStandard = evTvStandard_NTSC; TvOutputFormat = evTvOutputFormat_OUTPUT_OFF; OutputDevice = evOutputDevice_DigOvOnly; // HSyncTotal = PreHSync + HSyncActive + PostHSync + VideoWidth; // VSyncTotal = PreVSync + VSyncActive + PostVSync + VideoHeight; // HFreq = VFreq * VSyncTotal / (Interlaced ? 2:1); // PixelFreq = HFreq * HSyncTotal * ((nbits==8) ? 2:1); DVIParameters.HFreq = 18328; //27859; DVIParameters.VFreq = 7480; //11371; DVIParameters.VideoWidth = 320; DVIParameters.VideoHeight = 240; DVIParameters.PreHSync = 1; DVIParameters.HSyncActive = 19; DVIParameters.PostHSync = 1; DVIParameters.PreVSync = 5; DVIParameters.VSyncActive = 0; DVIParameters.PostVSync = 0; DVIParameters.HSyncTotal = DVIParameters.VideoWidth + DVIParameters.PreHSync + DVIParameters.HSyncActive + DVIParameters.PostHSync; DVIParameters.VSyncTotal = DVIParameters.VideoHeight + DVIParameters.PreVSync + DVIParameters.VSyncActive + DVIParameters.PostVSync; DVIParameters.PixelFreq = 0; DVIParameters.Interlaced = 0; DVIParameters.HSyncPolarity = 0; DVIParameters.VSyncPolarity = 0; DVIParameters.BitsPerClock = 24; DVIParameters.Ccir = CCIR_601; DVIParameters.InvertField = CCIR_NON_INVERT_FIELD; DVIParameters.SyncEnable = VSyncEn_HSyncEn_VrdyEn; DVIParameters.Vip20 = 1; DVIParameters.SyncGen = evSyncGen_em8xxx_Master; DVIParameters.TvHdtvStandard = evTvHdtvStandard_NTSC; // actually doesn't matter RUA_DECODER_SET_PROPERTY (m_handle, VIDEO_SET, evValidWindow, sizeof(Wnd), &Wnd); RUA_DECODER_SET_PROPERTY (m_handle, VIDEO_SET, evDigOvOnlyParams, sizeof(DVIParameters), &DVIParameters); RUA_DECODER_SET_PROPERTY (m_handle, VIDEO_SET, evTvOutputFormat, sizeof(TvOutputFormat), &TvOutputFormat); RUA_DECODER_SET_PROPERTY (m_handle, VIDEO_SET, evTvStandard, sizeof(TvStandard), &TvStandard); RUA_DECODER_SET_PROPERTY (m_handle, VIDEO_SET, evOutputDevice, sizeof(OutputDevice), &OutputDevice); Wnd.x = 0; Wnd.y = 0; Wnd.w = 320; Wnd.h = 240; RUA_DECODER_SET_PROPERTY (m_handle, OSD_SET, eOsdDestinationWindow, sizeof(Wnd), &Wnd); Wnd.x = 0; Wnd.y = 0; Wnd.w = 320; Wnd.h = 240; m_screenWidth = 320; m_screenHeight = 240; RUA_DECODER_SET_PROPERTY (m_handle, VIDEO_SET, evDestinationWindow, sizeof(Wnd), &Wnd); } else { TvStandard = evTvStandard_NTSC; TvOutputFormat = evTvOutputFormat_COMPOSITE; OutputDevice = evOutputDevice_TV; Wnd.x = 0; Wnd.y = 0; Wnd.w = 720; Wnd.h = 480; m_numeratorPixelAspectRatio = 8; m_denominatorPixelAspectRatio = 9;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -