BradLarson / GPUImage

An open source iOS framework for GPU-based image and video processing
http://www.sunsetlakesoftware.com/2012/02/12/introducing-gpuimage-framework
BSD 3-Clause "New" or "Revised" License
20.25k stars 4.61k forks source link

Struggling To Sort Out Rotation For Output #126

Closed OlyRice closed 12 years ago

OlyRice commented 12 years ago

Hi

I am trying to sort out the rotation, its seems that when the video file is created and then copied to the camera roll the rotation is completely out. Videos that are produced in portrait mode seem to be rotated to the right, the code below is an example of the live video recording.

@interface VideoScreen : UIViewController {

GPUImageVideoCamera *videoCamera;
GPUImageOutput<GPUImageInput> *filter;
GPUImageMovieWriter *movieWriter;

int recordingOn;

NSURL *moviePath;

}

The following is the part of the code that is run in the .m file.

-(void)startCamera {

videoCamera = [[GPUImageVideoCamera alloc] initWithSessionPreset:AVCaptureSessionPreset640x480 cameraPosition:AVCaptureDevicePositionBack];

videoCamera.outputImageOrientation = [[UIDevice currentDevice] orientation];

[videoCamera addTarget:videoWindow];

 //videoWindow.fillMode = kGPUImageFillModeStretch;

NSString *pathToMovie = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/Movie.m4v"];
unlink([pathToMovie UTF8String]); // If a file already exists, AVAssetWriter won't let you record new frames, so delete the old movie
self.moviePath = [NSURL fileURLWithPath:pathToMovie];

movieWriter = [[GPUImageMovieWriter alloc] initWithMovieURL:self.moviePath size:CGSizeMake(480.0, 640.0)];

[videoCamera addTarget:movieWriter];
[videoCamera startCameraCapture];

videoCamera.audioEncodingTarget = movieWriter;
[movieWriter startRecording];

}

Am I missing something? I know there used to be a rotation filter but I think that was taken out.

I have a UIView the height and width of the IPhone, my goal would be to mimic the display and output of the in-built camera.

Thanks

Oliver

OlyRice commented 12 years ago

I was looking at the framework and noticed "GPUImageRotationMode", do I need to use this to set the rotation?

Thanks

BradLarson commented 12 years ago

If you still need to rotate the video for output to a video writer, you'll need to have at least one filter in there. Right now, the GPUImageMovieWriter doesn't obey the rotation input and just writes out what is passed into it.

What you can do is use an inexpensive filter, like a GPUImageBrightnessFilter with the brightness set to the normal level of 0.0, to act as a passthrough. That filter will perform the appropriate rotation within it so that the movie writer is fed the proper rotated frames.

OlyRice commented 12 years ago

Hi Brad,

Thanks for the feedback, I did stumble upon that during some testing. I think I will use a filter as mentioned with a simple effect in.

One thing I have noticed is that with the following code the portrait mode works great but the landscape modes are different in the view compared to what is saved. For example, in Landcape "3" the saved video is perfect but the video that appears in the view is rotated by -90 degrees. With the new rotation system Is there a way of manually setting the rotation for the video display?

int orientation = [[UIDevice currentDevice] orientation];

NSLog(@"%d",orientation);

if( orientation == 1){

    videoCamera.outputImageOrientation = UIInterfaceOrientationPortrait;

     movieWriter = [[GPUImageMovieWriter alloc] initWithMovieURL:self.moviePath size:CGSizeMake(480, 640)];

}else if( orientation == 2 ) {

    videoCamera.outputImageOrientation = UIInterfaceOrientationPortraitUpsideDown;

    movieWriter = [[GPUImageMovieWriter alloc] initWithMovieURL:self.moviePath size:CGSizeMake(480, 640)];

}
else if( orientation == 3 ) {

    //videoCamera.outputImageOrientation = UIInterfaceOrientationLandscapeRight;

    movieWriter = [[GPUImageMovieWriter alloc] initWithMovieURL:self.moviePath size:CGSizeMake(640, 480)];

}
else {

    //videoCamera.outputImageOrientation = UIInterfaceOrientationLandscapeLeft;

    movieWriter = [[GPUImageMovieWriter alloc] initWithMovieURL:self.moviePath size:CGSizeMake(640, 480)];

}

[videoCamera addTarget:filter];

[filter addTarget:videoWindow];

[filter addTarget:movieWriter];

Thanks for the feedback, nice software.

BradLarson commented 12 years ago

The camera is mounted landscape left, so if you want to display that in a portrait view, it needs to be rotated. The outputImageOrientation property lets you specify the desired orientation of the interface you'll be displaying the camera feed into. Without that set, it just passes the camera input into the filters without rotation, and the image will appear in landscape left within a portrait orientation.

What you're trying to do in that third case, if I understand correctly, is to take the camera input and record it as landscape video while displaying it within a portrait interface. One way to do that would be to have a dummy filter after the camera input that only goes to the view, not to the movie. For that filter, explicitly use -setInputRotation:atIndex: with an index of 0 and a rotation of kGPUImageRotateRight. Every filter can apply rotation as part of its actions now, so you can just do this manually if you want two different rotations as outputs.

OlyRice commented 12 years ago

Thanks for the feedback Brad, I think I understand what you are saying. I am going to apply the rotation to the filter and UIView using setInputRotation:atIndex.

Cheers Oliver

tugberkgunver commented 8 years ago

Hi please help me. UIInterfaceOrientationLandscapeRight my video but save and output is always Vertical.

// // CameraViewController.m // AkcarayGreenScreen // // Created by Burçin Azaklı on 02/03/15. // Copyright (c) 2015 Artechin Production. All rights reserved. //

import "Video.h"

import "VideoPlay.h"

import <AssetsLibrary/ALAssetsLibrary.h>

@interface Video ()

@end

@implementation Video

pragma mark - View lifecycle

}

@end