title: CALayer.contents not rendering correctly in AVMutableComposition
body: <p>I have a very simple method that generates a video with a static background image which covers the entire video composition and a smaller, partially transparent image (watermark style) that's located at the bottom of the video. </p>
  
  <p>The background image renders correctly and appears exactly the same as it looks in an image viewer. However, the image that's supposed to be rendered at the bottom of the video is skewed/distorted.</p>
  
  <p><strong><a href="https://github.com/bshamblen/VideoWatermarkBugExample" rel="noreferrer">The source can be downloaded here, on GitHub.</a></strong></p>
  
  <p><strong>The expected output of my code (mockup of the desired video output):</strong></p>
  
  <p><img src="https://i.stack.imgur.com/jp2xZ.png" alt="The expected output of the video"></p>
  
  <p><strong>The actual output of my code (partial screenshot from the iOS Simulator):</strong></p>
  
  <p><img src="https://i.stack.imgur.com/gMXe6.png" alt="An actual screenshot of my video output"></p>
  
  <p>As you can see, the footer image appears skewed at a 45 degree angle and a little wavy. </p>
  
  <p>Below is the code that I'm currently using to generate the video. I've tried every possible combination of contentsGravity for the footer image, with no luck. Every other example that I've seen simply sets a CGImageRef to the layer's <code>contents</code> then sets the <code>bounds</code>, <code>position</code> and <code>anchorPoint</code> to their appropriate values. I haven't seen any other examples that set any other properties. I've read through almost all of the documentation for the AVFoundation to see if there setting that I'm missing, but I haven't come across anything obvious yet.</p>
  
  <p>Any suggestions would be greatly appreciated. Thanks!</p>
  
  <p><strong>Interface declarations:</strong></p>
  
  <pre><code>CGSize _renderingSize;
  float _displayDuration;
  
  AVMutableComposition *mutableComposition;
  AVMutableVideoComposition *videoComposition;
  AVMutableCompositionTrack *mutableCompositionVideoTrack;
  AVAssetExportSession *exporter;
  </code></pre>
  
  <p><strong>ViewDidLoad settings:</strong></p>
  
  <pre><code>_renderingSize = CGSizeMake(640, 360);
  _displayDuration = 2.0;
  </code></pre>
  
  <p><strong>Rendering code block:</strong></p>
  
  <pre><code>    mutableComposition = [AVMutableComposition composition];
      mutableCompositionVideoTrack = [mutableComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
  
      videoComposition = [AVMutableVideoComposition videoComposition];
      videoComposition.renderSize = _renderingSize;
      videoComposition.frameDuration = CMTimeMake(1, 30);
  
      CALayer *parentLayer = [CALayer layer];
      CALayer *videoLayer = [CALayer layer];
      parentLayer.frame = CGRectMake(0, 0, videoComposition.renderSize.width, videoComposition.renderSize.height);
      videoLayer.frame = CGRectMake(0, 0, videoComposition.renderSize.width, videoComposition.renderSize.height);
      [parentLayer addSublayer:videoLayer];
  
      videoComposition.animationTool = [AVVideoCompositionCoreAnimationTool videoCompositionCoreAnimationToolWithPostProcessingAsVideoLayer:videoLayer inLayer:parentLayer];
  
      NSString *path = [[NSBundle mainBundle] pathForResource:@"blank_1080p" ofType:@"mp4"];
      NSURL *url = [NSURL fileURLWithPath:path];
      AVAsset *asset = [AVAsset assetWithURL:url];
      AVAssetTrack *track = [[asset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
      [mutableCompositionVideoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero,CMTimeMakeWithSeconds(_displayDuration, 600)) ofTrack:track atTime:kCMTimeZero error:nil];
  
      CALayer *imageLayer = [CALayer layer];
      imageLayer.bounds = parentLayer.frame;
      imageLayer.anchorPoint = CGPointMake(0.5, 0.5);
      imageLayer.position = CGPointMake(CGRectGetMidX(imageLayer.bounds), CGRectGetMidY(imageLayer.bounds));
      imageLayer.contents = (id)[UIImage imageNamed:@"background.png"].CGImage;
      imageLayer.contentsGravity = kCAGravityResizeAspectFill;
      [parentLayer addSublayer:imageLayer];
  
      UIImage *testImage = [UIImage imageNamed:@"bannerTextLayer.png"];
  
      CALayer *footerLayer = [CALayer layer];
      footerLayer.bounds = CGRectMake(0, 0, 540, 40);
      footerLayer.anchorPoint = CGPointMake(0.5, 0.5);
      footerLayer.position = CGPointMake(CGRectGetMidX(footerLayer.bounds), CGRectGetMidY(footerLayer.bounds));
      footerLayer.contents = (id)testImage.CGImage;
      footerLayer.contentsGravity = kCAGravityResizeAspectFill;
      [parentLayer addSublayer:footerLayer];
  
      AVMutableVideoCompositionInstruction *instruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
      instruction.timeRange = CMTimeRangeMake(kCMTimeZero, CMTimeMakeWithSeconds(_displayDuration, 600));
      videoComposition.instructions = @[instruction];
  
      exporter = [[AVAssetExportSession alloc] initWithAsset:mutableComposition presetName:AVAssetExportPresetHighestQuality];
      exporter.outputURL = videoURL ;
      exporter.videoComposition = videoComposition;
      exporter.outputFileType= AVFileTypeMPEG4;
      exporter.timeRange = CMTimeRangeMake(kCMTimeZero, CMTimeMakeWithSeconds(_displayDuration, 600));
      exporter.shouldOptimizeForNetworkUse = YES;
  
      [exporter exportAsynchronouslyWithCompletionHandler:^(void){
          switch (exporter.status) {
              case AVAssetExportSessionStatusFailed:{
                  NSLog(@"Fail: %@", exporter.error);
                  break;
              }
              case AVAssetExportSessionStatusCompleted:{
                  NSLog(@"Success");
  
                  dispatch_async(dispatch_get_main_queue(), ^{
                      if (self.moviePlayer)
                          [self.moviePlayer.view removeFromSuperview];
  
                      self.moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:videoURL];
  
                      self.moviePlayer.view.frame = CGRectMake(0, 0, 320, 180);
                      [self.moviePlayer setControlStyle:MPMovieControlStyleNone];
  
                      [self.previewView addSubview:self.moviePlayer.view];
                      [self.moviePlayer play];
  
                  });
  
                  break;
              }
              default:
                  break;
          }
      }];
  </code></pre>