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

Commit

Permalink
Use struct callbacks instead of closures for AppendData and RangeRemoval
Browse files Browse the repository at this point in the history
  • Loading branch information
ferjm committed Dec 22, 2017
1 parent 3cf1b22 commit 79949bd
Show file tree
Hide file tree
Showing 7 changed files with 82 additions and 142 deletions.
15 changes: 4 additions & 11 deletions gecko-media/gecko/glue/GeckoMediaSourceBuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,16 +57,11 @@ GeckoMedia_SourceBuffer_EvictData(size_t aId, size_t aLength, bool* aBufferFull)
void
GeckoMedia_SourceBuffer_AppendData(size_t aId,
const uint8_t* aData,
size_t aLength,
success_callback_t aSuccessCb,
void* aSuccessCbContext,
error_callback_t aErrorCb,
void* aErrorCbContext)
size_t aLength)
{
IMPL_GECKO_MEDIA_REFLECTOR_GET(GeckoMediaSourceBuffer)

reflector->mSourceBuffer->AppendData(
aData, aLength, aSuccessCb, aSuccessCbContext, aErrorCb, aErrorCbContext);
reflector->mSourceBuffer->AppendData(aData, aLength);
}

void
Expand All @@ -88,13 +83,11 @@ GeckoMedia_SourceBuffer_ResetParserState(size_t aId)
void
GeckoMedia_SourceBuffer_RangeRemoval(size_t aId,
double aStart,
double aEnd,
success_callback_t aSuccessCb,
void* aSuccessCbContext)
double aEnd)
{
IMPL_GECKO_MEDIA_REFLECTOR_GET(GeckoMediaSourceBuffer)

reflector->mSourceBuffer->RangeRemoval(aStart, aEnd, aSuccessCb, aSuccessCbContext);
reflector->mSourceBuffer->RangeRemoval(aStart, aEnd);
}

SourceBuffer*
Expand Down
55 changes: 18 additions & 37 deletions gecko-media/gecko/glue/SourceBuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,45 +73,33 @@ SourceBuffer::EvictData(size_t aLength, bool* aBufferFull)
}

void
SourceBuffer::AppendData(const uint8_t* aData,
size_t aLength,
success_callback_t aSuccessCb,
void* aSuccessCbContext,
error_callback_t aErrorCb,
void* aErrorCbContext)
SourceBuffer::AppendData(const uint8_t* aData, size_t aLength)
{
MSE_DEBUG("AppendData(aLength=%zu)", aLength);

RefPtr<MediaByteBuffer> data = new MediaByteBuffer();
if (NS_WARN_IF(!data->AppendElements(aData, aLength, fallible))) {
return (*aErrorCb)(aErrorCbContext,
uint32_t(NS_ERROR_DOM_QUOTA_EXCEEDED_ERR));
return mCurrentAttributes.OnDataAppended(
uint32_t(NS_ERROR_DOM_QUOTA_EXCEEDED_ERR));
}

if (NS_WARN_IF(!mTrackBuffersManager)) {
return (*aErrorCb)(aErrorCbContext, uint32_t(NS_ERROR_NOT_INITIALIZED));
return mCurrentAttributes.OnDataAppended(
uint32_t(NS_ERROR_NOT_INITIALIZED));
}

RefPtr<SourceBuffer> self = this;
mTrackBuffersManager->AppendData(data.forget(), mCurrentAttributes)
->Then(AbstractThread::MainThread(),
__func__,
[self, this, aSuccessCb, aSuccessCbContext](
const SourceBufferTask::AppendBufferResult& aResult) {
AppendDataCompletedWithSuccess(
aResult, aSuccessCb, aSuccessCbContext);
},
[self, this, aErrorCb, aErrorCbContext](const MediaResult& aError) {
AppendDataErrored(aError, aErrorCb, aErrorCbContext);
})
this,
&SourceBuffer::AppendDataCompletedWithSuccess,
&SourceBuffer::AppendDataErrored)
->Track(mPendingAppend);
}

