/*---------------------------------------------------------------------- | ATX_RingBuffer_Create +---------------------------------------------------------------------*/ ATX_Result ATX_RingBuffer_Create(ATX_Size size, ATX_RingBuffer** buffer) { ATX_RingBuffer* ring; /* allocate a new object */ ring = (ATX_RingBuffer*)ATX_AllocateMemory(sizeof(ATX_RingBuffer)); *buffer = ring; if (ring == NULL) { return ATX_ERROR_OUT_OF_MEMORY; } /* construct the object */ ring->size = size; ring->data.start = ATX_AllocateZeroMemory(size); ring->data.end = ring->data.start + size; ring->in = ring->out = ring->data.start; /* check that everything is ok */ if (ring->data.start == NULL) { ATX_FreeMemory((void*)ring); return ATX_ERROR_OUT_OF_MEMORY; } return ATX_SUCCESS; }
/*---------------------------------------------------------------------- | ATX_HttpResponse_CreateFromStream +---------------------------------------------------------------------*/ ATX_Result ATX_HttpResponse_CreateFromStream(ATX_InputStream* stream, ATX_HttpResponse** response) { ATX_Result result; /* allocate a new object */ *response = (ATX_HttpResponse*)ATX_AllocateZeroMemory(sizeof(ATX_HttpResponse)); if (*response == NULL) { return ATX_ERROR_OUT_OF_MEMORY; } /* construct the base object */ result = ATX_HttpMessage_Construct(&(*response)->base); if (ATX_FAILED(result)) { ATX_FreeMemory((void*)*response); *response = NULL; return result; } /* parse the response from the stream */ result = ATX_HttpResponse_Parse(*response, stream); if (ATX_FAILED(result)) { ATX_HttpResponse_Destroy(*response); *response = NULL; return result; } return ATX_SUCCESS; }
/*---------------------------------------------------------------------- | BLT_BaseModule_ConstructEx +---------------------------------------------------------------------*/ BLT_Result BLT_BaseModule_ConstructEx(BLT_BaseModule* self, BLT_CString name, BLT_CString uid, BLT_Flags flags, BLT_Cardinal property_count, const ATX_Property* properties) { unsigned int i; if (name) { self->info.name = ATX_DuplicateString(name); } else { self->info.name = NULL; } if (uid) { self->info.uid = ATX_DuplicateString(uid); } else { self->info.uid = NULL; } self->info.flags = flags; self->info.property_count = property_count; if (property_count) { self->info.properties = (ATX_Property*)ATX_AllocateZeroMemory(property_count*sizeof(ATX_Property)); for (i=0; i<property_count; i++) { ATX_Property_Clone(&properties[i], &self->info.properties[i]); } } self->reference_count = 1; return BLT_SUCCESS; }
/*---------------------------------------------------------------------- | BLT_Decoder_Create +---------------------------------------------------------------------*/ BLT_Result BLT_Decoder_Create(BLT_Decoder** decoder) { BLT_Result result; ATX_LOG_FINE("BLT_Decoder::Create"); /* allocate a new decoder object */ *decoder = (BLT_Decoder*)ATX_AllocateZeroMemory(sizeof(BLT_Decoder)); if (*decoder == NULL) { return BLT_ERROR_OUT_OF_MEMORY; } /* get the core object */ result = BLT_Core_Create(&(*decoder)->core); if (BLT_FAILED(result)) goto failed; /* create a stream */ result = BLT_Core_CreateStream((*decoder)->core, &(*decoder)->stream); if (BLT_FAILED(result)) goto failed; /* done */ return BLT_SUCCESS; failed: BLT_Decoder_Destroy(*decoder); return result; }
/*---------------------------------------------------------------------- | BLT_BaseModule_CreateEx +---------------------------------------------------------------------*/ BLT_Result BLT_BaseModule_CreateEx(BLT_CString name, BLT_CString uid, BLT_Flags flags, BLT_Cardinal property_count, const ATX_Property* properties, const BLT_ModuleInterface* module_interface, const ATX_ReferenceableInterface* referenceable_interface, BLT_Size instance_size, BLT_Module** object) { BLT_BaseModule* module; ATX_LOG_FINE_1("creating module name=%s", name); /* allocate memory for the object */ if (instance_size == 0) instance_size = sizeof(BLT_BaseModule); module = (BLT_BaseModule*)ATX_AllocateZeroMemory(instance_size); if (module == NULL) { *object = NULL; return ATX_ERROR_OUT_OF_MEMORY; } /* construct the object */ BLT_BaseModule_ConstructEx(module, name, uid, flags, property_count, properties); /* setup interfaces */ ATX_BASE(module, BLT_Module).iface = module_interface; ATX_BASE(module, ATX_Referenceable).iface = referenceable_interface; *object = &ATX_BASE(module, BLT_Module); return BLT_SUCCESS; }
/*---------------------------------------------------------------------- | AlsaOutput_Create +---------------------------------------------------------------------*/ static BLT_Result AlsaOutput_Create(BLT_Module* module, BLT_Core* core, BLT_ModuleParametersType parameters_type, BLT_AnyConst parameters, BLT_MediaNode** object) { AlsaOutput* output; BLT_MediaNodeConstructor* constructor = (BLT_MediaNodeConstructor*)parameters; ATX_LOG_FINE("creating output"); /* check parameters */ if (parameters == NULL || parameters_type != BLT_MODULE_PARAMETERS_TYPE_MEDIA_NODE_CONSTRUCTOR) { return BLT_ERROR_INVALID_PARAMETERS; } /* allocate memory for the object */ output = ATX_AllocateZeroMemory(sizeof(AlsaOutput)); if (output == NULL) { *object = NULL; return BLT_ERROR_OUT_OF_MEMORY; } /* construct the inherited object */ BLT_BaseMediaNode_Construct(&ATX_BASE(output, BLT_BaseMediaNode), module, core); /* construct the object */ output->state = BLT_ALSA_OUTPUT_STATE_CLOSED; output->device_handle = NULL; output->media_type.sample_rate = 0; output->media_type.channel_count = 0; output->media_type.bits_per_sample = 0; /* parse the name */ if (constructor->name && ATX_StringLength(constructor->name) > 5) { output->device_name = ATX_String_Create(constructor->name+5); } else { output->device_name = ATX_String_Create("default"); } /* setup the expected media type */ BLT_PcmMediaType_Init(&output->expected_media_type); /* setup interfaces */ ATX_SET_INTERFACE_EX(output, AlsaOutput, BLT_BaseMediaNode, BLT_MediaNode); ATX_SET_INTERFACE_EX(output, AlsaOutput, BLT_BaseMediaNode, ATX_Referenceable); ATX_SET_INTERFACE(output, AlsaOutput, BLT_PacketConsumer); ATX_SET_INTERFACE(output, AlsaOutput, BLT_OutputNode); ATX_SET_INTERFACE(output, AlsaOutput, BLT_MediaPort); *object = &ATX_BASE_EX(output, BLT_BaseMediaNode, BLT_MediaNode); return BLT_SUCCESS; }
/*---------------------------------------------------------------------- | ATX_HttpClient_Create +---------------------------------------------------------------------*/ ATX_Result ATX_HttpClient_Create(ATX_HttpClient** client) { /* allocate memory */ *client = (ATX_HttpClient*)ATX_AllocateZeroMemory(sizeof(ATX_HttpClient)); /* construct the object */ (*client)->options.follow_redirect = ATX_TRUE; return ATX_SUCCESS; }
PcmAdapterOutput_GetPacket ATX_END_INTERFACE_MAP /*---------------------------------------------------------------------- | PcmAdapter_Create +---------------------------------------------------------------------*/ static BLT_Result PcmAdapter_Create(BLT_Module* module, BLT_Core* core, BLT_ModuleParametersType parameters_type, BLT_AnyConst parameters, BLT_MediaNode** object) { BLT_MediaNodeConstructor* constructor = (BLT_MediaNodeConstructor*)parameters; PcmAdapter* self; ATX_LOG_FINE("PcmAdapter::Create"); /* check parameters */ if (parameters == NULL || parameters_type != BLT_MODULE_PARAMETERS_TYPE_MEDIA_NODE_CONSTRUCTOR) { return BLT_ERROR_INVALID_PARAMETERS; } /* allocate memory for the object */ self = ATX_AllocateZeroMemory(sizeof(PcmAdapter)); if (self == NULL) { *object = NULL; return BLT_ERROR_OUT_OF_MEMORY; } /* construct the inherited object */ BLT_BaseMediaNode_Construct(&ATX_BASE(self, BLT_BaseMediaNode), module, core); /* check the media type */ if (constructor->spec.output.media_type->id != BLT_MEDIA_TYPE_ID_AUDIO_PCM) { return BLT_ERROR_INVALID_MEDIA_TYPE; } /* construct the object */ self->output.pcm_type = *(BLT_PcmMediaType*)constructor->spec.output.media_type; /* setup interfaces */ ATX_SET_INTERFACE_EX(self, PcmAdapter, BLT_BaseMediaNode, BLT_MediaNode); ATX_SET_INTERFACE_EX(self, PcmAdapter, BLT_BaseMediaNode, ATX_Referenceable); ATX_SET_INTERFACE(&self->input, PcmAdapterInput, BLT_MediaPort); ATX_SET_INTERFACE(&self->input, PcmAdapterInput, BLT_PacketConsumer); ATX_SET_INTERFACE(&self->output, PcmAdapterOutput, BLT_MediaPort); ATX_SET_INTERFACE(&self->output, PcmAdapterOutput, BLT_PacketProducer); *object = &ATX_BASE_EX(self, BLT_BaseMediaNode, BLT_MediaNode); return BLT_SUCCESS; }
WaveFormatterOutput_SetStream ATX_END_INTERFACE_MAP /*---------------------------------------------------------------------- | WaveFormatter_Create +---------------------------------------------------------------------*/ static BLT_Result WaveFormatter_Create(BLT_Module* module, BLT_Core* core, BLT_ModuleParametersType parameters_type, BLT_CString parameters, BLT_MediaNode** object) { WaveFormatter* self; ATX_LOG_FINE("WaveFormatter::Create"); /* check parameters */ if (parameters == NULL || parameters_type != BLT_MODULE_PARAMETERS_TYPE_MEDIA_NODE_CONSTRUCTOR) { return BLT_ERROR_INVALID_PARAMETERS; } /* allocate memory for the object */ self = ATX_AllocateZeroMemory(sizeof(WaveFormatter)); if (self == NULL) { *object = NULL; return BLT_ERROR_OUT_OF_MEMORY; } /* construct the inherited object */ BLT_BaseMediaNode_Construct(&ATX_BASE(self, BLT_BaseMediaNode), module, core); /* setup the input media type */ BLT_PcmMediaType_Init(&self->input.media_type); self->input.media_type.sample_format = BLT_PCM_SAMPLE_FORMAT_SIGNED_INT_LE; /* setup the output media type */ BLT_MediaType_Init(&self->output.media_type, ((WaveFormatterModule*)module)->wav_type_id); /* setup interfaces */ ATX_SET_INTERFACE_EX(self, WaveFormatter, BLT_BaseMediaNode, BLT_MediaNode); ATX_SET_INTERFACE_EX(self, WaveFormatter, BLT_BaseMediaNode, ATX_Referenceable); ATX_SET_INTERFACE(&self->input, WaveFormatterInput, BLT_MediaPort); ATX_SET_INTERFACE(&self->input, WaveFormatterInput, BLT_OutputStreamProvider); ATX_SET_INTERFACE(&self->output, WaveFormatterOutput, BLT_MediaPort); ATX_SET_INTERFACE(&self->output, WaveFormatterOutput, BLT_OutputStreamUser); *object = &ATX_BASE_EX(self, BLT_BaseMediaNode, BLT_MediaNode); return BLT_SUCCESS; }
/*---------------------------------------------------------------------- | SilenceRemover_Create +---------------------------------------------------------------------*/ static BLT_Result SilenceRemover_Create(BLT_Module* module, BLT_Core* core, BLT_ModuleParametersType parameters_type, BLT_AnyConst parameters, BLT_MediaNode** object) { SilenceRemover* self; BLT_Result result; ATX_LOG_FINE("SilenceRemover::Create"); /* check parameters */ if (parameters == NULL || parameters_type != BLT_MODULE_PARAMETERS_TYPE_MEDIA_NODE_CONSTRUCTOR) { return BLT_ERROR_INVALID_PARAMETERS; } /* allocate memory for the object */ self = ATX_AllocateZeroMemory(sizeof(SilenceRemover)); if (self == NULL) { *object = NULL; return BLT_ERROR_OUT_OF_MEMORY; } /* construct the inherited object */ BLT_BaseMediaNode_Construct(&ATX_BASE(self, BLT_BaseMediaNode), module, core); /* construct the object */ self->state = SILENCE_REMOVER_STATE_START_OF_STREAM; /* setup the input and output ports */ result = SilenceRemover_SetupPorts(self); if (BLT_FAILED(result)) { BLT_BaseMediaNode_Destruct(&ATX_BASE(self, BLT_BaseMediaNode)); ATX_FreeMemory(self); *object = NULL; return result; } /* setup interfaces */ ATX_SET_INTERFACE_EX(self, SilenceRemover, BLT_BaseMediaNode, BLT_MediaNode); ATX_SET_INTERFACE_EX(self, SilenceRemover, BLT_BaseMediaNode, ATX_Referenceable); ATX_SET_INTERFACE(&self->input, SilenceRemoverInput, BLT_MediaPort); ATX_SET_INTERFACE(&self->input, SilenceRemoverInput, BLT_PacketConsumer); ATX_SET_INTERFACE(&self->output, SilenceRemoverOutput, BLT_MediaPort); ATX_SET_INTERFACE(&self->output, SilenceRemoverOutput, BLT_PacketProducer); *object = &ATX_BASE_EX(self, BLT_BaseMediaNode, BLT_MediaNode); return BLT_SUCCESS; }
/*---------------------------------------------------------------------- | AacDecoder_Create +---------------------------------------------------------------------*/ static BLT_Result AacDecoder_Create(BLT_Module* module, BLT_Core* core, BLT_ModuleParametersType parameters_type, BLT_CString parameters, BLT_MediaNode** object) { AacDecoder* self; AacDecoderModule* aac_decoder_module = (AacDecoderModule*)module; BLT_Result result; ATX_LOG_FINE("AacDecoder::Create"); /* check parameters */ if (parameters == NULL || parameters_type != BLT_MODULE_PARAMETERS_TYPE_MEDIA_NODE_CONSTRUCTOR) { return BLT_ERROR_INVALID_PARAMETERS; } /* allocate memory for the object */ self = ATX_AllocateZeroMemory(sizeof(AacDecoder)); if (self == NULL) { *object = NULL; return BLT_ERROR_OUT_OF_MEMORY; } /* construct the inherited object */ BLT_BaseMediaNode_Construct(&ATX_BASE(self, BLT_BaseMediaNode), module, core); /* setup the input and output ports */ result = AacDecoder_SetupPorts(self, aac_decoder_module->mp4es_type_id); if (BLT_FAILED(result)) { ATX_FreeMemory(self); *object = NULL; return result; } /* setup interfaces */ ATX_SET_INTERFACE_EX(self, AacDecoder, BLT_BaseMediaNode, BLT_MediaNode); ATX_SET_INTERFACE_EX(self, AacDecoder, BLT_BaseMediaNode, ATX_Referenceable); ATX_SET_INTERFACE(&self->input, AacDecoderInput, BLT_MediaPort); ATX_SET_INTERFACE(&self->input, AacDecoderInput, BLT_PacketConsumer); ATX_SET_INTERFACE(&self->output, AacDecoderOutput, BLT_MediaPort); ATX_SET_INTERFACE(&self->output, AacDecoderOutput, BLT_PacketProducer); *object = &ATX_BASE_EX(self, BLT_BaseMediaNode, BLT_MediaNode); return BLT_SUCCESS; }
/*---------------------------------------------------------------------- | CrossFader_Create +---------------------------------------------------------------------*/ static BLT_Result CrossFader_Create(BLT_Module* module, BLT_Core* core, BLT_ModuleParametersType parameters_type, BLT_CString parameters, ATX_Object* object) { CrossFader* fader; BLT_Result result; ATX_LOG_FINE("CrossFader::Create"); /* check parameters */ if (parameters == NULL || parameters_type != BLT_MODULE_PARAMETERS_TYPE_MEDIA_NODE_CONSTRUCTOR) { return BLT_ERROR_INVALID_PARAMETERS; } /* allocate memory for the object */ fader = ATX_AllocateZeroMemory(sizeof(CrossFader)); if (fader == NULL) { ATX_CLEAR_OBJECT(object); return BLT_ERROR_OUT_OF_MEMORY; } /* construct the inherited object */ BLT_BaseMediaNode_Construct(&fader->base, module, core); /* construct the object */ fader->state = CROSS_FADER_STATE_IN_START; /* setup the input and output ports */ result = CrossFader_SetupPorts(fader); if (BLT_FAILED(result)) { BLT_BaseMediaNode_Destruct(&fader->base); ATX_FreeMemory(fader); ATX_CLEAR_OBJECT(object); return result; } /* construct reference */ ATX_INSTANCE(object) = (ATX_Instance*)fader; ATX_INTERFACE(object) = (ATX_Interface*)&CrossFader_BLT_MediaNodeInterface; return BLT_SUCCESS; }
/*---------------------------------------------------------------------- | StdcFileWrapper_Create +---------------------------------------------------------------------*/ static ATX_Result StdcFileWrapper_Create(FILE* file, ATX_Size size, StdcFileWrapper** wrapper) { /* allocate a new object */ (*wrapper) = ATX_AllocateZeroMemory(sizeof(StdcFileWrapper)); if (*wrapper == NULL) return ATX_ERROR_OUT_OF_MEMORY; /* construct the object */ (*wrapper)->file = file; (*wrapper)->position = 0; (*wrapper)->size = size; (*wrapper)->reference_count = 1; return ATX_SUCCESS; }
/*---------------------------------------------------------------------- | ATX_HttpHeader_Create +---------------------------------------------------------------------*/ static ATX_Result ATX_HttpHeader_Create(ATX_CString name, ATX_CString value, ATX_HttpHeader** header) { /* allocate a new object */ *header = (ATX_HttpHeader*)ATX_AllocateZeroMemory(sizeof(ATX_HttpHeader)); if (*header == NULL) { return ATX_ERROR_OUT_OF_MEMORY; } /* construct the object */ (*header)->name = ATX_String_Create(name); (*header)->value = ATX_String_Create(value); return ATX_SUCCESS; }
/*---------------------------------------------------------------------- | SdlVideoOutput_Create +---------------------------------------------------------------------*/ static BLT_Result SdlVideoOutput_Create(BLT_Module* module, BLT_Core* core, BLT_ModuleParametersType parameters_type, BLT_CString parameters, BLT_MediaNode** object) { SdlVideoOutput* self; /* check parameters */ if (parameters == NULL || parameters_type != BLT_MODULE_PARAMETERS_TYPE_MEDIA_NODE_CONSTRUCTOR) { return BLT_ERROR_INVALID_PARAMETERS; } /* allocate memory for the object */ self = ATX_AllocateZeroMemory(sizeof(SdlVideoOutput)); if (self == NULL) { *object = NULL; return BLT_ERROR_OUT_OF_MEMORY; } /* construct the inherited object */ BLT_BaseMediaNode_Construct(&ATX_BASE(self, BLT_BaseMediaNode), module, core); /* construct the object */ /* setup the expected media type */ BLT_MediaType_Init(&self->expected_media_type, BLT_MEDIA_TYPE_ID_VIDEO_RAW); /*self->expected_media_type.sample_format = BLT_PCM_SAMPLE_FORMAT_SIGNED_INT_NE;*/ SdlVideoOutput_CreateWindow(self); /* setup interfaces */ ATX_SET_INTERFACE_EX(self, SdlVideoOutput, BLT_BaseMediaNode, BLT_MediaNode); ATX_SET_INTERFACE_EX(self, SdlVideoOutput, BLT_BaseMediaNode, ATX_Referenceable); ATX_SET_INTERFACE (self, SdlVideoOutput, BLT_PacketConsumer); ATX_SET_INTERFACE (self, SdlVideoOutput, BLT_OutputNode); ATX_SET_INTERFACE (self, SdlVideoOutput, BLT_MediaPort); *object = &ATX_BASE_EX(self, BLT_BaseMediaNode, BLT_MediaNode); return BLT_SUCCESS; }
/*---------------------------------------------------------------------- | DebugOutput_Create +---------------------------------------------------------------------*/ static BLT_Result DebugOutput_Create(BLT_Module* module, BLT_Core* core, BLT_ModuleParametersType parameters_type, BLT_CString parameters, BLT_MediaNode** object) { DebugOutput* self; BLT_MediaNodeConstructor* constructor = (BLT_MediaNodeConstructor*)parameters; ATX_LOG_FINE("DebugOutput::Create"); /* check parameters */ if (parameters == NULL || parameters_type != BLT_MODULE_PARAMETERS_TYPE_MEDIA_NODE_CONSTRUCTOR) { return BLT_ERROR_INVALID_PARAMETERS; } /* allocate memory for the object */ self = ATX_AllocateZeroMemory(sizeof(DebugOutput)); if (self == NULL) { *object = NULL; return BLT_ERROR_OUT_OF_MEMORY; } /* construct the inherited object */ BLT_BaseMediaNode_Construct(&ATX_BASE(self, BLT_BaseMediaNode), module, core); /* keep the media type info */ BLT_MediaType_Clone(constructor->spec.input.media_type, &self->expected_media_type); /* setup interfaces */ ATX_SET_INTERFACE_EX(self, DebugOutput, BLT_BaseMediaNode, BLT_MediaNode); ATX_SET_INTERFACE_EX(self, DebugOutput, BLT_BaseMediaNode, ATX_Referenceable); ATX_SET_INTERFACE(self, DebugOutput, BLT_PacketConsumer); ATX_SET_INTERFACE(self, DebugOutput, BLT_MediaPort); *object = &ATX_BASE_EX(self, BLT_BaseMediaNode, BLT_MediaNode); return BLT_SUCCESS; }
/*---------------------------------------------------------------------- | ATX_HttpMessage_Create +---------------------------------------------------------------------*/ ATX_Result ATX_HttpMessage_Create(ATX_HttpMessage** message) { ATX_Result result; /* allocate a new object */ *message = (ATX_HttpMessage*)ATX_AllocateZeroMemory(sizeof(ATX_HttpMessage)); if (*message == NULL) { return ATX_ERROR_OUT_OF_MEMORY; } /* construct the object */ result = ATX_HttpMessage_Construct(*message); if (ATX_FAILED(result)) { ATX_FreeMemory(*message); return result; } return ATX_SUCCESS; }
/*---------------------------------------------------------------------- | OsxAudioUnitsOutput_CheckDownmix +---------------------------------------------------------------------*/ static void OsxAudioUnitsOutput_CheckDownmix(OsxAudioUnitsOutput* self) { OSStatus err; UInt32 prop_size; err = AudioDeviceGetPropertyInfo(self->audio_device_id, 0, FALSE, kAudioDevicePropertyStreamConfiguration, &prop_size, NULL); if (err != noErr) return; AudioBufferList* buffers = (AudioBufferList *)ATX_AllocateZeroMemory(prop_size); err = AudioDeviceGetProperty(self->audio_device_id, 0, FALSE, kAudioDevicePropertyStreamConfiguration, &prop_size, buffers); if (err == noErr) { unsigned int i; unsigned int channel_count = 0; for (i = 0; i < buffers->mNumberBuffers; ++i) { channel_count += buffers->mBuffers[i].mNumberChannels; } ATX_LOG_FINE_1("device has %d channels", channel_count); } ATX_FreeMemory(buffers); }
/*---------------------------------------------------------------------- | ATX_HttpRequest_Create +---------------------------------------------------------------------*/ ATX_Result ATX_HttpRequest_Create(ATX_CString method, ATX_CString url, ATX_HttpRequest** request) { ATX_Result result; /* allocate a new object */ *request = (ATX_HttpRequest*)ATX_AllocateZeroMemory(sizeof(ATX_HttpRequest)); if (*request == NULL) { return ATX_ERROR_OUT_OF_MEMORY; } /* construct the base object */ result = ATX_HttpMessage_Construct(&(*request)->base); if (ATX_FAILED(result)) { ATX_FreeMemory((void*)request); return result; } /* construct the object */ (*request)->method = ATX_String_Create(method); result = ATX_HttpUrl_Construct(&(*request)->url, url); if (ATX_FAILED(result)) { ATX_HttpMessage_Destruct(&(*request)->base); ATX_FreeMemory((void*)request); return result; } /* set the host header */ if (!ATX_String_IsEmpty(&(*request)->url.host)) { ATX_HttpMessage_SetHeader((ATX_HttpMessage*)(*request), ATX_HTTP_HEADER_HOST, ATX_CSTR((*request)->url.host)); } return ATX_SUCCESS; }
/*---------------------------------------------------------------------- | ATX_File_Create +---------------------------------------------------------------------*/ ATX_Result ATX_File_Create(const char* filename, ATX_File** object) { StdcFile* file; /* allocate a new object */ file = (StdcFile*)ATX_AllocateZeroMemory(sizeof(StdcFile)); if (file == NULL) { *object = NULL; return ATX_ERROR_OUT_OF_MEMORY; } /* construct the object */ file->name = ATX_String_Create(filename); /* get the size */ if (ATX_StringsEqual(filename, ATX_FILE_STANDARD_INPUT) || ATX_StringsEqual(filename, ATX_FILE_STANDARD_OUTPUT) || ATX_StringsEqual(filename, ATX_FILE_STANDARD_ERROR)) { file->size = 0; } else { struct stat info; if (stat(filename, &info) == 0) { file->size = info.st_size; } else { file->size = 0; } } /* setup the interfaces */ ATX_SET_INTERFACE(file, StdcFile, ATX_File); ATX_SET_INTERFACE(file, StdcFile, ATX_Destroyable); *object = &ATX_BASE(file, ATX_File); return ATX_SUCCESS; }
/*---------------------------------------------------------------------- | OsxAudioUnitsOutput_MapDeviceIndex +---------------------------------------------------------------------*/ static BLT_Result OsxAudioUnitsOutput_MapDeviceName(const char* name, AudioDeviceID* device_id) { OSStatus err; BLT_Result result = BLT_ERROR_NO_SUCH_DEVICE; UInt32 prop_size = 0; AudioDeviceID* devices = NULL; unsigned int device_count = 0; ATX_UInt32 device_index = 0; unsigned int device_selector = 1; char* device_name = NULL; unsigned int i; /* setup a default value */ *device_id = 0; /* check the parameters */ if (name[0] == '\0') return BLT_ERROR_NO_SUCH_DEVICE; /* parse the name */ if (name[0] == '#') { ++name; ATX_LOG_FINE_1("device name = %s", name); } else { if (BLT_FAILED(ATX_ParseInteger32U(name, &device_index, ATX_FALSE))) { return BLT_ERROR_NO_SUCH_DEVICE; } ATX_LOG_FINE_1("device index = %d", device_index); name = NULL; /* 0 means default */ if (device_index == 0) { /* look at the device's streams */ AudioDeviceID default_device_id = 0; prop_size = sizeof(AudioDeviceID); err = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice, &prop_size, &default_device_id); if (err == noErr) { prop_size = 0; err = AudioDeviceGetPropertyInfo(default_device_id, 0, FALSE, kAudioDevicePropertyStreams, &prop_size, NULL); if (err == noErr) { ATX_LOG_FINE_1("device has %d streams", (int)prop_size/4); } } return BLT_SUCCESS; } } /* ask how many devices exist */ err = AudioHardwareGetPropertyInfo(kAudioHardwarePropertyDevices, &prop_size, NULL); if (err != noErr) { ATX_LOG_FINE_1("AudioHardwareGetPropertyInfo failed (%d)", (int)err); return 0; } device_count = prop_size/sizeof(AudioDeviceID); ATX_LOG_FINE_1("found %d devices", device_count); /* allocate memory for the array */ devices = (AudioDeviceID*)ATX_AllocateZeroMemory(sizeof(AudioDeviceID) * device_count); if (devices == NULL) return 0; /* retrieve the list of device IDs */ err = AudioHardwareGetProperty(kAudioHardwarePropertyDevices, &prop_size, devices); if (err != noErr) { ATX_LOG_FINE_1("AudioHardwareGetProperty(kAudioHardwarePropertyDevices) failed (%d)", (int)err); return 0; } /* find the device ID we want */ for (i=0; i<device_count; i++) { /* get the device name */ err = AudioDeviceGetPropertyInfo(devices[i], 0, false, kAudioDevicePropertyDeviceName, &prop_size, NULL); if (err == noErr) { if (device_name) ATX_FreeMemory(device_name); device_name = (char*)ATX_AllocateZeroMemory(prop_size+1); err = AudioDeviceGetProperty(devices[i], 0, false, kAudioDevicePropertyDeviceName, &prop_size, device_name); if (err == noErr) { ATX_LOG_FINE_2("device name [%d] = %s", i, device_name); } /* cleanup the string */ device_name[prop_size] = '\0'; /* NULL-terminate the string */ if (prop_size > 0) { unsigned int x; for (x=prop_size-1; x; x--) { if (device_name[x] == ' ') { device_name[x] = '\0'; } else if (device_name[x]) { break; } } } } else { continue; } /* look at the device's streams */ prop_size = 0; err = AudioDeviceGetPropertyInfo(devices[i], 0, FALSE, kAudioDevicePropertyStreams, &prop_size, NULL); if (err != noErr || prop_size == 0) { ATX_LOG_FINE("skipping device (not an output)"); continue; } if (name) { /* look for a match by name */ if (ATX_StringsEqual(device_name, name)) { *device_id = devices[i]; ATX_LOG_FINE("device selected as output"); result = BLT_SUCCESS; break; } } else { /* look for a match by index */ if (device_selector++ == device_index) { *device_id = devices[i]; ATX_LOG_FINE("device selected as output"); result = BLT_SUCCESS; break; } } } if (device_name) ATX_FreeMemory(device_name); if (devices) ATX_FreeMemory(devices); return result; }
/*---------------------------------------------------------------------- | OsxAudioUnitsOutput_Create +---------------------------------------------------------------------*/ static BLT_Result OsxAudioUnitsOutput_Create(BLT_Module* module, BLT_Core* core, BLT_ModuleParametersType parameters_type, const void* parameters, BLT_MediaNode** object) { OsxAudioUnitsOutput* self; BLT_MediaNodeConstructor* constructor = (BLT_MediaNodeConstructor*)parameters; AudioDeviceID audio_device_id = 0; AudioUnit audio_unit = NULL; Component component; ComponentDescription component_desc; ComponentResult result; BLT_Result blt_result; /* check parameters */ if (parameters == NULL || parameters_type != BLT_MODULE_PARAMETERS_TYPE_MEDIA_NODE_CONSTRUCTOR) { return BLT_ERROR_INVALID_PARAMETERS; } /* parse the name */ if (!ATX_StringsEqualN(constructor->name, "osxau:", 6)) { return BLT_ERROR_INTERNAL; } /* map the name into a device ID */ blt_result = OsxAudioUnitsOutput_MapDeviceName(constructor->name+6, &audio_device_id); if (BLT_FAILED(blt_result)) return blt_result; /* get the default output audio unit */ ATX_SetMemory(&component_desc, 0, sizeof(component_desc)); component_desc.componentType = kAudioUnitType_Output; component_desc.componentSubType = audio_device_id?kAudioUnitSubType_HALOutput:kAudioUnitSubType_DefaultOutput; component_desc.componentManufacturer = kAudioUnitManufacturer_Apple; component_desc.componentFlags = 0; component_desc.componentFlagsMask = 0; component = FindNextComponent(NULL, &component_desc); if (component == NULL) { ATX_LOG_WARNING("FindNextComponent failed"); return BLT_FAILURE; } /* open the audio unit (we will initialize it later) */ result = OpenAComponent(component, &audio_unit); if (result != noErr) { ATX_LOG_WARNING_1("OpenAComponent failed (%d)", (int)result); return BLT_FAILURE; } /* Since SnowLeopard, kAudioHardwarePropertyRunLoop points at the process's main thread. Since not all apps service a run loop on the main thread (like command-line apps), we need to set the run loop to NULL to tell the HAL to run its own thread for this. This is important in order for the HAL to receive events when, for example, the headphones are plugged in or out. NOTE: this was the default before SnowLeopard (10.6), so we only do this if we're 10.6 or after */ { SInt32 major, minor; Gestalt(gestaltSystemVersionMajor, &major); Gestalt(gestaltSystemVersionMinor, &minor); if (major > 10 || (major == 10 && minor >= 6)) { ATX_LOG_INFO("configuring the HAL to use its own thread for the run loop"); CFRunLoopRef null_loop = NULL; AudioObjectPropertyAddress address = { kAudioHardwarePropertyRunLoop, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster }; AudioObjectSetPropertyData(kAudioObjectSystemObject, &address, 0, NULL, sizeof(CFRunLoopRef), &null_loop); } } /* allocate memory for the object */ self = ATX_AllocateZeroMemory(sizeof(OsxAudioUnitsOutput)); if (self == NULL) { *object = NULL; return BLT_ERROR_OUT_OF_MEMORY; } /* construct the inherited object */ BLT_BaseMediaNode_Construct(&ATX_BASE(self, BLT_BaseMediaNode), module, core); /* construct the object */ self->audio_device_id = audio_device_id; self->audio_unit = audio_unit; self->media_type.sample_rate = 0; self->media_type.channel_count = 0; self->media_type.bits_per_sample = 0; /* create a lock */ pthread_mutex_init(&self->lock, NULL); /* create the packet queue */ { ATX_ListDataDestructor destructor = { NULL, OsxAudioUnitsOutput_QueueItemDestructor }; ATX_List_CreateEx(&destructor, &self->packet_queue); self->max_packets_in_queue = BLT_OSX_AUDIO_UNITS_OUTPUT_DEFAULT_PACKET_QUEUE_SIZE; } /* setup the expected media type */ BLT_PcmMediaType_Init(&self->expected_media_type); self->expected_media_type.sample_format = BLT_PCM_SAMPLE_FORMAT_SIGNED_INT_NE; /* setup interfaces */ ATX_SET_INTERFACE_EX(self, OsxAudioUnitsOutput, BLT_BaseMediaNode, BLT_MediaNode); ATX_SET_INTERFACE_EX(self, OsxAudioUnitsOutput, BLT_BaseMediaNode, ATX_Referenceable); ATX_SET_INTERFACE (self, OsxAudioUnitsOutput, BLT_PacketConsumer); ATX_SET_INTERFACE (self, OsxAudioUnitsOutput, BLT_OutputNode); ATX_SET_INTERFACE (self, OsxAudioUnitsOutput, BLT_MediaPort); ATX_SET_INTERFACE (self, OsxAudioUnitsOutput, BLT_VolumeControl); *object = &ATX_BASE_EX(self, BLT_BaseMediaNode, BLT_MediaNode); return BLT_SUCCESS; }
/*---------------------------------------------------------------------- | ATX_FileByteStream_Create +---------------------------------------------------------------------*/ ATX_Result ATX_FileByteStream_Create(const char* filename, ATX_Flags mode, ATX_ByteStream* object) { FileByteStream* stream; int fd; /* decide wheter this is a file or stdin/stdout/stderr */ if (!strcmp(filename, "-stdin")) { fd = 0; } else if (!strcmp(filename, "-stdout")) { fd = 1; } else if (!strcmp(filename, "-stderr")) { fd = 2; } else { int flags = 0; /* compute mode */ if (mode & ATX_FILE_BYTE_STREAM_MODE_READ) { if (mode & ATX_FILE_BYTE_STREAM_MODE_WRITE) { flags |= O_RDWR; } else { flags |= O_RDONLY; } } else { if (mode & ATX_FILE_BYTE_STREAM_MODE_WRITE) { flags |= O_WRONLY; } } if (mode & ATX_FILE_BYTE_STREAM_MODE_CREATE) { flags |= O_CREAT; } if (mode & ATX_FILE_BYTE_STREAM_MODE_TRUNCATE) { flags |= O_TRUNC; } /* try to open the file */ fd = open(filename, flags, S_IWOTH | S_IRGRP | S_IWGRP | S_IWUSR | S_IRUSR); if (fd == -1) { switch (errno) { case EACCES: return ATX_ERROR_ACCESS_DENIED; case ENOENT: return ATX_ERROR_NO_SUCH_FILE; default: return ATX_ERROR_ERRNO(errno); } } } /* allocate new object */ stream = (FileByteStream*)ATX_AllocateZeroMemory(sizeof(FileByteStream)); if (stream == NULL) { ATX_CLEAR_OBJECT(object); return ATX_ERROR_OUT_OF_MEMORY; } /* construct object */ stream->reference_count = 1; stream->fd = fd; stream->offset = 0; /* get the size */ { struct stat info; if (fstat(fd, &info) == 0) { stream->size = info.st_size; } else { stream->size = 0; } } /* return reference */ ATX_INSTANCE(object) = (ATX_ByteStreamInstance*)stream; ATX_INTERFACE(object) = &FileByteStream_ATX_ByteStreamInterface; return ATX_SUCCESS; }
/*---------------------------------------------------------------------- | Mp4ParserOutput_SetSampleDescription +---------------------------------------------------------------------*/ static BLT_Result Mp4ParserOutput_SetSampleDescription(Mp4ParserOutput* self, unsigned int indx) { // if we had a decrypter before, release it now delete self->sample_decrypter; self->sample_decrypter = NULL; // check that the audio track is of the right type AP4_SampleDescription* sample_desc = self->track->GetSampleDescription(indx); if (sample_desc == NULL) { ATX_LOG_FINE("no sample description for track"); return BLT_ERROR_INVALID_MEDIA_FORMAT; } // handle encrypted tracks BLT_Result result = Mp4ParserOutput_ProcessCryptoInfo(self, sample_desc); if (BLT_FAILED(result)) return result; // update the generic part of the stream info BLT_StreamInfo stream_info; stream_info.id = self->track->GetId(); stream_info.duration = self->track->GetDurationMs(); stream_info.mask = BLT_STREAM_INFO_MASK_ID | BLT_STREAM_INFO_MASK_DURATION; // deal with audio details, if this is an audio track AP4_AudioSampleDescription* audio_desc = dynamic_cast<AP4_AudioSampleDescription*>(sample_desc); if (audio_desc) { ATX_LOG_FINE("sample description is audio"); stream_info.type = BLT_STREAM_TYPE_AUDIO; stream_info.channel_count = audio_desc->GetChannelCount(); stream_info.sample_rate = audio_desc->GetSampleRate(); stream_info.mask |= BLT_STREAM_INFO_MASK_TYPE | BLT_STREAM_INFO_MASK_CHANNEL_COUNT | BLT_STREAM_INFO_MASK_SAMPLE_RATE; } else if (self == &self->parser->audio_output) { ATX_LOG_FINE("expected audio sample description, but did not get one"); return BLT_ERROR_INVALID_MEDIA_FORMAT; } AP4_VideoSampleDescription* video_desc = dynamic_cast<AP4_VideoSampleDescription*>(sample_desc); if (video_desc) { ATX_LOG_FINE("sample description is video"); stream_info.type = BLT_STREAM_TYPE_VIDEO; stream_info.width = video_desc->GetWidth(); stream_info.height = video_desc->GetHeight(); stream_info.mask |= BLT_STREAM_INFO_MASK_TYPE | BLT_STREAM_INFO_MASK_WIDTH | BLT_STREAM_INFO_MASK_HEIGHT; } else if (self == &self->parser->video_output) { ATX_LOG_FINE("expected video sample descriton, but did not get one"); return BLT_ERROR_INVALID_MEDIA_FORMAT; } AP4_MpegSampleDescription* mpeg_desc = NULL; if (sample_desc->GetType() == AP4_SampleDescription::TYPE_MPEG) { ATX_LOG_FINE("sample description is of type MPEG"); mpeg_desc = dynamic_cast<AP4_MpegSampleDescription*>(sample_desc); } if (mpeg_desc) { stream_info.data_type = mpeg_desc->GetObjectTypeString(mpeg_desc->GetObjectTypeId()); stream_info.average_bitrate = mpeg_desc->GetAvgBitrate(); stream_info.nominal_bitrate = mpeg_desc->GetAvgBitrate(); stream_info.mask |= BLT_STREAM_INFO_MASK_AVERAGE_BITRATE | BLT_STREAM_INFO_MASK_NOMINAL_BITRATE | BLT_STREAM_INFO_MASK_DATA_TYPE; } // setup the output media type AP4_DataBuffer decoder_info; BLT_MediaTypeId media_type_id = BLT_MEDIA_TYPE_ID_NONE; AP4_UI32 format_or_object_type_id = 0; if (mpeg_desc) { decoder_info.SetData(mpeg_desc->GetDecoderInfo().GetData(), mpeg_desc->GetDecoderInfo().GetDataSize()); media_type_id = self->mp4_es_type_id; format_or_object_type_id = mpeg_desc->GetObjectTypeId(); } else { // here we have to be format-specific for the decoder info stream_info.data_type = AP4_GetFormatName(sample_desc->GetFormat()); stream_info.mask |= BLT_STREAM_INFO_MASK_DATA_TYPE; format_or_object_type_id = sample_desc->GetFormat(); if (sample_desc->GetFormat() == AP4_SAMPLE_FORMAT_AVC1) { // look for an 'avcC' atom AP4_AvccAtom* avcc = static_cast<AP4_AvccAtom*>(sample_desc->GetDetails().GetChild(AP4_ATOM_TYPE_AVCC)); if (avcc) { // pass the avcc payload as the decoder info decoder_info.SetData(avcc->GetRawBytes().GetData(), avcc->GetRawBytes().GetDataSize()); } } else if (sample_desc->GetFormat() == AP4_SAMPLE_FORMAT_ALAC) { // look for an 'alac' atom (either top-level or inside a 'wave') AP4_Atom* alac = sample_desc->GetDetails().GetChild(AP4_SAMPLE_FORMAT_ALAC); if (alac == NULL) { AP4_ContainerAtom* wave = dynamic_cast<AP4_ContainerAtom*>(sample_desc->GetDetails().GetChild(AP4_ATOM_TYPE_WAVE)); if (wave) { alac = wave->GetChild(AP4_SAMPLE_FORMAT_ALAC); } } if (alac) { // pass the alac payload as the decoder info AP4_MemoryByteStream* mbs = new AP4_MemoryByteStream((AP4_Size)alac->GetSize()); alac->WriteFields(*mbs); decoder_info.SetData(mbs->GetData(), mbs->GetDataSize()); mbs->Release(); } } media_type_id = self->iso_base_es_type_id; } BLT_Mp4MediaType* media_type = NULL; unsigned int struct_size = decoder_info.GetDataSize()?decoder_info.GetDataSize()-1:0; if (audio_desc) { struct_size += sizeof(BLT_Mp4AudioMediaType); BLT_Mp4AudioMediaType* audio_type = (BLT_Mp4AudioMediaType*)ATX_AllocateZeroMemory(struct_size);; audio_type->base.stream_type = BLT_MP4_STREAM_TYPE_AUDIO; audio_type->channel_count = audio_desc->GetChannelCount(); audio_type->sample_rate = audio_desc->GetSampleRate(); audio_type->decoder_info_length = decoder_info.GetDataSize(); if (decoder_info.GetDataSize()) { ATX_CopyMemory(&audio_type->decoder_info[0], decoder_info.GetData(), decoder_info.GetDataSize()); } media_type = &audio_type->base; } else { struct_size += sizeof(BLT_Mp4VideoMediaType); BLT_Mp4VideoMediaType* video_type = (BLT_Mp4VideoMediaType*)ATX_AllocateZeroMemory(struct_size); video_type->base.stream_type = BLT_MP4_STREAM_TYPE_VIDEO; video_type->width = video_desc->GetWidth(); video_type->height = video_desc->GetHeight(); video_type->decoder_info_length = decoder_info.GetDataSize(); if (decoder_info.GetDataSize()) { ATX_CopyMemory(&video_type->decoder_info[0], decoder_info.GetData(), decoder_info.GetDataSize()); } media_type = &video_type->base; } media_type->base.id = media_type_id; media_type->base.extension_size = struct_size-sizeof(BLT_MediaType); media_type->format_or_object_type_id = format_or_object_type_id; self->media_type = &media_type->base; self->sample_description_index = indx; // final update to the stream info BLT_Stream_SetInfo(ATX_BASE(self->parser, BLT_BaseMediaNode).context, &stream_info); // enable the track in the linear reader if we have one if (self->parser->input.reader) { self->parser->input.reader->EnableTrack(self->track->GetId()); } return BLT_SUCCESS; }
/*---------------------------------------------------------------------- | FileOutput_Create +---------------------------------------------------------------------*/ static BLT_Result FileOutput_Create(BLT_Module* module, BLT_Core* core, BLT_ModuleParametersType parameters_type, BLT_CString parameters, BLT_MediaNode** object) { FileOutput* self; BLT_MediaNodeConstructor* constructor = (BLT_MediaNodeConstructor*)parameters; BLT_Result result; ATX_LOG_FINE("FileOutput::Create"); /* check parameters */ *object = NULL; if (parameters == NULL || parameters_type != BLT_MODULE_PARAMETERS_TYPE_MEDIA_NODE_CONSTRUCTOR) { return BLT_ERROR_INVALID_PARAMETERS; } /* check the name */ if (constructor->name == NULL || ATX_StringLength(constructor->name) < 4) { return BLT_ERROR_INVALID_PARAMETERS; } /* allocate memory for the object */ self = ATX_AllocateZeroMemory(sizeof(FileOutput)); if (self == NULL) { return BLT_ERROR_OUT_OF_MEMORY; } /* construct the inherited object */ BLT_BaseMediaNode_Construct(&ATX_BASE(self, BLT_BaseMediaNode), module, core); /* figure out the media type */ if (constructor->spec.input.media_type->id == BLT_MEDIA_TYPE_ID_UNKNOWN) { /* unknown type, try to figure it out from the file extension */ BLT_MediaType_Clone(&BLT_MediaType_Unknown, &self->media_type); result = FileOutput_DecideMediaType(self, constructor->name); if (BLT_FAILED(result)) { /* if the type is not found, assume audio/pcm */ BLT_PcmMediaType pcm_type; BLT_PcmMediaType_Init(&pcm_type); BLT_MediaType_Clone((BLT_MediaType*)&pcm_type, &self->media_type); } } else { /* use the media type from the input spec */ BLT_MediaType_Clone(constructor->spec.input.media_type, &self->media_type); } /* create the output file object */ result = ATX_File_Create(constructor->name+5, &self->file); if (BLT_FAILED(result)) { self->file = NULL; goto failure; } /* open the output file */ result = ATX_File_Open(self->file, ATX_FILE_OPEN_MODE_WRITE | ATX_FILE_OPEN_MODE_CREATE | ATX_FILE_OPEN_MODE_TRUNCATE); if (ATX_FAILED(result)) goto failure; /* get the output stream */ result = ATX_File_GetOutputStream(self->file, &self->stream); if (BLT_FAILED(result)) { self->stream = NULL; goto failure; } /* setup interfaces */ ATX_SET_INTERFACE_EX(self, FileOutput, BLT_BaseMediaNode, BLT_MediaNode); ATX_SET_INTERFACE_EX(self, FileOutput, BLT_BaseMediaNode, ATX_Referenceable); ATX_SET_INTERFACE(self, FileOutput, BLT_OutputStreamProvider); ATX_SET_INTERFACE(self, FileOutput, BLT_OutputNode); ATX_SET_INTERFACE(self, FileOutput, BLT_MediaPort); *object = &ATX_BASE_EX(self, BLT_BaseMediaNode, BLT_MediaNode); return BLT_SUCCESS; failure: FileOutput_Destroy(self); *object = NULL; return result; }