Obj-C SDK Cleanup

This CL separates the files under sdk/objc into logical directories, replacing
the previous file layout under Framework/.

A long term goal is to have some system set up to generate the files under
sdk/objc/api (the PeerConnection API wrappers) from the C++ code. In the shorter
term the goal is to abstract out shared concepts from these classes in order to
make them as uniform as possible.

The separation into base/, components/, and helpers/ are to differentiate between
the base layer's common protocols, various utilities and the actual platform
specific components.

The old directory layout that resembled a framework's internal layout is not
necessary, since it is generated by the framework target when building it.

Bug: webrtc:9627
Change-Id: Ib084fd83f050ae980649ca99e841f4fb0580bd8f
Reviewed-on: https://webrtc-review.googlesource.com/94142
Reviewed-by: Kári Helgason <kthelgason@webrtc.org>
Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
Reviewed-by: Rasmus Brandt <brandtr@webrtc.org>
Reviewed-by: Henrik Andreassson <henrika@webrtc.org>
Commit-Queue: Anders Carlsson <andersc@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#24493}
diff --git a/sdk/objc/components/renderer/opengl/RTCNSGLVideoView.m b/sdk/objc/components/renderer/opengl/RTCNSGLVideoView.m
new file mode 100644
index 0000000..714cae7
--- /dev/null
+++ b/sdk/objc/components/renderer/opengl/RTCNSGLVideoView.m
@@ -0,0 +1,196 @@
+/*
+ *  Copyright 2015 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#import <Foundation/Foundation.h>
+
+#if !TARGET_OS_IPHONE
+
+#import "RTCNSGLVideoView.h"
+
+#import <AppKit/NSOpenGL.h>
+#import <CoreVideo/CVDisplayLink.h>
+#import <OpenGL/gl3.h>
+
+#import "RTCDefaultShader.h"
+#import "RTCI420TextureCache.h"
+#import "base/RTCLogging.h"
+#import "base/RTCVideoFrame.h"
+
+@interface RTCNSGLVideoView ()
+// |videoFrame| is set when we receive a frame from a worker thread and is read
+// from the display link callback so atomicity is required.
+@property(atomic, strong) RTCVideoFrame *videoFrame;
+@property(atomic, strong) RTCI420TextureCache *i420TextureCache;
+
+- (void)drawFrame;
+@end
+
+static CVReturn OnDisplayLinkFired(CVDisplayLinkRef displayLink,
+                                   const CVTimeStamp *now,
+                                   const CVTimeStamp *outputTime,
+                                   CVOptionFlags flagsIn,
+                                   CVOptionFlags *flagsOut,
+                                   void *displayLinkContext) {
+  RTCNSGLVideoView *view = (__bridge RTCNSGLVideoView *)displayLinkContext;
+  [view drawFrame];
+  return kCVReturnSuccess;
+}
+
+@implementation RTCNSGLVideoView {
+  CVDisplayLinkRef _displayLink;
+  RTCVideoFrame *_lastDrawnFrame;
+  id<RTCVideoViewShading> _shader;
+}
+
+@synthesize delegate = _delegate;
+@synthesize videoFrame = _videoFrame;
+@synthesize i420TextureCache = _i420TextureCache;
+
+- (instancetype)initWithFrame:(NSRect)frame pixelFormat:(NSOpenGLPixelFormat *)format {
+  return [self initWithFrame:frame pixelFormat:format shader:[[RTCDefaultShader alloc] init]];
+}
+
+- (instancetype)initWithFrame:(NSRect)frame
+                  pixelFormat:(NSOpenGLPixelFormat *)format
+                       shader:(id<RTCVideoViewShading>)shader {
+  if (self = [super initWithFrame:frame pixelFormat:format]) {
+    _shader = shader;
+  }
+  return self;
+}
+
+- (void)dealloc {
+  [self teardownDisplayLink];
+}
+
+- (void)drawRect:(NSRect)rect {
+  [self drawFrame];
+}
+
+- (void)reshape {
+  [super reshape];
+  NSRect frame = [self frame];
+  [self ensureGLContext];
+  CGLLockContext([[self openGLContext] CGLContextObj]);
+  glViewport(0, 0, frame.size.width, frame.size.height);
+  CGLUnlockContext([[self openGLContext] CGLContextObj]);
+}
+
+- (void)lockFocus {
+  NSOpenGLContext *context = [self openGLContext];
+  [super lockFocus];
+  if ([context view] != self) {
+    [context setView:self];
+  }
+  [context makeCurrentContext];
+}
+
+- (void)prepareOpenGL {
+  [super prepareOpenGL];
+  [self ensureGLContext];
+  glDisable(GL_DITHER);
+  [self setupDisplayLink];
+}
+
+- (void)clearGLContext {
+  [self ensureGLContext];
+  self.i420TextureCache = nil;
+  [super clearGLContext];
+}
+
+#pragma mark - RTCVideoRenderer
+
+// These methods may be called on non-main thread.
+- (void)setSize:(CGSize)size {
+  dispatch_async(dispatch_get_main_queue(), ^{
+    [self.delegate videoView:self didChangeVideoSize:size];
+  });
+}
+
+- (void)renderFrame:(RTCVideoFrame *)frame {
+  self.videoFrame = frame;
+}
+
+#pragma mark - Private
+
+- (void)drawFrame {
+  RTCVideoFrame *frame = self.videoFrame;
+  if (!frame || frame == _lastDrawnFrame) {
+    return;
+  }
+  // This method may be called from CVDisplayLink callback which isn't on the
+  // main thread so we have to lock the GL context before drawing.
+  NSOpenGLContext *context = [self openGLContext];
+  CGLLockContext([context CGLContextObj]);
+
+  [self ensureGLContext];
+  glClear(GL_COLOR_BUFFER_BIT);
+
+  // Rendering native CVPixelBuffer is not supported on OS X.
+  // TODO(magjed): Add support for NV12 texture cache on OS X.
+  frame = [frame newI420VideoFrame];
+  if (!self.i420TextureCache) {
+    self.i420TextureCache = [[RTCI420TextureCache alloc] initWithContext:context];
+  }
+  RTCI420TextureCache *i420TextureCache = self.i420TextureCache;
+  if (i420TextureCache) {
+    [i420TextureCache uploadFrameToTextures:frame];
+    [_shader applyShadingForFrameWithWidth:frame.width
+                                    height:frame.height
+                                  rotation:frame.rotation
+                                    yPlane:i420TextureCache.yTexture
+                                    uPlane:i420TextureCache.uTexture
+                                    vPlane:i420TextureCache.vTexture];
+    [context flushBuffer];
+    _lastDrawnFrame = frame;
+  }
+  CGLUnlockContext([context CGLContextObj]);
+}
+
+- (void)setupDisplayLink {
+  if (_displayLink) {
+    return;
+  }
+  // Synchronize buffer swaps with vertical refresh rate.
+  GLint swapInt = 1;
+  [[self openGLContext] setValues:&swapInt forParameter:NSOpenGLCPSwapInterval];
+
+  // Create display link.
+  CVDisplayLinkCreateWithActiveCGDisplays(&_displayLink);
+  CVDisplayLinkSetOutputCallback(_displayLink,
+                                 &OnDisplayLinkFired,
+                                 (__bridge void *)self);
+  // Set the display link for the current renderer.
+  CGLContextObj cglContext = [[self openGLContext] CGLContextObj];
+  CGLPixelFormatObj cglPixelFormat = [[self pixelFormat] CGLPixelFormatObj];
+  CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext(
+      _displayLink, cglContext, cglPixelFormat);
+  CVDisplayLinkStart(_displayLink);
+}
+
+- (void)teardownDisplayLink {
+  if (!_displayLink) {
+    return;
+  }
+  CVDisplayLinkRelease(_displayLink);
+  _displayLink = NULL;
+}
+
+- (void)ensureGLContext {
+  NSOpenGLContext* context = [self openGLContext];
+  NSAssert(context, @"context shouldn't be nil");
+  if ([NSOpenGLContext currentContext] != context) {
+    [context makeCurrentContext];
+  }
+}
+
+@end
+
+#endif  // !TARGET_OS_IPHONE