Backed out 2 changesets (bug 959440) on an unrelated CLOSED TREE

Backed out changeset f4fd03805620 (bug 959440)
Backed out changeset bfee2bc18e55 (bug 959440)
This commit is contained in:
Wes Kocher 2014-01-14 17:37:57 -08:00
Родитель 0e1fc31ed1
Коммит 91507c568f
11 изменённых файлов: 171 добавлений и 210 удалений

Просмотреть файл

@ -11,8 +11,6 @@
#include "mozilla/CheckedInt.h"
#include "VideoUtils.h"
#include "ImageContainer.h"
#include "mp4_demuxer/mp4_demuxer.h"
#include "mp4_demuxer/audio_decoder_config.h"
namespace mozilla {
@ -24,36 +22,33 @@ public:
BlankMediaDataDecoder(BlankMediaDataCreator* aCreator)
: mCreator(aCreator),
mNextTimeStamp(-1),
mNextDTS(-1),
mNextOffset(-1)
{
}
virtual nsresult Init() MOZ_OVERRIDE {
return NS_OK;
}
virtual nsresult Shutdown() MOZ_OVERRIDE {
return NS_OK;
}
virtual DecoderStatus Input(nsAutoPtr<mp4_demuxer::MP4Sample>& aSample) MOZ_OVERRIDE
virtual DecoderStatus Input(const uint8_t* aData,
uint32_t aLength,
Microseconds aDTS,
Microseconds aPTS,
int64_t aOffsetInStream) MOZ_OVERRIDE
{
// Accepts input, and outputs on the second input, using the difference
// in DTS as the duration.
if (mOutput) {
return DECODE_STATUS_NOT_ACCEPTING;
}
Microseconds timestamp = aSample->composition_timestamp;
if (mNextTimeStamp != -1 && mNextOffset != -1) {
Microseconds duration = timestamp - mNextTimeStamp;
mOutput = mCreator->Create(mNextTimeStamp, duration, mNextOffset);
if (mNextDTS != -1 && mNextOffset != -1) {
Microseconds duration = aDTS - mNextDTS;
mOutput = mCreator->Create(mNextDTS, duration, mNextOffset);
}
mNextTimeStamp = timestamp;
mNextOffset = aSample->byte_offset;
mNextDTS = aDTS;
mNextOffset = aOffsetInStream;
return DECODE_STATUS_OK;
}
@ -71,7 +66,7 @@ public:
}
private:
nsAutoPtr<BlankMediaDataCreator> mCreator;
Microseconds mNextTimeStamp;
Microseconds mNextDTS;
int64_t mNextOffset;
nsAutoPtr<MediaData> mOutput;
bool mHasInput;
@ -203,19 +198,21 @@ public:
}
// Decode thread.
virtual MediaDataDecoder* CreateH264Decoder(const mp4_demuxer::VideoDecoderConfig& aConfig,
layers::LayersBackend aLayersBackend,
virtual MediaDataDecoder* CreateH264Decoder(layers::LayersBackend aLayersBackend,
layers::ImageContainer* aImageContainer) MOZ_OVERRIDE {
BlankVideoDataCreator* decoder = new BlankVideoDataCreator(aImageContainer);
return new BlankMediaDataDecoder<BlankVideoDataCreator>(decoder);
}
// Decode thread.
virtual MediaDataDecoder* CreateAACDecoder(const mp4_demuxer::AudioDecoderConfig& aConfig) MOZ_OVERRIDE {
BlankAudioDataCreator* decoder =
new BlankAudioDataCreator(ChannelLayoutToChannelCount(aConfig.channel_layout()),
aConfig.samples_per_second(),
aConfig.bits_per_channel());
virtual MediaDataDecoder* CreateAACDecoder(uint32_t aChannelCount,
uint32_t aSampleRate,
uint16_t aBitsPerSample,
const uint8_t* aUserData,
uint32_t aUserDataLength) MOZ_OVERRIDE {
BlankAudioDataCreator* decoder = new BlankAudioDataCreator(aChannelCount,
aSampleRate,
aBitsPerSample);
return new BlankMediaDataDecoder<BlankAudioDataCreator>(decoder);
}
};

Просмотреть файл

@ -123,10 +123,12 @@ nsresult
MP4Reader::Init(MediaDecoderReader* aCloneDonor)
{
MOZ_ASSERT(NS_IsMainThread(), "Must be on main thread.");
PlatformDecoderModule::Init();
mMP4Stream = new MP4Stream(mDecoder->GetResource());
mDemuxer = new MP4Demuxer(mMP4Stream);
mPlatform = PlatformDecoderModule::Create();
NS_ENSURE_TRUE(mPlatform, NS_ERROR_FAILURE);
InitLayersBackendType();
return NS_OK;
@ -155,28 +157,25 @@ MP4Reader::ReadMetadata(MediaInfo* aInfo,
return NS_ERROR_FAILURE;
}
mPlatform = PlatformDecoderModule::Create();
NS_ENSURE_TRUE(mPlatform, NS_ERROR_FAILURE);
if (mHasAudio) {
mInfo.mAudio.mRate = audio.samples_per_second();
mInfo.mAudio.mChannels = ChannelLayoutToChannelCount(audio.channel_layout());
mAudioDecoder = mPlatform->CreateAACDecoder(audio);
mAudioDecoder = mPlatform->CreateAACDecoder(mInfo.mAudio.mChannels,
mInfo.mAudio.mRate,
audio.bits_per_channel(),
audio.extra_data(),
audio.extra_data_size());
NS_ENSURE_TRUE(mAudioDecoder != nullptr, NS_ERROR_FAILURE);
nsresult rv = mAudioDecoder->Init();
NS_ENSURE_SUCCESS(rv, rv);
}
mInfo.mVideo.mHasVideo = mHasVideo = mDemuxer->HasVideo();
if (mHasVideo) {
IntSize sz = video.natural_size();
const VideoDecoderConfig& config = mDemuxer->VideoConfig();
IntSize sz = config.natural_size();
mInfo.mVideo.mDisplay = nsIntSize(sz.width(), sz.height());
mVideoDecoder = mPlatform->CreateH264Decoder(video,
mLayersBackendType,
mVideoDecoder = mPlatform->CreateH264Decoder(mLayersBackendType,
mDecoder->GetImageContainer());
NS_ENSURE_TRUE(mVideoDecoder != nullptr, NS_ERROR_FAILURE);
nsresult rv = mVideoDecoder->Init();
NS_ENSURE_SUCCESS(rv, rv);
}
// Get the duration, and report it to the decoder if we have it.
@ -283,15 +282,16 @@ MP4Reader::Decode(TrackType aTrack, nsAutoPtr<MediaData>& aOutData)
// frames coming.
return false;
}
status = decoder->Input(compressed);
const std::vector<uint8_t>* data = compressed->data;
status = decoder->Input(&data->front(),
data->size(),
compressed->decode_timestamp,
compressed->composition_timestamp,
compressed->byte_offset);
} while (status == DECODE_STATUS_OK);
if (status == DECODE_STATUS_NOT_ACCEPTING) {
// Decoder should now be able to produce an output.
if (compressed != nullptr) {
// Decoder didn't consume data, attempt to decode the same
// sample next time.
SampleQueue(aTrack).push_front(compressed.forget());
}
SampleQueue(aTrack).push_front(compressed.forget());
continue;
}
LOG("MP4Reader decode failure. track=%d status=%d\n", aTrack, status);
@ -401,9 +401,8 @@ MP4Reader::OnDecodeThreadStart()
{
MOZ_ASSERT(!NS_IsMainThread(), "Must not be on main thread.");
MOZ_ASSERT(mDecoder->OnDecodeThread(), "Should be on decode thread.");
if (mPlatform) {
mPlatform->OnDecodeThreadStart();
}
MOZ_ASSERT(mPlatform);
mPlatform->OnDecodeThreadStart();
}
void
@ -411,9 +410,8 @@ MP4Reader::OnDecodeThreadFinish()
{
MOZ_ASSERT(!NS_IsMainThread(), "Must not be on main thread.");
MOZ_ASSERT(mDecoder->OnDecodeThread(), "Should be on decode thread.");
if (mPlatform) {
mPlatform->OnDecodeThreadFinish();
}
MOZ_ASSERT(mPlatform);
mPlatform->OnDecodeThreadFinish();
}
} // namespace mozilla

