mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-28 03:17:31 +09:00
Compare commits
No commits in common. "47600fab8639005c3c05c2b3ec929389260cca0e" and "96bc206271209f1a93e2ba4a92d4a45aff780855" have entirely different histories.
47600fab86
...
96bc206271
8 changed files with 59 additions and 25 deletions
|
|
@ -70,7 +70,8 @@ AudioSinkInputPin::CheckMediaType(const MediaType* aMediaType)
|
||||||
|
|
||||||
GUID majorType = *aMediaType->Type();
|
GUID majorType = *aMediaType->Type();
|
||||||
if (majorType == MEDIATYPE_Video &&
|
if (majorType == MEDIATYPE_Video &&
|
||||||
*aMediaType->Subtype() == MEDIASUBTYPE_YUY2 &&
|
(*aMediaType->Subtype() == MEDIASUBTYPE_YUY2 ||
|
||||||
|
*aMediaType->Subtype() == MEDIASUBTYPE_I420) &&
|
||||||
*aMediaType->FormatType() == FORMAT_VideoInfo) {
|
*aMediaType->FormatType() == FORMAT_VideoInfo) {
|
||||||
if (aMediaType->cbFormat >= sizeof(VIDEOINFOHEADER)) {
|
if (aMediaType->cbFormat >= sizeof(VIDEOINFOHEADER)) {
|
||||||
memcpy(&mVideoInfo, aMediaType->pbFormat, sizeof(VIDEOINFOHEADER));
|
memcpy(&mVideoInfo, aMediaType->pbFormat, sizeof(VIDEOINFOHEADER));
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ static LazyLogModule gDirectShowLog("DirectShowDecoder");
|
||||||
|
|
||||||
DirectShowReader::DirectShowReader(AbstractMediaDecoder* aDecoder)
|
DirectShowReader::DirectShowReader(AbstractMediaDecoder* aDecoder)
|
||||||
: MediaDecoderReader(aDecoder),
|
: MediaDecoderReader(aDecoder),
|
||||||
|
mMP3FrameParser(aDecoder->GetResource()->GetLength()),
|
||||||
#ifdef DIRECTSHOW_REGISTER_GRAPH
|
#ifdef DIRECTSHOW_REGISTER_GRAPH
|
||||||
mRotRegister(0),
|
mRotRegister(0),
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -52,6 +53,34 @@ DirectShowReader::~DirectShowReader()
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Try to parse the MP3 stream to make sure this is indeed an MP3, get the
|
||||||
|
// estimated duration of the stream, and find the offset of the actual MP3
|
||||||
|
// frames in the stream, as DirectShow doesn't like large ID3 sections.
|
||||||
|
static nsresult
|
||||||
|
ParseMP3Headers(MP3FrameParser *aParser, MediaResource *aResource)
|
||||||
|
{
|
||||||
|
const uint32_t MAX_READ_SIZE = 4096;
|
||||||
|
|
||||||
|
uint64_t offset = 0;
|
||||||
|
while (aParser->NeedsData() && !aParser->ParsedHeaders()) {
|
||||||
|
uint32_t bytesRead;
|
||||||
|
char buffer[MAX_READ_SIZE];
|
||||||
|
nsresult rv = aResource->ReadAt(offset, buffer,
|
||||||
|
MAX_READ_SIZE, &bytesRead);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
if (!bytesRead) {
|
||||||
|
// End of stream.
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
aParser->Parse(reinterpret_cast<uint8_t*>(buffer), bytesRead, offset);
|
||||||
|
offset += bytesRead;
|
||||||
|
}
|
||||||
|
|
||||||
|
return aParser->IsMP3() ? NS_OK : NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
DirectShowReader::ReadMetadata(MediaInfo* aInfo,
|
DirectShowReader::ReadMetadata(MediaInfo* aInfo,
|
||||||
MetadataTags** aTags)
|
MetadataTags** aTags)
|
||||||
|
|
@ -69,7 +98,10 @@ DirectShowReader::ReadMetadata(MediaInfo* aInfo,
|
||||||
reinterpret_cast<void**>(static_cast<IGraphBuilder**>(getter_AddRefs(mGraph))));
|
reinterpret_cast<void**>(static_cast<IGraphBuilder**>(getter_AddRefs(mGraph))));
|
||||||
NS_ENSURE_TRUE(SUCCEEDED(hr) && mGraph, NS_ERROR_FAILURE);
|
NS_ENSURE_TRUE(SUCCEEDED(hr) && mGraph, NS_ERROR_FAILURE);
|
||||||
|
|
||||||
#ifdef DIRECTSHOW_REGISTER_GRAPH
|
rv = ParseMP3Headers(&mMP3FrameParser, mDecoder->GetResource());
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
#ifdef DIRECTSHOW_REGISTER_GRAPH
|
||||||
hr = AddGraphToRunningObjectTable(mGraph, &mRotRegister);
|
hr = AddGraphToRunningObjectTable(mGraph, &mRotRegister);
|
||||||
NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE);
|
NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE);
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -93,7 +125,7 @@ DirectShowReader::ReadMetadata(MediaInfo* aInfo,
|
||||||
mSourceFilter = new SourceFilter(MEDIATYPE_Stream, MEDIASUBTYPE_MPEG1Audio);
|
mSourceFilter = new SourceFilter(MEDIATYPE_Stream, MEDIASUBTYPE_MPEG1Audio);
|
||||||
NS_ENSURE_TRUE(mSourceFilter, NS_ERROR_FAILURE);
|
NS_ENSURE_TRUE(mSourceFilter, NS_ERROR_FAILURE);
|
||||||
|
|
||||||
rv = mSourceFilter->Init(mDecoder->GetResource(), 0);
|
rv = mSourceFilter->Init(mDecoder->GetResource(), mMP3FrameParser.GetMP3Offset());
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
hr = mGraph->AddFilter(mSourceFilter, L"MozillaDirectShowSource");
|
hr = mGraph->AddFilter(mSourceFilter, L"MozillaDirectShowSource");
|
||||||
|
|
@ -157,11 +189,16 @@ DirectShowReader::ReadMetadata(MediaInfo* aInfo,
|
||||||
hr = mMediaSeeking->GetCapabilities(&seekCaps);
|
hr = mMediaSeeking->GetCapabilities(&seekCaps);
|
||||||
mInfo.mMediaSeekable = SUCCEEDED(hr) && (AM_SEEKING_CanSeekAbsolute & seekCaps);
|
mInfo.mMediaSeekable = SUCCEEDED(hr) && (AM_SEEKING_CanSeekAbsolute & seekCaps);
|
||||||
|
|
||||||
|
int64_t duration = mMP3FrameParser.GetDuration();
|
||||||
|
if (SUCCEEDED(hr)) {
|
||||||
|
mInfo.mMetadataDuration.emplace(TimeUnit::FromMicroseconds(duration));
|
||||||
|
}
|
||||||
|
|
||||||
LOG("Successfully initialized DirectShow MP3 decoder.");
|
LOG("Successfully initialized DirectShow MP3 decoder.");
|
||||||
LOG("Channels=%u Hz=%u duration=%lld bytesPerSample=%d",
|
LOG("Channels=%u Hz=%u duration=%lld bytesPerSample=%d",
|
||||||
mInfo.mAudio.mChannels,
|
mInfo.mAudio.mChannels,
|
||||||
mInfo.mAudio.mRate,
|
mInfo.mAudio.mRate,
|
||||||
0LL,
|
RefTimeToUsecs(duration),
|
||||||
mBytesPerSample);
|
mBytesPerSample);
|
||||||
|
|
||||||
*aInfo = mInfo;
|
*aInfo = mInfo;
|
||||||
|
|
@ -341,9 +378,10 @@ DirectShowReader::DecodeVideoFrame(bool &aKeyframeSkip,
|
||||||
nsTArray<uint8_t> y;
|
nsTArray<uint8_t> y;
|
||||||
nsTArray<uint8_t> u;
|
nsTArray<uint8_t> u;
|
||||||
nsTArray<uint8_t> v;
|
nsTArray<uint8_t> v;
|
||||||
y.SetLength(width * height);
|
NS_ENSURE_TRUE(y.SetLength(width * height) &&
|
||||||
u.SetLength((width / 2) * (height / 2));
|
u.SetLength((width / 2) * (height / 2)) &&
|
||||||
v.SetLength((width / 2) * (height / 2));
|
v.SetLength((width / 2) * (height / 2)),
|
||||||
|
Finish(E_OUTOFMEMORY));
|
||||||
for (int32_t row = 0; row < height; ++row) {
|
for (int32_t row = 0; row < height; ++row) {
|
||||||
const uint8_t* src = data + row * stride;
|
const uint8_t* src = data + row * stride;
|
||||||
for (int32_t x = 0; x < width; x += 2) {
|
for (int32_t x = 0; x < width; x += 2) {
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@
|
||||||
#include "MediaDecoderReader.h"
|
#include "MediaDecoderReader.h"
|
||||||
#include "MediaResource.h"
|
#include "MediaResource.h"
|
||||||
#include "mozilla/RefPtr.h"
|
#include "mozilla/RefPtr.h"
|
||||||
|
#include "MP3FrameParser.h"
|
||||||
|
|
||||||
// Add the graph to the Running Object Table so that we can connect
|
// Add the graph to the Running Object Table so that we can connect
|
||||||
// to this graph with GraphEdit/GraphStudio. Note: you must
|
// to this graph with GraphEdit/GraphStudio. Note: you must
|
||||||
|
|
@ -84,6 +85,11 @@ private:
|
||||||
RefPtr<AudioSinkFilter> mAudioSinkFilter;
|
RefPtr<AudioSinkFilter> mAudioSinkFilter;
|
||||||
bool mIsH264;
|
bool mIsH264;
|
||||||
|
|
||||||
|
// Some MP3s are variable bitrate, so DirectShow's duration estimation
|
||||||
|
// can make its duration estimation based on the wrong bitrate. So we parse
|
||||||
|
// the MP3 frames to get a more accuate estimate of the duration.
|
||||||
|
MP3FrameParser mMP3FrameParser;
|
||||||
|
|
||||||
#ifdef DIRECTSHOW_REGISTER_GRAPH
|
#ifdef DIRECTSHOW_REGISTER_GRAPH
|
||||||
// Used to add/remove the filter graph to the Running Object Table. You can
|
// Used to add/remove the filter graph to the Running Object Table. You can
|
||||||
// connect GraphEdit/GraphStudio to the graph to observe and/or debug its
|
// connect GraphEdit/GraphStudio to the graph to observe and/or debug its
|
||||||
|
|
|
||||||
|
|
@ -309,7 +309,8 @@ CanDecodeH264UsingDirectShow()
|
||||||
RefPtr<ICreateDevEnum> devEnum;
|
RefPtr<ICreateDevEnum> devEnum;
|
||||||
HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, nullptr,
|
HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, nullptr,
|
||||||
CLSCTX_INPROC_SERVER,
|
CLSCTX_INPROC_SERVER,
|
||||||
IID_ICreateDevEnum, getter_AddRefs(devEnum));
|
IID_ICreateDevEnum,
|
||||||
|
reinterpret_cast<void**>(getter_AddRefs(devEnum)));
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -325,9 +326,9 @@ CanDecodeH264UsingDirectShow()
|
||||||
ULONG fetched = 0;
|
ULONG fetched = 0;
|
||||||
while (filters->Next(1, getter_AddRefs(moniker), &fetched) == S_OK) {
|
while (filters->Next(1, getter_AddRefs(moniker), &fetched) == S_OK) {
|
||||||
RefPtr<IPropertyBag> bag;
|
RefPtr<IPropertyBag> bag;
|
||||||
if (SUCCEEDED(moniker->BindToStorage(nullptr, nullptr,
|
if (SUCCEEDED(moniker->BindToStorage(nullptr, nullptr,
|
||||||
IID_IPropertyBag,
|
IID_IPropertyBag,
|
||||||
getter_AddRefs(bag)))) {
|
reinterpret_cast<void**>(getter_AddRefs(bag))))) {
|
||||||
VARIANT value;
|
VARIANT value;
|
||||||
VariantInit(&value);
|
VariantInit(&value);
|
||||||
if (SUCCEEDED(bag->Read(L"FriendlyName", &value, nullptr)) &&
|
if (SUCCEEDED(bag->Read(L"FriendlyName", &value, nullptr)) &&
|
||||||
|
|
@ -353,7 +354,7 @@ AddH264DecoderFilter(IGraphBuilder* aGraph, IBaseFilter** aOutFilter)
|
||||||
RefPtr<ICreateDevEnum> devEnum;
|
RefPtr<ICreateDevEnum> devEnum;
|
||||||
HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, nullptr,
|
HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, nullptr,
|
||||||
CLSCTX_INPROC_SERVER, IID_ICreateDevEnum,
|
CLSCTX_INPROC_SERVER, IID_ICreateDevEnum,
|
||||||
getter_AddRefs(devEnum));
|
reinterpret_cast<void**>(getter_AddRefs(devEnum)));
|
||||||
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
||||||
RefPtr<IEnumMoniker> filters;
|
RefPtr<IEnumMoniker> filters;
|
||||||
hr = devEnum->CreateClassEnumerator(CLSID_LegacyAmFilterCategory,
|
hr = devEnum->CreateClassEnumerator(CLSID_LegacyAmFilterCategory,
|
||||||
|
|
@ -367,7 +368,7 @@ AddH264DecoderFilter(IGraphBuilder* aGraph, IBaseFilter** aOutFilter)
|
||||||
VariantInit(&value);
|
VariantInit(&value);
|
||||||
bool h264 = false;
|
bool h264 = false;
|
||||||
if (SUCCEEDED(moniker->BindToStorage(nullptr, nullptr, IID_IPropertyBag,
|
if (SUCCEEDED(moniker->BindToStorage(nullptr, nullptr, IID_IPropertyBag,
|
||||||
getter_AddRefs(bag))) &&
|
reinterpret_cast<void**>(getter_AddRefs(bag)))) &&
|
||||||
SUCCEEDED(bag->Read(L"FriendlyName", &value, nullptr)) &&
|
SUCCEEDED(bag->Read(L"FriendlyName", &value, nullptr)) &&
|
||||||
value.vt == VT_BSTR && value.bstrVal) {
|
value.vt == VT_BSTR && value.bstrVal) {
|
||||||
h264 = wcsstr(value.bstrVal, L"H264") ||
|
h264 = wcsstr(value.bstrVal, L"H264") ||
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@
|
||||||
#include "MediaResource.h"
|
#include "MediaResource.h"
|
||||||
#include "mozilla/RefPtr.h"
|
#include "mozilla/RefPtr.h"
|
||||||
#include "DirectShowUtils.h"
|
#include "DirectShowUtils.h"
|
||||||
|
#include "MP3FrameParser.h"
|
||||||
#include "mozilla/Logging.h"
|
#include "mozilla/Logging.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,5 @@ if not CONFIG['MOZ_WEBRTC']:
|
||||||
|
|
||||||
FINAL_LIBRARY = 'xul'
|
FINAL_LIBRARY = 'xul'
|
||||||
LOCAL_INCLUDES += [
|
LOCAL_INCLUDES += [
|
||||||
'/dom/media',
|
|
||||||
'/media/webrtc/trunk/webrtc/modules/video_capture/windows',
|
'/media/webrtc/trunk/webrtc/modules/video_capture/windows',
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -5,16 +5,6 @@
|
||||||
|
|
||||||
include('build/moz.configure/init.configure')
|
include('build/moz.configure/init.configure')
|
||||||
|
|
||||||
# DirectShow is the legacy Windows media backend. Keep this independent of
|
|
||||||
# the old configure scripts so the backend is actually compiled on Windows.
|
|
||||||
@depends(target)
|
|
||||||
def directshow_enabled(target):
|
|
||||||
if target.kernel == 'WINNT':
|
|
||||||
return True
|
|
||||||
|
|
||||||
set_config('MOZ_DIRECTSHOW', directshow_enabled)
|
|
||||||
set_define('MOZ_DIRECTSHOW', directshow_enabled)
|
|
||||||
|
|
||||||
# Note:
|
# Note:
|
||||||
# - Gecko-specific options and rules should go in toolkit/moz.configure.
|
# - Gecko-specific options and rules should go in toolkit/moz.configure.
|
||||||
# - Firefox-specific options and rules should go in browser/moz.configure.
|
# - Firefox-specific options and rules should go in browser/moz.configure.
|
||||||
|
|
|
||||||
|
|
@ -174,8 +174,6 @@ if CONFIG['OS_ARCH'] == 'WINNT':
|
||||||
'shell32',
|
'shell32',
|
||||||
'ole32',
|
'ole32',
|
||||||
'strmiids',
|
'strmiids',
|
||||||
'dmoguids',
|
|
||||||
'msdmo',
|
|
||||||
'version',
|
'version',
|
||||||
'winspool',
|
'winspool',
|
||||||
]
|
]
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue