?? curacao.cpp
字號:
/***************************************** Copyright (c) 2001-2003 Sigma Designs, Inc. All Rights Reserved Proprietary and Confidential *****************************************//** @file curacao.cpp @brief This is the main app for em86xx based dvdplayer @date 2004-01-06*/#define ALLOW_OS_CODE 1#include "common.h"//#include "cddaplayer.h"//#include "vcdplayer.h"#include "fileplayer.h"//#include "dvdvideo/dvdplayer.h"//#include "dvdaudio/dvdaudioplayer.h"#include "gui/gui.h"#include "samples/main_apps.h"#ifdef CURACAO_EM86XX_BOARD #include "em86xx.h" #if (EM86XX_MODE==EM86XX_MODEID_STANDALONE) #define TOTAL_MEMORY_NEEDED (4*1024*1024) // increased for 2 nero files #define MAX_BOARDS 1 // Always 1 in standalone #endif#endif#include <stdio.h>#include <stdlib.h>#include <string.h>#include <setjmp.h>#include <sys/time.h>// contains all system specific functions and callbacks for remote control#include "rmlocalremote.c"// for keyboard input//#include "rmlocalkeyboard.c"#ifdef WITH_MONO #include "rmmemorymanager/include/rmmmhomemade.h" #include "rmlibcw/include/rmcriticalsections.h" #if 1// extern struct mz *pZ0; #else static struct mz *pZ0 = (struct mz *) NULL; void *RMMalloc(RMuint32 size) { return RMMallocInZone(NULL,pZ0,size); } void RMFree(void *ptr) { RMFreeInZone(NULL,pZ0,ptr); } void *RMCalloc(RMuint32 nmemb,RMuint32 size) { return RMCallocInZone(NULL,pZ0,nmemb,size); } void *RMMemset(void *s, RMuint8 c, RMuint32 n) { return RMMemsetInZone(NULL,pZ0,s,c,n); } void *RMMemcpy(void *dest, const void *src, RMuint32 n) { return RMMemcpyInZone(NULL,pZ0,dest,src,n); } RMint32 RMMemcmp(const void *s1, const void *s2, RMuint32 n) { return RMMemcmpInZone(NULL,pZ0,s1,s2,n); } #ifdef WITH_THREADS void mzlock(void *mac,void *cookie) { RMEnterCriticalSection((RMcriticalsection)cookie); } void mzunlock(void *mac,void *cookie) { RMLeaveCriticalSection((RMcriticalsection)cookie); } #endif /* WITH_THREADS */ #endif#endifRMstatus InterpretCommand(RMremoteKey c, typeCuracaoContext *context);RMstatus CheckDriveStatus (typeCuracaoContext *context);RMstatus CreateMediaPlayer(/*RMdiscType *discType, */typeCuracaoContext *context);void UpdateFrontPanel(struct timeval *last_time, RMuint8 *currentFipSymbol, RMbool *show_disc, typeCuracaoContext *context);void UpdateGui(struct timeval *last_time, typeCuracaoContext *context);#ifdef WITH_RC5_REMOTE // RC5 buttons mappingRMremoteKey MapRC5RemoteKey(RMremoteKey c, typeCuracaoContext *context);#endif//RMbool g_useKeyboard = FALSE;typeCuracaoContext context = {0,};#if (EM86XX_MODE==EM86XX_MODEID_STANDALONE)RMascii MOUNT_POINT[_MAX_PATH] = "/mnt/";#elseRMascii MOUNT_POINT[_MAX_PATH] = "/mnt/cdrom/";#endif// this function create an instance of media player according to the disc typeRMstatus CreateMediaPlayer(/*RMdiscType *discType, */typeCuracaoContext *context){ RMstatus status; fprintf(stderr, "CreateMediaPlayer start\n"); // create new player if(context->player != 0){ delete (context->player); context->player = 0; fprintf(stderr, "Just killed the old player\n"); } printf("DiscType : dir\n"); context->player = (RMmediaPlayerIface *) new RMfilePlayer(context); status = RM_OK; if(status == RM_OK){ if(context->player == 0) status = RM_ERROR; else if(context->gui){ context->gui->Notify(CURACAO_MESSAGE_CREATED_MEDIA_PLAYER, /*discType*/0); fprintf(stderr, "CreateMediaPlayer ended successfully, now notifying GUI\n"); } } return status;}// this function check if the drive state has change (user pressed eject on the remote or on the drive),// in case of change, we need to detect again the media// and reset the current media player or create an other one.RMstatus CheckDriveStatus (typeCuracaoContext *context){// if (context->disc == NULL) { // a folder was specified (instead of a device) if (context->isDiscDetected) return RM_OK; //fprintf(stderr, "None device playback detected\n"); context->isDiscDetected = TRUE;// context->discType = RMFMediaDetect(MOUNT_POINT); if(context->gui) context->gui->DiscState(); // create a new media player // (the current media player deletion is made inside this function) return CreateMediaPlayer(/*&context->discType, */context);// } RMASSERT (FALSE); return RM_ERROR_NO_DISC_IN_DRIVE;}void UpdateFrontPanel(struct timeval *last_time, RMuint8 *currentFipSymbol, RMbool *show_disc, typeCuracaoContext *context){}void UpdateGui(struct timeval *last_time, typeCuracaoContext *context){ RMuint64 diff_in_usec; struct timeval current_time; typeMediaPlayerSate state; state = context->player->GetState(); if((state == STATE_PLAY) || (state == STATE_STEP) || (state == STATE_FAST_FORWARD) || (state == STATE_FAST_REWIND) || (state == STATE_SLOW_FORWARD)){ gettimeofday(¤t_time, NULL); diff_in_usec = (RMuint64)(((RMint64)current_time.tv_sec-(RMint64)(*last_time).tv_sec)*1000000LL + ((RMint64)current_time.tv_usec-(RMint64)(*last_time).tv_usec)); if(context->changeChannel) { printf("send key\n"); context->gui->SendKey((RMremoteKey)(161)); context->changeChannel = FALSE; } if(diff_in_usec > 500000LL){ context->player->UpdateMediaInfo(); *last_time = current_time; } }}void UpdateOutputs(struct timeval *last_time, typeCuracaoContext *context){ RMuint64 diff_in_usec; struct timeval current_time; gettimeofday(¤t_time, NULL); diff_in_usec = (RMuint64)(((RMint64)current_time.tv_sec-(RMint64)(*last_time).tv_sec)*1000000LL + ((RMint64)current_time.tv_usec-(RMint64)(*last_time).tv_usec)); if(diff_in_usec > 50000LL){ if (context->decoder){ if(context->gui){ RMbool autoswitch = context->gui->GetAutoSwitchState(); RMstatus status = context->decoder->UpdateOutputs(autoswitch); if(status == RM_PENDING) { context->gui->Notify(CURACAO_MESSAGE_VIDEOOUT_AUTO_CHANGE, NULL); }#ifndef GUI_REFID_3 else if(status == RM_INVALIDMODE) { RMbool useSaved = TRUE; context->gui->Notify(CURACAO_MESSAGE_VIDEOOUT_AUTO_CHANGE, &useSaved); }#endif } else context->decoder->UpdateOutputs(); } *last_time = current_time; }}#ifdef WITH_RC5_REMOTE // RC5 buttons mappingRMremoteKey MapRC5RemoteKey(RMremoteKey c, typeCuracaoContext *context){ typeMediaPlayerSate state = STATE_CLOSE; if (context->player != NULL) state = context->player->GetState(); switch(c){ case RM_HW_FAST_FORWARD: if (state == STATE_PAUSE || state == STATE_SLOW_FORWARD) c = RM_HW_SLOW_FORWARD; break; case RM_HW_FAST_REWIND: if (state == STATE_PAUSE || state == STATE_SLOW_FORWARD) c = RM_HW_SLOW_REVERSE; break; case RM_HW_PAUSE_PLAY: if (state != STATE_PAUSE && state != STATE_STEP) c = RM_HW_TIMEOUT; break; default: break; } return c;}#endifextern RMuint32 mem_status;extern void *Rmalloc(size_t size, const char *file);extern void *Rcalloc(size_t nelem, size_t size, const char *file);extern void *Rrealloc(void *p, size_t size, const char *file);extern void Rfree(void *p, const char *file);int main(int argc, char **argv){ RMremoteKey c; remoteHandleType *handle = 0; RMstatus status = RM_OK; struct timeval last_time; RMbool show_disc; RMuint8 currentFipSymbol; struct timeval last_gui_update_time; struct timeval last_output_update_time; RMbool useHDProfile; char *mediaDevice; char *remoteDevice; RMuint8 i; RMuint8 *pStart = NULL; mem_status = 0; useHDProfile = TRUE; mediaDevice = (char*) NULL; remoteDevice = (char*) NULL; // init context structure ... used by callbacks, decoders and media players context.isDiscDetected = FALSE;// context.disc = 0; context.needToExit = FALSE; context.needToStop = FALSE; context.bufferedKey = RM_HW_TIMEOUT; context.player = 0; context.device = (RMnonAscii*)mediaDevice; context.rh = 0; context.remoteTimeout = MS_REMOTE_TIMEOUT; context.boardNumber = 0; context.modeChange = FALSE; for (i=1 ; i<argc ; i++) { if (! strcmp(argv[i], "-sd")) { printf("Use SD profile ...\n"); useHDProfile = FALSE; } else if (! strcmp(argv[i], "-m")) { if (i+1 < argc) { context.boardNumber = strtol(argv[i+1], NULL, 0); i++; printf("board number %lu\n", context.boardNumber); } } else if (argv[i][0] == '-') { fprintf(stderr, "Unknown option : %s\n", argv[i]); } else break; } if ((argc != 1) && (i<argc)) { mediaDevice = argv[i]; context.device = (RMnonAscii*)mediaDevice; if (i+1 < argc) remoteDevice = argv[i+1]; } else { printf("Usage : %s [options] mediaDevice [remoteDevice] (if no remote device is specified, the keyboard is used\n", argv[0]); printf("options: \n"); printf("\t-sd: to force SD profile\n"); printf("\t-m <board number>: to select a board index. Default is 0\n"); return -1; } printf("Allocating %d bytes ...\n", TOTAL_MEMORY_NEEDED*MAX_BOARDS);// pStart=(RMuint8 *)malloc(TOTAL_MEMORY_NEEDED*MAX_BOARDS);// if (pStart==NULL) {// printf("Cannot allocate %d bytes.\n",TOTAL_MEMORY_NEEDED*MAX_BOARDS);// goto cleanup;// }// printf("Succeeded\n");// pZ0 = RMCreateZone(NULL, RM_MACHINEALIGNMENT, pStart, TOTAL_MEMORY_NEEDED);// RMSetSyncCookie(NULL, pZ0, RMCreateCriticalSection()); // after this call// RMobject::CreateLock(); printf("Creating Front panel handler ...\n"); // the board used is em86xx printf("Creating Em86xx decoder ...\n"); context.decoder = (RMdecoderIface *) new RMem86xxDecoder(&context, useHDProfile); context.gui = new RMcuracaoGui(&context); status = context.gui->Initialize((RMnonAscii *) "curacao.xml"); if (status != RM_OK) { fprintf(stderr,"Cannot Initialize gui -> EXIT\n"); goto cleanup; } // open remote control device if (RMlocalRemoteOpen(remoteDevice,&handle)!=RM_OK) { fprintf(stderr,"Cannot open remote control \"%s\"\n",remoteDevice); goto cleanup; } context.rh = RMFremoteOpenEx((void *)handle, PseudoFileReadWithTimeout, RMFlushCallback, RMSleepCallback, PseudoFileAvailable); if(context.rh != 0){ printf("remote device %s successfully opened\n", remoteDevice); } else { fprintf(stderr,"Cannot open remote control \"%s\"\n",remoteDevice); goto cleanup; } printf("Opening FOLDER : %s\n", mediaDevice); // it's a media folder// context.disc = NULL; RMCopyAscii(MOUNT_POINT, mediaDevice); RMAppendAscii(MOUNT_POINT, "/"); // an extra '/' wouldn't hurt show_disc = TRUE; currentFipSymbol = 0; gettimeofday(&last_time, NULL); gettimeofday(&last_gui_update_time, NULL); gettimeofday(&last_output_update_time, NULL); // this is the main loop // it checks the drive, read the input command and pass it to the interpreters while (1) { status = CheckDriveStatus (&context);// context.gui->DiscState(); context.gui->CheckVisualEvents(); if (context.bufferedKey == RM_HW_TIMEOUT){ c = RMFremoteWaitSymbol(context.rh, context.remoteTimeout); } else{ c = context.bufferedKey; context.bufferedKey = RM_HW_TIMEOUT; } if(context.needToStop){ c = RM_HW_STOP; context.needToStop = FALSE; }// printf("memory status: %lu\n", mem_status);#ifdef WITH_RC5_REMOTE // RC5 buttons mapping c = MapRC5RemoteKey(c, &context);#endif if(c > 0) { printf("Got Symbol : %d\n", c); status = context.gui->SendKey(c); if(status == RM_ERROR_QUEUE_COMMAND) { printf("The player temporarily can't accept the command, we'll try to send it again later.\n"); context.bufferedKey = c; } } if(! context.needToExit && ! context.needToRestart) { if(context.player != 0) { context.player->ProcessData(); // recheck player for null because the user may eject at the dvd parental password prompt in ProcessData if(context.player != NULL) { UpdateFrontPanel(&last_time, ¤tFipSymbol, &show_disc, &context); UpdateGui(&last_gui_update_time, &context); } } UpdateOutputs(&last_output_update_time, &context); } else {#if (EM86XX_MODE==EM86XX_MODEID_WITHHOST) break;#else if(context.player != 0) { if(context.player->Close() != RM_OK) { continue; } delete (context.player); context.player = 0; } if(context.gui != 0) context.gui->ClearScreen();//#ifdef GUI_REFID_2 // disable output -- to be reenabled on restart context.decoder->DisableVideoConnector(NULL);//#endif // for stand-alone, we won't exit the application if the POWER button is pressed RMbool restart = 0;#ifdef GUI_REFID_2 printf("\n\nStandby Mode: press POWER to restart\n");#else { // turn on panel with GPIO 14 struct SystemBlock_GPIO_type gpio; gpio.Bit = 11; gpio.Data = FALSE; RUASetProperty(context.gui->m_pRua, SystemBlock, RMSystemBlockPropertyID_GPIO, &gpio, sizeof(gpio), 0); } RMuint8 n = 0; static RMremoteKey exitSequence[4] = { RM_HW_KEY_0 }; printf("\n\nStandby Mode: press POWER to restart or 0 to quit\n");#endif while(!restart){ c = RMFremoteWaitSymbol(context.rh, context.remoteTimeout); if(context.needToExit || context.needToStop) { context.needToRestart = FALSE; } // curacao might restart forever on decoder errors // but it's no worse than exit(1) // (could add a restart count...) if(context.needToRestart) { RMDBGLOG((ENABLE, "\n\n\t\tOMG!!\t\tWe need to restart!!\n\n")); context.needToRestart = FALSE; RMFlushCallback(context.rh); // try to skip the commands that follow the error/restart //c = RM_HW_ON_OFF; c = RM_HW_EJECT; } if(c > 0){ printf("Got Symbol : %d\n", c); switch(c){ case RM_HW_EJECT: // context.gui->SendKey(c); // fall through to wake up player //case RM_HW_ON_OFF: context.isDiscDetected = FALSE;// context.discType = RM_NO_DISC; context.needToExit = FALSE; context.needToStop = FALSE;//#ifdef GUI_REFID_2 context.gui->ReenableDisplay();//#endif context.gui->DisplayMainPage(); restart = 1; break; default: if (c != exitSequence[n]){ n = 0; } else if (++n == 1){ goto cleanup; } break; } } }#endif //em86xx } } cleanup: // exit if(context.player != 0){ context.player->Close(); delete (context.player); context.player = 0; } if(context.rh != 0) RMFremoteRelease(context.rh); if(handle != 0) RMlocalRemoteClose(&handle); if(context.gui != 0){ context.gui->Close(); delete context.gui; } delete context.decoder;// RMGetZoneStats(NULL,pZ0,NULL,NULL,NULL,NULL);#ifdef WITH_THREADS /* once the above lines begin only one thread must run! */// RMDeleteCriticalSection((RMcriticalsection)RMGetSyncCookie(NULL,pZ0)); /* se what's left with: RMDumpMallocedBlocksInZone(pZ0); */// RMSetSyncCookie(NULL,pZ0,0);// RMobject::DeleteLock();#endif // WITH_THREADS// status = RMDeleteZone(NULL,pZ0); printf("memory status: %lu\n", mem_status); if(RMSUCCEEDED(status)) printf("interface closed, no error\n"); else printf("interface closed, unreleased memory error(s)\n"); if (pStart!=NULL) { free(pStart); } return 0;}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -