transfering.https.any.js (11064B)
1 // META: global=window,dedicatedworker 2 3 promise_test(async t => { 4 let fmt = 'RGBA'; 5 const rgb_plane = [ 6 0xBA, 0xDF, 0x00, 0xD0, 0xBA, 0xDF, 0x01, 0xD0, 0xBA, 0xDF, 0x02, 0xD0, 7 0xBA, 0xDF, 0x03, 0xD0 8 ]; 9 let data = new Uint8Array(rgb_plane); 10 let unused_buffer = new ArrayBuffer(123); 11 let init = { 12 format: fmt, 13 timestamp: 1234, 14 codedWidth: 2, 15 codedHeight: 2, 16 visibleRect: {x: 0, y: 0, width: 2, height: 2}, 17 transfer: [data.buffer, unused_buffer] 18 }; 19 assert_equals(data.length, 16, 'data.length'); 20 assert_equals(unused_buffer.byteLength, 123, 'unused_buffer.byteLength'); 21 22 let frame = new VideoFrame(data, init); 23 assert_equals(frame.format, fmt, 'format'); 24 assert_equals(data.length, 0, 'data.length after detach'); 25 assert_equals(unused_buffer.byteLength, 0, 'unused_buffer after detach'); 26 27 const options = { 28 rect: {x: 0, y: 0, width: init.codedWidth, height: init.codedHeight} 29 }; 30 let size = frame.allocationSize(options); 31 let output_data = new Uint8Array(size); 32 let layout = await frame.copyTo(output_data, options); 33 let expected_data = new Uint8Array(rgb_plane); 34 assert_equals(expected_data.length, size, 'expected_data size'); 35 for (let i = 0; i < size; i++) { 36 assert_equals(expected_data[i], output_data[i], `expected_data[${i}]`); 37 } 38 39 frame.close(); 40 }, 'Test transfering ArrayBuffer to VideoFrame'); 41 42 43 promise_test(async t => { 44 let fmt = 'I420'; 45 const i420_planes = [0xAA, 0xBB, 0xCC]; 46 let data = new Uint8Array(i420_planes); 47 let init = { 48 format: fmt, 49 timestamp: 1234, 50 codedWidth: 1, 51 codedHeight: 1, 52 visibleRect: {x: 0, y: 0, width: 1, height: 1}, 53 transfer: [data.buffer] 54 }; 55 56 let frame = new VideoFrame(data, init); 57 assert_equals(data.length, 0, 'data.length after detach'); 58 59 const options = { 60 rect: {x: 0, y: 0, width: init.codedWidth, height: init.codedHeight} 61 }; 62 let size = frame.allocationSize(options); 63 let output_data = new Uint8Array(size); 64 let layout = await frame.copyTo(output_data, options); 65 let expected_data = new Uint8Array(i420_planes); 66 assert_equals(expected_data.length, size, 'expected_data size'); 67 assert_equals(layout[0].stride, 1, 'layout[0].stride'); 68 assert_equals(layout[0].offset, 0, 'layout[0].offset'); 69 assert_equals(layout[1].stride, 1, 'layout[1].stride'); 70 assert_equals(layout[1].offset, 1, 'layout[1].offset'); 71 assert_equals(layout[2].stride, 1, 'layout[2].stride'); 72 assert_equals(layout[2].offset, 2, 'layout[2].offset'); 73 assert_equals(expected_data.length, size, 'expected_data size'); 74 for (let i = 0; i < size; i++) { 75 assert_equals(expected_data[i], output_data[i], `expected_data[${i}]`); 76 } 77 78 frame.close(); 79 }, 'Test transfering buffers to VideoFrame with uneven samples'); 80 81 promise_test(async t => { 82 const rgb_plane = [ 83 0xBA, 0xDF, 0x00, 0xD0, 0xBA, 0xDF, 0x01, 0xD0, 0xBA, 0xDF, 0x02, 0xD0, 84 0xBA, 0xDF, 0x03, 0xD0 85 ]; 86 let data = new Uint8Array(rgb_plane); 87 let detached_buffer = new ArrayBuffer(123); 88 89 // Detach `detached_buffer` 90 structuredClone({x: detached_buffer}, {transfer: [detached_buffer]}); 91 92 let init = { 93 format: 'RGBA', 94 timestamp: 1234, 95 codedWidth: 2, 96 codedHeight: 2, 97 visibleRect: {x: 0, y: 0, width: 2, height: 2}, 98 transfer: [data.buffer, detached_buffer] 99 }; 100 101 try { 102 new VideoFrame(data, init); 103 } catch (error) { 104 assert_equals(error.name, 'DataCloneError', 'error.name'); 105 } 106 // `data.buffer` didn't get detached 107 assert_equals(data.length, 16, 'data.length'); 108 }, 'Test transfering detached buffer to VideoFrame'); 109 110 111 promise_test(async t => { 112 const rgb_plane = [ 113 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 114 0xEE, 0xEE, 0xEE, 0xEE 115 ]; 116 const padding_size = 6; 117 let arraybuffer = new ArrayBuffer(padding_size + 16 /* pixels */); 118 let data = new Uint8Array(arraybuffer, padding_size); 119 data.set(rgb_plane); 120 121 let init = { 122 format: 'RGBA', 123 timestamp: 1234, 124 codedWidth: 2, 125 codedHeight: 2, 126 visibleRect: {x: 0, y: 0, width: 2, height: 2}, 127 transfer: [arraybuffer] 128 }; 129 130 let frame = new VideoFrame(data, init); 131 assert_equals(data.length, 0, 'data.length after detach'); 132 assert_equals(arraybuffer.byteLength, 0, 'arraybuffer after detach'); 133 134 const options = { 135 rect: {x: 0, y: 0, width: init.codedWidth, height: init.codedHeight} 136 }; 137 let size = frame.allocationSize(options); 138 let output_data = new Uint8Array(size); 139 let layout = await frame.copyTo(output_data, options); 140 for (let i = 0; i < size; i++) { 141 assert_equals(output_data[i], 0xEE, `output_data[${i}]`); 142 } 143 }, 'Test transfering view of an ArrayBuffer to VideoFrame'); 144 145 promise_test(async t => { 146 const rgb_plane = [ 147 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 148 0xEE, 0xEE, 0xEE, 0xEE 149 ]; 150 const padding_size = 6; 151 let arraybuffer = new ArrayBuffer(padding_size + 16 /* pixels */); 152 let data = new Uint8Array(arraybuffer, padding_size); 153 data.set(rgb_plane); 154 155 let init = { 156 format: 'RGBA', 157 timestamp: 1234, 158 codedWidth: 2, 159 codedHeight: 2, 160 visibleRect: {x: 0, y: 0, width: 2, height: 2}, 161 transfer: [arraybuffer, arraybuffer] 162 }; 163 164 try { 165 new VideoFrame(data, init); 166 } catch (error) { 167 assert_equals(error.name, 'DataCloneError', 'error.name'); 168 } 169 // `data.buffer` didn't get detached 170 assert_equals(data.length, 16, 'data.length'); 171 }, 'Test transfering same array buffer twice to VideoFrame'); 172 173 promise_test(async t => { 174 const bytes = [ 0xBA, 0xDF, 0x00, 0xD0, 0xBA, 0xDF, 0x01, 0xD0, 0xBA, 0xDF ]; 175 let data = new Uint8Array(bytes); 176 let unused_buffer = new ArrayBuffer(123); 177 let init = { 178 type: 'key', 179 timestamp: 0, 180 data: data, 181 transfer: [data.buffer, unused_buffer] 182 }; 183 184 assert_equals(data.length, 10, 'data.length'); 185 assert_equals(unused_buffer.byteLength, 123, 'unused_buffer.byteLength'); 186 187 let chunk = new EncodedAudioChunk(init); 188 assert_equals(data.length, 0, 'data.length after detach'); 189 assert_equals(unused_buffer.byteLength, 0, 'unused_buffer after detach'); 190 191 let output_data = new Uint8Array(chunk.byteLength); 192 chunk.copyTo(output_data); 193 let expected_data = new Uint8Array(bytes); 194 assert_equals(expected_data.length, chunk.byteLength, 'expected_data size'); 195 for (let i = 0; i < chunk.byteLength; i++) { 196 assert_equals(expected_data[i], output_data[i], `expected_data[${i}]`); 197 } 198 }, 'Test transfering ArrayBuffer to EncodedAudioChunk'); 199 200 promise_test(async t => { 201 const bytes = [ 0xBA, 0xDF, 0x00, 0xD0, 0xBA, 0xDF, 0x01, 0xD0, 0xBA, 0xDF ]; 202 let data = new Uint8Array(bytes); 203 let unused_buffer = new ArrayBuffer(123); 204 let init = { 205 type: 'key', 206 timestamp: 0, 207 data: data, 208 transfer: [data.buffer, unused_buffer] 209 }; 210 211 assert_equals(data.length, 10, 'data.length'); 212 assert_equals(unused_buffer.byteLength, 123, 'unused_buffer.byteLength'); 213 214 let chunk = new EncodedVideoChunk(init); 215 assert_equals(data.length, 0, 'data.length after detach'); 216 assert_equals(unused_buffer.byteLength, 0, 'unused_buffer after detach'); 217 218 let output_data = new Uint8Array(chunk.byteLength); 219 chunk.copyTo(output_data); 220 let expected_data = new Uint8Array(bytes); 221 assert_equals(expected_data.length, chunk.byteLength, 'expected_data size'); 222 for (let i = 0; i < chunk.byteLength; i++) { 223 assert_equals(expected_data[i], output_data[i], `expected_data[${i}]`); 224 } 225 }, 'Test transfering ArrayBuffer to EncodedVideoChunk'); 226 227 promise_test(async t => { 228 const bytes = [0xBA, 0xDF, 0x00, 0xD0, 0xBA, 0xDF, 0x01, 0xD0, 0xBA, 0xDF]; 229 let data = new Uint8Array(bytes); 230 let unused_buffer = new ArrayBuffer(123); 231 let init = { 232 type: 'key', 233 timestamp: 0, 234 numberOfFrames: data.length, 235 numberOfChannels: 1, 236 sampleRate: 10000, 237 format: 'u8', 238 data: data, 239 transfer: [data.buffer, unused_buffer] 240 }; 241 242 assert_equals(data.length, 10, 'data.length'); 243 assert_equals(unused_buffer.byteLength, 123, 'unused_buffer.byteLength'); 244 245 let audio_data = new AudioData(init); 246 assert_equals(data.length, 0, 'data.length after detach'); 247 assert_equals(unused_buffer.byteLength, 0, 'unused_buffer after detach'); 248 249 let readback_data = new Uint8Array(bytes.length); 250 audio_data.copyTo(readback_data, {planeIndex: 0, format: 'u8'}); 251 let expected_data = new Uint8Array(bytes); 252 for (let i = 0; i < expected_data.length; i++) { 253 assert_equals(expected_data[i], readback_data[i], `expected_data[${i}]`); 254 } 255 }, 'Test transfering ArrayBuffer to AudioData'); 256 257 promise_test(async t => { 258 let sample_rate = 48000; 259 let total_duration_s = 1; 260 let data_count = 10; 261 let chunks = []; 262 263 let encoder_init = { 264 error: t.unreached_func('Encoder error'), 265 output: (chunk, metadata) => { 266 chunks.push(chunk); 267 } 268 }; 269 let encoder = new AudioEncoder(encoder_init); 270 let config = { 271 codec: 'opus', 272 sampleRate: sample_rate, 273 numberOfChannels: 2, 274 bitrate: 256000, // 256kbit 275 }; 276 encoder.configure(config); 277 278 let timestamp_us = 0; 279 const data_duration_s = total_duration_s / data_count; 280 const frames = data_duration_s * config.sampleRate; 281 for (let i = 0; i < data_count; i++) { 282 let buffer = new Float32Array(frames * config.numberOfChannels); 283 let data = new AudioData({ 284 timestamp: timestamp_us, 285 data: buffer, 286 numberOfChannels: config.numberOfChannels, 287 numberOfFrames: frames, 288 sampleRate: config.sampleRate, 289 format: 'f32-planar', 290 transfer: [buffer.buffer] 291 }); 292 timestamp_us += data_duration_s * 1_000_000; 293 assert_equals(buffer.length, 0, 'buffer.length after detach'); 294 encoder.encode(data); 295 } 296 await encoder.flush(); 297 encoder.close(); 298 assert_greater_than(chunks.length, 0); 299 }, 'Encoding from AudioData with transferred buffer'); 300 301 302 promise_test(async t => { 303 let unused_buffer = new ArrayBuffer(123); 304 let support = await ImageDecoder.isTypeSupported('image/png'); 305 assert_implements_optional( 306 support, 'Optional codec image/png not supported.'); 307 let buffer = await fetch('four-colors.png').then(response => { 308 return response.arrayBuffer(); 309 }); 310 311 let decoder = new ImageDecoder( 312 {data: buffer, type: 'image/png', transfer: [buffer, unused_buffer]}); 313 assert_equals(buffer.byteLength, 0, 'buffer.byteLength after detach'); 314 assert_equals(unused_buffer.byteLength, 0, 'unused_buffer after detach'); 315 316 let result = await decoder.decode(); 317 assert_equals(result.image.displayWidth, 320); 318 assert_equals(result.image.displayHeight, 240); 319 }, 'Test transfering ArrayBuffer to ImageDecoder.'); 320 321 promise_test(async t => { 322 // Not a valid PNG but that shouldn't matter. 323 let arraybuffer = new ArrayBuffer(16); 324 let data = new Uint8Array(arraybuffer); 325 let init = { 326 type: 'image/png', 327 data: data, 328 transfer: [arraybuffer, arraybuffer] 329 }; 330 331 assert_throws_dom('DataCloneError', () => new ImageDecoder(init)); 332 // `data.buffer` didn't get detached 333 assert_equals(data.length, 16, 'data.length'); 334 }, 'Test transfering same array buffer twice to ImageDecoder');