SlideShare ist ein Scribd-Unternehmen logo
1 von 68
Stupid Video Tricks 
Chris Adamson • @invalidname 
CocoaConf Las Vegas • August, 2014
AV Foundation 
• Framework for working with time-based media 
• Audio, video, timed text (captions / subtitles), 
timecode 
• iOS 4.0 and up, Mac OS X 10.7 (Lion) and up 
• Replacing QuickTime on Mac
Ordinary AV Foundation stuff 
• Playback: AVAsset + AVPlayer 
• Capture to file: AVCaptureSession + 
AVCaptureDeviceInput + 
AVCaptureMovieFileOutput 
• Editing: AVComposition + AVExportSession
But Why Be Ordinary? 
http://www.crunchyroll.com/my-ordinary-life
Introductory Trick 
• AVPlayerLayer and 
AVCaptureVideoPreviewLayer are subclasses of 
CALayer 
• We can do lots of neat things with CALayers
Demo
Make an AVPlayerLayer 
self.player = [AVPlayer playerWithPlayerItem: 
[AVPlayerItem playerItemWithAsset:self.asset]]; 
self.playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.player]; 
self.playerLayer.videoGravity = AVLayerVideoGravityResizeAspect; 
[self.playerView.layer addSublayer:self.playerLayer]; 
self.playerLayer.frame = self.playerView.bounds;
Animate the layer 
CABasicAnimation *animateRotation; 
animateRotation = [CABasicAnimation animationWithKeyPath:@"transform"]; 
CATransform3D layerTransform = self.playerLayer.transform; 
layerTransform = CATransform3DRotate(layerTransform, M_PI, 1.0, 1.0, 0.0); 
animateRotation.toValue = [NSValue valueWithCATransform3D:layerTransform]; 
animateRotation.duration = 2.0; 
animateRotation.removedOnCompletion = NO; 
animateRotation.fillMode = kCAFillModeForwards; 
animateRotation.repeatCount = 1000; 
animateRotation.cumulative = YES; 
[self.playerLayer addAnimation:animateRotation forKey:@"transform"];
Going Deeper 
http://www.crunchyroll.com/angel-beats
AV Foundation 
Core Audio Core Media 
Core Video 
Video Toolbox
AV Foundation 
Core Audio Core Media 
Core Video 
Video Toolbox
AV Foundation 
Core Audio Core Media 
Core Video 
Video Toolbox
Core Media
Core Media 
• Opaque types to represent time: CMTime, 
CMTimeRange 
• Opaque types to represent media samples and their 
contents: CMSampleBuffer, CMBlockBuffer, 
CMFormatDescription
CMSampleBuffer 
• Provides timing information for one or more samples: 
when does this play and for how long? 
• Contains either 
• CVImageBuffer – visual data (video frames) 
• CMBlockBuffer — arbitrary data (sound, subtitles, 
timecodes)
Use & Abuse of 
CMSampleBuffers 
• AVCaptureDataOutput provides CMSampleBuffers 
in sample delegate callback 
• AVAssetReader provides CMSampleBuffers read 
from disk 
• AVAssetWriter accepts CMSampleBuffers to write 
to disk
Demo
How the Heck Does that 
Work? 
• Movies have tracks, tracks have media, media have 
sample data 
• All contents of a QuickTime file are defined in the 
QuickTime File Format documentation
Media Data Atom Types 
Subtitle Media 
Subtitle Sample Data 
Subtitle sample data consists of a 16-‐bit word that specifies the length (number of bytes) of the subtitle text, 
followed by the subtitle text and then by optional sample extensions. The subtitle text is Unicode text, encoded 
either as UTF-‐8 text or UTF-‐16 text beginning with a UTF-‐16 BYTE ORDER MARK ('uFEFF') in big or little endian 
order. There is no null termination for the text. 
Following the subtitle text, there may be one or more atoms containing additional information for selecting 
and drawing the subtitle. 
Table 4-‐12 (page 203) lists the currently defined subtitle sample extensions. 
Table 4-12 Subtitle sample extensions 
Subtitle Description 
sample 
extension 
The presence of this atom indicates that the sample contains a forced subtitle. This 
extension has no data. 
Forced subtitles are shown automatically when appropriate without any interaction 
from the user. If any sample contains a forced subtitle, the Some Samples Are Forced 
(0x40000000) flag must also be set in the display flags. 
Consider an example where the primary language of the content is English, but the 
user has chosen to listen to a French dub of the audio. If a scene in the video displays 
something in English that is important to the plot or the content (such as a newspaper 
headline), a forced subtitle displays the content translated into French. In this case, the 
subtitle is linked (“forced”) to the French language sound track. 
If this atom is not present, the subtitle is typically simply a translation of the audio 
content, which a user can choose to display or hide. 
'frcd' 
Style information for the subtitle. This atom allows you to override the default style in 
the sample description or to define more than one style within a sample. See “Subtitle 
Style Atom” (page 204). 
'styl' 
Override of the default text box for this sample. Used only if the 0x20000000 display 
flag is set in the sample description and, in that case, only the top is considered. Even 
so, all fields should be set as though they are considered. See “Text Box atom” (page 
205). 
'tbox' 
Text wrap. Set the one-‐byte payload to 0x00 for no wrapping or 0x01 for automatic 
soft wrapping. 
'twrp' 
2014-‐02-‐11 | Copyright © 2004, 2014 Apple Inc. All Rights Reserved. 
203
Subtitle Sample Data! 
Subtitle sample data consists of a 16-bit word that 
specifies the length (number of bytes) of the subtitle text, 
followed by the subtitle text and then by optional sample 
extensions. The subtitle text is Unicode text, encoded 
either as UTF-8 text or UTF-16 text beginning with a 
UTF-16 BYTE ORDER MARK ('uFEFF') in big or little 
endian order. There is no null termination for the text.! 
Following the subtitle text, there may be one or more 
atoms containing additional information for selecting and 
drawing the subtitle.!
I Iz In Ur Subtitle Track… 
AVAssetTrack *subtitleTrack = [[asset tracksWithMediaType: AVMediaTypeSubtitle] 
firstObject]; 
! 
AVAssetReaderTrackOutput *subtitleTrackOutput = 
[AVAssetReaderTrackOutput assetReaderTrackOutputWithTrack:subtitleTrack 
outputSettings:nil]; 
! 
// ... 
while (reading) { 
CMSampleBufferRef sampleBuffer = [subtitleTrackOutput copyNextSampleBuffer]; 
if (sampleBuffer == NULL) { 
AVAssetReaderStatus status = subtitleReader.status; 
if ((status == AVAssetReaderStatusCompleted) || 
(status == AVAssetReaderStatusFailed) || 
(status == AVAssetReaderStatusCancelled)) { 
reading = NO; 
NSLog (@"ending with reader status %d", status); 
} 
} else { 
CMTime presentationTime = CMSampleBufferGetPresentationTimeStamp(sampleBuffer) ; 
CMTime duration = CMSampleBufferGetDuration(sampleBuffer);
…Readin Ur CMBlockBuffers 
CMBlockBufferRef blockBuffer = CMSampleBufferGetDataBuffer(sampleBuffer); 
size_t dataSize =CMBlockBufferGetDataLength(blockBuffer); 
if (dataSize > 0) { 
UInt8* data = malloc(dataSize); 
OSStatus cmErr = CMBlockBufferCopyDataBytes (blockBuffer, 
0, 
dataSize, 
data);
Subtitle Summary 
• AVAssetReaderOutput provides CMSampleBuffers 
• Get timing info with 
CMSampleBufferGetPresentationTimestamp() 
and CMSampleGetDuration() 
• Get raw data with CMBlockBufferGet…() functions 
• Have at it
Writing Samples
Demo
Screen Recording 
• Run an NSTimer to get screenshots 
• Many ways to do this, such as drawing your 
CALayer to a CGContext, make it a UIImage 
• Convert image data into a CVPixelBuffer 
• Use AVAssetWriterPixelBufferAdaptor to write pixel 
buffer and presentation time to an AVAssetWriterInput
Make CVPixelBuffer 
CVPixelBufferRef pixelBuffer = NULL;! 
CFDataRef imageData=! 
CGDataProviderCopyData(CGImageGetDataProvider(image));! 
cvErr = CVPixelBufferCreateWithBytes(kCFAllocatorDefault,! 
! !! ! ! ! ! ! ! ! ! FRAME_WIDTH,! 
! !! ! ! ! ! ! ! ! ! FRAME_HEIGHT,! 
! !! ! ! ! ! ! ! ! ! kCVPixelFormatType_32BGRA,! 
! !! ! ! ! ! ! ! ! ! (void*)CFDataGetBytePtr(imageData),! 
! !! ! ! ! ! ! ! ! ! CGImageGetBytesPerRow(image),! 
! !! ! ! ! ! ! ! ! ! NULL,! 
! !! ! ! ! ! ! ! ! ! NULL,! 
! !! ! ! ! ! ! ! ! ! NULL,! 
! !! ! ! ! ! ! ! ! ! &pixelBuffer);!
Compute Presentation Time 
CFAbsoluteTime thisFrameWallClockTime = CFAbsoluteTimeGetCurrent();! 
CFTimeInterval elapsedTime = thisFrameWallClockTime -! 
self.firstFrameWallClockTime;! 
CMTime presentationTime = CMTimeMake (elapsedTime * TIME_SCALE,! 
TIME_SCALE);!
Append to 
AVAssetWriterInput 
BOOL appended = [self.assetWriterPixelBufferAdaptor! 
appendPixelBuffer:pixelBuffer! 
withPresentationTime:presentationTime];!
Audio 
http://indignation.deviantart.com/art/Hatsune-Miku-headphones-254724145
AV Foundation 
Core Audio Core Media 
Core Video 
Video Toolbox
Core Audio Core Media
Core Audio Core Media 
• Reading: 
CMSampleBufferGetAudioBufferListWithRetain 
edBlockBuffer(), 
CMSampleBufferGetAudioStreamPacketDescript 
ions() 
• Writing: 
CMSampleBufferSetDataBufferFromAudioBuffer 
List(), 
CMAudioSampleBufferCreateWithPacketDescrip 
tions()
Core Audio Core Media 
• Reading: 
CMSampleBufferGetAudioBufferListWithRetain 
edBlockBuffer(), 
CMSampleBufferGetAudioStreamPacketDescript 
ions() 
• Writing: 
CMSampleBufferSetDataBufferFromAudioBuffer 
List(), 
CMAudioSampleBufferCreateWithPacketDescrip 
tions()
Potential Uses 
• Run captured / read-in audio through effects in an 
AUGraph 
• See “AVCaptureAudioDataOutput To AudioUnit” 
examples (iOS & OS X) from WWDC 2012 
• May make more sense for audio-oriented apps to do 
capture / file reads entirely from Core Audio
Video 
http://www.crunchyroll.com/angel-beats
AV Foundation 
Core Audio Core Media 
Core Video 
Video Toolbox
Core Media Core Video
Core Media Core Video 
• CMSampleBuffers provide CVImageBuffers 
• Two sub-types: CVPixelBufferRef, 
CVOpenGLESTextureRef 
• Pixel buffers allow us to work with bitmaps, via 
CVPixelBufferGetBaseAddress() 
• Note: Must wrap calls with 
CVPixelBufferLockBaseAddress(), 
CVPixelBufferUnlockBaseAddress()
Use & Abuse of 
CVImageBuffers 
• Can be used to create Core Image CIImages 
• iOS: -[CIImage imageWithCVPixelBuffer:] 
• OS X: -[CIImage imageWithCVImageBuffer:] 
• CIImages can be used to do lots of stuff…
Demo
Recipe 
• Create CIContext from EAGLContext 
• Create CIFilter 
• During capture callback 
• Convert pixel buffer to CIImage 
• Run through filter 
• Draw to CIContext
Set Up GLKView 
if (! self.glkView.context.API != kEAGLRenderingAPIOpenGLES2) { 
EAGLContext *eagl2Context = [[EAGLContext alloc] 
initWithAPI:kEAGLRenderingAPIOpenGLES2]; 
self.glkView.context = eagl2Context; 
} 
self.glContext = self.glkView.context; 
// we'll do the updating, thanks 
self.glkView.enableSetNeedsDisplay = NO;
Make CIContext 
// make CIContext from GL context, clearing out default color space 
self.ciContext = [CIContext contextWithEAGLContext:self.glContext 
options:@{kCIContextWorkingColorSpace : 
[NSNull null]} ]; 
[self.glkView bindDrawable]; 
// from Core Image Fun House: 
_glkDrawBounds = CGRectZero; 
_glkDrawBounds.size.width = self.glkView.drawableWidth; 
_glkDrawBounds.size.height = self.glkView.drawableHeight; 
See also iOS Core Image Fun House from WWDC 2013
Ask for RGB in Callbacks 
self.videoDataOutput = [[AVCaptureVideoDataOutput alloc] init]; 
[self.videoDataOutput setSampleBufferDelegate:self 
queue:self.videoDataOutputQueue]; 
[self.captureSession addOutput: self.videoDataOutput]; 
NSDictionary *videoSettings = @{ 
(id) kCVPixelBufferPixelFormatTypeKey: 
@(kCVPixelFormatType_32BGRA)}; 
[self.videoDataOutput setVideoSettings:videoSettings]; 
Note: 32BGRA and two flavors of 4:2:0 YCbCr are the only valid 
pixel formats for video capture on iOS
Create CIFilter 
self.pixellateFilter = [CIFilter filterWithName:@"CIPixellate"]; 
[self.pixellateFilter setValue:[CIVector vectorWithX:100.0 Y:100.0] 
forKey:@"inputCenter"]; 
[self setPixellateFilterScale:self.pixellationScaleSlider.value];
Set CIFilter Params 
- (IBAction)handleScaleSliderValueChanged:(UISlider*) sender { 
[self setPixellateFilterScale:sender.value]; 
} 
! 
-(void) setPixellateFilterScale: (CGFloat) scale { 
[self.pixellateFilter setValue:[NSNumber numberWithFloat:scale] 
forKey:@"inputScale"]; 
}
Callback: Apply Filter 
CVImageBufferRef cvBuffer = 
CMSampleBufferGetImageBuffer(sampleBuffer); 
CVPixelBufferLockBaseAddress(cvBuffer,0); 
CIImage *bufferCIImage = [CIImage imageWithCVPixelBuffer:cvBuffer]; 
! 
[self.pixellateFilter setValue:bufferCIImage 
forKey:kCIInputImageKey]; 
bufferCIImage = [self.pixellateFilter 
valueForKey:kCIOutputImageKey];
Callback: Draw to GLKView 
[self.glkView bindDrawable]; 
if (self.glContext != [EAGLContext currentContext]) { 
[EAGLContext setCurrentContext: self.glContext]; 
} 
// drawing code here is from WWDC 2013 iOS Core Image Fun House 
// clear eagl view to grey 
glClearColor(0.5, 0.5, 0.5, 1.0); 
glClear(GL_COLOR_BUFFER_BIT); 
// set the blend mode to "source over" so that CI will use that 
glEnable(GL_BLEND); 
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); 
CGRect drawRect = bufferCIImage.extent; 
[self.ciContext drawImage:bufferCIImage 
inRect:self.glkDrawBounds 
fromRect:drawRect]; 
[self.glkView display]; 
CVPixelBufferUnlockBaseAddress(cvBuffer, 0);
Recap 
from 
camera CIFilter 
CVPixelBuffer CIImage CIImage 
CIContext 
-[CIContext 
drawImage: 
fromRect: 
inRect:] 
(OpenGL 
drawing) 
+[CIImage 
imageWith 
CVPixelBuff 
er:]
Recap 
from 
camera CIFilter 
+[CIImage 
imageWith 
CVPixelBuff 
er:] 
CVPixelBuffer CIImage CIImage 
CIContext 
-[CIContext 
drawImage: 
fromRect: 
inRect:] 
CVPixelBuffer 
(optional) 
AVAsset 
Writer 
(OpenGL Output 
drawing)
By the way…
There are lots of CIFilters 
CICategoryBlur 
! ! CIBoxBlur 
! ! CIDiscBlur 
! ! CIGaussianBlur 
! ! CIMedianFilter 
! ! CIMotionBlur 
! ! CINoiseReduction 
! ! CIZoomBlur 
CICategoryColorAdjust 
ment 
! ! CIColorClamp 
! ! CIColorControls 
! ! CIColorMatrix 
! ! CIColorPolynomial 
! ! CIExposureAdjust 
! ! CIGammaAdjust 
! ! CIHueAdjust 
! ! 
CILinearToSRGBToneCurv 
e 
! ! 
CISRGBToneCurveToLinea 
r 
! ! CITemperatureAndTint 
! ! CIToneCurve 
! ! CIVibrance 
! ! CIWhitePointAdjust 
CICategoryColorEffect 
! ! CIColorCrossPolynomial 
! ! CIColorCube 
! ! 
CIColorCubeWithColorSp 
ace 
! ! CIColorInvert 
! ! CIColorMap 
! ! CIColorMonochrome 
! ! CIColorPosterize 
! ! CIFalseColor 
! ! CIMaskToAlpha 
! ! CIMaximumComponent 
! ! CIMinimumComponent 
! ! CIPhotoEffectChrome 
! ! CIPhotoEffectFade 
! ! CIPhotoEffectInstant 
! ! CIPhotoEffectMono 
! ! CIPhotoEffectNoir 
! ! CIPhotoEffectProcess 
! ! CIPhotoEffectTonal 
! ! CIPhotoEffectTransfer 
! ! CISepiaTone 
! ! CIVignette 
! ! CIVignetteEffect 
CICategoryComposite 
Operation 
! ! CIAdditionCompositing 
! ! CIColorBlendMode 
! ! CIColorBurnBlendMode 
! ! CIColorDodgeBlendMode 
! ! CIDarkenBlendMode 
! ! CIDifferenceBlendMode 
! ! CIExclusionBlendMode 
! ! CIHardLightBlendMode 
! ! CIHueBlendMode 
! ! CILightenBlendMode 
! ! CILuminosityBlendMode 
! ! CIMaximumCompositing 
! ! CIMinimumCompositing 
! ! CIMultiplyBlendMode 
! ! CIMultiplyCompositing 
! ! CIOverlayBlendMode 
! ! CISaturationBlendMode 
! ! CIScreenBlendMode 
! ! CISoftLightBlendMode 
! ! 
CISourceAtopCompositin 
g 
! ! CISourceInCompositing 
! ! CISourceOutCompositing 
! ! 
CISourceOverCompositin 
g 
CICategoryDistortionE 
ffect 
! ! CIBumpDistortion 
! ! CIBumpDistortionLinear 
! ! 
CICircleSplashDistorti 
on 
! ! CICircularWrap 
! ! CIDroste 
! ! 
CIDisplacementDistorti 
on 
! ! CIGlassDistortion 
! ! CIGlassLozenge 
! ! CIHoleDistortion 
! ! CILightTunnel 
! ! CIPinchDistortion 
! ! CIStretchCrop 
! ! CITorusLensDistortion 
! ! CITwirlDistortion 
! ! CIVortexDistortion 
CICategoryGenerator 
! CICheckerboardGenerator 
! ! 
CIConstantColorGenerat 
or 
! ! 
CILenticularHaloGenera 
tor 
! ! CIQRCodeGenerator 
! ! CIRandomGenerator 
! ! CIStarShineGenerator 
! ! CIStripesGenerator 
! ! CISunbeamsGenerator 
CICategoryGeometryA 
djustment 
! ! CIAffineTransform 
! ! CICrop 
! ! 
CILanczosScaleTransfor 
m 
! ! CIPerspectiveTransform 
! ! 
CIPerspectiveTransform 
WithExtent 
! ! CIStraightenFilter 
CICategoryGradient 
! ! CIGaussianGradient 
! ! CILinearGradient 
! ! CIRadialGradient 
! ! CISmoothLinearGradient 
CICategoryHalftoneEff 
ect
Demo
CIColorCube 
Maps colors from one RGB “cube” to another 
http://en.wikipedia.org/wiki/RGB_color_space
Using CIColorCube 
CIColorCube maps green(-ish) colors to 0.0 alpha, 
all other colors pass through
CISourceOverCompositing 
inputBackgroundImage inputImage 
outputImage
consCt unsigInedC int sioze = 6l4; orCube Data 
size_t cubeDataSize = size * size * size * sizeof (float) * 4; 
float *keyCubeData = (float *)malloc (cubeDataSize); 
float rgb[3], hsv[3], *keyC = keyCubeData; 
// Populate cube with a simple gradient going from 0 to 1 
for (int z = 0; z < size; z++){ 
rgb[2] = ((double)z)/(size-1); // Blue value 
for (int y = 0; y < size; y++){ 
rgb[1] = ((double)y)/(size-1); // Green value 
for (int x = 0; x < size; x ++){ 
rgb[0] = ((double)x)/(size-1); // Red value ! 
// Convert RGB to HSV 
// You can find publicly available rgbToHSV functions on the Internet ! 
RGBtoHSV(rgb[0], rgb[1], rgb[2], 
&hsv[0], &hsv[1], &hsv[2]); ! 
// RGBtoHSV uses 0 to 360 for hue, while UIColor (used above) uses 0 to 1. 
hsv[0] /= 360.0; 
// Use the hue value to determine which to make transparent 
// The minimum and maximum hue angle depends on 
// the color you want to remove 
bool keyed = (hsv[0] > minHueAngle && hsv[0] < maxHueAngle) && 
(hsv[1] > minSaturation && hsv[1] < maxSaturation) && 
(hsv[2] > minBrightness && hsv[2] < maxBrightness); 
float alpha = keyed ? 0.0f : 1.0f; 
// re-calculate c pointer 
keyC = (((z * size * size) + (y * size) + x) * sizeof(float)) + keyCubeData; 
// Calculate premultiplied alpha values for the cube 
keyC[0] = rgb[0] * alpha; 
keyC[1] = rgb[1] * alpha; 
keyC[2] = rgb[2] * alpha; 
keyC[3] = alpha; 
} 
} 
} 
See “Chroma Key Filter Recipe” in Core Image Programming Guide
Create CIColorCube from 
mapping data 
// Create memory with the cube data 
NSData *data = [NSData dataWithBytesNoCopy:keyCubeData 
length:cubeDataSize 
freeWhenDone:YES]; 
self.colorCubeFilter = [CIFilter filterWithName:@"CIColorCube"]; 
[self.colorCubeFilter setValue:[NSNumber numberWithInt:size] 
forKey:@"inputCubeDimension"]; 
// Set data for cube 
[self.colorCubeFilter setValue:data forKey:@"inputCubeData"];
Create 
CISourceOverCompositing 
// source over filter 
self.sourceOverFilter = [CIFilter filterWithName: 
@"CISourceOverCompositing"]; 
CIImage *backgroundCIImage = [CIImage imageWithCGImage: 
self.backgroundImage.CGImage]; 
[self.sourceOverFilter setValue:backgroundCIImage 
forKeyPath:@"inputBackgroundImage"];
Apply Filters in Delegate 
Callback 
CIImage *bufferCIImage = [CIImage imageWithCVPixelBuffer: 
cvBuffer]; 
[self.colorCubeFilter setValue:bufferCIImage 
forKey:kCIInputImageKey]; 
CIImage *keyedCameraImage = [self.colorCubeFilter valueForKey: 
kCIOutputImageKey]; 
[self.sourceOverFilter setValue:keyedCameraImage 
forKeyPath:kCIInputImageKey]; 
CIImage *compositedImage = [self.sourceOverFilter valueForKeyPath: 
kCIOutputImageKey]; 
Then draw compositedImage to CIContext as before
More Fun with Filters 
• Alpha Matte: Use CIColorCube to map green to white 
(or transparent), everything else to black 
• Can then use this with other filters to do edge work 
on the “foreground” object 
• Be sure that any filters you use are of category 
CICategoryVideo.
More Fun With CIContexts 
• Can write effected pixels to a movie file with 
AVAssetWriterOutput 
• Use base address of CIContext to create a new 
CVPixelBuffer, use this and timing information to 
create a CMSampleBuffer 
• AVAssetWriterInputPixelBufferAdaptor makes this 
slightly easier
Recap 
• Most good tricks start with CMSampleBuffers 
• Audio: convert to Core Audio types 
• Video: convert to CIImage 
• Other: get CMBlockBuffer and parse by hand
Further Info 
and http://devforums.apple.com/
Q&A 
Slides at http://www.slideshare.net/invalidname/ 
See comments there for link to source code 
! 
invalidname [at] gmail.com 
@invalidname (Twitter, app.net) 
http://www.subfurther.com/blog

Weitere ähnliche Inhalte

Was ist angesagt?

Video Killed the Rolex Star (CocoaConf Columbus, July 2015)
Video Killed the Rolex Star (CocoaConf Columbus, July 2015)Video Killed the Rolex Star (CocoaConf Columbus, July 2015)
Video Killed the Rolex Star (CocoaConf Columbus, July 2015)Chris Adamson
 
AVFoundation @ TACOW 2013 05 14
AVFoundation @ TACOW 2013 05 14AVFoundation @ TACOW 2013 05 14
AVFoundation @ TACOW 2013 05 14Ryder Mackay
 
Building A Streaming Apple TV App (CocoaConf San Jose, Nov 2016)
Building A Streaming Apple TV App (CocoaConf San Jose, Nov 2016)Building A Streaming Apple TV App (CocoaConf San Jose, Nov 2016)
Building A Streaming Apple TV App (CocoaConf San Jose, Nov 2016)Chris Adamson
 
Building Modern Audio Apps with AVAudioEngine
Building Modern Audio Apps with AVAudioEngineBuilding Modern Audio Apps with AVAudioEngine
Building Modern Audio Apps with AVAudioEngineBob McCune
 
Introduction to the Roku SDK
Introduction to the Roku SDKIntroduction to the Roku SDK
Introduction to the Roku SDKChris Adamson
 
Master Video with AV Foundation
Master Video with AV FoundationMaster Video with AV Foundation
Master Video with AV FoundationBob McCune
 
Get On The Audiobus (CocoaConf Atlanta, November 2013)
Get On The Audiobus (CocoaConf Atlanta, November 2013)Get On The Audiobus (CocoaConf Atlanta, November 2013)
Get On The Audiobus (CocoaConf Atlanta, November 2013)Chris Adamson
 
CocoaConf Chicago 2017: Media Frameworks and Swift: This Is Fine
CocoaConf Chicago 2017: Media Frameworks and Swift: This Is FineCocoaConf Chicago 2017: Media Frameworks and Swift: This Is Fine
CocoaConf Chicago 2017: Media Frameworks and Swift: This Is FineChris Adamson
 
Media Frameworks Versus Swift (Swift by Northwest, October 2017)
Media Frameworks Versus Swift (Swift by Northwest, October 2017)Media Frameworks Versus Swift (Swift by Northwest, October 2017)
Media Frameworks Versus Swift (Swift by Northwest, October 2017)Chris Adamson
 
Managing Eclipse Preferences for Teams (EclipseCon 2011)
Managing Eclipse Preferences for Teams (EclipseCon 2011)Managing Eclipse Preferences for Teams (EclipseCon 2011)
Managing Eclipse Preferences for Teams (EclipseCon 2011)Netcetera
 
iOS Media APIs (MobiDevDay Detroit, May 2013)
iOS Media APIs (MobiDevDay Detroit, May 2013)iOS Media APIs (MobiDevDay Detroit, May 2013)
iOS Media APIs (MobiDevDay Detroit, May 2013)Chris Adamson
 
KKBOX WWDC17 Airplay 2 - Dolphin
KKBOX WWDC17 Airplay 2 - DolphinKKBOX WWDC17 Airplay 2 - Dolphin
KKBOX WWDC17 Airplay 2 - DolphinLiyao Chen
 
Game programming with Groovy
Game programming with GroovyGame programming with Groovy
Game programming with GroovyJames Williams
 
Creating Perl modules with Dist::Zilla
Creating Perl modules with Dist::ZillaCreating Perl modules with Dist::Zilla
Creating Perl modules with Dist::ZillaMark Gardner
 
Get On The Audiobus (CocoaConf Boston, October 2013)
Get On The Audiobus (CocoaConf Boston, October 2013)Get On The Audiobus (CocoaConf Boston, October 2013)
Get On The Audiobus (CocoaConf Boston, October 2013)Chris Adamson
 
Pragmatic plone projects
Pragmatic plone projectsPragmatic plone projects
Pragmatic plone projectsAndreas Jung
 

Was ist angesagt? (20)

Video Killed the Rolex Star (CocoaConf Columbus, July 2015)
Video Killed the Rolex Star (CocoaConf Columbus, July 2015)Video Killed the Rolex Star (CocoaConf Columbus, July 2015)
Video Killed the Rolex Star (CocoaConf Columbus, July 2015)
 
AVFoundation @ TACOW 2013 05 14
AVFoundation @ TACOW 2013 05 14AVFoundation @ TACOW 2013 05 14
AVFoundation @ TACOW 2013 05 14
 
Building A Streaming Apple TV App (CocoaConf San Jose, Nov 2016)
Building A Streaming Apple TV App (CocoaConf San Jose, Nov 2016)Building A Streaming Apple TV App (CocoaConf San Jose, Nov 2016)
Building A Streaming Apple TV App (CocoaConf San Jose, Nov 2016)
 
Building Modern Audio Apps with AVAudioEngine
Building Modern Audio Apps with AVAudioEngineBuilding Modern Audio Apps with AVAudioEngine
Building Modern Audio Apps with AVAudioEngine
 
Introduction to the Roku SDK
Introduction to the Roku SDKIntroduction to the Roku SDK
Introduction to the Roku SDK
 
Master Video with AV Foundation
Master Video with AV FoundationMaster Video with AV Foundation
Master Video with AV Foundation
 
Get On The Audiobus (CocoaConf Atlanta, November 2013)
Get On The Audiobus (CocoaConf Atlanta, November 2013)Get On The Audiobus (CocoaConf Atlanta, November 2013)
Get On The Audiobus (CocoaConf Atlanta, November 2013)
 
CocoaConf Chicago 2017: Media Frameworks and Swift: This Is Fine
CocoaConf Chicago 2017: Media Frameworks and Swift: This Is FineCocoaConf Chicago 2017: Media Frameworks and Swift: This Is Fine
CocoaConf Chicago 2017: Media Frameworks and Swift: This Is Fine
 
Media Frameworks Versus Swift (Swift by Northwest, October 2017)
Media Frameworks Versus Swift (Swift by Northwest, October 2017)Media Frameworks Versus Swift (Swift by Northwest, October 2017)
Media Frameworks Versus Swift (Swift by Northwest, October 2017)
 
Managing Eclipse Preferences for Teams (EclipseCon 2011)
Managing Eclipse Preferences for Teams (EclipseCon 2011)Managing Eclipse Preferences for Teams (EclipseCon 2011)
Managing Eclipse Preferences for Teams (EclipseCon 2011)
 
iOS Media APIs (MobiDevDay Detroit, May 2013)
iOS Media APIs (MobiDevDay Detroit, May 2013)iOS Media APIs (MobiDevDay Detroit, May 2013)
iOS Media APIs (MobiDevDay Detroit, May 2013)
 
KKBOX WWDC17 Airplay 2 - Dolphin
KKBOX WWDC17 Airplay 2 - DolphinKKBOX WWDC17 Airplay 2 - Dolphin
KKBOX WWDC17 Airplay 2 - Dolphin
 
Game programming with Groovy
Game programming with GroovyGame programming with Groovy
Game programming with Groovy
 
HTML5 Audio & Video
HTML5 Audio & VideoHTML5 Audio & Video
HTML5 Audio & Video
 
Creating Perl modules with Dist::Zilla
Creating Perl modules with Dist::ZillaCreating Perl modules with Dist::Zilla
Creating Perl modules with Dist::Zilla
 
Get On The Audiobus (CocoaConf Boston, October 2013)
Get On The Audiobus (CocoaConf Boston, October 2013)Get On The Audiobus (CocoaConf Boston, October 2013)
Get On The Audiobus (CocoaConf Boston, October 2013)
 
Dart on server - Meetup 18/05/2017
Dart on server - Meetup 18/05/2017Dart on server - Meetup 18/05/2017
Dart on server - Meetup 18/05/2017
 
AngularDart - Meetup 15/03/2017
AngularDart - Meetup 15/03/2017AngularDart - Meetup 15/03/2017
AngularDart - Meetup 15/03/2017
 
Power of Puppet 4
Power of Puppet 4Power of Puppet 4
Power of Puppet 4
 
Pragmatic plone projects
Pragmatic plone projectsPragmatic plone projects
Pragmatic plone projects
 

Andere mochten auch

What's New in Core Location - WWDC 2015
What's New in Core Location - WWDC 2015What's New in Core Location - WWDC 2015
What's New in Core Location - WWDC 2015Kosuke Ogawa
 
WWDC 2015 情報共有会
WWDC 2015 情報共有会WWDC 2015 情報共有会
WWDC 2015 情報共有会大介 束田
 
UI/UX に影響の大きい watchOS 2 の新機能 3つ
UI/UX に影響の大きい watchOS 2 の新機能 3つUI/UX に影響の大きい watchOS 2 の新機能 3つ
UI/UX に影響の大きい watchOS 2 の新機能 3つShuichi Tsutsumi
 
Building A Streaming Apple TV App (CocoaConf DC, Sept 2016)
Building A Streaming Apple TV App (CocoaConf DC, Sept 2016)Building A Streaming Apple TV App (CocoaConf DC, Sept 2016)
Building A Streaming Apple TV App (CocoaConf DC, Sept 2016)Chris Adamson
 
Firebase: Totally Not Parse All Over Again (Unless It Is) (CocoaConf San Jose...
Firebase: Totally Not Parse All Over Again (Unless It Is) (CocoaConf San Jose...Firebase: Totally Not Parse All Over Again (Unless It Is) (CocoaConf San Jose...
Firebase: Totally Not Parse All Over Again (Unless It Is) (CocoaConf San Jose...Chris Adamson
 
Firebase: Totally Not Parse All Over Again (Unless It Is)
Firebase: Totally Not Parse All Over Again (Unless It Is)Firebase: Totally Not Parse All Over Again (Unless It Is)
Firebase: Totally Not Parse All Over Again (Unless It Is)Chris Adamson
 
Revenge of the 80s: Cut/Copy/Paste, Undo/Redo, and More Big Hits (CocoaConf C...
Revenge of the 80s: Cut/Copy/Paste, Undo/Redo, and More Big Hits (CocoaConf C...Revenge of the 80s: Cut/Copy/Paste, Undo/Redo, and More Big Hits (CocoaConf C...
Revenge of the 80s: Cut/Copy/Paste, Undo/Redo, and More Big Hits (CocoaConf C...Chris Adamson
 
Core Image: The Most Fun API You're Not Using (CocoaConf Columbus 2014)
Core Image: The Most Fun API You're Not Using (CocoaConf Columbus 2014)Core Image: The Most Fun API You're Not Using (CocoaConf Columbus 2014)
Core Image: The Most Fun API You're Not Using (CocoaConf Columbus 2014)Chris Adamson
 
Search APIs in Spotlight and Safari
Search APIs in Spotlight and SafariSearch APIs in Spotlight and Safari
Search APIs in Spotlight and SafariYusuke Kita
 
Contents blocker on iOS9
Contents blocker on iOS9Contents blocker on iOS9
Contents blocker on iOS9toyship
 
Core Image: The Most Fun API You're Not Using, CocoaConf Atlanta, December 2014
Core Image: The Most Fun API You're Not Using, CocoaConf Atlanta, December 2014Core Image: The Most Fun API You're Not Using, CocoaConf Atlanta, December 2014
Core Image: The Most Fun API You're Not Using, CocoaConf Atlanta, December 2014Chris Adamson
 
Audio Unit Extensions 〜オーディオエフェクトのアプリ間共有〜
Audio Unit Extensions 〜オーディオエフェクトのアプリ間共有〜Audio Unit Extensions 〜オーディオエフェクトのアプリ間共有〜
Audio Unit Extensions 〜オーディオエフェクトのアプリ間共有〜Shuichi Tsutsumi
 
とにかく明るいCore Spotlight
とにかく明るいCore Spotlightとにかく明るいCore Spotlight
とにかく明るいCore Spotlight今城 善矩
 
Core Graphics on watchOS 2
Core Graphics on watchOS 2Core Graphics on watchOS 2
Core Graphics on watchOS 2Shuichi Tsutsumi
 
Core Image Tips & Tricks in iOS 9
Core Image Tips & Tricks in iOS 9Core Image Tips & Tricks in iOS 9
Core Image Tips & Tricks in iOS 9Shuichi Tsutsumi
 
watchOS 2 新機能の細かい話
watchOS 2 新機能の細かい話watchOS 2 新機能の細かい話
watchOS 2 新機能の細かい話Shuichi Tsutsumi
 
iOS 9 の新機能 Core Image 編
iOS 9 の新機能 Core Image 編iOS 9 の新機能 Core Image 編
iOS 9 の新機能 Core Image 編Shuichi Tsutsumi
 

Andere mochten auch (19)

What's New in Core Location - WWDC 2015
What's New in Core Location - WWDC 2015What's New in Core Location - WWDC 2015
What's New in Core Location - WWDC 2015
 
Watch connectivity
Watch connectivityWatch connectivity
Watch connectivity
 
20150707 wwdc21cafe
20150707 wwdc21cafe20150707 wwdc21cafe
20150707 wwdc21cafe
 
WWDC 2015 情報共有会
WWDC 2015 情報共有会WWDC 2015 情報共有会
WWDC 2015 情報共有会
 
UI/UX に影響の大きい watchOS 2 の新機能 3つ
UI/UX に影響の大きい watchOS 2 の新機能 3つUI/UX に影響の大きい watchOS 2 の新機能 3つ
UI/UX に影響の大きい watchOS 2 の新機能 3つ
 
Building A Streaming Apple TV App (CocoaConf DC, Sept 2016)
Building A Streaming Apple TV App (CocoaConf DC, Sept 2016)Building A Streaming Apple TV App (CocoaConf DC, Sept 2016)
Building A Streaming Apple TV App (CocoaConf DC, Sept 2016)
 
Firebase: Totally Not Parse All Over Again (Unless It Is) (CocoaConf San Jose...
Firebase: Totally Not Parse All Over Again (Unless It Is) (CocoaConf San Jose...Firebase: Totally Not Parse All Over Again (Unless It Is) (CocoaConf San Jose...
Firebase: Totally Not Parse All Over Again (Unless It Is) (CocoaConf San Jose...
 
Firebase: Totally Not Parse All Over Again (Unless It Is)
Firebase: Totally Not Parse All Over Again (Unless It Is)Firebase: Totally Not Parse All Over Again (Unless It Is)
Firebase: Totally Not Parse All Over Again (Unless It Is)
 
Revenge of the 80s: Cut/Copy/Paste, Undo/Redo, and More Big Hits (CocoaConf C...
Revenge of the 80s: Cut/Copy/Paste, Undo/Redo, and More Big Hits (CocoaConf C...Revenge of the 80s: Cut/Copy/Paste, Undo/Redo, and More Big Hits (CocoaConf C...
Revenge of the 80s: Cut/Copy/Paste, Undo/Redo, and More Big Hits (CocoaConf C...
 
Core Image: The Most Fun API You're Not Using (CocoaConf Columbus 2014)
Core Image: The Most Fun API You're Not Using (CocoaConf Columbus 2014)Core Image: The Most Fun API You're Not Using (CocoaConf Columbus 2014)
Core Image: The Most Fun API You're Not Using (CocoaConf Columbus 2014)
 
Search APIs in Spotlight and Safari
Search APIs in Spotlight and SafariSearch APIs in Spotlight and Safari
Search APIs in Spotlight and Safari
 
Contents blocker on iOS9
Contents blocker on iOS9Contents blocker on iOS9
Contents blocker on iOS9
 
Core Image: The Most Fun API You're Not Using, CocoaConf Atlanta, December 2014
Core Image: The Most Fun API You're Not Using, CocoaConf Atlanta, December 2014Core Image: The Most Fun API You're Not Using, CocoaConf Atlanta, December 2014
Core Image: The Most Fun API You're Not Using, CocoaConf Atlanta, December 2014
 
Audio Unit Extensions 〜オーディオエフェクトのアプリ間共有〜
Audio Unit Extensions 〜オーディオエフェクトのアプリ間共有〜Audio Unit Extensions 〜オーディオエフェクトのアプリ間共有〜
Audio Unit Extensions 〜オーディオエフェクトのアプリ間共有〜
 
とにかく明るいCore Spotlight
とにかく明るいCore Spotlightとにかく明るいCore Spotlight
とにかく明るいCore Spotlight
 
Core Graphics on watchOS 2
Core Graphics on watchOS 2Core Graphics on watchOS 2
Core Graphics on watchOS 2
 
Core Image Tips & Tricks in iOS 9
Core Image Tips & Tricks in iOS 9Core Image Tips & Tricks in iOS 9
Core Image Tips & Tricks in iOS 9
 
watchOS 2 新機能の細かい話
watchOS 2 新機能の細かい話watchOS 2 新機能の細かい話
watchOS 2 新機能の細かい話
 
iOS 9 の新機能 Core Image 編
iOS 9 の新機能 Core Image 編iOS 9 の新機能 Core Image 編
iOS 9 の新機能 Core Image 編
 

Ähnlich wie AV Foundation Tricks

Joost de Wit (Media Distillery) - Technology Update - Watskeburt?!
Joost de Wit (Media Distillery) - Technology Update - Watskeburt?!Joost de Wit (Media Distillery) - Technology Update - Watskeburt?!
Joost de Wit (Media Distillery) - Technology Update - Watskeburt?!Media Perspectives
 
Advanced AV Foundation (CocoaConf, Aug '11)
Advanced AV Foundation (CocoaConf, Aug '11)Advanced AV Foundation (CocoaConf, Aug '11)
Advanced AV Foundation (CocoaConf, Aug '11)Chris Adamson
 
[@NaukriEngineering] Video handlings on apple platforms
[@NaukriEngineering] Video handlings on apple platforms[@NaukriEngineering] Video handlings on apple platforms
[@NaukriEngineering] Video handlings on apple platformsNaukri.com
 
HTML5 vs Silverlight
HTML5 vs SilverlightHTML5 vs Silverlight
HTML5 vs SilverlightMatt Casto
 
Craft 2019 - “The Upside Down” Of The Web - Video technologies
Craft 2019 - “The Upside Down” Of The Web - Video technologiesCraft 2019 - “The Upside Down” Of The Web - Video technologies
Craft 2019 - “The Upside Down” Of The Web - Video technologiesMáté Nádasdi
 
Taking HTML5 video a step further
Taking HTML5 video a step furtherTaking HTML5 video a step further
Taking HTML5 video a step furtherSilvia Pfeiffer
 
HTML5 Multimedia Accessibility
HTML5 Multimedia AccessibilityHTML5 Multimedia Accessibility
HTML5 Multimedia Accessibilitybrucelawson
 
Voice That Matter 2010 - Core Audio
Voice That Matter 2010 - Core AudioVoice That Matter 2010 - Core Audio
Voice That Matter 2010 - Core AudioKevin Avila
 
Galaxy presentation.pptx
Galaxy presentation.pptxGalaxy presentation.pptx
Galaxy presentation.pptxtavo957203
 
#PDR15 - waf, wscript and Your Pebble App
#PDR15 - waf, wscript and Your Pebble App#PDR15 - waf, wscript and Your Pebble App
#PDR15 - waf, wscript and Your Pebble AppPebble Technology
 
Videostream compression in iOS
Videostream compression in iOSVideostream compression in iOS
Videostream compression in iOS*instinctools
 
Symbian OS - Descriptors
Symbian OS - DescriptorsSymbian OS - Descriptors
Symbian OS - DescriptorsAndreas Jakl
 
OSBConf 2015 | Using aws virtual tape library as storage for bacula bareos by...
OSBConf 2015 | Using aws virtual tape library as storage for bacula bareos by...OSBConf 2015 | Using aws virtual tape library as storage for bacula bareos by...
OSBConf 2015 | Using aws virtual tape library as storage for bacula bareos by...NETWAYS
 

Ähnlich wie AV Foundation Tricks (20)

Joost de Wit (Media Distillery) - Technology Update - Watskeburt?!
Joost de Wit (Media Distillery) - Technology Update - Watskeburt?!Joost de Wit (Media Distillery) - Technology Update - Watskeburt?!
Joost de Wit (Media Distillery) - Technology Update - Watskeburt?!
 
Advanced AV Foundation (CocoaConf, Aug '11)
Advanced AV Foundation (CocoaConf, Aug '11)Advanced AV Foundation (CocoaConf, Aug '11)
Advanced AV Foundation (CocoaConf, Aug '11)
 
[@NaukriEngineering] Video handlings on apple platforms
[@NaukriEngineering] Video handlings on apple platforms[@NaukriEngineering] Video handlings on apple platforms
[@NaukriEngineering] Video handlings on apple platforms
 
SDAccel Design Contest: Vivado HLS
SDAccel Design Contest: Vivado HLSSDAccel Design Contest: Vivado HLS
SDAccel Design Contest: Vivado HLS
 
FFmpeg
FFmpegFFmpeg
FFmpeg
 
HTML5 vs Silverlight
HTML5 vs SilverlightHTML5 vs Silverlight
HTML5 vs Silverlight
 
Craft 2019 - “The Upside Down” Of The Web - Video technologies
Craft 2019 - “The Upside Down” Of The Web - Video technologiesCraft 2019 - “The Upside Down” Of The Web - Video technologies
Craft 2019 - “The Upside Down” Of The Web - Video technologies
 
Introduce native html5 streaming player
Introduce native html5 streaming playerIntroduce native html5 streaming player
Introduce native html5 streaming player
 
Taking HTML5 video a step further
Taking HTML5 video a step furtherTaking HTML5 video a step further
Taking HTML5 video a step further
 
HTML5 Multimedia Accessibility
HTML5 Multimedia AccessibilityHTML5 Multimedia Accessibility
HTML5 Multimedia Accessibility
 
Voice That Matter 2010 - Core Audio
Voice That Matter 2010 - Core AudioVoice That Matter 2010 - Core Audio
Voice That Matter 2010 - Core Audio
 
Galaxy presentation.pptx
Galaxy presentation.pptxGalaxy presentation.pptx
Galaxy presentation.pptx
 
HTML5와 모바일
HTML5와 모바일HTML5와 모바일
HTML5와 모바일
 
#PDR15 - waf, wscript and Your Pebble App
#PDR15 - waf, wscript and Your Pebble App#PDR15 - waf, wscript and Your Pebble App
#PDR15 - waf, wscript and Your Pebble App
 
Html5 intro
Html5 introHtml5 intro
Html5 intro
 
Html 5
Html 5Html 5
Html 5
 
Videostream compression in iOS
Videostream compression in iOSVideostream compression in iOS
Videostream compression in iOS
 
Symbian OS - Descriptors
Symbian OS - DescriptorsSymbian OS - Descriptors
Symbian OS - Descriptors
 
OSBConf 2015 | Using aws virtual tape library as storage for bacula bareos by...
OSBConf 2015 | Using aws virtual tape library as storage for bacula bareos by...OSBConf 2015 | Using aws virtual tape library as storage for bacula bareos by...
OSBConf 2015 | Using aws virtual tape library as storage for bacula bareos by...
 
Introduction to Apache Beam
Introduction to Apache BeamIntroduction to Apache Beam
Introduction to Apache Beam
 

Mehr von Chris Adamson

Whatever Happened to Visual Novel Anime? (AWA/Youmacon 2018)
Whatever Happened to Visual Novel Anime? (AWA/Youmacon 2018)Whatever Happened to Visual Novel Anime? (AWA/Youmacon 2018)
Whatever Happened to Visual Novel Anime? (AWA/Youmacon 2018)Chris Adamson
 
Whatever Happened to Visual Novel Anime? (JAFAX 2018)
Whatever Happened to Visual Novel Anime? (JAFAX 2018)Whatever Happened to Visual Novel Anime? (JAFAX 2018)
Whatever Happened to Visual Novel Anime? (JAFAX 2018)Chris Adamson
 
Fall Premieres: Media Frameworks in iOS 11, macOS 10.13, and tvOS 11 (CocoaCo...
Fall Premieres: Media Frameworks in iOS 11, macOS 10.13, and tvOS 11 (CocoaCo...Fall Premieres: Media Frameworks in iOS 11, macOS 10.13, and tvOS 11 (CocoaCo...
Fall Premieres: Media Frameworks in iOS 11, macOS 10.13, and tvOS 11 (CocoaCo...Chris Adamson
 
Glitch-Free A/V Encoding (CocoaConf Boston, October 2013)
Glitch-Free A/V Encoding (CocoaConf Boston, October 2013)Glitch-Free A/V Encoding (CocoaConf Boston, October 2013)
Glitch-Free A/V Encoding (CocoaConf Boston, October 2013)Chris Adamson
 
Core Audio in iOS 6 (CocoaConf San Jose, April 2013)
Core Audio in iOS 6 (CocoaConf San Jose, April 2013) Core Audio in iOS 6 (CocoaConf San Jose, April 2013)
Core Audio in iOS 6 (CocoaConf San Jose, April 2013) Chris Adamson
 
Core Audio in iOS 6 (CocoaConf DC, March 2013)
Core Audio in iOS 6 (CocoaConf DC, March 2013)Core Audio in iOS 6 (CocoaConf DC, March 2013)
Core Audio in iOS 6 (CocoaConf DC, March 2013)Chris Adamson
 
Mobile Movies with HTTP Live Streaming (CocoaConf DC, March 2013)
Mobile Movies with HTTP Live Streaming (CocoaConf DC, March 2013)Mobile Movies with HTTP Live Streaming (CocoaConf DC, March 2013)
Mobile Movies with HTTP Live Streaming (CocoaConf DC, March 2013)Chris Adamson
 
Core Audio in iOS 6 (CocoaConf Chicago, March 2013)
Core Audio in iOS 6 (CocoaConf Chicago, March 2013)Core Audio in iOS 6 (CocoaConf Chicago, March 2013)
Core Audio in iOS 6 (CocoaConf Chicago, March 2013)Chris Adamson
 
Core Audio Intro (Detroit Mobile City 2013)
Core Audio Intro (Detroit Mobile City 2013)Core Audio Intro (Detroit Mobile City 2013)
Core Audio Intro (Detroit Mobile City 2013)Chris Adamson
 
Objective-C Is Not Java
Objective-C Is Not JavaObjective-C Is Not Java
Objective-C Is Not JavaChris Adamson
 
Core Audio in iOS 6 (CocoaConf Raleigh, Dec. '12)
Core Audio in iOS 6 (CocoaConf Raleigh, Dec. '12)Core Audio in iOS 6 (CocoaConf Raleigh, Dec. '12)
Core Audio in iOS 6 (CocoaConf Raleigh, Dec. '12)Chris Adamson
 

Mehr von Chris Adamson (11)

Whatever Happened to Visual Novel Anime? (AWA/Youmacon 2018)
Whatever Happened to Visual Novel Anime? (AWA/Youmacon 2018)Whatever Happened to Visual Novel Anime? (AWA/Youmacon 2018)
Whatever Happened to Visual Novel Anime? (AWA/Youmacon 2018)
 
Whatever Happened to Visual Novel Anime? (JAFAX 2018)
Whatever Happened to Visual Novel Anime? (JAFAX 2018)Whatever Happened to Visual Novel Anime? (JAFAX 2018)
Whatever Happened to Visual Novel Anime? (JAFAX 2018)
 
Fall Premieres: Media Frameworks in iOS 11, macOS 10.13, and tvOS 11 (CocoaCo...
Fall Premieres: Media Frameworks in iOS 11, macOS 10.13, and tvOS 11 (CocoaCo...Fall Premieres: Media Frameworks in iOS 11, macOS 10.13, and tvOS 11 (CocoaCo...
Fall Premieres: Media Frameworks in iOS 11, macOS 10.13, and tvOS 11 (CocoaCo...
 
Glitch-Free A/V Encoding (CocoaConf Boston, October 2013)
Glitch-Free A/V Encoding (CocoaConf Boston, October 2013)Glitch-Free A/V Encoding (CocoaConf Boston, October 2013)
Glitch-Free A/V Encoding (CocoaConf Boston, October 2013)
 
Core Audio in iOS 6 (CocoaConf San Jose, April 2013)
Core Audio in iOS 6 (CocoaConf San Jose, April 2013) Core Audio in iOS 6 (CocoaConf San Jose, April 2013)
Core Audio in iOS 6 (CocoaConf San Jose, April 2013)
 
Core Audio in iOS 6 (CocoaConf DC, March 2013)
Core Audio in iOS 6 (CocoaConf DC, March 2013)Core Audio in iOS 6 (CocoaConf DC, March 2013)
Core Audio in iOS 6 (CocoaConf DC, March 2013)
 
Mobile Movies with HTTP Live Streaming (CocoaConf DC, March 2013)
Mobile Movies with HTTP Live Streaming (CocoaConf DC, March 2013)Mobile Movies with HTTP Live Streaming (CocoaConf DC, March 2013)
Mobile Movies with HTTP Live Streaming (CocoaConf DC, March 2013)
 
Core Audio in iOS 6 (CocoaConf Chicago, March 2013)
Core Audio in iOS 6 (CocoaConf Chicago, March 2013)Core Audio in iOS 6 (CocoaConf Chicago, March 2013)
Core Audio in iOS 6 (CocoaConf Chicago, March 2013)
 
Core Audio Intro (Detroit Mobile City 2013)
Core Audio Intro (Detroit Mobile City 2013)Core Audio Intro (Detroit Mobile City 2013)
Core Audio Intro (Detroit Mobile City 2013)
 
Objective-C Is Not Java
Objective-C Is Not JavaObjective-C Is Not Java
Objective-C Is Not Java
 
Core Audio in iOS 6 (CocoaConf Raleigh, Dec. '12)
Core Audio in iOS 6 (CocoaConf Raleigh, Dec. '12)Core Audio in iOS 6 (CocoaConf Raleigh, Dec. '12)
Core Audio in iOS 6 (CocoaConf Raleigh, Dec. '12)
 

Kürzlich hochgeladen

Data governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationData governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationKnoldus Inc.
 
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS:  6 Ways to Automate Your Data IntegrationBridging Between CAD & GIS:  6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integrationmarketing932765
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI AgeCprime
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch TuesdayIvanti
 
Testing tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesTesting tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesKari Kakkonen
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfIngrid Airi González
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxLoriGlavin3
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxLoriGlavin3
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality AssuranceInflectra
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsNathaniel Shimoni
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterMydbops
 
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Nikki Chapple
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsPixlogix Infotech
 
Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)Kaya Weers
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Mark Goldstein
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 
QCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architecturesQCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architecturesBernd Ruecker
 

Kürzlich hochgeladen (20)

Data governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationData governance with Unity Catalog Presentation
Data governance with Unity Catalog Presentation
 
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS:  6 Ways to Automate Your Data IntegrationBridging Between CAD & GIS:  6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integration
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI Age
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch Tuesday
 
Testing tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesTesting tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examples
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdf
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptx
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directions
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL Router
 
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and Cons
 
Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 
QCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architecturesQCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architectures
 

AV Foundation Tricks

  • 1. Stupid Video Tricks Chris Adamson • @invalidname CocoaConf Las Vegas • August, 2014
  • 2. AV Foundation • Framework for working with time-based media • Audio, video, timed text (captions / subtitles), timecode • iOS 4.0 and up, Mac OS X 10.7 (Lion) and up • Replacing QuickTime on Mac
  • 3. Ordinary AV Foundation stuff • Playback: AVAsset + AVPlayer • Capture to file: AVCaptureSession + AVCaptureDeviceInput + AVCaptureMovieFileOutput • Editing: AVComposition + AVExportSession
  • 4. But Why Be Ordinary? http://www.crunchyroll.com/my-ordinary-life
  • 5. Introductory Trick • AVPlayerLayer and AVCaptureVideoPreviewLayer are subclasses of CALayer • We can do lots of neat things with CALayers
  • 7. Make an AVPlayerLayer self.player = [AVPlayer playerWithPlayerItem: [AVPlayerItem playerItemWithAsset:self.asset]]; self.playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.player]; self.playerLayer.videoGravity = AVLayerVideoGravityResizeAspect; [self.playerView.layer addSublayer:self.playerLayer]; self.playerLayer.frame = self.playerView.bounds;
  • 8. Animate the layer CABasicAnimation *animateRotation; animateRotation = [CABasicAnimation animationWithKeyPath:@"transform"]; CATransform3D layerTransform = self.playerLayer.transform; layerTransform = CATransform3DRotate(layerTransform, M_PI, 1.0, 1.0, 0.0); animateRotation.toValue = [NSValue valueWithCATransform3D:layerTransform]; animateRotation.duration = 2.0; animateRotation.removedOnCompletion = NO; animateRotation.fillMode = kCAFillModeForwards; animateRotation.repeatCount = 1000; animateRotation.cumulative = YES; [self.playerLayer addAnimation:animateRotation forKey:@"transform"];
  • 10. AV Foundation Core Audio Core Media Core Video Video Toolbox
  • 11. AV Foundation Core Audio Core Media Core Video Video Toolbox
  • 12. AV Foundation Core Audio Core Media Core Video Video Toolbox
  • 14. Core Media • Opaque types to represent time: CMTime, CMTimeRange • Opaque types to represent media samples and their contents: CMSampleBuffer, CMBlockBuffer, CMFormatDescription
  • 15. CMSampleBuffer • Provides timing information for one or more samples: when does this play and for how long? • Contains either • CVImageBuffer – visual data (video frames) • CMBlockBuffer — arbitrary data (sound, subtitles, timecodes)
  • 16. Use & Abuse of CMSampleBuffers • AVCaptureDataOutput provides CMSampleBuffers in sample delegate callback • AVAssetReader provides CMSampleBuffers read from disk • AVAssetWriter accepts CMSampleBuffers to write to disk
  • 17. Demo
  • 18. How the Heck Does that Work? • Movies have tracks, tracks have media, media have sample data • All contents of a QuickTime file are defined in the QuickTime File Format documentation
  • 19.
  • 20. Media Data Atom Types Subtitle Media Subtitle Sample Data Subtitle sample data consists of a 16-‐bit word that specifies the length (number of bytes) of the subtitle text, followed by the subtitle text and then by optional sample extensions. The subtitle text is Unicode text, encoded either as UTF-‐8 text or UTF-‐16 text beginning with a UTF-‐16 BYTE ORDER MARK ('uFEFF') in big or little endian order. There is no null termination for the text. Following the subtitle text, there may be one or more atoms containing additional information for selecting and drawing the subtitle. Table 4-‐12 (page 203) lists the currently defined subtitle sample extensions. Table 4-12 Subtitle sample extensions Subtitle Description sample extension The presence of this atom indicates that the sample contains a forced subtitle. This extension has no data. Forced subtitles are shown automatically when appropriate without any interaction from the user. If any sample contains a forced subtitle, the Some Samples Are Forced (0x40000000) flag must also be set in the display flags. Consider an example where the primary language of the content is English, but the user has chosen to listen to a French dub of the audio. If a scene in the video displays something in English that is important to the plot or the content (such as a newspaper headline), a forced subtitle displays the content translated into French. In this case, the subtitle is linked (“forced”) to the French language sound track. If this atom is not present, the subtitle is typically simply a translation of the audio content, which a user can choose to display or hide. 'frcd' Style information for the subtitle. This atom allows you to override the default style in the sample description or to define more than one style within a sample. See “Subtitle Style Atom” (page 204). 'styl' Override of the default text box for this sample. Used only if the 0x20000000 display flag is set in the sample description and, in that case, only the top is considered. Even so, all fields should be set as though they are considered. See “Text Box atom” (page 205). 'tbox' Text wrap. Set the one-‐byte payload to 0x00 for no wrapping or 0x01 for automatic soft wrapping. 'twrp' 2014-‐02-‐11 | Copyright © 2004, 2014 Apple Inc. All Rights Reserved. 203
  • 21. Subtitle Sample Data! Subtitle sample data consists of a 16-bit word that specifies the length (number of bytes) of the subtitle text, followed by the subtitle text and then by optional sample extensions. The subtitle text is Unicode text, encoded either as UTF-8 text or UTF-16 text beginning with a UTF-16 BYTE ORDER MARK ('uFEFF') in big or little endian order. There is no null termination for the text.! Following the subtitle text, there may be one or more atoms containing additional information for selecting and drawing the subtitle.!
  • 22. I Iz In Ur Subtitle Track… AVAssetTrack *subtitleTrack = [[asset tracksWithMediaType: AVMediaTypeSubtitle] firstObject]; ! AVAssetReaderTrackOutput *subtitleTrackOutput = [AVAssetReaderTrackOutput assetReaderTrackOutputWithTrack:subtitleTrack outputSettings:nil]; ! // ... while (reading) { CMSampleBufferRef sampleBuffer = [subtitleTrackOutput copyNextSampleBuffer]; if (sampleBuffer == NULL) { AVAssetReaderStatus status = subtitleReader.status; if ((status == AVAssetReaderStatusCompleted) || (status == AVAssetReaderStatusFailed) || (status == AVAssetReaderStatusCancelled)) { reading = NO; NSLog (@"ending with reader status %d", status); } } else { CMTime presentationTime = CMSampleBufferGetPresentationTimeStamp(sampleBuffer) ; CMTime duration = CMSampleBufferGetDuration(sampleBuffer);
  • 23. …Readin Ur CMBlockBuffers CMBlockBufferRef blockBuffer = CMSampleBufferGetDataBuffer(sampleBuffer); size_t dataSize =CMBlockBufferGetDataLength(blockBuffer); if (dataSize > 0) { UInt8* data = malloc(dataSize); OSStatus cmErr = CMBlockBufferCopyDataBytes (blockBuffer, 0, dataSize, data);
  • 24.
  • 25. Subtitle Summary • AVAssetReaderOutput provides CMSampleBuffers • Get timing info with CMSampleBufferGetPresentationTimestamp() and CMSampleGetDuration() • Get raw data with CMBlockBufferGet…() functions • Have at it
  • 27. Demo
  • 28. Screen Recording • Run an NSTimer to get screenshots • Many ways to do this, such as drawing your CALayer to a CGContext, make it a UIImage • Convert image data into a CVPixelBuffer • Use AVAssetWriterPixelBufferAdaptor to write pixel buffer and presentation time to an AVAssetWriterInput
  • 29. Make CVPixelBuffer CVPixelBufferRef pixelBuffer = NULL;! CFDataRef imageData=! CGDataProviderCopyData(CGImageGetDataProvider(image));! cvErr = CVPixelBufferCreateWithBytes(kCFAllocatorDefault,! ! !! ! ! ! ! ! ! ! ! FRAME_WIDTH,! ! !! ! ! ! ! ! ! ! ! FRAME_HEIGHT,! ! !! ! ! ! ! ! ! ! ! kCVPixelFormatType_32BGRA,! ! !! ! ! ! ! ! ! ! ! (void*)CFDataGetBytePtr(imageData),! ! !! ! ! ! ! ! ! ! ! CGImageGetBytesPerRow(image),! ! !! ! ! ! ! ! ! ! ! NULL,! ! !! ! ! ! ! ! ! ! ! NULL,! ! !! ! ! ! ! ! ! ! ! NULL,! ! !! ! ! ! ! ! ! ! ! &pixelBuffer);!
  • 30. Compute Presentation Time CFAbsoluteTime thisFrameWallClockTime = CFAbsoluteTimeGetCurrent();! CFTimeInterval elapsedTime = thisFrameWallClockTime -! self.firstFrameWallClockTime;! CMTime presentationTime = CMTimeMake (elapsedTime * TIME_SCALE,! TIME_SCALE);!
  • 31. Append to AVAssetWriterInput BOOL appended = [self.assetWriterPixelBufferAdaptor! appendPixelBuffer:pixelBuffer! withPresentationTime:presentationTime];!
  • 33. AV Foundation Core Audio Core Media Core Video Video Toolbox
  • 35. Core Audio Core Media • Reading: CMSampleBufferGetAudioBufferListWithRetain edBlockBuffer(), CMSampleBufferGetAudioStreamPacketDescript ions() • Writing: CMSampleBufferSetDataBufferFromAudioBuffer List(), CMAudioSampleBufferCreateWithPacketDescrip tions()
  • 36. Core Audio Core Media • Reading: CMSampleBufferGetAudioBufferListWithRetain edBlockBuffer(), CMSampleBufferGetAudioStreamPacketDescript ions() • Writing: CMSampleBufferSetDataBufferFromAudioBuffer List(), CMAudioSampleBufferCreateWithPacketDescrip tions()
  • 37. Potential Uses • Run captured / read-in audio through effects in an AUGraph • See “AVCaptureAudioDataOutput To AudioUnit” examples (iOS & OS X) from WWDC 2012 • May make more sense for audio-oriented apps to do capture / file reads entirely from Core Audio
  • 39. AV Foundation Core Audio Core Media Core Video Video Toolbox
  • 41. Core Media Core Video • CMSampleBuffers provide CVImageBuffers • Two sub-types: CVPixelBufferRef, CVOpenGLESTextureRef • Pixel buffers allow us to work with bitmaps, via CVPixelBufferGetBaseAddress() • Note: Must wrap calls with CVPixelBufferLockBaseAddress(), CVPixelBufferUnlockBaseAddress()
  • 42. Use & Abuse of CVImageBuffers • Can be used to create Core Image CIImages • iOS: -[CIImage imageWithCVPixelBuffer:] • OS X: -[CIImage imageWithCVImageBuffer:] • CIImages can be used to do lots of stuff…
  • 43. Demo
  • 44. Recipe • Create CIContext from EAGLContext • Create CIFilter • During capture callback • Convert pixel buffer to CIImage • Run through filter • Draw to CIContext
  • 45. Set Up GLKView if (! self.glkView.context.API != kEAGLRenderingAPIOpenGLES2) { EAGLContext *eagl2Context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; self.glkView.context = eagl2Context; } self.glContext = self.glkView.context; // we'll do the updating, thanks self.glkView.enableSetNeedsDisplay = NO;
  • 46. Make CIContext // make CIContext from GL context, clearing out default color space self.ciContext = [CIContext contextWithEAGLContext:self.glContext options:@{kCIContextWorkingColorSpace : [NSNull null]} ]; [self.glkView bindDrawable]; // from Core Image Fun House: _glkDrawBounds = CGRectZero; _glkDrawBounds.size.width = self.glkView.drawableWidth; _glkDrawBounds.size.height = self.glkView.drawableHeight; See also iOS Core Image Fun House from WWDC 2013
  • 47. Ask for RGB in Callbacks self.videoDataOutput = [[AVCaptureVideoDataOutput alloc] init]; [self.videoDataOutput setSampleBufferDelegate:self queue:self.videoDataOutputQueue]; [self.captureSession addOutput: self.videoDataOutput]; NSDictionary *videoSettings = @{ (id) kCVPixelBufferPixelFormatTypeKey: @(kCVPixelFormatType_32BGRA)}; [self.videoDataOutput setVideoSettings:videoSettings]; Note: 32BGRA and two flavors of 4:2:0 YCbCr are the only valid pixel formats for video capture on iOS
  • 48. Create CIFilter self.pixellateFilter = [CIFilter filterWithName:@"CIPixellate"]; [self.pixellateFilter setValue:[CIVector vectorWithX:100.0 Y:100.0] forKey:@"inputCenter"]; [self setPixellateFilterScale:self.pixellationScaleSlider.value];
  • 49. Set CIFilter Params - (IBAction)handleScaleSliderValueChanged:(UISlider*) sender { [self setPixellateFilterScale:sender.value]; } ! -(void) setPixellateFilterScale: (CGFloat) scale { [self.pixellateFilter setValue:[NSNumber numberWithFloat:scale] forKey:@"inputScale"]; }
  • 50. Callback: Apply Filter CVImageBufferRef cvBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); CVPixelBufferLockBaseAddress(cvBuffer,0); CIImage *bufferCIImage = [CIImage imageWithCVPixelBuffer:cvBuffer]; ! [self.pixellateFilter setValue:bufferCIImage forKey:kCIInputImageKey]; bufferCIImage = [self.pixellateFilter valueForKey:kCIOutputImageKey];
  • 51. Callback: Draw to GLKView [self.glkView bindDrawable]; if (self.glContext != [EAGLContext currentContext]) { [EAGLContext setCurrentContext: self.glContext]; } // drawing code here is from WWDC 2013 iOS Core Image Fun House // clear eagl view to grey glClearColor(0.5, 0.5, 0.5, 1.0); glClear(GL_COLOR_BUFFER_BIT); // set the blend mode to "source over" so that CI will use that glEnable(GL_BLEND); glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); CGRect drawRect = bufferCIImage.extent; [self.ciContext drawImage:bufferCIImage inRect:self.glkDrawBounds fromRect:drawRect]; [self.glkView display]; CVPixelBufferUnlockBaseAddress(cvBuffer, 0);
  • 52. Recap from camera CIFilter CVPixelBuffer CIImage CIImage CIContext -[CIContext drawImage: fromRect: inRect:] (OpenGL drawing) +[CIImage imageWith CVPixelBuff er:]
  • 53. Recap from camera CIFilter +[CIImage imageWith CVPixelBuff er:] CVPixelBuffer CIImage CIImage CIContext -[CIContext drawImage: fromRect: inRect:] CVPixelBuffer (optional) AVAsset Writer (OpenGL Output drawing)
  • 55. There are lots of CIFilters CICategoryBlur ! ! CIBoxBlur ! ! CIDiscBlur ! ! CIGaussianBlur ! ! CIMedianFilter ! ! CIMotionBlur ! ! CINoiseReduction ! ! CIZoomBlur CICategoryColorAdjust ment ! ! CIColorClamp ! ! CIColorControls ! ! CIColorMatrix ! ! CIColorPolynomial ! ! CIExposureAdjust ! ! CIGammaAdjust ! ! CIHueAdjust ! ! CILinearToSRGBToneCurv e ! ! CISRGBToneCurveToLinea r ! ! CITemperatureAndTint ! ! CIToneCurve ! ! CIVibrance ! ! CIWhitePointAdjust CICategoryColorEffect ! ! CIColorCrossPolynomial ! ! CIColorCube ! ! CIColorCubeWithColorSp ace ! ! CIColorInvert ! ! CIColorMap ! ! CIColorMonochrome ! ! CIColorPosterize ! ! CIFalseColor ! ! CIMaskToAlpha ! ! CIMaximumComponent ! ! CIMinimumComponent ! ! CIPhotoEffectChrome ! ! CIPhotoEffectFade ! ! CIPhotoEffectInstant ! ! CIPhotoEffectMono ! ! CIPhotoEffectNoir ! ! CIPhotoEffectProcess ! ! CIPhotoEffectTonal ! ! CIPhotoEffectTransfer ! ! CISepiaTone ! ! CIVignette ! ! CIVignetteEffect CICategoryComposite Operation ! ! CIAdditionCompositing ! ! CIColorBlendMode ! ! CIColorBurnBlendMode ! ! CIColorDodgeBlendMode ! ! CIDarkenBlendMode ! ! CIDifferenceBlendMode ! ! CIExclusionBlendMode ! ! CIHardLightBlendMode ! ! CIHueBlendMode ! ! CILightenBlendMode ! ! CILuminosityBlendMode ! ! CIMaximumCompositing ! ! CIMinimumCompositing ! ! CIMultiplyBlendMode ! ! CIMultiplyCompositing ! ! CIOverlayBlendMode ! ! CISaturationBlendMode ! ! CIScreenBlendMode ! ! CISoftLightBlendMode ! ! CISourceAtopCompositin g ! ! CISourceInCompositing ! ! CISourceOutCompositing ! ! CISourceOverCompositin g CICategoryDistortionE ffect ! ! CIBumpDistortion ! ! CIBumpDistortionLinear ! ! CICircleSplashDistorti on ! ! CICircularWrap ! ! CIDroste ! ! CIDisplacementDistorti on ! ! CIGlassDistortion ! ! CIGlassLozenge ! ! CIHoleDistortion ! ! CILightTunnel ! ! CIPinchDistortion ! ! CIStretchCrop ! ! CITorusLensDistortion ! ! CITwirlDistortion ! ! CIVortexDistortion CICategoryGenerator ! CICheckerboardGenerator ! ! CIConstantColorGenerat or ! ! CILenticularHaloGenera tor ! ! CIQRCodeGenerator ! ! CIRandomGenerator ! ! CIStarShineGenerator ! ! CIStripesGenerator ! ! CISunbeamsGenerator CICategoryGeometryA djustment ! ! CIAffineTransform ! ! CICrop ! ! CILanczosScaleTransfor m ! ! CIPerspectiveTransform ! ! CIPerspectiveTransform WithExtent ! ! CIStraightenFilter CICategoryGradient ! ! CIGaussianGradient ! ! CILinearGradient ! ! CIRadialGradient ! ! CISmoothLinearGradient CICategoryHalftoneEff ect
  • 56. Demo
  • 57. CIColorCube Maps colors from one RGB “cube” to another http://en.wikipedia.org/wiki/RGB_color_space
  • 58. Using CIColorCube CIColorCube maps green(-ish) colors to 0.0 alpha, all other colors pass through
  • 60. consCt unsigInedC int sioze = 6l4; orCube Data size_t cubeDataSize = size * size * size * sizeof (float) * 4; float *keyCubeData = (float *)malloc (cubeDataSize); float rgb[3], hsv[3], *keyC = keyCubeData; // Populate cube with a simple gradient going from 0 to 1 for (int z = 0; z < size; z++){ rgb[2] = ((double)z)/(size-1); // Blue value for (int y = 0; y < size; y++){ rgb[1] = ((double)y)/(size-1); // Green value for (int x = 0; x < size; x ++){ rgb[0] = ((double)x)/(size-1); // Red value ! // Convert RGB to HSV // You can find publicly available rgbToHSV functions on the Internet ! RGBtoHSV(rgb[0], rgb[1], rgb[2], &hsv[0], &hsv[1], &hsv[2]); ! // RGBtoHSV uses 0 to 360 for hue, while UIColor (used above) uses 0 to 1. hsv[0] /= 360.0; // Use the hue value to determine which to make transparent // The minimum and maximum hue angle depends on // the color you want to remove bool keyed = (hsv[0] > minHueAngle && hsv[0] < maxHueAngle) && (hsv[1] > minSaturation && hsv[1] < maxSaturation) && (hsv[2] > minBrightness && hsv[2] < maxBrightness); float alpha = keyed ? 0.0f : 1.0f; // re-calculate c pointer keyC = (((z * size * size) + (y * size) + x) * sizeof(float)) + keyCubeData; // Calculate premultiplied alpha values for the cube keyC[0] = rgb[0] * alpha; keyC[1] = rgb[1] * alpha; keyC[2] = rgb[2] * alpha; keyC[3] = alpha; } } } See “Chroma Key Filter Recipe” in Core Image Programming Guide
  • 61. Create CIColorCube from mapping data // Create memory with the cube data NSData *data = [NSData dataWithBytesNoCopy:keyCubeData length:cubeDataSize freeWhenDone:YES]; self.colorCubeFilter = [CIFilter filterWithName:@"CIColorCube"]; [self.colorCubeFilter setValue:[NSNumber numberWithInt:size] forKey:@"inputCubeDimension"]; // Set data for cube [self.colorCubeFilter setValue:data forKey:@"inputCubeData"];
  • 62. Create CISourceOverCompositing // source over filter self.sourceOverFilter = [CIFilter filterWithName: @"CISourceOverCompositing"]; CIImage *backgroundCIImage = [CIImage imageWithCGImage: self.backgroundImage.CGImage]; [self.sourceOverFilter setValue:backgroundCIImage forKeyPath:@"inputBackgroundImage"];
  • 63. Apply Filters in Delegate Callback CIImage *bufferCIImage = [CIImage imageWithCVPixelBuffer: cvBuffer]; [self.colorCubeFilter setValue:bufferCIImage forKey:kCIInputImageKey]; CIImage *keyedCameraImage = [self.colorCubeFilter valueForKey: kCIOutputImageKey]; [self.sourceOverFilter setValue:keyedCameraImage forKeyPath:kCIInputImageKey]; CIImage *compositedImage = [self.sourceOverFilter valueForKeyPath: kCIOutputImageKey]; Then draw compositedImage to CIContext as before
  • 64. More Fun with Filters • Alpha Matte: Use CIColorCube to map green to white (or transparent), everything else to black • Can then use this with other filters to do edge work on the “foreground” object • Be sure that any filters you use are of category CICategoryVideo.
  • 65. More Fun With CIContexts • Can write effected pixels to a movie file with AVAssetWriterOutput • Use base address of CIContext to create a new CVPixelBuffer, use this and timing information to create a CMSampleBuffer • AVAssetWriterInputPixelBufferAdaptor makes this slightly easier
  • 66. Recap • Most good tricks start with CMSampleBuffers • Audio: convert to Core Audio types • Video: convert to CIImage • Other: get CMBlockBuffer and parse by hand
  • 67. Further Info and http://devforums.apple.com/
  • 68. Q&A Slides at http://www.slideshare.net/invalidname/ See comments there for link to source code ! invalidname [at] gmail.com @invalidname (Twitter, app.net) http://www.subfurther.com/blog