Просмотреть файл

@ -14,7 +14,6 @@
#include "mp4_demuxer/box_definitions.h"
#include <deque>
#include "mozilla/Monitor.h"
namespace mozilla {
@ -83,6 +82,7 @@ private:
bool mHasAudio;
bool mHasVideo;
};
} // namespace mozilla

Просмотреть файл

@ -14,34 +14,16 @@ namespace mozilla {
extern PlatformDecoderModule* CreateBlankDecoderModule();
bool PlatformDecoderModule::sUseBlankDecoder = false;
/* static */
void
PlatformDecoderModule::Init()
{
MOZ_ASSERT(NS_IsMainThread());
static bool alreadyInitialized = false;
if (alreadyInitialized) {
return;
}
alreadyInitialized = true;
sUseBlankDecoder = Preferences::GetBool("media.fragmented-mp4.use-blank-decoder");
#ifdef XP_WIN
WMFDecoderModule::Init();
#endif
}
/* static */
PlatformDecoderModule*
PlatformDecoderModule::Create()
{
if (sUseBlankDecoder) {
if (Preferences::GetBool("media.fragmented-mp4.use-blank-decoder")) {
return CreateBlankDecoderModule();
}
#ifdef XP_WIN
nsAutoPtr<WMFDecoderModule> m(new WMFDecoderModule());
if (NS_SUCCEEDED(m->Startup())) {
if (NS_SUCCEEDED(m->Init())) {
return m.forget();
}
#endif

Просмотреть файл

@ -9,13 +9,6 @@
#include "MediaDecoderReader.h"
#include "mozilla/layers/LayersTypes.h"
#include "nsTArray.h"
namespace mp4_demuxer {
class VideoDecoderConfig;
class AudioDecoderConfig;
class MP4Sample;
}
namespace mozilla {
@ -42,9 +35,6 @@ typedef int64_t Microseconds;
// "media.fragmented-mp4.use-blank-decoder" is true.
class PlatformDecoderModule {
public:
// Call on the main thread to initialize the static state
// needed by Create().
static void Init();
// Factory method that creates the appropriate PlatformDecoderModule for
// the platform we're running on. Caller is responsible for deleting this
@ -66,8 +56,7 @@ public:
// decoding can be used. Returns nullptr if the decoder can't be
// initialized.
// Called on decode thread.
virtual MediaDataDecoder* CreateH264Decoder(const mp4_demuxer::VideoDecoderConfig& aConfig,
layers::LayersBackend aLayersBackend,
virtual MediaDataDecoder* CreateH264Decoder(layers::LayersBackend aLayersBackend,
layers::ImageContainer* aImageContainer) = 0;
// Creates and initializes an AAC decoder with the specified properties.
@ -76,7 +65,11 @@ public:
// so it must be copied if it is to be retained by the decoder.
// Returns nullptr if the decoder can't be initialized.
// Called on decode thread.
virtual MediaDataDecoder* CreateAACDecoder(const mp4_demuxer::AudioDecoderConfig& aConfig) = 0;
virtual MediaDataDecoder* CreateAACDecoder(uint32_t aChannelCount,
uint32_t aSampleRate,
uint16_t aBitsPerSample,
const uint8_t* aAACConfig,
uint32_t aAACConfigLength) = 0;
// Called when a decode thread is started. Called on decode thread.
virtual void OnDecodeThreadStart() {}
@ -87,8 +80,6 @@ public:
virtual ~PlatformDecoderModule() {}
protected:
PlatformDecoderModule() {}
// Caches pref media.fragmented-mp4.use-blank-decoder
static bool sUseBlankDecoder;
};
// Return value of the MediaDataDecoder functions.
@ -111,29 +102,10 @@ class MediaDataDecoder {
public:
virtual ~MediaDataDecoder() {};
// Initialize the decoder. The decoder should be ready to decode after
// this returns. The decoder should do any initialization here, rather
// than in its constructor, so that if the MP4Reader needs to Shutdown()
// during initialization it can call Shutdown() to cancel this.
// Any initialization that requires blocking the calling thread *must*
// be done here so that it can be canceled by calling Shutdown()!
virtual nsresult Init() = 0;
// Inserts aData into the decoding pipeline. Decoding may begin
// asynchronously.
//
// If the decoder needs to assume ownership of the sample it may do so by
// calling forget() on aSample.
//
// If Input() returns DECODE_STATUS_NOT_ACCEPTING without forget()ing
// aSample, then the next call will have the same aSample. Otherwise
// the caller will delete aSample after Input() returns.
//
// The MP4Reader calls Input() in a loop until Input() stops returning
// DECODE_STATUS_OK. Input() should return DECODE_STATUS_NOT_ACCEPTING
// once the underlying decoder should have enough data to output decoded
// data.
//
// asynchronously. The caller owns aData, so it may need to be copied.
// The MP4Reader calls Input() with new input in a loop until Input()
// stops returning DECODE_STATUS_OK.
// Called on the media decode thread.
// Returns:
// - DECODE_STATUS_OK if input was successfully inserted into
@ -142,13 +114,15 @@ public:
// at this time. The MP4Reader will assume that the decoder can now
// produce one or more output samples, and call the Output() function.
// The MP4Reader will call Input() again with the same data later,
// after the decoder's Output() function has stopped producing output,
// except if Input() called forget() on aSample, whereupon a new sample
// will come in next call.
// after the decoder's Output() function has stopped producing output.
// - DECODE_STATUS_ERROR if the decoder has been shutdown, or some
// unspecified error.
// This function should not return DECODE_STATUS_NEED_MORE_INPUT.
virtual DecoderStatus Input(nsAutoPtr<mp4_demuxer::MP4Sample>& aSample) = 0;
virtual DecoderStatus Input(const uint8_t* aData,
uint32_t aLength,
Microseconds aDTS,
Microseconds aPTS,
int64_t aOffsetInStream) = 0;
// Blocks until a decoded sample is produced by the deoder. The MP4Reader
// calls this until it stops returning DECODE_STATUS_OK.

Просмотреть файл

@ -21,6 +21,17 @@ 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,
@ -66,26 +77,12 @@ 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()
WMFAudioDecoder::Init(uint32_t aChannelCount,
uint32_t aSampleRate,
uint16_t aBitsPerSample,
const uint8_t* aAudioSpecConfig,
uint32_t aConfigLength)
{
mDecoder = new MFTDecoder();
@ -104,23 +101,31 @@ WMFAudioDecoder::Init()
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, mAudioRate);
hr = type->SetUINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND, aSampleRate);
NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE);
hr = type->SetUINT32(MF_MT_AUDIO_NUM_CHANNELS, mAudioChannels);
hr = type->SetUINT32(MF_MT_AUDIO_NUM_CHANNELS, aChannelCount);
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,
mUserData.Elements(),
mUserData.Length());
userData.Elements(),
userData.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;
}
@ -131,12 +136,14 @@ WMFAudioDecoder::Shutdown()
}
DecoderStatus
WMFAudioDecoder::Input(nsAutoPtr<mp4_demuxer::MP4Sample>& aSample)
WMFAudioDecoder::Input(const uint8_t* aData,
uint32_t aLength,
Microseconds aDTS,
Microseconds aPTS,
int64_t aOffsetInStream)
{
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);
mLastStreamOffset = aOffsetInStream;
HRESULT hr = mDecoder->Input(aData, aLength, aPTS);
if (hr == MF_E_NOTACCEPTING) {
return DECODE_STATUS_NOT_ACCEPTING;
}

Просмотреть файл

@ -15,18 +15,22 @@ namespace mozilla {
class WMFAudioDecoder : public MediaDataDecoder {
public:
WMFAudioDecoder(uint32_t aChannelCount,
uint32_t aSampleRate,
uint16_t aBitsPerSample,
const uint8_t* aUserData,
uint32_t aUserDataLength);
WMFAudioDecoder();
virtual nsresult Init() MOZ_OVERRIDE;
nsresult Init(uint32_t aChannelCount,
uint32_t aSampleRate,
uint16_t aBitsPerSample,
const uint8_t* aUserData,
uint32_t aUserDataLength);
virtual nsresult Shutdown() MOZ_OVERRIDE;
// Inserts data into the decoder's pipeline.
virtual DecoderStatus Input(nsAutoPtr<mp4_demuxer::MP4Sample>& aSample);
virtual DecoderStatus Input(const uint8_t* aData,
uint32_t aLength,
Microseconds aDTS,
Microseconds aPTS,
int64_t aOffsetInStream);
// Blocks until a decoded sample is produced by the decoder.
virtual DecoderStatus Output(nsAutoPtr<MediaData>& aOutData);
@ -49,7 +53,6 @@ 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.

Просмотреть файл

@ -11,46 +11,36 @@
#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()
{
}
/* static */
void
WMFDecoderModule::Init()
{
MOZ_ASSERT(NS_IsMainThread(), "Must be on main thread.");
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()
WMFDecoderModule::Init()
{
if (!sIsWMFEnabled) {
MOZ_ASSERT(NS_IsMainThread(), "Must be on main thread.");
if (!Preferences::GetBool("media.windows-media-foundation.enabled", false)) {
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;
}
@ -66,23 +56,30 @@ WMFDecoderModule::Shutdown()
}
MediaDataDecoder*
WMFDecoderModule::CreateH264Decoder(const mp4_demuxer::VideoDecoderConfig& aConfig,
mozilla::layers::LayersBackend aLayersBackend,
WMFDecoderModule::CreateH264Decoder(mozilla::layers::LayersBackend aLayersBackend,
mozilla::layers::ImageContainer* aImageContainer)
{
return new WMFVideoDecoder(aLayersBackend,
aImageContainer,
sDXVAEnabled);
nsAutoPtr<WMFVideoDecoder> decoder(new WMFVideoDecoder(mDXVAEnabled));
nsresult rv = decoder->Init(aLayersBackend, aImageContainer);
NS_ENSURE_SUCCESS(rv, nullptr);
return decoder.forget();
}
MediaDataDecoder*
WMFDecoderModule::CreateAACDecoder(const mp4_demuxer::AudioDecoderConfig& aConfig)
WMFDecoderModule::CreateAACDecoder(uint32_t aChannelCount,
uint32_t aSampleRate,
uint16_t aBitsPerSample,
const uint8_t* aUserData,
uint32_t aUserDataLength)
{
return new WMFAudioDecoder(ChannelLayoutToChannelCount(aConfig.channel_layout()),
aConfig.samples_per_second(),
aConfig.bits_per_channel(),
aConfig.extra_data(),
aConfig.extra_data_size());
nsAutoPtr<WMFAudioDecoder> decoder(new WMFAudioDecoder());
nsresult rv = decoder->Init(aChannelCount,
aSampleRate,
aBitsPerSample,
aUserData,
aUserDataLength);
NS_ENSURE_SUCCESS(rv, nullptr);
return decoder.forget();
}
void

Просмотреть файл

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

Просмотреть файл

@ -28,20 +28,15 @@ using mozilla::layers::LayersBackend;
namespace mozilla {
WMFVideoDecoder::WMFVideoDecoder(mozilla::layers::LayersBackend aLayersBackend,
mozilla::layers::ImageContainer* aImageContainer,
bool aDXVAEnabled)
WMFVideoDecoder::WMFVideoDecoder(bool aDXVAEnabled)
: mVideoStride(0),
mVideoWidth(0),
mVideoHeight(0),
mLastStreamOffset(0),
mImageContainer(aImageContainer),
mDXVAEnabled(aDXVAEnabled),
mLayersBackend(aLayersBackend),
mUseHwAccel(false)
{
NS_ASSERTION(!NS_IsMainThread(), "Should not be on main thread.");
MOZ_ASSERT(mImageContainer);
NS_ASSERTION(!NS_IsMainThread(), "Must be on main thread.");
MOZ_COUNT_CTOR(WMFVideoDecoder);
}
@ -61,14 +56,14 @@ public:
};
bool
WMFVideoDecoder::InitializeDXVA()
WMFVideoDecoder::InitializeDXVA(mozilla::layers::LayersBackend aLayersBackend)
{
// 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 ||
(mLayersBackend != LayersBackend::LAYERS_D3D9 &&
mLayersBackend != LayersBackend::LAYERS_D3D10)) {
(aLayersBackend != LayersBackend::LAYERS_D3D9 &&
aLayersBackend != LayersBackend::LAYERS_D3D10)) {
return false;
}
@ -81,9 +76,12 @@ WMFVideoDecoder::InitializeDXVA()
}
nsresult
WMFVideoDecoder::Init()
WMFVideoDecoder::Init(mozilla::layers::LayersBackend aLayersBackend,
mozilla::layers::ImageContainer* aImageContainer)
{
bool useDxva = InitializeDXVA();
NS_ENSURE_ARG_POINTER(aImageContainer);
bool useDxva= InitializeDXVA(aLayersBackend);
mDecoder = new MFTDecoder();
@ -128,6 +126,8 @@ WMFVideoDecoder::Init()
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,12 +202,14 @@ WMFVideoDecoder::Shutdown()
// Inserts data into the decoder's pipeline.
DecoderStatus
WMFVideoDecoder::Input(nsAutoPtr<mp4_demuxer::MP4Sample>& aSample)
WMFVideoDecoder::Input(const uint8_t* aData,
uint32_t aLength,
Microseconds aDTS,
Microseconds aPTS,
int64_t aOffsetInStream)
{
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);
mLastStreamOffset = aOffsetInStream;
HRESULT hr = mDecoder->Input(aData, aLength, aPTS);
if (hr == MF_E_NOTACCEPTING) {
return DECODE_STATUS_NOT_ACCEPTING;
}

Просмотреть файл

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