Bug 959440 - Apply MP4Reader cleanups to WMFDecoderModule. r=padenot

Update WMFDecoderModule and friends to reflect changes to PlatformDecoderModule
interface in previous patch.
This commit is contained in:
Chris Pearce 2014-01-15 16:14:15 +13:00
parent f6c08a2043
commit 778de3dc48
7 changed files with 103 additions and 110 deletions

View File

@ -27,6 +27,9 @@ PlatformDecoderModule::Init()
}
alreadyInitialized = true;
sUseBlankDecoder = Preferences::GetBool("media.fragmented-mp4.use-blank-decoder");
#ifdef XP_WIN
WMFDecoderModule::Init();
#endif
}
/* static */

View File

@ -21,17 +21,6 @@ PRLogModuleInfo* GetDemuxerLog();
namespace mozilla {
WMFAudioDecoder::WMFAudioDecoder()
: mAudioChannels(0),
mAudioBytesPerSample(0),
mAudioRate(0),
mLastStreamOffset(0),
mAudioFrameOffset(0),
mAudioFrameSum(0),
mMustRecaptureAudioPosition(true)
{
}
static void
AACAudioSpecificConfigToUserData(const uint8_t* aAudioSpecConfig,
uint32_t aConfigLength,
@ -77,12 +66,26 @@ AACAudioSpecificConfigToUserData(const uint8_t* aAudioSpecConfig,
aOutUserData.AppendElements(aAudioSpecConfig, aConfigLength);
}
WMFAudioDecoder::WMFAudioDecoder(uint32_t aChannelCount,
uint32_t aSampleRate,
uint16_t aBitsPerSample,
const uint8_t* aAudioSpecConfig,
uint32_t aConfigLength)
: mAudioChannels(aChannelCount),
mAudioBytesPerSample(aBitsPerSample / 8),
mAudioRate(aSampleRate),
mLastStreamOffset(0),
mAudioFrameOffset(0),
mAudioFrameSum(0),
mMustRecaptureAudioPosition(true)
{
AACAudioSpecificConfigToUserData(aAudioSpecConfig,
aConfigLength,
mUserData);
}
nsresult
WMFAudioDecoder::Init(uint32_t aChannelCount,
uint32_t aSampleRate,
uint16_t aBitsPerSample,
const uint8_t* aAudioSpecConfig,
uint32_t aConfigLength)
WMFAudioDecoder::Init()
{
mDecoder = new MFTDecoder();
@ -101,31 +104,23 @@ WMFAudioDecoder::Init(uint32_t aChannelCount,
hr = type->SetGUID(MF_MT_SUBTYPE, MFAudioFormat_AAC);
NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE);
hr = type->SetUINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND, aSampleRate);
hr = type->SetUINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND, mAudioRate);
NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE);
hr = type->SetUINT32(MF_MT_AUDIO_NUM_CHANNELS, aChannelCount);
hr = type->SetUINT32(MF_MT_AUDIO_NUM_CHANNELS, mAudioChannels);
NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE);
hr = type->SetUINT32(MF_MT_AAC_PAYLOAD_TYPE, 0x1); // ADTS
NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE);
nsTArray<BYTE> userData;
AACAudioSpecificConfigToUserData(aAudioSpecConfig,
aConfigLength,
userData);
hr = type->SetBlob(MF_MT_USER_DATA,
userData.Elements(),
userData.Length());
mUserData.Elements(),
mUserData.Length());
NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE);
hr = mDecoder->SetMediaTypes(type, MFAudioFormat_PCM);
NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE);
mAudioChannels = aChannelCount;
mAudioBytesPerSample = aBitsPerSample / 8;
mAudioRate = aSampleRate;
return NS_OK;
}
@ -136,14 +131,12 @@ WMFAudioDecoder::Shutdown()
}
DecoderStatus
WMFAudioDecoder::Input(const uint8_t* aData,
uint32_t aLength,
Microseconds aDTS,
Microseconds aPTS,
int64_t aOffsetInStream)
WMFAudioDecoder::Input(nsAutoPtr<mp4_demuxer::MP4Sample>& aSample)
{
mLastStreamOffset = aOffsetInStream;
HRESULT hr = mDecoder->Input(aData, aLength, aPTS);
mLastStreamOffset = aSample->byte_offset;
const uint8_t* data = &aSample->data->front();
uint32_t length = aSample->data->size();
HRESULT hr = mDecoder->Input(data, length, aSample->composition_timestamp);
if (hr == MF_E_NOTACCEPTING) {
return DECODE_STATUS_NOT_ACCEPTING;
}

View File

@ -15,22 +15,18 @@ namespace mozilla {
class WMFAudioDecoder : public MediaDataDecoder {
public:
WMFAudioDecoder();
WMFAudioDecoder(uint32_t aChannelCount,
uint32_t aSampleRate,
uint16_t aBitsPerSample,
const uint8_t* aUserData,
uint32_t aUserDataLength);
nsresult Init(uint32_t aChannelCount,
uint32_t aSampleRate,
uint16_t aBitsPerSample,
const uint8_t* aUserData,
uint32_t aUserDataLength);
virtual nsresult Init() MOZ_OVERRIDE;
virtual nsresult Shutdown() MOZ_OVERRIDE;
// Inserts data into the decoder's pipeline.
virtual DecoderStatus Input(const uint8_t* aData,
uint32_t aLength,
Microseconds aDTS,
Microseconds aPTS,
int64_t aOffsetInStream);
virtual DecoderStatus Input(nsAutoPtr<mp4_demuxer::MP4Sample>& aSample);
// Blocks until a decoded sample is produced by the decoder.
virtual DecoderStatus Output(nsAutoPtr<MediaData>& aOutData);
@ -53,6 +49,7 @@ private:
uint32_t mAudioChannels;
uint32_t mAudioBytesPerSample;
uint32_t mAudioRate;
nsTArray<BYTE> mUserData;
// The last offset into the media resource that was passed into Input().
// This is used to approximate the decoder's position in the media resource.

View File

@ -11,36 +11,46 @@
#include "WMFAudioDecoder.h"
#include "mozilla/Preferences.h"
#include "mozilla/DebugOnly.h"
#include "mp4_demuxer/audio_decoder_config.h"
namespace mozilla {
bool WMFDecoderModule::sIsWMFEnabled = false;
bool WMFDecoderModule::sDXVAEnabled = false;
WMFDecoderModule::WMFDecoderModule()
: mDXVAEnabled(Preferences::GetBool("media.windows-media-foundation.use-dxva", false))
{
MOZ_ASSERT(NS_IsMainThread(), "Must be on main thread.");
}
WMFDecoderModule::~WMFDecoderModule()
{
MOZ_ASSERT(NS_IsMainThread(), "Must be on main thread.");
}
nsresult
/* static */
void
WMFDecoderModule::Init()
{
MOZ_ASSERT(NS_IsMainThread(), "Must be on main thread.");
if (!Preferences::GetBool("media.windows-media-foundation.enabled", false)) {
sIsWMFEnabled = Preferences::GetBool("media.windows-media-foundation.enabled", false);
if (!sIsWMFEnabled) {
return;
}
if (NS_FAILED(WMFDecoder::LoadDLLs())) {
sIsWMFEnabled = false;
}
sDXVAEnabled = Preferences::GetBool("media.windows-media-foundation.use-dxva", false);
}
nsresult
WMFDecoderModule::Startup()
{
if (!sIsWMFEnabled) {
return NS_ERROR_FAILURE;
}
nsresult rv = WMFDecoder::LoadDLLs();
NS_ENSURE_SUCCESS(rv, rv);
if (FAILED(wmf::MFStartup())) {
NS_WARNING("Failed to initialize Windows Media Foundation");
return NS_ERROR_FAILURE;
}
return NS_OK;
}
@ -56,30 +66,23 @@ WMFDecoderModule::Shutdown()
}
MediaDataDecoder*
WMFDecoderModule::CreateH264Decoder(mozilla::layers::LayersBackend aLayersBackend,
WMFDecoderModule::CreateH264Decoder(const mp4_demuxer::VideoDecoderConfig& aConfig,
mozilla::layers::LayersBackend aLayersBackend,
mozilla::layers::ImageContainer* aImageContainer)
{
nsAutoPtr<WMFVideoDecoder> decoder(new WMFVideoDecoder(mDXVAEnabled));
nsresult rv = decoder->Init(aLayersBackend, aImageContainer);
NS_ENSURE_SUCCESS(rv, nullptr);
return decoder.forget();
return new WMFVideoDecoder(aLayersBackend,
aImageContainer,
sDXVAEnabled);
}
MediaDataDecoder*
WMFDecoderModule::CreateAACDecoder(uint32_t aChannelCount,
uint32_t aSampleRate,
uint16_t aBitsPerSample,
const uint8_t* aUserData,
uint32_t aUserDataLength)
WMFDecoderModule::CreateAACDecoder(const mp4_demuxer::AudioDecoderConfig& aConfig)
{
nsAutoPtr<WMFAudioDecoder> decoder(new WMFAudioDecoder());
nsresult rv = decoder->Init(aChannelCount,
aSampleRate,
aBitsPerSample,
aUserData,
aUserDataLength);
NS_ENSURE_SUCCESS(rv, nullptr);
return decoder.forget();
return new WMFAudioDecoder(ChannelLayoutToChannelCount(aConfig.channel_layout()),
aConfig.samples_per_second(),
aConfig.bits_per_channel(),
aConfig.extra_data(),
aConfig.extra_data_size());
}
void

View File

@ -18,7 +18,7 @@ public:
// Initializes the module, loads required dynamic libraries, etc.
// Main thread only.
nsresult Init();
nsresult Startup();
// Called when the decoders have shutdown. Main thread only.
// Does this really need to be main thread only????
@ -26,21 +26,22 @@ public:
// Decode thread.
virtual MediaDataDecoder*
CreateH264Decoder(mozilla::layers::LayersBackend aLayersBackend,
CreateH264Decoder(const mp4_demuxer::VideoDecoderConfig& aConfig,
mozilla::layers::LayersBackend aLayersBackend,
mozilla::layers::ImageContainer* aImageContainer) MOZ_OVERRIDE;
// Decode thread.
virtual MediaDataDecoder* CreateAACDecoder(uint32_t aChannelCount,
uint32_t aSampleRate,
uint16_t aBitsPerSample,
const uint8_t* aUserData,
uint32_t aUserDataLength) MOZ_OVERRIDE;
virtual MediaDataDecoder* CreateAACDecoder(
const mp4_demuxer::AudioDecoderConfig& aConfig) MOZ_OVERRIDE;
// Platform decoders can override these. Base implementation does nothing.
virtual void OnDecodeThreadStart() MOZ_OVERRIDE;
virtual void OnDecodeThreadFinish() MOZ_OVERRIDE;
static void Init();
private:
const bool mDXVAEnabled;
static bool sIsWMFEnabled;
static bool sDXVAEnabled;
};
} // namespace mozilla

View File

@ -28,15 +28,20 @@ using mozilla::layers::LayersBackend;
namespace mozilla {
WMFVideoDecoder::WMFVideoDecoder(bool aDXVAEnabled)
WMFVideoDecoder::WMFVideoDecoder(mozilla::layers::LayersBackend aLayersBackend,
mozilla::layers::ImageContainer* aImageContainer,
bool aDXVAEnabled)
: mVideoStride(0),
mVideoWidth(0),
mVideoHeight(0),
mLastStreamOffset(0),
mImageContainer(aImageContainer),
mDXVAEnabled(aDXVAEnabled),
mLayersBackend(aLayersBackend),
mUseHwAccel(false)
{
NS_ASSERTION(!NS_IsMainThread(), "Must be on main thread.");
NS_ASSERTION(!NS_IsMainThread(), "Should not be on main thread.");
MOZ_ASSERT(mImageContainer);
MOZ_COUNT_CTOR(WMFVideoDecoder);
}
@ -56,14 +61,14 @@ public:
};
bool
WMFVideoDecoder::InitializeDXVA(mozilla::layers::LayersBackend aLayersBackend)
WMFVideoDecoder::InitializeDXVA()
{
// If we use DXVA but aren't running with a D3D layer manager then the
// readback of decoded video frames from GPU to CPU memory grinds painting
// to a halt, and makes playback performance *worse*.
if (!mDXVAEnabled ||
(aLayersBackend != LayersBackend::LAYERS_D3D9 &&
aLayersBackend != LayersBackend::LAYERS_D3D10)) {
(mLayersBackend != LayersBackend::LAYERS_D3D9 &&
mLayersBackend != LayersBackend::LAYERS_D3D10)) {
return false;
}
@ -76,12 +81,9 @@ WMFVideoDecoder::InitializeDXVA(mozilla::layers::LayersBackend aLayersBackend)
}
nsresult
WMFVideoDecoder::Init(mozilla::layers::LayersBackend aLayersBackend,
mozilla::layers::ImageContainer* aImageContainer)
WMFVideoDecoder::Init()
{
NS_ENSURE_ARG_POINTER(aImageContainer);
bool useDxva= InitializeDXVA(aLayersBackend);
bool useDxva = InitializeDXVA();
mDecoder = new MFTDecoder();
@ -126,8 +128,6 @@ WMFVideoDecoder::Init(mozilla::layers::LayersBackend aLayersBackend,
hr = mDecoder->SetMediaTypes(type, outputType);
NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE);
mImageContainer = aImageContainer;
LOG("Video Decoder initialized, Using DXVA: %s", (mUseHwAccel ? "Yes" : "No"));
return NS_OK;
@ -202,14 +202,12 @@ WMFVideoDecoder::Shutdown()
// Inserts data into the decoder's pipeline.
DecoderStatus
WMFVideoDecoder::Input(const uint8_t* aData,
uint32_t aLength,
Microseconds aDTS,
Microseconds aPTS,
int64_t aOffsetInStream)
WMFVideoDecoder::Input(nsAutoPtr<mp4_demuxer::MP4Sample>& aSample)
{
mLastStreamOffset = aOffsetInStream;
HRESULT hr = mDecoder->Input(aData, aLength, aPTS);
mLastStreamOffset = aSample->byte_offset;
const uint8_t* data = &aSample->data->front();
uint32_t length = aSample->data->size();
HRESULT hr = mDecoder->Input(data, length, aSample->composition_timestamp);
if (hr == MF_E_NOTACCEPTING) {
return DECODE_STATUS_NOT_ACCEPTING;
}

View File

@ -20,21 +20,18 @@ class DXVA2Manager;
class WMFVideoDecoder : public MediaDataDecoder {
public:
WMFVideoDecoder(bool aDXVAEnabled);
WMFVideoDecoder(mozilla::layers::LayersBackend aLayersBackend,
mozilla::layers::ImageContainer* aImageContainer,
bool aDXVAEnabled);
~WMFVideoDecoder();
// Decode thread.
nsresult Init(mozilla::layers::LayersBackend aLayersBackend,
mozilla::layers::ImageContainer* aImageContainer);
virtual nsresult Init() MOZ_OVERRIDE;
virtual nsresult Shutdown() MOZ_OVERRIDE;
// Inserts data into the decoder's pipeline.
virtual DecoderStatus Input(const uint8_t* aData,
uint32_t aLength,
Microseconds aDTS,
Microseconds aPTS,
int64_t aOffsetInStream) MOZ_OVERRIDE;
virtual DecoderStatus Input(nsAutoPtr<mp4_demuxer::MP4Sample>& aSample) MOZ_OVERRIDE;
// Blocks until a decoded sample is produced by the decoder.
virtual DecoderStatus Output(nsAutoPtr<MediaData>& aOutData) MOZ_OVERRIDE;
@ -43,7 +40,7 @@ public:
private:
bool InitializeDXVA(mozilla::layers::LayersBackend aLayersBackend);
bool InitializeDXVA();
HRESULT ConfigureVideoFrameGeometry();
@ -68,6 +65,7 @@ private:
nsAutoPtr<DXVA2Manager> mDXVA2Manager;
const bool mDXVAEnabled;
const layers::LayersBackend mLayersBackend;
bool mUseHwAccel;
};