Skip to content
This repository has been archived by the owner on Jun 20, 2023. It is now read-only.

Commit

Permalink
Introduce create_media_source_player
Browse files Browse the repository at this point in the history
  • Loading branch information
ferjm committed Dec 28, 2017
1 parent b5d3c91 commit 136ddce
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 20 deletions.
41 changes: 40 additions & 1 deletion gecko-media/gecko/glue/Player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
#include "GeckoMediaDecoder.h"
#include "GeckoMediaDecoderOwner.h"
#include "GeckoMediaMacros.h"
#include "GeckoMediaSource.h"
#include "MediaSource.h"
#include "MediaSourceDecoder.h"
#include "RustMediaResource.h"
#include "UniquePtr.h"
#include "mozilla/RefPtr.h"
Expand Down Expand Up @@ -111,6 +114,42 @@ GeckoMedia_Player_CreateNetworkPlayer(size_t aId,
resource->SetDecoder(reflector->mDecoder);
}

bool
GeckoMedia_Player_CreateMediaSourcePlayer(size_t aId,
size_t aMediaSourceId,
PlayerCallbackObject aCallback,
FrameAllocatorObject aAllocator)
{
Player* reflector =
sReflectors.AppendElement(Player(aId, aCallback, aAllocator));
MOZ_ASSERT(GetReflector(aId) == reflector);

MediaDecoderInit decoderInit(
reflector->mDecoderOwner.get(),
1.0, // volume
true, // mPreservesPitch
1.0, // mPlaybackRate
false, // mMinimizePreroll
false, // mHasSuspendTaint
false, // mLooping
MediaContainerType(MEDIAMIMETYPE("application/x.mediasource")));
RefPtr<MediaSourceDecoder> decoder = new MediaSourceDecoder(decoderInit);
reflector->mDecoder = static_cast<GeckoMediaDecoder*>(decoder);
reflector->mDecoderOwner->SetDecoder(reflector->mDecoder);

RefPtr<mozilla::dom::MediaSource> mediaSource =
GetMediaSource(aMediaSourceId);
if (NS_WARN_IF(!mediaSource || !mediaSource->Attach(decoder))) {
return false;
}

if (NS_WARN_IF(reflector->mDecoder->Load(nullptr) != NS_OK)) {
return false;
}

return true;
}

