play_asf.c
来自「1. 8623L平台」· C语言 代码 · 共 1,567 行 · 第 1/4 页
C
1,567 行
} } } else { RMDBGLOG((READ_DBG, "read %lu bytes\n", buffersize)); status = RMReadFile(pSendContext->f_bitstream, buffer, buffersize, &count); if (status == RM_OK && pSendContext && pSendContext->asf_packetSize && pSendContext->isContentEncrypted && buffersize != count) { RMDBGLOG((ENABLE, "ERROR: buffersize=%lu, count=%lu, status=%d\n", buffersize, count, (int)status)); count = (count/pSendContext->asf_packetSize)*pSendContext->asf_packetSize; RMDBGLOG((ENABLE,"SOLVE: count=%lu, asf_packet_size=%lu\n", count, pSendContext->asf_packetSize)); // status = RM_ERRORENDOFFILE; } } *bytesRead = count; RMDBGLOG((DISABLE, "buf: %02x %02x %02x %02x %02x %02x %02x %02x \n", buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5], buffer[6], buffer[7])); return status; }#ifdef WITH_MONORMstatus asf_get_video_duration(void *context, RMuint32 *time_sec){ struct asf_context *pSendContext = (struct asf_context *)context; if(pSendContext == NULL) return RM_ERROR; if (!pSendContext->filePropSET) return RM_ERROR; else { if (pSendContext->Duration >= 1000) *time_sec = pSendContext->Duration / 1000; else *time_sec = 0; if (*time_sec == 0) return RM_ERROR; RMDBGLOG((ENABLE, "asf_get_video_duration: %lu s\n", *time_sec)); return RM_OK; }}RMstatus asf_get_playback_position(void *context, RMuint32 *time_sec){ struct asf_context *pSendContext = (struct asf_context *)context; RMstatus err = RM_OK; if(pSendContext == NULL) return RM_ERROR; if (pSendContext->VideoStreamFound) { RMuint64 videoPTS; err = RUAGetProperty(pSendContext->pRUA, pSendContext->dcc_info->SurfaceID, RMGenericPropertyID_CurrentDisplayPTS, &videoPTS, sizeof(videoPTS)); if (err != RM_OK) { RMDBGLOG((ENABLE, "error getting current display pts property, error %lu\n", (RMuint32)err)); return RM_ERROR; } if (pSendContext->video_vop_tir == 90000) videoPTS *= 2; *time_sec = (RMuint32) round_int_div(videoPTS, (RMuint32) pSendContext->video_vop_tir); if (*time_sec == 0) return RM_ERROR; RMDBGLOG((ENABLE, "asf_get_playback_position: %lu s (video)\n", *time_sec)); return RM_OK; } else if (pSendContext->AudioStreamFound) { RMuint32 audioPTS; struct DCCAudioSourceHandle audioHandle; if (pSendContext->dcc_info->pMultipleAudioSource) { err = DCCMultipleAudioSourceGetSingleDecoderHandleForInstance(pSendContext->dcc_info->pMultipleAudioSource, 0, &audioHandle); if (err != RM_OK) return RM_ERROR; err = RUAGetProperty(pSendContext->pRUA, audioHandle.moduleID, RMAudioDecoderPropertyID_CurrentPTS, &audioPTS, sizeof(audioPTS)); if (err != RM_OK) { RMDBGLOG((ENABLE, "error getting current pts property for audio, error %lu\n", (RMuint32)err)); return RM_ERROR; } *time_sec = (RMuint32) round_int_div((RMuint64)audioPTS, (RMuint32) pSendContext->audio_vop_tir); if (*time_sec == 0) return RM_ERROR; RMDBGLOG((ENABLE, "asf_get_playback_position: %lu s (audio only)\n", *time_sec)); return RM_OK; } } return RM_OK;}RMstatus asf_get_audio_languageId(void *context, RMasfdemuxLanguageID * languageID){ struct asf_context *pSendContext = (struct asf_context *)context; if(pSendContext == NULL) return RM_ERROR; if (pSendContext->langPropSET) { if ((languageID) && (languageID->languageIDIndex < MAX_NUMBER_OF_AUDIO_STREAMS)) { RMDBGLOG((ENABLE, "asf_get_audio_languageId: index %lu\n", languageID->languageIDIndex)); languageID->languageIDCount = pSendContext->lang[languageID->languageIDIndex].languageIDCount; languageID->languageIDLength = pSendContext->lang[languageID->languageIDIndex].languageIDLength; languageID->languageID = pSendContext->lang[languageID->languageIDIndex].languageID; return RM_OK; } } return RM_ERROR;}RMstatus asf_get_current_audio_stream(void *context, RMuint32 *stream){ struct asf_context *pSendContext = (struct asf_context *)context; if(pSendContext == NULL) return RM_ERROR; *stream = (RMuint32)pSendContext->audio_stream_index; RMDBGLOG((ENABLE, "asf_get_current_audio_stream: %lu\n", *stream)); return RM_OK;}RMstatus asf_get_audio_stream_count(void *context, RMuint32 *count){ struct asf_context *pSendContext = (struct asf_context *)context; *count = (RMuint32)pSendContext->audioStreams; RMDBGLOG((ENABLE, "asf_get_audio_stream_count: %lu\n", *count)); return RM_OK;}RMstatus asf_get_real_seek_position(void *context, RMuint32 time_sec, RMuint32 *true_time_sec){ struct asf_context *pSendContext = (struct asf_context *)context; RMuint64 position; RMuint32 time = time_sec * 1000; if(pSendContext == NULL) return RM_ERROR; position = RMASFVDemuxSeekToTime(pSendContext->vASFDemux, &time); if (position == 0) { RMDBGLOG((ENABLE, "asf_get_real_seek_position: error seeking\n")); return RM_ERROR; } *true_time_sec = time / 1000; RMDBGLOG((ENABLE, "asf_get_real_seek_position: seek to %lu s will seek to %lu s\n", time_sec, *true_time_sec)); return RM_OK;}#endif //WITH_MONO#ifdef WITH_MONOint main_asf(struct mono_info *mono){#elseint 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;/*access through disp_opt*/ struct video_cmdline video_options; struct audio_cmdline audio_options[MAX_AUDIO_DECODER_INSTANCES]; /*access through audio_opt*/ struct dh_context dh_info = {0,};#endif //WITH_MONO struct asf_context SendContext = {0,}; RMstatus err = RM_OK; RMint32 rc = 0; RMint32 error = 0; struct dcc_context dcc_info = {0,}; struct stream_options_s stream_options; RMuint32 NTimes = 0; struct RMfifo wmapro_fifo; RMuint8 *wmapro_fifo_buffer=NULL; RMuint8 *wmapro_fifo_buffer_original=NULL; struct RM_PSM_Context PSMContext; /* #### Begin DTCP code #### */ struct dtcp_cookie *dtcpCookieHandle = NULL; /* #### End DTCP code #### */ RMDBGLOG((ENABLE, "wmaprofifobuffer @ %p\n" "wmaprofifobufferorig @ %p\n", wmapro_fifo_buffer, wmapro_fifo_buffer_original)); if((err = asf_init(&SendContext,#ifdef WITH_MONO 0, NULL, NULL, NULL, NULL, NULL,#else argc, argv, &playback_options, &display_options, &video_options, audio_options,#endif &stream_options,#ifdef WITH_MONO NULL,#else &dh_info,#endif &PSMContext, &dcc_info,#ifdef WITH_MONO mono,#else NULL,#endif process_key_sub, &wmapro_fifo, &wmapro_fifo_buffer, &wmapro_fifo_buffer_original, dtcpCookieHandle, KEYFLAGS, FALSE)) != RM_OK){ fprintf(stderr, "ERROR WHILE INITIALIZING : %s\n", RMstatusToString(err)); goto exit_with_error; } RMDBGLOG((ENABLE, "wmaprofifobuffer @ %p\n" "wmaprofifobufferorig @ %p\n", wmapro_fifo_buffer, wmapro_fifo_buffer_original));#ifndef WITH_MONO display_key_usage(KEYFLAGS);#endif RM_PSM_SetState(SendContext.PSMcontext, &(SendContext.dcc_info), RM_PSM_Playing); // main do-while do { RMuint8 *buffer = NULL; enum RM_PSM_State PlaybackStatus; if (SendContext.play_opt->start_pause) { RMDBGLOG((ENABLE, "start in pause mode!\n")); /* required, because if we do 'next' the decoder *must* be running */ err = asf_Play(&SendContext, RM_DEVICES_VIDEO, /*DCCVideoPlayIFrame*/DCCVideoPlayFwd); if (RMFAILED(err)) { fprintf(stderr, "Cannot start decoders %d\n", err); goto cleanup; } err = asf_Pause(&SendContext, RM_DEVICES_VIDEO); if (RMFAILED(err)) { fprintf(stderr, "Cannot pause decoders %d\n", err); goto cleanup; } RM_PSM_SetState(SendContext.PSMcontext, &(SendContext.dcc_info), RM_PSM_Paused); } /* do not change PSM state in case there is no start_pause. Otherwise after pressing STOP the application play again immediately */ SendContext.play_opt->start_pause = FALSE; RMDBGLOG((ENABLE, "mainloop\n")); SendContext.IFrameFSMState = RMasfIFrameFSM_Disabled; SendContext.firstIFrame = FALSE; SendContext.video_decoder_initialized = FALSE; SendContext.audio_decoder_initialized = FALSE; SendContext.FirstSystemTimeStamp = TRUE; SendContext.prev_video_media_object_number = -1; SendContext.video_frame_counter = 0; SendContext.VideoByteCounter = 0; SendContext.video_last_pts = 0; SendContext.prev_audio_media_object_number = -1; SendContext.audio_frame_counter = 0; SendContext.AudioByteCounter = 0; SendContext.start_ms = SendContext.play_opt->start_ms; SendContext.isTrickMode = FALSE; SendContext.isIFrameMode = FALSE; SendContext.audioSamplesDropped = FALSE; SendContext.gotoRequest=RMProcess_key_goto_none; if (SendContext.isVC1) { SendContext.getStartCodeBuffer = TRUE; SendContext.addSeqHeader = TRUE; SendContext.addEntryHeader = TRUE; SendContext.addFrameHeader = TRUE; } if (!SendContext.linear_playback) { RMint64 position = 0; /* seek to first packet, at position [headerSize+50] */ RMSeekFile(SendContext.f_bitstream, SendContext.asf_Header_Object_Size+50, RM_FILE_SEEK_START); /* presets the demux to start parsing first packet */ RMASFVDemuxResetState(SendContext.vASFDemux); /* Check current position only if seek is supported */ RMGetCurrentPositionOfFile (SendContext.f_bitstream, &position); RMDBGLOG((ENABLE, "current position %lld\n", position)); } DCCSTCSetTime(dcc_info.pStcSource, SendContext.stc_offset_ms*((RMint64)(SendContext.video_vop_tir/1000)), SendContext.video_vop_tir); DCCSTCSetSpeed(dcc_info.pStcSource, SendContext.play_opt->speed_N, SendContext.play_opt->speed_M); PlaybackStatus = RM_PSM_GetState(SendContext.PSMcontext, &(SendContext.dcc_info)); if ((PlaybackStatus != RM_PSM_Paused) && (PlaybackStatus != RM_PSM_Stopped)) { RMDBGLOG((ENABLE, "setting play state\n")); RM_PSM_SetState(SendContext.PSMcontext, &(SendContext.dcc_info), RM_PSM_Playing); } else { PROCESS_KEY(FALSE, TRUE); update_hdmi(SendContext.dcc_info, SendContext.disp_opt, &(SendContext.audio_opt[0])); } mainloop_seek: RMDBGLOG((ENABLE, "mainloop_seek\n")); if (!SendContext.linear_playback) { // the following call will configure the decoders, after that we can 'pause' them err = asf_Play(&SendContext, RM_DEVICES_AUDIO | RM_DEVICES_VIDEO, DCCVideoPlayFwd); if (err != RM_OK) goto exit_with_error; /* do prebufferization only when in playing state */ if (RM_PSM_GetState(SendContext.PSMcontext, &(SendContext.dcc_info)) == RM_PSM_Playing) { asf_Pause(&SendContext, RM_DEVICES_STC | RM_DEVICES_VIDEO | RM_DEVICES_AUDIO); RM_PSM_SetState(SendContext.PSMcontext, &(SendContext.dcc_info), RM_PSM_Prebuffering); fprintf(stderr, "prebuffering\n"); } } #ifdef WITH_MONO RMDCCInfo(&dcc_info); // pass DCC context to application#endif /* wake up disks if necessary */ switch (SendContext.play_opt->disk_ctrl_state) { case DISK_CONTROL_STATE_DISABLE: case DISK_CONTROL_STATE_RUNNING: break; case DISK_CONTROL_STATE_SLEEPING: if (SendContext.play_opt->disk_ctrl_callback) { RMuint32 poll_count = DISK_CONTROL_MAX_WAKEUP_COUNT;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?