From 419d7b68c314b3a5e21a78d2e18a7655d16ce200 Mon Sep 17 00:00:00 2001 From: Joshua Moerman Date: Wed, 20 Apr 2016 11:40:57 +0100 Subject: [PATCH] (committing very old stuff) Generates video --- VideoGeneration.xcodeproj/project.pbxproj | 2 + VideoGeneration/main.m | 112 ++++++++++++++++++++-- 2 files changed, 106 insertions(+), 8 deletions(-) diff --git a/VideoGeneration.xcodeproj/project.pbxproj b/VideoGeneration.xcodeproj/project.pbxproj index bf0089e..fef6690 100644 --- a/VideoGeneration.xcodeproj/project.pbxproj +++ b/VideoGeneration.xcodeproj/project.pbxproj @@ -152,6 +152,7 @@ ALWAYS_SEARCH_USER_PATHS = NO; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; @@ -189,6 +190,7 @@ ALWAYS_SEARCH_USER_PATHS = NO; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; diff --git a/VideoGeneration/main.m b/VideoGeneration/main.m index 53a239f..cd146f6 100644 --- a/VideoGeneration/main.m +++ b/VideoGeneration/main.m @@ -6,17 +6,113 @@ // Copyright (c) 2014 Joshua Moerman. All rights reserved. // -#import +@import Foundation; +@import AVFoundation; +@import CoreGraphics; +#import -int main(int argc, const char * argv[]) -{ +static const size_t w = 1280; +static const size_t h = 800; +double length(double x, double y){ + return sqrt(x*x + y*y); +} + +@interface Generator : NSObject{ + double* values; +} +- (void)fillBuffer:(CVPixelBufferRef)buffer; +@end + +@implementation Generator + +- (id)init{ + if(self = [super init]){ + values = calloc(3*w*h, sizeof(double)); + for(size_t y = 0; y < h; ++y){ + for(size_t x = 0; x < w; ++x){ + values[3*(x + y*w) + 0] = x / (double)(w-1); + values[3*(x + y*w) + 1] = y / (double)(h-1); + values[3*(x + y*w) + 2] = 0.5; + } + } + } + return self; +} + +- (void)dealloc{ + free(values); +} + +- (void)fillBuffer:(CVPixelBufferRef)image{ + for(size_t y = 0; y < h; ++y){ + for(size_t x = 0; x < w; ++x){ + for(size_t c = 0; c < 3; ++c){ + double r = 4.0 - 0.1*length(x - 0.5*w, y - 0.5*h) / length(0.5*w, 0.5*h); + double v = values[3*(x + y*w) + c]; + values[c + 3*(x + y*w)] = r*v*(1.0 - v); + } + } + } + + CVPixelBufferLockBaseAddress(image, 0); + UInt32* data = CVPixelBufferGetBaseAddress(image); + assert(data); + for(size_t y = 0; y < h; ++y){ + for(size_t x = 0; x < w; ++x){ + uint8_t bb = 255*values[3*(x + y*w) + 0]; + uint8_t gb = 255*values[3*(x + y*w) + 1]; + uint8_t rb = 255*values[3*(x + y*w) + 2]; + uint8_t ab = 255; + data[x + y*1280] = ab | (rb << 8) | (gb << 16) | (bb << 24); + } + } + CVPixelBufferUnlockBaseAddress(image, 0); +} + +@end + +static void do_it(){ + [[NSFileManager defaultManager] removeItemAtURL:[NSURL fileURLWithPath:@"test.mov"] error:nil]; + + AVAssetWriter* asset = [AVAssetWriter assetWriterWithURL:[NSURL fileURLWithPath:@"test.mov"] fileType:AVFileTypeQuickTimeMovie error:nil]; + AVAssetWriterInput* assetInput = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeVideo outputSettings:@{AVVideoCodecKey: AVVideoCodecH264, AVVideoWidthKey: @1280, AVVideoHeightKey: @800}]; + NSDictionary *sourcePixelBufferAttributesDictionary = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithInt:kCVPixelFormatType_32ARGB], kCVPixelBufferPixelFormatTypeKey, nil]; + AVAssetWriterInputPixelBufferAdaptor* adaptor = [AVAssetWriterInputPixelBufferAdaptor assetWriterInputPixelBufferAdaptorWithAssetWriterInput:assetInput sourcePixelBufferAttributes:sourcePixelBufferAttributesDictionary]; + assert(asset && assetInput && adaptor && [asset canAddInput:assetInput]); + + [asset addInput:assetInput]; + [asset startWriting]; + [asset startSessionAtSourceTime:kCMTimeZero]; + assert(adaptor.pixelBufferPool); + + Generator* gen = [[Generator alloc] init]; + + CMTime duration = CMTimeMake(1, 30); + CMTime current = CMTimeMake(0, 30); + for(int i = 0; i < 300; ++i){ + while(!assetInput.readyForMoreMediaData) [NSThread sleepForTimeInterval:0.005]; + + CVPixelBufferRef image = nil; + CVReturn ret = CVPixelBufferPoolCreatePixelBuffer(kCFAllocatorDefault, adaptor.pixelBufferPool, &image); + assert(ret == kCVReturnSuccess && image); + + [gen fillBuffer:image]; + [adaptor appendPixelBuffer:image withPresentationTime:current]; + + CVPixelBufferRelease(image); + + current = CMTimeAdd(current, duration); + } + + [assetInput markAsFinished]; + [asset finishWriting]; +} + +int main(int argc, const char * argv[]){ @autoreleasepool { - - // insert code here... - NSLog(@"Hello, World!"); - + do_it(); } - return 0; + return 0; }