{"record":{"id":"f9b6d2f95524744c","repo":"stride3d/stride","slug":"videotexture-was-not-deallocated-properly-before-trying-to","errorCode":null,"errorMessage":"\"videoTexture\" was not deallocated properly before trying to create a new one!","messagePattern":"\"videoTexture\" was not deallocated properly before trying to create a new one!","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"sources/engine/Stride.Video/VideoInstance.cs","lineNumber":428,"sourceCode":"        {\n            if (url == null || startPosition < 0 || length < 0)\n                return;\n\n            var factory = videoSystem.ActiveBackendFactory\n                ?? throw new InvalidOperationException(\"No video backend is registered or supported on this platform.\");\n            backend = factory.CreateBackend(this);\n            mediaInitialized = backend.Initialize(url, startPosition, length);\n            if (!mediaInitialized)\n            {\n                backend.Dispose();\n                backend = null;\n            }\n        }\n\n        internal void AllocateVideoTexture(int width, int height)\n        {\n            if (videoTexture != null)\n                throw new InvalidOperationException(\"\\\"videoTexture\\\" was not deallocated properly before trying to create a new one!\");\n\n            videoTexture = new VideoTexture(GraphicsDevice, services, width, height, videoComponent.MaxMipMapCount);\n        }\n\n        private void DeallocateVideoTexture()\n        {\n            videoTexture?.Dispose();\n            videoTexture = null;\n        }\n\n        // Backend-accessible state. Internal to keep VideoInstance's public surface stable.\n        internal IServiceRegistry Services => services;\n        internal VideoComponent VideoComponent => videoComponent;\n        internal VideoTexture VideoTexture => videoTexture;\n        internal void SetCurrentTime(TimeSpan time) => CurrentTime = time;\n        internal void SetDuration(TimeSpan duration) => Duration = duration;\n\n        // Called by a backend right after it writes a freshly-decoded frame to the target.","sourceCodeStart":410,"sourceCodeEnd":446,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/engine/Stride.Video/VideoInstance.cs#L410-L446","documentation":"VideoInstance.AllocateVideoTexture throws this InvalidOperationException when a video texture already exists and has not been released. The class enforces a strict allocate/deallocate lifecycle: only one VideoTexture may be live at a time, so re-allocation without an intervening DeallocateVideoTexture is treated as a caller bug rather than being silently tolerated.","triggerScenarios":"Calling AllocateVideoTexture(width, height) when the internal videoTexture field is non-null — i.e. after a previous allocation that was not followed by DeallocateVideoTexture, or re-preparing/seeking/restarting the same VideoInstance without releasing its texture.","commonSituations":"Replaying or restarting a video without disposing the previous playback; calling video preparation APIs twice in a row; a playback path that skips the deallocation step on error or early exit; reusing a cached VideoInstance across plays.","solutions":["Call DeallocateVideoTexture (or the public API that triggers it, e.g. stopping/invalidating the video) before calling AllocateVideoTexture again.","Ensure the playback lifecycle is linear: allocate -> play -> deallocate -> (optionally) allocate again.","If reusing the instance, reset it (seek to start / re-prepare via the media player) so its internal texture is released first.","Wrap the sequence in try/finally so the texture is deallocated even when playback throws."],"exampleFix":"// before\nvideoInstance.AllocateVideoTexture(1920, 1080);\nvideoInstance.Play();\nvideoInstance.AllocateVideoTexture(1920, 1080); // throws\n\n// after\nvideoInstance.AllocateVideoTexture(1920, 1080);\nvideoInstance.Play();\nvideoInstance.DeallocateVideoTexture();\nvideoInstance.AllocateVideoTexture(1920, 1080); // ok","handlingStrategy":"try-catch","validationCode":"// C#\nbool canAllocate = videoInstance != null; // texture state is internal; wrap allocation\n","typeGuard":null,"tryCatchPattern":"// C#\ntry { videoInstance.AllocateVideoTexture(w, h); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"not deallocated\"))\n{\n    // deallocate and retry once\n}","preventionTips":["Always pair AllocateVideoTexture with DeallocateVideoTexture in try/finally","Never re-prepare or restart playback on the same VideoInstance without deallocating first","Do not cache VideoInstance across plays without resetting it"],"tags":["lifecycle","resource-leak","video","invalid-state-transition"],"backgroundTag":"invalid-state-transition","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}