📄 play_model3_video.c
字号:
/* * * Copyright (c) Sigma Designs, Inc. 2002. All rights reserved. * *//** @file dcc_demo.c @brief sample application to access the Mambo chip and test DMA transfers @author Julien Soulier @ingroup dccsamplecode*/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <unistd.h>#include <sys/time.h>#define ALLOW_OS_CODE 1#include "dcc/include/dcc.h"#include "rmlibcw/include/rmfile.h"#include "samples/common.h"#define ABCDRM_MODEL3 1#ifdef ABCDRM_MODEL3// openssl enc -aes-128-cbc -K 56e47a38c5598974bc46903dba290349 -iv 8ce82eefbea0da3c44699ed7db51b7d9 < video_only_mpeg_file.m2v > video_only_mpeg_file.m2v.aes#include "../include/abcdrm_api.h"#define ABCDRM_SERIAL_FLASH_SECTOR 1static RMuint32 abcdrm_base_addr = 0;static RMbool abcdrm_init_flag = FALSE;#endif // ABCDRM_MODEL3#define COMMON_TIMEOUT_US 10000#define WAIT_EOS_TIMEOUT_US 20000000#define DMA_BUFFER_SIZE_LOG2 15#define DMA_BUFFER_COUNT 32#define VIDEO_FIFO_SIZE (1024*1024)#define XFER_FIFO_COUNT (32)#define KEYFLAGS (SET_KEY_DISPLAY | SET_KEY_PLAYBACK | SET_KEY_DEBUG)#define RM_DEVICES_STC 0x1#define RM_DEVICES_VIDEO 0x2#define DEBUG ENABLE#if 0#define SENDDBG ENABLE#else#define SENDDBG DISABLE#endifstatic RMuint32 NTimes = 0;static struct playback_cmdline *play_opt;static struct video_cmdline *video_opt;static struct display_cmdline *disp_opt;struct struct_context { struct RUABufferPool *pDMA; RMbool FirstSystemTimeStamp; RMuint32 FirstPTS; struct dcc_context *dcc_info; struct RM_PSM_Context *PSMcontext; RMfile f_bitstream; RMint64 fileSize; RMbool video_decoder_initialized; RMbool initVideo; RMbool ResyncTimer; RMuint64 lastSTC; RMuint64 lastVideoPTS; RMuint64 lastDecoded; RMbool isSTCRunning;};static struct RM_PSM_Actions actions;#define PROCESS_KEY(release, getkey) \do { \ RMDBGLOG((DISABLE, "process_key\n")); \ if (getkey) { \ err = process_command(context.PSMcontext, &(context.dcc_info), &actions); \ if (RMFAILED(err)) { \ fprintf(stderr, "Error while processing key %d\n", err); \ goto cleanup; \ } \ } \ if (actions.toDoActions & RM_PSM_FLUSH_VIDEO) { \ RMDBGLOG((ENABLE, "flushVIDEO\n")); \ Stop(&context, RM_DEVICES_VIDEO); \ context.video_decoder_initialized = FALSE; \ context.initVideo = TRUE; \ actions.toDoActions &= ~RM_PSM_FLUSH_VIDEO; \ } \ if (actions.toDoActions & RM_PSM_FIRST_PTS) { \ RMDBGLOG((ENABLE, "firstPTS\n")); \ context.FirstSystemTimeStamp = TRUE; \ actions.toDoActions &= ~RM_PSM_FIRST_PTS; \ } \ if (actions.toDoActions & RM_PSM_RESYNC_TIMER) { \ RMDBGLOG((ENABLE, "resyncTimer\n")); \ context.ResyncTimer = TRUE; \ actions.toDoActions &= ~RM_PSM_RESYNC_TIMER; \ } \ if (actions.performedActions & RM_PSM_VIDEO_STOPPED) { \ RMDBGLOG((ENABLE, "video stopped\n")); \ context.video_decoder_initialized = FALSE; \ context.initVideo = TRUE; \ actions.performedActions &= ~RM_PSM_VIDEO_STOPPED; \ } \ if (actions.performedActions & RM_PSM_STC_STOPPED) { \ RMDBGLOG((ENABLE, "stc stopped\n")); \ context.isSTCRunning = FALSE; \ actions.performedActions &= ~RM_PSM_STC_STOPPED; \ } \ if ((RM_PSM_GetState(context.PSMcontext, &(context.dcc_info)) == RM_PSM_Stopped) && (actions.cmdProcessed)) { \ RMDBGLOG((ENABLE,"Got stop command\n")); \ if (release) \ RUAReleaseBuffer(pDMA, buf); \ context.video_decoder_initialized = FALSE; \ context.initVideo = TRUE; \ byte_counter = 0; \ goto mainloop_no_seek; \ } \ if ((actions.cmd == RM_QUIT) && (!actions.cmdProcessed)) { \ RMDBGLOG((ENABLE, "Got quit command\n")); \ if (release) \ RUAReleaseBuffer(pDMA, buf); \ goto cleanup; \ } \ if ((actions.cmd == RM_STOP_SEEK_ZERO) && (!actions.cmdProcessed)) { \ RMDBGLOG((ENABLE,"Got stop seek zero command\n")); \ Stop(&context, RM_DEVICES_VIDEO | RM_DEVICES_STC); \ RM_PSM_SetState(context.PSMcontext, &(context.dcc_info), RM_PSM_Stopped); \ if (release) \ RUAReleaseBuffer(pDMA, buf); \ context.video_decoder_initialized = FALSE; \ context.initVideo = TRUE; \ goto mainloop; \ } \} while(0)static void show_usage(char *progname){ show_playback_options(); show_display_options(); show_video_options(); fprintf(stderr, "--------------------------------\n"); fprintf(stderr, "Minimum cmd line: %s <file name>\n", progname); fprintf(stderr, "--------------------------------\n"); exit(1);}static void parse_cmdline(int argc, char *argv[]){ int i; RMstatus err; if (argc < 2) show_usage(argv[0]); i = 1; while ((argc > i)) { if (argv[i][0] != '-') { if (play_opt->filename == NULL) { play_opt->filename = argv[i]; i++; } else show_usage(argv[0]); } else { err = parse_playback_cmdline(argc, argv, &i, play_opt); if (err == RM_ERROR) show_usage(argv[0]); if (err != RM_PENDING) continue; err = parse_display_cmdline(argc, argv, &i, disp_opt); if (err == RM_ERROR) show_usage(argv[0]); if (err != RM_PENDING) continue; err = parse_video_cmdline(argc, argv, &i, video_opt); if (RMFAILED(err)) show_usage(argv[0]); } } if (play_opt->filename == NULL) show_usage(argv[0]);}static RMstatus WaitForEOS(struct struct_context *pSendContext, struct RM_PSM_Actions *pActions){ RMuint32 eos_bit_field = 0; if (pSendContext == NULL || pActions == NULL) return RM_ERROR; NTimes++; fprintf(stderr, "File ready %ld times, waiting for EOS\n", NTimes); eos_bit_field |= EOS_BIT_FIELD_VIDEO; return WaitForEOSWithCommand(pSendContext->PSMcontext, &(pSendContext->dcc_info), pActions, eos_bit_field);}static RMstatus Stop(struct struct_context *pSendContext, RMuint32 devices){ RMstatus err = RM_OK; if (devices & RM_DEVICES_STC) { RMDBGLOG((ENABLE, "STOP: stc\n")); DCCSTCStop(pSendContext->dcc_info->pStcSource); pSendContext->isSTCRunning = FALSE; } if (devices & RM_DEVICES_VIDEO) { if (pSendContext->dcc_info->pVideoSource) { RMDBGLOG((ENABLE, "STOP: video decoder\n")); err = DCCStopVideoSource(pSendContext->dcc_info->pVideoSource, DCCStopMode_LastFrame); if (RMFAILED(err)){ RMDBGLOG((ENABLE, "Error stopping video source %d\n", err)); return err; } pSendContext->video_decoder_initialized = FALSE; pSendContext->FirstSystemTimeStamp = TRUE; pSendContext->initVideo = TRUE; } } return err;}static RMstatus Play(struct struct_context * pSendContext, RMuint32 devices, enum DCCVideoPlayCommand mode){ RMstatus err = RM_OK; if (devices & RM_DEVICES_STC) { RMDBGLOG((ENABLE, "PLAY: stc\n")); DCCSTCPlay(pSendContext->dcc_info->pStcSource); } if (devices & RM_DEVICES_VIDEO) { if (pSendContext->dcc_info->pVideoSource) { if (pSendContext->initVideo) { /*(!pSendContext->video_decoder_initialized) {*/ RMbool keep_sequence = TRUE; RMDBGLOG((ENABLE, "PLAY: initDecoder\n")); err = RUASetProperty(pSendContext->dcc_info->pRUA, pSendContext->dcc_info->video_decoder, RMVideoDecoderPropertyID_StorePreviousVideoHeader, &keep_sequence, sizeof(keep_sequence), 0); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Error setting video decoder to keep sequence header on Stop %d\n", err)); return err; } pSendContext->video_decoder_initialized = TRUE; pSendContext->initVideo = FALSE; } RMDBGLOG((ENABLE, "PLAY: video decoder %s\n", (mode == DCCVideoPlayIFrame ? "(iframe)":""))); err = DCCPlayVideoSource(pSendContext->dcc_info->pVideoSource, mode); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Cannot play video decoder %d\n", err)); return err; } } } return err;}#ifdef ABCDRM_MODEL3static RMstatus start_abcdrm(struct RUA *pInstance, RMuint32 BtsFIFO){ RMstatus err; /* Initialize global state variables */ abcdrm_base_addr = 0; abcdrm_init_flag = FALSE; /* Allocate a temporary RUA buffer */ abcdrm_base_addr = RUAMalloc(pInstance, 0, RUA_DRAM_UNPROTECTED, ABCDRM_XRPC_SIZE); if (abcdrm_base_addr == 0) { RMDBGLOG((ENABLE, "RUAMalloc failed\n")); return RM_ERROR; } /* Initialize the ABCDRM shared library and xtask */#ifdef WITH_DRM_PRELOAD_XTASK /* Assumes ruaxrpc -xload xtask_drm_abcdrm.xload into image slot 0 */ err = abcdrm_initialize_with_preload(abcdrm_base_addr, ABCDRM_XRPC_SIZE, ABCDRM_SERIAL_FLASH_SECTOR, 0);#else err = abcdrm_initialize(abcdrm_base_addr, ABCDRM_XRPC_SIZE, ABCDRM_SERIAL_FLASH_SECTOR);#endif if (RMFAILED(err)) { RMDBGLOG((ENABLE, "abcdrm_initialize failed %s\n", RMstatusToString(err))); return err; } /* ABCDRM has been initialized successfully */ abcdrm_init_flag = TRUE; /* Set pointer to Eraser FIFO control structure */ err = abcdrm_set_eraser(BtsFIFO); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "abcdrm_set_eraser failed %s\n", RMstatusToString(err))); return err; } return err;}static void stop_abcdrm(struct RUA *pInstance){ /* Terminate the ABCDRM xtask and shared library */ if (abcdrm_init_flag == TRUE) abcdrm_terminate(); /* Free temporary RUA buffer */ if (abcdrm_base_addr != 0) RUAFree(pInstance, abcdrm_base_addr); /* Reset global state variables */ abcdrm_base_addr = 0; abcdrm_init_flag = FALSE;}#endif // ABCDRM_MODEL3/* highspeed iframe mode works only when using STC timers */#define MEAN_DEPTH 7#define DIVERGENCE_TRIGGER 10int main(int argc, char *argv[]){ /*for MONO compatibility, always access these variables through the global pointers*/ struct playback_cmdline playback_options; /*access through play_opt*/ struct display_cmdline display_options;/*not accessible*/ struct video_cmdline video_options; /*access through video_opt*/ struct display_context disp_info; struct dh_context dh_info = {0,}; struct DCCVideoSource *pVideoSource = NULL; struct RUABufferPool *pDMA = NULL; RMstatus err; RMfile file = NULL; static struct dcc_context dcc_info = {0,}; RMuint32 videoscaler_id = 0; struct RM_PSM_Context PSMContext; RMuint32 byte_counter; struct struct_context context = {0,}; play_opt = &playback_options; disp_opt = &display_options; video_opt = &video_options; dcc_info.disp_info = &disp_info; init_display_options(disp_opt); init_playback_options(play_opt); init_video_options(video_opt); video_opt->display_cc = TRUE; disp_opt->dh_info = &dh_info; parse_cmdline(argc, argv); err = RUACreateInstance(&(dcc_info.pRUA), play_opt->chip_num); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Error creating RUA instance! %d\n", err)); return -1; } err = DCCOpen(dcc_info.pRUA, &(dcc_info.pDCC)); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Error Opening DCC! %d\n", err)); return -1; } err = DCCInitMicroCodeEx(dcc_info.pDCC, disp_opt->init_mode); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Cannot initialize microcode %d\n", err)); return -1; } dcc_info.chip_num = play_opt->chip_num; dcc_info.route = DCCRoute_Main; err = apply_playback_options(&dcc_info, play_opt); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Cannot set playback options %d\n", err)); return -1; } { // open first stc module struct DCCStcProfile stc_profile; stc_profile.STCID = 0; stc_profile.master = Master_STC; stc_profile.stc_timer_id = 0; stc_profile.stc_time_resolution = 90000; stc_profile.video_timer_id = 1; stc_profile.video_time_resolution = 90000; stc_profile.video_offset = 0; stc_profile.audio_timer_id = NO_TIMER; stc_profile.audio_time_resolution = 0; stc_profile.audio_offset = 0; err = DCCSTCOpen(dcc_info.pDCC, &stc_profile, &dcc_info.pStcSource); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Cannot open stc module %d\n", err)); goto cleanup; } } { struct DCCXVideoProfile video_profile; enum EMhwlibVideoCodec vcodec;#ifdef ABCDRM_MODEL3 video_profile.ProtectedFlags = EMHWLIB_USE_ERASER_FIFO;#else // ABCDRM_MODEL3 video_profile.ProtectedFlags = 0; #endif // ABCDRM_MODEL3 video_profile.BitstreamFIFOSize = VIDEO_FIFO_SIZE; video_profile.XferFIFOCount = XFER_FIFO_COUNT; video_profile.PtsFIFOCount = 180; video_profile.InbandFIFOCount = 16; video_profile.XtaskInbandFIFOCount = 0; video_profile.VideoDecoderID = 0; video_profile.SPUBitstreamFIFOSize = 0; video_profile.SPUXferFIFOCount = 0; video_profile.STCID = 0; /* set codec based on command line options either "-pv" or "-vcodec" */ if (video_opt->vcodec_max_width) { video_profile.Codec = video_opt->vcodec; video_profile.Profile = video_opt->vcodec_profile; video_profile.Level = video_opt->vcodec_level; video_profile.MaxWidth = video_opt->vcodec_max_width; video_profile.MaxHeight = video_opt->vcodec_max_height; } else { err = video_profile_to_codec(video_opt->Codec, &video_profile.Codec,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -