Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to change video orientation for AVCaptureVideoDataOutput


Here's the problem. I am using AVCaptureVideoDataOutput to get video frames from camera and make video from them with AVAssetWriter. Its working OK, but the video that I get is upside down because default orientation of device for my app is landscape left, not landscape right as its stated by default in AVCaptureVideoDataOutput. Im trying to change orientation in AVCaptureConnection class, but isVideoOrientationSupported is always false, is it somehow possible to fix it?

Here is some code:

 AVCaptureDeviceInput *captureInput = [AVCaptureDeviceInput 
            deviceInputWithDevice:[AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo] 
            error:nil];
 /*We setupt the output*/
 AVCaptureVideoDataOutput *captureOutput = [[AVCaptureVideoDataOutput alloc] init]; 
 captureOutput.alwaysDiscardsLateVideoFrames = YES; 
 captureOutput.minFrameDuration = CMTimeMake(1.0, 24.0); //Uncomment it to specify a minimum duration for each video frame
 [captureOutput setSampleBufferDelegate:self queue:dispatch_get_main_queue()];

 // Set the video output to store frame in BGRA (It is supposed to be faster)
 NSString* key = (NSString*)kCVPixelBufferPixelFormatTypeKey; 
 NSNumber* value = [NSNumber numberWithUnsignedInt:kCVPixelFormatType_32BGRA]; 



 NSDictionary* videoSettings = [NSDictionary dictionaryWithObject:value forKey:key]; 
 [captureOutput setVideoSettings:videoSettings]; 


 /*And we create a capture session*/
 self.captureSession = [[AVCaptureSession alloc] init];
 self.captureSession.sessionPreset = AVCaptureSessionPresetLow;
 /*We add input and output*/
 if ([self.captureSession canAddInput:captureInput]) 
 {
  [self.captureSession addInput:captureInput];
 }
 if ([self.captureSession canAddOutput:captureOutput]) 
 {
  [self.captureSession addOutput:captureOutput];
 }

 /*We add the preview layer*/
 self.prevLayer = [AVCaptureVideoPreviewLayer layerWithSession: self.captureSession];

 if ([self.prevLayer isOrientationSupported]) 
 {
  [self.prevLayer setOrientation:AVCaptureVideoOrientationLandscapeLeft];
 }

 self.prevLayer.frame = self.view.bounds; 

 self.prevLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
 [self.view.layer addSublayer: self.prevLayer];

 AVCaptureConnection *videoConnection = NULL;

 [self.captureSession beginConfiguration];

 for ( AVCaptureConnection *connection in [captureOutput connections] ) 
 {
  for ( AVCaptureInputPort *port in [connection inputPorts] ) 
  {
   if ( [[port mediaType] isEqual:AVMediaTypeVideo] ) 
   {
    videoConnection = connection;

   }
  }
 }
    if([videoConnection isVideoOrientationSupported]) // **Here it is, its always false**
     {
        [videoConnection setVideoOrientation:AVCaptureVideoOrientationLandscapeLeft];
     }

 [self.captureSession commitConfiguration];

 [self.captureSession startRunning]; 

Upd: figured that when exporting video, the AVAssetExportSession loses preferredTransform info.

like image 271
Steve Avatar asked Sep 29 '10 16:09

Steve


2 Answers

I ran into the same problem and poked around the AVCamDemo from WWDC. I don't know why (yet) but if you query your videoConnection right after you create all the inputs/outputs/connections then both isVideoOrientationSupported and supportsVideoOrientation return NO.

However, if you query supportsVideoOrientation or isVideoOrientationSupported at some later point (after the GUI is setup for instance) then it will return YES. For instance I query it right after the user clicks the record button just before I call [[self movieFileOutput] startRecordingToOutputFileURL...]

Give it a try, works for me.

like image 171
Shizam Avatar answered Nov 07 '22 13:11

Shizam


From here: http://developer.apple.com/library/ios/#qa/qa1744/_index.html#//apple_ref/doc/uid/DTS40011134

Currently, the capture outputs for a movie file (AVCaptureMovieFileOutput) and still image (AVCaptureStillImageOutput) support setting the orientation, but the data output for processing video frames (AVCaptureVideoDataOutput) does not.

like image 27
Or Arbel Avatar answered Nov 07 '22 13:11

Or Arbel