Skip to content

Commit

Permalink
Perform data-serialization as sendMessage-time
Browse files Browse the repository at this point in the history
  • Loading branch information
peaBerberian committed Jan 13, 2025
1 parent 3db53f1 commit 809f8e8
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 15 deletions.
16 changes: 4 additions & 12 deletions src/core/main/worker/content_preparer.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import features from "../../../features";
import log from "../../../log";
import type { IManifest, IManifestMetadata } from "../../../manifest";
import type { IManifest } from "../../../manifest";
import { createRepresentationFilterFromFnString } from "../../../manifest";
import type { IMediaSourceInterface } from "../../../mse";
import MainMediaSourceInterface from "../../../mse/main_media_source_interface";
Expand All @@ -13,7 +13,6 @@ import type {
import { WorkerMessageType } from "../../../multithread_types";
import type { IPlayerError } from "../../../public_types";
import idGenerator from "../../../utils/id_generator";
import objectAssign from "../../../utils/object_assign";
import type {
CancellationError,
CancellationSignal,
Expand Down Expand Up @@ -76,7 +75,7 @@ export default class ContentPreparer {
public initializeNewContent(
sendMessage: (msg: IWorkerMessage, transferables?: Transferable[]) => void,
context: IContentInitializationData,
): Promise<IManifestMetadata> {
): Promise<IManifest> {
return new Promise((res, rej) => {
this.disposeCurrentContent();
const contentCanceller = this._contentCanceller;
Expand Down Expand Up @@ -222,30 +221,23 @@ export default class ContentPreparer {
return;
}

const sentManifest = manifest.getMetadataSnapshot();
manifest.addEventListener(
"manifestUpdate",
(updates) => {
if (manifest === null) {
// TODO log warn?
return;
}

// Remove `periods` key to reduce cost of an unnecessary manifest
// clone.
const snapshot = objectAssign(manifest.getMetadataSnapshot(), {
periods: [],
});
sendMessage({
type: WorkerMessageType.ManifestUpdate,
contentId,
value: { manifest: snapshot, updates },
value: { manifest, updates },
});
},
contentCanceller.signal,
);
unbindRejectOnCancellation();
res(sentManifest);
res(manifest);
}
});
}
Expand Down
40 changes: 38 additions & 2 deletions src/multithread_types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -772,17 +772,53 @@ export interface IRepresentationChangeWorkerMessage {
};
}

/** Message sent by the Worker when the Manifest is first loaded. */
export interface IManifestReadyWorkerMessage {
/** Identify this particular message. */
type: WorkerMessageType.ManifestReady;
/** The `contentId` linked to this Manifest. */
contentId: string;
value: { manifest: IManifestMetadata };
value: {
/**
* The actual `Manifest` loaded.
*
* When possible, this should be a `Manifest` instance.
*
* Only if this is not possible (e.g. because the `Manifest` cannot be
* communicated as is between both Worker and main_thread) might you convert
* it to another object also respecting the `IManifestMetadata` interface.
*
* However doing this might lead to some loss of performance and minor
* features.
*/
manifest: IManifestMetadata;
};
}

/** Message sent by the Worker everytime the Manifest is updated. */
export interface IManifestUpdateWorkerMessage {
/** Identify this particular message. */
type: WorkerMessageType.ManifestUpdate;
/** The `contentId` linked to this Manifest. */
contentId: string | undefined;
value: {
manifest: IManifestMetadata; // TODO only subpart that changed?
/**
* The new manifest once updated.
*
* When possible, this should be a `Manifest` instance to improve
* performance and allow some advanced features.
*
* Only if this is not possible (e.g. because the `Manifest` cannot be
* communicated as is between both Worker and main_thread) might you convert
* it to another object also respecting the `IManifestMetadata` interface.
* In that last case, you're also authorized to reset the `periods` property
* of that `IManifestMetadata` to an empty array to save up message-passing
* performance.
*/
manifest: IManifestMetadata;
/**
* Object describing what has changed in this update.
*/
updates: IPeriodsUpdateResult;
};
}
Expand Down
36 changes: 35 additions & 1 deletion src/worker_entry_point.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ import {
} from "./core/main/worker/globals";
import log from "./experimental/tools/mediaCapabilitiesProber/log";
import features from "./features";
import type { IWorkerMessage } from "./multithread_types";
import Manifest from "./manifest/classes";
import { WorkerMessageType, type IWorkerMessage } from "./multithread_types";
import DashFastJsParser from "./parsers/manifest/dash/fast-js-parser";
import DashWasmParser from "./parsers/manifest/dash/wasm-parser";
import createDashPipelines from "./transports/dash";
Expand Down Expand Up @@ -45,7 +46,15 @@ initializeWorkerMain(
},
);

/**
* Perform a `postMessage` to main thread with the given message.
* Arguments follow the `postMessage` API.
* @param {Object} msg
* @param {Array.<Object>} [transferables]
*/
function sendMessage(msg: IWorkerMessage, transferables?: Transferable[]): void {
updateMessageFormat(msg);

log.debug("<--- Sending to Main:", msg.type);
if (transferables === undefined) {
postMessage(msg);
Expand All @@ -57,3 +66,28 @@ function sendMessage(msg: IWorkerMessage, transferables?: Transferable[]): void
);
}
}

/**
* Ensure that we're sending data that can be serialized, as this is a
* requirement for the `postMessage` browser API.
*
* If necessary, mutations are done in place.
* @param {Object} msg
*/
function updateMessageFormat(msg: IWorkerMessage): void {
if (
msg.type === WorkerMessageType.ManifestReady ||
msg.type === WorkerMessageType.ManifestUpdate
) {
if (msg.value.manifest instanceof Manifest) {
msg.value.manifest = msg.value.manifest.getMetadataSnapshot();
if (msg.type === WorkerMessageType.ManifestUpdate) {
// Remove `periods` key to reduce cost of an unnecessary manifest
// clone.
msg.value.manifest.periods = [];
}
} else {
log.warn("Worker: the Manifest instance should be communicated to `sendMessage`.");
}
}
}

0 comments on commit 809f8e8

Please sign in to comment.