Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Return media changes back
  • Loading branch information
romaxa committed Oct 31, 2014
1 parent 2204493 commit b318b3c
Show file tree
Hide file tree
Showing 8 changed files with 224 additions and 9 deletions.
4 changes: 4 additions & 0 deletions dom/media/MediaDecoder.cpp
Expand Up @@ -33,6 +33,7 @@
#ifdef MOZ_WMF
#include "WMFDecoder.h"
#endif
#include "NemoResourceHandler.h"

using namespace mozilla::layers;
using namespace mozilla::dom;
Expand Down Expand Up @@ -161,6 +162,7 @@ void MediaDecoder::SetDormantIfNecessary(bool aDormant)
void MediaDecoder::Pause()
{
MOZ_ASSERT(NS_IsMainThread());
NemoResourceHandler::ReleaseResources(this);
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
if ((mPlayState == PLAY_STATE_LOADING && mIsDormant) ||
mPlayState == PLAY_STATE_SEEKING ||
Expand Down Expand Up @@ -609,6 +611,7 @@ nsresult MediaDecoder::Play()
}
nsresult res = ScheduleStateMachineThread();
NS_ENSURE_SUCCESS(res,res);
NemoResourceHandler::AquireResources(this);
if ((mPlayState == PLAY_STATE_LOADING && mIsDormant) || mPlayState == PLAY_STATE_SEEKING) {
mNextState = PLAY_STATE_PLAYING;
return NS_OK;
Expand Down Expand Up @@ -693,6 +696,7 @@ void MediaDecoder::MetadataLoaded(MediaInfo* aInfo, MetadataTags* aTags)
return;
}

NemoResourceHandler::MediaInfo(this, aInfo->HasAudio(), aInfo->HasVideo());
DECODER_LOG("MetadataLoaded, channels=%u rate=%u hasAudio=%d hasVideo=%d",
aInfo->mAudio.mChannels, aInfo->mAudio.mRate,
aInfo->HasAudio(), aInfo->HasVideo());
Expand Down
116 changes: 116 additions & 0 deletions dom/media/NemoResourceHandler.cpp
@@ -0,0 +1,116 @@
/* -*- 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 "NemoResourceHandler.h"

#include "nsThreadUtils.h"
#include "mozilla/Services.h"
#include "nsIObserverService.h"
#include "nsStringGlue.h"
#include "mozilla/Preferences.h"

namespace mozilla {

NemoResourceHandler* NemoResourceHandler::mGlobalHandler = nullptr;

void
NemoResourceHandler::AquireResources(void* aHolder)
{
MOZ_ASSERT(NS_IsMainThread());
nsCOMPtr<nsIObserverService> obs =
mozilla::services::GetObserverService();
if (obs) {
nsString data;
data.AppendPrintf("{ \"owner\" : \"%p\", \"state\": \"play\" }", aHolder);
obs->NotifyObservers(nullptr, "media-decoder-info", data.get());
}

if (Preferences::GetBool("media.resource_handler_disabled", false) == true) {
return;
}

if (mGlobalHandler == nullptr)
{
mGlobalHandler = new NemoResourceHandler();
}
mGlobalHandler->Aquire();
}

void
NemoResourceHandler::ReleaseResources(void* aHolder)
{
MOZ_ASSERT(NS_IsMainThread());
nsCOMPtr<nsIObserverService> obs =
mozilla::services::GetObserverService();
if (obs) {
nsString data;
data.AppendPrintf("{ \"owner\" : \"%p\", \"state\": \"pause\" }", aHolder);
obs->NotifyObservers(nullptr, "media-decoder-info", data.get());
}

if (Preferences::GetBool("media.resource_handler_disabled", false) == true) {
return;
}

if (!mGlobalHandler) {
return;
}

mGlobalHandler->Release();

if (mGlobalHandler->CanDestroy())
{
delete mGlobalHandler;
mGlobalHandler = nullptr;
}
}

void
NemoResourceHandler::MediaInfo(void* aHolder, bool aHasAudio, bool aHasVideo)
{
MOZ_ASSERT(NS_IsMainThread());
nsCOMPtr<nsIObserverService> obs =
mozilla::services::GetObserverService();
if (obs) {
nsString data;
data.AppendPrintf("{ \"owner\" : \"%p\", \"state\": \"meta\", \"a\" : %i, \"v\" : %i }", aHolder, aHasAudio, aHasVideo);
obs->NotifyObservers(nullptr, "media-decoder-info", data.get());
}
}

void
NemoResourceHandler::Aquire()
{
mCounter++;
}

void
NemoResourceHandler::Release()
{
mCounter--;
}

bool
NemoResourceHandler::CanDestroy()
{
return mCounter <= 0;
}

NemoResourceHandler::NemoResourceHandler()
: mCounter(0)
{
MOZ_ASSERT(mGlobalHandler == nullptr);
mGlobalHandler = this;
}

NemoResourceHandler::~NemoResourceHandler()
{
MOZ_ASSERT(mGlobalHandler != nullptr);
mGlobalHandler = nullptr;
}

} // namespace mozilla

31 changes: 31 additions & 0 deletions dom/media/NemoResourceHandler.h
@@ -0,0 +1,31 @@
/* -*- 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/. */

#ifndef NEMO_RESOURCE_HANDLER
#define NEMO_RESOURCE_HANDLER

namespace mozilla {

class NemoResourceHandler
{
public:
static void AquireResources(void* aHolder);
static void ReleaseResources(void* aHolder);
static void MediaInfo(void* aHolder, bool aHasAudio, bool aHasVideo);
private:
NemoResourceHandler();
virtual ~NemoResourceHandler();
void Aquire();
void Release();
bool CanDestroy();

static NemoResourceHandler* mGlobalHandler;
int mCounter;
};

} // namespace mozilla

#endif // NEMO_RESOURCE_HANDLER
19 changes: 18 additions & 1 deletion dom/media/gstreamer/GStreamerDecoder.cpp
Expand Up @@ -13,7 +13,8 @@ namespace mozilla {

MediaDecoderStateMachine* GStreamerDecoder::CreateStateMachine()
{
return new MediaDecoderStateMachine(this, new GStreamerReader(this));
mLastReader = new GStreamerReader(this);
return new MediaDecoderStateMachine(this, mLastReader);
}

bool
Expand All @@ -24,5 +25,21 @@ GStreamerDecoder::CanHandleMediaType(const nsACString& aMIMEType,
GStreamerFormatHelper::Instance()->CanHandleMediaType(aMIMEType, aCodecs);
}

void
GStreamerDecoder::Suspend()
{
if (mLastReader) {
mLastReader->Suspend();
}
}

void GStreamerDecoder::NotifyPlaybackStopped()
{
if (mLastReader) {
mLastReader->Suspend();
}
MediaDecoder::NotifyPlaybackStopped();
}

} // namespace mozilla

6 changes: 6 additions & 0 deletions dom/media/gstreamer/GStreamerDecoder.h
Expand Up @@ -12,12 +12,18 @@

namespace mozilla {

class GStreamerReader;
class GStreamerDecoder : public MediaDecoder
{
public:
virtual MediaDecoder* Clone() { return new GStreamerDecoder(); }
virtual void Suspend() MOZ_OVERRIDE;
virtual MediaDecoderStateMachine* CreateStateMachine();
static bool CanHandleMediaType(const nsACString& aMIMEType, const nsAString* aCodecs);
virtual void NotifyPlaybackStopped() MOZ_OVERRIDE;

private:
GStreamerReader* mLastReader;
};

} // namespace mozilla
Expand Down
53 changes: 45 additions & 8 deletions dom/media/gstreamer/GStreamerReader.cpp
Expand Up @@ -65,6 +65,30 @@ typedef enum {
GST_PLAY_FLAG_SOFT_COLORBALANCE = (1 << 10)
} PlayFlags;

static const char defaultFilter[] = "capsfilter name=filter ! ";
static const char nemoFilter[] = "colorconv ! capsfilter name=filter ! ";
static bool useNemoFilter = getenv("USE_NEMO_GSTREAMER") != 0;

void* sCurrentDecoderUser = nullptr;
static bool sNoLimitOneGSTDecoder = getenv("NO_LIMIT_ONE_GST_DECODER") != 0;

void ResetIfCurrentDecoderActive(void* aCaller)
{
if (!sNoLimitOneGSTDecoder && sCurrentDecoderUser == aCaller) {
sCurrentDecoderUser = nullptr;
}
}

bool UpdateCurrentAsActiveIfNotBusy(void* aCaller)
{
if (!sNoLimitOneGSTDecoder && sCurrentDecoderUser != nullptr && sCurrentDecoderUser != aCaller)
{
return false;
}
sCurrentDecoderUser = aCaller;
return true;
}

GStreamerReader::GStreamerReader(AbstractMediaDecoder* aDecoder)
: MediaDecoderReader(aDecoder),
mMP3FrameParser(aDecoder->GetResource()->GetLength()),
Expand Down Expand Up @@ -117,6 +141,7 @@ GStreamerReader::~GStreamerReader()
MOZ_COUNT_DTOR(GStreamerReader);
ResetDecode();

ResetIfCurrentDecoderActive(this);
if (mPlayBin) {
gst_app_src_end_of_stream(mSource);
if (mSource)
Expand All @@ -137,6 +162,11 @@ GStreamerReader::~GStreamerReader()
}
}

