?? 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];extern BM_FONT font_myfont; // include "myfont.c" somewhere in your projectstatic 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 (PBM_FONT 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 (PBM_FONT 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 (PBM_FONT 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; RMint32 k = 1; 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 == 0xa) { xOffset = pLoc->x; pLoc->y += pFont->height; k++; str++; continue; } 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] = 0x40; 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; /* // Enable this if you do NOT want to wait for an I frame before // the decoding AFTER a STOP RMuint32 BroadcastVideo; BroadcastVideo = 1; RUA_DECODER_SET_PROPERTY (m_handle, VIDEO_SET, evBroadcastedVideo, sizeof(BroadcastVideo), &BroadcastVideo); */ 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, RMuint8 Pal){ 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 = 0; DVIParameters.HSyncActive = 18; DVIParameters.PostHSync = 2; DVIParameters.PreVSync = 1; DVIParameters.VSyncActive = 3; DVIParameters.PostVSync = 1; 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 = 1; 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 = Pal ? evTvStandard_PAL : evTvStandard_NTSC; TvOutputFormat = evTvOutputFormat_COMPOSITE; OutputDevice = evOutputDevice_TV; Wnd.x = 0; Wnd.y = 0; Wnd.w = 720; Wnd.h = Pal ? 576 : 480; m_numeratorPixelAspectRatio = 8; m_denominatorPixelAspectRatio = 9; RUA_DECODER_SET_PROPERTY (m_handle, VIDEO_SET, evValidWindow, sizeof(Wnd), &Wnd); 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.w = Pal ? 720 : 680; //ntsc: shrink width a bit Wnd.h = Pal ? 576 : 480; Wnd.x = (720 - Wnd.w)/2; Wnd.y = ((Pal ? 576 : 480) - Wnd.h)/2; RUA_DECODER_SET_PROPERTY (m_handle, OSD_SET, eOsdDestinationWindow, sizeof(Wnd), &Wnd); Wnd.x = 0; Wnd.y = 0; Wnd.w = 720; Wnd.h = Pal ? 576 : 480; m_screenWidth = 720; m_screenHeight = Pal ? 576 : 480; RUA_DECODER_SET_PROPERTY (m_handle, VIDEO_SET, evDestinationWindow, sizeof(Wnd), &Wnd); } return MPEG_DECODER_ERROR_NO_ERROR;}MPEG_DECODER_ERROR MpegDecoder::GetScreenDimensions (RMint32 *w, RMint32 *h, RMint32 *n, RMint32 *d){ ASSERT (w); ASSERT (h); *w = m_screenWidth; *h = m_screenHeight; *n = m_numeratorPixelAspectRatio; *d = m_denominatorPixelAspectRatio; return MPEG_DECODER_ERROR_NO_ERROR; }MPEG_DECODER_ERROR MpegDecoder::DisplayYUV420 (RMuint8 *pY, RMuint8 *pUV, RMint32 x, RMint32 y, RMint32 w, RMint32 h, RMint32 w_screen, RMint32 h_screen){ RMint32 i, Yaddr, UVaddr, isMPEG4; YUVframe F; RMuint8 *Y = (RMuint8 *)pY; RMuint8 *UV = (RMuint8 *)pUV; if ((pY == 0) && (pUV == 0)) { int retval; decoderproperty Dp; evYUVWriteParams_type yuv; ASSERT (m_yuvWidth); ASSERT (m_yuvHeight); isMPEG4 = 0; RUA_DECODER_SET_PROPERTY (m_handle, DECODER_SET, edecVideoStd, sizeof (isMPEG4), &isMPEG4); yuv.wWidth = m_yuvWidth; yuv.wHeight = m_yuvHeight; yuv.YUVFormat = YUV_420_UNPACKED; Dp.PropSet = VIDEO_SET; Dp.PropId = evYUVWriteParams; Dp.PropTypeLength = sizeof (evYUVWriteParams_type); Dp.pValue = &yuv; retval = ioctl (m_handle, REALMAGICHWL_IOCTL_DECODER_SET_PROPERTY, &Dp); if (retval != 0) { DEBUGMSG (1, ("ERROR: could not set yuv display parameters\n")); return (MPEG_DECODER_ERROR)retval; } isMPEG4 = m_isMPEG4; RUA_DECODER_SET_PROPERTY (m_handle, DECODER_SET, edecVideoStd, sizeof (isMPEG4), &isMPEG4); return MPEG_DECODER_ERROR_NO_ERROR; } if ((w_screen != m_yuvWidth) || (h_screen != m_yuvHeight)) {
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -