diff options
4 files changed, 55 insertions, 18 deletions
diff --git a/src/multimedia/platform/darwin/camera/avfcamerautility.mm b/src/multimedia/platform/darwin/camera/avfcamerautility.mm index 444162523..f5c90bb77 100644 --- a/src/multimedia/platform/darwin/camera/avfcamerautility.mm +++ b/src/multimedia/platform/darwin/camera/avfcamerautility.mm @@ -711,4 +711,37 @@ std::optional<QList<UInt32>> qt_supported_channel_counts_for_format(int codecId) return result; } +QList<UInt32> qt_supported_channel_layout_tags_for_format(int codecId, int noChannels) +{ + QList<UInt32> result; + AudioStreamBasicDescription sf = {}; + sf.mFormatID = codecId; + sf.mChannelsPerFrame = noChannels; + UInt32 size; + OSStatus err = AudioFormatGetPropertyInfo( + kAudioFormatProperty_AvailableEncodeChannelLayoutTags, + sizeof(sf), + &sf, + &size); + + if (err != noErr) + return result; + + UInt32 noTags = (UInt32)size / sizeof(UInt32); + AudioChannelLayoutTag tagsArr[noTags]; + + err = AudioFormatGetProperty(kAudioFormatProperty_AvailableEncodeChannelLayoutTags, + sizeof(sf), + &sf, + &size, + tagsArr); + if (err != noErr) + return result; + + for (UInt32 i = 0; i < noTags; i++) + result << tagsArr[i]; + + return result; +} + QT_END_NAMESPACE diff --git a/src/multimedia/platform/darwin/camera/avfcamerautility_p.h b/src/multimedia/platform/darwin/camera/avfcamerautility_p.h index 26a023be9..00ff4bb29 100644 --- a/src/multimedia/platform/darwin/camera/avfcamerautility_p.h +++ b/src/multimedia/platform/darwin/camera/avfcamerautility_p.h @@ -195,6 +195,7 @@ void qt_set_framerate_limits(AVCaptureDevice *captureDevice, AVCaptureConnection QList<AudioValueRange> qt_supported_sample_rates_for_format(int codecId); QList<AudioValueRange> qt_supported_bit_rates_for_format(int codecId); std::optional<QList<UInt32>> qt_supported_channel_counts_for_format(int codecId); +QList<UInt32> qt_supported_channel_layout_tags_for_format(int codecId, int noChannels); QT_END_NAMESPACE diff --git a/src/multimedia/platform/darwin/camera/avfmediaassetwriter.mm b/src/multimedia/platform/darwin/camera/avfmediaassetwriter.mm index 61f248c72..243f8455a 100644 --- a/src/multimedia/platform/darwin/camera/avfmediaassetwriter.mm +++ b/src/multimedia/platform/darwin/camera/avfmediaassetwriter.mm @@ -529,12 +529,8 @@ using AVFAtomicInt64 = QAtomicInteger<qint64>; m_audioWriterInput.reset(); if (m_audioQueue) { - CMFormatDescriptionRef sourceFormat = session->audioCaptureDevice() - ? session->audioCaptureDevice().activeFormat.formatDescription - : 0; m_audioWriterInput.reset([[AVAssetWriterInput alloc] initWithMediaType:AVMediaTypeAudio - outputSettings:m_audioSettings - sourceFormatHint:sourceFormat]); + outputSettings:m_audioSettings]); if (!m_audioWriterInput) { qWarning() << Q_FUNC_INFO << "failed to create audio writer input"; // But we still can record video. diff --git a/src/multimedia/platform/darwin/camera/avfmediaencoder.mm b/src/multimedia/platform/darwin/camera/avfmediaencoder.mm index 87e7a357f..b669dd960 100644 --- a/src/multimedia/platform/darwin/camera/avfmediaencoder.mm +++ b/src/multimedia/platform/darwin/camera/avfmediaencoder.mm @@ -139,12 +139,14 @@ static NSDictionary *avfAudioSettings(const QMediaEncoderSettings &encoderSettin { NSMutableDictionary *settings = [NSMutableDictionary dictionary]; + // Codec int codecId = QDarwinFormatInfo::audioFormatForCodec(encoderSettings.mediaFormat().audioCodec()); [settings setObject:[NSNumber numberWithInt:codecId] forKey:AVFormatIDKey]; // Setting AVEncoderQualityKey is not allowed when format ID is alac or lpcm if (codecId != kAudioFormatAppleLossless && codecId != kAudioFormatLinearPCM && encoderSettings.encodingMode() == QMediaRecorder::ConstantQualityEncoding) { + // AudioQuality int quality; switch (encoderSettings.quality()) { case QMediaRecorder::VeryLowQuality: @@ -166,6 +168,7 @@ static NSDictionary *avfAudioSettings(const QMediaEncoderSettings &encoderSettin } [settings setObject:[NSNumber numberWithInt:quality] forKey:AVEncoderAudioQualityKey]; } else { + // BitRate bool isBitRateSupported = false; int bitRate = encoderSettings.audioBitRate(); if (bitRate > 0) { @@ -183,6 +186,7 @@ static NSDictionary *avfAudioSettings(const QMediaEncoderSettings &encoderSettin } } + // SampleRate int sampleRate = encoderSettings.audioSampleRate(); bool isSampleRateSupported = false; if (sampleRate >= 8000 && sampleRate <= 192000) { @@ -194,7 +198,11 @@ static NSDictionary *avfAudioSettings(const QMediaEncoderSettings &encoderSettin } } } + if (!isSampleRateSupported) + sampleRate = 44100; + [settings setObject:[NSNumber numberWithInt:sampleRate] forKey:AVSampleRateKey]; + // Channels int channelCount = encoderSettings.audioChannelCount(); bool isChannelCountSupported = false; if (channelCount > 0) { @@ -213,16 +221,20 @@ static NSDictionary *avfAudioSettings(const QMediaEncoderSettings &encoderSettin } } -#ifdef Q_OS_IOS - // Some keys are mandatory only on iOS - if (!isSampleRateSupported) { - sampleRate = 44100; - isSampleRateSupported = true; +if (isChannelCountSupported && channelCount > 2) { + AudioChannelLayout channelLayout; + memset(&channelLayout, 0, sizeof(AudioChannelLayout)); + auto channelLayoutTags = qt_supported_channel_layout_tags_for_format(codecId, channelCount); + if (channelLayoutTags.size()) { + channelLayout.mChannelLayoutTag = channelLayoutTags.first(); + [settings setObject:[NSData dataWithBytes: &channelLayout length: sizeof(channelLayout)] forKey:AVChannelLayoutKey]; + } else { + isChannelCountSupported = false; + } } - if (!isChannelCountSupported) { + if (!isChannelCountSupported) channelCount = 2; - isChannelCountSupported = true; - } + [settings setObject:[NSNumber numberWithInt:channelCount] forKey:AVNumberOfChannelsKey]; if (codecId == kAudioFormatAppleLossless) [settings setObject:[NSNumber numberWithInt:24] forKey:AVEncoderBitDepthHintKey]; @@ -233,11 +245,6 @@ static NSDictionary *avfAudioSettings(const QMediaEncoderSettings &encoderSettin [settings setObject:[NSNumber numberWithInt:NO] forKey:AVLinearPCMIsFloatKey]; [settings setObject:[NSNumber numberWithInt:NO] forKey:AVLinearPCMIsNonInterleaved]; } -#endif - if (isSampleRateSupported) - [settings setObject:[NSNumber numberWithInt:sampleRate] forKey:AVSampleRateKey]; - if (isChannelCountSupported) - [settings setObject:[NSNumber numberWithInt:channelCount] forKey:AVNumberOfChannelsKey]; return settings; } |