?? play_mp4.c
字號:
/* * * Copyright (c) Sigma Designs, Inc. 2005. All rights reserved. * *//** @file play_mp4.c @brief sample application to access the Mambo chip and test DMA transfers @author Sebastian Frias Feltrer @ingroup dccsamplecode*//* ****************************************************************************************** This file is part of libsamples library, therefore *NO* static variables should be defined *******************************************************************************************/#include "sample_os.h"#define ALLOW_OS_CODE 1#include "../dcc/include/dcc.h"#include "../rmmp4api/include/rmmp4api.h"#include "common.h"#include "parsemp4dsi.h"#ifndef WITHOUT_NERO_SPU#ifdef WITH_MONO#include "spuapi.h"#endif#endif // WITHOUT_NERO_SPU#define MAX_SAMPLE_SIZE 2048#define COMMON_TIMEOUT_US (TIMEOUT_10MS) // 10 ms#define DMA_BUFFER_SIZE_LOG2 14#define DMA_BUFFER_COUNT 64#define AUDIO_BASE 90000#define VIDEO_FIFO_SIZE (1024*1024)#define AUDIO_FIFO_SIZE (128*1024)#define VIDEO_XFER_FIFO_COUNT 1024#define AUDIO_XFER_FIFO_COUNT 1024#define VIDEO_PREBUFFER_SIZE (2048) // in KB#define AUDIO_PREBUFFER_SIZE ( 128) // in KB#define KEYFLAGS (SET_KEY_DISPLAY | SET_KEY_PLAYBACK | SET_KEY_AUDIO | SET_KEY_SPI)#define RM_DEVICES_STC 0x1#define RM_DEVICES_VIDEO 0x2#define RM_DEVICES_AUDIO 0x4#define SEND_VIDEO_TRACK 1#define SEND_AUDIO_TRACK 2#define SEND_SPU_TRACK 3#if 0 #define SENDDBG ENABLE#else #define SENDDBG DISABLE#endif#if 0 #define DBG ENABLE#else #define DBG DISABLE#endif#if 0 #define SPU_DBG ENABLE#else #define SPU_DBG DISABLE#endif#if 0 #define INTERLEAVE_DBG ENABLE#else #define INTERLEAVE_DBG DISABLE#endif#if 0 #define H264_SC_DBG ENABLE#else #define H264_SC_DBG DISABLE#endif#define DMABUFFER_UNUSED_BLOCK_SIZE 256typedef enum { MP4_MP3, MP4_AAC} RMmp4AudioTrackType_t;typedef enum { MP4_MP4} RMmp4VideoTrackType_t;typedef enum { RMMP4_AVSend_FSM_GetBuffer = 0, RMMP4_AVSend_FSM_ReadData, RMMP4_AVSend_FSM_SendData, RMMP4_AVSend_FSM_ReleaseBuffer, RMMP4_AVSend_FSM_StopSending} RMMP4SendFSMStates;typedef enum { RMMP4_Subtitle_FSM_Get = 0, RMMP4_Subtitle_FSM_WaitSync, RMMP4_Subtitle_FSM_Show, RMMP4_Subtitle_FSM_Clear, RMMP4_Subtitle_FSM_Stop} RMMP4SubtitleFSMStates;typedef enum { RMMP4_SPU_FSM_Get = 0, RMMP4_SPU_FSM_WaitSync, RMMP4_SPU_FSM_Clear, RMMP4_SPU_FSM_Stop} RMMP4SPUFSMStates;enum goto_label { LABEL_ERROR = 1, LABEL_NONE, LABEL_CLEANUP, LABEL_MAINLOOP, LABEL_MAINLOOP_NOSEEK, LABEL_START_SENDING_DATA, LABEL_SIGNAL_EOS_AND_EXIT};#define SPU_FIFO_ENTRIES 256struct spu_fifo_entry_type { RMuint8 *ptr; RMuint32 size; struct emhwlib_info Info;};struct priv_cmdline { RMuint32 audio_track; RMuint32 internal_file_open; // should we open the file internally RMbool spuEnabled; RMbool subtitlesEnabled; RMbool monitorFIFOs;};struct SendMP4DataContext { struct RUA *pRUA; struct DCC *pDCC; struct RUABufferPool *pDMA; RMbool FirstSystemTimeStamp; RMbool WaitAtExit; RMMP4SPUFSMStates spuFSMStatus; RMfile mp4_file; ExternalRMmp4Client mp4c; ExternalRMmp4Track mp4tV, mp4tA, mp4tSPU, mp4tSubT; RMmp4Sample audiosample, videosample, spusample, subtitlesample; RMuint8 *subtitleString; RMbool SendVideoData; RMbool SendAudioData; RMbool SendSPUData; RMbool SendVideoPts; RMbool SendAudioPts; RMbool SendSPUPts; RMuint32 videoDataSent; RMuint32 audioDataSent; RMuint32 spuDataSent; RMbool isIFrameMode; RMint32 IFrameDirection; RMbool isTrickMode; RMuint32 video_vop_tir, audio_vop_tir; // is AudioCTSTimeScale RMuint32 VideoCTSTimeScale; RMuint32 AudioCTSTimeScale; RMuint32 spuCTSTimeScale; RMuint32 subtCTSTimeScale; RMuint32 audioSampleRate; RMuint32 AAC_SampleRateFromDSI; RMuint32 AAC_ChannelsFromDSI; RMuint32 AAC_ObjectIDFromDSI; RMbool isAudioOnly; RMuint64 lastSTC; RMuint64 Duration; RMint64 fileSize; struct emhwlib_info video_Info; struct emhwlib_info audio_Info; struct emhwlib_info spu_Info; struct emhwlib_info subt_Info; struct dcc_context *dcc_info; struct RM_PSM_Context *PSMcontext; RMbool video_ptsScalingMsg; RMbool audio_ptsScalingMsg; RMbool forceTimersToZero; RMbool isNeroDigitalFile; RMbool hasChapters; RMbool playbackAllowed; RMuint32 videoTracks; RMuint32 audioTracks; RMuint32 spuTracks; RMuint32 subtitleTracks; RMuint32 currentVideoTrack; RMuint32 currentAudioTrack; RMuint32 currentSPUTrack; RMuint32 currentSubtitleTrack; RMuint8 *videodsiBuf; RMuint32 videodsiSize; RMbool sendVideoDSI; RMuint32 videoWidth; RMuint32 videoHeight; RMuint8 *spuDSIBuf; RMuint32 spuDSISize; RMbool setSPUPalette; RMuint32 spuWidth; RMuint32 spuHeight; RMbool enableSPU; RMbool displaySPU;#ifdef WITH_MONO struct OSDdoubleBuffer doubleBuffer;#ifndef WITHOUT_NERO_SPU RMNeroSPUDecoderHandle SPUDecoder;#endif //WITHOUT_NERO_SPU RMbool clearSPU; RMuint8 *ndsp_buffer;#endif RMint32 queuedSPUsamples; RMbool enableSubtitles; RMbool displaySubtitles; RMbool initTerminal; // for prebuffering RMuint32 videoPrebufferSize; RMuint32 audioPrebufferSize; RMbool prebufferingDone; struct RMFileStreamInfo streamInfo; RMbool isAACaudioPayload; RMint32 avRatio; RMuint32 dmaBufferCount; RMuint32 dmaBufferSizeLog2; RMuint32 videoBitstreamFIFOSize; RMuint32 videoFIFOXFERCount; RMuint32 audioBitstreamFIFOSize[MAX_AUDIO_DECODER_INSTANCES]; RMuint32 audioFIFOXFERCount[MAX_AUDIO_DECODER_INSTANCES]; RMuint64 lastVideoPTS; RMuint64 lastAudioPTS; RMuint64 lastSPUPTS; RMbool videoEOS; RMbool audioEOS; RMbool spuEOS; RMuint8 *startCodeDMABuffer; RMuint32 startCodeDMABufferOffset; RMuint8 *videoDMABuffer; RMuint32 videoDMABufferOffset; RMbool videoTransferPending; RMuint8 *audioDMABuffer; RMuint32 audioDMABufferOffset; RMbool audioTransferPending; RMuint8 *spuDMABuffer; RMuint32 spuDMABufferOffset; RMbool spuTransferPending; RMuint8 h264DummyBuffer[4]; RMuint8 *h264PktLenBuf; RMuint32 h264PktLen; RMuint32 h264LengthSize; RMuint32 h264BytesLeft; RMbool h264sendStartCode; RMbool h264readPacketSize; struct RMfifo *spu_fifo; RMuint32 videoTrackSize; RMuint32 audioTrackSize; RMuint32 videoMeanSampleSize; RMuint32 audioMeanSampleSize; RMbool monitorFIFOs; RMbool linearInterleaving; void **dmabuffer_array; RMuint32 dmabuffer_index; RMbool isH264; struct RM_PSM_Actions actions; enum RM_PSM_State ACTUAL_PlaybackStatus; enum RM_PSM_State OLD_PlaybackStatus; RMuint32 Ntimes; struct playback_cmdline *play_opt; struct video_cmdline *video_opt; struct display_cmdline *disp_opt; struct audio_cmdline *audio_opt; struct priv_cmdline priv_opt; RMuint32 audioInstances; struct timeval last; RMbool first; RMuint32 videoSampleSize; RMuint32 videoFrameCount; // equivalent to AUs // the result of local_process_key are put here enum goto_label processKeyResult; RMbool processKeyResultValid;};#define GET_DATA_FIFO_INFO(pRUA, ModuleId) \ { \ struct DataFIFOInfo DataFIFOInfo; \ RMuint32 fullness; \ RUAGetProperty(pRUA, ModuleId, RMGenericPropertyID_DataFIFOInfo, &DataFIFOInfo, sizeof(DataFIFOInfo)); \ fullness = (100*DataFIFOInfo.Readable)/DataFIFOInfo.Size; \ fprintf(stderr, "Data 0x%lx: st=0x%08lx sz=%ld wr=%ld rd=%ld --> f : %lu/100\n", ModuleId, DataFIFOInfo.StartAddress, \ DataFIFOInfo.Size, DataFIFOInfo.Writable, DataFIFOInfo.Readable, fullness); \ } \#define GET_XFER_FIFO_INFO(pRUA, ModuleId) \ { \ struct XferFIFOInfo_type XferFIFOInfo; \ RMuint32 fullness; \ RUAGetProperty(pRUA, ModuleId, RMGenericPropertyID_XferFIFOInfo, &XferFIFOInfo, sizeof(XferFIFOInfo)); \ fullness = (100*XferFIFOInfo.Readable)/XferFIFOInfo.Size; \ fprintf(stderr, "XFER 0x%lx: st=0x%08lx sz=%ld wr=%ld rd=%ld er=%lx --> f : %lu/100\n", ModuleId, XferFIFOInfo.StartAddress, \ XferFIFOInfo.Size, XferFIFOInfo.Writable, XferFIFOInfo.Readable, XferFIFOInfo.Erasable, fullness); \ }#define GET_XFER_FIFO_BYTES_QUEUED(pRUA, ModuleId) \ { \ RMuint32 bytes_queued; \ RUAGetProperty(pRUA, ModuleId, RMGenericPropertyID_XferFIFOBytesQueued, &bytes_queued, sizeof(bytes_queued)); \ fprintf(stderr, "XFER 0x%lx: %lu\n", ModuleId, bytes_queued); \ }#define MONITOR_FIFO_INTERVAL_US 250000static void monitorFIFO(struct SendMP4DataContext *context, RMbool alwaysShow){ struct timeval now; RMuint32 elapsed; RMuint64 ptime; struct dcc_context *dcc_info = context->dcc_info; gettimeofday(&now, NULL); elapsed = (now.tv_sec - context->last.tv_sec) * 1000000; elapsed += (now.tv_usec - context->last.tv_usec); if (elapsed > MONITOR_FIFO_INTERVAL_US || alwaysShow) { DCCSTCGetTime(dcc_info->pStcSource, &ptime, 90000); fprintf(stderr, "\n*****************************\n"); fprintf(stderr, "STC = %lld (%lld secs)\n", ptime, (ptime/90000)); /* sample code to get fifo info */ if (dcc_info->pVideoSource) { fprintf(stderr, "Video :\n"); GET_DATA_FIFO_INFO(dcc_info->pRUA, dcc_info->video_decoder); GET_XFER_FIFO_INFO(dcc_info->pRUA, dcc_info->video_decoder); GET_XFER_FIFO_BYTES_QUEUED(dcc_info->pRUA, dcc_info->video_decoder); } if (dcc_info->pMultipleAudioSource) { struct DCCAudioSourceHandle audioHandle; RMuint32 i; for (i = 0; i < context->audioInstances; i++) { fprintf(stderr, "Audio[%lu] :\n", i); DCCMultipleAudioSourceGetSingleDecoderHandleForInstance(dcc_info->pMultipleAudioSource, i, &audioHandle); GET_DATA_FIFO_INFO(dcc_info->pRUA, audioHandle.moduleID); GET_XFER_FIFO_INFO(dcc_info->pRUA, audioHandle.moduleID); GET_XFER_FIFO_BYTES_QUEUED(dcc_info->pRUA, audioHandle.moduleID); } } fprintf(stderr, "*****************************\n"); gettimeofday(&(context->last), NULL); fflush(stderr); } return;}#define PROCESS_KEY(release, getkey) \do { \ local_process_key(&SendContext, getkey, release); \ if (SendContext.ACTUAL_PlaybackStatus != SendContext.OLD_PlaybackStatus) { \ RMDBGLOG((ENABLE, "old status %lu new status %lu\n", (RMuint32)SendContext.OLD_PlaybackStatus, (RMuint32)SendContext.ACTUAL_PlaybackStatus)); \ SendContext.OLD_PlaybackStatus = SendContext.ACTUAL_PlaybackStatus; \ } \ if (SendContext.processKeyResultValid) { \ SendContext.processKeyResultValid = FALSE; \ switch(SendContext.processKeyResult) { \ case LABEL_ERROR: \ case LABEL_CLEANUP: \ goto cleanup; \ case LABEL_MAINLOOP: \ goto mainloop; \ case LABEL_MAINLOOP_NOSEEK: \
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -