Split video_render_module implementation into default and internal implementation.
Targets must now link with implementation of their choice instead of at "gyp"-time.

Targets linking with libjingle_media:
- internal implementation when build_with_chromium=0, default otherwise.

Targets linking with default render implementation:
- video_engine_tests
- video_loopback
- video_replay
- anything dependent on webrtc_test_common

Targets linking with internal render implementation:
- vie_auto_test
- video_render_tests
- libwebrtcdemo-jni
- video_engine_core_unittests

GN changes:
- Not many since there is almost no test definitions.

Work-around for chromium:
- Until chromium has updated libpeerconnection to link with video_capture_impl and video_render_impl, webrtc target automatically depends on it. This should fix the FYI bots and not require a webrtc roll to fix.

Re-enable android tests by reverting 7026 (some tests left disabled).

TESTED: passes all the bots. If this inadvertently breaks a target please fix the linking rules so the target has the desired implementation linked in.
BUG=3770
R=kjellander@webrtc.org, pbos@webrtc.org
TBR=mflodman@webrtc.org

Review URL: https://webrtc-codereview.appspot.com/19359004

git-svn-id: http://webrtc.googlecode.com/svn/trunk/webrtc@7217 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/build/common.gypi b/build/common.gypi
index 7287600..92404fd 100644
--- a/build/common.gypi
+++ b/build/common.gypi
@@ -132,8 +132,6 @@
         # Exclude internal ADM since Chromium uses its own IO handling.
         'include_internal_audio_device%': 0,
 
-        # Exclude internal video render module in Chromium build.
-        'include_internal_video_render%': 0,
       }, {  # Settings for the standalone (not-in-Chromium) build.
         # TODO(andrew): For now, disable the Chrome plugins, which causes a
         # flood of chromium-style warnings. Investigate enabling them:
@@ -142,7 +140,6 @@
 
         'include_pulse_audio%': 1,
         'include_internal_audio_device%': 1,
-        'include_internal_video_render%': 1,
       }],
       ['build_with_libjingle==1', {
         'include_tests%': 0,
diff --git a/build/webrtc.gni b/build/webrtc.gni
index 5e3adfa..878b6ff 100644
--- a/build/webrtc.gni
+++ b/build/webrtc.gni
@@ -74,8 +74,6 @@
     # Exclude internal ADM since Chromium uses its own IO handling.
     rtc_include_internal_audio_device = false
 
-    # Exclude internal video render module in Chromium build.
-    rtc_include_internal_video_render = false
   } else {
     # Settings for the standalone (not-in-Chromium) build.
 
@@ -86,7 +84,6 @@
 
     rtc_include_pulse_audio = true
     rtc_include_internal_audio_device = true
-    rtc_include_internal_video_render = true
   }
 
   if (build_with_libjingle) {
diff --git a/modules/video_render/BUILD.gn b/modules/video_render/BUILD.gn
index 2c14b54..d8d9200 100644
--- a/modules/video_render/BUILD.gn
+++ b/modules/video_render/BUILD.gn
@@ -8,15 +8,6 @@
 
 import("../../build/webrtc.gni")
 
-config("video_render_config") {
-  if (is_ios) {
-    libs = [
-      "OpenGLES.framework",
-      "QuartzCore.framework",
-    ]
-  }
-}
-
 source_set("video_render") {
   sources = [
     "external/video_render_external_impl.cc",
@@ -28,116 +19,142 @@
     "incoming_video_stream.h",
     "video_render_frames.cc",
     "video_render_frames.h",
-    "video_render_impl.cc",
     "video_render_impl.h",
   ]
 
-  libs = []
-  deps = []
-
-  if (rtc_include_internal_video_render) {
-    defines += [ "WEBRTC_INCLUDE_INTERNAL_VIDEO_RENDER" ]
-
-    if (is_linux) {
-      sources += [
-        "linux/video_render_linux_impl.cc",
-        "linux/video_render_linux_impl.h",
-        "linux/video_x11_channel.cc",
-        "linux/video_x11_channel.h",
-        "linux/video_x11_render.cc",
-        "linux/video_x11_render.h",
-      ]
-
-      libs += [ "Xext" ]
-    }
-    if (is_mac) {
-      sources += [
-        "mac/cocoa_full_screen_window.h",
-        "mac/cocoa_full_screen_window.mm",
-        "mac/cocoa_render_view.h",
-        "mac/cocoa_render_view.mm",
-        "mac/video_render_agl.cc",
-        "mac/video_render_agl.h",
-        "mac/video_render_mac_carbon_impl.cc",
-        "mac/video_render_mac_carbon_impl.h",
-        "mac/video_render_mac_cocoa_impl.h",
-        "mac/video_render_mac_cocoa_impl.mm",
-        "mac/video_render_nsopengl.h",
-        "mac/video_render_nsopengl.mm",
-      ]
-
-      libs += [
-        "CoreVideo.framework",
-        "QTKit.framework",
-      ]
-    }
-    if (is_win) {
-      sources += [
-        "windows/i_video_render_win.h",
-        "windows/video_render_direct3d9.cc",
-        "windows/video_render_direct3d9.h",
-        "windows/video_render_windows_impl.cc",
-        "windows/video_render_windows_impl.h",
-      ]
-
-      directxsdk_exists =
-        (exec_script("//build/dir_exists.py",
-                     [ rebase_path("//third_party/directxsdk/files",
-                                   root_build_dir) ],
-                     "trim string") == "True")
-      if (directxsdk_exists) {
-        directxsdk_path = "//third_party/directxsdk/files"
-      } else {
-        directxsdk_path = getenv("DXSDK_DIR")
-      }
-      include_dirs = [ directxsdk_path +  "/Include" ]
-
-    }
-    if (is_android) {
-      sources += [
-        "android/video_render_android_impl.cc",
-        "android/video_render_android_impl.h",
-        "android/video_render_android_native_opengl2.cc",
-        "android/video_render_android_native_opengl2.h",
-        "android/video_render_android_surface_view.cc",
-        "android/video_render_android_surface_view.h",
-        "android/video_render_opengles20.cc",
-        "android/video_render_opengles20.h",
-      ]
-
-      libs += [ "GLESv2" ]
-    }
-    if (is_ios) {
-      sources += [
-        "ios/open_gles20.h",
-        "ios/open_gles20.mm",
-        "ios/video_render_ios_channel.h",
-        "ios/video_render_ios_channel.mm",
-        "ios/video_render_ios_gles20.h",
-        "ios/video_render_ios_gles20.mm",
-        "ios/video_render_ios_impl.h",
-        "ios/video_render_ios_impl.mm",
-        "ios/video_render_ios_view.h",
-        "ios/video_render_ios_view.mm",
-      ]
-    }
-  }
-
-  all_dependent_configs = [ ":video_render_config"]
-
-  if (is_ios) {
-    cflags += [ "-fobjc-arc" ]  # CLANG_ENABLE_OBJC_ARC = YES.
-  }
+  deps = [
+    "../../common_video",
+    "../../system_wrappers",
+    "../utility",
+  ]
 
   if (is_clang) {
     # Suppress warnings from Chrome's Clang plugins.
     # See http://code.google.com/p/webrtc/issues/detail?id=163 for details.
     configs -= [ "//build/config/clang:find_bad_constructs" ]
   }
+}
 
-  deps += [
-    "../../common_video",
-    "../../system_wrappers",
-    "../utility",
+source_set("video_render_impl") {
+  sources = [
+    "video_render_impl.cc",
   ]
+  deps = [
+    ":video_render",
+  ]
+
+  if (is_clang) {
+    # Suppress warnings from Chrome's Clang plugins.
+    # See http://code.google.com/p/webrtc/issues/detail?id=163 for details.
+    configs -= [ "//build/config/clang:find_bad_constructs" ]
+  }
+}
+
+config("video_render_internal_impl_config") {
+  if (is_ios) {
+    libs = [
+      "OpenGLES.framework",
+      "QuartzCore.framework",
+    ]
+  }
+}
+
+source_set("video_render_internal_impl") {
+  libs = []
+  sources = [
+    "video_render_internal_impl.cc",
+  ]
+
+  if (is_linux) {
+    sources += [
+      "linux/video_render_linux_impl.cc",
+      "linux/video_render_linux_impl.h",
+      "linux/video_x11_channel.cc",
+      "linux/video_x11_channel.h",
+      "linux/video_x11_render.cc",
+      "linux/video_x11_render.h",
+    ]
+
+    libs += [ "Xext" ]
+  }
+  if (is_mac) {
+    sources += [
+      "mac/cocoa_full_screen_window.h",
+      "mac/cocoa_full_screen_window.mm",
+      "mac/cocoa_render_view.h",
+      "mac/cocoa_render_view.mm",
+      "mac/video_render_agl.cc",
+      "mac/video_render_agl.h",
+      "mac/video_render_mac_carbon_impl.cc",
+      "mac/video_render_mac_carbon_impl.h",
+      "mac/video_render_mac_cocoa_impl.h",
+      "mac/video_render_mac_cocoa_impl.mm",
+      "mac/video_render_nsopengl.h",
+      "mac/video_render_nsopengl.mm",
+    ]
+
+    libs += [
+      "CoreVideo.framework",
+      "QTKit.framework",
+    ]
+  }
+  if (is_win) {
+    sources += [
+      "windows/i_video_render_win.h",
+      "windows/video_render_direct3d9.cc",
+      "windows/video_render_direct3d9.h",
+      "windows/video_render_windows_impl.cc",
+      "windows/video_render_windows_impl.h",
+    ]
+
+    directxsdk_exists =
+      (exec_script("//build/dir_exists.py",
+                   [ rebase_path("//third_party/directxsdk/files",
+                                 root_build_dir) ],
+                   "trim string") == "True")
+    if (directxsdk_exists) {
+      directxsdk_path = "//third_party/directxsdk/files"
+    } else {
+      directxsdk_path = getenv("DXSDK_DIR")
+    }
+    include_dirs = [ directxsdk_path +  "/Include" ]
+  }
+  if (is_android) {
+    sources += [
+      "android/video_render_android_impl.cc",
+      "android/video_render_android_impl.h",
+      "android/video_render_android_native_opengl2.cc",
+      "android/video_render_android_native_opengl2.h",
+      "android/video_render_android_surface_view.cc",
+      "android/video_render_android_surface_view.h",
+      "android/video_render_opengles20.cc",
+      "android/video_render_opengles20.h",
+    ]
+
+    libs += [ "GLESv2" ]
+  }
+  if (is_ios) {
+    sources += [
+      "ios/open_gles20.h",
+      "ios/open_gles20.mm",
+      "ios/video_render_ios_channel.h",
+      "ios/video_render_ios_channel.mm",
+      "ios/video_render_ios_gles20.h",
+      "ios/video_render_ios_gles20.mm",
+      "ios/video_render_ios_impl.h",
+      "ios/video_render_ios_impl.mm",
+      "ios/video_render_ios_view.h",
+      "ios/video_render_ios_view.mm",
+    ]
+
+    cflags += [ "-fobjc-arc" ]  # CLANG_ENABLE_OBJC_ARC = YES.
+  }
+
+  all_dependent_configs = [ ":video_render_internal_impl_config"]
+
+  if (is_clang) {
+    # Suppress warnings from Chrome's Clang plugins.
+    # See http://code.google.com/p/webrtc/issues/detail?id=163 for details.
+    configs -= [ "//build/config/clang:find_bad_constructs" ]
+  }
 }
diff --git a/modules/video_render/include/video_render.h b/modules/video_render/include/video_render.h
index 56e0cdb..53a4041 100644
--- a/modules/video_render/include/video_render.h
+++ b/modules/video_render/include/video_render.h
@@ -25,10 +25,6 @@
 
 namespace webrtc {
 
-#if defined(WEBRTC_ANDROID) && !defined(WEBRTC_CHROMIUM_BUILD)
-int32_t SetRenderAndroidVM(void* javaVM);
-#endif
-
 // Class definitions
 class VideoRender: public Module
 {
diff --git a/modules/video_render/test/testAPI/testAPI.cc b/modules/video_render/test/testAPI/testAPI.cc
index 4181718..3ec68dd 100644
--- a/modules/video_render/test/testAPI/testAPI.cc
+++ b/modules/video_render/test/testAPI/testAPI.cc
@@ -294,11 +294,6 @@
     VideoRenderCallback* renderCallback0 = renderModule->AddIncomingRenderStream(streamId0, 0, 0.0f, 0.0f, 1.0f, 1.0f);
     assert(renderCallback0 != NULL);
 
-#ifndef WEBRTC_INCLUDE_INTERNAL_VIDEO_RENDER
-    MyRenderCallback externalRender;
-    renderModule->AddExternalRenderCallback(streamId0, &externalRender);
-#endif
-
     printf("Start render\n");
     error = renderModule->StartRender(streamId0);
     if (error != 0) {
@@ -577,10 +572,6 @@
 }
 
 void RunVideoRenderTests(void* window, VideoRenderType windowType) {
-#ifndef WEBRTC_INCLUDE_INTERNAL_VIDEO_RENDER
-    windowType = kRenderExternal;
-#endif
-
     int myId = 12345;
 
     // Create the render module
diff --git a/modules/video_render/video_render.gypi b/modules/video_render/video_render.gypi
index 0828e55..da51588 100644
--- a/modules/video_render/video_render.gypi
+++ b/modules/video_render/video_render.gypi
@@ -9,6 +9,10 @@
 {
   'targets': [
     {
+      # Note this library is missing an implementation for the video render.
+      # For that targets must link with 'video_render_module_impl' or
+      # 'video_render_module_internal_impl' if they want to compile and use
+      # the internal render as the default renderer.
       'target_name': 'video_render_module',
       'type': 'static_library',
       'dependencies': [
@@ -26,16 +30,36 @@
         'incoming_video_stream.h',
         'video_render_frames.cc',
         'video_render_frames.h',
-        'video_render_impl.cc',
         'video_render_impl.h',
       ],
-      # TODO(andrew): with the proper suffix, these files will be excluded
-      # automatically.
+    },
+    {
+      # Default video_render_module implementation that only supports external
+      # renders.
+      'target_name': 'video_render_module_impl',
+      'type': 'static_library',
+      'dependencies': [
+        'video_render_module',
+      ],
+      'sources': [
+        'video_render_impl.cc',
+      ],
+    },
+    {
+      # video_render_module implementation that supports the internal
+      # video_render implementation.
+      'target_name': 'video_render_module_internal_impl',
+      'type': 'static_library',
+      'dependencies': [
+        'video_render_module',
+      ],
+      'sources': [
+        'video_render_internal_impl.cc',
+      ],
+       # TODO(andrew): with the proper suffix, these files will be excluded
+       # automatically.
       'conditions': [
-        ['include_internal_video_render==1', {
-          'defines': ['WEBRTC_INCLUDE_INTERNAL_VIDEO_RENDER',],
-        }],
-        ['OS=="android" and include_internal_video_render==1', {
+        ['OS=="android"', {
           'sources': [
             'android/video_render_android_impl.h',
             'android/video_render_android_native_opengl2.h',
@@ -52,7 +76,7 @@
             ],
           },
         }],
-        ['OS=="ios" and include_internal_video_render==1', {
+        ['OS=="ios"', {
           'sources': [
             # iOS
             'ios/open_gles20.h',
@@ -66,8 +90,20 @@
             'ios/video_render_ios_view.h',
             'ios/video_render_ios_view.mm',
           ],
+          'xcode_settings': {
+            'CLANG_ENABLE_OBJC_ARC': 'YES',
+          },
+          'all_dependent_settings': {
+            'xcode_settings': {
+              'OTHER_LDFLAGS': [
+                '-framework OpenGLES',
+                '-framework QuartzCore',
+                '-framework UIKit',
+              ],
+            },
+          },
         }],
-        ['OS=="linux" and include_internal_video_render==1', {
+        ['OS=="linux"', {
           'sources': [
             'linux/video_render_linux_impl.h',
             'linux/video_x11_channel.h',
@@ -82,7 +118,7 @@
             ],
           },
         }],
-        ['OS=="mac" and include_internal_video_render==1', {
+        ['OS=="mac"', {
           'sources': [
             'mac/cocoa_full_screen_window.h',
             'mac/cocoa_render_view.h',
@@ -98,21 +134,14 @@
             'mac/cocoa_full_screen_window.mm',
           ],
         }],
-        ['OS=="ios"', {
-          'xcode_settings': {
-            'CLANG_ENABLE_OBJC_ARC': 'YES',
-          },
-          'all_dependent_settings': {
-            'xcode_settings': {
-              'OTHER_LDFLAGS': [
-                '-framework OpenGLES',
-                '-framework QuartzCore',
-                '-framework UIKit',
-              ],
-            },
-          },
-        }],
-        ['OS=="win" and include_internal_video_render==1', {
+        ['OS=="win"', {
+          'sources': [
+            'windows/i_video_render_win.h',
+            'windows/video_render_direct3d9.h',
+            'windows/video_render_windows_impl.h',
+            'windows/video_render_direct3d9.cc',
+            'windows/video_render_windows_impl.cc',
+	  ],
           'variables': {
             # 'directx_sdk_path' will be overridden in the condition block
             # below, but it must not be declared as empty here since gyp
@@ -133,30 +162,18 @@
             '<(directx_sdk_path)/Include',
           ],
         }],
-        ['OS=="win" and include_internal_video_render==1', {
-          'sources': [
-            'windows/i_video_render_win.h',
-            'windows/video_render_direct3d9.h',
-            'windows/video_render_windows_impl.h',
-            'windows/video_render_direct3d9.cc',
-            'windows/video_render_windows_impl.cc',
-          ],
-        }],
       ] # conditions
-    }, # video_render_module
+    },
   ], # targets
 
   'conditions': [
-    ['include_internal_video_render==1', {
-      'defines': ['WEBRTC_INCLUDE_INTERNAL_VIDEO_RENDER',],
-    }],
     ['include_tests==1', {
       'targets': [
         {
           'target_name': 'video_render_tests',
           'type': 'executable',
           'dependencies': [
-            'video_render_module',
+            'video_render_module_internal_impl',
             'webrtc_utility',
             '<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:system_wrappers',
             '<(webrtc_root)/common_video/common_video.gyp:common_video',
diff --git a/modules/video_render/video_render_impl.cc b/modules/video_render/video_render_impl.cc
index 763590f..db0dd5a 100644
--- a/modules/video_render/video_render_impl.cc
+++ b/modules/video_render/video_render_impl.cc
@@ -11,55 +11,14 @@
 #include <assert.h>
 
 #include "webrtc/engine_configurations.h"
-#include "webrtc/modules/video_render/i_video_render.h"
+#include "webrtc/modules/video_render/external/video_render_external_impl.h"
 #include "webrtc/modules/video_render/include/video_render_defines.h"
 #include "webrtc/modules/video_render/incoming_video_stream.h"
+#include "webrtc/modules/video_render/i_video_render.h"
 #include "webrtc/modules/video_render/video_render_impl.h"
 #include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
 #include "webrtc/system_wrappers/interface/trace.h"
 
-#ifdef WEBRTC_INCLUDE_INTERNAL_VIDEO_RENDER
-
-#if defined (_WIN32)
-#include "webrtc/modules/video_render/windows/video_render_windows_impl.h"
-#define STANDARD_RENDERING kRenderWindows
-
-// WEBRTC_IOS should go before WEBRTC_MAC because WEBRTC_MAC
-// gets defined if WEBRTC_IOS is defined
-#elif defined(WEBRTC_IOS)
-#define STANDARD_RENDERING kRenderiOS
-#include "ios/video_render_ios_impl.h"
-#elif defined(WEBRTC_MAC)
-#if defined(COCOA_RENDERING)
-#define STANDARD_RENDERING kRenderCocoa
-#include "webrtc/modules/video_render/mac/video_render_mac_cocoa_impl.h"
-#elif defined(CARBON_RENDERING)
-#define STANDARD_RENDERING kRenderCarbon
-#include "webrtc/modules/video_render/mac/video_render_mac_carbon_impl.h"
-#endif
-
-#elif defined(WEBRTC_ANDROID)
-#include "webrtc/modules/video_render/android/video_render_android_impl.h"
-#include "webrtc/modules/video_render/android/video_render_android_native_opengl2.h"
-#include "webrtc/modules/video_render/android/video_render_android_surface_view.h"
-#define STANDARD_RENDERING kRenderAndroid
-
-#elif defined(WEBRTC_LINUX)
-#include "webrtc/modules/video_render/linux/video_render_linux_impl.h"
-#define STANDARD_RENDERING kRenderX11
-
-#else
-//Other platforms
-#endif
-
-#endif  // WEBRTC_INCLUDE_INTERNAL_VIDEO_RENDER
-
-// For external rendering
-#include "webrtc/modules/video_render/external/video_render_external_impl.h"
-#ifndef STANDARD_RENDERING
-#define STANDARD_RENDERING kRenderExternal
-#endif  // STANDARD_RENDERING
-
 namespace webrtc {
 
 VideoRender*
@@ -71,7 +30,7 @@
     VideoRenderType resultVideoRenderType = videoRenderType;
     if (videoRenderType == kRenderDefault)
     {
-        resultVideoRenderType = STANDARD_RENDERING;
+        resultVideoRenderType = kRenderExternal;
     }
     return new ModuleVideoRenderImpl(id, resultVideoRenderType, window,
                                      fullscreen);
@@ -98,97 +57,6 @@
     // Create platform specific renderer
     switch (videoRenderType)
     {
-#ifdef WEBRTC_INCLUDE_INTERNAL_VIDEO_RENDER
-
-#if defined(_WIN32)
-        case kRenderWindows:
-        {
-            VideoRenderWindowsImpl* ptrRenderer;
-            ptrRenderer = new VideoRenderWindowsImpl(_id, videoRenderType, window, _fullScreen);
-            if (ptrRenderer)
-            {
-                _ptrRenderer = reinterpret_cast<IVideoRender*>(ptrRenderer);
-            }
-        }
-        break;
-
-#elif defined(WEBRTC_IOS)
-        case kRenderiOS:
-        {
-            VideoRenderIosImpl* ptrRenderer = new VideoRenderIosImpl(_id, window, _fullScreen);
-            if(ptrRenderer)
-            {
-                _ptrRenderer = reinterpret_cast<IVideoRender*>(ptrRenderer);
-            }
-        }
-        break;
-
-#elif defined(WEBRTC_MAC)
-
-#if defined(COCOA_RENDERING)
-        case kRenderCocoa:
-        {
-            VideoRenderMacCocoaImpl* ptrRenderer = new VideoRenderMacCocoaImpl(_id, videoRenderType, window, _fullScreen);
-            if(ptrRenderer)
-            {
-                _ptrRenderer = reinterpret_cast<IVideoRender*>(ptrRenderer);
-            }
-        }
-
-        break;
-#elif defined(CARBON_RENDERING)
-        case kRenderCarbon:
-        {
-            VideoRenderMacCarbonImpl* ptrRenderer = new VideoRenderMacCarbonImpl(_id, videoRenderType, window, _fullScreen);
-            if(ptrRenderer)
-            {
-                _ptrRenderer = reinterpret_cast<IVideoRender*>(ptrRenderer);
-            }
-        }
-        break;
-#endif
-
-#elif defined(WEBRTC_ANDROID)
-        case kRenderAndroid:
-        {
-            if(AndroidNativeOpenGl2Renderer::UseOpenGL2(window))
-            {
-                AndroidNativeOpenGl2Renderer* ptrRenderer = NULL;
-                ptrRenderer = new AndroidNativeOpenGl2Renderer(_id, videoRenderType, window, _fullScreen);
-                if (ptrRenderer)
-                {
-                    _ptrRenderer = reinterpret_cast<IVideoRender*> (ptrRenderer);
-                }
-            }
-            else
-            {
-                AndroidSurfaceViewRenderer* ptrRenderer = NULL;
-                ptrRenderer = new AndroidSurfaceViewRenderer(_id, videoRenderType, window, _fullScreen);
-                if (ptrRenderer)
-                {
-                    _ptrRenderer = reinterpret_cast<IVideoRender*> (ptrRenderer);
-                }
-            }
-
-        }
-        break;
-#elif defined(WEBRTC_LINUX)
-        case kRenderX11:
-        {
-            VideoRenderLinuxImpl* ptrRenderer = NULL;
-            ptrRenderer = new VideoRenderLinuxImpl(_id, videoRenderType, window, _fullScreen);
-            if ( ptrRenderer )
-            {
-                _ptrRenderer = reinterpret_cast<IVideoRender*> (ptrRenderer);
-            }
-        }
-        break;
-
-#else
-        // Other platforms
-#endif
-
-#endif  // WEBRTC_INCLUDE_INTERNAL_VIDEO_RENDER
         case kRenderExternal:
         {
             VideoRenderExternalImpl* ptrRenderer(NULL);
@@ -238,66 +106,6 @@
                 delete ptrRenderer;
             }
             break;
-#ifdef WEBRTC_INCLUDE_INTERNAL_VIDEO_RENDER
-
-#if defined(_WIN32)
-            case kRenderWindows:
-            {
-                VideoRenderWindowsImpl* ptrRenderer = reinterpret_cast<VideoRenderWindowsImpl*>(_ptrRenderer);
-                _ptrRenderer = NULL;
-                delete ptrRenderer;
-            }
-            break;
-#elif defined(WEBRTC_IOS)
-            case kRenderiOS:
-            {
-              VideoRenderIosImpl* ptrRenderer = reinterpret_cast<VideoRenderIosImpl*> (_ptrRenderer);
-              _ptrRenderer = NULL;
-              delete ptrRenderer;
-            }
-            break;
-#elif defined(WEBRTC_MAC)
-
-#if defined(COCOA_RENDERING)
-            case kRenderCocoa:
-            {
-                VideoRenderMacCocoaImpl* ptrRenderer = reinterpret_cast<VideoRenderMacCocoaImpl*> (_ptrRenderer);
-                _ptrRenderer = NULL;
-                delete ptrRenderer;
-            }
-            break;
-#elif defined(CARBON_RENDERING)
-            case kRenderCarbon:
-            {
-                VideoRenderMacCarbonImpl* ptrRenderer = reinterpret_cast<VideoRenderMacCarbonImpl*> (_ptrRenderer);
-                _ptrRenderer = NULL;
-                delete ptrRenderer;
-            }
-            break;
-#endif
-
-#elif defined(WEBRTC_ANDROID)
-            case kRenderAndroid:
-            {
-                VideoRenderAndroid* ptrRenderer = reinterpret_cast<VideoRenderAndroid*> (_ptrRenderer);
-                _ptrRenderer = NULL;
-                delete ptrRenderer;
-            }
-            break;
-
-#elif defined(WEBRTC_LINUX)
-            case kRenderX11:
-            {
-                VideoRenderLinuxImpl* ptrRenderer = reinterpret_cast<VideoRenderLinuxImpl*> (_ptrRenderer);
-                _ptrRenderer = NULL;
-                delete ptrRenderer;
-            }
-            break;
-#else
-            //other platforms
-#endif
-
-#endif  // WEBRTC_INCLUDE_INTERNAL_VIDEO_RENDER
 
             default:
                 // Error...
@@ -341,56 +149,7 @@
 
 int32_t ModuleVideoRenderImpl::ChangeWindow(void* window)
 {
-
-    CriticalSectionScoped cs(&_moduleCrit);
-
-#ifdef WEBRTC_INCLUDE_INTERNAL_VIDEO_RENDER
-
-#if defined(WEBRTC_IOS) // WEBRTC_IOS must go before WEBRTC_MAC
-    _ptrRenderer = NULL;
-    delete _ptrRenderer;
-
-    VideoRenderIosImpl* ptrRenderer;
-    ptrRenderer = new VideoRenderIosImpl(_id, window, _fullScreen);
-    if (!ptrRenderer)
-    {
-        return -1;
-    }
-    _ptrRenderer = reinterpret_cast<IVideoRender*>(ptrRenderer);
-    return _ptrRenderer->ChangeWindow(window);
-#elif defined(WEBRTC_MAC)
-
-    _ptrRenderer = NULL;
-    delete _ptrRenderer;
-
-#if defined(COCOA_RENDERING)
-    VideoRenderMacCocoaImpl* ptrRenderer;
-    ptrRenderer = new VideoRenderMacCocoaImpl(_id, kRenderCocoa, window, _fullScreen);
-#elif defined(CARBON_RENDERING)
-    VideoRenderMacCarbonImpl* ptrRenderer;
-    ptrRenderer = new VideoRenderMacCarbonImpl(_id, kRenderCarbon, window, _fullScreen);
-#endif
-    if (!ptrRenderer)
-    {
-        return -1;
-    }
-    _ptrRenderer = reinterpret_cast<IVideoRender*>(ptrRenderer);
-    return _ptrRenderer->ChangeWindow(window);
-
-#else
-    if (!_ptrRenderer)
-    {
-        WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
-                     "%s: No renderer", __FUNCTION__);
-        return -1;
-    }
-    return _ptrRenderer->ChangeWindow(window);
-
-#endif
-
-#else  // WEBRTC_INCLUDE_INTERNAL_VIDEO_RENDER
     return -1;
-#endif
 }
 
 int32_t ModuleVideoRenderImpl::Id()
diff --git a/modules/video_render/video_render_internal_impl.cc b/modules/video_render/video_render_internal_impl.cc
new file mode 100644
index 0000000..106a375
--- /dev/null
+++ b/modules/video_render/video_render_internal_impl.cc
@@ -0,0 +1,917 @@
+/*
+ *  Copyright (c) 2012 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.
+ */
+
+#include <assert.h>
+
+#include "webrtc/engine_configurations.h"
+#include "webrtc/modules/video_render/i_video_render.h"
+#include "webrtc/modules/video_render/include/video_render_defines.h"
+#include "webrtc/modules/video_render/incoming_video_stream.h"
+#include "webrtc/modules/video_render/video_render_impl.h"
+#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
+#include "webrtc/system_wrappers/interface/trace.h"
+
+#if defined (_WIN32)
+#include "webrtc/modules/video_render/windows/video_render_windows_impl.h"
+#define STANDARD_RENDERING kRenderWindows
+
+// WEBRTC_IOS should go before WEBRTC_MAC because WEBRTC_MAC
+// gets defined if WEBRTC_IOS is defined
+#elif defined(WEBRTC_IOS)
+#define STANDARD_RENDERING kRenderiOS
+#include "webrtc/modules/video_render/ios/video_render_ios_impl.h"
+#elif defined(WEBRTC_MAC)
+#if defined(COCOA_RENDERING)
+#define STANDARD_RENDERING kRenderCocoa
+#include "webrtc/modules/video_render/mac/video_render_mac_cocoa_impl.h"
+#elif defined(CARBON_RENDERING)
+#define STANDARD_RENDERING kRenderCarbon
+#include "webrtc/modules/video_render/mac/video_render_mac_carbon_impl.h"
+#endif
+
+#elif defined(WEBRTC_ANDROID)
+#include "webrtc/modules/video_render/android/video_render_android_impl.h"
+#include "webrtc/modules/video_render/android/video_render_android_native_opengl2.h"
+#include "webrtc/modules/video_render/android/video_render_android_surface_view.h"
+#define STANDARD_RENDERING kRenderAndroid
+
+#elif defined(WEBRTC_LINUX)
+#include "webrtc/modules/video_render/linux/video_render_linux_impl.h"
+#define STANDARD_RENDERING kRenderX11
+
+#else
+//Other platforms
+#endif
+
+// For external rendering
+#include "webrtc/modules/video_render/external/video_render_external_impl.h"
+#ifndef STANDARD_RENDERING
+#define STANDARD_RENDERING kRenderExternal
+#endif  // STANDARD_RENDERING
+
+namespace webrtc {
+
+VideoRender*
+VideoRender::CreateVideoRender(const int32_t id,
+                               void* window,
+                               const bool fullscreen,
+                               const VideoRenderType videoRenderType/*=kRenderDefault*/)
+{
+    VideoRenderType resultVideoRenderType = videoRenderType;
+    if (videoRenderType == kRenderDefault)
+    {
+        resultVideoRenderType = STANDARD_RENDERING;
+    }
+    return new ModuleVideoRenderImpl(id, resultVideoRenderType, window,
+                                     fullscreen);
+}
+
+void VideoRender::DestroyVideoRender(
+                                                         VideoRender* module)
+{
+    if (module)
+    {
+        delete module;
+    }
+}
+
+ModuleVideoRenderImpl::ModuleVideoRenderImpl(
+                                             const int32_t id,
+                                             const VideoRenderType videoRenderType,
+                                             void* window,
+                                             const bool fullscreen) :
+    _id(id), _moduleCrit(*CriticalSectionWrapper::CreateCriticalSection()),
+    _ptrWindow(window), _fullScreen(fullscreen), _ptrRenderer(NULL)
+{
+
+    // Create platform specific renderer
+    switch (videoRenderType)
+    {
+#if defined(_WIN32)
+        case kRenderWindows:
+        {
+            VideoRenderWindowsImpl* ptrRenderer;
+            ptrRenderer = new VideoRenderWindowsImpl(_id, videoRenderType, window, _fullScreen);
+            if (ptrRenderer)
+            {
+                _ptrRenderer = reinterpret_cast<IVideoRender*>(ptrRenderer);
+            }
+        }
+        break;
+
+#elif defined(WEBRTC_IOS)
+        case kRenderiOS:
+        {
+            VideoRenderIosImpl* ptrRenderer = new VideoRenderIosImpl(_id, window, _fullScreen);
+            if(ptrRenderer)
+            {
+                _ptrRenderer = reinterpret_cast<IVideoRender*>(ptrRenderer);
+            }
+        }
+        break;
+
+#elif defined(WEBRTC_MAC)
+
+#if defined(COCOA_RENDERING)
+        case kRenderCocoa:
+        {
+            VideoRenderMacCocoaImpl* ptrRenderer = new VideoRenderMacCocoaImpl(_id, videoRenderType, window, _fullScreen);
+            if(ptrRenderer)
+            {
+                _ptrRenderer = reinterpret_cast<IVideoRender*>(ptrRenderer);
+            }
+        }
+
+        break;
+#elif defined(CARBON_RENDERING)
+        case kRenderCarbon:
+        {
+            VideoRenderMacCarbonImpl* ptrRenderer = new VideoRenderMacCarbonImpl(_id, videoRenderType, window, _fullScreen);
+            if(ptrRenderer)
+            {
+                _ptrRenderer = reinterpret_cast<IVideoRender*>(ptrRenderer);
+            }
+        }
+        break;
+#endif
+
+#elif defined(WEBRTC_ANDROID)
+        case kRenderAndroid:
+        {
+            if(AndroidNativeOpenGl2Renderer::UseOpenGL2(window))
+            {
+                AndroidNativeOpenGl2Renderer* ptrRenderer = NULL;
+                ptrRenderer = new AndroidNativeOpenGl2Renderer(_id, videoRenderType, window, _fullScreen);
+                if (ptrRenderer)
+                {
+                    _ptrRenderer = reinterpret_cast<IVideoRender*> (ptrRenderer);
+                }
+            }
+            else
+            {
+                AndroidSurfaceViewRenderer* ptrRenderer = NULL;
+                ptrRenderer = new AndroidSurfaceViewRenderer(_id, videoRenderType, window, _fullScreen);
+                if (ptrRenderer)
+                {
+                    _ptrRenderer = reinterpret_cast<IVideoRender*> (ptrRenderer);
+                }
+            }
+
+        }
+        break;
+#elif defined(WEBRTC_LINUX)
+        case kRenderX11:
+        {
+            VideoRenderLinuxImpl* ptrRenderer = NULL;
+            ptrRenderer = new VideoRenderLinuxImpl(_id, videoRenderType, window, _fullScreen);
+            if ( ptrRenderer )
+            {
+                _ptrRenderer = reinterpret_cast<IVideoRender*> (ptrRenderer);
+            }
+        }
+        break;
+
+#else
+        // Other platforms
+#endif
+        case kRenderExternal:
+        {
+            VideoRenderExternalImpl* ptrRenderer(NULL);
+            ptrRenderer = new VideoRenderExternalImpl(_id, videoRenderType,
+                                                      window, _fullScreen);
+            if (ptrRenderer)
+            {
+                _ptrRenderer = reinterpret_cast<IVideoRender*> (ptrRenderer);
+            }
+        }
+            break;
+        default:
+            // Error...
+            break;
+    }
+    if (_ptrRenderer)
+    {
+        if (_ptrRenderer->Init() == -1)
+        {
+        }
+    }
+}
+
+ModuleVideoRenderImpl::~ModuleVideoRenderImpl()
+{
+    delete &_moduleCrit;
+
+    for (IncomingVideoStreamMap::iterator it = _streamRenderMap.begin();
+         it != _streamRenderMap.end();
+         ++it) {
+      delete it->second;
+    }
+
+    // Delete platform specific renderer
+    if (_ptrRenderer)
+    {
+        VideoRenderType videoRenderType = _ptrRenderer->RenderType();
+
+        switch (videoRenderType)
+        {
+            case kRenderExternal:
+            {
+                VideoRenderExternalImpl
+                        * ptrRenderer =
+                                reinterpret_cast<VideoRenderExternalImpl*> (_ptrRenderer);
+                _ptrRenderer = NULL;
+                delete ptrRenderer;
+            }
+            break;
+#if defined(_WIN32)
+            case kRenderWindows:
+            {
+                VideoRenderWindowsImpl* ptrRenderer = reinterpret_cast<VideoRenderWindowsImpl*>(_ptrRenderer);
+                _ptrRenderer = NULL;
+                delete ptrRenderer;
+            }
+            break;
+#elif defined(WEBRTC_IOS)
+            case kRenderiOS:
+            {
+              VideoRenderIosImpl* ptrRenderer = reinterpret_cast<VideoRenderIosImpl*> (_ptrRenderer);
+              _ptrRenderer = NULL;
+              delete ptrRenderer;
+            }
+            break;
+#elif defined(WEBRTC_MAC)
+
+#if defined(COCOA_RENDERING)
+            case kRenderCocoa:
+            {
+                VideoRenderMacCocoaImpl* ptrRenderer = reinterpret_cast<VideoRenderMacCocoaImpl*> (_ptrRenderer);
+                _ptrRenderer = NULL;
+                delete ptrRenderer;
+            }
+            break;
+#elif defined(CARBON_RENDERING)
+            case kRenderCarbon:
+            {
+                VideoRenderMacCarbonImpl* ptrRenderer = reinterpret_cast<VideoRenderMacCarbonImpl*> (_ptrRenderer);
+                _ptrRenderer = NULL;
+                delete ptrRenderer;
+            }
+            break;
+#endif
+
+#elif defined(WEBRTC_ANDROID)
+            case kRenderAndroid:
+            {
+                VideoRenderAndroid* ptrRenderer = reinterpret_cast<VideoRenderAndroid*> (_ptrRenderer);
+                _ptrRenderer = NULL;
+                delete ptrRenderer;
+            }
+            break;
+
+#elif defined(WEBRTC_LINUX)
+            case kRenderX11:
+            {
+                VideoRenderLinuxImpl* ptrRenderer = reinterpret_cast<VideoRenderLinuxImpl*> (_ptrRenderer);
+                _ptrRenderer = NULL;
+                delete ptrRenderer;
+            }
+            break;
+#else
+            //other platforms
+#endif
+
+            default:
+                // Error...
+                break;
+        }
+    }
+}
+
+int32_t ModuleVideoRenderImpl::ChangeUniqueId(const int32_t id)
+{
+
+    CriticalSectionScoped cs(&_moduleCrit);
+
+    _id = id;
+
+    if (_ptrRenderer)
+    {
+        _ptrRenderer->ChangeUniqueId(_id);
+    }
+
+    return 0;
+}
+
+int32_t ModuleVideoRenderImpl::TimeUntilNextProcess()
+{
+    // Not used
+    return 50;
+}
+int32_t ModuleVideoRenderImpl::Process()
+{
+    // Not used
+    return 0;
+}
+
+void*
+ModuleVideoRenderImpl::Window()
+{
+    CriticalSectionScoped cs(&_moduleCrit);
+    return _ptrWindow;
+}
+
+int32_t ModuleVideoRenderImpl::ChangeWindow(void* window)
+{
+
+    CriticalSectionScoped cs(&_moduleCrit);
+
+#if defined(WEBRTC_IOS) // WEBRTC_IOS must go before WEBRTC_MAC
+    _ptrRenderer = NULL;
+    delete _ptrRenderer;
+
+    VideoRenderIosImpl* ptrRenderer;
+    ptrRenderer = new VideoRenderIosImpl(_id, window, _fullScreen);
+    if (!ptrRenderer)
+    {
+        return -1;
+    }
+    _ptrRenderer = reinterpret_cast<IVideoRender*>(ptrRenderer);
+    return _ptrRenderer->ChangeWindow(window);
+#elif defined(WEBRTC_MAC)
+
+    _ptrRenderer = NULL;
+    delete _ptrRenderer;
+
+#if defined(COCOA_RENDERING)
+    VideoRenderMacCocoaImpl* ptrRenderer;
+    ptrRenderer = new VideoRenderMacCocoaImpl(_id, kRenderCocoa, window, _fullScreen);
+#elif defined(CARBON_RENDERING)
+    VideoRenderMacCarbonImpl* ptrRenderer;
+    ptrRenderer = new VideoRenderMacCarbonImpl(_id, kRenderCarbon, window, _fullScreen);
+#endif
+    if (!ptrRenderer)
+    {
+        return -1;
+    }
+    _ptrRenderer = reinterpret_cast<IVideoRender*>(ptrRenderer);
+    return _ptrRenderer->ChangeWindow(window);
+
+#else
+    if (!_ptrRenderer)
+    {
+        WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
+                     "%s: No renderer", __FUNCTION__);
+        return -1;
+    }
+    return _ptrRenderer->ChangeWindow(window);
+
+#endif
+}
+
+int32_t ModuleVideoRenderImpl::Id()
+{
+    CriticalSectionScoped cs(&_moduleCrit);
+    return _id;
+}
+
+uint32_t ModuleVideoRenderImpl::GetIncomingFrameRate(const uint32_t streamId) {
+  CriticalSectionScoped cs(&_moduleCrit);
+
+  IncomingVideoStreamMap::iterator it = _streamRenderMap.find(streamId);
+
+  if (it == _streamRenderMap.end()) {
+    // This stream doesn't exist
+    WEBRTC_TRACE(kTraceError,
+                 kTraceVideoRenderer,
+                 _id,
+                 "%s: stream doesn't exist",
+                 __FUNCTION__);
+    return 0;
+  }
+  assert(it->second != NULL);
+  return it->second->IncomingRate();
+}
+
+VideoRenderCallback*
+ModuleVideoRenderImpl::AddIncomingRenderStream(const uint32_t streamId,
+                                               const uint32_t zOrder,
+                                               const float left,
+                                               const float top,
+                                               const float right,
+                                               const float bottom)
+{
+    CriticalSectionScoped cs(&_moduleCrit);
+
+    if (!_ptrRenderer)
+    {
+        WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
+                     "%s: No renderer", __FUNCTION__);
+        return NULL;
+    }
+
+    if (_streamRenderMap.find(streamId) != _streamRenderMap.end()) {
+        // The stream already exists...
+        WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
+                     "%s: stream already exists", __FUNCTION__);
+        return NULL;
+    }
+
+    VideoRenderCallback* ptrRenderCallback =
+            _ptrRenderer->AddIncomingRenderStream(streamId, zOrder, left, top,
+                                                  right, bottom);
+    if (ptrRenderCallback == NULL)
+    {
+        WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
+                     "%s: Can't create incoming stream in renderer",
+                     __FUNCTION__);
+        return NULL;
+    }
+
+    // Create platform independant code
+    IncomingVideoStream* ptrIncomingStream = new IncomingVideoStream(_id,
+                                                                     streamId);
+    if (ptrIncomingStream == NULL)
+    {
+        WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
+                     "%s: Can't create incoming stream", __FUNCTION__);
+        return NULL;
+    }
+
+
+    if (ptrIncomingStream->SetRenderCallback(ptrRenderCallback) == -1)
+    {
+        WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
+                     "%s: Can't set render callback", __FUNCTION__);
+        delete ptrIncomingStream;
+        _ptrRenderer->DeleteIncomingRenderStream(streamId);
+        return NULL;
+    }
+
+    VideoRenderCallback* moduleCallback =
+            ptrIncomingStream->ModuleCallback();
+
+    // Store the stream
+    _streamRenderMap[streamId] = ptrIncomingStream;
+
+    return moduleCallback;
+}
+
+int32_t ModuleVideoRenderImpl::DeleteIncomingRenderStream(
+                                                                const uint32_t streamId)
+{
+    CriticalSectionScoped cs(&_moduleCrit);
+
+    if (!_ptrRenderer)
+    {
+        WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
+                     "%s: No renderer", __FUNCTION__);
+        return -1;
+    }
+
+    IncomingVideoStreamMap::iterator item = _streamRenderMap.find(streamId);
+    if (item == _streamRenderMap.end())
+    {
+        WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
+                     "%s: stream doesn't exist", __FUNCTION__);
+        return -1;
+    }
+
+    delete item->second;
+
+    _ptrRenderer->DeleteIncomingRenderStream(streamId);
+
+    _streamRenderMap.erase(item);
+
+    return 0;
+}
+
+int32_t ModuleVideoRenderImpl::AddExternalRenderCallback(
+    const uint32_t streamId,
+    VideoRenderCallback* renderObject) {
+    CriticalSectionScoped cs(&_moduleCrit);
+
+    IncomingVideoStreamMap::iterator item = _streamRenderMap.find(streamId);
+
+    if (item == _streamRenderMap.end())
+    {
+        WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
+                     "%s: stream doesn't exist", __FUNCTION__);
+        return -1;
+    }
+
+    if (item->second == NULL) {
+        WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
+                     "%s: could not get stream", __FUNCTION__);
+        return -1;
+    }
+    return item->second->SetExternalCallback(renderObject);
+}
+
+int32_t ModuleVideoRenderImpl::GetIncomingRenderStreamProperties(
+    const uint32_t streamId,
+    uint32_t& zOrder,
+    float& left,
+    float& top,
+    float& right,
+    float& bottom) const {
+    CriticalSectionScoped cs(&_moduleCrit);
+
+    if (!_ptrRenderer)
+    {
+        WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
+                     "%s: No renderer", __FUNCTION__);
+        return -1;
+    }
+
+    return _ptrRenderer->GetIncomingRenderStreamProperties(streamId, zOrder,
+                                                           left, top, right,
+                                                           bottom);
+}
+
+uint32_t ModuleVideoRenderImpl::GetNumIncomingRenderStreams() const
+{
+    CriticalSectionScoped cs(&_moduleCrit);
+
+    return static_cast<uint32_t>(_streamRenderMap.size());
+}
+
+bool ModuleVideoRenderImpl::HasIncomingRenderStream(
+    const uint32_t streamId) const {
+  CriticalSectionScoped cs(&_moduleCrit);
+
+  return _streamRenderMap.find(streamId) != _streamRenderMap.end();
+}
+
+int32_t ModuleVideoRenderImpl::RegisterRawFrameCallback(
+    const uint32_t streamId,
+    VideoRenderCallback* callbackObj) {
+  return -1;
+}
+
+int32_t ModuleVideoRenderImpl::StartRender(const uint32_t streamId)
+{
+    CriticalSectionScoped cs(&_moduleCrit);
+
+    if (!_ptrRenderer)
+    {
+        WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
+                     "%s: No renderer", __FUNCTION__);
+        return -1;
+    }
+
+    // Start the stream
+    IncomingVideoStreamMap::iterator item = _streamRenderMap.find(streamId);
+
+    if (item == _streamRenderMap.end())
+    {
+        return -1;
+    }
+
+    if (item->second->Start() == -1)
+    {
+        return -1;
+    }
+
+    // Start the HW renderer
+    if (_ptrRenderer->StartRender() == -1)
+    {
+        return -1;
+    }
+    return 0;
+}
+
+int32_t ModuleVideoRenderImpl::StopRender(const uint32_t streamId)
+{
+    CriticalSectionScoped cs(&_moduleCrit);
+
+    if (!_ptrRenderer)
+    {
+        WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
+                     "%s(%d): No renderer", __FUNCTION__, streamId);
+        return -1;
+    }
+
+    // Stop the incoming stream
+    IncomingVideoStreamMap::iterator item = _streamRenderMap.find(streamId);
+
+    if (item == _streamRenderMap.end())
+    {
+        return -1;
+    }
+
+    if (item->second->Stop() == -1)
+    {
+        return -1;
+    }
+
+    return 0;
+}
+
+int32_t ModuleVideoRenderImpl::ResetRender()
+{
+    CriticalSectionScoped cs(&_moduleCrit);
+
+    int32_t ret = 0;
+    // Loop through all incoming streams and reset them
+    for (IncomingVideoStreamMap::iterator it = _streamRenderMap.begin();
+         it != _streamRenderMap.end();
+         ++it) {
+      if (it->second->Reset() == -1)
+        ret = -1;
+    }
+    return ret;
+}
+
+RawVideoType ModuleVideoRenderImpl::PreferredVideoType() const
+{
+    CriticalSectionScoped cs(&_moduleCrit);
+
+    if (_ptrRenderer == NULL)
+    {
+        return kVideoI420;
+    }
+
+    return _ptrRenderer->PerferedVideoType();
+}
+
+bool ModuleVideoRenderImpl::IsFullScreen()
+{
+    CriticalSectionScoped cs(&_moduleCrit);
+
+    if (!_ptrRenderer)
+    {
+        WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
+                     "%s: No renderer", __FUNCTION__);
+        return false;
+    }
+    return _ptrRenderer->FullScreen();
+}
+
+int32_t ModuleVideoRenderImpl::GetScreenResolution(
+                                                         uint32_t& screenWidth,
+                                                         uint32_t& screenHeight) const
+{
+    CriticalSectionScoped cs(&_moduleCrit);
+
+    if (!_ptrRenderer)
+    {
+        WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
+                     "%s: No renderer", __FUNCTION__);
+        return false;
+    }
+    return _ptrRenderer->GetScreenResolution(screenWidth, screenHeight);
+}
+
+uint32_t ModuleVideoRenderImpl::RenderFrameRate(
+                                                      const uint32_t streamId)
+{
+    CriticalSectionScoped cs(&_moduleCrit);
+
+    if (!_ptrRenderer)
+    {
+        WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
+                     "%s: No renderer", __FUNCTION__);
+        return false;
+    }
+    return _ptrRenderer->RenderFrameRate(streamId);
+}
+
+int32_t ModuleVideoRenderImpl::SetStreamCropping(
+                                                       const uint32_t streamId,
+                                                       const float left,
+                                                       const float top,
+                                                       const float right,
+                                                       const float bottom)
+{
+    CriticalSectionScoped cs(&_moduleCrit);
+
+    if (!_ptrRenderer)
+    {
+        WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
+                     "%s: No renderer", __FUNCTION__);
+        return false;
+    }
+    return _ptrRenderer->SetStreamCropping(streamId, left, top, right, bottom);
+}
+
+int32_t ModuleVideoRenderImpl::SetTransparentBackground(const bool enable)
+{
+    CriticalSectionScoped cs(&_moduleCrit);
+
+    if (!_ptrRenderer)
+    {
+        WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
+                     "%s: No renderer", __FUNCTION__);
+        return false;
+    }
+    return _ptrRenderer->SetTransparentBackground(enable);
+}
+
+int32_t ModuleVideoRenderImpl::FullScreenRender(void* window, const bool enable)
+{
+    return -1;
+}
+
+int32_t ModuleVideoRenderImpl::SetText(
+                                             const uint8_t textId,
+                                             const uint8_t* text,
+                                             const int32_t textLength,
+                                             const uint32_t textColorRef,
+                                             const uint32_t backgroundColorRef,
+                                             const float left, const float top,
+                                             const float right,
+                                             const float bottom)
+{
+    CriticalSectionScoped cs(&_moduleCrit);
+
+    if (!_ptrRenderer)
+    {
+        WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
+                     "%s: No renderer", __FUNCTION__);
+        return -1;
+    }
+    return _ptrRenderer->SetText(textId, text, textLength, textColorRef,
+                                 backgroundColorRef, left, top, right, bottom);
+}
+
+int32_t ModuleVideoRenderImpl::SetBitmap(const void* bitMap,
+                                         const uint8_t pictureId,
+                                         const void* colorKey,
+                                         const float left,
+                                         const float top,
+                                         const float right,
+                                         const float bottom)
+{
+    CriticalSectionScoped cs(&_moduleCrit);
+
+    if (!_ptrRenderer)
+    {
+        WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
+                     "%s: No renderer", __FUNCTION__);
+        return -1;
+    }
+    return _ptrRenderer->SetBitmap(bitMap, pictureId, colorKey, left, top,
+                                   right, bottom);
+}
+
+int32_t ModuleVideoRenderImpl::GetLastRenderedFrame(
+    const uint32_t streamId,
+    I420VideoFrame &frame) const
+{
+    CriticalSectionScoped cs(&_moduleCrit);
+
+    if (!_ptrRenderer)
+    {
+        WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
+                     "%s: No renderer", __FUNCTION__);
+        return -1;
+    }
+
+    IncomingVideoStreamMap::const_iterator item =
+        _streamRenderMap.find(streamId);
+    if (item == _streamRenderMap.end())
+    {
+        // This stream doesn't exist
+        WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
+                     "%s: stream doesn't exist", __FUNCTION__);
+        return 0;
+    }
+
+    assert(item->second != NULL);
+    return item->second->GetLastRenderedFrame(frame);
+}
+
+int32_t ModuleVideoRenderImpl::SetExpectedRenderDelay(
+    uint32_t stream_id, int32_t delay_ms) {
+  CriticalSectionScoped cs(&_moduleCrit);
+
+  if (!_ptrRenderer) {
+    WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
+                 "%s: No renderer", __FUNCTION__);
+    return false;
+  }
+
+  IncomingVideoStreamMap::const_iterator item =
+      _streamRenderMap.find(stream_id);
+  if (item == _streamRenderMap.end()) {
+    // This stream doesn't exist
+    WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
+                 "%s(%u, %d): stream doesn't exist", __FUNCTION__, stream_id,
+                 delay_ms);
+    return -1;
+  }
+
+  assert(item->second != NULL);
+  return item->second->SetExpectedRenderDelay(delay_ms);
+}
+
+int32_t ModuleVideoRenderImpl::ConfigureRenderer(
+                                                       const uint32_t streamId,
+                                                       const unsigned int zOrder,
+                                                       const float left,
+                                                       const float top,
+                                                       const float right,
+                                                       const float bottom)
+{
+    CriticalSectionScoped cs(&_moduleCrit);
+
+    if (!_ptrRenderer)
+    {
+        WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
+                     "%s: No renderer", __FUNCTION__);
+        return false;
+    }
+    return _ptrRenderer->ConfigureRenderer(streamId, zOrder, left, top, right,
+                                           bottom);
+}
+
+int32_t ModuleVideoRenderImpl::SetStartImage(
+    const uint32_t streamId,
+    const I420VideoFrame& videoFrame)
+{
+    CriticalSectionScoped cs(&_moduleCrit);
+
+    if (!_ptrRenderer)
+    {
+        WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
+                     "%s: No renderer", __FUNCTION__);
+        return -1;
+    }
+
+    IncomingVideoStreamMap::const_iterator item =
+        _streamRenderMap.find(streamId);
+    if (item == _streamRenderMap.end())
+    {
+        // This stream doesn't exist
+        WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
+                     "%s: stream doesn't exist", __FUNCTION__);
+        return -1;
+    }
+    assert (item->second != NULL);
+    return item->second->SetStartImage(videoFrame);
+
+}
+
+int32_t ModuleVideoRenderImpl::SetTimeoutImage(
+    const uint32_t streamId,
+    const I420VideoFrame& videoFrame,
+    const uint32_t timeout)
+{
+    CriticalSectionScoped cs(&_moduleCrit);
+
+    if (!_ptrRenderer)
+    {
+        WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
+                     "%s: No renderer", __FUNCTION__);
+        return -1;
+    }
+
+    IncomingVideoStreamMap::const_iterator item =
+        _streamRenderMap.find(streamId);
+    if (item == _streamRenderMap.end())
+    {
+        // This stream doesn't exist
+        WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
+                     "%s: stream doesn't exist", __FUNCTION__);
+        return -1;
+    }
+    assert(item->second != NULL);
+    return item->second->SetTimeoutImage(videoFrame, timeout);
+}
+
+int32_t ModuleVideoRenderImpl::MirrorRenderStream(const int renderId,
+                                                  const bool enable,
+                                                  const bool mirrorXAxis,
+                                                  const bool mirrorYAxis)
+{
+    CriticalSectionScoped cs(&_moduleCrit);
+
+    if (!_ptrRenderer)
+    {
+        WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
+                     "%s: No renderer", __FUNCTION__);
+        return -1;
+    }
+
+    IncomingVideoStreamMap::const_iterator item =
+        _streamRenderMap.find(renderId);
+    if (item == _streamRenderMap.end())
+    {
+        // This stream doesn't exist
+        WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
+                     "%s: stream doesn't exist", __FUNCTION__);
+        return 0;
+    }
+    assert(item->second != NULL);
+
+    return item->second->EnableMirroring(enable, mirrorXAxis, mirrorYAxis);
+}
+
+}  // namespace webrtc
diff --git a/test/webrtc_test_common.gyp b/test/webrtc_test_common.gyp
index 9d7cfce..98b9577 100644
--- a/test/webrtc_test_common.gyp
+++ b/test/webrtc_test_common.gyp
@@ -60,6 +60,7 @@
         '<(DEPTH)/third_party/gflags/gflags.gyp:gflags',
         '<(webrtc_root)/modules/modules.gyp:media_file',
         '<(webrtc_root)/modules/modules.gyp:video_capture_module_impl',
