this repo has no description
1/*
2This file is part of Darling.
3
4Copyright (C) 2020 Lubos Dolezel
5
6Darling is free software: you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation, either version 3 of the License, or
9(at your option) any later version.
10
11Darling is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with Darling. If not, see <http://www.gnu.org/licenses/>.
18*/
19#include "AudioFileFormatGeneric.h"
20#include <cstring>
21#include <CarbonCore/MacErrors.h>
22
23extern "C" {
24#include <libavformat/avformat.h>
25}
26
27AudioFileFormatGeneric::AudioFileFormatGeneric(UInt32 inFileType, const char* avformatShortName)
28: AudioFileFormat(inFileType), m_avformatShortName(avformatShortName)
29{
30}
31
32Boolean AudioFileFormatGeneric::ExtensionIsThisFormat(CFStringRef inExtension)
33{
34 const char* inStr = CFStringGetCStringPtr(inExtension, kCFStringEncodingUTF8);
35 const Description& desc = description();
36
37 for (const char* ext : desc.extensions)
38 {
39 if (::strcasecmp(ext, inStr) == 0)
40 return true;
41 }
42
43 return false;
44}
45
46void AudioFileFormatGeneric::GetExtensions(CFArrayRef *outArray)
47{
48 *outArray = toCFArray(description().extensions);
49}
50
51CFArrayRef AudioFileFormatGeneric::toCFArray(const std::vector<const char*>& array)
52{
53 std::vector<CFStringRef> strings;
54 strings.reserve(array.size());
55
56 for (const char* str : array)
57 strings.push_back(CFStringCreateWithCString(nullptr, str, kCFStringEncodingUTF8));
58
59 CFArrayRef rv = CFArrayCreate(nullptr, (const void**) strings.data(), array.size(), &kCFTypeArrayCallBacks);
60
61 for (CFStringRef str : strings)
62 CFRelease(str);
63
64 return rv;
65}
66
67void AudioFileFormatGeneric::GetUTIs(CFArrayRef *outArray)
68{
69 *outArray = toCFArray(description().utis);
70}
71
72void AudioFileFormatGeneric::GetMIMETypes(CFArrayRef *outArray)
73{
74 *outArray = toCFArray(description().mimeTypes);
75}
76
77void AudioFileFormatGeneric::GetFileTypeName(CFStringRef *outName)
78{
79 *outName = CFStringCreateWithCString(nullptr, description().name, kCFStringEncodingUTF8);
80}
81
82UncertainResult AudioFileFormatGeneric::FileDataIsThisFormat(UInt32 inDataByteSize, const void* inData)
83{
84 std::vector<uint8_t> buf;
85 AVProbeData probeData;
86
87 buf.reserve(inDataByteSize + AVPROBE_PADDING_SIZE);
88 buf.insert(buf.end(), static_cast<const uint8_t*>(inData), static_cast<const uint8_t*>(inData) + inDataByteSize);
89 buf.resize(inDataByteSize + AVPROBE_PADDING_SIZE);
90
91 probeData.filename = "";
92 probeData.buf = buf.data();
93 probeData.buf_size = inDataByteSize;
94
95 return av_probe_input_format(&probeData, false) != nullptr ? kTrue : kFalse;
96}
97
98AudioFileObject* AudioFileFormatGeneric::New()
99{
100 // This method is never called from AFPublic
101 return nullptr;
102}
103
104OSStatus AudioFileFormatGeneric::GetAvailableFormatIDs(UInt32* ioDataSize, void* outPropertyData)
105{
106 const std::vector<Format>& formats = description().formats;
107
108 *ioDataSize = formats.size() * sizeof(UInt32);
109 if (outPropertyData)
110 {
111 UInt32* dest = static_cast<UInt32*>(outPropertyData);
112 for (int i = 0; i < formats.size(); i++)
113 dest[i] = formats[i].mFormatID;
114 }
115
116 return noErr;
117}
118
119OSStatus AudioFileFormatGeneric::GetAvailableStreamDescriptions(UInt32 inFormatID, UInt32* ioDataSize, void* outPropertyData)
120{
121 int count = 0;
122
123 for (const Format& format : description().formats)
124 {
125 if (format.mFormatID == inFormatID)
126 {
127 if (outPropertyData)
128 {
129 AudioStreamBasicDescription* ptr = static_cast<AudioStreamBasicDescription*>(outPropertyData);
130 ptr[count] = format;
131 }
132 count++;
133 }
134 }
135
136 *ioDataSize = count * sizeof(AudioStreamBasicDescription);
137 return noErr;
138}