/*---------------------------------------------------------------------- | SilenceRemover_Destroy +---------------------------------------------------------------------*/ static BLT_Result SilenceRemover_Destroy(SilenceRemover* self) { ATX_ListItem* item; ATX_LOG_FINE("SilenceRemover::Destroy"); /* release any input packet we may hold */ if (self->input.pending) { BLT_MediaPacket_Release(self->input.pending); } /* release any output packet we may hold */ item = ATX_List_GetFirstItem(self->output.packets); while (item) { BLT_MediaPacket* packet = ATX_ListItem_GetData(item); if (packet) { BLT_MediaPacket_Release(packet); } item = ATX_ListItem_GetNext(item); } ATX_List_Destroy(self->output.packets); /* destruct the inherited object */ BLT_BaseMediaNode_Destruct(&ATX_BASE(self, BLT_BaseMediaNode)); /* free the object memory */ ATX_FreeMemory(self); return BLT_SUCCESS; }
/*---------------------------------------------------------------------- | CrossFader_Destroy +---------------------------------------------------------------------*/ static BLT_Result CrossFader_Destroy(CrossFader* fader) { ATX_ListItem* item; ATX_LOG_FINE("CrossFader::Destroy"); /* release any packet we may hold */ item = ATX_List_GetFirstItem(fader->output.packets); while (item) { BLT_MediaPacket* packet = ATX_ListItem_GetData(item); if (packet) { BLT_MediaPacket_Release(packet); } item = ATX_ListItem_GetNext(item); } ATX_List_Destroy(fader->output.packets); /* destroy the input buffer */ if (fader->input.buffer) { ATX_RingBuffer_Destroy(fader->input.buffer); } /* destruct the inherited object */ BLT_BaseMediaNode_Destruct(&fader->base); /* free the object memory */ ATX_FreeMemory(fader); return BLT_SUCCESS; }
/*---------------------------------------------------------------------- | CrossFader_PromotePacket +---------------------------------------------------------------------*/ static BLT_Result CrossFader_PromotePacket(CrossFader* fader, BLT_Size size) { BLT_MediaPacket* packet; unsigned char* payload; BLT_Result result; ATX_LOG_FINER_1("CrossFader::PromotePacket - size = %d", size); /* create a packet */ result = BLT_Core_CreateMediaPacket(&fader->base.core, size, (const BLT_MediaType*)&fader->input.media_type, &packet); if (BLT_FAILED(result)) return result; /* get the addr of the buffer */ payload = BLT_MediaPacket_GetPayloadBuffer(packet); /* read the data from the input ring buffer */ result = ATX_RingBuffer_Read(fader->input.buffer, payload, size); if (BLT_FAILED(result)) { BLT_MediaPacket_Release(packet); return result; } /* update the size of the packet */ BLT_MediaPacket_SetPayloadSize(packet, size); /* make the packet ready for the output */ ATX_List_AddData(fader->output.packets, packet); return BLT_SUCCESS; }
/*---------------------------------------------------------------------- | 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); }
/*---------------------------------------------------------------------- | 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; }
/*---------------------------------------------------------------------- | SilenceRemover_AcceptPending +---------------------------------------------------------------------*/ static void SilenceRemover_AcceptPending(SilenceRemover* self) { BLT_MediaPacket* packet = self->input.pending; BLT_Result result; if (packet != NULL) { result = ATX_List_AddData(self->output.packets, packet); if (ATX_FAILED(result)) { BLT_MediaPacket_Release(packet); } self->input.pending = NULL; ATX_LOG_FINER("SilenceRemover: accepting pending packet"); } else { ATX_LOG_FINER("SilenceRemover: no pending packet"); } }
ATX_END_INTERFACE_MAP /*---------------------------------------------------------------------- | AacDecoderOutput_Flush +---------------------------------------------------------------------*/ static BLT_Result AacDecoderOutput_Flush(AacDecoder* self) { ATX_ListItem* item; while ((item = ATX_List_GetFirstItem(self->output.packets))) { BLT_MediaPacket* packet = ATX_ListItem_GetData(item); if (packet) BLT_MediaPacket_Release(packet); ATX_List_RemoveItem(self->output.packets, item); } return BLT_SUCCESS; }
/*---------------------------------------------------------------------- | PcmAdapter_Destroy +---------------------------------------------------------------------*/ static BLT_Result PcmAdapter_Destroy(PcmAdapter* self) { ATX_LOG_FINE("PcmAdapter::Destroy"); /* release any input packet we may hold */ if (self->output.packet) { BLT_MediaPacket_Release(self->output.packet); } /* destruct the inherited object */ BLT_BaseMediaNode_Destruct(&ATX_BASE(self, BLT_BaseMediaNode)); /* free the object memory */ ATX_FreeMemory((void*)self); return BLT_SUCCESS; }
/*---------------------------------------------------------------------- | AacDecoderInput_PutPacket +---------------------------------------------------------------------*/ BLT_METHOD AacDecoderInput_PutPacket(BLT_PacketConsumer* _self, BLT_MediaPacket* packet) { AacDecoder* self = ATX_SELF_M(input, AacDecoder, BLT_PacketConsumer); ATX_Result result; /* check to see if this is the end of a stream */ if (BLT_MediaPacket_GetFlags(packet) & BLT_MEDIA_PACKET_FLAG_END_OF_STREAM) { self->input.eos = BLT_TRUE; } /* check to see if we need to create a decoder for this */ if (self->helix_decoder == NULL) { AacDecoderConfig decoder_config; AACFrameInfo aac_frame_info; const BLT_MediaType* media_type; const BLT_Mp4AudioMediaType* mp4_media_type; BLT_MediaPacket_GetMediaType(packet, &media_type); if (media_type == NULL || media_type->id != self->mp4es_type_id) { return BLT_ERROR_INVALID_MEDIA_TYPE; } mp4_media_type = (const BLT_Mp4AudioMediaType*)media_type; if (mp4_media_type->base.stream_type != BLT_MP4_STREAM_TYPE_AUDIO) { return BLT_ERROR_INVALID_MEDIA_TYPE; } if (BLT_FAILED(AacDecoderConfig_Parse(mp4_media_type->decoder_info, mp4_media_type->decoder_info_length, &decoder_config))) { return BLT_ERROR_INVALID_MEDIA_FORMAT; } if (decoder_config.object_type != BLT_AAC_OBJECT_TYPE_AAC_LC && decoder_config.object_type != BLT_AAC_OBJECT_TYPE_SBR) { return BLT_ERROR_UNSUPPORTED_CODEC; } /* create the decoder */ self->helix_decoder = AACInitDecoder(); if (self->helix_decoder == NULL) return BLT_ERROR_OUT_OF_MEMORY; /* configure the decoder */ ATX_SetMemory(&aac_frame_info, 0, sizeof(aac_frame_info)); aac_frame_info.nChans = AacDecoderConfig_GetChannelCount(&decoder_config); aac_frame_info.sampRateCore = AacDecoderConfig_GetSampleRate(&decoder_config); if (decoder_config.object_type == BLT_AAC_OBJECT_TYPE_AAC_LC) { aac_frame_info.profile = AAC_PROFILE_LC; } self->sample_buffer_size = BLT_AAC_FRAME_SIZE*2*aac_frame_info.nChans*2; /* the last *2 is for SBR support */ AACSetRawBlockParams(self->helix_decoder, 0, &aac_frame_info); } { unsigned char* in_buffer; int in_size; short* out_buffer; BLT_MediaPacket* out_packet; AACFrameInfo aac_frame_info; /* create a PCM packet for the output */ result = BLT_Core_CreateMediaPacket(ATX_BASE(self, BLT_BaseMediaNode).core, self->sample_buffer_size, (BLT_MediaType*)&self->output.media_type, &out_packet); if (BLT_FAILED(result)) return result; /* copy the timestamp */ BLT_MediaPacket_SetTimeStamp(out_packet, BLT_MediaPacket_GetTimeStamp(packet)); /* decode the packet as a frame */ in_buffer = BLT_MediaPacket_GetPayloadBuffer(packet); in_size = BLT_MediaPacket_GetPayloadSize(packet); out_buffer = (short*)BLT_MediaPacket_GetPayloadBuffer(out_packet); result = AACDecode(self->helix_decoder, &in_buffer, &in_size, out_buffer); if (result != 0) { BLT_MediaPacket_Release(out_packet); return BLT_ERROR_INVALID_MEDIA_FORMAT; } /* check that the sample buffer matches our current media type */ AACGetLastFrameInfo(self->helix_decoder, &aac_frame_info); if (self->output.media_type.channel_count == 0) { /* first time, setup our media type */ self->output.media_type.channel_count = aac_frame_info.nChans; self->output.media_type.sample_rate = aac_frame_info.sampRateOut; self->output.media_type.bits_per_sample = 16; self->output.media_type.sample_format = BLT_PCM_SAMPLE_FORMAT_SIGNED_INT_NE; self->output.media_type.channel_mask = 0; /* update the stream info */ if (ATX_BASE(self, BLT_BaseMediaNode).context) { BLT_StreamInfo stream_info; stream_info.data_type = "MPEG-4 AAC"; stream_info.sample_rate = aac_frame_info.sampRateOut; stream_info.channel_count = aac_frame_info.nChans; stream_info.mask = BLT_STREAM_INFO_MASK_DATA_TYPE | BLT_STREAM_INFO_MASK_SAMPLE_RATE | BLT_STREAM_INFO_MASK_CHANNEL_COUNT; BLT_Stream_SetInfo(ATX_BASE(self, BLT_BaseMediaNode).context, &stream_info); } /* update the packet media type */ BLT_MediaPacket_SetMediaType(out_packet, (BLT_MediaType*)&self->output.media_type); } else { /* we've already setup a media type, check that this is the same */ if (self->output.media_type.sample_rate != (unsigned int)aac_frame_info.sampRateOut || self->output.media_type.channel_count != aac_frame_info.nChans) { BLT_MediaPacket_Release(out_packet); return BLT_ERROR_INVALID_MEDIA_FORMAT; } } /* add to the output packet list */ BLT_MediaPacket_SetPayloadSize(out_packet, aac_frame_info.outputSamps*2); ATX_List_AddData(self->output.packets, out_packet); } return BLT_SUCCESS; }