diff options
Diffstat (limited to 'dom/media/ipc/MFMediaEngineUtils.h')
-rw-r--r-- | dom/media/ipc/MFMediaEngineUtils.h | 195 |
1 files changed, 195 insertions, 0 deletions
diff --git a/dom/media/ipc/MFMediaEngineUtils.h b/dom/media/ipc/MFMediaEngineUtils.h new file mode 100644 index 0000000000..67f18b6fca --- /dev/null +++ b/dom/media/ipc/MFMediaEngineUtils.h @@ -0,0 +1,195 @@ +/* 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_IPC_MFMEDIAENGINEUTILS_H_ +#define DOM_MEDIA_IPC_MFMEDIAENGINEUTILS_H_ + +#include "MFMediaEngineExtra.h" +#include "ipc/EnumSerializer.h" +#include "mozilla/Logging.h" +#include "mozilla/ProfilerMarkerTypes.h" +#include "nsPrintfCString.h" + +namespace mozilla { + +inline LazyLogModule gMFMediaEngineLog{"MFMediaEngine"}; + +// https://docs.microsoft.com/en-us/windows/win32/api/mfmediaengine/ne-mfmediaengine-mf_media_engine_event +using MFMediaEngineEvent = MF_MEDIA_ENGINE_EVENT; + +// https://docs.microsoft.com/en-us/windows/win32/api/mfmediaengine/ne-mfmediaengine-mf_media_engine_err +using MFMediaEngineError = MF_MEDIA_ENGINE_ERR; + +#define LOG_AND_WARNING(msg, ...) \ + do { \ + NS_WARNING(nsPrintfCString(msg, rv).get()); \ + MOZ_LOG(gMFMediaEngineLog, LogLevel::Debug, \ + ("%s:%d, " msg, __FILE__, __LINE__, ##__VA_ARGS__)); \ + } while (false) + +#ifndef LOG_IF_FAILED +# define LOG_IF_FAILED(x) \ + do { \ + HRESULT rv = x; \ + if (MOZ_UNLIKELY(FAILED(rv))) { \ + LOG_AND_WARNING("(" #x ") failed, rv=%lx", rv); \ + } \ + } while (false) +#endif + +#ifndef RETURN_IF_FAILED +# define RETURN_IF_FAILED(x) \ + do { \ + HRESULT rv = x; \ + if (MOZ_UNLIKELY(FAILED(rv))) { \ + LOG_AND_WARNING("(" #x ") failed, rv=%lx", rv); \ + return rv; \ + } \ + } while (false) +#endif + +#ifndef RETURN_VOID_IF_FAILED +# define RETURN_VOID_IF_FAILED(x) \ + do { \ + HRESULT rv = x; \ + if (MOZ_UNLIKELY(FAILED(rv))) { \ + LOG_AND_WARNING("(" #x ") failed, rv=%lx", rv); \ + return; \ + } \ + } while (false) +#endif + +#ifndef RETURN_PARAM_IF_FAILED +# define RETURN_PARAM_IF_FAILED(x, defaultOut) \ + do { \ + HRESULT rv = x; \ + if (MOZ_UNLIKELY(FAILED(rv))) { \ + LOG_AND_WARNING("(" #x ") failed, rv=%lx", rv); \ + return defaultOut; \ + } \ + } while (false) +#endif + +#ifndef SHUTDOWN_IF_POSSIBLE +# define SHUTDOWN_IF_POSSIBLE(class) \ + do { \ + IMFShutdown* pShutdown = nullptr; \ + HRESULT rv = class->QueryInterface(IID_PPV_ARGS(&pShutdown)); \ + if (SUCCEEDED(rv)) { \ + rv = pShutdown->Shutdown(); \ + if (FAILED(rv)) { \ + LOG_AND_WARNING(#class " failed to shutdown, rv=%lx", rv); \ + } else { \ + MOZ_LOG(gMFMediaEngineLog, LogLevel::Verbose, \ + ((#class " shutdowned successfully"))); \ + } \ + pShutdown->Release(); \ + } else { \ + LOG_AND_WARNING(#class " doesn't support IMFShutdown?, rv=%lx", rv); \ + } \ + } while (false) +#endif + +#define ENGINE_MARKER(markerName) \ + PROFILER_MARKER(markerName, MEDIA_PLAYBACK, {}, MediaEngineMarker, Id()) + +#define ENGINE_MARKER_TEXT(markerName, text) \ + PROFILER_MARKER(markerName, MEDIA_PLAYBACK, {}, MediaEngineTextMarker, Id(), \ + text) + +const char* MediaEventTypeToStr(MediaEventType aType); +const char* MediaEngineEventToStr(MF_MEDIA_ENGINE_EVENT aEvent); +const char* MFMediaEngineErrorToStr(MFMediaEngineError aError); +const char* GUIDToStr(GUID aGUID); +const char* MFVideoRotationFormatToStr(MFVideoRotationFormat aFormat); +const char* MFVideoTransferFunctionToStr(MFVideoTransferFunction aFunc); +const char* MFVideoPrimariesToStr(MFVideoPrimaries aPrimaries); +void ByteArrayFromGUID(REFGUID aGuidIn, nsTArray<uint8_t>& aByteArrayOut); +void GUIDFromByteArray(const nsTArray<uint8_t>& aByteArrayIn, GUID& aGuidOut); +BSTR CreateBSTRFromConstChar(const char* aNarrowStr); + +// See cdm::SubsampleEntry +struct MediaFoundationSubsampleEntry { + uint32_t mClearBytes; + uint32_t mCipherBytes; +}; + +template <typename T> +class ScopedCoMem { + public: + ScopedCoMem() : mPtr(nullptr) {} + + ~ScopedCoMem() { Reset(nullptr); } + + ScopedCoMem(const ScopedCoMem&) = delete; + ScopedCoMem& operator=(const ScopedCoMem&) = delete; + + T** operator&() { // NOLINT + MOZ_ASSERT(mPtr == nullptr); // To catch memory leaks. + return &mPtr; + } + + operator T*() { return mPtr; } + + T* operator->() { + MOZ_ASSERT(mPtr != nullptr); + return mPtr; + } + + const T* operator->() const { + MOZ_ASSERT(mPtr != nullptr); + return mPtr; + } + + explicit operator bool() const { return mPtr; } + + friend bool operator==(const ScopedCoMem& lhs, std::nullptr_t) { + return lhs.Get() == nullptr; + } + + friend bool operator==(std::nullptr_t, const ScopedCoMem& rhs) { + return rhs.Get() == nullptr; + } + + friend bool operator!=(const ScopedCoMem& lhs, std::nullptr_t) { + return lhs.Get() != nullptr; + } + + friend bool operator!=(std::nullptr_t, const ScopedCoMem& rhs) { + return rhs.Get() != nullptr; + } + + void Reset(T* ptr) { + if (mPtr) CoTaskMemFree(mPtr); + mPtr = ptr; + } + + T* Get() const { return mPtr; } + + private: + T* mPtr; +}; + +} // namespace mozilla + +namespace IPC { + +template <> +struct ParamTraits<mozilla::MFMediaEngineError> + : public ContiguousEnumSerializerInclusive< + mozilla::MFMediaEngineError, + mozilla::MFMediaEngineError::MF_MEDIA_ENGINE_ERR_ABORTED, + mozilla::MFMediaEngineError::MF_MEDIA_ENGINE_ERR_ENCRYPTED> {}; + +template <> +struct ParamTraits<mozilla::MFMediaEngineEvent> + : public ContiguousEnumSerializerInclusive< + mozilla::MFMediaEngineEvent, + mozilla::MFMediaEngineEvent::MF_MEDIA_ENGINE_EVENT_LOADSTART, + mozilla::MFMediaEngineEvent:: + MF_MEDIA_ENGINE_EVENT_AUDIOENDPOINTCHANGE> {}; + +} // namespace IPC + +#endif // DOM_MEDIA_IPC_MFMEDIAENGINECHILD_H_ |