mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 930833 - Extract more WMF utility functions to WMFUtils.h/cpp. r=padenot
This commit is contained in:
parent
9a1f3c003b
commit
9125652ed9
@ -31,6 +31,13 @@ which makes Windows Media Foundation unavailable.
|
||||
#include <initguid.h>
|
||||
#include <d3d9.h>
|
||||
#include <dxva2api.h>
|
||||
#include <wmcodecdsp.h>
|
||||
|
||||
// Some SDK versions don't define the AAC decoder CLSID.
|
||||
#ifndef CLSID_CMSAACDecMFT
|
||||
extern const CLSID CLSID_CMSAACDecMFT;
|
||||
#define WMF_MUST_DEFINE_AAC_MFT_CLSID
|
||||
#endif
|
||||
|
||||
namespace mozilla {
|
||||
namespace wmf {
|
||||
@ -104,6 +111,13 @@ HRESULT MFGetService(IUnknown *punkObject,
|
||||
|
||||
HRESULT DXVA2CreateDirect3DDeviceManager9(UINT *pResetToken,
|
||||
IDirect3DDeviceManager9 **ppDXVAManager);
|
||||
|
||||
HRESULT MFCreateSample(IMFSample **ppIMFSample);
|
||||
|
||||
HRESULT MFCreateAlignedMemoryBuffer(DWORD cbMaxLength,
|
||||
DWORD fAlignmentFlags,
|
||||
IMFMediaBuffer **ppBuffer);
|
||||
|
||||
} // end namespace wmf
|
||||
} // end namespace mozilla
|
||||
|
||||
|
@ -284,93 +284,6 @@ GetSourceReaderCanSeek(IMFSourceReader* aReader, bool& aOutCanSeek)
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT
|
||||
GetDefaultStride(IMFMediaType *aType, uint32_t* aOutStride)
|
||||
{
|
||||
// Try to get the default stride from the media type.
|
||||
HRESULT hr = aType->GetUINT32(MF_MT_DEFAULT_STRIDE, aOutStride);
|
||||
if (SUCCEEDED(hr)) {
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
// Stride attribute not set, calculate it.
|
||||
GUID subtype = GUID_NULL;
|
||||
uint32_t width = 0;
|
||||
uint32_t height = 0;
|
||||
|
||||
hr = aType->GetGUID(MF_MT_SUBTYPE, &subtype);
|
||||
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
||||
|
||||
hr = MFGetAttributeSize(aType, MF_MT_FRAME_SIZE, &width, &height);
|
||||
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
||||
|
||||
hr = wmf::MFGetStrideForBitmapInfoHeader(subtype.Data1, width, (LONG*)(aOutStride));
|
||||
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static int32_t
|
||||
MFOffsetToInt32(const MFOffset& aOffset)
|
||||
{
|
||||
return int32_t(aOffset.value + (aOffset.fract / 65536.0f));
|
||||
}
|
||||
|
||||
// Gets the sub-region of the video frame that should be displayed.
|
||||
// See: http://msdn.microsoft.com/en-us/library/windows/desktop/bb530115(v=vs.85).aspx
|
||||
static HRESULT
|
||||
GetPictureRegion(IMFMediaType* aMediaType, nsIntRect& aOutPictureRegion)
|
||||
{
|
||||
// Determine if "pan and scan" is enabled for this media. If it is, we
|
||||
// only display a region of the video frame, not the entire frame.
|
||||
BOOL panScan = MFGetAttributeUINT32(aMediaType, MF_MT_PAN_SCAN_ENABLED, FALSE);
|
||||
|
||||
// If pan and scan mode is enabled. Try to get the display region.
|
||||
HRESULT hr = E_FAIL;
|
||||
MFVideoArea videoArea;
|
||||
memset(&videoArea, 0, sizeof(MFVideoArea));
|
||||
if (panScan) {
|
||||
hr = aMediaType->GetBlob(MF_MT_PAN_SCAN_APERTURE,
|
||||
(UINT8*)&videoArea,
|
||||
sizeof(MFVideoArea),
|
||||
nullptr);
|
||||
}
|
||||
|
||||
// If we're not in pan-and-scan mode, or the pan-and-scan region is not set,
|
||||
// check for a minimimum display aperture.
|
||||
if (!panScan || hr == MF_E_ATTRIBUTENOTFOUND) {
|
||||
hr = aMediaType->GetBlob(MF_MT_MINIMUM_DISPLAY_APERTURE,
|
||||
(UINT8*)&videoArea,
|
||||
sizeof(MFVideoArea),
|
||||
nullptr);
|
||||
}
|
||||
|
||||
if (hr == MF_E_ATTRIBUTENOTFOUND) {
|
||||
// Minimum display aperture is not set, for "backward compatibility with
|
||||
// some components", check for a geometric aperture.
|
||||
hr = aMediaType->GetBlob(MF_MT_GEOMETRIC_APERTURE,
|
||||
(UINT8*)&videoArea,
|
||||
sizeof(MFVideoArea),
|
||||
nullptr);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr)) {
|
||||
// The media specified a picture region, return it.
|
||||
aOutPictureRegion = nsIntRect(MFOffsetToInt32(videoArea.OffsetX),
|
||||
MFOffsetToInt32(videoArea.OffsetY),
|
||||
videoArea.Area.cx,
|
||||
videoArea.Area.cy);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
// No picture region defined, fall back to using the entire video area.
|
||||
UINT32 width = 0, height = 0;
|
||||
hr = MFGetAttributeSize(aMediaType, MF_MT_FRAME_SIZE, &width, &height);
|
||||
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
||||
aOutPictureRegion = nsIntRect(0, 0, width, height);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
WMFReader::ConfigureVideoFrameGeometry(IMFMediaType* aMediaType)
|
||||
{
|
||||
@ -639,39 +552,6 @@ WMFReader::ReadMetadata(MediaInfo* aInfo,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static int64_t
|
||||
GetSampleDuration(IMFSample* aSample)
|
||||
{
|
||||
int64_t duration = 0;
|
||||
aSample->GetSampleDuration(&duration);
|
||||
return HNsToUsecs(duration);
|
||||
}
|
||||
|
||||
HRESULT
|
||||
HNsToFrames(int64_t aHNs, uint32_t aRate, int64_t* aOutFrames)
|
||||
{
|
||||
MOZ_ASSERT(aOutFrames);
|
||||
const int64_t HNS_PER_S = USECS_PER_S * 10;
|
||||
CheckedInt<int64_t> i = aHNs;
|
||||
i *= aRate;
|
||||
i /= HNS_PER_S;
|
||||
NS_ENSURE_TRUE(i.isValid(), E_FAIL);
|
||||
*aOutFrames = i.value();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
FramesToUsecs(int64_t aSamples, uint32_t aRate, int64_t* aOutUsecs)
|
||||
{
|
||||
MOZ_ASSERT(aOutUsecs);
|
||||
CheckedInt<int64_t> i = aSamples;
|
||||
i *= USECS_PER_S;
|
||||
i /= aRate;
|
||||
NS_ENSURE_TRUE(i.isValid(), E_FAIL);
|
||||
*aOutUsecs = i.value();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
WMFReader::DecodeAudioData()
|
||||
{
|
||||
|
@ -11,9 +11,17 @@
|
||||
#include "nsThreadUtils.h"
|
||||
#include "WinUtils.h"
|
||||
#include "nsWindowsHelpers.h"
|
||||
#include "mozilla/CheckedInt.h"
|
||||
#include "VideoUtils.h"
|
||||
|
||||
using namespace mozilla::widget;
|
||||
|
||||
#ifdef WMF_MUST_DEFINE_AAC_MFT_CLSID
|
||||
// Some SDK versions don't define the AAC decoder CLSID.
|
||||
// {32D186A7-218F-4C75-8876-DD77273A8999}
|
||||
DEFINE_GUID(CLSID_CMSAACDecMFT, 0x32D186A7, 0x218F, 0x4C75, 0x88, 0x76, 0xDD, 0x77, 0x27, 0x3A, 0x89, 0x99);
|
||||
#endif
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
struct GuidToName {
|
||||
@ -213,13 +221,138 @@ DoGetInterface(IUnknown* aUnknown, void** aInterface)
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
namespace wmf {
|
||||
HRESULT
|
||||
HNsToFrames(int64_t aHNs, uint32_t aRate, int64_t* aOutFrames)
|
||||
{
|
||||
MOZ_ASSERT(aOutFrames);
|
||||
const int64_t HNS_PER_S = USECS_PER_S * 10;
|
||||
CheckedInt<int64_t> i = aHNs;
|
||||
i *= aRate;
|
||||
i /= HNS_PER_S;
|
||||
NS_ENSURE_TRUE(i.isValid(), E_FAIL);
|
||||
*aOutFrames = i.value();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
// Some SDK versions don't define the AAC decoder CLSID.
|
||||
#ifndef CLSID_CMSAACDecMFT
|
||||
// {32D186A7-218F-4C75-8876-DD77273A8999}
|
||||
DEFINE_GUID(CLSID_CMSAACDecMFT, 0x32D186A7, 0x218F, 0x4C75, 0x88, 0x76, 0xDD, 0x77, 0x27, 0x3A, 0x89, 0x99);
|
||||
#endif
|
||||
HRESULT
|
||||
FramesToUsecs(int64_t aSamples, uint32_t aRate, int64_t* aOutUsecs)
|
||||
{
|
||||
MOZ_ASSERT(aOutUsecs);
|
||||
CheckedInt<int64_t> i = aSamples;
|
||||
i *= USECS_PER_S;
|
||||
i /= aRate;
|
||||
NS_ENSURE_TRUE(i.isValid(), E_FAIL);
|
||||
*aOutUsecs = i.value();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
GetDefaultStride(IMFMediaType *aType, uint32_t* aOutStride)
|
||||
{
|
||||
// Try to get the default stride from the media type.
|
||||
HRESULT hr = aType->GetUINT32(MF_MT_DEFAULT_STRIDE, aOutStride);
|
||||
if (SUCCEEDED(hr)) {
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
// Stride attribute not set, calculate it.
|
||||
GUID subtype = GUID_NULL;
|
||||
uint32_t width = 0;
|
||||
uint32_t height = 0;
|
||||
|
||||
hr = aType->GetGUID(MF_MT_SUBTYPE, &subtype);
|
||||
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
||||
|
||||
hr = MFGetAttributeSize(aType, MF_MT_FRAME_SIZE, &width, &height);
|
||||
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
||||
|
||||
hr = wmf::MFGetStrideForBitmapInfoHeader(subtype.Data1, width, (LONG*)(aOutStride));
|
||||
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
int32_t
|
||||
MFOffsetToInt32(const MFOffset& aOffset)
|
||||
{
|
||||
return int32_t(aOffset.value + (aOffset.fract / 65536.0f));
|
||||
}
|
||||
|
||||
int64_t
|
||||
GetSampleDuration(IMFSample* aSample)
|
||||
{
|
||||
NS_ENSURE_TRUE(aSample, -1);
|
||||
int64_t duration = 0;
|
||||
aSample->GetSampleDuration(&duration);
|
||||
return HNsToUsecs(duration);
|
||||
}
|
||||
|
||||
int64_t
|
||||
GetSampleTime(IMFSample* aSample)
|
||||
{
|
||||
NS_ENSURE_TRUE(aSample, -1);
|
||||
LONGLONG timestampHns = 0;
|
||||
HRESULT hr = aSample->GetSampleTime(×tampHns);
|
||||
NS_ENSURE_TRUE(SUCCEEDED(hr), -1);
|
||||
return HNsToUsecs(timestampHns);
|
||||
}
|
||||
|
||||
// Gets the sub-region of the video frame that should be displayed.
|
||||
// See: http://msdn.microsoft.com/en-us/library/windows/desktop/bb530115(v=vs.85).aspx
|
||||
HRESULT
|
||||
GetPictureRegion(IMFMediaType* aMediaType, nsIntRect& aOutPictureRegion)
|
||||
{
|
||||
// Determine if "pan and scan" is enabled for this media. If it is, we
|
||||
// only display a region of the video frame, not the entire frame.
|
||||
BOOL panScan = MFGetAttributeUINT32(aMediaType, MF_MT_PAN_SCAN_ENABLED, FALSE);
|
||||
|
||||
// If pan and scan mode is enabled. Try to get the display region.
|
||||
HRESULT hr = E_FAIL;
|
||||
MFVideoArea videoArea;
|
||||
memset(&videoArea, 0, sizeof(MFVideoArea));
|
||||
if (panScan) {
|
||||
hr = aMediaType->GetBlob(MF_MT_PAN_SCAN_APERTURE,
|
||||
(UINT8*)&videoArea,
|
||||
sizeof(MFVideoArea),
|
||||
nullptr);
|
||||
}
|
||||
|
||||
// If we're not in pan-and-scan mode, or the pan-and-scan region is not set,
|
||||
// check for a minimimum display aperture.
|
||||
if (!panScan || hr == MF_E_ATTRIBUTENOTFOUND) {
|
||||
hr = aMediaType->GetBlob(MF_MT_MINIMUM_DISPLAY_APERTURE,
|
||||
(UINT8*)&videoArea,
|
||||
sizeof(MFVideoArea),
|
||||
nullptr);
|
||||
}
|
||||
|
||||
if (hr == MF_E_ATTRIBUTENOTFOUND) {
|
||||
// Minimum display aperture is not set, for "backward compatibility with
|
||||
// some components", check for a geometric aperture.
|
||||
hr = aMediaType->GetBlob(MF_MT_GEOMETRIC_APERTURE,
|
||||
(UINT8*)&videoArea,
|
||||
sizeof(MFVideoArea),
|
||||
nullptr);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr)) {
|
||||
// The media specified a picture region, return it.
|
||||
aOutPictureRegion = nsIntRect(MFOffsetToInt32(videoArea.OffsetX),
|
||||
MFOffsetToInt32(videoArea.OffsetY),
|
||||
videoArea.Area.cx,
|
||||
videoArea.Area.cy);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
// No picture region defined, fall back to using the entire video area.
|
||||
UINT32 width = 0, height = 0;
|
||||
hr = MFGetAttributeSize(aMediaType, MF_MT_FRAME_SIZE, &width, &height);
|
||||
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
||||
aOutPictureRegion = nsIntRect(0, 0, width, height);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
namespace wmf {
|
||||
|
||||
static bool
|
||||
IsSupportedDecoder(const GUID& aDecoderGUID)
|
||||
@ -533,5 +666,23 @@ DXVA2CreateDirect3DDeviceManager9(UINT *pResetToken,
|
||||
return (DXVA2CreateDirect3DDeviceManager9Ptr)(pResetToken, ppDXVAManager);
|
||||
}
|
||||
|
||||
HRESULT
|
||||
MFCreateSample(IMFSample **ppIMFSample)
|
||||
{
|
||||
DECL_FUNCTION_PTR(MFCreateSample, IMFSample **);
|
||||
ENSURE_FUNCTION_PTR(MFCreateSample, mfplat.dll)
|
||||
return (MFCreateSamplePtr)(ppIMFSample);
|
||||
}
|
||||
|
||||
HRESULT
|
||||
MFCreateAlignedMemoryBuffer(DWORD cbMaxLength,
|
||||
DWORD fAlignmentFlags,
|
||||
IMFMediaBuffer **ppBuffer)
|
||||
{
|
||||
DECL_FUNCTION_PTR(MFCreateAlignedMemoryBuffer, DWORD, DWORD, IMFMediaBuffer**);
|
||||
ENSURE_FUNCTION_PTR(MFCreateAlignedMemoryBuffer, mfplat.dll)
|
||||
return (MFCreateAlignedMemoryBufferPtr)(cbMaxLength, fAlignmentFlags, ppBuffer);
|
||||
}
|
||||
|
||||
} // end namespace wmf
|
||||
} // end namespace mozilla
|
||||
|
@ -6,6 +6,8 @@
|
||||
|
||||
#include "WMF.h"
|
||||
#include "nsString.h"
|
||||
#include "nsRect.h"
|
||||
#include "VideoUtils.h"
|
||||
|
||||
// Various utilities shared by WMF backend files.
|
||||
|
||||
@ -64,4 +66,31 @@ HNsToUsecs(int64_t hNanoSecs) {
|
||||
HRESULT
|
||||
DoGetInterface(IUnknown* aUnknown, void** aInterface);
|
||||
|
||||
HRESULT
|
||||
HNsToFrames(int64_t aHNs, uint32_t aRate, int64_t* aOutFrames);
|
||||
|
||||
HRESULT
|
||||
FramesToUsecs(int64_t aSamples, uint32_t aRate, int64_t* aOutUsecs);
|
||||
|
||||
HRESULT
|
||||
GetDefaultStride(IMFMediaType *aType, uint32_t* aOutStride);
|
||||
|
||||
int32_t
|
||||
MFOffsetToInt32(const MFOffset& aOffset);
|
||||
|
||||
// Gets the sub-region of the video frame that should be displayed.
|
||||
// See: http://msdn.microsoft.com/en-us/library/windows/desktop/bb530115(v=vs.85).aspx
|
||||
HRESULT
|
||||
GetPictureRegion(IMFMediaType* aMediaType, nsIntRect& aOutPictureRegion);
|
||||
|
||||
// Returns the duration of a IMFSample in microseconds.
|
||||
// Returns -1 on failure.
|
||||
int64_t
|
||||
GetSampleDuration(IMFSample* aSample);
|
||||
|
||||
// Returns the presentation time of a IMFSample in microseconds.
|
||||
// Returns -1 on failure.
|
||||
int64_t
|
||||
GetSampleTime(IMFSample* aSample);
|
||||
|
||||
} // namespace mozilla
|
||||
|
@ -10,6 +10,7 @@ EXPORTS += [
|
||||
'WMF.h',
|
||||
'WMFDecoder.h',
|
||||
'WMFReader.h',
|
||||
'WMFUtils.h',
|
||||
]
|
||||
|
||||
SOURCES += [
|
||||
|
Loading…
Reference in New Issue
Block a user