void
GeckoMedia_Player_Play(size_t aId)
{
Expand Down Expand Up @@ -144,5 +183,5 @@ void
GeckoMedia_Player_SetPlaybackRate(size_t aId, double rate)
{
IMPL_GECKO_MEDIA_REFLECTOR_GET(Player)
reflector->mDecoder->SetPlaybackRate(rate);
reflector->mDecoder->SetPlaybackRate(rate);
}
2 changes: 1 addition & 1 deletion gecko-media/gecko/glue/include/GeckoMediaDecoderOwner.h
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ class GeckoMediaDecoderOwner : public MediaDecoderOwner
void NotifyWaitingForKey() override;

/*
* Methods that are used only in Gecko go here. We provide defaul
* Methods that are used only in Gecko go here. We provide default
* implementations so they can compile in Servo without modification.
*/
// Return an abstract thread on which to run main thread runnables.
Expand Down
6 changes: 6 additions & 0 deletions gecko-media/gecko/glue/include/Player.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,12 @@ GeckoMedia_Player_CreateNetworkPlayer(size_t aId,
PlayerCallbackObject aCallback,
FrameAllocatorObject aAllocator);

bool
GeckoMedia_Player_CreateMediaSourcePlayer(size_t aId,
size_t aMediaSourceId,
PlayerCallbackObject aCallback,
FrameAllocatorObject aAllocator);

void
GeckoMedia_Player_Play(size_t aId);

Expand Down
58 changes: 40 additions & 18 deletions gecko-media/src/player.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// 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/.

use bindings::GeckoMedia_Player_CreateMediaSourcePlayer;
use bindings::NetworkResourceObject;
use bindings::{CachedRangesObserverObject, FrameAllocatorObject, GeckoImagePlane};
use bindings::{GeckoMediaByteRange, GeckoPlanarYCbCrImage, GeckoPlanarYCbCrImageData};
Expand All @@ -16,7 +17,7 @@ use std::mem;
use std::ops::Range;
use std::os::raw::c_char;
use std::slice;
use std::sync::{Arc, Mutex};
use std::sync::{mpsc, Arc, Mutex};
use timestamp::TimeStamp;

/// Holds useful metadata extracted from a media resource during loading.
Expand Down Expand Up @@ -287,10 +288,7 @@ impl Player {
_ => return Err(()),
};
let ffi_frame_allocator = to_ffi_frame_allocator(video_frame_allocator.clone());
let player = Player {
gecko_media,
id,
};
let player = Player { gecko_media, id };
player.gecko_media.queue_task(move || unsafe {
GeckoMedia_Player_CreateBlobPlayer(
id,
Expand Down Expand Up @@ -318,10 +316,7 @@ impl Player {
let callback = to_ffi_callback(sink, video_frame_allocator.clone());
let ffi_frame_allocator = to_ffi_frame_allocator(video_frame_allocator.clone());
let resource = to_ffi_resource(resource);
let player = Player {
gecko_media,
id,
};
let player = Player { gecko_media, id };
player.gecko_media.queue_task(move || unsafe {
GeckoMedia_Player_CreateNetworkPlayer(
id,
Expand All @@ -334,6 +329,34 @@ impl Player {
Ok(player)
}

pub fn from_media_source(
gecko_media: GeckoMedia,
id: usize,
media_source_id: usize,
sink: Box<PlayerEventSink>,
) -> Result<Player, ()> {
let video_frame_allocator = Arc::new(Mutex::new(VideoFrameAllocator::new()));
let callback = to_ffi_callback(sink, video_frame_allocator.clone());
let ffi_frame_allocator = to_ffi_frame_allocator(video_frame_allocator.clone());
let player = Player { gecko_media, id };
let (sender, receiver) = mpsc::channel();
player.gecko_media.queue_task(move || unsafe {
sender
.send(GeckoMedia_Player_CreateMediaSourcePlayer(
id,
media_source_id,
callback,
ffi_frame_allocator,
))
.unwrap();
});
if receiver.recv().unwrap() {
Ok(player)
} else {
Err(())
}
}

/// Starts playback of the media resource. While playing,
/// PlayerEventSink::time_update() will be called once per frame,
/// or every 40 milliseconds if there is no video.
Expand Down Expand Up @@ -405,9 +428,10 @@ impl CachedRangesSink {
});
}
unsafe {
self.observer.mUpdate.as_ref().map(|f| {
f(self.observer.mResourceID, data.as_ptr(), data.len())
});
self.observer
.mUpdate
.as_ref()
.map(|f| f(self.observer.mResourceID, data.as_ptr(), data.len()));
}
}
}
Expand Down Expand Up @@ -546,9 +570,9 @@ fn to_ffi_resource(callbacks: Box<NetworkResource>) -> NetworkResourceObject {

unsafe extern "C" fn set_ranges_observer(ptr: *mut c_void, observer: CachedRangesObserverObject) {
let wrapper = &*(ptr as *mut Wrapper);
wrapper.callbacks.set_cached_ranges_sink(CachedRangesSink {
observer,
})
wrapper
.callbacks
.set_cached_ranges_sink(CachedRangesSink { observer })
}

unsafe extern "C" fn read_at(
Expand Down Expand Up @@ -599,9 +623,7 @@ fn to_ffi_resource(callbacks: Box<NetworkResource>) -> NetworkResourceObject {
mLength: Some(length),
mReadFromCache: Some(read_from_cache),
mFree: Some(free),
mData: Box::into_raw(Box::new(Wrapper {
callbacks,
})) as *mut c_void,
mData: Box::into_raw(Box::new(Wrapper { callbacks })) as *mut c_void,
}
}

Expand Down
7 changes: 7 additions & 0 deletions gecko-media/src/top.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,13 @@ impl GeckoMedia {
Player::from_network_resource(handle, id, resource, mime_type, sink)
}

/// Creates a Player to play from a MediaSource.
pub fn create_media_source_player(media_source_id: usize, sink: Box<PlayerEventSink>) -> Result<Player, ()> {
let handle = GeckoMedia::get()?;
let id = NEXT_PLAYER_ID.fetch_add(1, Ordering::SeqCst);
Player::from_media_source(handle, id, media_source_id, sink)
}

/// Creates a MediaSource instance and its corresponding GeckoMediaSource reflector.
impl_gecko_media_struct_constructor!(
create_media_source,
Expand Down

0 comments on commit 136ddce

Please sign in to comment.