gecko/content/media/WebVTTListener.cpp
Ryan VanderMeulen f4de297d84 Backed out 6 changesets (bug 939294) for B2G bustage on a CLOSED TREE.
Backed out changeset 8c3aa9973da0 (bug 939294)
Backed out changeset 37098c13e59e (bug 939294)
Backed out changeset 7c9ade6c871c (bug 939294)
Backed out changeset fed59539afc1 (bug 939294)
Backed out changeset 89e9d3fa16fc (bug 939294)
Backed out changeset c97e58ebc5f4 (bug 939294)
2014-01-09 14:17:39 -05:00

193 lines
5.1 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_2(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)
#ifdef PR_LOGGING
PRLogModuleInfo* gTextTrackLog;
# define VTT_LOG(...) PR_LOG(gTextTrackLog, PR_LOG_DEBUG, (__VA_ARGS__))
#else
# define VTT_LOG(msg)
#endif
WebVTTListener::WebVTTListener(HTMLTrackElement* aElement)
: mElement(aElement)
{
MOZ_ASSERT(mElement, "Must pass an element to the callback");
#ifdef PR_LOGGING
if (!gTextTrackLog) {
gTextTrackLog = PR_NewLogModule("TextTrack");
}
#endif
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->mTrack->SetReadyState(HTMLTrackElement::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 (mElement->ReadyState() != HTMLTrackElement::ERROR) {
TextTrack* track = mElement->Track();
track->SetReadyState(HTMLTrackElement::LOADED);
}
// Attempt to parse any final data the parser might still have.
mParserWrapper->Flush();
return NS_OK;
}
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(const 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(const JS::Value &aRegion, JSContext* aCx)
{
if (!aRegion.isObject()) {
return NS_ERROR_FAILURE;
}
TextTrackRegion* region;
nsresult rv = UNWRAP_OBJECT(VTTRegion, &aRegion.toObject(), region);
NS_ENSURE_SUCCESS(rv, rv);
mElement->mTrack->AddRegion(*region);
return NS_OK;
}
} // namespace dom
} // namespace mozilla