[video_player] Fixes a bug where the aspect ratio of some HLS videos are incorrectly inverted (#6507)

diff --git a/packages/video_player/video_player_avfoundation/CHANGELOG.md b/packages/video_player/video_player_avfoundation/CHANGELOG.md
index 7cfa025..ed2f345 100644
--- a/packages/video_player/video_player_avfoundation/CHANGELOG.md
+++ b/packages/video_player/video_player_avfoundation/CHANGELOG.md
@@ -1,5 +1,6 @@
-## NEXT
+## 2.3.7
 
+* Fixes a bug where the aspect ratio of some HLS videos are incorrectly inverted.
 * Updates code for `no_leading_underscores_for_local_identifiers` lint.
 
 ## 2.3.6
diff --git a/packages/video_player/video_player_avfoundation/example/ios/RunnerTests/VideoPlayerTests.m b/packages/video_player/video_player_avfoundation/example/ios/RunnerTests/VideoPlayerTests.m
index 813fca2..f9f66e0 100644
--- a/packages/video_player/video_player_avfoundation/example/ios/RunnerTests/VideoPlayerTests.m
+++ b/packages/video_player/video_player_avfoundation/example/ios/RunnerTests/VideoPlayerTests.m
@@ -11,9 +11,6 @@
 
 @interface FLTVideoPlayer : NSObject <FlutterStreamHandler>
 @property(readonly, nonatomic) AVPlayer *player;
-// This is to fix a bug (https://github.com/flutter/flutter/issues/111457) in iOS 16 with blank
-// video for encrypted video streams. An invisible AVPlayerLayer is used to overwrite the
-// protection of pixel buffers in those streams.
 @property(readonly, nonatomic) AVPlayerLayer *playerLayer;
 @end
 
@@ -65,13 +62,12 @@
 
 @implementation VideoPlayerTests
 
-- (void)testIOS16BugWithEncryptedVideoStream {
-  // This is to fix a bug (https://github.com/flutter/flutter/issues/111457) in iOS 16 with blank
-  // video for encrypted video streams. An invisible AVPlayerLayer is used to overwrite the
-  // protection of pixel buffers in those streams.
-  // Note that a better unit test is to validate that `copyPixelBuffer` API returns the pixel
-  // buffers as expected, which requires setting up the video player properly with a protected video
-  // stream (.m3u8 file).
+- (void)testBlankVideoBugWithEncryptedVideoStreamAndInvertedAspectRatioBugForSomeVideoStream {
+  // This is to fix 2 bugs: 1. blank video for encrypted video streams on iOS 16
+  // (https://github.com/flutter/flutter/issues/111457) and 2. swapped width and height for some
+  // video streams (not just iOS 16).  (https://github.com/flutter/flutter/issues/109116). An
+  // invisible AVPlayerLayer is used to overwrite the protection of pixel buffers in those streams
+  // for issue #1, and restore the correct width and height for issue #2.
   NSObject<FlutterPluginRegistry> *registry =
       (NSObject<FlutterPluginRegistry> *)[[UIApplication sharedApplication] delegate];
   NSObject<FlutterPluginRegistrar> *registrar =
@@ -95,13 +91,8 @@
   FLTVideoPlayer *player = videoPlayerPlugin.playersByTextureId[textureMessage.textureId];
   XCTAssertNotNil(player);
 
-  if (@available(iOS 16.0, *)) {
-    XCTAssertNotNil(player.playerLayer, @"AVPlayerLayer should be present for iOS 16.");
-    XCTAssertNotNil(player.playerLayer.superlayer,
-                    @"AVPlayerLayer should be added on screen for iOS 16.");
-  } else {
-    XCTAssertNil(player.playerLayer, @"AVPlayerLayer should not be present before iOS 16.");
-  }
+  XCTAssertNotNil(player.playerLayer, @"AVPlayerLayer should be present.");
+  XCTAssertNotNil(player.playerLayer.superlayer, @"AVPlayerLayer should be added on screen.");
 }
 
 - (void)testSeekToInvokesTextureFrameAvailableOnTextureRegistry {
diff --git a/packages/video_player/video_player_avfoundation/ios/Classes/FLTVideoPlayerPlugin.m b/packages/video_player/video_player_avfoundation/ios/Classes/FLTVideoPlayerPlugin.m
index 645c86d..3b06676 100644
--- a/packages/video_player/video_player_avfoundation/ios/Classes/FLTVideoPlayerPlugin.m
+++ b/packages/video_player/video_player_avfoundation/ios/Classes/FLTVideoPlayerPlugin.m
@@ -36,7 +36,11 @@
 @interface FLTVideoPlayer : NSObject <FlutterTexture, FlutterStreamHandler>
 @property(readonly, nonatomic) AVPlayer *player;
 @property(readonly, nonatomic) AVPlayerItemVideoOutput *videoOutput;
-/// An invisible player layer used to access the pixel buffers in protected video streams in iOS 16.
+// This is to fix 2 bugs: 1. blank video for encrypted video streams on iOS 16
+// (https://github.com/flutter/flutter/issues/111457) and 2. swapped width and height for some video
+// streams (not just iOS 16).  (https://github.com/flutter/flutter/issues/109116).
+// An invisible AVPlayerLayer is used to overwrite the protection of pixel buffers in those streams
+// for issue #1, and restore the correct width and height for issue #2.
 @property(readonly, nonatomic) AVPlayerLayer *playerLayer;
 @property(readonly, nonatomic) CADisplayLink *displayLink;
 @property(nonatomic) FlutterEventChannel *eventChannel;
@@ -134,17 +138,13 @@
   return degrees;
 };
 
-NS_INLINE UIViewController *rootViewController() API_AVAILABLE(ios(16.0)) {
-  for (UIScene *scene in UIApplication.sharedApplication.connectedScenes) {
-    if ([scene isKindOfClass:UIWindowScene.class]) {
-      for (UIWindow *window in ((UIWindowScene *)scene).windows) {
-        if (window.isKeyWindow) {
-          return window.rootViewController;
-        }
-      }
-    }
-  }
-  return nil;
+NS_INLINE UIViewController *rootViewController() {
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+  // TODO: (hellohuanlin) Provide a non-deprecated codepath. See
+  // https://github.com/flutter/flutter/issues/104117
+  return UIApplication.sharedApplication.keyWindow.rootViewController;
+#pragma clang diagnostic pop
 }
 
 - (AVMutableVideoComposition *)getVideoCompositionWithTransform:(CGAffineTransform)transform
@@ -242,13 +242,13 @@
   _player = [AVPlayer playerWithPlayerItem:item];
   _player.actionAtItemEnd = AVPlayerActionAtItemEndNone;
 
-  // This is to fix a bug (https://github.com/flutter/flutter/issues/111457) in iOS 16 with blank
-  // video for encrypted video streams. An invisible AVPlayerLayer is used to overwrite the
-  // protection of pixel buffers in those streams.
-  if (@available(iOS 16.0, *)) {
-    _playerLayer = [AVPlayerLayer playerLayerWithPlayer:_player];
-    [rootViewController().view.layer addSublayer:_playerLayer];
-  }
+  // This is to fix 2 bugs: 1. blank video for encrypted video streams on iOS 16
+  // (https://github.com/flutter/flutter/issues/111457) and 2. swapped width and height for some
+  // video streams (not just iOS 16).  (https://github.com/flutter/flutter/issues/109116). An
+  // invisible AVPlayerLayer is used to overwrite the protection of pixel buffers in those streams
+  // for issue #1, and restore the correct width and height for issue #2.
+  _playerLayer = [AVPlayerLayer playerLayerWithPlayer:_player];
+  [rootViewController().view.layer addSublayer:_playerLayer];
 
   [self createVideoOutputAndDisplayLink:frameUpdater];
 
@@ -481,9 +481,7 @@
 /// so the channel is going to die or is already dead.
 - (void)disposeSansEventChannel {
   _disposed = YES;
-  if (@available(iOS 16.0, *)) {
-    [_playerLayer removeFromSuperlayer];
-  }
+  [_playerLayer removeFromSuperlayer];
   [_displayLink invalidate];
   AVPlayerItem *currentItem = self.player.currentItem;
   [currentItem removeObserver:self forKeyPath:@"status"];
diff --git a/packages/video_player/video_player_avfoundation/pubspec.yaml b/packages/video_player/video_player_avfoundation/pubspec.yaml
index bd88ddf..6da1667 100644
--- a/packages/video_player/video_player_avfoundation/pubspec.yaml
+++ b/packages/video_player/video_player_avfoundation/pubspec.yaml
@@ -2,7 +2,7 @@
 description: iOS implementation of the video_player plugin.
 repository: https://github.com/flutter/plugins/tree/main/packages/video_player/video_player_avfoundation
 issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+video_player%22
-version: 2.3.6
+version: 2.3.7
 
 environment:
   sdk: ">=2.14.0 <3.0.0"