gecko/dom/media/WebVTTListener.cpp
Wes Kocher bd796581dc Backed out 14 changesets (bug 1165515) for b2g mochitest-6 permafail CLOSED TREE
Backed out changeset 9b97e2aa2ed9 (bug 1165515)
Backed out changeset 150606c022a2 (bug 1165515)
Backed out changeset 4e875a488349 (bug 1165515)
Backed out changeset 467e7feeb546 (bug 1165515)
Backed out changeset d6b6cc373197 (bug 1165515)
Backed out changeset 0615265b593c (bug 1165515)
Backed out changeset fafd1dce9f08 (bug 1165515)
Backed out changeset d1df869245f9 (bug 1165515)
Backed out changeset 6876a7c63611 (bug 1165515)
Backed out changeset b7841c94a9a3 (bug 1165515)
Backed out changeset e5e3617f7c73 (bug 1165515)
Backed out changeset 39be3db95978 (bug 1165515)
Backed out changeset 0ec74176f8de (bug 1165515)
Backed out changeset 5b928dd10d71 (bug 1165515)
2015-06-01 17:57:58 -07:00

194 lines
5.3 KiB
C++

/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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 "WebVTTListener.h"
#include "mozilla/dom/TextTrackCue.h"
#include "mozilla/dom/TextTrackRegion.h"
#include "mozilla/dom/VTTRegionBinding.h"
#include "mozilla/dom/HTMLTrackElement.h"
#include "nsIInputStream.h"
#include "nsIWebVTTParserWrapper.h"
#include "nsComponentManagerUtils.h"
namespace mozilla {
namespace dom {
NS_IMPL_CYCLE_COLLECTION(WebVTTListener, mElement, mParserWrapper)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(WebVTTListener)
NS_INTERFACE_MAP_ENTRY(nsIWebVTTListener)
NS_INTERFACE_MAP_ENTRY(nsIStreamListener)
NS_INTERFACE_MAP_ENTRY(nsIChannelEventSink)
NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIWebVTTListener)
NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTING_ADDREF(WebVTTListener)
NS_IMPL_CYCLE_COLLECTING_RELEASE(WebVTTListener)
PRLogModuleInfo* gTextTrackLog;
# define VTT_LOG(...) MOZ_LOG(gTextTrackLog, PR_LOG_DEBUG, (__VA_ARGS__))
WebVTTListener::WebVTTListener(HTMLTrackElement* aElement)
: mElement(aElement)
{
MOZ_ASSERT(mElement, "Must pass an element to the callback");
if (!gTextTrackLog) {
gTextTrackLog = PR_NewLogModule("TextTrack");
}
VTT_LOG("WebVTTListener created.");
}
WebVTTListener::~WebVTTListener()
{
VTT_LOG("WebVTTListener destroyed.");
}
NS_IMETHODIMP
WebVTTListener::GetInterface(const nsIID &aIID,
void** aResult)
{
return QueryInterface(aIID, aResult);
}
nsresult
WebVTTListener::LoadResource()
{
if (!HTMLTrackElement::IsWebVTTEnabled()) {
NS_WARNING("WebVTT support disabled."
" See media.webvtt.enabled in about:config. ");
return NS_ERROR_FAILURE;
}
nsresult rv;
mParserWrapper = do_CreateInstance(NS_WEBVTTPARSERWRAPPER_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsPIDOMWindow* window = mElement->OwnerDoc()->GetWindow();
rv = mParserWrapper->LoadParser(window);
NS_ENSURE_SUCCESS(rv, rv);
rv = mParserWrapper->Watch(this);
NS_ENSURE_SUCCESS(rv, rv);
mElement->SetReadyState(TextTrackReadyState::Loading);
return NS_OK;
}
NS_IMETHODIMP
WebVTTListener::AsyncOnChannelRedirect(nsIChannel* aOldChannel,
nsIChannel* aNewChannel,
uint32_t aFlags,
nsIAsyncVerifyRedirectCallback* cb)
{
if (mElement) {
mElement->OnChannelRedirect(aOldChannel, aNewChannel, aFlags);
}
return NS_OK;
}
NS_IMETHODIMP
WebVTTListener::OnStartRequest(nsIRequest* aRequest,
nsISupports* aContext)
{
return NS_OK;
}
NS_IMETHODIMP
WebVTTListener::OnStopRequest(nsIRequest* aRequest,
nsISupports* aContext,
nsresult aStatus)
{
if (NS_FAILED(aStatus)) {
mElement->SetReadyState(TextTrackReadyState::FailedToLoad);
}
// Attempt to parse any final data the parser might still have.
mParserWrapper->Flush();
if (mElement->ReadyState() != TextTrackReadyState::FailedToLoad) {
mElement->SetReadyState(TextTrackReadyState::Loaded);
}
mElement->DropChannel();
return aStatus;
}
NS_METHOD
WebVTTListener::ParseChunk(nsIInputStream* aInStream, void* aClosure,
const char* aFromSegment, uint32_t aToOffset,
uint32_t aCount, uint32_t* aWriteCount)
{
nsCString buffer(aFromSegment, aCount);
WebVTTListener* listener = static_cast<WebVTTListener*>(aClosure);
if (NS_FAILED(listener->mParserWrapper->Parse(buffer))) {
VTT_LOG("Unable to parse chunk of WEBVTT text. Aborting.");
*aWriteCount = 0;
return NS_ERROR_FAILURE;
}
*aWriteCount = aCount;
return NS_OK;
}
NS_IMETHODIMP
WebVTTListener::OnDataAvailable(nsIRequest* aRequest,
nsISupports* aContext,
nsIInputStream* aStream,
uint64_t aOffset,
uint32_t aCount)
{
uint32_t count = aCount;
while (count > 0) {
uint32_t read;
nsresult rv = aStream->ReadSegments(ParseChunk, this, count, &read);
NS_ENSURE_SUCCESS(rv, rv);
if (!read) {
return NS_ERROR_FAILURE;
}
count -= read;
}
return NS_OK;
}
NS_IMETHODIMP
WebVTTListener::OnCue(JS::Handle<JS::Value> aCue, JSContext* aCx)
{
if (!aCue.isObject()) {
return NS_ERROR_FAILURE;
}
TextTrackCue* cue;
nsresult rv = UNWRAP_OBJECT(VTTCue, &aCue.toObject(), cue);
NS_ENSURE_SUCCESS(rv, rv);
cue->SetTrackElement(mElement);
mElement->mTrack->AddCue(*cue);
return NS_OK;
}
NS_IMETHODIMP
WebVTTListener::OnRegion(JS::Handle<JS::Value> aRegion, JSContext* aCx)
{
// Nothing for this callback to do.
return NS_OK;
}
NS_IMETHODIMP
WebVTTListener::OnParsingError(int32_t errorCode, JSContext* cx)
{
// We only care about files that have a bad WebVTT file signature right now
// as that means the file failed to load.
if (errorCode == ErrorCodes::BadSignature) {
mElement->SetReadyState(TextTrackReadyState::FailedToLoad);
}
return NS_OK;
}
} // namespace dom
} // namespace mozilla