Bug 455500 - Enormous memory usage with fieldset, legend, audio and DOMAttrModified event listener - s+sr=roc
authorChris Double <chris.double@double.co.nz>
Tue, 30 Sep 2008 12:05:06 +1300
changeset 19889 20af22e0eb6ad2bc003c60c999a2fbe853177d0d
parent 19888 8f53fcb8bde55931bb7a60835f858db3af67bc6a
child 19890 74aad43f37a5370a6e19893ccb631af1c54853b5
push idunknown
push userunknown
push dateunknown
bugs455500
milestone1.9.1b1pre
Bug 455500 - Enormous memory usage with fieldset, legend, audio and DOMAttrModified event listener - s+sr=roc
content/html/content/public/nsHTMLMediaElement.h
content/html/content/src/nsHTMLMediaElement.cpp
content/media/video/test/test_defaultPlaybackRate.html
content/media/video/test/test_playbackRate.html
--- a/content/html/content/public/nsHTMLMediaElement.h
+++ b/content/html/content/public/nsHTMLMediaElement.h
@@ -131,16 +131,31 @@ protected:
   // Error attribute
   nsCOMPtr<nsIDOMHTMLMediaError> mError;
 
   // Media loading flags. See: 
   //   http://www.whatwg.org/specs/web-apps/current-work/#video)
   nsMediaNetworkState mNetworkState;
   nsMediaReadyState mReadyState;
 
+  // Value of the volume before it was muted
+  float mMutedVolume;
+
+  // The defaultPlaybackRate attribute gives the desired speed at
+  // which the media resource is to play, as a multiple of its
+  // intrinsic speed.
+  float mDefaultPlaybackRate;
+
+  // The playbackRate attribute gives the speed at which the media
+  // resource plays, as a multiple of its intrinsic speed. If it is
+  // not equal to the defaultPlaybackRate, then the implication is
+  // that the user is using a feature such as fast forward or slow
+  // motion playback.
+  float mPlaybackRate;
+
   // If true then we have begun downloading the media content.
   // Set to false when completed, or not yet started.
   PRPackedBool mBegun;
 
   // If truen then the video playback has completed.
   PRPackedBool mEnded;
 
   // True when the decoder has loaded enough data to display the
@@ -163,15 +178,12 @@ protected:
   PRPackedBool mPaused;
 
   // True if we are currently seeking through the media file.
   PRPackedBool mSeeking;
 
   // True if the sound is muted
   PRPackedBool mMuted;
 
-  // Value of the volume before it was muted
-  float mMutedVolume; 
-
   // Flag to indicate if the child elements (eg. <source/>) have been
   // parsed.
   PRPackedBool mIsDoneAddingChildren;
 };
--- a/content/html/content/src/nsHTMLMediaElement.cpp
+++ b/content/html/content/src/nsHTMLMediaElement.cpp
@@ -91,18 +91,16 @@ public:
       mElement->DispatchSimpleEvent(mName);
   }
 };
 
 // nsIDOMHTMLMediaElement
 NS_IMPL_URI_ATTR(nsHTMLMediaElement, Src, src)
 NS_IMPL_BOOL_ATTR(nsHTMLMediaElement, Controls, controls)
 NS_IMPL_BOOL_ATTR(nsHTMLMediaElement, Autoplay, autoplay)
-NS_IMPL_FLOAT_ATTR_DEFAULT_VALUE(nsHTMLMediaElement, PlaybackRate, playbackrate, 1.0)
-NS_IMPL_FLOAT_ATTR_DEFAULT_VALUE(nsHTMLMediaElement, DefaultPlaybackRate, defaultplaybackrate, 1.0)
 NS_IMPL_FLOAT_ATTR(nsHTMLMediaElement, Start, start)
 NS_IMPL_FLOAT_ATTR(nsHTMLMediaElement, End, end)
 NS_IMPL_FLOAT_ATTR(nsHTMLMediaElement, LoopStart, loopstart)
 NS_IMPL_FLOAT_ATTR(nsHTMLMediaElement, LoopEnd, loopend)
 
 /* readonly attribute nsIDOMHTMLMediaError error; */
 NS_IMETHODIMP nsHTMLMediaElement::GetError(nsIDOMHTMLMediaError * *aError)
 {
@@ -133,16 +131,58 @@ NS_IMETHODIMP nsHTMLMediaElement::GetCur
     }
   }
 
   aCurrentSrc = NS_ConvertUTF8toUTF16(src);
 
   return NS_OK;
 }
 
+/* attribute float defaultPlaybackRate; */
+NS_IMETHODIMP nsHTMLMediaElement::GetDefaultPlaybackRate(float *aDefaultPlaybackRate)
+{
+  *aDefaultPlaybackRate = mDefaultPlaybackRate;
+  return NS_OK;
+}
+
+NS_IMETHODIMP nsHTMLMediaElement::SetDefaultPlaybackRate(float aDefaultPlaybackRate)
+{
+  if (aDefaultPlaybackRate == 0.0) {
+    return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
+  }
+
+  mDefaultPlaybackRate = aDefaultPlaybackRate;
+  DispatchAsyncSimpleEvent(NS_LITERAL_STRING("ratechange"));
+
+  return NS_OK;
+}
+
+/* attribute float playbackRate; */
+NS_IMETHODIMP nsHTMLMediaElement::GetPlaybackRate(float *aPlaybackRate)
+{
+  *aPlaybackRate = mPlaybackRate;
+  return NS_OK;
+}
+
+NS_IMETHODIMP nsHTMLMediaElement::SetPlaybackRate(float aPlaybackRate)
+{
+  if (aPlaybackRate == 0.0) {
+    return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
+  }
+
+  mPlaybackRate = aPlaybackRate;
+
+  if (mDecoder) {
+    mDecoder->PlaybackRateChanged();
+  }
+
+  DispatchAsyncSimpleEvent(NS_LITERAL_STRING("ratechange"));
+  return NS_OK;
+}
+
 /* readonly attribute unsigned short networkState; */
 NS_IMETHODIMP nsHTMLMediaElement::GetNetworkState(PRUint16 *aNetworkState)
 {
   *aNetworkState = mNetworkState;
 
   return NS_OK;
 }
 
@@ -389,24 +429,26 @@ NS_IMETHODIMP nsHTMLMediaElement::SetMut
     DispatchSimpleEvent(NS_LITERAL_STRING("volumechange"));
   return NS_OK;
 }
 
 nsHTMLMediaElement::nsHTMLMediaElement(nsINodeInfo *aNodeInfo, PRBool aFromParser)
   : nsGenericHTMLElement(aNodeInfo),
     mNetworkState(nsIDOMHTMLMediaElement::EMPTY),
     mReadyState(nsIDOMHTMLMediaElement::DATA_UNAVAILABLE),
+    mMutedVolume(0.0),
+    mDefaultPlaybackRate(1.0),
+    mPlaybackRate(1.0),
     mBegun(PR_FALSE),
     mEnded(PR_FALSE),
     mLoadedFirstFrame(PR_FALSE),
     mAutoplaying(PR_TRUE),
     mPaused(PR_TRUE),
     mSeeking(PR_FALSE),
     mMuted(PR_FALSE),
-    mMutedVolume(0.0),
     mIsDoneAddingChildren(!aFromParser)
 {
 }
 
 nsHTMLMediaElement::~nsHTMLMediaElement()
 {
   if (mDecoder) 
     mDecoder->Stop();
@@ -451,19 +493,17 @@ nsHTMLMediaElement::ParseAttribute(PRInt
                                    nsAttrValue& aResult)
 {
   if (aNamespaceID == kNameSpaceID_None) {
     if (aAttribute == nsGkAtoms::src) {
       static const char* kWhitespace = " \n\r\t\b";
       aResult.SetTo(nsContentUtils::TrimCharsInSet(kWhitespace, aValue));
       return PR_TRUE;
     }
-    else if (aAttribute == nsGkAtoms::playbackrate
-            || aAttribute == nsGkAtoms::defaultplaybackrate
-            || aAttribute == nsGkAtoms::loopstart
+    else if (aAttribute == nsGkAtoms::loopstart
             || aAttribute == nsGkAtoms::loopend
             || aAttribute == nsGkAtoms::start
             || aAttribute == nsGkAtoms::end) {
       return aResult.ParseFloatValue(aValue);
     }
     else if (ParseImageAttribute(aAttribute, aValue, aResult)) {
       return PR_TRUE;
     }
@@ -480,21 +520,16 @@ nsHTMLMediaElement::SetAttr(PRInt32 aNam
 {
   nsresult rv = 
     nsGenericHTMLElement::SetAttr(aNameSpaceID, aName, aPrefix, aValue,
                                     aNotify);
   if (aNotify && aNameSpaceID == kNameSpaceID_None) {
     if (aName == nsGkAtoms::src) {
       Load();
     }
-    else if (aName == nsGkAtoms::playbackrate || aName == nsGkAtoms::defaultplaybackrate) {
-      if (mDecoder) 
-        mDecoder->PlaybackRateChanged();
-      DispatchAsyncSimpleEvent(NS_LITERAL_STRING("ratechange"));
-    }
   }
 
   return rv;
 }
 
 nsresult nsHTMLMediaElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
                                         nsIContent* aBindingParent,
                                         PRBool aCompileEventHandlers)
--- a/content/media/video/test/test_defaultPlaybackRate.html
+++ b/content/media/video/test/test_defaultPlaybackRate.html
@@ -22,14 +22,14 @@ a1.defaultPlaybackRate = 2.5;
 is(v1.defaultPlaybackRate, 2.5);
 is(a1.defaultPlaybackRate, 2.5);
 
 try {
   v1.defaultPlaybackRate = 0
   a1.defaultPlaybackRate = 0
   passed = false;
 } catch(e) { }
-todo(passed, "Should not be able to set defaultPlaybackRate to 0");
+ok(passed, "Should not be able to set defaultPlaybackRate to 0");
 
 </script>
 </pre>
 </body>
 </html>
--- a/content/media/video/test/test_playbackRate.html
+++ b/content/media/video/test/test_playbackRate.html
@@ -22,14 +22,14 @@ a1.playbackRate = 2.5;
 is(v1.playbackRate, 2.5);
 is(a1.playbackRate, 2.5);
 
 try {
   v1.playbackRate = 0
   a1.playbackRate = 0
   passed = false;
 } catch(e) { }
-todo(passed, "Should not be able to set playbackRate to 0");
+ok(passed, "Should not be able to set playbackRate to 0");
 
 </script>
 </pre>
 </body>
 </html>