UNPKG

yuv-rx

Version:

Reading videos as Rx Observables of decoded frames

114 lines (113 loc) 3.74 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Y4MHeader = exports.Y4MFrame = exports.Y4MFrameHeader = void 0; const frame_1 = require("./frame"); function interlacingFromChar(char) { switch (char) { case 't': return 'TopFieldFirst'; case 'b': return 'BottomFieldFirst'; case 'm': return 'Mixed'; case 'p': default: return 'Progressive'; } } class Y4MFrameHeader { } exports.Y4MFrameHeader = Y4MFrameHeader; class Y4MFrame { constructor(fn, yuv) { this.fn = fn; this.yuv = yuv; } } exports.Y4MFrame = Y4MFrame; class Y4MHeader { constructor() { this.interlacing = 'Progressive'; this.aspectRatio = { numerator: 1, denominator: 1 }; this.colorspace = 'C420mpeg2'; this.timeScale = -1; } chromaWidth() { if (this.colorspace == 'C444' || this.colorspace == 'C422') { return this.width; } else { return Math.ceil(this.width / 2); } } chromaHeight() { if (this.colorspace == 'C444') { return this.height; } else { return Math.ceil(this.height / 2); } } chromaSize() { return this.chromaWidth() * this.chromaHeight(); } lumaSize() { return this.width * this.height; } getFrameSize() { return this.lumaSize() + this.chromaSize() * 2; } static fromString(line) { if ('YUV4MPEG2 ' != line.substring(0, 10)) { throw new Error('Wrong yuv4mpeg header.'); } const split = line.substring(10).split(' '); const header = new Y4MHeader(); for (const s of split) { const key = s.charAt(0); const value = s.substring(1); switch (key) { case 'W': header.width = parseInt(value); break; case 'H': header.height = parseInt(value); break; case 'F': header.frameRate = (0, frame_1.parseRational)(value); header.timeScale = header.frameRate.numerator; header.videoMediaTimeScale = header.timeScale; break; case 'I': header.interlacing = interlacingFromChar(s.charAt(1)); break; case 'A': header.aspectRatio = (0, frame_1.parseRational)(value); break; case 'C': header.colorspace = s; break; case 'X': header.comment = value; const vmtsMatch = Y4MHeader.videoMediaTimeScaleRegex.exec(line); if (vmtsMatch != null) { header.videoMediaTimeScale = parseInt(vmtsMatch.groups.ts); } else { const tsMatch = Y4MHeader.timeScaleRegex.exec(line); if (tsMatch != null) { header.timeScale = parseInt(tsMatch.groups.ts); } } break; } } return header; } toString() { return `YUV4MPEG2 W${this.width} H${this.height} F${this.frameRate.numerator}:${this.frameRate.denominator} Ip A${this.aspectRatio.numerator}:${this.aspectRatio.denominator} ${this.colorspace} XYSCSS=420MPEG2`; } } exports.Y4MHeader = Y4MHeader; Y4MHeader.timeScaleRegex = /TS=(?<ts>\d+)/; Y4MHeader.videoMediaTimeScaleRegex = /VMTS=(?<ts>\d+)/;