/*---------------------------------------------------------------------- | 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; }
/*---------------------------------------------------------------------- | ATX_HttpMessage_GetHeader +---------------------------------------------------------------------*/ const ATX_String* ATX_HttpMessage_GetHeader(const ATX_HttpMessage* message, ATX_CString name) { /* find the header */ ATX_ListItem* item = ATX_List_GetFirstItem(message->headers); while (item) { ATX_HttpHeader* header = (ATX_HttpHeader*)ATX_ListItem_GetData(item); if (ATX_String_Equals(&header->name, name, ATX_TRUE)) { /* found a match */ return &header->value; } item = ATX_ListItem_GetNext(item); } /* not found */ return NULL; }
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; }
/*---------------------------------------------------------------------- | ATX_HttpMessage_Destruct +---------------------------------------------------------------------*/ static ATX_Result ATX_HttpMessage_Destruct(ATX_HttpMessage* message) { /* destroy all headers */ ATX_ListItem* item = ATX_List_GetFirstItem(message->headers); while (item) { ATX_HttpHeader_Destroy((ATX_HttpHeader*)ATX_ListItem_GetData(item)); item = ATX_ListItem_GetNext(item); } ATX_List_Destroy(message->headers); /* free the protocol string */ ATX_String_Destruct(&message->protocol); /* release the body stream */ ATX_RELEASE_OBJECT(message->body); return ATX_SUCCESS; }
/*---------------------------------------------------------------------- | CrossFaderOutputPort_GetPacket +---------------------------------------------------------------------*/ BLT_METHOD CrossFaderOutputPort_GetPacket(BLT_PacketProducerInstance* instance, BLT_MediaPacket** packet) { CrossFader* fader = (CrossFader*)instance; ATX_ListItem* item; item = ATX_List_GetFirstItem(fader->output.packets); if (item) { *packet = ATX_ListItem_GetData(item); ATX_List_RemoveItem(fader->output.packets, item); ATX_LOG_FINER("CrossFaderInputPort_GetPacket - got one"); return BLT_SUCCESS; } else { *packet = NULL; ATX_LOG_FINER("CrossFaderInputPort_GetPacket - no more data"); return BLT_ERROR_PORT_HAS_NO_DATA; } }
/*---------------------------------------------------------------------- | AacDecoderOutput_GetPacket +---------------------------------------------------------------------*/ BLT_METHOD AacDecoderOutput_GetPacket(BLT_PacketProducer* _self, BLT_MediaPacket** packet) { AacDecoder* self = ATX_SELF_M(output, AacDecoder, BLT_PacketProducer); ATX_ListItem* packet_item; /* default return */ *packet = NULL; /* check if we have a packet available */ packet_item = ATX_List_GetFirstItem(self->output.packets); if (packet_item) { *packet = (BLT_MediaPacket*)ATX_ListItem_GetData(packet_item); ATX_List_RemoveItem(self->output.packets, packet_item); return BLT_SUCCESS; } return BLT_ERROR_PORT_HAS_NO_DATA; }
/*---------------------------------------------------------------------- | ATX_HttpMessage_Emit +---------------------------------------------------------------------*/ static ATX_Result ATX_HttpMessage_Emit(const ATX_HttpMessage* message, ATX_OutputStream* stream) { ATX_ListItem* item = ATX_List_GetFirstItem(message->headers); /* output the headers */ while (item) { ATX_HttpHeader* header = ATX_ListItem_GetData(item); if (header && !ATX_String_IsEmpty(&header->name) && !ATX_String_IsEmpty(&header->value)) { ATX_OutputStream_WriteString(stream, ATX_CSTR(header->name)); ATX_OutputStream_Write(stream, ": ", 2, NULL); ATX_OutputStream_WriteLine(stream, ATX_CSTR(header->value)); ATX_LOG_FINE_2("ATX_HttpMessage::Emit - %s: %s", ATX_CSTR(header->name), ATX_CSTR(header->value)); } item = ATX_ListItem_GetNext(item); } return ATX_SUCCESS; }
ATX_END_INTERFACE_MAP /*---------------------------------------------------------------------- | SilenceRemoverOutput_GetPacket +---------------------------------------------------------------------*/ BLT_METHOD SilenceRemoverOutput_GetPacket(BLT_PacketProducer* _self, BLT_MediaPacket** packet) { SilenceRemover* self = ATX_SELF_M(output, SilenceRemover, BLT_PacketProducer); ATX_ListItem* item; item = ATX_List_GetFirstItem(self->output.packets); if (item) { *packet = ATX_ListItem_GetData(item); ATX_List_RemoveItem(self->output.packets, item); return BLT_SUCCESS; } else { *packet = NULL; return BLT_ERROR_PORT_HAS_NO_DATA; } }
/*---------------------------------------------------------------------- | ATX_HttpMessage_SetHeader +---------------------------------------------------------------------*/ ATX_Result ATX_HttpMessage_SetHeader(ATX_HttpMessage* message, ATX_CString name, ATX_CString value) { ATX_HttpHeader* header; ATX_Result result; /* find if the header already exists */ ATX_ListItem* item = ATX_List_GetFirstItem(message->headers); while (item) { header = (ATX_HttpHeader*)ATX_ListItem_GetData(item); if (ATX_String_Equals(&header->name, name, ATX_TRUE)) { /* found a match */ return ATX_HttpHeader_SetValue(header, value); } item = ATX_ListItem_GetNext(item); } /* create a new header */ result = ATX_HttpHeader_Create(name, value, &header); if (ATX_FAILED(result)) return result; return ATX_List_AddData(message->headers, header); }
/*---------------------------------------------------------------------- | 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; }