void
SourceBuffer::AppendDataCompletedWithSuccess(
const SourceBufferTask::AppendBufferResult& aResult,
success_callback_t aSuccessCb,
void* aSuccessCbContext)
const SourceBufferTask::AppendBufferResult& aResult)
{
MOZ_ASSERT(mCurrentAttributes.GetUpdating());
mPendingAppend.Complete();
Expand All @@ -120,14 +108,13 @@ SourceBuffer::AppendDataCompletedWithSuccess(
if (!mCurrentAttributes.GetActive()) {
mCurrentAttributes.SetActive(true);
MSE_DEBUG("Init segment received");
RefPtr<SourceBuffer> self = this;
mMediaSource->SourceBufferIsActive(this)
->Then(AbstractThread::MainThread(),
__func__,
[self, this, aSuccessCb, aSuccessCbContext]() {
[this]() {
MSE_DEBUG("Complete AppendBuffer operation");
mCompletionPromise.Complete();
(*aSuccessCb)(aSuccessCbContext);
mCurrentAttributes.OnDataAppended(0 /* success */);
})
->Track(mCompletionPromise);
}
Expand All @@ -143,14 +130,12 @@ SourceBuffer::AppendDataCompletedWithSuccess(
CheckEndTime();

if (!mCompletionPromise.Exists()) {
(*aSuccessCb)(aSuccessCbContext);
mCurrentAttributes.OnDataAppended(0 /* success */);
}
}

void
SourceBuffer::AppendDataErrored(const MediaResult& aError,
error_callback_t aErrorCb,
void* aErrorCbContext)
SourceBuffer::AppendDataErrored(const MediaResult& aError)
{
MOZ_ASSERT(mCurrentAttributes.GetUpdating());
mPendingAppend.Complete();
Expand All @@ -162,7 +147,7 @@ SourceBuffer::AppendDataErrored(const MediaResult& aError,
break;
default:
ResetParserState();
(*aErrorCb)(aErrorCbContext, uint32_t(NS_ERROR_DOM_MEDIA_CANCELED));
mCurrentAttributes.OnDataAppended(uint32_t(NS_ERROR_DOM_MEDIA_CANCELED));
break;
}
}
Expand Down Expand Up @@ -202,21 +187,17 @@ SourceBuffer::ResetParserState()
}

void
SourceBuffer::RangeRemoval(double aStart,
double aEnd,
success_callback_t aSuccessCb,
void* aSuccessCbContext)
SourceBuffer::RangeRemoval(double aStart, double aEnd)
{
MOZ_ASSERT(NS_IsMainThread());

RefPtr<SourceBuffer> self = this;
mTrackBuffersManager
->RangeRemoval(TimeUnit::FromSeconds(aStart), TimeUnit::FromSeconds(aEnd))
->Then(AbstractThread::MainThread(),
__func__,
[self, aSuccessCb, aSuccessCbContext](bool) {
self->mPendingRemoval.Complete();
(*aSuccessCb)(aSuccessCbContext);
[this](bool) {
mPendingRemoval.Complete();
mCurrentAttributes.OnRangeRemoved();
},
[]() { MOZ_ASSERT(false); })
->Track(mPendingRemoval);
Expand Down
15 changes: 4 additions & 11 deletions gecko-media/gecko/glue/include/GeckoMediaSourceBuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,14 +64,13 @@ struct GeckoMediaSourceBufferImpl
void (*mSetUpdating)(void*, bool);
bool (*mGetActive)(void*);
void (*mSetActive)(void*, bool);
void (*mOnDataAppended)(void*, uint32_t);
void (*mOnRangeRemoved)(void*);
};

SourceBuffer*
GetSourceBuffer(const size_t aId);

typedef void (*success_callback_t)(void*);
typedef void (*error_callback_t)(void*, uint32_t);

extern "C" {
// TODO error handling (i.e. aId or aParentId may not be valid)
void
Expand All @@ -92,11 +91,7 @@ GeckoMedia_SourceBuffer_EvictData(size_t aId,
void
GeckoMedia_SourceBuffer_AppendData(size_t aId,
const uint8_t* aData,
size_t aLength,
success_callback_t aSuccessCb,
void* aSuccessCbContext,
error_callback_t aErrorCb,
void* aErrorCbContext);
size_t aLength);

void
GeckoMedia_SourceBuffer_AbortBufferAppend(size_t aId);
Expand All @@ -107,9 +102,7 @@ GeckoMedia_SourceBuffer_ResetParserState(size_t aId);
void
GeckoMedia_SourceBuffer_RangeRemoval(size_t aId,
double aStart,
double aEnd,
success_callback_t aSuccessCb,
void* aSuccessCbContext);
double aEnd);
}

#endif // GeckoMediaSourceBuffer_h_
23 changes: 6 additions & 17 deletions gecko-media/gecko/glue/include/SourceBuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,21 +31,13 @@ class SourceBuffer final

void EvictData(size_t aLength, bool* aBufferFull);

void AppendData(const uint8_t* aData,
size_t aLength,
success_callback_t aSuccessCb,
void* aSuccessCbContext,
error_callback_t aErrorCb,
void* aErrorCbContext);
void AppendData(const uint8_t* aData, size_t aLength);

void AbortBufferAppend();

void ResetParserState();

void RangeRemoval(double aStart,
double aEnd,
success_callback_t aSuccessCb,
void* aSuccessCbContext);
void RangeRemoval(double aStart, double aEnd);

private:
friend class MediaSource;
Expand All @@ -58,12 +50,8 @@ class SourceBuffer final
void CheckEndTime();

void AppendDataCompletedWithSuccess(
const SourceBufferTask::AppendBufferResult& aResult,
success_callback_t aSuccessCb,
void* aSuccessCbContext);
void AppendDataErrored(const MediaResult& aError,
error_callback_t aErrorCb,
void* aErrorCbContext);
const SourceBufferTask::AppendBufferResult& aResult);
void AppendDataErrored(const MediaResult& aError);

bool GetActive() { return mCurrentAttributes.GetActive(); }
void SetActive(bool aActive) { mCurrentAttributes.SetActive(aActive); }
Expand All @@ -75,7 +63,8 @@ class SourceBuffer final
RefPtr<TrackBuffersManager> mTrackBuffersManager;

MozPromiseRequestHolder<SourceBufferTask::AppendPromise> mPendingAppend;
MozPromiseRequestHolder<SourceBufferTask::RangeRemovalPromise> mPendingRemoval;
MozPromiseRequestHolder<SourceBufferTask::RangeRemovalPromise>
mPendingRemoval;
MozPromiseRequestHolder<MediaSource::ActiveCompletionPromise>
mCompletionPromise;
};
Expand Down
12 changes: 12 additions & 0 deletions gecko-media/gecko/glue/include/SourceBufferAttributes.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,18 @@ class SourceBufferAttributes
aGroupEndTimestamp.ToSeconds());
}

void OnDataAppended(uint32_t aResult)
{
CALLBACK_GUARD_VOID(OnDataAppended);
(*mImpl.mOnDataAppended)(mImpl.mContext, aResult);
}

void OnRangeRemoved()
{
CALLBACK_GUARD_VOID(OnRangeRemoved);
(*mImpl.mOnRangeRemoved)(mImpl.mContext);
}

// mGenerateTimestamp isn't mutable once the source buffer has been
// constructed
bool mGenerateTimestamps;
Expand Down
42 changes: 24 additions & 18 deletions gecko-media/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -427,11 +427,15 @@ mod tests {
assert_eq!(gecko_media.is_type_supported("audio/wav"), false);
}

struct SourceBufferAttributes {}
struct SourceBufferAttributes {
pub expect_data_appended_success: Cell<bool>,
}

impl SourceBufferAttributes {
pub fn new() -> Self {
SourceBufferAttributes {}
SourceBufferAttributes {
expect_data_appended_success: Cell::new(true),
}
}
}

Expand Down Expand Up @@ -478,6 +482,14 @@ mod tests {
false
}
fn set_active(&self, _: bool) {}
fn on_data_appended(&self, result: u32) {
if self.expect_data_appended_success.get() {
assert!(result == 0);
} else {
assert!(result != 0);
}
}
fn on_range_removed(&self) {}
}

struct SourceBufferDom {
Expand All @@ -496,30 +508,24 @@ mod tests {
}
}

pub fn append_data<S, E>(&self, data: *const u8, len: usize, success_cb: S, error_cb: E)
where
S: Fn(),
E: Fn(u32),
{
self.gecko_media.append_data(
data,
len,
success_cb,
error_cb,
pub fn append_data(&self, data: *const u8, len: usize, expect_success: bool) {
self.attributes.expect_data_appended_success.set(
expect_success,
);
self.gecko_media.append_data(data, len);
}
}

fn test_source_buffer() {
let media_source = MediaSourceDom::new();
let source_buffer = SourceBufferDom::new(&media_source, "video/mp4");
let source_buffer = Box::new(SourceBufferDom::new(&media_source, "video/mp4"));
let empty: [u8; 0] = [];
// TODO For now this only tests that the mechanism to send closures through FFI works.
// Should throw error because no decoder is attached yet.
source_buffer.append_data(empty.as_ptr(), empty.len(), || unreachable!(), |_| {
// TODO check error code.
assert!(true);
});
source_buffer.append_data(
empty.as_ptr(),
empty.len(),
false, /* expect error: no decoder */
);
}

#[test]
Expand Down
Loading

0 comments on commit 79949bd

Please sign in to comment.