mirror of
https://github.com/arcodange-org/mediabunny.git
synced 2026-09-27 02:43:48 +02:00
Fix AAC error in Matroska muxer, remove special VideoFrame path for VideoSample due to Chromium bug
This commit is contained in:
@@ -118,25 +118,52 @@ class ProresDecoder extends CustomVideoDecoder {
|
||||
this.trimCodedHeightToVisibleHeight(result);
|
||||
}
|
||||
|
||||
const sample = new VideoSample(result.frameData, {
|
||||
format: result.pixelFormat,
|
||||
codedWidth: result.codedWidth,
|
||||
codedHeight: result.codedHeight,
|
||||
visibleRect: {
|
||||
left: 0,
|
||||
top: 0,
|
||||
width: result.visibleWidth,
|
||||
height: result.visibleHeight,
|
||||
},
|
||||
timestamp: packet.timestamp,
|
||||
duration: packet.duration,
|
||||
colorSpace: {
|
||||
primaries: result.colorPrimariesString as VideoColorPrimaries | undefined,
|
||||
matrix: result.colorMatrixString as VideoMatrixCoefficients | undefined,
|
||||
transfer: result.colorTransferString as VideoTransferCharacteristics | undefined,
|
||||
fullRange: result.colorRangeFull,
|
||||
},
|
||||
});
|
||||
const colorSpaceInit = {
|
||||
primaries: result.colorPrimariesString as VideoColorPrimaries | undefined,
|
||||
matrix: result.colorMatrixString as VideoMatrixCoefficients | undefined,
|
||||
transfer: result.colorTransferString as VideoTransferCharacteristics | undefined,
|
||||
fullRange: result.colorRangeFull,
|
||||
};
|
||||
|
||||
let sample: VideoSample;
|
||||
if (typeof VideoFrame !== 'undefined') {
|
||||
// Create a VideoFrame directly; this avoids the frame data being copied twice
|
||||
const frame = new VideoFrame(result.frameData, {
|
||||
format: result.pixelFormat as VideoPixelFormat,
|
||||
codedWidth: result.codedWidth,
|
||||
codedHeight: result.codedHeight,
|
||||
visibleRect: {
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: result.visibleWidth,
|
||||
height: result.visibleHeight,
|
||||
},
|
||||
timestamp: packet.microsecondTimestamp,
|
||||
duration: packet.microsecondDuration,
|
||||
colorSpace: colorSpaceInit,
|
||||
});
|
||||
|
||||
sample = new VideoSample(frame, {
|
||||
timestamp: packet.timestamp,
|
||||
duration: packet.duration,
|
||||
});
|
||||
} else {
|
||||
sample = new VideoSample(result.frameData, {
|
||||
format: result.pixelFormat,
|
||||
codedWidth: result.codedWidth,
|
||||
codedHeight: result.codedHeight,
|
||||
visibleRect: {
|
||||
left: 0,
|
||||
top: 0,
|
||||
width: result.visibleWidth,
|
||||
height: result.visibleHeight,
|
||||
},
|
||||
timestamp: packet.timestamp,
|
||||
duration: packet.duration,
|
||||
colorSpace: colorSpaceInit,
|
||||
});
|
||||
}
|
||||
|
||||
this.onSample(sample);
|
||||
}
|
||||
|
||||
|
||||
@@ -844,7 +844,7 @@ export class MatroskaMuxer extends Muxer {
|
||||
},
|
||||
chunkQueue: [],
|
||||
lastWrittenMsTimestamp: null,
|
||||
codecPrivate: meta.decoderConfig.description ?? null,
|
||||
codecPrivate: decoderConfig.description ?? null,
|
||||
closed: false,
|
||||
};
|
||||
|
||||
|
||||
+4
-35
@@ -469,41 +469,10 @@ export class VideoSample implements Disposable {
|
||||
this.squarePixelHeight = this.visibleRect.height;
|
||||
}
|
||||
|
||||
// If VideoFrame is available, route through it directly instead of holding onto the buffer. Going
|
||||
// buffer -> VideoSample -> VideoFrame would copy the data twice (once here, once in toVideoFrame);
|
||||
// building the VideoFrame now means it's only ever copied once.
|
||||
if (typeof VideoFrame !== 'undefined' && !init._doNotCopy) {
|
||||
let videoFrame: VideoFrame | null = null;
|
||||
|
||||
try {
|
||||
videoFrame = new VideoFrame(toUint8Array(data), {
|
||||
format: init.format as VideoPixelFormat,
|
||||
codedWidth: init.codedWidth!,
|
||||
codedHeight: init.codedHeight!,
|
||||
layout,
|
||||
colorSpace: colorSpaceInit,
|
||||
visibleRect: {
|
||||
x: this.visibleRect.left,
|
||||
y: this.visibleRect.top,
|
||||
width: this.visibleRect.width,
|
||||
height: this.visibleRect.height,
|
||||
},
|
||||
displayWidth: this.squarePixelWidth,
|
||||
displayHeight: this.squarePixelHeight,
|
||||
timestamp: Math.trunc(init.timestamp! * SECOND_TO_MICROSECOND_FACTOR),
|
||||
// Drag 0 to undefined
|
||||
duration: Math.trunc((init.duration ?? 0) * SECOND_TO_MICROSECOND_FACTOR) || undefined,
|
||||
});
|
||||
} catch {
|
||||
// Ignore the error and move on like it didn't happen. We don't want errors caused by the local
|
||||
// VideoFrame implementation to prevent us from creating the VideoSample. Errors, for example, could
|
||||
// be caused by an unsupported pixel format.
|
||||
}
|
||||
|
||||
if (videoFrame) {
|
||||
return new VideoSample(videoFrame, init);
|
||||
}
|
||||
}
|
||||
// As an optimization, one could check if VideoFrame is defined and if it is, create a VideoFrame here from
|
||||
// the data. Since VideoFrames are typically needed anyway, doing it this way would avoid an additional
|
||||
// copy of the frame data. But due to https://issues.chromium.org/issues/529413114, this is currently
|
||||
// not done.
|
||||
|
||||
this._data = init._doNotCopy
|
||||
? toUint8Array(data)
|
||||
|
||||
Reference in New Issue
Block a user