content/media/WebVTTListener.cpp

changeset 0
6474c204b198
equal deleted inserted replaced
-1:000000000000 0:45200d4624f3
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6 #include "WebVTTListener.h"
7 #include "mozilla/dom/TextTrackCue.h"
8 #include "mozilla/dom/TextTrackRegion.h"
9 #include "mozilla/dom/VTTRegionBinding.h"
10 #include "mozilla/dom/HTMLTrackElement.h"
11 #include "nsIInputStream.h"
12 #include "nsIWebVTTParserWrapper.h"
13 #include "nsComponentManagerUtils.h"
14
15 namespace mozilla {
16 namespace dom {
17
18 NS_IMPL_CYCLE_COLLECTION(WebVTTListener, mElement, mParserWrapper)
19
20 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(WebVTTListener)
21 NS_INTERFACE_MAP_ENTRY(nsIWebVTTListener)
22 NS_INTERFACE_MAP_ENTRY(nsIStreamListener)
23 NS_INTERFACE_MAP_ENTRY(nsIChannelEventSink)
24 NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
25 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIWebVTTListener)
26 NS_INTERFACE_MAP_END
27
28 NS_IMPL_CYCLE_COLLECTING_ADDREF(WebVTTListener)
29 NS_IMPL_CYCLE_COLLECTING_RELEASE(WebVTTListener)
30
31 #ifdef PR_LOGGING
32 PRLogModuleInfo* gTextTrackLog;
33 # define VTT_LOG(...) PR_LOG(gTextTrackLog, PR_LOG_DEBUG, (__VA_ARGS__))
34 #else
35 # define VTT_LOG(msg)
36 #endif
37
38 WebVTTListener::WebVTTListener(HTMLTrackElement* aElement)
39 : mElement(aElement)
40 {
41 MOZ_ASSERT(mElement, "Must pass an element to the callback");
42 #ifdef PR_LOGGING
43 if (!gTextTrackLog) {
44 gTextTrackLog = PR_NewLogModule("TextTrack");
45 }
46 #endif
47 VTT_LOG("WebVTTListener created.");
48 }
49
50 WebVTTListener::~WebVTTListener()
51 {
52 VTT_LOG("WebVTTListener destroyed.");
53 }
54
55 NS_IMETHODIMP
56 WebVTTListener::GetInterface(const nsIID &aIID,
57 void** aResult)
58 {
59 return QueryInterface(aIID, aResult);
60 }
61
62 nsresult
63 WebVTTListener::LoadResource()
64 {
65 if (!HTMLTrackElement::IsWebVTTEnabled()) {
66 NS_WARNING("WebVTT support disabled."
67 " See media.webvtt.enabled in about:config. ");
68 return NS_ERROR_FAILURE;
69 }
70 nsresult rv;
71 mParserWrapper = do_CreateInstance(NS_WEBVTTPARSERWRAPPER_CONTRACTID, &rv);
72 NS_ENSURE_SUCCESS(rv, rv);
73
74 nsPIDOMWindow* window = mElement->OwnerDoc()->GetWindow();
75 rv = mParserWrapper->LoadParser(window);
76 NS_ENSURE_SUCCESS(rv, rv);
77
78 rv = mParserWrapper->Watch(this);
79 NS_ENSURE_SUCCESS(rv, rv);
80
81 mElement->SetReadyState(TextTrackReadyState::Loading);
82 return NS_OK;
83 }
84
85 NS_IMETHODIMP
86 WebVTTListener::AsyncOnChannelRedirect(nsIChannel* aOldChannel,
87 nsIChannel* aNewChannel,
88 uint32_t aFlags,
89 nsIAsyncVerifyRedirectCallback* cb)
90 {
91 if (mElement) {
92 mElement->OnChannelRedirect(aOldChannel, aNewChannel, aFlags);
93 }
94 return NS_OK;
95 }
96
97 NS_IMETHODIMP
98 WebVTTListener::OnStartRequest(nsIRequest* aRequest,
99 nsISupports* aContext)
100 {
101 return NS_OK;
102 }
103
104 NS_IMETHODIMP
105 WebVTTListener::OnStopRequest(nsIRequest* aRequest,
106 nsISupports* aContext,
107 nsresult aStatus)
108 {
109 if (NS_FAILED(aStatus)) {
110 mElement->SetReadyState(TextTrackReadyState::FailedToLoad);
111 }
112 // Attempt to parse any final data the parser might still have.
113 mParserWrapper->Flush();
114 if (mElement->ReadyState() != TextTrackReadyState::FailedToLoad) {
115 mElement->SetReadyState(TextTrackReadyState::Loaded);
116 }
117 return aStatus;
118 }
119
120 NS_METHOD
121 WebVTTListener::ParseChunk(nsIInputStream* aInStream, void* aClosure,
122 const char* aFromSegment, uint32_t aToOffset,
123 uint32_t aCount, uint32_t* aWriteCount)
124 {
125 nsCString buffer(aFromSegment, aCount);
126 WebVTTListener* listener = static_cast<WebVTTListener*>(aClosure);
127
128 if (NS_FAILED(listener->mParserWrapper->Parse(buffer))) {
129 VTT_LOG("Unable to parse chunk of WEBVTT text. Aborting.");
130 *aWriteCount = 0;
131 return NS_ERROR_FAILURE;
132 }
133
134 *aWriteCount = aCount;
135 return NS_OK;
136 }
137
138 NS_IMETHODIMP
139 WebVTTListener::OnDataAvailable(nsIRequest* aRequest,
140 nsISupports* aContext,
141 nsIInputStream* aStream,
142 uint64_t aOffset,
143 uint32_t aCount)
144 {
145 uint32_t count = aCount;
146 while (count > 0) {
147 uint32_t read;
148 nsresult rv = aStream->ReadSegments(ParseChunk, this, count, &read);
149 NS_ENSURE_SUCCESS(rv, rv);
150 if (!read) {
151 return NS_ERROR_FAILURE;
152 }
153 count -= read;
154 }
155
156 return NS_OK;
157 }
158
159 NS_IMETHODIMP
160 WebVTTListener::OnCue(JS::Handle<JS::Value> aCue, JSContext* aCx)
161 {
162 if (!aCue.isObject()) {
163 return NS_ERROR_FAILURE;
164 }
165
166 TextTrackCue* cue;
167 nsresult rv = UNWRAP_OBJECT(VTTCue, &aCue.toObject(), cue);
168 NS_ENSURE_SUCCESS(rv, rv);
169
170 cue->SetTrackElement(mElement);
171 mElement->mTrack->AddCue(*cue);
172
173 return NS_OK;
174 }
175
176
177 NS_IMETHODIMP
178 WebVTTListener::OnRegion(JS::Handle<JS::Value> aRegion, JSContext* aCx)
179 {
180 // Nothing for this callback to do.
181 return NS_OK;
182 }
183
184 NS_IMETHODIMP
185 WebVTTListener::OnParsingError(int32_t errorCode, JSContext* cx)
186 {
187 // We only care about files that have a bad WebVTT file signature right now
188 // as that means the file failed to load.
189 if (errorCode == ErrorCodes::BadSignature) {
190 mElement->SetReadyState(TextTrackReadyState::FailedToLoad);
191 }
192 return NS_OK;
193 }
194
195 } // namespace dom
196 } // namespace mozilla

mercurial