Commit 2ad8478d authored by François Grisez's avatar François Grisez

check whether h.264/h.265 encoders are present on the device before...

check whether h.264/h.265 encoders are present on the device before registering the corresponding VideoToolbox filters
parent 9eaed75d
......@@ -17,9 +17,12 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include <array>
#include <sstream>
#include <unordered_map>
#include <VideoToolbox/VTVideoEncoderList.h>
#include "videotoolbox-h264-utilities.h"
#include "videotoolbox-h265-utilities.h"
......@@ -77,6 +80,11 @@ std::string toString(::OSStatus status) {
return message.str();
}
bool VideoToolboxUtilities::encoderIsAvailable() const {
if (_codecAvailability.empty()) loadCodecAvailability();
return _codecAvailability.at(getCodecType());
}
void VideoToolboxUtilities::getParameterSets(const CMFormatDescriptionRef format, MSQueue *outPs) const {
size_t offset = 0;
size_t parameterSetsCount;
......@@ -125,4 +133,26 @@ VideoToolboxUtilities *VideoToolboxUtilities::create(const std::string &mime) {
}
}
void VideoToolboxUtilities::loadCodecAvailability() {
array<CMVideoCodecType,2> codecTypes = { kCMVideoCodecType_H264, kCMVideoCodecType_HEVC };
CFArrayRef encoderLists = nullptr;
VTCopyVideoEncoderList(nullptr, &encoderLists);
for (auto codecType : codecTypes) {
_codecAvailability[codecType] = false;
for (CFIndex i = 0; i < CFArrayGetCount(encoderLists); i++) {
CMVideoCodecType codecType2;
auto dict = static_cast<const CFDictionaryRef>(CFArrayGetValueAtIndex(encoderLists, i));
auto codecTypeNumber = static_cast<const CFNumberRef>(CFDictionaryGetValue(dict, kVTVideoEncoderList_CodecType));
CFNumberGetValue(codecTypeNumber, kCFNumberIntType, &codecType2);
if (codecType == codecType2) {
_codecAvailability[codecType] = true;
break;
}
}
}
CFRelease(encoderLists);
}
std::map<CMVideoCodecType,bool> VideoToolboxUtilities::_codecAvailability;
} // namespace mediastreamer
......@@ -48,6 +48,7 @@ public:
virtual CMVideoCodecType getCodecType() const = 0;
virtual CFStringRef getDefaultProfileLevel() const = 0;
bool encoderIsAvailable() const;
void getParameterSets(const CMFormatDescriptionRef format, MSQueue *outPs) const;
CMFormatDescriptionRef createFormatDescription(const H26xParameterSetsStore &psStore) const;
......@@ -56,6 +57,10 @@ public:
protected:
virtual void getParameterSet(const CMFormatDescriptionRef format, size_t offset, const uint8_t *&parameterSet, size_t &parameterSetSize, size_t &parameterSetsCount) const = 0;
virtual CMFormatDescriptionRef createFormatDescription(size_t parameterSetsCount, const uint8_t *parameterSets[], const size_t parameterSetSizes[]) const = 0;
static void loadCodecAvailability();
static std::map<CMVideoCodecType,bool> _codecAvailability;
};
} // namespace mediastreamer
......@@ -23,6 +23,7 @@
#include "h26x/h26x-encoder-filter.h"
#include "h26x/videotoolbox-decoder.h"
#include "h26x/videotoolbox-encoder.h"
#include "h26x/videotoolbox-utils.h"
using namespace std;
......@@ -83,9 +84,14 @@ extern "C" void _register_videotoolbox_if_supported(MSFactory *factory) {
ms_message("VideoToolbox H264 codec is not supported on simulators");
#else
if (kCFCoreFoundationVersionNumber >= 744.00) { // MacOS >= 10.8 or iOS >= 8.0
ms_message("Registering VideoToolbox H264 codec");
ms_factory_register_filter(factory, &ms_VideoToolboxH264Encoder_desc);
ms_factory_register_filter(factory, &ms_VideoToolboxH264Decoder_desc);
unique_ptr<VideoToolboxUtilities> codecInfo(VideoToolboxUtilities::create("video/avc"));
if (codecInfo->encoderIsAvailable()) {
ms_message("Registering VideoToolbox H264 codec");
ms_factory_register_filter(factory, &ms_VideoToolboxH264Encoder_desc);
ms_factory_register_filter(factory, &ms_VideoToolboxH264Decoder_desc);
} else {
ms_message("No H264 encoder found on this device");
}
} else {
ms_message("Cannot register VideoToolbox H264 codec. That "
"requires iOS 8 or MacOS 10.8");
......@@ -93,9 +99,14 @@ extern "C" void _register_videotoolbox_if_supported(MSFactory *factory) {
#if TARGET_OS_IPHONE
if (kCFCoreFoundationVersionNumber >= 1400) { // MacOS >= 10.13 or iOS >= 11.0
ms_message("Registering VideoToolbox H265 codec");
ms_factory_register_filter(factory, &ms_VideoToolboxH265Encoder_desc);
ms_factory_register_filter(factory, &ms_VideoToolboxH265Decoder_desc);
unique_ptr<VideoToolboxUtilities> codecInfo(VideoToolboxUtilities::create("video/hevc"));
if (codecInfo->encoderIsAvailable()) {
ms_message("Registering VideoToolbox H265 codec");
ms_factory_register_filter(factory, &ms_VideoToolboxH265Encoder_desc);
ms_factory_register_filter(factory, &ms_VideoToolboxH265Decoder_desc);
} else {
ms_message("No H265 encoder found on this device");
}
} else {
ms_message("Cannot register VideoToolbox H265 codec. That "
"requires iOS 11.0 or MacOS 10.13");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment