@@ -17,13 +17,15 @@ use crate::dom::bindings::codegen::Bindings::MediaErrorBinding::MediaErrorMethod
1717use crate :: dom:: bindings:: codegen:: Bindings :: TextTrackBinding :: { TextTrackKind , TextTrackMode } ;
1818use crate :: dom:: bindings:: codegen:: InheritTypes :: { ElementTypeId , HTMLElementTypeId } ;
1919use crate :: dom:: bindings:: codegen:: InheritTypes :: { HTMLMediaElementTypeId , NodeTypeId } ;
20- use crate :: dom:: bindings:: codegen:: UnionTypes :: VideoTrackOrAudioTrackOrTextTrack ;
20+ use crate :: dom:: bindings:: codegen:: UnionTypes :: {
21+ MediaStreamOrBlob , VideoTrackOrAudioTrackOrTextTrack ,
22+ } ;
2123use crate :: dom:: bindings:: error:: { Error , ErrorResult , Fallible } ;
2224use crate :: dom:: bindings:: inheritance:: Castable ;
2325use crate :: dom:: bindings:: num:: Finite ;
2426use crate :: dom:: bindings:: refcounted:: Trusted ;
2527use crate :: dom:: bindings:: reflector:: DomObject ;
26- use crate :: dom:: bindings:: root:: { DomRoot , LayoutDom , MutNullableDom } ;
28+ use crate :: dom:: bindings:: root:: { Dom , DomRoot , LayoutDom , MutNullableDom } ;
2729use crate :: dom:: bindings:: str:: { DOMString , USVString } ;
2830use crate :: dom:: blob:: Blob ;
2931use crate :: dom:: document:: Document ;
@@ -35,13 +37,15 @@ use crate::dom::htmlelement::HTMLElement;
3537use crate :: dom:: htmlsourceelement:: HTMLSourceElement ;
3638use crate :: dom:: htmlvideoelement:: HTMLVideoElement ;
3739use crate :: dom:: mediaerror:: MediaError ;
40+ use crate :: dom:: mediastream:: MediaStream ;
3841use crate :: dom:: node:: { document_from_node, window_from_node, Node , NodeDamage , UnbindContext } ;
3942use crate :: dom:: performanceresourcetiming:: InitiatorType ;
4043use crate :: dom:: promise:: Promise ;
4144use crate :: dom:: texttrack:: TextTrack ;
4245use crate :: dom:: texttracklist:: TextTrackList ;
4346use crate :: dom:: timeranges:: { TimeRanges , TimeRangesContainer } ;
4447use crate :: dom:: trackevent:: TrackEvent ;
48+ use crate :: dom:: url:: URL ;
4549use crate :: dom:: videotrack:: VideoTrack ;
4650use crate :: dom:: videotracklist:: VideoTrackList ;
4751use crate :: dom:: virtualmethods:: VirtualMethods ;
@@ -156,6 +160,25 @@ impl FrameRenderer for MediaFrameRenderer {
156160 }
157161}
158162
163+ #[ must_root]
164+ #[ derive( JSTraceable , MallocSizeOf ) ]
165+ enum SrcObject {
166+ MediaStream ( Dom < MediaStream > ) ,
167+ Blob ( Dom < Blob > ) ,
168+ }
169+
170+ impl From < MediaStreamOrBlob > for SrcObject {
171+ #[ allow( unrooted_must_root) ]
172+ fn from ( src_object : MediaStreamOrBlob ) -> SrcObject {
173+ match src_object {
174+ MediaStreamOrBlob :: Blob ( blob) => SrcObject :: Blob ( Dom :: from_ref ( & * blob) ) ,
175+ MediaStreamOrBlob :: MediaStream ( stream) => {
176+ SrcObject :: MediaStream ( Dom :: from_ref ( & * stream) )
177+ } ,
178+ }
179+ }
180+ }
181+
159182#[ dom_struct]
160183pub struct HTMLMediaElement {
161184 htmlelement : HTMLElement ,
@@ -164,7 +187,7 @@ pub struct HTMLMediaElement {
164187 /// <https://html.spec.whatwg.org/multipage/#dom-media-readystate>
165188 ready_state : Cell < ReadyState > ,
166189 /// <https://html.spec.whatwg.org/multipage/#dom-media-srcobject>
167- src_object : MutNullableDom < Blob > ,
190+ src_object : DomRefCell < Option < SrcObject > > ,
168191 /// <https://html.spec.whatwg.org/multipage/#dom-media-currentsrc>
169192 current_src : DomRefCell < String > ,
170193 /// Incremented whenever tasks associated with this element are cancelled.
@@ -211,6 +234,9 @@ pub struct HTMLMediaElement {
211234 muted : Cell < bool > ,
212235 /// URL of the media resource, if any.
213236 resource_url : DomRefCell < Option < ServoUrl > > ,
237+ /// URL of the media resource, if the resource is set through the src_object attribute and it
238+ /// is a blob.
239+ blob_url : DomRefCell < Option < ServoUrl > > ,
214240 /// https://html.spec.whatwg.org/multipage/#dom-media-played
215241 #[ ignore_malloc_size_of = "Rc" ]
216242 played : DomRefCell < TimeRangesContainer > ,
@@ -280,6 +306,7 @@ impl HTMLMediaElement {
280306 volume : Cell :: new ( 1.0 ) ,
281307 seeking : Cell :: new ( false ) ,
282308 resource_url : DomRefCell :: new ( None ) ,
309+ blob_url : DomRefCell :: new ( None ) ,
283310 played : DomRefCell :: new ( TimeRangesContainer :: new ( ) ) ,
284311 audio_tracks_list : Default :: default ( ) ,
285312 video_tracks_list : Default :: default ( ) ,
@@ -557,7 +584,7 @@ impl HTMLMediaElement {
557584 Children ( DomRoot < HTMLSourceElement > ) ,
558585 }
559586 fn mode ( media : & HTMLMediaElement ) -> Option < Mode > {
560- if media. src_object . get ( ) . is_some ( ) {
587+ if media. src_object . borrow ( ) . is_some ( ) {
561588 return Some ( Mode :: Object ) ;
562589 }
563590 if let Some ( attr) = media
@@ -661,7 +688,7 @@ impl HTMLMediaElement {
661688 }
662689
663690 fn fetch_request ( & self , offset : Option < u64 > ) {
664- if self . resource_url . borrow ( ) . is_none ( ) {
691+ if self . resource_url . borrow ( ) . is_none ( ) && self . blob_url . borrow ( ) . is_none ( ) {
665692 eprintln ! ( "Missing request url" ) ;
666693 self . queue_dedicated_media_source_failure_steps ( ) ;
667694 return ;
@@ -679,8 +706,12 @@ impl HTMLMediaElement {
679706 header:: RANGE ,
680707 HeaderValue :: from_str ( & format ! ( "bytes={}-" , offset. unwrap_or( 0 ) ) ) . unwrap ( ) ,
681708 ) ;
709+ let url = match self . resource_url . borrow ( ) . as_ref ( ) {
710+ Some ( url) => url. clone ( ) ,
711+ None => self . blob_url . borrow ( ) . as_ref ( ) . unwrap ( ) . clone ( ) ,
712+ } ;
682713 let request = RequestInit {
683- url : self . resource_url . borrow ( ) . as_ref ( ) . unwrap ( ) . clone ( ) ,
714+ url : url . clone ( ) ,
684715 headers,
685716 destination,
686717 credentials_mode : CredentialsMode :: Include ,
@@ -700,7 +731,7 @@ impl HTMLMediaElement {
700731 * current_fetch_context = Some ( fetch_context) ;
701732 let fetch_listener = Arc :: new ( Mutex :: new ( HTMLMediaElementFetchListener :: new (
702733 self ,
703- self . resource_url . borrow ( ) . as_ref ( ) . unwrap ( ) . clone ( ) ,
734+ url . clone ( ) ,
704735 offset. unwrap_or ( 0 ) ,
705736 ) ) ) ;
706737 let ( action_sender, action_receiver) = ipc:: channel ( ) . unwrap ( ) ;
@@ -788,8 +819,19 @@ impl HTMLMediaElement {
788819 self . fetch_request ( None ) ;
789820 } ,
790821 Resource :: Object => {
791- // FIXME(nox): Actually do something with the object.
792- self . queue_dedicated_media_source_failure_steps ( ) ;
822+ if let Some ( ref src_object) = * self . src_object . borrow ( ) {
823+ match src_object {
824+ SrcObject :: Blob ( blob) => {
825+ let blob_url = URL :: CreateObjectURL ( & self . global ( ) , & * blob) ;
826+ * self . blob_url . borrow_mut ( ) =
827+ Some ( ServoUrl :: parse ( & blob_url) . expect ( "infallible" ) ) ;
828+ self . fetch_request ( None ) ;
829+ } ,
830+ SrcObject :: MediaStream ( _) => {
831+ self . queue_dedicated_media_source_failure_steps ( ) ;
832+ } ,
833+ }
834+ }
793835 } ,
794836 }
795837 }
@@ -1550,13 +1592,21 @@ impl HTMLMediaElementMethods for HTMLMediaElement {
15501592 }
15511593
15521594 // https://html.spec.whatwg.org/multipage/#dom-media-srcobject
1553- fn GetSrcObject ( & self ) -> Option < DomRoot < Blob > > {
1554- self . src_object . get ( )
1595+ fn GetSrcObject ( & self ) -> Option < MediaStreamOrBlob > {
1596+ match * self . src_object . borrow ( ) {
1597+ Some ( ref src_object) => Some ( match src_object {
1598+ SrcObject :: Blob ( blob) => MediaStreamOrBlob :: Blob ( DomRoot :: from_ref ( & * blob) ) ,
1599+ SrcObject :: MediaStream ( stream) => {
1600+ MediaStreamOrBlob :: MediaStream ( DomRoot :: from_ref ( & * stream) )
1601+ } ,
1602+ } ) ,
1603+ None => None ,
1604+ }
15551605 }
15561606
15571607 // https://html.spec.whatwg.org/multipage/#dom-media-srcobject
1558- fn SetSrcObject ( & self , value : Option < & Blob > ) {
1559- self . src_object . set ( value) ;
1608+ fn SetSrcObject ( & self , value : Option < MediaStreamOrBlob > ) {
1609+ * self . src_object . borrow_mut ( ) = value. map ( |value| value . into ( ) ) ;
15601610 self . media_element_load_algorithm ( ) ;
15611611 }
15621612
0 commit comments