📄 fileplayer.c
字号:
duration = pSendContext->Duration; hour = duration / (3600 * 1000); duration -= (hour * 3600 * 1000); min = duration / (60 * 1000); duration -= min * 60 * 1000; sec = duration / 1000; duration -= sec * 1000; milisec = duration; RMDBGLOG((ENABLE, ">>> Duration %ldh %ldm %lds %ldms\n", (RMuint32)hour, (RMuint32)min, (RMuint32)sec, (RMuint32)milisec)); RMDBGLOG((ENABLE, "\tCreation Data = %llu\n", Creation_Date)); RMDBGLOG((ENABLE, "\tFile Size = %llu %s %s\n", File_Size, ((Broadcast) ? "[Broadcast (play and send duration invalid!)]":""), ((Seekable) ? "[Seekable]":""))); RMDBGLOG((ENABLE, "\tData Packets Count = %llu\n", Data_Packets_Count)); }static void detect_asf_duration_drm_callback(void *context, RMuint8 *Secret_Data, RMuint32 Partial_Secret_Data_Length, RMuint32 Secret_Data_Length, RMuint8 *Key_ID, // ASCII char RMuint32 Partial_Key_ID_Length, RMuint32 Key_ID_Length, RMuint8 *License_URL, // ASCII char RMuint32 Partial_License_URL_Length, RMuint32 License_URL_Length){ /* if we don't set an application defined callback, the default one will be used. the default callback initialises the DRM libraries; we want to prevent that so we use dummy callbacks */ RMDBGLOG((ENABLE, "DRM CALLBACK, content is probably encrypted!\n")); return; }static void detect_asf_duration_extContentEncryption_callback(void *context, RMuint8 *Data, RMuint32 Partial_Data_Size, RMuint32 Data_Size){ /* if we don't set an application defined callback, the default one will be used. the default callback initialises the DRM libraries; we want to prevent that so we use dummy callbacks */ RMDBGLOG((ENABLE, "Extended DRM CALLBACK, content is probably encrypted!\n")); return; }static void detect_asf_parameters_audio_stream_properties_callback(void *context, unsigned char Stream_Number, unsigned short Codec_ID, unsigned short Number_of_Channels, unsigned long Samples_Per_Second, unsigned long Average_Number_of_Bytes_Per_Second, unsigned short Block_Alignment, unsigned short Bits_Per_Sample, unsigned char *Codec_Specific_Data, unsigned long Partial_Codec_Specific_Data_Size, unsigned long Codec_Specific_Data_Size) { struct detect_asf_context *pSendContext = (struct detect_asf_context *) context; pSendContext->samplingFrequency = Samples_Per_Second; RMDBGLOG((ENABLE, ">>> sampling frequency %lu Hz\n", pSendContext->samplingFrequency)); }static RMstatus detect_asf_parameters(RMfile fileHandle, struct detect_asf_context *DetectContext){ RMstatus err = RM_OK; RMuint64 position; DetectContext->vASFDemux = NULL; RMDBGLOG((ENABLE, "begin asf parameters detection\n")); RMDBGLOG((ENABLE, "create asf demux\n")); err = RMCreateASFVDemux(&(DetectContext->vASFDemux)); if (err != RM_OK) { fprintf(stderr, "error creating demux\n"); return err; } err = RMASFVDemuxInit(DetectContext->vASFDemux, DetectContext); if (err != RM_OK) { fprintf(stderr, "error during demux init\n"); return err; } err = RMASFVDemuxSetCallbacks(DetectContext->vASFDemux, NULL, detect_asf_parameters_file_properties_callback, NULL, NULL, detect_asf_parameters_audio_stream_properties_callback, NULL, detect_asf_duration_drm_callback, detect_asf_duration_extContentEncryption_callback, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); if (err != RM_OK) { fprintf(stderr, "error registering callbacks\n"); return err; } /* Check current position only if seek is supported */ RMGetCurrentPositionOfFile(fileHandle, (RMint64*)&position); RMDBGLOG((ENABLE, "current position %lld\n", position)); err = RMASFVDemuxBuildIndexWithHandle(DetectContext->vASFDemux, fileHandle, &(DetectContext->packetSize), &(DetectContext->headerObjectSize)); /* seek to first packet, at position [headerSize+50] */ RMSeekFile(fileHandle, position, RM_FILE_SEEK_START); /* Check current position only if seek is supported */ RMGetCurrentPositionOfFile(fileHandle, (RMint64*)&position); RMDBGLOG((ENABLE, "current position %lld\n", position)); if (DetectContext->vASFDemux) { RMDBGLOG((ENABLE, "delete demux\n")); RMDeleteASFVDemux(DetectContext->vASFDemux); } return RM_OK;}struct parse_avi_context { RMaviPushHandle pAvi; RMbool packed; RMuint32 version; RMuint32 build;};#define PARSE_AVI_BUF_SIZE 4096static void avi_demux_callback (RMuint8 chunkid[4], RMuint8 *chunk, RMuint32 chunkLength, RMuint32 flags, void *context){ RMuint32 i; struct parse_avi_context *pContext = (struct parse_avi_context*)context; if ((chunkid[2] == 'd') && ((chunkid[3] == 'c') || (chunkid[3] == 'b'))){ //RMDBGLOG((ENABLE, "video chunk, size %lu\n", chunkLength)); if (chunkLength > 3) { for (i = 0; i < chunkLength - 3; i++) { if ((chunk[i] == 'D') && (chunk[i+1] == 'i') && (chunk[i+2] == 'v') && (chunk[i+3] == 'X')) { int parsed, build, version; char packed; RMuint32 j = 0; RMDBGPRINT((ENABLE, "\n")); while((chunk[i+j] >= 32) && (chunk[i+j] <= 126)) { RMDBGPRINT((ENABLE, "%c", chunk[i+j])); j++; } RMDBGPRINT((ENABLE, "\n")); parsed = sscanf((char *)&chunk[i], "DivX%dBuild%d%c", &version, &build, &packed); if (parsed < 2) parsed = sscanf((char *)&chunk[i], "DivX%db%d%c", &version, &build, &packed); if ((parsed == 3) && (packed == 'p')) { pContext->packed = TRUE; } pContext->version = (RMuint32)version; pContext->build = (RMuint32)build; RMDBGLOG((ENABLE, "parsed %lu, version %lu, build %lu, packed '%c'\n", (RMuint32)parsed, (RMuint32)version, (RMuint32)build, packed)); } } } } else if ((chunkid[2] == 'w') && (chunkid[3] == 'b')){ RMDBGLOG((DISABLE, "audio, size %lu\n", chunkLength)); }}static RMstatus parse_avi(RMfile fileHandle, struct parse_avi_context *avi_info){ RMuint8 buf[PARSE_AVI_BUF_SIZE]; RMuint32 parsed_bytes = 0, max_parsed_bytes; RMuint32 buf_size = PARSE_AVI_BUF_SIZE; RMuint32 movi_offset, movi_size; RMstatus err = RM_OK; RMDBGLOG((ENABLE, "enter parse_avi\n")); err = RMAviPushOpenExternal(fileHandle, &(avi_info->pAvi)); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Error opening avi file\n")); goto exit; } err = RMAviPushGetMoviOffset(avi_info->pAvi, &movi_offset); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Cannot get movi offset\n")); goto exit; } err = RMAviPushGetMoviSize(avi_info->pAvi, &movi_size); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Cannot get movi size\n")); goto exit; } err = RMSeekFile(fileHandle, movi_offset, RM_FILE_SEEK_START); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Error seeking file to movi\n")); goto exit; } RMAviPushInitDemuxMovi (avi_info->pAvi, avi_demux_callback, NULL); max_parsed_bytes = RMmin(1024*1024, movi_size/4); while(parsed_bytes < max_parsed_bytes){ RMuint32 count; err = RMReadFile(fileHandle, buf, buf_size, &count); if (RMFAILED(err)) { break; } RMAviPushDemuxMovi(avi_info->pAvi, buf, count, (void*)avi_info); parsed_bytes += count; } exit: if (avi_info->pAvi != NULL) { err = RMAviPushClose(avi_info->pAvi); avi_info->pAvi = NULL; } RMDBGLOG((ENABLE, "exit parse_avi\n")); return err; return RM_OK;}RMstatus rfp_open_file(struct mono_info *app_params, struct rfp_stream_info *stream_info, struct rfp_file *pfile){ /* the passed *stream_info could be NULL... */ struct rfp_stream_info stream_info_loc; struct playback_cmdline *play_opt = app_params->play_opt; pfile->file = (RMfile) NULL; if(stream_info == NULL){ stream_info = &stream_info_loc; } stream_info->system_type = RM_SYSTEM_UNKNOWN; stream_info->audio_type = eAudioFormat_UNKNOWN; stream_info->video_type = RM_VIDEO_UNKNOWN; /* #### Begin CARDEA code #### */ { if ( find_cardea_url(play_opt->filename) != NULL ) { RMDBGLOG((ENABLE, "Playing cardea file, skip detection ... (only ASF supported).\n")); stream_info->system_type = RM_SYSTEM_ASF; return RM_OK; } } /* #### End CARDEA code #### */ /* open the stream */ pfile->file = open_stream(play_opt->filename, RM_FILE_OPEN_READ, &app_params->stream_opts); if (pfile->file == NULL) { RMDBGLOG((ENABLE, "Cannot open file %s\n", play_opt->filename)); goto open_error; } return RM_OK; open_error: rfp_close_file(pfile); return RM_ERROR;}RMstatus rfp_close_file(struct rfp_file *pfile){ if (pfile->file) RMCloseFile(pfile->file); return RM_OK;}RMstatus rfp_detect(struct mono_info *app_params, struct rfp_detect_options *detect_opt, enum rfp_application *app, struct rfp_stream_info *stream_info){ struct rfp_file rfpfile; RMstatus err; /* the passed *stream_info could be NULL... */ struct rfp_stream_info stream_info_loc;#ifndef NDEBUG struct playback_cmdline *play_opt = app_params->play_opt;#endif if(stream_info == NULL){ stream_info = &stream_info_loc; } err = rfp_open_file(app_params, stream_info, &rfpfile); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Cannot open File %s\n", play_opt->filename)); return err; } if (stream_info->system_type == RM_SYSTEM_ASF) { *app = get_app_from_stream_info(stream_info); /* In this case file is not open */ err = RM_OK; } else { err = rfp_detect_open_file(rfpfile.file, app_params, detect_opt, app, stream_info); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Cannot detect file %s\n", play_opt->filename)); } err = rfp_close_file(&rfpfile); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Cannot close file %s\n", play_opt->filename)); } } return err; }RMstatus rfp_detect_open_file(RMfile file, struct mono_info *app_params, struct rfp_detect_options *detect_opt, enum rfp_application *app, struct rfp_stream_info *stream_info){ RMstatus err; RMdetectorHandle detector = NULL; RMFDetector_type type; RMuint32 frequency = 0, channel_count = 0, bitrate = 0; RMint64 file_size = 0; RMbool detected; RMint32 error = 0; struct playback_cmdline *play_opt = app_params->play_opt; struct video_cmdline *video_opt = app_params->video_opt; struct audio_cmdline *audio_opt = app_params->audio_opt; struct demux_cmdline *demux_opt = app_params->demux_opt; /* give the stream and the filename to the detector */ detector = RMFDetectorCreate(); RMDBGLOG((LOCALDBG, "Created detector handle\n")); RMFDetectOnOpenFile(detector, play_opt->filename, file, &type); switch(type){ case DETECTOR_AUDIO: fprintf(stderr, "audio\n"); err = RMSizeOfOpenFile(file, &file_size); if(RMFAILED(err)) { RMDBGLOG((ENABLE, "Cannot get size of file %s\n", play_opt->filename)); } /* this works because the detector has not been reset */ { struct RM_Detection_Specific_Info specificInfo; eAudioFormat_type detectedAudioType; err = RMFGetDetectedAudioType(detector, &detectedAudioType); if (err != RM_OK) { RMDBGLOG((ENABLE, "error getting detected audio type\n")); } err = RMFGetAudioSpecificInfo(detector, detectedAudioType, &specificInfo); if (err != RM_OK) { RMDBGLOG((ENABLE, "error getting specific information!\n")); ERROR_CLEANUP(-1); } switch (specificInfo.audioType) { case eAudioFormat_PCM: RMDBGLOG((ENABLE, "PCM\n")); bitrate = specificInfo.data.wave.bitrate; frequency = specificInfo.data.wave.sampleRate;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -