Skip to content

Commit

Permalink
Implemented hdlr box decoding.
Browse files Browse the repository at this point in the history
  • Loading branch information
BTOdell committed Jul 27, 2021
1 parent 338495a commit ea80440
Show file tree
Hide file tree
Showing 6 changed files with 133 additions and 8 deletions.
4 changes: 2 additions & 2 deletions boxes/ftyp/src/ftyp.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type {Buffer} from "buffer";
import type {Box, FourCC, BoxHeader} from "@isomp4/core";
import type {Box, BoxHeader, FourCC} from "@isomp4/core";
import {BoxEncoding, readFourCC} from "@isomp4/core";

export interface FileTypeBox extends Box {
Expand Down Expand Up @@ -30,7 +30,7 @@ class FileTypeBoxEncoding extends BoxEncoding {
return superBox;
}
const offset: number = this.decodedBytes;
const end: number = offset > 0 ? superBox.size : superBox.size - super.encodingLength(superBox);
const end: number = FileTypeBoxEncoding.end(superBox, header);
if (buffer.length < end) {
return end;
}
Expand Down
80 changes: 80 additions & 0 deletions boxes/moov/src/hdlr.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import type {Buffer} from "buffer";
import type {BoxHeader, FourCC, FullBox} from "@isomp4/core";
import {FullBoxEncoding} from "@isomp4/core";
import {readString} from "@isomp4/core/src/BufferUtils";

export interface HandlerBox extends FullBox {

/**
* The type of media handler for the track.
*
* Common types:
* * `vide`
* * `soun`
* * `auxv`
* * `meta`
* * `hint`
* * `text`
* * `subt`
* * `fdsm`
*/
handlerType: "vide" | "soun" | "auxv" | "meta" | "hint" | "text" | "subt" | "fdsm" | FourCC;

/**
* A human-readable name for the track type.
*/
name: string;

}

class HandlerBoxEncoding extends FullBoxEncoding {

constructor() {
super("hdlr");
}

public override encodingLength(obj: HandlerBox): number {
return super.encodingLength(obj); // TODO implement
}

public override encodeTo(obj: HandlerBox, buffer: Buffer): number {
const requiredBytes = super.encodeTo(obj, buffer);
if (requiredBytes > 0) {
return requiredBytes;
}
// let offset = this.encodedBytes;
// // TODO implementing encoding
// this.encodedBytes = offset;
return 0;
}

public override decode(buffer: Buffer, header?: BoxHeader): HandlerBox | number {
const superBox = super.decode(buffer, header);
if (typeof superBox === "number") {
return superBox;
}
let offset: number = this.decodedBytes;
// Assume there are no child boxes of hdlr
const end: number = HandlerBoxEncoding.end(superBox, header);
if (buffer.length < end) {
return end;
}
offset += 4; // pre_defined = 0
const handlerType: FourCC = buffer.toString("binary", offset, offset += 4);
offset += 12; // reserved = 0
const name: string | number = readString(buffer, offset);
if (typeof name === "number") {
return offset + name;
}
offset += readString.decodedBytes;
this.decodedBytes = offset;
return {
...superBox,
handlerType,
name,
};
}

}

export const hdlr = new HandlerBoxEncoding();
4 changes: 3 additions & 1 deletion boxes/moov/src/moov.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import {BoxEncoding} from "@isomp4/core";
import {hdlr} from "./hdlr.js";
import {mvhd} from "./mvhd.js";
import {stsd} from "./stsd.js";

export const stbl = new BoxEncoding("stbl", stsd);
export const minf = new BoxEncoding("minf", stbl);
export const mdia = new BoxEncoding("mdia", minf);
export const mdia = new BoxEncoding("mdia", hdlr, minf);
export const trak = new BoxEncoding("trak", mdia);
export const moov = new BoxEncoding("moov", mvhd, trak);

export * from "./hdlr.js";
export * from "./mvhd.js";
export * from "./samples/avc.js";
export * from "./stsd.js";
10 changes: 5 additions & 5 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions packages/core/src/BoxEncoding.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,16 @@ export class BoxEncoding {
return parsedHeader;
}

/**
* Calculates the (exclusive) end index of the given box.
* @param box The box to get the end index of.
* @param header The optional header if it was parsed before the box.
* @return The end index of the box.
*/
protected static end(box: Box, header?: BoxHeader): number {
return header == null ? box.size : box.size - BoxHeader.encodingLength(header);
}

}

/**
Expand Down
33 changes: 33 additions & 0 deletions packages/core/src/BufferUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,36 @@ export function readMatrix(buffer: Buffer, offset: number, n: number): number[]
}
return mat;
}

/**
* Reads a null-terminated UTF-8 string from the buffer.
* @param buffer The buffer to read from.
* @param offset The offset in the buffer to read from.
* @return A decoded string,
* or if there isn't enough data in the buffer, returns the total
* number of bytes needed to read the string.
*/
export function readString(buffer: Buffer, offset: number): string | number {
let end = offset;
search: {
const len = buffer.length;
for (; end < len; end++) {
if (buffer[end] === 0) {
break search;
}
}
// Ran out of bytes, need at least one more
return end - offset + 1;
}
readString.decodedBytes = end - offset + 1;
return buffer.toString("utf8", offset, end);
}

export namespace readString {

/**
* The number of bytes that were decoded by the last call to {@link readString}.
*/
export let decodedBytes: number;

}

0 comments on commit ea80440

Please sign in to comment.