(buffer: ArrayBuffer)
| 42 | }; |
| 43 | |
| 44 | function readNv12Metadata(buffer: ArrayBuffer): Nv12Metadata | null { |
| 45 | if (buffer.byteLength < NV12_METADATA_SIZE) return null; |
| 46 | |
| 47 | const formatCheck = new DataView(buffer, buffer.byteLength - 4, 4); |
| 48 | const magic = formatCheck.getUint32(0, true); |
| 49 | if (magic !== NV12_VIDEO_MAGIC && magic !== NV12_FULL_MAGIC) return null; |
| 50 | |
| 51 | const metadataOffset = buffer.byteLength - NV12_METADATA_SIZE; |
| 52 | const meta = new DataView(buffer, metadataOffset, NV12_METADATA_SIZE); |
| 53 | const yStride = meta.getUint32(0, true); |
| 54 | const height = meta.getUint32(4, true); |
| 55 | const width = meta.getUint32(8, true); |
| 56 | |
| 57 | const ySize = yStride * height; |
| 58 | const uvSize = yStride * Math.floor(height / 2); |
| 59 | const totalSize = ySize + uvSize; |
| 60 | if ( |
| 61 | yStride === 0 || |
| 62 | height === 0 || |
| 63 | width === 0 || |
| 64 | buffer.byteLength - NV12_METADATA_SIZE < totalSize |
| 65 | ) { |
| 66 | return null; |
| 67 | } |
| 68 | |
| 69 | return { |
| 70 | yStride, |
| 71 | height, |
| 72 | width, |
| 73 | fullRange: magic === NV12_FULL_MAGIC, |
| 74 | }; |
| 75 | } |
| 76 | |
| 77 | export type FpsStats = { |
| 78 | fps: number; |
no outgoing calls
no test coverage detected