📄 play_mosaic.c
字号:
config.canvas_profile.Width = mosaic_width; config.canvas_profile.Height = mosaic_height; smx = RMSMXOpen(&config); if(smx == NULL){ fprintf(stderr, "Cannot open the softmixer %d\n", err); return -1; } event_list[0].ModuleID = DisplayBlock; event_list[0].Mask = EMHWLIB_DISPLAY_EVENT_ID(config.canvas_scaler); } PSMcontext.validPSMContexts = task_count; PSMcontext.currentActivePSMContext = 0; PSMcontext.keyflags = KEYFLAGS; for (i=0; i< task_count; i++) { struct DCCStcProfile stc_profile; fprintf(stderr, "****************** open video %lx/%lx: instance = %lx ******************\n", i+1, task_count, task_list[i].id); play_opt = &playback_options[i]; video_opt = &video_options[i]; disp_opt = &display_options[i]; task_list[i].pDMA = NULL; task_list[i].buf = NULL; task_list[i].buffer_used = FALSE; task_list[i].file = NULL; task_list[i].byte_counter = 0; task_list[i].smx_eos_wait = FALSE; task_list[i].send_info.ValidFields = 0; dcc_info[i].RM_PSM_commands = RM_PSM_ENABLE_PLAY; dcc_info[i].RM_PSM_commands |= RM_PSM_ENABLE_STOP; dcc_info[i].RM_PSM_commands |= RM_PSM_ENABLE_PAUSE; dcc_info[i].RM_PSM_commands |= RM_PSM_ENABLE_SPEED; err = apply_playback_options(&dcc_info[i], play_opt); if (RMFAILED(err)) { fprintf(stderr, "%lx_Cannot set playback options err=%d\n", task_list[i].id, err); goto cleanup; } /* open stc module */ if (i == 0) { stc_profile.STCID = task_list[i].id; stc_profile.master = Master_STC; stc_profile.stc_timer_id = 2*(task_list[i].id); stc_profile.stc_time_resolution = 90000; stc_profile.video_timer_id = 2*task_list[i].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(pDCC, &stc_profile, &dcc_info[i].pStcSource); if (RMFAILED(err)) { fprintf(stderr, "%lx_Cannot open stc module err=%d\n", task_list[i].id, err); goto cleanup; } } else { dcc_info[i].pStcSource = dcc_info[0].pStcSource; }#if 1 { /* open video decoder using DCCX functions */ struct DCCXVideoProfile video_profile; enum EMhwlibVideoCodec vcodec; video_profile.ProtectedFlags = 0; 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.MpegEngineID = video_opt->MpegEngineID; video_profile.VideoDecoderID = task_list[i].id; video_profile.SPUBitstreamFIFOSize = 0; video_profile.SPUXferFIFOCount = 0; video_profile.STCID = task_list[i].id; /* 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, &video_profile.Profile, &video_profile.Level, &video_profile.ExtraPictureBufferCount, &video_profile.MaxWidth, &video_profile.MaxHeight); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Unknown video decoder codec \n")); goto cleanup; } } /* set the extra pictures after the profile to codec conversion */ video_profile.ExtraPictureBufferCount = video_opt->vcodec_extra_pictures; err = DCCXOpenVideoDecoderSource(pDCC, &video_profile, &dcc_info[i].pVideoSource); if (RMFAILED(err)) { fprintf(stderr, "%lx_Cannot open video decoder err=%d\n", task_list[i].id, err); goto cleanup; } vcodec = video_profile.Codec; err = DCCXSetVideoDecoderSourceCodec(dcc_info[i].pVideoSource, vcodec); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Cannot set video decoder codec %d\n", err)); goto cleanup; } }#else { struct DCCVideoProfile video_profile; video_profile.MPEGProfile = video_opt->MPEGProfile; video_profile.BitstreamFIFOSize = VIDEO_FIFO_SIZE; video_profile.XferFIFOCount = XFER_FIFO_COUNT; video_profile.DemuxProgramID = task_list[i].id; video_profile.MpegEngineID = video_opt->MpegEngineID; video_profile.VideoDecoderID = task_list[i].id; video_profile.SPUBitstreamFIFOSize = 0; video_profile.SPUXferFIFOCount = 0; video_profile.STCID = task_list[i].id; err = DCCOpenVideoDecoderSource(pDCC, &video_profile, &dcc_info[i].pVideoSource); if (RMFAILED(err)) { fprintf(stderr, "%lx_Cannoth open video decoder err=%d\n", task_list[i].id, err); goto cleanup; } err = DCCSetVideoDecoderSourceCodec(dcc_info[i].pVideoSource, video_opt->Codec); if (RMFAILED(err)) { fprintf(stderr, "%lx_Cannot set video decoder codec err=%d\n", task_list[i].id, err); goto cleanup; } }#endif err = DCCGetVideoDecoderSourceInfo(dcc_info[i].pVideoSource, &(dcc_info[i].video_decoder), &(dcc_info[i].spu_decoder), &(dcc_info[i].video_timer)); if (RMFAILED(err)) { fprintf(stderr, "%lx_Error getting video decoder source information err=%d\n", task_list[i].id, err); goto cleanup; } dcc_info[i].SurfaceID = 0; dcc_info[i].state = RM_PLAYING; dcc_info[i].trickmode_id = RM_NO_TRICKMODE; dcc_info[i].seek_supported = FALSE; // apply the fixed vop rate if required err = apply_video_decoder_options(&dcc_info[i], video_opt); if (RMFAILED(err)) { fprintf(stderr, "%lx_Error applying video_decoder_options err=%d\n", task_list[i].id, err); goto cleanup; } /* dmapool must be created after the module open in case we do no copy transfers */ err = RUAOpenPool(pRUA, dcc_info[i].video_decoder, DMA_BUFFER_COUNT, DMA_BUFFER_SIZE_LOG2, RUA_POOL_DIRECTION_SEND, &task_list[i].pDMA); if (RMFAILED(err)) { fprintf(stderr, "%lx_Error cannot open dmapool err=%d\n", task_list[i].id, err); goto cleanup; } task_list[i].file = open_stream(play_opt->filename, RM_FILE_OPEN_READ, 0); if (task_list[i].file == NULL) { fprintf(stderr, "%lx_Cannot open file %s\n", task_list[i].id, play_opt->filename); goto cleanup; } { struct rmsmx_source source; RMuint32 border_width = 2; RMuint32 col, row; row = i / col_no; col = i - row*col_no; fprintf(stderr, "i %ld col %ld row %ld\n", i, col, row); DCCSTCGetModuleId(dcc_info[i].pStcSource, &source.stc_id); source.decoder_id = dcc_info[i].video_decoder;/* task_list[i].smx_thumb_window.x = 560; *//* task_list[i].smx_thumb_window.y = 42; *//* task_list[i].smx_thumb_window.width = 100; *//* task_list[i].smx_thumb_window.height = 75; *//* task_list[i].smx_thumb_window.border_width = 2; *//* task_list[i].smx_thumb_window.border_color = 0xff808080; */ task_list[i].smx_window.x = border_width + col*mosaic_width/col_no; task_list[i].smx_window.y = border_width + row*mosaic_height/row_no; task_list[i].smx_window.width = mosaic_width/col_no - 2*border_width; task_list[i].smx_window.height = mosaic_height/row_no - 2*border_width; task_list[i].smx_window.border_width = border_width; task_list[i].smx_window.border_color = 0xffff8023; fprintf(stderr, "x %ld y %ld w %ld h %ld\n", task_list[i].smx_window.x, task_list[i].smx_window.y, task_list[i].smx_window.width, task_list[i].smx_window.height ); err = RMSMXSetOutputWindow(smx, &(task_list[i].smx_window), i); if(RMFAILED(err)){ fprintf(stderr, "Error while setting the output window\n"); goto cleanup; } RMSMXSetInputSource(smx, &source, i); if(RMFAILED(err)){ fprintf(stderr, "Error while setting the input source\n"); goto cleanup; } } } display_key_usage(KEYFLAGS); RMTermInit(TRUE); // don't allow ctrl-C and the like ... RMSignalInit(NULL, NULL); // ... but catch other termination signals to call RMTermExit() for (i=0; i< task_count; i++) { if (RMSeekFile(task_list[i].file, 0, RM_FILE_SEEK_START) == RM_ERRORSEEKFILE) { fprintf(stderr, "%lx_seeking file to beginning\n", task_list[i].id); goto cleanup; } task_list[i].byte_counter = 0; task_list[i].buf = NULL; if (task_list[i].nTimes) { /* first time in loop no need to stop */ DCCSTCStop(dcc_info[i].pStcSource); err = DCCStopVideoSource(dcc_info[i].pVideoSource, DCCStopMode_LastFrame); if (RMFAILED(err)) { fprintf(stderr, "%lx_Cannot stop video decoder err=%d\n", task_list[i].id, err); goto cleanup; } err = RMSMXFlushSlot(smx, i); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "[%ld] Cannot flush video display fifo err %d\n",i, err)); goto cleanup; } err = RUAResetPool(task_list[i].pDMA); /* needed for no dram copy version on standalone */ if (RMFAILED(err)) { fprintf(stderr, "%lx_Error cannot reset dmapool\n", task_list[i].id); goto cleanup; } } DCCSTCSetSpeed(dcc_info[i].pStcSource, play_opt->speed_N, play_opt->speed_M); err = DCCPlayVideoSource(dcc_info[i].pVideoSource, DCCVideoPlayFwd); if (RMFAILED(err)) { fprintf(stderr, "%lx_Cannot play video decoder %d\n", task_list[i].id, err); goto cleanup; } DCCSTCSetTime(dcc_info[i].pStcSource, 0, 90000); DCCSTCPlay(dcc_info[i].pStcSource); RM_PSM_SetState(&(PSMcontext), pdcc_info, RM_PSM_Playing); } /* we need to refresh once before entering the loop to trigger the next_pictures events * RMSMXRefresh() might return pending here because RMSMXOpen() uses the GFXEngine to draw the * background. RMSMXRefresh() requires the engine not to be busy. */ do{ err = RMSMXRefresh(smx); if(err == RM_PENDING){ struct RUAEvent evt; evt.ModuleID = GFXEngine; evt.Mask = RUAEVENT_COMMANDCOMPLETION; RUAWaitForMultipleEvents(pRUA, &evt, 1, 10000, NULL); } }while(err == RM_PENDING); while (1) { RMuint32 count; struct InbandCommand_type InbandCmd; RMuint32 event_index, nEvents; nEvents = 1; /* the wait for picture event */ for (i=0; i< task_count; i++) { /* check if the task finished */ if(task_list[i].smx_eos_wait) continue; if ((playback_options[i].loop_count == 0) && (playback_options[i].infinite_loop == FALSE)) continue; if(task_list[i].sync_timer){ RMuint64 stc_time64; RMuint32 timescale; task_list[i].sync_timer = FALSE; DCCSTCGetTimeResolution(dcc_info[i].pStcSource, DCC_Video, ×cale); DCCSTCGetTime(dcc_info[i].pStcSource, &stc_time64, timescale); task_list[i].send_info.ValidFields = TIME_STAMP_INFO; task_list[i].send_info.TimeStamp = stc_time64; } if ((task_list[i].buf == NULL) && (task_list[i].buffer_used == FALSE)) { err = RUAGetBuffer(task_list[i].pDMA, &task_list[i].buf, 0); if(err != RM_OK) { /* no buffer prepare to wait */ event_list[nEvents].ModuleID = dcc_info[i].video_decoder; event_list[nEvents].Mask = RUAEVENT_XFER_FIFO_READY; nEvents++; } } if (task_list[i].buf) { if (task_list[i].buffer_used == FALSE) { task_list[i].file_status = RMReadFile(task_list[i].file, task_list[i].buf, (1<<DMA_BUFFER_SIZE_LOG2), &count); task_list[i].buffer_used = TRUE; if (task_list[i].file_status == RM_ERRORREADFILE) { fprintf(stderr, "%lx_Error reading file\n", task_list[i].id); goto cleanup; } if (task_list[i].file_status == RM_ERRORENDOFFILE) { /*fprintf(stderr, "%lx_EndOfFile\n", task_list[i].id);*/ RUAReleaseBuffer(task_list[i].pDMA, task_list[i].buf); task_list[i].buf = NULL; /*send eos inband command */ InbandCmd.Tag = EMhwlibInbandCommand_EOS | INBAND_COMMAND_TYPE_BYTECOUNT | INBAND_COMMAND_NO_COORDINATE | INBAND_COMMAND_ACTION_CONTINUE; RUASetProperty(pRUA, dcc_info[i].video_decoder, RMGenericPropertyID_InbandCommand, &InbandCmd, sizeof(InbandCmd), 0); continue; } } err = RUASendData(pRUA, dcc_info[i].video_decoder, task_list[i].pDMA, task_list[i].buf, count, &(task_list[i].send_info), sizeof(task_list[i].send_info)); if (err == RM_OK) { if(task_list[i].send_info.ValidFields == TIME_STAMP_INFO){ fprintf(stderr, "set video pts to %lld at bc=%ld\n", task_list[i].send_info.TimeStamp, task_list[i].byte_counter); } task_list[i].send_info.ValidFields = 0; task_list[i].byte_counter += count; RUAReleaseBuffer(task_list[i].pDMA, task_list[i].buf); task_list[i].buf = 0; task_list[i].buffer_used = FALSE; } else { event_list[nEvents].ModuleID = dcc_info[i].video_decoder; event_list[nEvents].Mask = RUAEVENT_XFER_FIFO_READY; nEvents++; } } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -