Repository: flutter
Issue: CVMetalTextureRef created by CVMetalTextureCacheCreateTextureFromImage is released while in use
Labels: engine,platform-mac,a: platform-views,p: video_player,package,P2,team-macos,triaged-macos

### Steps to reproduce

Originally spotted in:
https://github.com/flutter/packages/pull/7466
https://github.com/flutter/packages/pull/7466#issuecomment-2377628306
https://github.com/flutter/packages/pull/7466#issuecomment-2405893042

Try something that uses `FlutterTexture` like `video_player` plugin on macos. For example https://github.com/flutter/packages/tree/main/packages/video_player/video_player_avfoundation/example and in this concrete sample set speed to 1.5 and click play (with some other videos this is not needed, and it is not the cause).

Seems this is caused by a bug in the flutter engine. [There](https://developer.apple.com/documentation/corevideo/cvmetaltexturecachecreatetexturefromimage(_:_:_:_:_:_:_:_:_:)?language=objc) is this "You need to maintain a strong reference to textureOut until the GPU finishes execution of commands accessing the texture, because the system doesn’t automatically retain it.". But here is `textureOut` released right after `CVMetalTextureCacheCreateTextureFromImage`:

https://github.com/flutter/engine/blob/6f802b39ab0669eb6ba3272dff1d34e85febeb77/shell/platform/darwin/graphics/FlutterDarwinExternalTextureMetal.mm#L233-L249
https://github.com/flutter/engine/blob/6f802b39ab0669eb6ba3272dff1d34e85febeb77/shell/platform/darwin/graphics/FlutterDarwinExternalTextureMetal.mm#L177-L197

I thought that it flashes video frames from the past but I looked closely at video recorded from the screen and for example at one moment for 1/60 of a second it shows a frame from video X frames into the future. Maybe when the underlying `textureOut` is released this memory may be reused and overwritten by `AVPlayer` for decoding following video frames.

_(There is also this "Note that Core Video doesn’t explicitly declare any pixel format types as Metal compatible. Specify true for the kCVPixelBufferMetalCompatibilityKey option to create Metal-compatible buffers when creating or requesting Core Video pixel buffers.". Maybe the player should also specify this in `pixBuffAttributes` when creating `AVPlayerItemVideoOutput`?)_

It seems that macOS actually uses some different code path than ios but here it is the same, `cvMetalTexture` is released right after `CVMetalTextureCacheCreateTextureFromImage`:

https://github.com/flutter/engine/blob/6f802b39ab0669eb6ba3272dff1d34e85febeb77/shell/platform/darwin/macos/framework/Source/FlutterExternalTexture.mm#L119-L135
https://github.com/flutter/engine/blob/6f802b39ab0669eb6ba3272dff1d34e85febeb77/shell/platform/darwin/macos/framework/Source/FlutterExternalTexture.mm#L77-L97

_(And this is eventually called from `embedder_external_texture_metal.mm` which handles things differently, it does not use flag like `_textureFrameAvailable` like is used in `FlutterDarwinExternalTextureMetal.mm` but instead it nullifies last stored image when is called `textureFrameAvailable` so if `copyPixelBuffer` returns NULL it will not show anything and will periodically call it until it returns non-NULL.)_

For example, changing [relevant lines](https://github.com/flutter/engine/blob/6f802b39ab0669eb6ba3272dff1d34e85febeb77/shell/platform/darwin/macos/framework/Source/FlutterExternalTexture.mm#L134-L135) to this fixes it (where `stored_cvMetalTexture` is for example a member variable in `FlutterExternalTexture`):

```
  _textures = {(__bridge FlutterMetalTextureHandle)CVMetalTextureGetTexture(cvMetalTexture)};
  //CVBufferRelease(cvMetalTexture);
  CVBufferRelease(stored_cvMetalTexture);
  stored_cvMetalTexture = cvMetalTexture;
```


### Expected results

Smooth video playback.

### Actual results

Some frames of the video look like they are coming from the future.

### Code sample

<details open><summary>Code sample</summary>

https://github.com/flutter/packages/tree/main/packages/video_player/video_player_avfoundation/example

</details>


### Screenshots or Video

<details open>
<summary>Screenshots / Video demonstration</summary>

https://github.com/user-attachments/assets/43e51437-9e2a-41ab-8e51-50d0b8a29538

https://github.com/user-attachments/assets/09b3083e-7ed9-4f81-b58b-5f13d820ffd7

</details>


### Logs

<details open><summary>Logs</summary>

```console
[Paste your logs here]
```

</details>


### Flutter Doctor output

<details open><summary>Doctor output</summary>

```console
[✓] Flutter (Channel stable, 3.24.3, on macOS 14.5 23F79 darwin-x64)
[✓] Xcode - develop for iOS and macOS (Xcode 15.4)
```

</details>