+        '<(webrtc_root)/modules/modules.gyp:video_render_module_impl',
         '<(webrtc_root)/test/test.gyp:frame_generator',
         '<(webrtc_root)/test/test.gyp:test_support',
         '<(webrtc_root)/webrtc.gyp:webrtc',
@@ -103,11 +104,29 @@
           'sources!': [
             'null_platform_renderer.cc',
           ],
+          'variables': {
+            # 'directx_sdk_path' will be overridden in the condition block
+            # below, but it must not be declared as empty here since gyp
+            # will check if the first character is '/' for some reason.
+            # If it's empty, we'll get an out-of-bounds error.
+            'directx_sdk_path': 'will_be_overridden',
+            'directx_sdk_default_path': '<(DEPTH)/third_party/directxsdk/files',
+            'conditions': [
+              ['"<!(python <(DEPTH)/build/dir_exists.py <(directx_sdk_default_path))"=="True"', {
+                'directx_sdk_path': '<(DEPTH)/third_party/directxsdk/files',
+              }, {
+                'directx_sdk_path': '$(DXSDK_DIR)',
+              }],
+            ],
+          },
+
+          'include_dirs': [
+            '<(directx_sdk_path)/Include',
+          ],
         }],
       ],
       'dependencies': [
         '<(DEPTH)/testing/gtest.gyp:gtest',
-        '<(webrtc_root)/modules/modules.gyp:video_capture_module_internal_impl',
         '<(webrtc_root)/modules/modules.gyp:media_file',
         '<(webrtc_root)/test/test.gyp:frame_generator',
         '<(webrtc_root)/test/test.gyp:test_support',
diff --git a/test/win/d3d_renderer.h b/test/win/d3d_renderer.h
index e8b0692..7f37535 100644
--- a/test/win/d3d_renderer.h
+++ b/test/win/d3d_renderer.h
@@ -12,6 +12,7 @@
 
 #include <Windows.h>
 #include <d3d9.h>
+#pragma comment(lib, "d3d9.lib")       // located in DirectX SDK
 
 #include "webrtc/system_wrappers/interface/scoped_refptr.h"
 #include "webrtc/test/video_renderer.h"
diff --git a/video/bitrate_estimator_tests.cc b/video/bitrate_estimator_tests.cc
index 9b55cd1..40c1ed6 100644
--- a/video/bitrate_estimator_tests.cc
+++ b/video/bitrate_estimator_tests.cc
@@ -26,9 +26,6 @@
 #include "webrtc/test/fake_encoder.h"
 #include "webrtc/test/frame_generator_capturer.h"
 
-// Disabled on Android since all tests currently fail (webrtc:3770).
-#ifndef WEBRTC_ANDROID
-
 namespace webrtc {
 namespace {
 // Note: consider to write tests that don't depend on the trace system instead
@@ -332,5 +329,3 @@
   EXPECT_EQ(kEventSignaled, receiver_trace_.Wait());
 }
 }  // namespace webrtc
-
-#endif // !WEBRTC_ANDROID
diff --git a/video/call_perf_tests.cc b/video/call_perf_tests.cc
index 3d1bf7f..557c514 100644
--- a/video/call_perf_tests.cc
+++ b/video/call_perf_tests.cc
@@ -41,9 +41,6 @@
 #include "webrtc/voice_engine/include/voe_rtp_rtcp.h"
 #include "webrtc/voice_engine/include/voe_video_sync.h"
 
-// Disabled on Android since all these tests currently fail (webrtc:3770).
-#ifndef WEBRTC_ANDROID
-
 namespace webrtc {
 
 class CallPerfTest : public test::CallTest {
@@ -579,5 +576,3 @@
 }
 
 }  // namespace webrtc
-
-#endif // !WEBRTC_ANDROID
diff --git a/video/end_to_end_tests.cc b/video/end_to_end_tests.cc
index a83eddc..46420ec 100644
--- a/video/end_to_end_tests.cc
+++ b/video/end_to_end_tests.cc
@@ -34,13 +34,11 @@
 #include "webrtc/test/null_transport.h"
 #include "webrtc/test/rtp_rtcp_observer.h"
 #include "webrtc/test/testsupport/fileutils.h"
+#include "webrtc/test/testsupport/gtest_disable.h"
 #include "webrtc/test/testsupport/perf_test.h"
 #include "webrtc/video/transport_adapter.h"
 #include "webrtc/video_encoder.h"
 
-// Disabled on Android since all tests currently fail (webrtc:3770).
-#ifndef WEBRTC_ANDROID
-
 namespace webrtc {
 
 static const unsigned long kSilenceTimeoutMs = 2000;
@@ -580,7 +578,8 @@
   DecodesRetransmittedFrame(true);
 }
 
-TEST_F(EndToEndTest, UsesFrameCallbacks) {
+// Disabled due to: https://code.google.com/p/webrtc/issues/detail?id=3770
+TEST_F(EndToEndTest, DISABLED_ON_ANDROID(UsesFrameCallbacks)) {
   static const int kWidth = 320;
   static const int kHeight = 240;
 
@@ -926,7 +925,9 @@
 // Another is set up to receive all three of these with different renderers.
 // Each renderer verifies that it receives the expected resolution, and as soon
 // as every renderer has received a frame, the test finishes.
-TEST_F(EndToEndTest, SendsAndReceivesMultipleStreams) {
+//
+// Disabled due to: https://code.google.com/p/webrtc/issues/detail?id=3770
+TEST_F(EndToEndTest, DISABLED_ON_ANDROID(SendsAndReceivesMultipleStreams)) {
   static const size_t kNumStreams = 3;
 
   class VideoOutputObserver : public VideoRenderer {
@@ -2076,5 +2077,3 @@
   DestroyStreams();
 }
 }  // namespace webrtc
-
-#endif // !WEBRTC_ANDROID
diff --git a/video/full_stack.cc b/video/full_stack.cc
index 54abd1f..cd1190c 100644
--- a/video/full_stack.cc
+++ b/video/full_stack.cc
@@ -32,9 +32,6 @@
 #include "webrtc/test/testsupport/fileutils.h"
 #include "webrtc/typedefs.h"
 
-// Disabled on Android since all tests currently fail (webrtc:3770).
-#ifndef WEBRTC_ANDROID
-
 namespace webrtc {
 
 static const int kFullStackTestDurationSecs = 60;
@@ -535,5 +532,3 @@
   RunTest(foreman_cif);
 }
 }  // namespace webrtc
-
-#endif // !WEBRTC_ANDROID
diff --git a/video_engine/test/auto_test/vie_auto_test.gypi b/video_engine/test/auto_test/vie_auto_test.gypi
index 6029084..a415b3b 100644
--- a/video_engine/test/auto_test/vie_auto_test.gypi
+++ b/video_engine/test/auto_test/vie_auto_test.gypi
@@ -14,8 +14,8 @@
       'dependencies': [
         '<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:system_wrappers',
         '<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:field_trial_default',
-        '<(webrtc_root)/modules/modules.gyp:video_render_module',
         '<(webrtc_root)/modules/modules.gyp:video_capture_module_internal_impl',
+        '<(webrtc_root)/modules/modules.gyp:video_render_module_internal_impl',
         '<(webrtc_root)/voice_engine/voice_engine.gyp:voice_engine',
         '<(DEPTH)/testing/gtest.gyp:gtest',
         '<(DEPTH)/third_party/gflags/gflags.gyp:gflags',
diff --git a/video_engine/video_engine_core.gypi b/video_engine/video_engine_core.gypi
index ffe63c5..fd61043 100644
--- a/video_engine/video_engine_core.gypi
+++ b/video_engine/video_engine_core.gypi
@@ -123,6 +123,7 @@
           'dependencies': [
             'video_engine_core',
             '<(webrtc_root)/modules/modules.gyp:video_capture_module_internal_impl',
+	    '<(webrtc_root)/modules/modules.gyp:video_render_module_internal_impl',
             '<(DEPTH)/testing/gtest.gyp:gtest',
             '<(DEPTH)/testing/gmock.gyp:gmock',
             '<(webrtc_root)/test/test.gyp:test_support_main',
diff --git a/webrtc.gyp b/webrtc.gyp
index b17077b..dee366c 100644
--- a/webrtc.gyp
+++ b/webrtc.gyp
@@ -78,6 +78,16 @@
         'common.gyp:*',
         '<@(webrtc_video_dependencies)',
       ],
+      'conditions': [
+        # TODO(andresp): Chromium libpeerconnection should link directly with
+	# this and no if conditions should be needed on webrtc build files.
+        ['build_with_chromium==1', {
+	  'dependencies': [
+	    '<(webrtc_root)/modules/modules.gyp:video_capture_module_impl',
+	    '<(webrtc_root)/modules/modules.gyp:video_render_module_impl',
+	  ],
+	}],
+      ],
     },
   ],
 }
diff --git a/webrtc_examples.gyp b/webrtc_examples.gyp
index f4e3f6f..1af259c 100644
--- a/webrtc_examples.gyp
+++ b/webrtc_examples.gyp
@@ -16,6 +16,7 @@
           'dependencies': [
             '<(DEPTH)/third_party/icu/icu.gyp:icuuc',
             '<(webrtc_root)/modules/modules.gyp:video_capture_module_internal_impl',
+	    '<(webrtc_root)/modules/modules.gyp:video_render_module_internal_impl',
             '<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:field_trial_default',
             '<(webrtc_root)/test/test.gyp:channel_transport',
             '<(webrtc_root)/video_engine/video_engine.gyp:video_engine_core',
diff --git a/webrtc_tests.gypi b/webrtc_tests.gypi
index 7584954..833fef9 100644
--- a/webrtc_tests.gypi
+++ b/webrtc_tests.gypi
@@ -48,6 +48,7 @@
         '<(DEPTH)/third_party/gflags/gflags.gyp:gflags',
         'test/webrtc_test_common.gyp:webrtc_test_common',
         'test/webrtc_test_common.gyp:webrtc_test_renderer',
+        '<(webrtc_root)/modules/modules.gyp:video_render_module_impl',
         '<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:field_trial_default',
         'webrtc',
       ],
@@ -71,9 +72,10 @@
       'dependencies': [
         '<(DEPTH)/testing/gtest.gyp:gtest',
         '<(DEPTH)/third_party/gflags/gflags.gyp:gflags',
-        'system_wrappers/source/system_wrappers.gyp:field_trial_default',
         'test/webrtc_test_common.gyp:webrtc_test_common',
         'test/webrtc_test_common.gyp:webrtc_test_renderer',
+        '<(webrtc_root)/modules/modules.gyp:video_render_module_impl',
+        '<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:field_trial_default',
         'webrtc',
       ],
     },
@@ -90,7 +92,8 @@
       ],
       'dependencies': [
         '<(DEPTH)/testing/gtest.gyp:gtest',
-        'modules/modules.gyp:rtp_rtcp',
+        '<(webrtc_root)/modules/modules.gyp:rtp_rtcp',
+        '<(webrtc_root)/modules/modules.gyp:video_render_module_impl',
         'test/metrics.gyp:metrics',
         'test/webrtc_test_common.gyp:webrtc_test_common',
         'test/test.gyp:test_main',
@@ -114,9 +117,6 @@
         'video/full_stack.cc',
         'video/rampup_tests.cc',
         'video/rampup_tests.h',
-        # Needed to make the test binary pass since all tests are disabled on
-        # Android (webrtc:3770).
-        'test/testsupport/always_passing_unittest.cc',
       ],
       'dependencies': [
         '<(DEPTH)/testing/gtest.gyp:gtest',