Bug 862182. r=roc,doublec

This commit is contained in:
Chris Pearce 2013-05-03 10:59:18 +12:00
parent 97aa06ad85
commit 01b2b87eff
13 changed files with 68 additions and 72 deletions

View File

@ -2389,7 +2389,7 @@ nsresult HTMLMediaElement::InitializeDecoderAsClone(MediaDecoder* aOriginal)
decoder->SetMediaSeekable(aOriginal->IsMediaSeekable());
}
MediaResource* resource = originalResource->CloneData(decoder);
nsRefPtr<MediaResource> resource = originalResource->CloneData(decoder);
if (!resource) {
LOG(PR_LOG_DEBUG, ("%p Failed to cloned stream for decoder %p", this, decoder.get()));
return NS_ERROR_FAILURE;
@ -2421,7 +2421,7 @@ nsresult HTMLMediaElement::InitializeDecoderForChannel(nsIChannel* aChannel,
LOG(PR_LOG_DEBUG, ("%p Created decoder %p for type %s", this, decoder.get(), mimeType.get()));
MediaResource* resource = MediaResource::Create(decoder, aChannel);
nsRefPtr<MediaResource> resource = MediaResource::Create(decoder, aChannel);
if (!resource)
return NS_ERROR_OUT_OF_MEMORY;

View File

@ -48,7 +48,7 @@ public:
return principal.forget();
}
virtual bool CanClone() { return false; }
virtual MediaResource* CloneData(MediaDecoder* aDecoder)
virtual already_AddRefed<MediaResource> CloneData(MediaDecoder* aDecoder)
{
return nullptr;
}
@ -102,7 +102,7 @@ public:
virtual int64_t GetNextCachedData(int64_t aOffset) { return aOffset; }
virtual int64_t GetCachedDataEnd(int64_t aOffset) { return mLength; }
virtual bool IsDataCachedToEndOfResource(int64_t aOffset) { return true; }
virtual bool IsSuspendedByCache(MediaResource** aActiveResource) { return false; }
virtual bool IsSuspendedByCache() { return false; }
virtual bool IsSuspended() { return false; }
virtual nsresult ReadFromCache(char* aBuffer,
int64_t aOffset,

View File

@ -1830,7 +1830,7 @@ MediaCacheStream::IsTransportSeekable()
}
bool
MediaCacheStream::AreAllStreamsForResourceSuspended(MediaResource** aActiveStream)
MediaCacheStream::AreAllStreamsForResourceSuspended()
{
ReentrantMonitorAutoEnter mon(gMediaCache->GetReentrantMonitor());
MediaCache::ResourceStreamIterator iter(mResourceID);
@ -1847,15 +1847,9 @@ MediaCacheStream::AreAllStreamsForResourceSuspended(MediaResource** aActiveStrea
if (stream->mChannelOffset > dataOffset) {
continue;
}
if (aActiveStream) {
*aActiveStream = stream->mClient;
}
return false;
}
if (aActiveStream) {
*aActiveStream = nullptr;
}
return true;
}

View File

@ -331,9 +331,7 @@ public:
// Returns true when all streams for this resource are suspended or their
// channel has ended.
// If aActiveResource is non-null, fills it with a pointer to a stream
// for this resource that is not suspended or ended.
bool AreAllStreamsForResourceSuspended(MediaResource** aActiveResource);
bool AreAllStreamsForResourceSuspended();
// These methods must be called on a different thread from the main
// thread. They should always be called on the same thread for a given

View File

@ -409,7 +409,7 @@ MediaDecoder::~MediaDecoder()
}
nsresult MediaDecoder::OpenResource(MediaResource* aResource,
nsIStreamListener** aStreamListener)
nsIStreamListener** aStreamListener)
{
MOZ_ASSERT(NS_IsMainThread());
if (aStreamListener) {
@ -425,7 +425,6 @@ nsresult MediaDecoder::OpenResource(MediaResource* aResource,
nsresult rv = aResource->Open(aStreamListener);
if (NS_FAILED(rv)) {
LOG(PR_LOG_DEBUG, ("%p Failed to open stream!", this));
delete aResource;
return rv;
}
@ -948,9 +947,7 @@ void MediaDecoder::NotifySuspendedStatusChanged()
MOZ_ASSERT(NS_IsMainThread());
if (!mResource)
return;
MediaResource* activeStream;
bool suspended = mResource->IsSuspendedByCache(&activeStream);
bool suspended = mResource->IsSuspendedByCache();
if (mOwner) {
mOwner->NotifySuspendedByCache(suspended);
UpdateReadyStateForData();

View File

@ -296,6 +296,12 @@ public:
// Get the current MediaResource being used. Its URI will be returned
// by currentSrc. Returns what was passed to Load(), if Load() has been called.
// Note: The MediaResource is refcounted, but it outlives the MediaDecoder,
// so it's OK to use the reference returned by this function without
// refcounting, *unless* you need to store and use the reference after the
// MediaDecoder has been destroyed. You might need to do this if you're
// wrapping the MediaResource in some kind of byte stream interface to be
// passed to a platform decoder.
MediaResource* GetResource() const MOZ_FINAL MOZ_OVERRIDE
{
return mResource;

View File

@ -713,15 +713,16 @@ bool ChannelMediaResource::CanClone()
return mCacheStream.IsAvailableForSharing();
}
MediaResource* ChannelMediaResource::CloneData(MediaDecoder* aDecoder)
already_AddRefed<MediaResource> ChannelMediaResource::CloneData(MediaDecoder* aDecoder)
{
NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
NS_ASSERTION(mCacheStream.IsAvailableForSharing(), "Stream can't be cloned");
ChannelMediaResource* resource = new ChannelMediaResource(aDecoder,
nullptr,
mURI,
GetContentType());
nsRefPtr<ChannelMediaResource> resource =
new ChannelMediaResource(aDecoder,
nullptr,
mURI,
GetContentType());
if (resource) {
// Initially the clone is treated as suspended by the cache, because
// we don't have a channel. If the cache needs to read data from the clone
@ -734,7 +735,7 @@ MediaResource* ChannelMediaResource::CloneData(MediaDecoder* aDecoder)
resource->mChannelStatistics = new MediaChannelStatistics(mChannelStatistics);
resource->mChannelStatistics->Stop();
}
return resource;
return resource.forget();
}
void ChannelMediaResource::CloseChannel()
@ -1187,9 +1188,9 @@ ChannelMediaResource::EnsureCacheUpToDate()
}
bool
ChannelMediaResource::IsSuspendedByCache(MediaResource** aActiveResource)
ChannelMediaResource::IsSuspendedByCache()
{
return mCacheStream.AreAllStreamsForResourceSuspended(aActiveResource);
return mCacheStream.AreAllStreamsForResourceSuspended();
}
bool
@ -1283,7 +1284,7 @@ public:
virtual void Resume() {}
virtual already_AddRefed<nsIPrincipal> GetCurrentPrincipal();
virtual bool CanClone();
virtual MediaResource* CloneData(MediaDecoder* aDecoder);
virtual already_AddRefed<MediaResource> CloneData(MediaDecoder* aDecoder);
virtual nsresult ReadFromCache(char* aBuffer, int64_t aOffset, uint32_t aCount);
// These methods are called off the main thread.
@ -1326,13 +1327,7 @@ public:
return std::max(aOffset, mSize);
}
virtual bool IsDataCachedToEndOfResource(int64_t aOffset) { return true; }
virtual bool IsSuspendedByCache(MediaResource** aActiveResource)
{
if (aActiveResource) {
*aActiveResource = nullptr;
}
return false;
}
virtual bool IsSuspendedByCache() { return false; }
virtual bool IsSuspended() { return false; }
virtual bool IsTransportSeekable() MOZ_OVERRIDE { return true; }
@ -1504,7 +1499,7 @@ bool FileMediaResource::CanClone()
return true;
}
MediaResource* FileMediaResource::CloneData(MediaDecoder* aDecoder)
already_AddRefed<MediaResource> FileMediaResource::CloneData(MediaDecoder* aDecoder)
{
NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
@ -1527,7 +1522,8 @@ MediaResource* FileMediaResource::CloneData(MediaDecoder* aDecoder)
if (NS_FAILED(rv))
return nullptr;
return new FileMediaResource(aDecoder, channel, mURI, GetContentType());
nsRefPtr<MediaResource> resource(new FileMediaResource(aDecoder, channel, mURI, GetContentType()));
return resource.forget();
}
nsresult FileMediaResource::ReadFromCache(char* aBuffer, int64_t aOffset, uint32_t aCount)
@ -1592,7 +1588,7 @@ int64_t FileMediaResource::Tell()
return offset;
}
MediaResource*
already_AddRefed<MediaResource>
MediaResource::Create(MediaDecoder* aDecoder, nsIChannel* aChannel)
{
NS_ASSERTION(NS_IsMainThread(),
@ -1609,10 +1605,13 @@ MediaResource::Create(MediaDecoder* aDecoder, nsIChannel* aChannel)
aChannel->GetContentType(contentType);
nsCOMPtr<nsIFileChannel> fc = do_QueryInterface(aChannel);
nsRefPtr<MediaResource> resource;
if (fc || IsBlobURI(uri)) {
return new FileMediaResource(aDecoder, aChannel, uri, contentType);
resource = new FileMediaResource(aDecoder, aChannel, uri, contentType);
} else {
resource = new ChannelMediaResource(aDecoder, aChannel, uri, contentType);
}
return new ChannelMediaResource(aDecoder, aChannel, uri, contentType);
return resource.forget();
}
void BaseMediaResource::MoveLoadsToBackground() {

View File

@ -196,8 +196,6 @@ public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaResource)
virtual ~MediaResource() {}
// The following can be called on the main thread only:
// Get the URI
virtual nsIURI* URI() const { return nullptr; }
@ -224,7 +222,7 @@ public:
// Create a new stream of the same type that refers to the same URI
// with a new channel. Any cached data associated with the original
// stream should be accessible in the new stream too.
virtual MediaResource* CloneData(MediaDecoder* aDecoder) = 0;
virtual already_AddRefed<MediaResource> CloneData(MediaDecoder* aDecoder) = 0;
// Set statistics to be recorded to the object passed in.
virtual void RecordStatisticsTo(MediaChannelStatistics *aStatistics) { }
@ -313,9 +311,7 @@ public:
// changes.
// For resources using the media cache, this returns true only when all
// streams for the same resource are all suspended.
// If aActiveResource is non-null, fills it with a pointer to a stream
// for this resource that is not suspended or ended.
virtual bool IsSuspendedByCache(MediaResource** aActiveResource) = 0;
virtual bool IsSuspendedByCache() = 0;
// Returns true if this stream has been suspended.
virtual bool IsSuspended() = 0;
// Reads only data which is cached in the media cache. If you try to read
@ -335,7 +331,7 @@ public:
* Create a resource, reading data from the channel. Call on main thread only.
* The caller must follow up by calling resource->Open().
*/
static MediaResource* Create(MediaDecoder* aDecoder, nsIChannel* aChannel);
static already_AddRefed<MediaResource> Create(MediaDecoder* aDecoder, nsIChannel* aChannel);
/**
* Open the stream. This creates a stream listener and returns it in
@ -374,6 +370,8 @@ public:
// nsIChannel when the MediaResource is created. Safe to call from
// any thread.
virtual const nsCString& GetContentType() const = 0;
protected:
virtual ~MediaResource() {};
};
class BaseMediaResource : public MediaResource {
@ -496,7 +494,7 @@ public:
// Return true if the stream has been closed.
bool IsClosed() const { return mCacheStream.IsClosed(); }
virtual bool CanClone();
virtual MediaResource* CloneData(MediaDecoder* aDecoder);
virtual already_AddRefed<MediaResource> CloneData(MediaDecoder* aDecoder);
// Set statistics to be recorded to the object passed in. If not called,
// |ChannelMediaResource| will create it's own statistics objects in |Open|.
void RecordStatisticsTo(MediaChannelStatistics *aStatistics) MOZ_OVERRIDE {
@ -526,7 +524,7 @@ public:
virtual int64_t GetNextCachedData(int64_t aOffset);
virtual int64_t GetCachedDataEnd(int64_t aOffset);
virtual bool IsDataCachedToEndOfResource(int64_t aOffset);
virtual bool IsSuspendedByCache(MediaResource** aActiveResource);
virtual bool IsSuspendedByCache();
virtual bool IsSuspended();
virtual bool IsTransportSeekable() MOZ_OVERRIDE;
@ -547,7 +545,7 @@ public:
void Revoke() { mResource = nullptr; }
private:
ChannelMediaResource* mResource;
nsRefPtr<ChannelMediaResource> mResource;
};
friend class Listener;

View File

@ -22,7 +22,6 @@ struct VideoPlane {
struct VideoFrame {
int64_t mTimeUs;
int64_t mEndTimeUs;
bool mKeyFrame;
bool mShouldSkip;
void *mData;

View File

@ -43,7 +43,7 @@ nsresult MediaOmxReader::Init(MediaDecoderReader* aCloneDonor)
}
nsresult MediaOmxReader::ReadMetadata(VideoInfo* aInfo,
MetadataTags** aTags)
MetadataTags** aTags)
{
NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
@ -118,7 +118,7 @@ nsresult MediaOmxReader::ResetDecode()
}
bool MediaOmxReader::DecodeVideoFrame(bool &aKeyframeSkip,
int64_t aTimeThreshold)
int64_t aTimeThreshold)
{
// Record number of frames decoded and parsed. Automatically update the
// stats counters using the AutoNotifyDecoded stack-based class.
@ -339,7 +339,7 @@ void MediaOmxReader::OnDecodeThreadFinish() {
void MediaOmxReader::OnDecodeThreadStart() {
if (mOmxDecoder.get()) {
nsresult result = mOmxDecoder->Play();
DebugOnly<nsresult> result = mOmxDecoder->Play();
NS_ASSERTION(result == NS_OK, "OmxDecoder should be in play state to continue decoding");
}
}

View File

@ -39,8 +39,8 @@ VideoGraphicBuffer::VideoGraphicBuffer(const android::wp<android::OmxDecoder> aO
android::MediaBuffer *aBuffer,
SurfaceDescriptor *aDescriptor)
: GraphicBufferLocked(*aDescriptor),
mOmxDecoder(aOmxDecoder),
mMediaBuffer(aBuffer)
mMediaBuffer(aBuffer),
mOmxDecoder(aOmxDecoder)
{
mMediaBuffer->add_ref();
}
@ -74,7 +74,7 @@ namespace android {
MediaStreamSource::MediaStreamSource(MediaResource *aResource,
AbstractMediaDecoder *aDecoder) :
mDecoder(aDecoder), mResource(aResource)
mResource(aResource), mDecoder(aDecoder)
{
}
@ -127,8 +127,8 @@ using namespace android;
OmxDecoder::OmxDecoder(MediaResource *aResource,
AbstractMediaDecoder *aDecoder) :
mResource(aResource),
mDecoder(aDecoder),
mResource(aResource),
mVideoWidth(0),
mVideoHeight(0),
mVideoColorFormat(0),
@ -141,8 +141,8 @@ OmxDecoder::OmxDecoder(MediaResource *aResource,
mVideoBuffer(nullptr),
mAudioBuffer(nullptr),
mIsVideoSeeking(false),
mPaused(false),
mAudioMetadataRead(false)
mAudioMetadataRead(false),
mPaused(false)
{
}
@ -234,7 +234,7 @@ bool OmxDecoder::Init() {
// OMXClient::connect() always returns OK and abort's fatally if
// it can't connect.
OMXClient client;
status_t err = client.connect();
DebugOnly<status_t> err = client.connect();
NS_ASSERTION(err == OK, "Failed to connect to OMX in mediaserver.");
sp<IOMX> omx = client.interface();
@ -512,7 +512,6 @@ bool OmxDecoder::ReadVideo(VideoFrame *aFrame, int64_t aTimeUs,
if (err == OK && mVideoBuffer->range_length() > 0) {
int64_t timeUs;
int64_t durationUs;
int32_t unreadable;
int32_t keyFrame;
@ -545,7 +544,6 @@ bool OmxDecoder::ReadVideo(VideoFrame *aFrame, int64_t aTimeUs,
aFrame->mGraphicBuffer = new mozilla::layers::VideoGraphicBuffer(this, mVideoBuffer, &newDescriptor);
aFrame->mRotation = mVideoRotation;
aFrame->mTimeUs = timeUs;
aFrame->mEndTimeUs = timeUs + durationUs;
aFrame->mKeyFrame = keyFrame;
aFrame->Y.mWidth = mVideoWidth;
aFrame->Y.mHeight = mVideoHeight;
@ -560,8 +558,6 @@ bool OmxDecoder::ReadVideo(VideoFrame *aFrame, int64_t aTimeUs,
if (!ToVideoFrame(aFrame, timeUs, data, length, keyFrame)) {
return false;
}
aFrame->mEndTimeUs = timeUs + durationUs;
}
if (aKeyframeSkip && timeUs < aTimeUs) {
@ -696,3 +692,4 @@ void OmxDecoder::Pause() {
}
mPaused = true;
}

View File

@ -38,10 +38,10 @@ class MediaStreamSource : public DataSource {
typedef mozilla::MediaResource MediaResource;
typedef mozilla::AbstractMediaDecoder AbstractMediaDecoder;
MediaResource *mResource;
nsRefPtr<MediaResource> mResource;
AbstractMediaDecoder *mDecoder;
public:
MediaStreamSource(MediaResource *aResource,
MediaStreamSource(MediaResource* aResource,
AbstractMediaDecoder *aDecoder);
virtual status_t initCheck() const;
@ -80,7 +80,7 @@ class OmxDecoder : public RefBase {
};
AbstractMediaDecoder *mDecoder;
MediaResource *mResource;
nsRefPtr<MediaResource> mResource;
sp<GonkNativeWindow> mNativeWindow;
sp<GonkNativeWindowClient> mNativeWindowClient;
sp<MediaSource> mVideoTrack;

View File

@ -273,15 +273,16 @@ bool MediaPluginHost::FindDecoder(const nsACString& aMimeType, const char* const
MPAPI::Decoder *MediaPluginHost::CreateDecoder(MediaResource *aResource, const nsACString& aMimeType)
{
const char *chars;
size_t len = NS_CStringGetData(aMimeType, &chars, nullptr);
NS_ENSURE_TRUE(aResource, nullptr);
Decoder *decoder = new Decoder();
nsAutoPtr<Decoder> decoder(new Decoder());
if (!decoder) {
return nullptr;
}
decoder->mResource = aResource;
const char *chars;
size_t len = NS_CStringGetData(aMimeType, &chars, nullptr);
for (size_t n = 0; n < mPlugins.Length(); ++n) {
Manifest *plugin = mPlugins[n];
const char* const *codecs;
@ -289,7 +290,8 @@ MPAPI::Decoder *MediaPluginHost::CreateDecoder(MediaResource *aResource, const n
continue;
}
if (plugin->CreateDecoder(&sPluginHost, decoder, chars, len)) {
return decoder;
aResource->AddRef();
return decoder.forget();
}
}
@ -299,6 +301,12 @@ MPAPI::Decoder *MediaPluginHost::CreateDecoder(MediaResource *aResource, const n
void MediaPluginHost::DestroyDecoder(Decoder *aDecoder)
{
aDecoder->DestroyDecoder(aDecoder);
MediaResource* resource = GetResource(aDecoder);
if (resource) {
// resource *shouldn't* be null, but check anyway just in case the plugin
// decoder does something stupid.
resource->Release();
}
delete aDecoder;
}