?? play_vdemux.c
字號:
pSendContext->spu_repack_offset = repack_offset; pSendContext->spu_repack_size = repack_size; pSendContext->spu_repack_pts = repack_pts; pSendContext->spu_repack_pts_valid = repack_pts_valid; break; default: RMDBGLOG((ENABLE, "Invalid data type %d\n", dataType)); return; } return_from_callback: return;}static void AC3DTSCallback(RMuint8 numberOfFrameHeaders, RMuint16 firstAccessUnitPointer, void *context){ struct demux_context *pSendContext = (struct demux_context *) context; //RMDBGPRINT((ENABLE, "AC3DTSCallback: firstAccessUnitPointer= %x\n", firstAccessUnitPointer)); pSendContext->audio_first_access_unit_pointer_valid = TRUE; pSendContext->audio_first_access_unit_pointer = firstAccessUnitPointer; return;}static void LPCMCallback(RMuint8 numberOfFrameHeaders, RMuint16 firstAccessUnitPointer, RMuint32 frequency, RMuint8 numberOfChannels, RMvdemuxQuantization quantizationWordLength, void *context){ struct demux_context *pSendContext = (struct demux_context *) context; //RMDBGPRINT((ENABLE, "LPCMCallback: firstAccessUnitPointer= %x\n", firstAccessUnitPointer)); pSendContext->audio_first_access_unit_pointer_valid = TRUE; pSendContext->audio_first_access_unit_pointer = firstAccessUnitPointer; return;}static void aobPcm_callback (RMuint16 firstAccessUnitPointer, RMvdemuxQuantization quantizationGr1, RMvdemuxQuantization quantizationGr2, RMuint32 samplingFreqGr1, RMuint32 samplingFreqGr2, RMuint8 bitShift, RMuint8 channelAssign, void * context){} static void mlp_callback (RMuint16 firstAccessUnitPointer, RMuint8 forwardAUSearchPointer, RMuint8 backwardAUSearchPointer, void *context){}static RMstatus WaitForEOS(struct demux_context *context, struct RM_PSM_Actions *pActions){ RMuint32 eos_bit_field = 0; NTimes++; fprintf(stderr, "File ready %ld times, waiting for EOS\n", NTimes); if (context->video_byte_counter > 0) { eos_bit_field |= EOS_BIT_FIELD_VIDEO; } if (context->audio_byte_counter > 0) { eos_bit_field |= EOS_BIT_FIELD_AUDIO; } return WaitForEOSWithCommand(context->PSMcontext, &(context->dcc_info), pActions, eos_bit_field);}// thread functionvoid *main_vdemux( void * context_data ){ struct display_context disp_info; struct DCCVideoSource *pVideoSource = NULL; struct DCCAudioSource *pAudioSource = NULL; struct RUABufferPool *pDMA = NULL; ExternalRMvdemux demux; struct demux_context context; RMstatus err; RMfile file = NULL; RMuint32 videoscaler_id = 0; RMuint8 *repack_buf = (RMuint8 *) NULL; void **dmabuffer_array = (void **) NULL; RMuint32 dmabuffer_index = 0; RMuint32 error = 0; struct RM_PSM_Context PSMContext; RMMemset(&context, 0, sizeof(struct demux_context)); { struct context_per_task * task = (struct context_per_task *)context_data; dcc_info.disp_info = &disp_info; play_opt = task->play_opt; video_opt = task->video_opt; audio_opt = task->audio_opt; demux_opt = task->demux_opt; disp_opt = task->disp_opt; dcc_info.pRUA = task->pRUA; dcc_info.pDCC = task->dcc_info->pDCC; dcc_info.disp_info = NULL; videoscaler_id = 0; //mono->video_scaler; dcc_info.route = DCCRoute_Main; RMDBGLOG((ENABLE, "created thread play_opt %lx, video_opt %lx, audio_opt %lx, disp_opt %lx, videoscaler %d\n", play_opt, video_opt, audio_opt, demux_opt, videoscaler_id )); RMMemcpy( &dcc_info, task->dcc_info, sizeof( struct dcc_context ) ); pVideoSource = task->dcc_info->pVideoSource; pAudioSource = task->dcc_info->pMultipleAudioSource->AudioSourceHandles[0].pAudioSource; dcc_info.pAudioSource = dcc_info.pMultipleAudioSource->AudioSourceHandles[0].pAudioSource; // the software demux thread has its own demux context with the main thread context.pRUA = dcc_info.pRUA; // share the same rua, however use separate pDMA for transfer context.dcc_info = &dcc_info; // separate copy of dcc context.PSMcontext = &PSMContext; play_opt->prebuf_max = 1*1024*1024; // force a limit on prebuffering context.repack_sample = TRUE; demux_opt->repack_sample = TRUE; } // create software demux if(demux_opt->system_type != RM_SYSTEM_UNKNOWN) { err = RMCreateVdemux(&demux); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Cannot create demux %d\n", err)); goto exit_with_error; } //RMvdemuxSetType(demux, demux_opt->system_type); RMvdemuxSetType(demux, RM_SYSTEM_MPEG2_TRANSPORT); RMDBGLOG((ENABLE, "Cannot set system type %d. ", err, demux_opt->system_type )); RMDBGLOG((ENABLE, "Force system type to %d\n", err, RM_SYSTEM_MPEG2_TRANSPORT )); RMvdemuxSetCallbackData(demux, PESCallback, &context); RMvdemuxSetAudioCallbacks(demux, AC3DTSCallback, LPCMCallback, aobPcm_callback, mlp_callback); } else { demux = (ExternalRMvdemux)NULL; RMDBGLOG((ENABLE, "System Type Unknown, exiting\n")); err = RM_ERROR; goto exit_with_error; } dcc_info.chip_num = play_opt->chip_num; RMDBGLOG((ENABLE, "disk_ctrl_low_level %d, disk_ctrl_log2_block_size %d, disk_ctrl_max_mem %d \n", (int)play_opt->disk_ctrl_low_level, (int)play_opt->disk_ctrl_log2_block_size, (int)play_opt->disk_ctrl_max_mem )); /* if HD control is enabled and mode is auto, setup parameters */ if ((play_opt->disk_ctrl_low_level) && (play_opt->disk_ctrl_log2_block_size) && (play_opt->disk_ctrl_max_mem)) { RMuint32 bufferSize = 0; RMuint32 bufferCount = 0; RMuint32 log2BlockSize = play_opt->disk_ctrl_log2_block_size; RMuint32 maxBufferingMem = play_opt->disk_ctrl_max_mem; bufferSize = (1 << log2BlockSize); bufferCount = maxBufferingMem >> log2BlockSize; play_opt->dmapool_count = bufferCount; play_opt->dmapool_log2size = log2BlockSize; if (play_opt->disk_ctrl_low_level >= bufferCount) play_opt->disk_ctrl_low_level = bufferCount >> 1; video_opt->fifo_size = 4 * (1024 * 1024); audio_opt->fifo_size = 2 * (1024 * 1024); fprintf(stderr, ">> low level %lu => %lu bytes bufferized (+ bitstreamFIFO)\n", play_opt->disk_ctrl_low_level, play_opt->disk_ctrl_low_level * bufferSize); video_opt->xfer_count = (bufferSize / 512) * bufferCount; audio_opt->xfer_count = (bufferSize / 512) * bufferCount; err = setup_disk_control_parameters(&dcc_info, play_opt, audio_opt, video_opt, NULL); if (err != RM_OK) { fprintf(stderr, "Error %d trying to setup HD control params\n", err); goto exit_with_error; } } switch (play_opt->disk_ctrl_state) { case DISK_CONTROL_STATE_DISABLE: break; case DISK_CONTROL_STATE_SLEEPING: case DISK_CONTROL_STATE_RUNNING: dmabuffer_array = (void **) RMMalloc(sizeof(void*) * play_opt->dmapool_count); dmabuffer_index = 0; if (dmabuffer_array == NULL) { RMDBGLOG((ENABLE, "Cannot allocate dmapool array! Disable disk control\n")); play_opt->disk_ctrl_state = DISK_CONTROL_STATE_DISABLE; } break; } // dmapool must be created after the module open in case we do no copy transfers */ RMDBGLOG((ENABLE, "Open pool %lu, %lu 0x%x\n", play_opt->dmapool_count, play_opt->dmapool_log2size, pDMA )); err = RUAOpenPool(dcc_info.pRUA, 0, play_opt->dmapool_count, play_opt->dmapool_log2size, RUA_POOL_DIRECTION_SEND, &pDMA); if (RMFAILED(err)) { RMuint32 poolSize = play_opt->dmapool_count << play_opt->dmapool_log2size; fprintf(stderr, "Error cannot open dmapool %d\n\n" "requested %lu bytes of dmapool (%lu buffers of %lu bytes), make sure you\n" "loaded llad with the right parameters. For example:\n" "max_dmapool_memory_size >= %lu max_dmabuffer_log2_size >= %lu\n\n", err, poolSize, play_opt->dmapool_count, (RMuint32)(1<<play_opt->dmapool_log2size), poolSize, play_opt->dmapool_log2size); goto exit_with_error; } RMDBGLOG((ENABLE, "Opened pool 0x%lx\n", pDMA )); dcc_info.pVideoSource = pVideoSource; dcc_info.pAudioSource = pAudioSource; dcc_info.trickmode_id = RM_NO_TRICKMODE; dcc_info.seek_supported = FALSE; err = DCCGetVideoDecoderSourceInfo(pVideoSource, &(dcc_info.video_decoder), &(dcc_info.spu_decoder), &(dcc_info.video_timer)); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Error getting video decoder source information %d\n", err)); goto exit_with_error; } err = DCCGetAudioDecoderSourceInfo(pAudioSource, &(dcc_info.audio_decoder), &(dcc_info.audio_engine), &(dcc_info.audio_timer)); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Error getting audio decoder source information %d\n", err)); goto exit_with_error; } context.pRUA = dcc_info.pRUA; context.pDMA = pDMA; context.repack_sample = demux_opt->repack_sample; context.enable_spu = enable_spu; context.cmd = 0; context.start_90khz = play_opt->start_ms * 90; context.dcc_info = &dcc_info; context.PSMcontext = &PSMContext; PSMContext.validPSMContexts = 1; PSMContext.currentActivePSMContext = 1; PSMContext.keyflags = KEYFLAGS; file = open_stream( alt_filename, RM_FILE_OPEN_READ, 0); if (file == NULL) { fprintf(stderr, "Cannot open file %s\n", alt_filename); goto exit_with_error; } err = RMSizeOfOpenFile(file, &(context.file_size)); if (err != RM_OK) { RMDBGLOG((ENABLE, "Cannot find file size\n")); context.file_size = (RMint64) -1; } RMDBGLOG((ENABLE, "file: %s, size %llu, duration %llu\n", alt_filename, context.file_size, play_opt->duration / 1000)); if (play_opt->duration) fprintf(stderr, "duration %llu secs\n", play_opt->duration / 1000); dcc_info.RM_PSM_commands = RM_PSM_ENABLE_PLAY; dcc_info.RM_PSM_commands |= RM_PSM_ENABLE_STOP; dcc_info.RM_PSM_commands |= RM_PSM_ENABLE_PAUSE; dcc_info.RM_PSM_commands |= RM_PSM_ENABLE_SPEED; dcc_info.RM_PSM_commands |= RM_PSM_ENABLE_FASTER; dcc_info.RM_PSM_commands |= RM_PSM_ENABLE_SLOWER; dcc_info.RM_PSM_commands |= RM_PSM_ENABLE_NEXTPIC; if ((play_opt->duration > 1000) && (context.file_size > 0)) { RMDBGLOG((ENABLE, "seek and iframe mode enabled\n")); dcc_info.RM_PSM_commands |= RM_PSM_ENABLE_SEEK; dcc_info.RM_PSM_commands |= RM_PSM_ENABLE_IFWD; dcc_info.RM_PSM_commands |= RM_PSM_ENABLE_IRWD; context.dcc_info->seek_supported = TRUE; context.dcc_info->iframe_supported = TRUE; } /* correct pids according to audio codec and system type */ if ((demux_opt->system_type == RM_SYSTEM_MPEG2_DVD) || (demux_opt->system_type == RM_SYSTEM_MPEG2_PROGRAM)) { if (demux_opt->audio_pid == 0) {/* If audio PID==PES ID is not provided by user use audio codec option to detect */ demux_opt->audio_pid = (audio_opt->Codec == AudioDecoder_Codec_MPEG1) ? 0xC0:0xBD; } if (audio_opt->Codec == AudioDecoder_Codec_MPEG1) { if ( demux_opt->audio_pid != (0xC0 + demux_opt->audio_subid)) { RMDBGPRINT((ENABLE, "\n***************** audio_pid audio_subid conflict *****************\n")); RMDBGPRINT((ENABLE, "*** for mpeg audio select either audio_pid, either audio_subid ***\n")); RMDBGPRINT((ENABLE, "******************************************************************\n\n")); } demux_opt->audio_pid = 0xC0 + demux_opt->audio_subid; } } RMTermInit(TRUE); // don't allow ctrl-C and the like ... RMSignalInit(NULL, NULL); // ... but catch other termination signals to call RMTermExit() repack_buf = (RMuint8 *) RMMalloc(1<<DMA_BUFFER_SIZE_LOG2); if (repack_buf == NULL) goto cleanup; do { RMuint8 *buf = NULL; enum RM_PSM_State PlaybackStatus; RMDBGLOG((ENABLE, "do-while\n")); if (play_opt->start_pause) { RMDBGLOG((ENABLE, "start in pause mode!\n")); /* required, because if we do 'next' the decoder *must* be running */ err = Play(&context, RM_DEVICES_VIDEO, DCCVideoPlayFwd); if (RMFAILED(err)) { fprintf(stderr, "Cannot start decoders %d\n", err); goto cleanup; } err = Pause(&context, RM_DEVICES_VIDEO); if (RMFAILED(err)) { fprintf(stderr, "Cannot pause decoders %d\n", err); goto cleanup; } RM_PSM_SetState(context.PSMcontext, &(context.dcc_info), RM_PSM_Paused); } else RM_PSM_SetState(context.PSMcontext, &(context.dcc_info), RM_PSM_Playing); play_opt->start_pause = FALSE; mainloop: RMDBGLOG((ENABLE, "mainloop\n")); file_offset = 0; err = RMSeekFile(file, start_file_position, RM_FILE_SEEK_START); if (err != RM_OK) { RMDBGLOG((ENABLE, "Error seeking file to beginning %d\n", err)); goto cleanup; } { struct EMhwlibDisplayTimeInterval time_interval; time_interval.Mode = EMhwlibDisplayIntervalMode_Start; time_interval.StartPTSLo = (RMuint32)(start_time_stamp); time_interval.StartPTSHi = (RMuint32)(start_time_stamp>>32); time_interval.EndPTSLo = 0; time_interval.EndPTSHi = 0; while( (err = RUASetProperty(context.dcc_info->pRUA, context.dcc_info->SurfaceID, RMGenericPropertyID_DisplayTimeInterval, &(time_interval), sizeof(time_interval), 0)) == RM_PENDING ) ; if (RMFAILED(err) && (err != RM_INVALIDMODE)) { RMDBGLOG((ENABLE, "Cannot set time interval\n")); goto cleanup; } RMDBGLOG((ENABLE, "Time Interval: %d, 0x%lx%lx\n", time_interval.Mode, time_interval.StartPTSHi, time_interval.StartPTSLo)); } mainloop_no_seek: RMDBGLOG((ENABLE, "mainloop_noseek\n")); if (actions.cmd == RM_SEEK) { RMint64 seek_pos; seek_pos = (dcc_info.seek_time * context.file_size * 1000) / (play_opt->duration); RMDBGLOG((ENABLE, "seeking to %lu s, pos %llu\n", dcc_info.seek_time, seek_pos)); if (RMSeekFile(file, seek_pos, RM_FILE_SEEK_START) != RM_OK) { RMDBGLOG((ENABLE, "Error: seeking file to position %lu s, %lld kB\n", dcc_info.seek_time, seek_pos/1024)); goto cleanup; } } context.FirstSystemTimeStamp = TRUE; context.ResumeFromTrickMode = FALSE; context.audio_byte_counter = 0; context.video_byte_counter = 0; context.audio_repack_buf = (RMuint8 *) NULL; context.video_repack_buf = (RMuint8 *) NULL; context.spu_repack_buf = (RMuint8 *) NULL; context.audio_repack_offset = 0; context.video_repack_offset = 0; context.spu_repack_offset = 0; context.audio_repack_size = 0; context.video_repack_size = 0;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -