/* This file is part of Darling. Copyright (C) 2020 Lubos Dolezel Darling is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Darling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Darling. If not, see . */ #include "AudioFileFormatGeneric.h" #include #include extern "C" { #include } AudioFileFormatGeneric::AudioFileFormatGeneric(UInt32 inFileType, const char* avformatShortName) : AudioFileFormat(inFileType), m_avformatShortName(avformatShortName) { } Boolean AudioFileFormatGeneric::ExtensionIsThisFormat(CFStringRef inExtension) { const char* inStr = CFStringGetCStringPtr(inExtension, kCFStringEncodingUTF8); const Description& desc = description(); for (const char* ext : desc.extensions) { if (::strcasecmp(ext, inStr) == 0) return true; } return false; } void AudioFileFormatGeneric::GetExtensions(CFArrayRef *outArray) { *outArray = toCFArray(description().extensions); } CFArrayRef AudioFileFormatGeneric::toCFArray(const std::vector& array) { std::vector strings; strings.reserve(array.size()); for (const char* str : array) strings.push_back(CFStringCreateWithCString(nullptr, str, kCFStringEncodingUTF8)); CFArrayRef rv = CFArrayCreate(nullptr, (const void**) strings.data(), array.size(), &kCFTypeArrayCallBacks); for (CFStringRef str : strings) CFRelease(str); return rv; } void AudioFileFormatGeneric::GetUTIs(CFArrayRef *outArray) { *outArray = toCFArray(description().utis); } void AudioFileFormatGeneric::GetMIMETypes(CFArrayRef *outArray) { *outArray = toCFArray(description().mimeTypes); } void AudioFileFormatGeneric::GetFileTypeName(CFStringRef *outName) { *outName = CFStringCreateWithCString(nullptr, description().name, kCFStringEncodingUTF8); } UncertainResult AudioFileFormatGeneric::FileDataIsThisFormat(UInt32 inDataByteSize, const void* inData) { std::vector buf; AVProbeData probeData; buf.reserve(inDataByteSize + AVPROBE_PADDING_SIZE); buf.insert(buf.end(), static_cast(inData), static_cast(inData) + inDataByteSize); buf.resize(inDataByteSize + AVPROBE_PADDING_SIZE); probeData.filename = ""; probeData.buf = buf.data(); probeData.buf_size = inDataByteSize; return av_probe_input_format(&probeData, false) != nullptr ? kTrue : kFalse; } AudioFileObject* AudioFileFormatGeneric::New() { // This method is never called from AFPublic return nullptr; } OSStatus AudioFileFormatGeneric::GetAvailableFormatIDs(UInt32* ioDataSize, void* outPropertyData) { const std::vector& formats = description().formats; *ioDataSize = formats.size() * sizeof(UInt32); if (outPropertyData) { UInt32* dest = static_cast(outPropertyData); for (int i = 0; i < formats.size(); i++) dest[i] = formats[i].mFormatID; } return noErr; } OSStatus AudioFileFormatGeneric::GetAvailableStreamDescriptions(UInt32 inFormatID, UInt32* ioDataSize, void* outPropertyData) { int count = 0; for (const Format& format : description().formats) { if (format.mFormatID == inFormatID) { if (outPropertyData) { AudioStreamBasicDescription* ptr = static_cast(outPropertyData); ptr[count] = format; } count++; } } *ioDataSize = count * sizeof(AudioStreamBasicDescription); return noErr; }