cornerstonejs / cornerstone3D

Cornerstone is a set of JavaScript libraries that can be used to build web-based medical imaging applications. It provides a framework to build radiology applications such as the OHIF Viewer.
https://cornerstonejs.org
MIT License
557 stars 285 forks source link

[Bug] chromium browser poor playback performance with multiframe DCM #935

Closed ZacharyCauchi closed 10 months ago

ZacharyCauchi commented 10 months ago

Describe the Bug

I'm playing back a stack of images that are all different frames of the same dicom media file. In the .then() of the promise setstack returns, I run the .playclip() method. In Chrome, this results in really poor performance as it takes several playthroughs of the dicom file before I get looped playback with no stutter/pauses. I'm only encountering this on chromium browsers (chrome and edge). Firefox is good.

Steps to Reproduce

  1. Load multiframe dicom multiframe file with cornerstoneDICOMImageLoader.wadouri.dataSetCacheManager
  2. Create an array of strings, one for each frame of the dicom file, and pass it as your argument to viewport.setStack()
  3. within the .then(), run csToolsUtilities.cine.playClip, with the viewport element as the first argument, and the dicom medias framerate and autoloop: true as the second argument.

The current behavior

I've recorded a video demonstrating the playback in chromium browsers https://github.com/cornerstonejs/cornerstone3D/assets/27774340/ebc6b5c8-4b83-4bb4-807f-7722f8c8e454

The expected behavior

This is the same file on firefox, its a little slow on the first playback but is immediately resolved. https://github.com/cornerstonejs/cornerstone3D/assets/27774340/6a0b417d-1c6b-48bf-a141-2cd3b00e9d36

OS

Windows 11

Node version

16.17.1

Browser

Chrome Version 119.0.6045.200

ZacharyCauchi commented 10 months ago

This is the first bug I've raised on github as a developer. I hope I have provided enough detail 😊. Below is the code snippet that is causing the problem in case that helps

cornerstoneDICOMImageLoader.wadouri.dataSetCacheManager.load('${SERVER_URL}/api/files/${studyFileId}', 
cornerstoneDICOMImageLoader.internal.xhrRequest)
                    .then( async (dataSet: any) => {
                        const numFrames = dataSet.intString('x00280008');
                        const frameRate = dataSet.intString('x00082144');
                        setFramerate(frameRate)
                        if (!numFrames) {
                            imageIds.push('wadouri:${SERVER_URL}/api/files/${studyFileId}');
                        } else {
                            for (let i = 1; i < numFrames; i++) {
                                const imageId = 'wadouri:${SERVER_URL}/api/files/${studyFileId}?frame=${i}';
                                imageIds.push(imageId);
                            }
                        }
                        const viewport = (renderingEngine.getViewport(viewportId) as Types.IStackViewport);
                        viewport.setStack(imageIds).then(()=>{
                            viewport.render();
                            if (numFrames && numFrames > 1) {
                                const element = document.querySelector('#element') as HTMLDivElement;
                                csToolsUtilities.cine.playClip(element, {framesPerSecond: framerate,loop:true});    
                            }       
                        });

                    });
sedghi commented 10 months ago

wadouri is slow, prefetching might help using the stackContextPrefetch

ZacharyCauchi commented 10 months ago

The performance improvement with stackContextPrefetch prefetch is like night and day. Thanks for the sugggestion.