зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1206977: [webm] P7. Remove IntelWebMVideoDecoder. r=kinetik
That code path is no longer used and handled directly in the MediaFormatReader. Also, partially revert commit ac6d0b0befb2 as it broke WebMReader.
This commit is contained in:
Родитель
7ad7357100
Коммит
6c9f5d0954
|
@ -47,7 +47,7 @@ ogg_packet InitOggPacket(const unsigned char* aData, size_t aLength,
|
|||
class VorbisDecoder : public WebMAudioDecoder
|
||||
{
|
||||
public:
|
||||
nsRefPtr<InitPromise> Init() override;
|
||||
nsresult Init() override;
|
||||
void Shutdown() override;
|
||||
nsresult ResetDecode() override;
|
||||
nsresult DecodeHeader(const unsigned char* aData, size_t aLength) override;
|
||||
|
@ -94,14 +94,14 @@ VorbisDecoder::Shutdown()
|
|||
mReader = nullptr;
|
||||
}
|
||||
|
||||
nsRefPtr<InitPromise>
|
||||
nsresult
|
||||
VorbisDecoder::Init()
|
||||
{
|
||||
vorbis_info_init(&mVorbisInfo);
|
||||
vorbis_comment_init(&mVorbisComment);
|
||||
PodZero(&mVorbisDsp);
|
||||
PodZero(&mVorbisBlock);
|
||||
return InitPromise::CreateAndResolve(TrackType::kAudioTrack, __func__);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -229,7 +229,7 @@ VorbisDecoder::Decode(const unsigned char* aData, size_t aLength,
|
|||
class OpusDecoder : public WebMAudioDecoder
|
||||
{
|
||||
public:
|
||||
nsRefPtr<InitPromise> Init() override;
|
||||
nsresult Init() override;
|
||||
void Shutdown() override;
|
||||
nsresult ResetDecode() override;
|
||||
nsresult DecodeHeader(const unsigned char* aData, size_t aLength) override;
|
||||
|
@ -277,10 +277,10 @@ OpusDecoder::Shutdown()
|
|||
mReader = nullptr;
|
||||
}
|
||||
|
||||
nsRefPtr<InitPromise>
|
||||
nsresult
|
||||
OpusDecoder::Init()
|
||||
{
|
||||
return InitPromise::CreateAndResolve(TrackType::kAudioTrack, __func__);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
|
|
@ -1,443 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et cindent: */
|
||||
/* 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/. */
|
||||
#include "IntelWebMVideoDecoder.h"
|
||||
|
||||
#include "mozilla/TaskQueue.h"
|
||||
|
||||
#include "gfx2DGlue.h"
|
||||
#include "Layers.h"
|
||||
#include "MediaResource.h"
|
||||
#include "mozilla/dom/HTMLMediaElement.h"
|
||||
#include "nsError.h"
|
||||
#include "mozilla/SharedThreadPool.h"
|
||||
#include "VorbisUtils.h"
|
||||
#include "nestegg/nestegg.h"
|
||||
|
||||
#define VPX_DONT_DEFINE_STDINT_TYPES
|
||||
#include "vpx/vp8dx.h"
|
||||
#include "vpx/vpx_decoder.h"
|
||||
|
||||
#undef LOG
|
||||
extern PRLogModuleInfo* GetPDMLog();
|
||||
#define LOG(...) MOZ_LOG(GetPDMLog(), mozilla::LogLevel::Debug, (__VA_ARGS__))
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
using layers::Image;
|
||||
using layers::LayerManager;
|
||||
using layers::LayersBackend;
|
||||
|
||||
class VP8Sample : public MediaRawData
|
||||
{
|
||||
public:
|
||||
VP8Sample(int64_t aTimestamp,
|
||||
int64_t aDuration,
|
||||
int64_t aByteOffset,
|
||||
uint8_t* aData,
|
||||
size_t aSize,
|
||||
bool aSyncPoint)
|
||||
: MediaRawData(aData, aSize)
|
||||
{
|
||||
mTimecode = -1;
|
||||
mTime = aTimestamp;
|
||||
mDuration = aDuration;
|
||||
mOffset = aByteOffset;
|
||||
mKeyframe = aSyncPoint;
|
||||
}
|
||||
};
|
||||
|
||||
IntelWebMVideoDecoder::IntelWebMVideoDecoder(WebMReader* aReader)
|
||||
: WebMVideoDecoder()
|
||||
, mReader(aReader)
|
||||
, mMonitor("IntelWebMVideoDecoder")
|
||||
, mNumSamplesInput(0)
|
||||
, mNumSamplesOutput(0)
|
||||
, mDecodeAhead(2)
|
||||
, mInputExhausted(false)
|
||||
, mDrainComplete(false)
|
||||
, mError(false)
|
||||
, mEOS(false)
|
||||
, mIsFlushing(false)
|
||||
{
|
||||
MOZ_COUNT_CTOR(IntelWebMVideoDecoder);
|
||||
}
|
||||
|
||||
IntelWebMVideoDecoder::~IntelWebMVideoDecoder()
|
||||
{
|
||||
MOZ_COUNT_DTOR(IntelWebMVideoDecoder);
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
void
|
||||
IntelWebMVideoDecoder::Shutdown()
|
||||
{
|
||||
if (mMediaDataDecoder) {
|
||||
Flush();
|
||||
mMediaDataDecoder->Shutdown();
|
||||
mMediaDataDecoder = nullptr;
|
||||
}
|
||||
|
||||
mTaskQueue = nullptr;
|
||||
|
||||
mQueuedVideoSample = nullptr;
|
||||
mReader = nullptr;
|
||||
}
|
||||
|
||||
/* static */
|
||||
WebMVideoDecoder*
|
||||
IntelWebMVideoDecoder::Create(WebMReader* aReader)
|
||||
{
|
||||
nsAutoPtr<IntelWebMVideoDecoder> decoder(new IntelWebMVideoDecoder(aReader));
|
||||
|
||||
decoder->mTaskQueue = aReader->GetVideoTaskQueue();
|
||||
NS_ENSURE_TRUE(decoder->mTaskQueue, nullptr);
|
||||
|
||||
return decoder.forget();
|
||||
}
|
||||
|
||||
bool
|
||||
IntelWebMVideoDecoder::IsSupportedVideoMimeType(const nsACString& aMimeType)
|
||||
{
|
||||
return (aMimeType.EqualsLiteral("video/webm; codecs=vp8") ||
|
||||
aMimeType.EqualsLiteral("video/webm; codecs=vp9")) &&
|
||||
mPlatform->SupportsMimeType(aMimeType);
|
||||
}
|
||||
|
||||
nsRefPtr<InitPromise>
|
||||
IntelWebMVideoDecoder::Init(unsigned int aWidth, unsigned int aHeight)
|
||||
{
|
||||
mPlatform = PlatformDecoderModule::Create();
|
||||
if (!mPlatform) {
|
||||
return InitPromise::CreateAndReject(DecoderFailureReason::INIT_ERROR, __func__);
|
||||
}
|
||||
|
||||
mDecoderConfig = new VideoInfo();
|
||||
mDecoderConfig->mDuration = 0;
|
||||
mDecoderConfig->mDisplay.width = aWidth;
|
||||
mDecoderConfig->mDisplay.height = aHeight;
|
||||
|
||||
switch (mReader->GetVideoCodec()) {
|
||||
case NESTEGG_CODEC_VP8:
|
||||
mDecoderConfig->mMimeType = "video/webm; codecs=vp8";
|
||||
break;
|
||||
case NESTEGG_CODEC_VP9:
|
||||
mDecoderConfig->mMimeType = "video/webm; codecs=vp9";
|
||||
break;
|
||||
default:
|
||||
return InitPromise::CreateAndReject(DecoderFailureReason::INIT_ERROR, __func__);
|
||||
}
|
||||
|
||||
const VideoInfo& video = *mDecoderConfig;
|
||||
if (!IsSupportedVideoMimeType(video.mMimeType)) {
|
||||
return InitPromise::CreateAndReject(DecoderFailureReason::INIT_ERROR, __func__);
|
||||
}
|
||||
mMediaDataDecoder =
|
||||
mPlatform->CreateDecoder(video,
|
||||
mTaskQueue,
|
||||
this,
|
||||
mReader->GetLayersBackendType(),
|
||||
mReader->GetDecoder()->GetImageContainer());
|
||||
if (!mMediaDataDecoder) {
|
||||
return InitPromise::CreateAndReject(DecoderFailureReason::INIT_ERROR, __func__);
|
||||
}
|
||||
|
||||
return mMediaDataDecoder->Init();
|
||||
}
|
||||
|
||||
bool
|
||||
IntelWebMVideoDecoder::Demux(nsRefPtr<VP8Sample>& aSample, bool* aEOS)
|
||||
{
|
||||
nsRefPtr<NesteggPacketHolder> holder(mReader->NextPacket(WebMReader::VIDEO));
|
||||
if (!holder) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nestegg_packet* packet = holder->Packet();
|
||||
unsigned int track = 0;
|
||||
int r = nestegg_packet_track(packet, &track);
|
||||
if (r == -1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned int count = 0;
|
||||
r = nestegg_packet_count(packet, &count);
|
||||
if (r == -1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (count > 1) {
|
||||
NS_WARNING("Packet contains more than one video frame");
|
||||
return false;
|
||||
}
|
||||
|
||||
int64_t tstamp = holder->Timestamp();
|
||||
|
||||
// The end time of this frame is the start time of the next frame. Fetch
|
||||
// the timestamp of the next packet for this track. If we've reached the
|
||||
// end of the resource, use the file's duration as the end time of this
|
||||
// video frame.
|
||||
int64_t next_tstamp = 0;
|
||||
nsRefPtr<NesteggPacketHolder> next_holder(mReader->NextPacket(WebMReader::VIDEO));
|
||||
if (next_holder) {
|
||||
next_tstamp = holder->Timestamp();
|
||||
mReader->PushVideoPacket(next_holder);
|
||||
} else {
|
||||
next_tstamp = tstamp;
|
||||
next_tstamp += tstamp - mReader->GetLastVideoFrameTime();
|
||||
}
|
||||
mReader->SetLastVideoFrameTime(tstamp);
|
||||
|
||||
unsigned char* data;
|
||||
size_t length;
|
||||
r = nestegg_packet_data(packet, 0, &data, &length);
|
||||
if (r == -1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
vpx_codec_stream_info_t si;
|
||||
PodZero(&si);
|
||||
si.sz = sizeof(si);
|
||||
if (mReader->GetVideoCodec() == NESTEGG_CODEC_VP8) {
|
||||
vpx_codec_peek_stream_info(vpx_codec_vp8_dx(), data, length, &si);
|
||||
} else if (mReader->GetVideoCodec() == NESTEGG_CODEC_VP9) {
|
||||
vpx_codec_peek_stream_info(vpx_codec_vp9_dx(), data, length, &si);
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mPlatform && mMediaDataDecoder);
|
||||
|
||||
aSample = new VP8Sample(tstamp,
|
||||
next_tstamp - tstamp,
|
||||
0,
|
||||
data,
|
||||
length,
|
||||
si.is_kf);
|
||||
if (!aSample->Data()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
IntelWebMVideoDecoder::Decode()
|
||||
{
|
||||
MOZ_ASSERT(mMediaDataDecoder);
|
||||
|
||||
mMonitor.Lock();
|
||||
uint64_t prevNumFramesOutput = mNumSamplesOutput;
|
||||
while (prevNumFramesOutput == mNumSamplesOutput) {
|
||||
mMonitor.AssertCurrentThreadOwns();
|
||||
if (mError) {
|
||||
// Decode error!
|
||||
mMonitor.Unlock();
|
||||
return false;
|
||||
}
|
||||
while (prevNumFramesOutput == mNumSamplesOutput &&
|
||||
(mInputExhausted ||
|
||||
(mNumSamplesInput - mNumSamplesOutput) < mDecodeAhead) &&
|
||||
!mEOS) {
|
||||
mMonitor.AssertCurrentThreadOwns();
|
||||
mMonitor.Unlock();
|
||||
nsRefPtr<VP8Sample> compressed(PopSample());
|
||||
if (!compressed) {
|
||||
// EOS, or error. Let the state machine know there are no more
|
||||
// frames coming.
|
||||
LOG("Draining Video");
|
||||
mMonitor.Lock();
|
||||
MOZ_ASSERT(!mEOS);
|
||||
mEOS = true;
|
||||
MOZ_ASSERT(!mDrainComplete);
|
||||
mDrainComplete = false;
|
||||
mMonitor.Unlock();
|
||||
mMediaDataDecoder->Drain();
|
||||
} else {
|
||||
#ifdef LOG_SAMPLE_DECODE
|
||||
LOG("PopSample %s time=%lld dur=%lld", TrackTypeToStr(aTrack),
|
||||
compressed->mTime, compressed->mDuration);
|
||||
#endif
|
||||
mMonitor.Lock();
|
||||
mDrainComplete = false;
|
||||
mInputExhausted = false;
|
||||
mNumSamplesInput++;
|
||||
mMonitor.Unlock();
|
||||
if (NS_FAILED(mMediaDataDecoder->Input(compressed))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
mMonitor.Lock();
|
||||
}
|
||||
mMonitor.AssertCurrentThreadOwns();
|
||||
while (!mError &&
|
||||
prevNumFramesOutput == mNumSamplesOutput &&
|
||||
(!mInputExhausted || mEOS) &&
|
||||
!mDrainComplete) {
|
||||
mMonitor.Wait();
|
||||
}
|
||||
if (mError ||
|
||||
(mEOS && mDrainComplete)) {
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
mMonitor.AssertCurrentThreadOwns();
|
||||
bool rv = !(mEOS || mError);
|
||||
mMonitor.Unlock();
|
||||
return rv;
|
||||
}
|
||||
|
||||
bool
|
||||
IntelWebMVideoDecoder::SkipVideoDemuxToNextKeyFrame(int64_t aTimeThreshold, uint32_t& aParsed)
|
||||
{
|
||||
MOZ_ASSERT(mReader->GetDecoder());
|
||||
|
||||
Flush();
|
||||
|
||||
// Loop until we reach the next keyframe after the threshold.
|
||||
while (true) {
|
||||
nsRefPtr<VP8Sample> compressed(PopSample());
|
||||
if (!compressed) {
|
||||
// EOS, or error. Let the state machine know.
|
||||
return false;
|
||||
}
|
||||
aParsed++;
|
||||
if (!compressed->mKeyframe ||
|
||||
compressed->mTime < aTimeThreshold) {
|
||||
continue;
|
||||
}
|
||||
mQueuedVideoSample = compressed;
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
IntelWebMVideoDecoder::DecodeVideoFrame(bool& aKeyframeSkip,
|
||||
int64_t aTimeThreshold)
|
||||
{
|
||||
AbstractMediaDecoder::AutoNotifyDecoded a(mReader->GetDecoder());
|
||||
|
||||
MOZ_ASSERT(mPlatform && mReader->GetDecoder());
|
||||
|
||||
if (aKeyframeSkip) {
|
||||
bool ok = SkipVideoDemuxToNextKeyFrame(aTimeThreshold, a.mDropped);
|
||||
if (!ok) {
|
||||
NS_WARNING("Failed to skip demux up to next keyframe");
|
||||
return false;
|
||||
}
|
||||
a.mParsed = a.mDropped;
|
||||
aKeyframeSkip = false;
|
||||
nsresult rv = mMediaDataDecoder->Flush();
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mReader->OnTaskQueue());
|
||||
bool rv = Decode();
|
||||
{
|
||||
// Report the number of "decoded" frames as the difference in the
|
||||
// mNumSamplesOutput field since the last time we were called.
|
||||
MonitorAutoLock mon(mMonitor);
|
||||
uint64_t delta = mNumSamplesOutput - mLastReportedNumDecodedFrames;
|
||||
a.mDecoded = static_cast<uint32_t>(delta);
|
||||
mLastReportedNumDecodedFrames = mNumSamplesOutput;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
already_AddRefed<VP8Sample>
|
||||
IntelWebMVideoDecoder::PopSample()
|
||||
{
|
||||
if (mQueuedVideoSample) {
|
||||
return mQueuedVideoSample.forget();
|
||||
}
|
||||
nsRefPtr<VP8Sample> sample;
|
||||
while (mSampleQueue.empty()) {
|
||||
bool eos = false;
|
||||
bool ok = Demux(sample, &eos);
|
||||
if (!ok || eos) {
|
||||
MOZ_ASSERT(!sample);
|
||||
return nullptr;
|
||||
}
|
||||
MOZ_ASSERT(sample);
|
||||
mSampleQueue.push_back(sample.forget());
|
||||
}
|
||||
|
||||
MOZ_ASSERT(!mSampleQueue.empty());
|
||||
sample = mSampleQueue.front().forget();
|
||||
mSampleQueue.pop_front();
|
||||
return sample.forget();
|
||||
}
|
||||
|
||||
void
|
||||
IntelWebMVideoDecoder::Output(MediaData* aSample)
|
||||
{
|
||||
#ifdef LOG_SAMPLE_DECODE
|
||||
LOG("Decoded video sample time=%lld dur=%lld",
|
||||
aSample->mTime, aSample->mDuration);
|
||||
#endif
|
||||
|
||||
// Don't accept output while we're flushing.
|
||||
MonitorAutoLock mon(mMonitor);
|
||||
if (mIsFlushing) {
|
||||
mon.NotifyAll();
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(aSample->mType == MediaData::VIDEO_DATA);
|
||||
mReader->VideoQueue().Push(static_cast<VideoData*>(aSample));
|
||||
|
||||
mNumSamplesOutput++;
|
||||
mon.NotifyAll();
|
||||
}
|
||||
|
||||
void
|
||||
IntelWebMVideoDecoder::DrainComplete()
|
||||
{
|
||||
MonitorAutoLock mon(mMonitor);
|
||||
mDrainComplete = true;
|
||||
mon.NotifyAll();
|
||||
}
|
||||
|
||||
void
|
||||
IntelWebMVideoDecoder::InputExhausted()
|
||||
{
|
||||
MonitorAutoLock mon(mMonitor);
|
||||
mInputExhausted = true;
|
||||
mon.NotifyAll();
|
||||
}
|
||||
|
||||
void
|
||||
IntelWebMVideoDecoder::Error()
|
||||
{
|
||||
MonitorAutoLock mon(mMonitor);
|
||||
mError = true;
|
||||
mon.NotifyAll();
|
||||
}
|
||||
|
||||
nsresult
|
||||
IntelWebMVideoDecoder::Flush()
|
||||
{
|
||||
if (!mReader->GetDecoder()) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
// Purge the current decoder's state.
|
||||
// Set a flag so that we ignore all output while we call
|
||||
// MediaDataDecoder::Flush().
|
||||
{
|
||||
MonitorAutoLock mon(mMonitor);
|
||||
mIsFlushing = true;
|
||||
mDrainComplete = false;
|
||||
mEOS = false;
|
||||
}
|
||||
mMediaDataDecoder->Flush();
|
||||
{
|
||||
MonitorAutoLock mon(mMonitor);
|
||||
mIsFlushing = false;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
|
@ -1,97 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et cindent: */
|
||||
/* 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/. */
|
||||
#if !defined(IntelWebMVideoDecoder_h_)
|
||||
#define IntelWebMVideoDecoder_h_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "WebMReader.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "PlatformDecoderModule.h"
|
||||
#include "mozilla/Monitor.h"
|
||||
|
||||
#include "MediaInfo.h"
|
||||
#include "MediaData.h"
|
||||
|
||||
class TaskQueue;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class VP8Sample;
|
||||
|
||||
typedef std::deque<nsRefPtr<VP8Sample>> VP8SampleQueue;
|
||||
|
||||
class IntelWebMVideoDecoder : public WebMVideoDecoder, public MediaDataDecoderCallback
|
||||
{
|
||||
public:
|
||||
static WebMVideoDecoder* Create(WebMReader* aReader);
|
||||
virtual nsRefPtr<InitPromise> Init(unsigned int aWidth = 0,
|
||||
unsigned int aHeight = 0) override;
|
||||
virtual nsresult Flush() override;
|
||||
virtual void Shutdown() override;
|
||||
|
||||
virtual bool DecodeVideoFrame(bool &aKeyframeSkip,
|
||||
int64_t aTimeThreshold) override;
|
||||
|
||||
virtual void Output(MediaData* aSample) override;
|
||||
|
||||
virtual void DrainComplete() override;
|
||||
|
||||
virtual void InputExhausted() override;
|
||||
virtual void Error() override;
|
||||
|
||||
virtual bool OnReaderTaskQueue() override
|
||||
{
|
||||
return mReader->OnTaskQueue();
|
||||
}
|
||||
|
||||
IntelWebMVideoDecoder(WebMReader* aReader);
|
||||
~IntelWebMVideoDecoder();
|
||||
|
||||
private:
|
||||
void InitLayersBackendType();
|
||||
|
||||
bool Decode();
|
||||
|
||||
bool Demux(nsRefPtr<VP8Sample>& aSample, bool* aEOS);
|
||||
|
||||
bool SkipVideoDemuxToNextKeyFrame(int64_t aTimeThreshold, uint32_t& parsed);
|
||||
|
||||
bool IsSupportedVideoMimeType(const nsACString& aMimeType);
|
||||
|
||||
already_AddRefed<VP8Sample> PopSample();
|
||||
|
||||
nsRefPtr<WebMReader> mReader;
|
||||
nsRefPtr<PlatformDecoderModule> mPlatform;
|
||||
nsRefPtr<MediaDataDecoder> mMediaDataDecoder;
|
||||
|
||||
// TaskQueue on which decoder can choose to decode.
|
||||
// Only non-null up until the decoder is created.
|
||||
nsRefPtr<FlushableTaskQueue> mTaskQueue;
|
||||
|
||||
// Monitor that protects all non-threadsafe state; the primitives
|
||||
// that follow.
|
||||
Monitor mMonitor;
|
||||
nsAutoPtr<VideoInfo> mDecoderConfig;
|
||||
|
||||
VP8SampleQueue mSampleQueue;
|
||||
nsRefPtr<VP8Sample> mQueuedVideoSample;
|
||||
uint64_t mNumSamplesInput;
|
||||
uint64_t mNumSamplesOutput;
|
||||
uint64_t mLastReportedNumDecodedFrames;
|
||||
uint32_t mDecodeAhead;
|
||||
|
||||
// Whether this stream exists in the media.
|
||||
bool mInputExhausted;
|
||||
bool mDrainComplete;
|
||||
bool mError;
|
||||
bool mEOS;
|
||||
bool mIsFlushing;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
|
@ -53,16 +53,10 @@ SoftwareWebMVideoDecoder::Create(WebMReader* aReader)
|
|||
return new SoftwareWebMVideoDecoder(aReader);
|
||||
}
|
||||
|
||||
nsRefPtr<InitPromise>
|
||||
nsresult
|
||||
SoftwareWebMVideoDecoder::Init(unsigned int aWidth, unsigned int aHeight)
|
||||
{
|
||||
nsresult rv = InitDecoder(aWidth, aHeight);
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
return InitPromise::CreateAndResolve(TrackType::kVideoTrack, __func__);
|
||||
}
|
||||
|
||||
return InitPromise::CreateAndReject(DecoderFailureReason::INIT_ERROR, __func__);
|
||||
return InitDecoder(aWidth, aHeight);
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
|
|
@ -17,8 +17,8 @@ class SoftwareWebMVideoDecoder : public WebMVideoDecoder
|
|||
public:
|
||||
static WebMVideoDecoder* Create(WebMReader* aReader);
|
||||
|
||||
virtual nsRefPtr<InitPromise> Init(unsigned int aWidth = 0,
|
||||
unsigned int aHeight = 0) override;
|
||||
virtual nsresult Init(unsigned int aWidth = 0,
|
||||
unsigned int aHeight = 0) override;
|
||||
|
||||
virtual bool DecodeVideoFrame(bool &aKeyframeSkip,
|
||||
int64_t aTimeThreshold) override;
|
||||
|
|
|
@ -20,11 +20,6 @@
|
|||
#include "vpx/vp8dx.h"
|
||||
#include "vpx/vpx_decoder.h"
|
||||
|
||||
// IntelWebMVideoDecoder uses the WMF backend, which is Windows Vista+ only.
|
||||
#if defined(MOZ_PDM_VPX)
|
||||
#include "IntelWebMVideoDecoder.h"
|
||||
#endif
|
||||
|
||||
// Un-comment to enable logging of seek bisections.
|
||||
//#define SEEK_LOGGING
|
||||
|
||||
|
@ -125,10 +120,6 @@ static void webm_log(nestegg * context,
|
|||
va_end(args);
|
||||
}
|
||||
|
||||
#if defined(MOZ_PDM_VPX)
|
||||
static bool sIsIntelDecoderEnabled = false;
|
||||
#endif
|
||||
|
||||
WebMReader::WebMReader(AbstractMediaDecoder* aDecoder, TaskQueue* aBorrowedTaskQueue)
|
||||
: MediaDecoderReader(aDecoder, aBorrowedTaskQueue)
|
||||
, mContext(nullptr)
|
||||
|
@ -149,10 +140,6 @@ WebMReader::WebMReader(AbstractMediaDecoder* aDecoder, TaskQueue* aBorrowedTaskQ
|
|||
if (!gNesteggLog) {
|
||||
gNesteggLog = PR_NewLogModule("Nestegg");
|
||||
}
|
||||
|
||||
#if defined(MOZ_PDM_VPX)
|
||||
sIsIntelDecoderEnabled = Preferences::GetBool("media.webm.intel_decoder.enabled", false);
|
||||
#endif
|
||||
}
|
||||
|
||||
WebMReader::~WebMReader()
|
||||
|
@ -168,12 +155,6 @@ WebMReader::~WebMReader()
|
|||
nsRefPtr<ShutdownPromise>
|
||||
WebMReader::Shutdown()
|
||||
{
|
||||
#if defined(MOZ_PDM_VPX)
|
||||
if (mVideoTaskQueue) {
|
||||
mVideoTaskQueue->BeginShutdown();
|
||||
mVideoTaskQueue->AwaitShutdownAndIdle();
|
||||
}
|
||||
#endif
|
||||
if (mAudioDecoder) {
|
||||
mAudioDecoder->Shutdown();
|
||||
mAudioDecoder = nullptr;
|
||||
|
@ -189,18 +170,6 @@ WebMReader::Shutdown()
|
|||
|
||||
nsresult WebMReader::Init(MediaDecoderReader* aCloneDonor)
|
||||
{
|
||||
#if defined(MOZ_PDM_VPX)
|
||||
if (sIsIntelDecoderEnabled) {
|
||||
PlatformDecoderModule::Init();
|
||||
|
||||
InitLayersBackendType();
|
||||
|
||||
mVideoTaskQueue = new FlushableTaskQueue(
|
||||
SharedThreadPool::Get(NS_LITERAL_CSTRING("IntelVP8 Video Decode")));
|
||||
NS_ENSURE_TRUE(mVideoTaskQueue, NS_ERROR_FAILURE);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (aCloneDonor) {
|
||||
mBufferedState = static_cast<WebMReader*>(aCloneDonor)->mBufferedState;
|
||||
} else {
|
||||
|
@ -327,23 +296,13 @@ WebMReader::RetrieveWebMMetadata(MediaInfo* aInfo)
|
|||
|
||||
mVideoCodec = nestegg_track_codec_id(mContext, track);
|
||||
|
||||
#if defined(MOZ_PDM_VPX)
|
||||
if (sIsIntelDecoderEnabled) {
|
||||
mVideoDecoder = IntelWebMVideoDecoder::Create(this);
|
||||
}
|
||||
#endif
|
||||
|
||||
// If there's no decoder yet (e.g. HW decoder not available), use the software decoder.
|
||||
if (!mVideoDecoder) {
|
||||
mVideoDecoder = SoftwareWebMVideoDecoder::Create(this);
|
||||
}
|
||||
|
||||
if (mVideoDecoder) {
|
||||
mInitPromises.AppendElement(mVideoDecoder->Init(params.display_width,
|
||||
params.display_height));
|
||||
}
|
||||
|
||||
if (!mVideoDecoder) {
|
||||
if (!mVideoDecoder ||
|
||||
NS_FAILED(mVideoDecoder->Init(params.display_width,
|
||||
params.display_height))) {
|
||||
Cleanup();
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
@ -424,9 +383,7 @@ WebMReader::RetrieveWebMMetadata(MediaInfo* aInfo)
|
|||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (mAudioDecoder) {
|
||||
mInitPromises.AppendElement(mAudioDecoder->Init());
|
||||
} else {
|
||||
if (!mAudioDecoder || NS_FAILED(mAudioDecoder->Init())) {
|
||||
Cleanup();
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
#include "FlushableTaskQueue.h"
|
||||
#include "MediaDecoderReader.h"
|
||||
#include "MediaResource.h"
|
||||
#include "PlatformDecoderModule.h"
|
||||
#include "nsAutoRef.h"
|
||||
#include "nestegg/nestegg.h"
|
||||
|
||||
|
@ -26,9 +25,7 @@ namespace mozilla {
|
|||
static const unsigned NS_PER_USEC = 1000;
|
||||
static const double NS_PER_S = 1e9;
|
||||
|
||||
typedef MediaDataDecoder::InitPromise InitPromise;
|
||||
typedef TrackInfo::TrackType TrackType;
|
||||
typedef MediaDataDecoder::DecoderFailureReason DecoderFailureReason;
|
||||
|
||||
class WebMBufferedState;
|
||||
class WebMPacketQueue;
|
||||
|
@ -39,7 +36,7 @@ class WebMReader;
|
|||
class WebMVideoDecoder
|
||||
{
|
||||
public:
|
||||
virtual nsRefPtr<InitPromise> Init(unsigned int aWidth = 0, unsigned int aHeight = 0) = 0;
|
||||
virtual nsresult Init(unsigned int aWidth = 0, unsigned int aHeight = 0) = 0;
|
||||
virtual nsresult Flush() { return NS_OK; }
|
||||
virtual void Shutdown() = 0;
|
||||
virtual bool DecodeVideoFrame(bool &aKeyframeSkip,
|
||||
|
@ -52,7 +49,7 @@ public:
|
|||
class WebMAudioDecoder
|
||||
{
|
||||
public:
|
||||
virtual nsRefPtr<InitPromise> Init() = 0;
|
||||
virtual nsresult Init() = 0;
|
||||
virtual void Shutdown() = 0;
|
||||
virtual nsresult ResetDecode() = 0;
|
||||
virtual nsresult DecodeHeader(const unsigned char* aData, size_t aLength) = 0;
|
||||
|
@ -122,7 +119,6 @@ public:
|
|||
int64_t GetLastVideoFrameTime();
|
||||
void SetLastVideoFrameTime(int64_t aFrameTime);
|
||||
layers::LayersBackend GetLayersBackendType() { return mLayersBackendType; }
|
||||
FlushableTaskQueue* GetVideoTaskQueue() { return mVideoTaskQueue; }
|
||||
uint64_t GetCodecDelay() { return mCodecDelay; }
|
||||
|
||||
protected:
|
||||
|
@ -167,8 +163,6 @@ private:
|
|||
nsAutoPtr<WebMAudioDecoder> mAudioDecoder;
|
||||
nsAutoPtr<WebMVideoDecoder> mVideoDecoder;
|
||||
|
||||
nsTArray<nsRefPtr<InitPromise>> mInitPromises;
|
||||
|
||||
// Queue of video and audio packets that have been read but not decoded. These
|
||||
// must only be accessed from the decode thread.
|
||||
WebMPacketQueue mVideoPackets;
|
||||
|
@ -212,9 +206,6 @@ private:
|
|||
|
||||
layers::LayersBackend mLayersBackendType;
|
||||
|
||||
// For hardware video decoding.
|
||||
nsRefPtr<FlushableTaskQueue> mVideoTaskQueue;
|
||||
|
||||
// Booleans to indicate if we have audio and/or video data
|
||||
bool mHasVideo;
|
||||
bool mHasAudio;
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
EXPORTS += [
|
||||
'IntelWebMVideoDecoder.h',
|
||||
'NesteggPacketHolder.h',
|
||||
'SoftwareWebMVideoDecoder.h',
|
||||
'WebMBufferedParser.h',
|
||||
|
@ -23,10 +22,6 @@ UNIFIED_SOURCES += [
|
|||
'WebMReader.cpp',
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_FMP4'] and CONFIG['MOZ_WMF']:
|
||||
DEFINES['MOZ_PDM_VPX'] = True
|
||||
UNIFIED_SOURCES += ['IntelWebMVideoDecoder.cpp']
|
||||
|
||||
if CONFIG['MOZ_WEBM_ENCODER']:
|
||||
EXPORTS += ['WebMWriter.h']
|
||||
UNIFIED_SOURCES += ['EbmlComposer.cpp',
|
||||
|
|
Загрузка…
Ссылка в новой задаче