void GStreamerReader::Suspend()
{
ResetIfCurrentDecoderActive(this);
}

nsresult GStreamerReader::Init(MediaDecoderReader* aCloneDonor)
{
GStreamerFormatHelper::Instance();
Expand All @@ -160,14 +190,16 @@ nsresult GStreamerReader::Init(MediaDecoderReader* aCloneDonor)
g_object_set(mPlayBin, "buffer-size", 0, nullptr);
mBus = gst_pipeline_get_bus(GST_PIPELINE(mPlayBin));

mVideoSink = gst_parse_bin_from_description("capsfilter name=filter ! "
"appsink name=videosink sync=false max-buffers=1 "
nsAutoCString description;
description.AppendPrintf("%s %s %s", useNemoFilter ? nemoFilter : defaultFilter,
"appsink name=videosink sync=false max-buffers=1 ",
#if GST_VERSION_MAJOR >= 1
"caps=video/x-raw,format=I420"
#else
"caps=video/x-raw-yuv,format=(fourcc)I420"
#endif
, TRUE, nullptr);
);
mVideoSink = gst_parse_bin_from_description(description.get(), TRUE, nullptr);
mVideoAppSink = GST_APP_SINK(gst_bin_get_by_name(GST_BIN(mVideoSink),
"videosink"));
mAudioSink = gst_parse_bin_from_description("capsfilter name=filter ! "
Expand Down Expand Up @@ -369,10 +401,12 @@ nsresult GStreamerReader::ReadMetadata(MediaInfo* aInfo,
}

LOG(PR_LOG_DEBUG, "starting metadata pipeline");
if (gst_element_set_state(mPlayBin, GST_STATE_PAUSED) == GST_STATE_CHANGE_FAILURE) {
LOG(PR_LOG_DEBUG, "metadata pipeline state change failed");
ret = NS_ERROR_FAILURE;
continue;
if (UpdateCurrentAsActiveIfNotBusy(this)) {
if (gst_element_set_state(mPlayBin, GST_STATE_PAUSED) == GST_STATE_CHANGE_FAILURE) {
LOG(PR_LOG_DEBUG, "metadata pipeline state change failed");
ret = NS_ERROR_FAILURE;
continue;
}
}

/* Wait for ASYNC_DONE, which is emitted when the pipeline is built,
Expand Down Expand Up @@ -400,6 +434,7 @@ nsresult GStreamerReader::ReadMetadata(MediaInfo* aInfo,
/* Unexpected stream close/EOS or other error. We'll give up if all
* streams are in error/eos. */
gst_element_set_state(mPlayBin, GST_STATE_NULL);
ResetIfCurrentDecoderActive(this);
gst_message_unref(message);
ret = NS_ERROR_FAILURE;
}
Expand Down Expand Up @@ -458,7 +493,9 @@ nsresult GStreamerReader::ReadMetadata(MediaInfo* aInfo,

/* set the pipeline to PLAYING so that it starts decoding and queueing data in
* the appsinks */
gst_element_set_state(mPlayBin, GST_STATE_PLAYING);
if (UpdateCurrentAsActiveIfNotBusy(this)) {
gst_element_set_state(mPlayBin, GST_STATE_PLAYING);
}

return NS_OK;
}
Expand Down
1 change: 1 addition & 0 deletions dom/media/gstreamer/GStreamerReader.h
Expand Up @@ -68,6 +68,7 @@ class GStreamerReader : public MediaDecoderReader

layers::ImageContainer* GetImageContainer() { return mDecoder->GetImageContainer(); }

void Suspend();
virtual bool IsMediaSeekable() MOZ_OVERRIDE;

private:
Expand Down
3 changes: 3 additions & 0 deletions dom/media/moz.build
Expand Up @@ -210,6 +210,9 @@ UNIFIED_SOURCES += [
'WebVTTListener.cpp',
]

SOURCES += [
'NemoResourceHandler.cpp',
]
if CONFIG['OS_TARGET'] == 'WINNT':
SOURCES += [ 'ThreadPoolCOMListener.cpp' ]

Expand Down

0 comments on commit b318b3c

Please sign in to comment.