/*---------------------------------------------------------------------- | OsxAudioUnitsOutput_Seek +---------------------------------------------------------------------*/ BLT_METHOD OsxAudioUnitsOutput_Seek(BLT_MediaNode* _self, BLT_SeekMode* mode, BLT_SeekPoint* point) { OsxAudioUnitsOutput* self = ATX_SELF_EX(OsxAudioUnitsOutput, BLT_BaseMediaNode, BLT_MediaNode); ComponentResult result; BLT_COMPILER_UNUSED(mode); BLT_COMPILER_UNUSED(point); /* flush the queue */ pthread_mutex_lock(&self->lock); ATX_List_Clear(self->packet_queue); pthread_mutex_unlock(&self->lock); /* reset the device */ result = AudioUnitReset(self->audio_unit, kAudioUnitScope_Input, 0); if (result != noErr) { ATX_LOG_WARNING_1("AudioUnitReset failed (%d)", (int)result); } return BLT_SUCCESS; }
/*---------------------------------------------------------------------- | AlsaOutput_Seek +---------------------------------------------------------------------*/ BLT_METHOD AlsaOutput_Seek(BLT_MediaNode* _self, BLT_SeekMode* mode, BLT_SeekPoint* point) { AlsaOutput* self = ATX_SELF_EX(AlsaOutput, BLT_BaseMediaNode, BLT_MediaNode); BLT_COMPILER_UNUSED(mode); BLT_COMPILER_UNUSED(point); /* ignore unless we're prepared */ if (self->state != BLT_ALSA_OUTPUT_STATE_PREPARED) { return BLT_SUCCESS; } /* reset the device */ AlsaOutput_Reset(self); /* update the media time */ if (point->mask & BLT_SEEK_POINT_MASK_TIME_STAMP) { self->media_time = BLT_TimeStamp_ToNanos(point->time_stamp); self->next_media_time = self->media_time; } else { self->media_time = 0; self->next_media_time = 0; } return BLT_SUCCESS; }
/*---------------------------------------------------------------------- | AlsaOutputModule_Probe +---------------------------------------------------------------------*/ BLT_METHOD AlsaOutputModule_Probe(BLT_Module* self, BLT_Core* core, BLT_ModuleParametersType parameters_type, BLT_AnyConst parameters, BLT_Cardinal* match) { BLT_COMPILER_UNUSED(self); BLT_COMPILER_UNUSED(core); switch (parameters_type) { case BLT_MODULE_PARAMETERS_TYPE_MEDIA_NODE_CONSTRUCTOR: { BLT_MediaNodeConstructor* constructor = (BLT_MediaNodeConstructor*)parameters; /* the input protocol should be PACKET and the */ /* output protocol should be NONE */ if ((constructor->spec.input.protocol != BLT_MEDIA_PORT_PROTOCOL_ANY && constructor->spec.input.protocol != BLT_MEDIA_PORT_PROTOCOL_PACKET) || (constructor->spec.output.protocol != BLT_MEDIA_PORT_PROTOCOL_ANY && constructor->spec.output.protocol != BLT_MEDIA_PORT_PROTOCOL_NONE)) { return BLT_FAILURE; } /* the input type should be unknown, or audio/pcm */ if (!(constructor->spec.input.media_type->id == BLT_MEDIA_TYPE_ID_AUDIO_PCM) && !(constructor->spec.input.media_type->id == BLT_MEDIA_TYPE_ID_UNKNOWN)) { return BLT_FAILURE; } /* the name should be 'alsa:<name>' */ if (constructor->name == NULL || !ATX_StringsEqualN(constructor->name, "alsa:", 4)) { return BLT_FAILURE; } /* always an exact match, since we only respond to our name */ *match = BLT_MODULE_PROBE_MATCH_EXACT; ATX_LOG_FINE_1("probe ok [%d]", *match); return BLT_SUCCESS; } break; default: break; } return BLT_FAILURE; }
/*---------------------------------------------------------------------- | OsxAudioUnitsOutput_QueueItemDestructor +---------------------------------------------------------------------*/ static void OsxAudioUnitsOutput_QueueItemDestructor(ATX_ListDataDestructor* self, ATX_Any data, ATX_UInt32 type) { BLT_COMPILER_UNUSED(self); BLT_COMPILER_UNUSED(type); BLT_MediaPacket_Release((BLT_MediaPacket*)data); }
/*---------------------------------------------------------------------- | CrossFader_OnPropertyChanged +---------------------------------------------------------------------*/ BLT_VOID_METHOD CrossFader_OnPropertyChanged(ATX_PropertyListenerInstance* instance, ATX_CString name, ATX_PropertyType type, const ATX_PropertyValue* value) { /*CrossFader* fader = (CrossFader*)instance;*/ BLT_COMPILER_UNUSED(instance); BLT_COMPILER_UNUSED(type); ATX_LOG_FINE_2("CrossFader::OnPropertyChanged - name=%s val=%d", name ? name : "*", value ? value->integer : 0); }
/*---------------------------------------------------------------------- | FileOutputModule_Probe +---------------------------------------------------------------------*/ BLT_METHOD FileOutputModule_Probe(BLT_Module* self, BLT_Core* core, BLT_ModuleParametersType parameters_type, BLT_AnyConst parameters, BLT_Cardinal* match) { BLT_COMPILER_UNUSED(self); BLT_COMPILER_UNUSED(core); switch (parameters_type) { case BLT_MODULE_PARAMETERS_TYPE_MEDIA_NODE_CONSTRUCTOR: { BLT_MediaNodeConstructor* constructor = (BLT_MediaNodeConstructor*)parameters; /* the input protocol should be STREAM_PUSH and the */ /* output protocol should be NONE */ if ((constructor->spec.input.protocol != BLT_MEDIA_PORT_PROTOCOL_ANY && constructor->spec.input.protocol != BLT_MEDIA_PORT_PROTOCOL_STREAM_PUSH) || (constructor->spec.output.protocol != BLT_MEDIA_PORT_PROTOCOL_ANY && constructor->spec.output.protocol != BLT_MEDIA_PORT_PROTOCOL_NONE)) { return BLT_FAILURE; } /* we need a name */ if (constructor->name == NULL) { return BLT_FAILURE; } /* the name needs to be file:<filename> */ if (!ATX_StringsEqualN(constructor->name, "file:", 5)) { return BLT_FAILURE; } /* always an exact match, since we only respond to our name */ *match = BLT_MODULE_PROBE_MATCH_EXACT; ATX_LOG_FINE_1("FileOutputModule::Probe - Ok [%d]", *match); return BLT_SUCCESS; } break; default: break; } return BLT_FAILURE; }
/*---------------------------------------------------------------------- | BLT_BaseModule_Attach +---------------------------------------------------------------------*/ BLT_DIRECT_METHOD BLT_BaseModule_Attach(BLT_Module* _self, BLT_Core* core) { BLT_COMPILER_UNUSED(_self); BLT_COMPILER_UNUSED(core); #if defined(BLT_DEBUG) { BLT_BaseModule* self = ATX_SELF(BLT_BaseModule, BLT_Module); ATX_LOG_FINE_1("attaching module name=%s", self->info.name?self->info.name:""); } #endif return BLT_SUCCESS; }
/*---------------------------------------------------------------------- | CrossFader_Seek +---------------------------------------------------------------------*/ BLT_METHOD CrossFader_Seek(BLT_MediaNodeInstance* instance, BLT_SeekMode* mode, BLT_SeekPoint* point) { BLT_COMPILER_UNUSED(instance); BLT_COMPILER_UNUSED(mode); BLT_COMPILER_UNUSED(point); /*CrossFader* fader = (CrossFader*)instance;*/ /* flush pending input packets */ /*CrossFaderInputPort_Flush(fader);*/ return BLT_SUCCESS; }
/*---------------------------------------------------------------------- | SilenceRemover_Seek +---------------------------------------------------------------------*/ BLT_METHOD SilenceRemover_Seek(BLT_MediaNode* instance, BLT_SeekMode* mode, BLT_SeekPoint* point) { SilenceRemover* self = (SilenceRemover*)instance; BLT_COMPILER_UNUSED(mode); BLT_COMPILER_UNUSED(point); /* flush the pending packet */ if (self->input.pending) { BLT_MediaPacket_Release(self->input.pending); } self->input.pending = NULL; return BLT_SUCCESS; }
/*---------------------------------------------------------------------- | AacDecoder_Seek +---------------------------------------------------------------------*/ BLT_METHOD AacDecoder_Seek(BLT_MediaNode* _self, BLT_SeekMode* mode, BLT_SeekPoint* point) { AacDecoder* self = ATX_SELF_EX(AacDecoder, BLT_BaseMediaNode, BLT_MediaNode); BLT_COMPILER_UNUSED(mode); BLT_COMPILER_UNUSED(point); /* clear the eos flag */ self->input.eos = BLT_FALSE; /* remove any packets in the output list */ AacDecoderOutput_Flush(self); /* reset the decoder */ if (self->helix_decoder) AACFlushCodec(self->helix_decoder); return BLT_SUCCESS; }
/*---------------------------------------------------------------------- | AlsaOutput_Activate +---------------------------------------------------------------------*/ BLT_METHOD AlsaOutput_Activate(BLT_MediaNode* _self, BLT_Stream* stream) { AlsaOutput* self = ATX_SELF_EX(AlsaOutput, BLT_BaseMediaNode, BLT_MediaNode); BLT_COMPILER_UNUSED(stream); ATX_LOG_FINER("activating output"); /* open the device */ AlsaOutput_Open(self); return BLT_SUCCESS; }
/*---------------------------------------------------------------------- | SdlVideoOutput_GetStatus +---------------------------------------------------------------------*/ BLT_METHOD SdlVideoOutput_GetStatus(BLT_OutputNode* _self, BLT_OutputNodeStatus* status) { SdlVideoOutput* self = ATX_SELF(SdlVideoOutput, BLT_OutputNode); BLT_COMPILER_UNUSED(self); /* default value */ status->media_time.seconds = 0; status->media_time.nanoseconds = 0; return BLT_SUCCESS; }
/*---------------------------------------------------------------------- | CrossFaderOutputPort_QueryMediaType +---------------------------------------------------------------------*/ BLT_METHOD CrossFaderOutputPort_QueryMediaType(BLT_MediaPortInstance* instance, BLT_Ordinal index, const BLT_MediaType** media_type) { BLT_COMPILER_UNUSED(instance); if (index == 0) { *media_type = &BLT_GenericPcmMediaType; return BLT_SUCCESS; } else { *media_type = NULL; return BLT_FAILURE; } }
/*---------------------------------------------------------------------- | PcmAdapterInput_QueryMediaType +---------------------------------------------------------------------*/ BLT_METHOD PcmAdapterInput_QueryMediaType(BLT_MediaPort* self, BLT_Ordinal index, const BLT_MediaType** media_type) { BLT_COMPILER_UNUSED(self); if (index == 0) { *media_type = &BLT_GenericPcmMediaType; return BLT_SUCCESS; } else { *media_type = NULL; return BLT_FAILURE; } }
/*---------------------------------------------------------------------- | DcfParserModule_Probe +---------------------------------------------------------------------*/ BLT_METHOD DcfParserModule_Probe(BLT_Module* _self, BLT_Core* core, BLT_ModuleParametersType parameters_type, BLT_AnyConst parameters, BLT_Cardinal* match) { DcfParserModule* self = ATX_SELF_EX(DcfParserModule, BLT_BaseModule, BLT_Module); BLT_COMPILER_UNUSED(core); switch (parameters_type) { case BLT_MODULE_PARAMETERS_TYPE_MEDIA_NODE_CONSTRUCTOR: { BLT_MediaNodeConstructor* constructor = (BLT_MediaNodeConstructor*)parameters; /* we need the input protocol to be STREAM_PULL and the output */ /* protocol to be STREAM_PULL */ if ((constructor->spec.input.protocol != BLT_MEDIA_PORT_PROTOCOL_ANY && constructor->spec.input.protocol != BLT_MEDIA_PORT_PROTOCOL_STREAM_PULL) || (constructor->spec.output.protocol != BLT_MEDIA_PORT_PROTOCOL_ANY && constructor->spec.output.protocol != BLT_MEDIA_PORT_PROTOCOL_STREAM_PULL)) { return BLT_FAILURE; } /* we need the input media type to be 'application/vnd.oma.drm.content' */ /* or 'application/vnd.oma.drm.dcf' */ if (constructor->spec.input.media_type->id != self->dcf1_type_id && constructor->spec.input.media_type->id != self->dcf2_type_id) { return BLT_FAILURE; } /* the output type should be unknown at this point */ if (constructor->spec.output.media_type->id != BLT_MEDIA_TYPE_ID_UNKNOWN) { return BLT_FAILURE; } /* compute the match level */ if (constructor->name != NULL) { /* we're being probed by name */ if (ATX_StringsEqual(constructor->name, "DcfParser")) { /* our name */ *match = BLT_MODULE_PROBE_MATCH_EXACT; } else { /* not out name */ return BLT_FAILURE; } } else { /* we're probed by protocol/type specs only */ *match = BLT_MODULE_PROBE_MATCH_MAX - 10; } ATX_LOG_FINE_1("DcfParserModule::Probe - Ok [%d]", *match); return BLT_SUCCESS; } break; default: break; } return BLT_FAILURE; }
/*---------------------------------------------------------------------- | OsxAudioUnitsOutput_Activate +---------------------------------------------------------------------*/ BLT_METHOD OsxAudioUnitsOutput_Activate(BLT_MediaNode* _self, BLT_Stream* stream) { OsxAudioUnitsOutput* self = ATX_SELF_EX(OsxAudioUnitsOutput, BLT_BaseMediaNode, BLT_MediaNode); ComponentResult result; AURenderCallbackStruct callback; BLT_COMPILER_UNUSED(stream); ATX_LOG_FINER("start"); /* select the device */ if (self->audio_device_id) { result = AudioUnitSetProperty(self->audio_unit, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, 0, &self->audio_device_id, sizeof(self->audio_device_id)); if (result != noErr) { ATX_LOG_WARNING_1("AudioUnitSetProperty (kAudioOutputUnitProperty_CurrentDevice) failed (%d)", (int)result); } } /* initialize the output */ if (self->audio_unit) { result = AudioUnitInitialize(self->audio_unit); if (result != noErr) { ATX_LOG_WARNING_1("AudioUnitInitialize failed (%d)", (int)result); return BLT_FAILURE; } } /* set some default audio format */ { AudioStreamBasicDescription audio_desc; ATX_SetMemory(&audio_desc, 0, sizeof(audio_desc)); /* setup the audio description */ audio_desc.mFormatID = kAudioFormatLinearPCM; audio_desc.mFormatFlags = kAudioFormatFlagsNativeEndian | kLinearPCMFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked; audio_desc.mFramesPerPacket = 1; audio_desc.mSampleRate = 44100; audio_desc.mChannelsPerFrame = 2; audio_desc.mBitsPerChannel = 16; audio_desc.mBytesPerFrame = (audio_desc.mBitsPerChannel * audio_desc.mChannelsPerFrame) / 8; audio_desc.mBytesPerPacket = audio_desc.mBytesPerFrame * audio_desc.mFramesPerPacket; audio_desc.mReserved = 0; result = AudioUnitSetProperty(self->audio_unit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &audio_desc, sizeof(audio_desc)); if (result != noErr) { ATX_LOG_WARNING_1("AudioUnitSetProperty failed (%d)", (int)result); return BLT_FAILURE; } } /* check for downmix based on the number of supported channels */ OsxAudioUnitsOutput_CheckDownmix(self); /* setup the callback */ callback.inputProc = OsxAudioUnitsOutput_RenderCallback; callback.inputProcRefCon = _self; result = AudioUnitSetProperty(self->audio_unit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, 0, &callback, sizeof(callback)); if (result != noErr) { ATX_LOG_SEVERE_1("AudioUnitSetProperty failed when setting callback (%d)", (int)result); return BLT_FAILURE; } return BLT_SUCCESS; }
/*---------------------------------------------------------------------- | OsxAudioUnitsOutput_RenderCallback +---------------------------------------------------------------------*/ static OSStatus OsxAudioUnitsOutput_RenderCallback(void* inRefCon, AudioUnitRenderActionFlags* ioActionFlags, const AudioTimeStamp* inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList* ioData) { OsxAudioUnitsOutput* self = (OsxAudioUnitsOutput*)inRefCon; ATX_ListItem* item; unsigned int requested; unsigned char* out; ATX_Boolean timestamp_measured = ATX_FALSE; BLT_COMPILER_UNUSED(ioActionFlags); BLT_COMPILER_UNUSED(inTimeStamp); BLT_COMPILER_UNUSED(inBusNumber); BLT_COMPILER_UNUSED(inNumberFrames); /* sanity check on the parameters */ if (ioData == NULL || ioData->mNumberBuffers == 0) return 0; /* in case we have a strange request with more than one buffer, just return silence */ if (ioData->mNumberBuffers != 1) { unsigned int i; ATX_LOG_FINEST_1("strange request with %d buffers", (int)ioData->mNumberBuffers); for (i=0; i<ioData->mNumberBuffers; i++) { ATX_SetMemory(ioData->mBuffers[i].mData, 0, ioData->mBuffers[i].mDataByteSize); } return 0; } /* init local variables */ requested = ioData->mBuffers[0].mDataByteSize; out = (unsigned char*)ioData->mBuffers[0].mData; ATX_LOG_FINEST_2("request for %d bytes, %d frames", (int)requested, (int)inNumberFrames); /* lock the packet queue */ pthread_mutex_lock(&self->lock); /* return now if we're paused */ //if (self->paused) goto end; /* abort early if we have no packets */ if (ATX_List_GetItemCount(self->packet_queue) == 0) goto end; /* fill as much as we can */ while (requested && (item = ATX_List_GetFirstItem(self->packet_queue))) { BLT_MediaPacket* packet = ATX_ListItem_GetData(item); const BLT_PcmMediaType* media_type; BLT_Size payload_size; BLT_Size chunk_size; BLT_TimeStamp chunk_duration; BLT_TimeStamp packet_ts; unsigned int bytes_per_frame; unsigned int sample_rate; /* get the packet info */ BLT_MediaPacket_GetMediaType(packet, (const BLT_MediaType**)&media_type); packet_ts = BLT_MediaPacket_GetTimeStamp(packet); bytes_per_frame = media_type->channel_count*media_type->bits_per_sample/8; sample_rate = media_type->sample_rate; /* record the timestamp if we have not already done so */ if (!timestamp_measured) { self->media_time_snapshot.rendered_packet_ts = packet_ts; self->media_time_snapshot.rendered_host_time = AudioConvertHostTimeToNanos(AudioGetCurrentHostTime()); BLT_TimeStamp_Set(self->media_time_snapshot.rendered_duration, 0, 0); timestamp_measured = ATX_TRUE; ATX_LOG_FINEST_2("rendered TS: packet ts=%lld, host ts=%lld", BLT_TimeStamp_ToNanos(packet_ts), self->media_time_snapshot.rendered_host_time); } /* compute how much to copy from this packet */ payload_size = BLT_MediaPacket_GetPayloadSize(packet); if (payload_size <= requested) { /* copy the entire payload and remove the packet from the queue */ chunk_size = payload_size; ATX_CopyMemory(out, BLT_MediaPacket_GetPayloadBuffer(packet), chunk_size); ATX_List_RemoveItem(self->packet_queue, item); packet = NULL; media_type = NULL; ATX_LOG_FINER_1("media packet fully consumed, %d left in queue", ATX_List_GetItemCount(self->packet_queue)); } else { /* only copy a portion of the payload */ chunk_size = requested; ATX_CopyMemory(out, BLT_MediaPacket_GetPayloadBuffer(packet), chunk_size); } /* update the counters */ requested -= chunk_size; out += chunk_size; /* update the media time snapshot */ if (bytes_per_frame) { unsigned int frames_in_chunk = chunk_size/bytes_per_frame; chunk_duration = BLT_TimeStamp_FromSamples(frames_in_chunk, sample_rate); } else { BLT_TimeStamp_Set(chunk_duration, 0, 0); } self->media_time_snapshot.rendered_duration = BLT_TimeStamp_Add(self->media_time_snapshot.rendered_duration, chunk_duration); /* update the packet unless we're done with it */ if (packet) { /* update the packet offset and timestamp */ BLT_MediaPacket_SetPayloadOffset(packet, BLT_MediaPacket_GetPayloadOffset(packet)+chunk_size); BLT_MediaPacket_SetTimeStamp(packet, BLT_TimeStamp_Add(packet_ts, chunk_duration)); } } end: /* fill whatever is left with silence */ if (requested) { ATX_LOG_FINEST_1("filling with %d bytes of silence", requested); ATX_SetMemory(out, 0, requested); } pthread_mutex_unlock(&self->lock); return 0; }
/*---------------------------------------------------------------------- | CrossFaderModule_Probe +---------------------------------------------------------------------*/ BLT_METHOD CrossFaderModule_Probe(BLT_ModuleInstance* instance, BLT_Core* core, BLT_ModuleParametersType parameters_type, BLT_AnyConst parameters, BLT_Cardinal* match) { BLT_COMPILER_UNUSED(core); BLT_COMPILER_UNUSED(instance); switch (parameters_type) { case BLT_MODULE_PARAMETERS_TYPE_MEDIA_NODE_CONSTRUCTOR: { BLT_MediaNodeConstructor* constructor = (BLT_MediaNodeConstructor*)parameters; /* we need a name */ if (constructor->name == NULL || !ATX_StringsEqual(constructor->name, "CrossFader")) { return BLT_FAILURE; } /* the input and output protocols should be PACKET */ if ((constructor->spec.input.protocol != BLT_MEDIA_PORT_PROTOCOL_ANY && constructor->spec.input.protocol != BLT_MEDIA_PORT_PROTOCOL_PACKET) || (constructor->spec.output.protocol != BLT_MEDIA_PORT_PROTOCOL_ANY && constructor->spec.output.protocol != BLT_MEDIA_PORT_PROTOCOL_PACKET)) { return BLT_FAILURE; } /* the input type should be unspecified, or audio/pcm */ if (!(constructor->spec.input.media_type->id == BLT_MEDIA_TYPE_ID_AUDIO_PCM) && !(constructor->spec.input.media_type->id == BLT_MEDIA_TYPE_ID_UNKNOWN)) { return BLT_FAILURE; } /* the output type should be unspecified, or audio/pcm */ if (!(constructor->spec.output.media_type->id == BLT_MEDIA_TYPE_ID_AUDIO_PCM) && !(constructor->spec.output.media_type->id == BLT_MEDIA_TYPE_ID_UNKNOWN)) { return BLT_FAILURE; } /* match level is always exact */ *match = BLT_MODULE_PROBE_MATCH_EXACT; ATX_LOG_FINE_1("CrossFaderModule::Probe - Ok [%d]", *match); return BLT_SUCCESS; } break; default: break; } return BLT_FAILURE; }
/*---------------------------------------------------------------------- | PcmAdapterModule_Probe +---------------------------------------------------------------------*/ BLT_METHOD PcmAdapterModule_Probe(BLT_Module* self, BLT_Core* core, BLT_ModuleParametersType parameters_type, BLT_AnyConst parameters, BLT_Cardinal* match) { BLT_COMPILER_UNUSED(self); BLT_COMPILER_UNUSED(core); switch (parameters_type) { case BLT_MODULE_PARAMETERS_TYPE_MEDIA_NODE_CONSTRUCTOR: { BLT_MediaNodeConstructor* constructor = (BLT_MediaNodeConstructor*)parameters; /* compute match based on specified name */ if (constructor->name == NULL) { *match = BLT_MODULE_PROBE_MATCH_DEFAULT; /* the input protocol should be PACKET */ if (constructor->spec.input.protocol != BLT_MEDIA_PORT_PROTOCOL_PACKET) { return BLT_FAILURE; } /* output protocol should be PACKET */ if (constructor->spec.output.protocol != BLT_MEDIA_PORT_PROTOCOL_PACKET) { return BLT_FAILURE; } /* check that the in and out formats are supported */ if (!BLT_Pcm_CanConvert(constructor->spec.input.media_type, constructor->spec.output.media_type)) { return BLT_FAILURE; } } else { /* if a name is specified, it needs to match exactly */ if (!ATX_StringsEqual(constructor->name, "PcmAdapter")) { return BLT_FAILURE; } else { *match = BLT_MODULE_PROBE_MATCH_EXACT; } /* the input protocol should be PACKET or ANY */ if (constructor->spec.input.protocol != BLT_MEDIA_PORT_PROTOCOL_ANY && constructor->spec.input.protocol != BLT_MEDIA_PORT_PROTOCOL_PACKET) { return BLT_FAILURE; } /* output protocol should be PACKET or ANY */ if ((constructor->spec.output.protocol != BLT_MEDIA_PORT_PROTOCOL_ANY && constructor->spec.output.protocol != BLT_MEDIA_PORT_PROTOCOL_PACKET)) { return BLT_FAILURE; } /* check that the in and out formats are supported */ if (!BLT_Pcm_CanConvert(constructor->spec.input.media_type, constructor->spec.output.media_type)) { return BLT_FAILURE; } } ATX_LOG_FINE_1("PcmAdapterModule::Probe - Ok [%d]", *match); return BLT_SUCCESS; } break; default: break; } return BLT_FAILURE; }
/*---------------------------------------------------------------------- | WaveFormatterModule_Probe +---------------------------------------------------------------------*/ BLT_METHOD WaveFormatterModule_Probe(BLT_Module* _self, BLT_Core* core, BLT_ModuleParametersType parameters_type, BLT_AnyConst parameters, BLT_Cardinal* match) { WaveFormatterModule* self = ATX_SELF_EX(WaveFormatterModule, BLT_BaseModule, BLT_Module); BLT_COMPILER_UNUSED(core); switch (parameters_type) { case BLT_MODULE_PARAMETERS_TYPE_MEDIA_NODE_CONSTRUCTOR: { BLT_MediaNodeConstructor* constructor = (BLT_MediaNodeConstructor*)parameters; /* the input protocol should be STREAM_PUSH and the */ /* output protocol should be STREAM_PUSH */ if ((constructor->spec.input.protocol != BLT_MEDIA_PORT_PROTOCOL_ANY && constructor->spec.input.protocol != BLT_MEDIA_PORT_PROTOCOL_STREAM_PUSH) || (constructor->spec.output.protocol != BLT_MEDIA_PORT_PROTOCOL_ANY && constructor->spec.output.protocol != BLT_MEDIA_PORT_PROTOCOL_STREAM_PUSH)) { return BLT_FAILURE; } /* the input type should be audio/pcm */ if (constructor->spec.input.media_type->id != BLT_MEDIA_TYPE_ID_AUDIO_PCM) { return BLT_FAILURE; } /* compute the match level */ if (constructor->name != NULL) { /* we're being probed by name */ if (ATX_StringsEqual(constructor->name, "WaveFormatter")) { /* our name */ *match = BLT_MODULE_PROBE_MATCH_EXACT; } else { /* not our name */ return BLT_FAILURE; } } else { /* we're probed by protocol/type specs only */ /* the output type should be audio/wav */ if (constructor->spec.output.media_type->id != self->wav_type_id) { return BLT_FAILURE; } *match = BLT_MODULE_PROBE_MATCH_MAX - 10; } ATX_LOG_FINE_1("WaveFormatterModule::Probe - Ok [%d]", *match); return BLT_SUCCESS; } break; default: break; } return BLT_FAILURE; }
/*---------------------------------------------------------------------- | Mp4ParserModule_Probe +---------------------------------------------------------------------*/ BLT_METHOD Mp4ParserModule_Probe(BLT_Module* _self, BLT_Core* core, BLT_ModuleParametersType parameters_type, BLT_AnyConst parameters, BLT_Cardinal* match) { Mp4ParserModule* self = ATX_SELF_EX(Mp4ParserModule, BLT_BaseModule, BLT_Module); BLT_COMPILER_UNUSED(core); switch (parameters_type) { case BLT_MODULE_PARAMETERS_TYPE_MEDIA_NODE_CONSTRUCTOR: { BLT_MediaNodeConstructor* constructor = (BLT_MediaNodeConstructor*)parameters; /* check if we're being probed by name */ if (constructor->name != NULL) { /* we're being probed by name */ if (ATX_StringsEqual(constructor->name, "com.bluetune.parsers.mp4")) { /* our name */ *match = BLT_MODULE_PROBE_MATCH_EXACT; return BLT_SUCCESS; } else { /* not out name */ *match = 0; return BLT_FAILURE; } } /* we need the input protocol to be STREAM_PULL and the output */ /* protocol to be PACKET */ if ((constructor->spec.input.protocol != BLT_MEDIA_PORT_PROTOCOL_ANY && constructor->spec.input.protocol != BLT_MEDIA_PORT_PROTOCOL_STREAM_PULL) || (constructor->spec.output.protocol != BLT_MEDIA_PORT_PROTOCOL_ANY && constructor->spec.output.protocol != BLT_MEDIA_PORT_PROTOCOL_PACKET)) { return BLT_FAILURE; } /* we need the input media type to be 'audio/mp4' or 'video/mp4' */ if (constructor->spec.input.media_type->id != self->mp4_audio_type_id && constructor->spec.input.media_type->id != self->mp4_video_type_id) { return BLT_FAILURE; } /* the output type should be unknown at this point */ if (constructor->spec.output.media_type->id != BLT_MEDIA_TYPE_ID_UNKNOWN) { return BLT_FAILURE; } /* set the match level */ *match = BLT_MODULE_PROBE_MATCH_MAX - 10; ATX_LOG_FINE_1("match %d", *match); return BLT_SUCCESS; } break; default: break; } return BLT_FAILURE; }
/*---------------------------------------------------------------------- | AacDecoderModule_Probe +---------------------------------------------------------------------*/ BLT_METHOD AacDecoderModule_Probe(BLT_Module* _self, BLT_Core* core, BLT_ModuleParametersType parameters_type, BLT_AnyConst parameters, BLT_Cardinal* match) { AacDecoderModule* self = ATX_SELF_EX(AacDecoderModule, BLT_BaseModule, BLT_Module); BLT_COMPILER_UNUSED(core); switch (parameters_type) { case BLT_MODULE_PARAMETERS_TYPE_MEDIA_NODE_CONSTRUCTOR: { BLT_MediaNodeConstructor* constructor = (BLT_MediaNodeConstructor*)parameters; /* the input and output protocols should be PACKET */ if ((constructor->spec.input.protocol != BLT_MEDIA_PORT_PROTOCOL_ANY && constructor->spec.input.protocol != BLT_MEDIA_PORT_PROTOCOL_PACKET) || (constructor->spec.output.protocol != BLT_MEDIA_PORT_PROTOCOL_ANY && constructor->spec.output.protocol != BLT_MEDIA_PORT_PROTOCOL_PACKET)) { return BLT_FAILURE; } /* the input type should be BLT_MP4_ES_MIME_TYPE */ if (constructor->spec.input.media_type->id != self->mp4es_type_id) { return BLT_FAILURE; } else { /* check the object type id */ BLT_Mp4AudioMediaType* media_type = (BLT_Mp4AudioMediaType*)constructor->spec.input.media_type; if (media_type->base.stream_type != BLT_MP4_STREAM_TYPE_AUDIO) return BLT_FAILURE; if (media_type->base.format_or_object_type_id != BLT_AAC_OBJECT_TYPE_ID_MPEG2_AAC_LC && media_type->base.format_or_object_type_id != BLT_AAC_OBJECT_TYPE_ID_MPEG4_AUDIO) { return BLT_FAILURE; } if (media_type->base.format_or_object_type_id == BLT_AAC_OBJECT_TYPE_ID_MPEG4_AUDIO) { /* check that this is AAC LC */ AacDecoderConfig decoder_config; if (BLT_FAILED(AacDecoderConfig_Parse(media_type->decoder_info, media_type->decoder_info_length, &decoder_config))) { return BLT_FAILURE; } if (decoder_config.object_type != BLT_AAC_OBJECT_TYPE_AAC_LC && decoder_config.object_type != BLT_AAC_OBJECT_TYPE_SBR) { return BLT_FAILURE; } } } /* the output type should be unspecified, or audio/pcm */ if (!(constructor->spec.output.media_type->id == BLT_MEDIA_TYPE_ID_AUDIO_PCM) && !(constructor->spec.output.media_type->id == BLT_MEDIA_TYPE_ID_UNKNOWN)) { return BLT_FAILURE; } /* compute the match level */ if (constructor->name != NULL) { /* we're being probed by name */ if (ATX_StringsEqual(constructor->name, "AacDecoder")) { /* our name */ *match = BLT_MODULE_PROBE_MATCH_EXACT; } else { /* not our name */ return BLT_FAILURE; } } else { /* we're probed by protocol/type specs only */ *match = BLT_MODULE_PROBE_MATCH_MAX - 10; } ATX_LOG_FINE_1("AacDecoderModule::Probe - Ok [%d]", *match); return BLT_SUCCESS; } break; default: break; } return BLT_FAILURE; }