📄 play_asf.c
字号:
context->dcc_info->video_decoder, RMVideoDecoderPropertyID_WMV9VSProp, &context->wmv9_prop, sizeof(context->wmv9_prop), 0); if (RMFAILED(err)) { RMDBGLOG((ENABLE,"Error setting WMV9 video info : %d !\n", err)); return RM_ERROR; } break; case 0x41564D57: //WMVA - Windows Media Video 9 Advanced Profile case 0x31435657: //WVC1 RMDBGLOG((ENABLE, "VC1 Advanced Profile\n")); //context->addSeqHeader = TRUE; break; default: fprintf(stderr,"FourCC: 0x%lx not supported !!!\n",context->Compression_ID); return RM_VIDEO_CODEC_NOT_SUPPORTED; } context->video_decoder_initialized = TRUE; } return RM_OK;}static void languagelistcb(void *context, RMuint16 Language_ID_Records_Count, RMuint16 Language_ID_Records_Index, RMuint8 *Language_ID, RMuint8 Partial_Language_ID_Length, RMuint8 Language_ID_Length) { struct asf_context *pSendContext = (struct asf_context *) context; RMDBGLOG((ENABLE, "languagelist called\n")); if( (Language_ID_Length != 0) && (Partial_Language_ID_Length == Language_ID_Length) ) {#ifdef _DEBUG RMuint32 i;#endif pSendContext->lang[Language_ID_Records_Index].languageIDCount = Language_ID_Records_Count; pSendContext->lang[Language_ID_Records_Index].languageIDIndex = Language_ID_Records_Index; if (pSendContext->lang[Language_ID_Records_Index].languageID) RMFree(pSendContext->lang[Language_ID_Records_Index].languageID); pSendContext->lang[Language_ID_Records_Index].languageID = (RMnonAscii *) RMMalloc(Language_ID_Length*sizeof(RMuint8)); RMMemcpy(pSendContext->lang[Language_ID_Records_Index].languageID, Language_ID, Language_ID_Length); pSendContext->lang[Language_ID_Records_Index].languageIDLength = Language_ID_Length; RMDBGLOG((ENABLE,"Language %hu/%hu ->", Language_ID_Records_Index, pSendContext->lang[Language_ID_Records_Index].languageIDCount));#ifdef _DEBUG for(i=0;i<Language_ID_Length;i++) fprintf(stderr, "%c", (RMuint8)pSendContext->lang[Language_ID_Records_Index].languageID[i]); fprintf(stderr, "\n");#endif pSendContext->langPropSET = TRUE; }}static void print_Audio_Stream_Properties(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 asf_context *pSendContext = (struct asf_context *) context; struct RMaudio_parameters *audio_params; if (!pSendContext->SendAudioData) { RMDBGLOG((ENABLE, ">>> audio disabled by cmdline, skip audio detection\n")); return; } // Check stream number if (Stream_Number >= MAX_NUMBER_OF_AUDIO_STREAMS) { RMDBGLOG((ENABLE, "Invalid audio track\n")); return; } if (Codec_Specific_Data_Size > CODEC_SPECIFIC_DATA_MAX_SIZE_BYTES) { RMDBGLOG((ENABLE, ">>> Error Codec_Specific_Data_Size to high (%d>%d)\n", Codec_Specific_Data_Size, Codec_Specific_Data)); return; } pSendContext->WMAPROBitsPacketLength = 0; // Set pointer to current parameters list audio_params = &(pSendContext->audio_parameters[Stream_Number]); // Store partial specific data memcpy( audio_params->Codec_Specific_Data+pSendContext->Audio_Codec_Specific_Data_Received, Codec_Specific_Data, Partial_Codec_Specific_Data_Size); // Update received size, WE SUPPOSE HERE THAT AUDIO HEADERS ARE NOT INTERLEAVED pSendContext->Audio_Codec_Specific_Data_Received += Partial_Codec_Specific_Data_Size; if (pSendContext->Audio_Codec_Specific_Data_Received != Codec_Specific_Data_Size) RMDBGLOG((ENABLE, "########## Received %d bytes on %d bytes for stream %d", pSendContext->Audio_Codec_Specific_Data_Received,Codec_Specific_Data_Size)); // End of data if (pSendContext->Audio_Codec_Specific_Data_Received == Codec_Specific_Data_Size) { RMuint32 cnt; // Store size audio_params->Codec_Specific_Data_Size = pSendContext->Audio_Codec_Specific_Data_Received; RMDBGLOG((ENABLE,"print_Audio_Stream_Properties %lu, %lu, %lu\n", pSendContext->Audio_Codec_Specific_Data_Received, Partial_Codec_Specific_Data_Size, Codec_Specific_Data_Size)); // Reset value for next stream pSendContext->Audio_Codec_Specific_Data_Received = 0; // Store and increments audio streams pSendContext->audioStreamTable[pSendContext->audioStreams++] = Stream_Number; // Print Infos RMDBGLOG((ENABLE, "Stream #%hu - Audio with codec 0x%x\n", Stream_Number,Codec_ID)); RMDBGLOG((ENABLE, " %hu channel(s), %lu samples/second, %hu bits/sample\n", Number_of_Channels, Samples_Per_Second, Bits_Per_Sample)); RMDBGLOG((ENABLE, " Bitrate: %lu bit/s, Block size is 0x%04x bytes [0x%05x bits]\n", Average_Number_of_Bytes_Per_Second * 8, Block_Alignment, Block_Alignment * 8)); // Check that codec is supported for (cnt=0;cnt<(sizeof(RMSupported_codec_list)/sizeof(RMuint32));cnt++) { if (Codec_ID == RMSupported_codec_list[cnt]) break; } // Enable codec only if it is in our supported codecs list if (cnt < (sizeof(RMSupported_codec_list)/sizeof(RMuint32))) { audio_params->enabled = TRUE; // Store codec parameters audio_params->Codec_ID = Codec_ID; audio_params->Number_of_Channels = Number_of_Channels; audio_params->Samples_Per_Second = Samples_Per_Second; audio_params->Average_Number_of_Bytes_Per_Second = Average_Number_of_Bytes_Per_Second; audio_params->Block_Alignment = Block_Alignment; audio_params->Bits_Per_Sample = Bits_Per_Sample; // Set first audio stream as default if (pSendContext->audio_stream_index == -1) pSendContext->audio_stream_index = Stream_Number; } else { RMDBGLOG((ENABLE, " UNSUPPORTED CODEC #\n")); audio_params->enabled = FALSE; } RMDBGLOG((ENABLE, "audioStreamTable[%ld]=%ld\n", pSendContext->audioStreams-1, Stream_Number)); // Pre Setup audio decoders if not done yet if (!pSendContext->AudioStreamFound) { RMstatus status; status = setup_audio_decoder(context); pSendContext->audioSetupStatus = status; if (RMFAILED(status)) { fprintf(stderr, "Error initializing audio (%s)\n", RMstatusToString(status)); pSendContext->SendAudioData = FALSE; return ; } else { RMDBGLOG((ENABLE, ">>> audio stream found, enabling audio playback\n")); pSendContext->AudioStreamFound = TRUE; /* Seek is not supported, do play now */ if (pSendContext->linear_playback) Play(pSendContext, RM_DEVICES_AUDIO | RM_DEVICES_STC, DCCVideoPlayFwd); } } }}static RMuint32 ResyncAudio(struct asf_context *pSendContext, struct emhwlib_info *pInfo){ RMuint64 CurrentSTC; RMuint32 CutSTC; RMuint32 Presentation_Time; // Check that stream is enabled if (pSendContext->audio_parameters[pSendContext->audio_stream_index].enabled != TRUE) return 0; if (pInfo->ValidFields & TIME_STAMP_INFO) Presentation_Time = pInfo->TimeStamp; else return 0; if (!pSendContext->FirstSystemTimeStamp) { //get the time in 1000th units because presentation time from ASF is always in 1/1000 DCCSTCGetTime(pSendContext->dcc_info->pStcSource, &CurrentSTC, 1000); CutSTC = CurrentSTC & 0xffffffff; if( (RMint32)(Presentation_Time - CutSTC) <= 0) { RMDBGLOG((ENABLE, "Current STC = %lld PTS=%lu skipping to resync\n", CurrentSTC, Presentation_Time)); if (pSendContext->isWMAPRO) { pSendContext->audioSamplesDropped = TRUE; RMWMAProVDecoderFlushParser(pSendContext->vDecoder); return RM_SKIP_TO_RESYNC; } } } return 0;}static RMstatus initAudioDecoder(struct asf_context * context){ RMstatus status = RM_ERROR; RMuint32 i; RMuint16 EncoderOptions = 0; RMuint16 wValidBitsPerSample = 0; RMuint32 dwChannelMask = 0; struct RMaudio_parameters *audio_params; RMuint32 codec; // Check that stream is enabled if (context->audio_parameters[context->audio_stream_index].enabled != TRUE) { RMDBGLOG((ENABLE, "Audio channel #%d is disabled, audio init bypassed\n",context->audio_stream_index)); return RM_ERROR; } // Set audio decoder for current stream if (context->audio_decoder_initialized == TRUE) return RM_OK; // Get audio parameters audio_params = &(context->audio_parameters[context->audio_stream_index]); codec = (RMuint32) audio_params->Codec_ID; RMDBGLOG((ENABLE, "initAudioDecoder: Stream %d instance %lu codec 0x%08lx\n",context->audio_stream_index, context->audioInstances, codec)); // Codec specific switch switch (codec) { case 0x161: case 0x7A21: case 0x7A22: { //WMA if (audio_params->Codec_Specific_Data_Size == 10) { // 4 + 2 + 4 RMuint32 dwSamplesPerBlock; dwSamplesPerBlock = (((RMuint32) audio_params->Codec_Specific_Data[3]) << 24) + (((RMuint32) audio_params->Codec_Specific_Data[2]) << 16) + (((RMuint32) audio_params->Codec_Specific_Data[1]) << 8) + ((RMuint32) audio_params->Codec_Specific_Data[0]); EncoderOptions = + (((RMuint16) audio_params->Codec_Specific_Data[5]) << 8) + ((RMuint16) audio_params->Codec_Specific_Data[4]); RMDBGLOG((ENABLE, " Audio codec ID: %04x,\n" " Bits per block: 0x%04x\n" " Encode option: 0x%04x \n", (int) audio_params->Codec_ID, (int) dwSamplesPerBlock, (int) EncoderOptions)); } else { RMDBGLOG((ENABLE, "Error: audio specific data has invalid size (%d)\n", (int) audio_params->Codec_Specific_Data_Size)); context->audio_parameters[context->audio_stream_index].enabled = FALSE; return RM_ERROR; }#ifdef WITH_MONO RMDBGLOG((ENABLE, "set audio codec to WMA\n")); for (i = 0; i < context->audioInstances; i++) context->audio_opt[i].Codec = AudioDecoder_Codec_WMA; context->isWMAPRO = FALSE;#endif break; } case 0x162: { // WMAPro RMstatus err; RMMetaWMAParameters temp_wmaparams; wValidBitsPerSample = + (((RMuint16) audio_params->Codec_Specific_Data[1]) << 8) + ((RMuint16) audio_params->Codec_Specific_Data[0]); dwChannelMask = (((RMuint32) audio_params->Codec_Specific_Data[5]) << 24) + (((RMuint32) audio_params->Codec_Specific_Data[4]) << 16) + (((RMuint32) audio_params->Codec_Specific_Data[3]) << 8) + ((RMuint32) audio_params->Codec_Specific_Data[2]); EncoderOptions = + (((RMuint16) audio_params->Codec_Specific_Data[15]) << 8) + ((RMuint16) audio_params->Codec_Specific_Data[14]); RMDBGLOG((ENABLE, " Audio codec ID: %04x,\n" " %u valid bits/sample, %08X channel mask\n" " 0x%04x encode options\n", (int) audio_params->Codec_ID, (int) wValidBitsPerSample, (int) dwChannelMask, (int) EncoderOptions)); // Get stored values temp_wmaparams.VersionNumber = audio_params->Codec_ID; temp_wmaparams.SamplingFrequency = audio_params->Samples_Per_Second; temp_wmaparams.NumberOfChannels = audio_params->Number_of_Channels; temp_wmaparams.Bitrate = audio_params->Average_Number_of_Bytes_Per_Second * 8; temp_wmaparams.PacketSize = audio_params->Block_Alignment * 8; temp_wmaparams.EncoderOptions = EncoderOptions; temp_wmaparams.BitsPerSample = audio_params->Bits_Per_Sample; temp_wmaparams.WMAProValidBitsPerSample = wValidBitsPerSample; temp_wmaparams.WMAProChannelMask = dwChannelMask; temp_wmaparams.WMAProVersionNumber = 0; //temp_wmaparams.OutputChannels = audio_params->OutputChannels; // Create video decoder only once if(context->vDecoder == (void *)NULL) { RMDBGLOG((ENABLE,"******** using RMF's WMAPRO decoder ********\n")); err = RMCreateWMAProVDecoder(&(context->vDecoder)); if (err != RM_OK) { RMDBGLOG((ENABLE,"error: cant create wmaproVdecoder!\n")); context->audio_parameters[context->audio_stream_index].enabled = FALSE; return RM_ERROR; } err = RMWMAProVDecoderOpen(context->vDecoder); if (err != RM_OK) { RMDBGLOG((ENABLE,"error: cant open wmaproVdecoder!\n")); context->audio_parameters[context->audio_stream_index].enabled = FALSE; return RM_ERROR; } } // Init video decoder if (context->vDecoder != (void *)NULL) { err = RMWMAProVDecoderInit(context->vDecoder, EncoderOptions, temp_wmaparams.PacketSize, &temp_wmaparams); if (err != RM_OK) { RMDBGLOG((ENABLE, "wmaprodecoder init error\n")); context->audio_parameters[context->audio_stream_index].enabled = FALSE; return RM_ERROR; } } else { RMDBGLOG((ENABLE, "calling wmaprodecoder init before open!\n")); context->audio_paramet
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -