Skip to content

Commit

Permalink
Make DASH parsing first pass closer to original XML
Browse files Browse the repository at this point in the history
This is to facilitate code understanding as well as a first step to
facilitate DASH PATCH MPD, by having a less destructive first pass
regarding the original XML.
  • Loading branch information
peaBerberian committed Mar 3, 2025
1 parent b32084c commit 8dbe03b
Show file tree
Hide file tree
Showing 47 changed files with 1,547 additions and 829 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,11 @@ describe("DASH Parser - getHTTPUTCTimingURL", () => {
it("should return undefined if the given intermediate representation has no UTCTimings element", async () => {
const mpdIR: IMPDIntermediateRepresentation = {
children: {
baseURLs: [],
locations: [],
periods: [],
utcTimings: [],
BaseURL: [],
Location: [],
Period: [],
UTCTiming: [],
ContentProtection: [],
},
attributes: {},
};
Expand All @@ -25,19 +26,24 @@ describe("DASH Parser - getHTTPUTCTimingURL", () => {
it("should return undefined if the given intermediate representation has no http-iso UTCTimings element", async () => {
const mpdIR: IMPDIntermediateRepresentation = {
children: {
baseURLs: [],
locations: [],
periods: [],
utcTimings: [
BaseURL: [],
Location: [],
Period: [],
UTCTiming: [
{
schemeIdUri: "urn:mpeg:dash:utc:direct-iso:2014",
value: "foob",
attributes: {
schemeIdUri: "urn:mpeg:dash:utc:direct-iso:2014",
value: "foob",
},
},
{
schemeIdUri: "urn:mpeg:dash:utc:http-iso:2009",
value: "foob",
attributes: {
schemeIdUri: "urn:mpeg:dash:utc:http-iso:2009",
value: "foob",
},
},
],
ContentProtection: [],
},
attributes: {},
};
Expand All @@ -49,19 +55,26 @@ describe("DASH Parser - getHTTPUTCTimingURL", () => {
it("should return undefined if the given intermediate representation has no value for its http-iso UTCTimings element", async () => {
const mpdIR: IMPDIntermediateRepresentation = {
children: {
baseURLs: [],
locations: [],
periods: [],
utcTimings: [
BaseURL: [],
Location: [],
Period: [],
ContentProtection: [],
UTCTiming: [
{
schemeIdUri: "urn:mpeg:dash:utc:http-iso:2014",
attributes: {
schemeIdUri: "urn:mpeg:dash:utc:http-iso:2014",
},
},
{
schemeIdUri: "urn:mpeg:dash:utc:direct-iso:2014",
value: "foob",
attributes: {
schemeIdUri: "urn:mpeg:dash:utc:direct-iso:2014",
value: "foob",
},
},
{
schemeIdUri: "urn:mpeg:dash:utc:http-iso:2014",
attributes: {
schemeIdUri: "urn:mpeg:dash:utc:http-iso:2014",
},
},
],
},
Expand All @@ -75,13 +88,16 @@ describe("DASH Parser - getHTTPUTCTimingURL", () => {
it("should return the value of a single http-iso UTCTimings element", async () => {
const mpdIR: IMPDIntermediateRepresentation = {
children: {
baseURLs: [],
locations: [],
periods: [],
utcTimings: [
BaseURL: [],
Location: [],
Period: [],
ContentProtection: [],
UTCTiming: [
{
schemeIdUri: "urn:mpeg:dash:utc:http-iso:2014",
value: "foobar2000",
attributes: {
schemeIdUri: "urn:mpeg:dash:utc:http-iso:2014",
value: "foobar2000",
},
},
],
},
Expand All @@ -95,21 +111,28 @@ describe("DASH Parser - getHTTPUTCTimingURL", () => {
it("should return the first value of multiple http-iso UTCTimings elements", async () => {
const mpdIR: IMPDIntermediateRepresentation = {
children: {
baseURLs: [],
locations: [],
periods: [],
utcTimings: [
BaseURL: [],
Location: [],
Period: [],
ContentProtection: [],
UTCTiming: [
{
schemeIdUri: "urn:mpeg:dash:utc:http-iso:2014",
value: "foobar1000",
attributes: {
schemeIdUri: "urn:mpeg:dash:utc:http-iso:2014",
value: "foobar1000",
},
},
{
schemeIdUri: "urn:mpeg:dash:utc:http-iso:2014",
value: "foobar2000",
attributes: {
schemeIdUri: "urn:mpeg:dash:utc:http-iso:2014",
value: "foobar2000",
},
},
{
schemeIdUri: "urn:mpeg:dash:utc:http-iso:2014",
value: "foobar3000",
attributes: {
schemeIdUri: "urn:mpeg:dash:utc:http-iso:2014",
value: "foobar3000",
},
},
],
},
Expand All @@ -123,29 +146,40 @@ describe("DASH Parser - getHTTPUTCTimingURL", () => {
it("should return the first value of a http-iso UTCTimings element when mixed with other elements", async () => {
const mpdIR: IMPDIntermediateRepresentation = {
children: {
baseURLs: [],
locations: [],
periods: [],
utcTimings: [
BaseURL: [],
Location: [],
Period: [],
ContentProtection: [],
UTCTiming: [
{
schemeIdUri: "urn:mpeg:dash:utc:direct-iso:2014",
value: "foob",
attributes: {
schemeIdUri: "urn:mpeg:dash:utc:direct-iso:2014",
value: "foob",
},
},
{
schemeIdUri: "urn:mpeg:dash:utc:http-iso:2014",
value: "foobar2000",
attributes: {
schemeIdUri: "urn:mpeg:dash:utc:http-iso:2014",
value: "foobar2000",
},
},
{
schemeIdUri: "urn:mpeg:dash:utc:http-iso:2014",
value: "foobar1000",
attributes: {
schemeIdUri: "urn:mpeg:dash:utc:http-iso:2014",
value: "foobar1000",
},
},
{
schemeIdUri: "urn:mpeg:dash:utc:direct-iso:2014",
value: "foob",
attributes: {
schemeIdUri: "urn:mpeg:dash:utc:direct-iso:2014",
value: "foob",
},
},
{
schemeIdUri: "urn:mpeg:dash:utc:http-iso:2014",
value: "foobar1000",
attributes: {
schemeIdUri: "urn:mpeg:dash:utc:http-iso:2014",
value: "foobar1000",
},
},
],
},
Expand Down
21 changes: 11 additions & 10 deletions src/parsers/manifest/dash/common/content_protection_parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -152,12 +152,13 @@ export default class ContentProtectionParser {

// Referenced ContentProtection found, let's inherit its attributes

contentProt.children.cencPssh.push(...referenced.children.cencPssh);
contentProt.children["cenc:pssh"].push(...referenced.children["cenc:pssh"]);
if (
contentProt.attributes.keyId === undefined &&
referenced.attributes.keyId !== undefined
contentProt.attributes["cenc:default_KID"] === undefined &&
referenced.attributes["cenc:default_KID"] !== undefined
) {
contentProt.attributes.keyId = referenced.attributes.keyId;
contentProt.attributes["cenc:default_KID"] =
referenced.attributes["cenc:default_KID"];
}
if (
contentProt.attributes.schemeIdUri === undefined &&
Expand Down Expand Up @@ -211,10 +212,10 @@ function parseContentProtection(
.toLowerCase();
}
if (
contentProtectionIr.attributes.keyId !== undefined &&
contentProtectionIr.attributes.keyId.length > 0
contentProtectionIr.attributes["cenc:default_KID"] !== undefined &&
contentProtectionIr.attributes["cenc:default_KID"].length > 0
) {
const kid = contentProtectionIr.attributes.keyId;
const kid = contentProtectionIr.attributes["cenc:default_KID"];
if (representation.contentProtections === undefined) {
representation.contentProtections = { keyIds: [kid], initData: [] };
} else if (representation.contentProtections.keyIds === undefined) {
Expand All @@ -227,10 +228,10 @@ function parseContentProtection(
if (systemId === undefined) {
return;
}
const { cencPssh } = contentProtectionIr.children;
const cencPssh = contentProtectionIr.children["cenc:pssh"];
const values: Array<{ systemId: string; data: Uint8Array }> = [];
for (const data of cencPssh) {
values.push({ systemId, data });
for (const pssh of cencPssh) {
values.push({ systemId, data: pssh.value });
}
if (values.length === 0) {
return;
Expand Down
22 changes: 13 additions & 9 deletions src/parsers/manifest/dash/common/get_http_utc-timing_url.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,16 @@ import type { IMPDIntermediateRepresentation } from "../node_parser_types";

type ISupportedHttpUtcTimingScheme =
| {
schemeIdUri: "urn:mpeg:dash:utc:http-iso:2014";
value: string;
attributes: {
schemeIdUri: "urn:mpeg:dash:utc:http-iso:2014";
value: string;
};
}
| {
schemeIdUri: "urn:mpeg:dash:utc:http-xsdate:2014";
value: string;
attributes: {
schemeIdUri: "urn:mpeg:dash:utc:http-xsdate:2014";
value: string;
};
};

/**
Expand All @@ -33,12 +37,12 @@ type ISupportedHttpUtcTimingScheme =
export default function getHTTPUTCTimingURL(
mpdIR: IMPDIntermediateRepresentation,
): string | undefined {
const UTCTimingHTTP = mpdIR.children.utcTimings.filter(
const UTCTimingHTTP = mpdIR.children.UTCTiming.filter(
(utcTiming): utcTiming is ISupportedHttpUtcTimingScheme =>
(utcTiming.schemeIdUri === "urn:mpeg:dash:utc:http-iso:2014" ||
utcTiming.schemeIdUri === "urn:mpeg:dash:utc:http-xsdate:2014") &&
utcTiming.value !== undefined,
(utcTiming.attributes.schemeIdUri === "urn:mpeg:dash:utc:http-iso:2014" ||
utcTiming.attributes.schemeIdUri === "urn:mpeg:dash:utc:http-xsdate:2014") &&
utcTiming.attributes.value !== undefined,
);

return UTCTimingHTTP.length > 0 ? UTCTimingHTTP[0].value : undefined;
return UTCTimingHTTP.length > 0 ? UTCTimingHTTP[0].attributes.value : undefined;
}
2 changes: 1 addition & 1 deletion src/parsers/manifest/dash/common/indexes/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ export interface IBaseIndexIndexArgument {
timescale?: number;
media?: string;
indexRange?: [number, number];
initialization?: { media?: string; range?: [number, number] };
initialization?: { media?: string; range?: [number, number] } | undefined;
startNumber?: number;
endNumber?: number;
/**
Expand Down
10 changes: 6 additions & 4 deletions src/parsers/manifest/dash/common/indexes/list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,12 @@ export interface IListIndex {
export interface IListIndexIndexArgument {
duration?: number | undefined;
indexRange?: [number, number] | undefined;
initialization?: {
media?: string | undefined;
range?: [number, number] | undefined;
};
initialization?:
| {
media?: string | undefined;
range?: [number, number] | undefined;
}
| undefined;
list: Array<{
media?: string | undefined;
mediaRange?: [number, number] | undefined;
Expand Down
21 changes: 9 additions & 12 deletions src/parsers/manifest/dash/common/infer_adaptation_type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,17 @@
import { SUPPORTED_ADAPTATIONS_TYPE } from "../../../../manifest";
import arrayFind from "../../../../utils/array_find";
import arrayIncludes from "../../../../utils/array_includes";
import type { IRepresentationIntermediateRepresentation } from "../node_parser_types";
import type {
IRepresentationIntermediateRepresentation,
ISchemeIntermediateRepresentation,
} from "../node_parser_types";

/** Different "type" a parsed Adaptation can be. */
type IAdaptationType = "audio" | "video" | "text";

/** Different `role`s a text Adaptation can be. */
const SUPPORTED_TEXT_TYPES = ["subtitle", "caption"];

/** Structure of a parsed "scheme-like" element in the MPD. */
interface IScheme {
schemeIdUri?: string | undefined;
value?: string | undefined;
}

/**
* Infers the type of adaptation from codec and mimetypes found in it.
*
Expand All @@ -52,11 +49,11 @@ export default function inferAdaptationType(
representations: IRepresentationIntermediateRepresentation[],
adaptationMimeType: string | null,
adaptationCodecs: string | null,
adaptationRoles: IScheme[] | null,
adaptationRoles: ISchemeIntermediateRepresentation[],
): IAdaptationType | undefined {
function fromMimeType(
mimeType: string,
roles: IScheme[] | null,
roles: ISchemeIntermediateRepresentation[],
): IAdaptationType | undefined {
const topLevel = mimeType.split("/")[0];
if (
Expand All @@ -72,13 +69,13 @@ export default function inferAdaptationType(
}
// manage DASH-IF mp4-embedded subtitles and metadata
if (mimeType === "application/mp4") {
if (roles !== null) {
if (roles.length > 0) {
if (
arrayFind(
roles,
(role) =>
role.schemeIdUri === "urn:mpeg:dash:role:2011" &&
arrayIncludes(SUPPORTED_TEXT_TYPES, role.value),
role.attributes.schemeIdUri === "urn:mpeg:dash:role:2011" &&
arrayIncludes(SUPPORTED_TEXT_TYPES, role.attributes.value),
) !== undefined
) {
return "text";
Expand Down
Loading

0 comments on commit 8dbe03b

Please sign in to comment.