mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-23 21:01:08 +00:00
76c0a48045
Differential Revision: https://phabricator.services.mozilla.com/D215396
225 lines
7.8 KiB
C++
225 lines
7.8 KiB
C++
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* vim:set ts=2 sw=2 sts=2 et cindent: */
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
#ifndef DOM_MEDIA_PLATFORMS_MEDIACODECSSUPPORT_H_
|
|
#define DOM_MEDIA_PLATFORMS_MEDIACODECSSUPPORT_H_
|
|
#include <array>
|
|
|
|
#include "mozilla/Atomics.h"
|
|
#include "mozilla/ClearOnShutdown.h"
|
|
#include "mozilla/EnumSet.h"
|
|
#include "mozilla/StaticMutex.h"
|
|
#include "nsString.h"
|
|
#include "nsTHashMap.h"
|
|
#include "nsThreadUtils.h"
|
|
|
|
namespace mozilla::media {
|
|
// List of codecs we support, used in the below macros
|
|
// to generate MediaCodec and MediaCodecSupports enums.
|
|
#define CODEC_LIST \
|
|
X(H264) \
|
|
X(VP8) \
|
|
X(VP9) \
|
|
X(AV1) \
|
|
X(HEVC) \
|
|
X(AAC) \
|
|
X(FLAC) \
|
|
X(MP3) \
|
|
X(Opus) \
|
|
X(Vorbis) \
|
|
X(Wave)
|
|
|
|
// Generate MediaCodec enum with the names of each codec we support.
|
|
// Example: MediaCodec::H264
|
|
enum class MediaCodec : int {
|
|
#define X(name) name,
|
|
CODEC_LIST
|
|
#undef X
|
|
SENTINEL
|
|
};
|
|
using MediaCodecSet = EnumSet<MediaCodec, uint64_t>;
|
|
|
|
// Helper macros used to create codec-specific SW/HW decode enums below.
|
|
#define SW_DECODE(codec) codec##SoftwareDecode
|
|
#define HW_DECODE(codec) codec##HardwareDecode
|
|
|
|
// For codec which we can do hardware decoding once user installs the free
|
|
// platform extension, eg. AV1 on Windows
|
|
#define LACK_HW_EXTENSION(codec) codec##LackOfExtension
|
|
|
|
// Generate the MediaCodecsSupport enum, containing
|
|
// codec-specific SW/HW decode/encode information.
|
|
// Entries for HW audio decode/encode should never be set as we
|
|
// don't support HW audio decode/encode, but they are included
|
|
// for debug purposes / check for erroneous PDM return values.
|
|
// Example: MediaCodecsSupport::AACSoftwareDecode
|
|
enum class MediaCodecsSupport : int {
|
|
#define X(name) SW_DECODE(name), HW_DECODE(name), LACK_HW_EXTENSION(name),
|
|
CODEC_LIST
|
|
#undef X
|
|
SENTINEL
|
|
};
|
|
#undef SW_DECODE
|
|
#undef HW_DECODE
|
|
#undef CODEC_LIST // end of macros!
|
|
|
|
// Enumset containing per-codec SW/HW support
|
|
using MediaCodecsSupported = EnumSet<MediaCodecsSupport, uint64_t>;
|
|
|
|
// Codec-agnostic SW/HW decode support information.
|
|
enum class DecodeSupport : int {
|
|
SoftwareDecode,
|
|
HardwareDecode,
|
|
UnsureDueToLackOfExtension,
|
|
};
|
|
using DecodeSupportSet = EnumSet<DecodeSupport, uint64_t>;
|
|
|
|
// CodecDefinition stores information needed to convert / index
|
|
// codec support information between types. See: GetAllCodecDefinitions()
|
|
struct CodecDefinition {
|
|
MediaCodec codec = MediaCodec::SENTINEL;
|
|
const char* commonName = "Undefined codec name";
|
|
const char* mimeTypeString = "Undefined MIME type string";
|
|
MediaCodecsSupport swDecodeSupport = MediaCodecsSupport::SENTINEL;
|
|
MediaCodecsSupport hwDecodeSupport = MediaCodecsSupport::SENTINEL;
|
|
MediaCodecsSupport lackOfHWExtenstion = MediaCodecsSupport::SENTINEL;
|
|
};
|
|
|
|
// Singleton class used to collect, manage, and report codec support data.
|
|
class MCSInfo final {
|
|
public:
|
|
// Add codec support information to our aggregated list of supported codecs.
|
|
// Incoming support info is merged with the current support info.
|
|
// This is because different PDMs may report different codec support
|
|
// information, so merging their results allows us to maintain a
|
|
// cumulative support list without overwriting any existing data.
|
|
static void AddSupport(const MediaCodecsSupported& aSupport);
|
|
|
|
// Return a cumulative list of codec support information.
|
|
// Each call to AddSupport adds to or updates this list.
|
|
// This support information can be used to create user-readable strings
|
|
// to report codec support information in about:support.
|
|
static MediaCodecsSupported GetSupport();
|
|
|
|
// Reset codec support information saved from calls to AddSupport().
|
|
static void ResetSupport();
|
|
|
|
// Query a MediaCodecsSupported EnumSet for codec-specific SW/HW support enums
|
|
// and return general support information as stored in a DecodeSupportSet.
|
|
//
|
|
// Example input:
|
|
//
|
|
// aCodec: MediaCodec::H264
|
|
// aDecode: MediaCodecsSupport {
|
|
// MediaCodecsSupport::AACSoftwareDecode
|
|
// MediaCodecsSupport::H264HardwareDecode,
|
|
// MediaCodecsSupport::H264SoftwareDecode,
|
|
// MediaCodecsSupport::VP8SoftwareDecode,
|
|
// }
|
|
//
|
|
// Example output:
|
|
//
|
|
// DecodeSupportSet {
|
|
// DecodeSupport::SoftwareDecode,
|
|
// DecodeSupport::HardwareDecode
|
|
// }
|
|
//
|
|
static DecodeSupportSet GetDecodeSupportSet(
|
|
const MediaCodec& aCodec, const MediaCodecsSupported& aSupported);
|
|
|
|
// Return codec-specific SW/HW support enums for a given codec.
|
|
// The DecodeSupportSet argument is used which codec-specific SW/HW
|
|
// support values are returned, if any.
|
|
//
|
|
// Example input:
|
|
// aCodec: MediaCodec::VP8
|
|
// aSupportSet: DecodeSupportSet {DecodeSupport::SoftwareDecode}
|
|
//
|
|
// Example output:
|
|
// MediaCodecsSupported {MediaCodecsSupport::VP8SoftwareDecode}
|
|
//
|
|
static MediaCodecsSupported GetDecodeMediaCodecsSupported(
|
|
const MediaCodec& aCodec, const DecodeSupportSet& aSupportSet);
|
|
|
|
// Generate a plaintext description for the SW/HW support information
|
|
// contained in a MediaCodecsSupported EnumSet.
|
|
//
|
|
// Example input:
|
|
// MediaCodecsSupported {
|
|
// MediaCodecsSupport::H264SoftwareDecode,
|
|
// MediaCodecsSupport::H264HardwareDecode,
|
|
// MediaCodecsSupport::VP8SoftwareDecode
|
|
// }
|
|
//
|
|
// Example output (returned via argument aCodecString)
|
|
//
|
|
// "SW H264 decode\n
|
|
// HW H264 decode\n
|
|
// SW VP8 decode"_ns
|
|
//
|
|
static void GetMediaCodecsSupportedString(
|
|
nsCString& aSupportString, const MediaCodecsSupported& aSupportedCodecs);
|
|
|
|
// Returns a MediaCodec enum representing the given MIME type string.
|
|
//
|
|
// Example input:
|
|
// "audio/flac"_ns
|
|
//
|
|
// Example output:
|
|
// MediaCodec::FLAC
|
|
//
|
|
static MediaCodec GetMediaCodecFromMimeType(const nsACString& aMimeType);
|
|
|
|
// Returns array of hardcoded codec definitions.
|
|
static std::array<CodecDefinition, 13> GetAllCodecDefinitions();
|
|
|
|
// Parses an array of MIME type strings and returns a MediaCodecSet.
|
|
static MediaCodecSet GetMediaCodecSetFromMimeTypes(
|
|
const nsTArray<nsCString>& aCodecStrings);
|
|
|
|
// Returns a MediaCodecsSupport enum corresponding to the provided
|
|
// codec type and decode support level requested.
|
|
static MediaCodecsSupport GetMediaCodecsSupportEnum(
|
|
const MediaCodec& aCodec, const DecodeSupport& aSupport);
|
|
|
|
// Returns true if SW/HW decode enum for a given codec is present in the args.
|
|
static bool SupportsSoftwareDecode(
|
|
const MediaCodecsSupported& aSupportedCodecs, const MediaCodec& aCodec);
|
|
static bool SupportsHardwareDecode(
|
|
const MediaCodecsSupported& aSupportedCodecs, const MediaCodec& aCodec);
|
|
|
|
MCSInfo(MCSInfo const&) = delete;
|
|
void operator=(MCSInfo const&) = delete;
|
|
~MCSInfo() = default;
|
|
|
|
private:
|
|
MCSInfo();
|
|
static MCSInfo* GetInstance();
|
|
|
|
// Returns a codec definition by MIME type name ("media/vp9")
|
|
// or "common" name ("VP9")
|
|
static CodecDefinition GetCodecDefinition(const MediaCodec& aCodec);
|
|
|
|
UniquePtr<nsTHashMap<MediaCodecsSupport, CodecDefinition>> mHashTableMCS;
|
|
UniquePtr<nsTHashMap<const char*, CodecDefinition>> mHashTableString;
|
|
UniquePtr<nsTHashMap<MediaCodec, CodecDefinition>> mHashTableCodec;
|
|
MediaCodecsSupported mSupport;
|
|
};
|
|
} // namespace mozilla::media
|
|
|
|
namespace mozilla {
|
|
// Used for IPDL serialization.
|
|
// The 'value' has to be the biggest enum from MediaCodecsSupport.
|
|
template <typename T>
|
|
struct MaxEnumValue;
|
|
template <>
|
|
struct MaxEnumValue<media::MediaCodecsSupport> {
|
|
static constexpr unsigned int value =
|
|
static_cast<unsigned int>(media::MediaCodecsSupport::SENTINEL);
|
|
};
|
|
} // namespace mozilla
|
|
|
|
#endif /* MediaCodecsSupport_h_ */
|