Import Cobalt 21.lts.4.300899
diff --git a/src/buildtools/linux64/gn b/src/buildtools/linux64/gn
deleted file mode 100755
index 9485341..0000000
--- a/src/buildtools/linux64/gn
+++ /dev/null
Binary files differ
diff --git a/src/cobalt/CHANGELOG.md b/src/cobalt/CHANGELOG.md
index 644ecae..b201080 100644
--- a/src/cobalt/CHANGELOG.md
+++ b/src/cobalt/CHANGELOG.md
@@ -125,6 +125,18 @@
This behavior can now be overridden by implementing the cobalt extension
function `CobaltExtensionGraphicsApi::ShouldClearFrameOnShutdown`.
+ - **Added support for adjusting colors of 360 videos.**
+
+ Platforms which support 360 videos may adjust the colors of the video frame
+ using `CobaltExtensionGraphicsApi::GetMapToMeshColorAdjustments`.
+
+ - **Added support for rendering the frame with a custom root transform.**
+
+ Platforms can force frame rendering to use a custom root transform by using
+ `CobaltExtensionGraphicsApi::GetRenderRootTransform`. This only impacts
+ rendering; the web app does not know about the custom transform so may not
+ layout elements appropriately.
+
## Version 20
- **Support for QUIC and SPDY is now enabled.**
@@ -483,7 +495,7 @@
The Cobalt splash screen is customizable. Documents may use a link element
with attribute rel="splashscreen" to reference the splash screen which will
be cached if local cache is implemented on the platform. Additionally
- fallbacks may be specified via command line parmeter or gypi variable.
+ fallbacks may be specified via command line parameter or gypi variable.
For more information, see [doc/splash_screen.md](doc/splash_screen.md).
- **Introduce C\+\+11**
diff --git a/src/cobalt/build/build.id b/src/cobalt/build/build.id
index 9bdf0dc..4021ee4 100644
--- a/src/cobalt/build/build.id
+++ b/src/cobalt/build/build.id
@@ -1 +1 @@
-300530
\ No newline at end of file
+300899
\ No newline at end of file
diff --git a/src/cobalt/content/ssl/certs/9c2e7d30.0 b/src/cobalt/content/ssl/certs/9c2e7d30.0
deleted file mode 100644
index 36a998d..0000000
--- a/src/cobalt/content/ssl/certs/9c2e7d30.0
+++ /dev/null
@@ -1,19 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIDIDCCAgigAwIBAgIBHTANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJGSTEP
-MA0GA1UEChMGU29uZXJhMRkwFwYDVQQDExBTb25lcmEgQ2xhc3MyIENBMB4XDTAx
-MDQwNjA3Mjk0MFoXDTIxMDQwNjA3Mjk0MFowOTELMAkGA1UEBhMCRkkxDzANBgNV
-BAoTBlNvbmVyYTEZMBcGA1UEAxMQU29uZXJhIENsYXNzMiBDQTCCASIwDQYJKoZI
-hvcNAQEBBQADggEPADCCAQoCggEBAJAXSjWdyvANlsdE+hY3/Ei9vX+ALTU74W+o
-Z6m/AxxNjG8yR9VBaKQTBME1DJqEQ/xcHf+Js+gXGM2RX/uJ4+q/Tl18GybTdXnt
-5oTjV+WtKcT0OijnpXuENmmz/V52vaMtmdOQTiMofRhj8VQ7Jp12W5dCsv+u8E7s
-3TmVToMGf+dJQMjFAbJUWmYdPfz56TwKnoG4cPABi+QjVHzIrviQHgCWctRUz2Ej
-vOr7nQKV0ba5cTppCD8PtOFCx4j1P5iop7oc4HFx71hXgVB6XGt0Rg6DA5jDjqhu
-8nYybieDwnPz3BjotJPqdURrBGAgcVeHnfO+oJAjPYok4doh28MCAwEAAaMzMDEw
-DwYDVR0TAQH/BAUwAwEB/zARBgNVHQ4ECgQISqCqWITTXjwwCwYDVR0PBAQDAgEG
-MA0GCSqGSIb3DQEBBQUAA4IBAQBazof5FnIVV0sd2ZvnoiYw7JNn39Yt0jSv9zil
-zqsWuasvfDXLrNAPtEwr/IDva4yRXzZ299uzGxnq9LIR/WFxRL8oszodv7ND6J+/
-3DEIcbCdjdY0RzKQxmUk96BKfARzjzlvF4xytb1LyHr4e4PDKE6cCepnP7JnBBvD
-FNr450kkkdAdavphOe9r5yF1BgfYErQhIHBCcYHaPJo2vqZbDWpsmh+Re/n570K6
-Tk6ezAyNlNzZRZxe7EJQY670XcSxEtzKO6gunRRaBXW37Ndj4ro1tgQIkejanZz2
-ZrUYrAqmVCY0M9IbwdR/GjqOC6oybtv8TyWf2TLHllpwrN9M
------END CERTIFICATE-----
diff --git a/src/cobalt/extension/extension_test.cc b/src/cobalt/extension/extension_test.cc
index 0670fbb..1bbc6c8 100644
--- a/src/cobalt/extension/extension_test.cc
+++ b/src/cobalt/extension/extension_test.cc
@@ -63,7 +63,7 @@
EXPECT_STREQ(extension_api->name, kExtensionName);
EXPECT_GE(extension_api->version, 1u);
- EXPECT_LE(extension_api->version, 4u);
+ EXPECT_LE(extension_api->version, 5u);
EXPECT_NE(extension_api->GetMaximumFrameIntervalInMilliseconds, nullptr);
float maximum_frame_interval =
@@ -97,6 +97,11 @@
}
}
+ if (extension_api->version >= 5) {
+ EXPECT_NE(extension_api->GetMapToMeshColorAdjustments, nullptr);
+ EXPECT_NE(extension_api->GetRenderRootTransform, nullptr);
+ }
+
const ExtensionApi* second_extension_api =
static_cast<const ExtensionApi*>(SbSystemGetExtension(kExtensionName));
EXPECT_EQ(second_extension_api, extension_api)
diff --git a/src/cobalt/extension/graphics.h b/src/cobalt/extension/graphics.h
index a1a3b4e..ed55a2e 100644
--- a/src/cobalt/extension/graphics.h
+++ b/src/cobalt/extension/graphics.h
@@ -25,6 +25,21 @@
#define kCobaltExtensionGraphicsName "dev.cobalt.extension.Graphics"
+// This structure allows post-processing of output colors for 360 videos.
+// Given "rgba" is the color that the pixel shader calculates, this struct
+// allows additional processing in the form of:
+// final color = rgba0_scale +
+// rgba1_scale * rgba +
+// rgba2_scale * rgba * rgba +
+// rgba3_scale * rgba * rgba * rgba;
+// The final_color is then clamped to the range of [0,1] for each element.
+typedef struct CobaltExtensionGraphicsMapToMeshColorAdjustment {
+ float rgba0_scale[4]; // multiplier for rgba^0
+ float rgba1_scale[4]; // multiplier for rgba^1
+ float rgba2_scale[4]; // multiplier for rgba^2
+ float rgba3_scale[4]; // multiplier for rgba^3
+} CobaltExtensionGraphicsMapToMeshColorAdjustment;
+
typedef struct CobaltExtensionGraphicsApi {
// Name should be the string kCobaltExtensionGraphicsName.
// This helps to validate that the extension API is correct.
@@ -75,6 +90,23 @@
float* clear_color_green,
float* clear_color_blue,
float* clear_color_alpha);
+
+ // The fields below this point were added in version 5 or later.
+
+ // Use the provided color adjustments for 360 videos if the function returns
+ // true. See declaration of CobaltExtensionGraphicsMapToMeshColorAdjustment
+ // for details.
+ bool (*GetMapToMeshColorAdjustments)(
+ CobaltExtensionGraphicsMapToMeshColorAdjustment* adjustment);
+
+ // This function can be used to insert a custom transform at the root of
+ // rendering. This allows custom scaling, rotating, etc. of the frame. This
+ // only impacts rendering of the frame -- the web app will not know about this
+ // transform, so it may not layout elements appropriately. This function
+ // should return true if a custom transform should be used.
+ bool (*GetRenderRootTransform)(float* m00, float* m01, float* m02, float* m10,
+ float* m11, float* m12, float* m20, float* m21,
+ float* m22);
} CobaltExtensionGraphicsApi;
#ifdef __cplusplus
diff --git a/src/cobalt/layout/layout.cc b/src/cobalt/layout/layout.cc
index b635518..6ab79ff 100644
--- a/src/cobalt/layout/layout.cc
+++ b/src/cobalt/layout/layout.cc
@@ -24,12 +24,14 @@
#include "cobalt/dom/html_body_element.h"
#include "cobalt/dom/html_element_context.h"
#include "cobalt/dom/html_html_element.h"
+#include "cobalt/extension/graphics.h"
#include "cobalt/layout/benchmark_stat_names.h"
#include "cobalt/layout/box_generator.h"
#include "cobalt/layout/initial_containing_block.h"
#include "cobalt/layout/layout_boxes.h"
#include "cobalt/layout/used_style.h"
#include "cobalt/render_tree/animations/animate_node.h"
+#include "cobalt/render_tree/matrix_transform_node.h"
namespace cobalt {
namespace layout {
@@ -194,9 +196,26 @@
// status for animated images.
used_style_provider->UpdateAnimatedImages();
- render_tree::CompositionNode* static_root_node =
+ render_tree::Node* static_root_node =
new render_tree::CompositionNode(std::move(render_tree_root_builder));
+#if SB_API_VERSION >= 11
+ // Support insertion of a custom transform at the render tree root.
+ static const CobaltExtensionGraphicsApi* s_graphics_extension =
+ static_cast<const CobaltExtensionGraphicsApi*>(
+ SbSystemGetExtension(kCobaltExtensionGraphicsName));
+ float m00, m01, m02, m10, m11, m12, m20, m21, m22;
+ if (s_graphics_extension &&
+ strcmp(s_graphics_extension->name, kCobaltExtensionGraphicsName) == 0 &&
+ s_graphics_extension->version >= 5 &&
+ s_graphics_extension->GetRenderRootTransform(&m00, &m01, &m02, &m10, &m11,
+ &m12, &m20, &m21, &m22)) {
+ static_root_node = new render_tree::MatrixTransformNode(
+ static_root_node, math::Matrix3F::FromValues(m00, m01, m02, m10, m11,
+ m12, m20, m21, m22));
+ }
+#endif // SB_API_VERSION >= 11
+
// Make it easy to animate the entire tree by placing an AnimateNode at the
// root to merge any sub-AnimateNodes.
render_tree::animations::AnimateNode* animate_node =
diff --git a/src/cobalt/renderer/glimp_shaders/glsl/fragment_directgles_color_include.glsl b/src/cobalt/renderer/glimp_shaders/glsl/fragment_directgles_color_include.glsl
index f42f765..ddeb45d 100644
--- a/src/cobalt/renderer/glimp_shaders/glsl/fragment_directgles_color_include.glsl
+++ b/src/cobalt/renderer/glimp_shaders/glsl/fragment_directgles_color_include.glsl
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-precision mediump float;
+precision highp float;
uniform vec4 u_include; // include scissor (x_min, y_min, x_max, y_max)
varying vec2 v_offset;
varying vec4 v_color;
diff --git a/src/cobalt/renderer/glimp_shaders/glsl/fragment_textured_vbo_rgba.glsl b/src/cobalt/renderer/glimp_shaders/glsl/fragment_textured_vbo_rgba.glsl
index 04eaa9c..fdffec9 100644
--- a/src/cobalt/renderer/glimp_shaders/glsl/fragment_textured_vbo_rgba.glsl
+++ b/src/cobalt/renderer/glimp_shaders/glsl/fragment_textured_vbo_rgba.glsl
@@ -4,5 +4,6 @@
void main() {
vec4 untransformed_color = vec4(texture2D(texture_rgba, v_tex_coord_rgba).rgba);
- gl_FragColor = untransformed_color;
-}
\ No newline at end of file
+ vec4 color = untransformed_color;
+ gl_FragColor = color;
+}
diff --git a/src/cobalt/renderer/glimp_shaders/glsl/fragment_textured_vbo_uyvy_1plane.glsl b/src/cobalt/renderer/glimp_shaders/glsl/fragment_textured_vbo_uyvy_1plane.glsl
index 9a77757..1a36b31 100644
--- a/src/cobalt/renderer/glimp_shaders/glsl/fragment_textured_vbo_uyvy_1plane.glsl
+++ b/src/cobalt/renderer/glimp_shaders/glsl/fragment_textured_vbo_uyvy_1plane.glsl
@@ -30,5 +30,6 @@
}
vec4 untransformed_color = vec4(y_value, uv_value.r, uv_value.g, 1.0);
- gl_FragColor = untransformed_color * to_rgb_color_matrix;
+ vec4 color = untransformed_color * to_rgb_color_matrix;
+ gl_FragColor = color;
}
diff --git a/src/cobalt/renderer/glimp_shaders/glsl/fragment_textured_vbo_yuv_2plane.glsl b/src/cobalt/renderer/glimp_shaders/glsl/fragment_textured_vbo_yuv_2plane.glsl
index 75b5036..15c79fa 100644
--- a/src/cobalt/renderer/glimp_shaders/glsl/fragment_textured_vbo_yuv_2plane.glsl
+++ b/src/cobalt/renderer/glimp_shaders/glsl/fragment_textured_vbo_yuv_2plane.glsl
@@ -10,5 +10,6 @@
texture2D(texture_y, v_tex_coord_y).a,
texture2D(texture_uv, v_tex_coord_uv).ba, 1.0);
- gl_FragColor = untransformed_color * to_rgb_color_matrix;
+ vec4 color = untransformed_color * to_rgb_color_matrix;
+ gl_FragColor = color;
}
diff --git a/src/cobalt/renderer/glimp_shaders/glsl/fragment_textured_vbo_yuv_3plane.glsl b/src/cobalt/renderer/glimp_shaders/glsl/fragment_textured_vbo_yuv_3plane.glsl
index 91137c6..da6e748 100644
--- a/src/cobalt/renderer/glimp_shaders/glsl/fragment_textured_vbo_yuv_3plane.glsl
+++ b/src/cobalt/renderer/glimp_shaders/glsl/fragment_textured_vbo_yuv_3plane.glsl
@@ -11,5 +11,6 @@
texture2D(texture_y, v_tex_coord_y).a,
texture2D(texture_u, v_tex_coord_u).a,
texture2D(texture_v, v_tex_coord_v).a, 1.0);
- gl_FragColor = untransformed_color * to_rgb_color_matrix;
+ vec4 color = untransformed_color * to_rgb_color_matrix;
+ gl_FragColor = color;
}
diff --git a/src/cobalt/renderer/rasterizer/egl/shaders/fragment_color_include.glsl b/src/cobalt/renderer/rasterizer/egl/shaders/fragment_color_include.glsl
index 2cb71f7..aadf5d0 100644
--- a/src/cobalt/renderer/rasterizer/egl/shaders/fragment_color_include.glsl
+++ b/src/cobalt/renderer/rasterizer/egl/shaders/fragment_color_include.glsl
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-precision mediump float;
+precision highp float;
uniform vec4 u_include; // include scissor (x_min, y_min, x_max, y_max)
varying vec2 v_offset;
varying vec4 v_color;
diff --git a/src/cobalt/renderer/rasterizer/egl/textured_mesh_renderer.cc b/src/cobalt/renderer/rasterizer/egl/textured_mesh_renderer.cc
index 874c225..ac3cb80 100644
--- a/src/cobalt/renderer/rasterizer/egl/textured_mesh_renderer.cc
+++ b/src/cobalt/renderer/rasterizer/egl/textured_mesh_renderer.cc
@@ -21,6 +21,7 @@
#include <vector>
#include "base/strings/stringprintf.h"
+#include "cobalt/extension/graphics.h"
#include "cobalt/math/size.h"
#include "cobalt/renderer/backend/egl/utils.h"
#include "cobalt/renderer/egl_and_gles.h"
@@ -346,12 +347,53 @@
if (color_matrix) {
blit_fragment_shader_source +=
");"
- " gl_FragColor = untransformed_color * to_rgb_color_matrix;"
- "}";
+ " vec4 color = untransformed_color * to_rgb_color_matrix;";
} else {
blit_fragment_shader_source +=
");"
- " gl_FragColor = untransformed_color;"
+ " vec4 color = untransformed_color;";
+ }
+#if SB_API_VERSION >= 11
+ const CobaltExtensionGraphicsApi* graphics_extension =
+ static_cast<const CobaltExtensionGraphicsApi*>(
+ SbSystemGetExtension(kCobaltExtensionGraphicsName));
+ CobaltExtensionGraphicsMapToMeshColorAdjustment color_adjustment;
+ if (graphics_extension != nullptr &&
+ strcmp(graphics_extension->name, kCobaltExtensionGraphicsName) == 0 &&
+ graphics_extension->version >= 5 &&
+ graphics_extension->GetMapToMeshColorAdjustments(&color_adjustment)) {
+ // Setup vectors for the color adjustments. Ensure they use dot for decimal
+ // point regardless of locale.
+ std::stringstream buffer;
+ buffer.imbue(std::locale::classic());
+ buffer << " vec4 scale0 = vec4(" << color_adjustment.rgba0_scale[0] << ","
+ << color_adjustment.rgba0_scale[1] << ","
+ << color_adjustment.rgba0_scale[2] << ","
+ << color_adjustment.rgba0_scale[3] << ");";
+ buffer << " vec4 scale1 = vec4(" << color_adjustment.rgba1_scale[0] << ","
+ << color_adjustment.rgba1_scale[1] << ","
+ << color_adjustment.rgba1_scale[2] << ","
+ << color_adjustment.rgba1_scale[3] << ");";
+ buffer << " vec4 scale2 = vec4(" << color_adjustment.rgba2_scale[0] << ","
+ << color_adjustment.rgba2_scale[1] << ","
+ << color_adjustment.rgba2_scale[2] << ","
+ << color_adjustment.rgba2_scale[3] << ");";
+ buffer << " vec4 scale3 = vec4(" << color_adjustment.rgba3_scale[0] << ","
+ << color_adjustment.rgba3_scale[1] << ","
+ << color_adjustment.rgba3_scale[2] << ","
+ << color_adjustment.rgba3_scale[3] << ");";
+ blit_fragment_shader_source +=
+ " vec4 color2 = color * color;"
+ " vec4 color3 = color2 * color;" +
+ buffer.str() +
+ " color = scale0 + scale1*color + scale2*color2 + scale3*color3;"
+ " gl_FragColor = clamp(color, vec4(0.0), vec4(1.0));"
+ "}";
+ } else
+#endif // SB_API_VERSION >= 11
+ {
+ blit_fragment_shader_source +=
+ " gl_FragColor = color;"
"}";
}
diff --git a/src/cobalt/renderer/rasterizer/skia/render_tree_node_visitor.cc b/src/cobalt/renderer/rasterizer/skia/render_tree_node_visitor.cc
index 537a25f..2558ad5 100644
--- a/src/cobalt/renderer/rasterizer/skia/render_tree_node_visitor.cc
+++ b/src/cobalt/renderer/rasterizer/skia/render_tree_node_visitor.cc
@@ -45,8 +45,6 @@
#include "cobalt/renderer/rasterizer/skia/font.h"
#include "cobalt/renderer/rasterizer/skia/glyph_buffer.h"
#include "cobalt/renderer/rasterizer/skia/image.h"
-#include "cobalt/renderer/rasterizer/skia/skia/src/effects/SkNV122RGBShader.h"
-#include "cobalt/renderer/rasterizer/skia/skia/src/effects/SkYUV2RGBShader.h"
#include "cobalt/renderer/rasterizer/skia/skottie_animation.h"
#include "cobalt/renderer/rasterizer/skia/software_image.h"
#include "third_party/skia/include/core/SkBlendMode.h"
diff --git a/src/cobalt/renderer/rasterizer/skia/skia/skia_cobalt.gypi b/src/cobalt/renderer/rasterizer/skia/skia/skia_cobalt.gypi
index 6f73d3e..72ac12e 100644
--- a/src/cobalt/renderer/rasterizer/skia/skia/skia_cobalt.gypi
+++ b/src/cobalt/renderer/rasterizer/skia/skia/skia_cobalt.gypi
@@ -19,10 +19,6 @@
'sources': [
'config/SkUserConfig.h',
- 'src/effects/SkNV122RGBShader.cc',
- 'src/effects/SkNV122RGBShader.h',
- 'src/effects/SkYUV2RGBShader.cc',
- 'src/effects/SkYUV2RGBShader.h',
'src/google_logging.cc',
'src/gpu/gl/GrGLMakeNativeInterface_cobalt.cc',
'src/ports/SkFontConfigParser_cobalt.cc',
diff --git a/src/cobalt/renderer/rasterizer/skia/skia/src/effects/SkNV122RGBShader.cc b/src/cobalt/renderer/rasterizer/skia/skia/src/effects/SkNV122RGBShader.cc
deleted file mode 100644
index 8f9f343..0000000
--- a/src/cobalt/renderer/rasterizer/skia/skia/src/effects/SkNV122RGBShader.cc
+++ /dev/null
@@ -1,174 +0,0 @@
-// Copyright 2016 The Cobalt Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "cobalt/renderer/rasterizer/skia/skia/src/effects/SkNV122RGBShader.h"
-
-#include <algorithm>
-
-#include "base/logging.h"
-#include "cobalt/base/polymorphic_downcast.h"
-#include "third_party/skia/include/core/SkColorPriv.h"
-#include "third_party/skia/include/core/SkShader.h"
-#include "third_party/skia/include/core/SkString.h"
-#include "third_party/skia/src/core/SkReadBuffer.h"
-#include "third_party/skia/src/core/SkWriteBuffer.h"
-
-#if SK_SUPPORT_GPU
-#include "third_party/skia/src/gpu/GrFragmentProcessor.h"
-#endif
-
-SkNV122RGBShader::SkNV122RGBShader(SkYUVColorSpace color_space,
- const sk_sp<SkImage>& y_image,
- const SkMatrix& y_matrix,
- const sk_sp<SkImage>& uv_image,
- const SkMatrix& uv_matrix)
- : color_space_(color_space),
- y_image_(y_image),
- y_matrix_(y_matrix),
- uv_image_(uv_image),
- uv_matrix_(uv_matrix) {
- DCHECK(y_image_);
- DCHECK(uv_image_);
- InitializeShaders();
-}
-
-void SkNV122RGBShader::InitializeShaders() {
- y_shader_.reset(base::polymorphic_downcast<SkImageShader*>(
- SkImageShader::Make(y_image_, SkTileMode::kClamp, SkTileMode::kClamp,
- &y_matrix_, false)
- .get()));
- DCHECK(y_shader_);
-
- uv_shader_.reset(base::polymorphic_downcast<SkImageShader*>(
- SkImageShader::Make(uv_image_, SkTileMode::kClamp, SkTileMode::kClamp,
- &uv_matrix_, false)
- .get()));
- DCHECK(uv_shader_);
-}
-
-SkNV122RGBShader::~SkNV122RGBShader() {
-}
-
-void SkNV122RGBShader::flatten(SkWriteBuffer& buffer) const {
- buffer.writeInt(color_space_);
- buffer.writeImage(y_image_.get());
- buffer.writeMatrix(y_matrix_);
- buffer.writeImage(uv_image_.get());
- buffer.writeMatrix(uv_matrix_);
-}
-
-uint32_t SkNV122RGBShader::NV122RGBShaderContext::getFlags() const { return 0; }
-
-SkNV122RGBShader::NV122RGBShaderContext::NV122RGBShaderContext(
- SkYUVColorSpace color_space, const SkNV122RGBShader& yuv2rgb_shader,
- SkShaderBase::Context* y_shader_context,
- SkShaderBase::Context* uv_shader_context, const ContextRec& rec)
- : INHERITED(yuv2rgb_shader, rec),
- color_space_(color_space),
- y_shader_context_(y_shader_context),
- uv_shader_context_(uv_shader_context) {}
-
-SkNV122RGBShader::NV122RGBShaderContext::~NV122RGBShaderContext() {
- y_shader_context_->~Context();
- uv_shader_context_->~Context();
-}
-
-void SkNV122RGBShader::NV122RGBShaderContext::shadeSpan(int x, int y,
- SkPMColor result[],
- int count) {
- static const int kPixelCountPerSpan = 64;
- SkPMColor y_values[kPixelCountPerSpan];
- SkPMColor uv_values[kPixelCountPerSpan];
-
- DCHECK_EQ(kRec709_SkYUVColorSpace, color_space_)
- << "Currently we only support the BT.709 YUV colorspace.";
-
- do {
- int count_in_chunk =
- count > kPixelCountPerSpan ? kPixelCountPerSpan : count;
-
- y_shader_context_->shadeSpan(x, y, y_values, count_in_chunk);
- uv_shader_context_->shadeSpan(x, y, uv_values, count_in_chunk);
-
- for (int i = 0; i < count_in_chunk; ++i) {
- int32_t y_value = SkColorGetA(y_values[i]) - 16;
- int32_t u_value = SkColorGetB(uv_values[i]) - 128;
- int32_t v_value = SkColorGetA(uv_values[i]) - 128;
-
- const float kA = 1.164f;
- const float kB = -0.213f;
- const float kC = 2.112f;
- const float kD = 1.793f;
- const float kE = -0.533f;
- int32_t r_unclamped = static_cast<int32_t>(kA * y_value + kD * v_value);
- int32_t g_unclamped =
- static_cast<int32_t>(kA * y_value + kB * u_value + kE * v_value);
- int32_t b_unclamped = static_cast<int32_t>(kA * y_value + kC * u_value);
-
- int32_t r_clamped =
- std::min<int32_t>(255, std::max<int32_t>(0, r_unclamped));
- int32_t g_clamped =
- std::min<int32_t>(255, std::max<int32_t>(0, g_unclamped));
- int32_t b_clamped =
- std::min<int32_t>(255, std::max<int32_t>(0, b_unclamped));
-
- result[i] = SkPackARGB32NoCheck(255, r_clamped, g_clamped, b_clamped);
- }
- result += count_in_chunk;
- x += count_in_chunk;
- count -= count_in_chunk;
- } while (count > 0);
-}
-
-#if SK_SUPPORT_GPU
-
-std::unique_ptr<GrFragmentProcessor> SkNV122RGBShader::asFragmentProcessor(
- const GrFPArgs&) const {
-#if 0
- // TODO SKIA_M61_EFFECTS. Investigate if we still need this.
- // Code snippet taken from SkBitmapProcShader::asFragmentProcessor().
- SkMatrix matrix;
- matrix.setIDiv(y_image_->width(), y_image_->height());
-
- SkMatrix lmInverse;
- if (!y_shader_->getLocalMatrix().invert(&lmInverse)) {
- return false;
- }
- if (localMatrix) {
- SkMatrix inv;
- if (!localMatrix->invert(&inv)) {
- return false;
- }
- lmInverse.postConcat(inv);
- }
- matrix.preConcat(lmInverse);
-
- GrTextureParams::FilterMode filter_mode =
- paint.getFilterLevel() == SkPaint::kNone_FilterLevel
- ? GrTextureParams::kNone_FilterMode
- : GrTextureParams::kBilerp_FilterMode;
- GrTextureParams texture_params;
- texture_params.setFilterMode(filter_mode);
-
- *fp = GrYUVtoRGBEffect::Create(y_image_->getTexture(),
- uv_image_->getTexture(),
- NULL, matrix, texture_params,
- kRec709_SkYUVColorSpace, true);
- return true;
-#else
- return nullptr;
-#endif
-}
-
-#endif // SK_SUPPORT_GPU
diff --git a/src/cobalt/renderer/rasterizer/skia/skia/src/effects/SkNV122RGBShader.h b/src/cobalt/renderer/rasterizer/skia/skia/src/effects/SkNV122RGBShader.h
deleted file mode 100644
index c822333..0000000
--- a/src/cobalt/renderer/rasterizer/skia/skia/src/effects/SkNV122RGBShader.h
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright 2016 The Cobalt Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef COBALT_RENDERER_RASTERIZER_SKIA_SKIA_SRC_EFFECTS_SKNV122RGBSHADER_H_
-#define COBALT_RENDERER_RASTERIZER_SKIA_SKIA_SRC_EFFECTS_SKNV122RGBSHADER_H_
-
-#include "third_party/skia/src/shaders/SkShaderBase.h"
-
-#include "third_party/skia/src/shaders/SkImageShader.h"
-
-class SkNV122RGBShader : public SkShaderBase {
- public:
- SkNV122RGBShader(SkYUVColorSpace color_space, const sk_sp<SkImage>& y_image,
- const SkMatrix& y_matrix, const sk_sp<SkImage>& uv_image,
- const SkMatrix& uv_matrix);
- virtual ~SkNV122RGBShader();
-
- class NV122RGBShaderContext : public SkShaderBase::Context {
- public:
- // Takes ownership of shaderContext and calls its destructor.
- NV122RGBShaderContext(SkYUVColorSpace color_space,
- const SkNV122RGBShader& yuv2rgb_shader,
- SkShaderBase::Context* y_shader_context,
- SkShaderBase::Context* uv_shader_context,
- const ContextRec& rec);
- virtual ~NV122RGBShaderContext();
-
- uint32_t getFlags() const override;
-
- void shadeSpan(int x, int y, SkPMColor[], int count) override;
-
- private:
- SkYUVColorSpace color_space_;
-
- SkShaderBase::Context* y_shader_context_;
- SkShaderBase::Context* uv_shader_context_;
-
- typedef SkShaderBase::Context INHERITED;
- };
-
-#if SK_SUPPORT_GPU
- std::unique_ptr<GrFragmentProcessor> asFragmentProcessor(
- const GrFPArgs&) const override;
-#endif
-
- SK_FLATTENABLE_HOOKS(SkNV122RGBShader)
-
- protected:
- void flatten(SkWriteBuffer&) const override;
-
- private:
- void InitializeShaders();
-
- SkYUVColorSpace color_space_;
-
- sk_sp<SkImage> y_image_;
- SkMatrix y_matrix_;
- sk_sp<SkImageShader> y_shader_;
-
- sk_sp<SkImage> uv_image_;
- SkMatrix uv_matrix_;
- sk_sp<SkImageShader> uv_shader_;
-
- typedef SkShaderBase INHERITED;
-};
-
-#endif // COBALT_RENDERER_RASTERIZER_SKIA_SKIA_SRC_EFFECTS_SKNV122RGBSHADER_H_
diff --git a/src/cobalt/renderer/rasterizer/skia/skia/src/effects/SkYUV2RGBShader.cc b/src/cobalt/renderer/rasterizer/skia/skia/src/effects/SkYUV2RGBShader.cc
deleted file mode 100644
index 71efe90..0000000
--- a/src/cobalt/renderer/rasterizer/skia/skia/src/effects/SkYUV2RGBShader.cc
+++ /dev/null
@@ -1,159 +0,0 @@
-// Copyright 2015 The Cobalt Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "cobalt/renderer/rasterizer/skia/skia/src/effects/SkYUV2RGBShader.h"
-
-#include <algorithm>
-
-#include "base/logging.h"
-#include "cobalt/base/polymorphic_downcast.h"
-#include "third_party/skia/include/core/SkColorPriv.h"
-#include "third_party/skia/include/core/SkShader.h"
-#include "third_party/skia/include/core/SkString.h"
-#include "third_party/skia/src/core/SkReadBuffer.h"
-#include "third_party/skia/src/core/SkWriteBuffer.h"
-#include "third_party/skia/src/gpu/GrFragmentProcessor.h"
-#include "third_party/skia/src/gpu/effects/GrYUVtoRGBEffect.h"
-#include "third_party/skia/src/shaders/SkImageShader.h"
-
-SkYUV2RGBShader::SkYUV2RGBShader(SkYUVColorSpace color_space,
- const sk_sp<SkImage>& y_image,
- const SkMatrix& y_matrix,
- const sk_sp<SkImage>& u_image,
- const SkMatrix& u_matrix,
- const sk_sp<SkImage>& v_image,
- const SkMatrix& v_matrix)
- : color_space_(color_space),
- y_image_(y_image),
- y_matrix_(y_matrix),
- u_image_(u_image),
- u_matrix_(u_matrix),
- v_image_(v_image),
- v_matrix_(v_matrix) {
- DCHECK(y_image_);
- DCHECK(u_image_);
- DCHECK(v_image_);
- InitializeShaders();
-}
-
-void SkYUV2RGBShader::InitializeShaders() {
- y_shader_.reset(base::polymorphic_downcast<SkImageShader*>(
- SkImageShader::Make(y_image_, SkTileMode::kClamp, SkTileMode::kClamp,
- &y_matrix_, false)
- .get()));
- DCHECK(y_shader_);
-
- u_shader_.reset(base::polymorphic_downcast<SkImageShader*>(
- SkImageShader::Make(u_image_, SkTileMode::kClamp, SkTileMode::kClamp,
- &u_matrix_, false)
- .get()));
- DCHECK(u_shader_);
-
- v_shader_.reset(base::polymorphic_downcast<SkImageShader*>(
- SkImageShader::Make(v_image_, SkTileMode::kClamp, SkTileMode::kClamp,
- &v_matrix_, false)
- .get()));
- DCHECK(v_shader_);
-}
-
-void SkYUV2RGBShader::flatten(SkWriteBuffer& buffer) const {
- buffer.writeInt(color_space_);
- buffer.writeImage(y_image_.get());
- buffer.writeMatrix(y_matrix_);
- buffer.writeImage(u_image_.get());
- buffer.writeMatrix(u_matrix_);
- buffer.writeImage(v_image_.get());
- buffer.writeMatrix(v_matrix_);
-}
-
-uint32_t SkYUV2RGBShader::YUV2RGBShaderContext::getFlags() const {
- return 0;
-}
-
-SkShaderBase::Context* SkYUV2RGBShader::onMakeContext(
- const ContextRec& rec, SkArenaAlloc* storage) const {
- return nullptr;
-}
-SkYUV2RGBShader::YUV2RGBShaderContext::YUV2RGBShaderContext(
- SkYUVColorSpace color_space, const SkYUV2RGBShader& yuv2rgb_shader,
- SkShaderBase::Context* y_shader_context,
- SkShaderBase::Context* u_shader_context,
- SkShaderBase::Context* v_shader_context, const ContextRec& rec)
- : INHERITED(yuv2rgb_shader, rec),
- color_space_(color_space),
- y_shader_context_(y_shader_context),
- u_shader_context_(u_shader_context),
- v_shader_context_(v_shader_context) {}
-
-SkYUV2RGBShader::YUV2RGBShaderContext::~YUV2RGBShaderContext() {
- y_shader_context_->~Context();
- u_shader_context_->~Context();
- v_shader_context_->~Context();
-}
-void SkYUV2RGBShader::YUV2RGBShaderContext::shadeSpan(
- int x, int y, SkPMColor result[], int count) {
- static const int kPixelCountPerSpan = 64;
- SkPMColor y_values[kPixelCountPerSpan];
- SkPMColor u_values[kPixelCountPerSpan];
- SkPMColor v_values[kPixelCountPerSpan];
-
- DCHECK_EQ(kRec709_SkYUVColorSpace, color_space_) <<
- "Currently we only support the BT.709 YUV colorspace.";
-
- do {
- int count_in_chunk =
- count > kPixelCountPerSpan ? kPixelCountPerSpan : count;
-
- y_shader_context_->shadeSpan(x, y, y_values, count_in_chunk);
- u_shader_context_->shadeSpan(x, y, u_values, count_in_chunk);
- v_shader_context_->shadeSpan(x, y, v_values, count_in_chunk);
-
- for (int i = 0; i < count_in_chunk; ++i) {
- int32_t y_value = SkColorGetA(y_values[i]) - 16;
- int32_t u_value = SkColorGetA(u_values[i]) - 128;
- int32_t v_value = SkColorGetA(v_values[i]) - 128;
-
- const float kA = 1.164f;
- const float kB = -0.213f;
- const float kC = 2.112f;
- const float kD = 1.793f;
- const float kE = -0.533f;
- int32_t r_unclamped = static_cast<int32_t>(kA * y_value + kD * v_value);
- int32_t g_unclamped =
- static_cast<int32_t>(kA * y_value + kB * u_value + kE * v_value);
- int32_t b_unclamped = static_cast<int32_t>(kA * y_value + kC * u_value);
-
- int32_t r_clamped =
- std::min<int32_t>(255, std::max<int32_t>(0, r_unclamped));
- int32_t g_clamped =
- std::min<int32_t>(255, std::max<int32_t>(0, g_unclamped));
- int32_t b_clamped =
- std::min<int32_t>(255, std::max<int32_t>(0, b_unclamped));
-
- result[i] = SkPackARGB32NoCheck(255, r_clamped, g_clamped, b_clamped);
- }
- result += count_in_chunk;
- x += count_in_chunk;
- count -= count_in_chunk;
- } while (count > 0);
-}
-
-#if SK_SUPPORT_GPU
-
-std::unique_ptr<GrFragmentProcessor> SkYUV2RGBShader::asFragmentProcessor(
- const GrFPArgs&) const {
- return nullptr;
-}
-
-#endif // SK_SUPPORT_GPU
diff --git a/src/cobalt/renderer/rasterizer/skia/skia/src/effects/SkYUV2RGBShader.h b/src/cobalt/renderer/rasterizer/skia/skia/src/effects/SkYUV2RGBShader.h
deleted file mode 100644
index f05534b..0000000
--- a/src/cobalt/renderer/rasterizer/skia/skia/src/effects/SkYUV2RGBShader.h
+++ /dev/null
@@ -1,87 +0,0 @@
-// Copyright 2015 The Cobalt Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef COBALT_RENDERER_RASTERIZER_SKIA_SKIA_SRC_EFFECTS_SKYUV2RGBSHADER_H_
-#define COBALT_RENDERER_RASTERIZER_SKIA_SKIA_SRC_EFFECTS_SKYUV2RGBSHADER_H_
-
-#include "third_party/skia/src/shaders/SkShaderBase.h"
-
-#include "third_party/skia/src/shaders/SkImageShader.h"
-
-class SkYUV2RGBShader : public SkShaderBase {
- public:
- SkYUV2RGBShader(SkYUVColorSpace color_space, const sk_sp<SkImage>& y_image,
- const SkMatrix& y_matrix, const sk_sp<SkImage>& u_image,
- const SkMatrix& u_matrix, const sk_sp<SkImage>& v_image,
- const SkMatrix& v_matrix);
- virtual ~SkYUV2RGBShader() = default;
-
- class YUV2RGBShaderContext : public SkShaderBase::Context {
- public:
- // Takes ownership of shaderContext and calls its destructor.
- YUV2RGBShaderContext(SkYUVColorSpace color_space,
- const SkYUV2RGBShader& yuv2rgb_shader,
- SkShaderBase::Context* y_shader_context,
- SkShaderBase::Context* u_shader_context,
- SkShaderBase::Context* v_shader_context,
- const ContextRec& rec);
- virtual ~YUV2RGBShaderContext();
-
- uint32_t getFlags() const override;
-
- void shadeSpan(int x, int y, SkPMColor[], int count) override;
-
- private:
- SkYUVColorSpace color_space_;
-
- SkShaderBase::Context* y_shader_context_;
- SkShaderBase::Context* u_shader_context_;
- SkShaderBase::Context* v_shader_context_;
-
- typedef SkShaderBase::Context INHERITED;
- };
-
-#if SK_SUPPORT_GPU
- std::unique_ptr<GrFragmentProcessor> asFragmentProcessor(
- const GrFPArgs&) const override;
-#endif
-
- SK_FLATTENABLE_HOOKS(SkYUV2RGBShader)
-
- protected:
- void flatten(SkWriteBuffer&) const override;
- SkShaderBase::Context* onMakeContext(const ContextRec& rec,
- SkArenaAlloc* storage) const override;
-
- private:
- void InitializeShaders();
-
- SkYUVColorSpace color_space_;
-
- sk_sp<SkImage> y_image_;
- SkMatrix y_matrix_;
- sk_sp<SkImageShader> y_shader_;
-
- sk_sp<SkImage> u_image_;
- SkMatrix u_matrix_;
- sk_sp<SkImageShader> u_shader_;
-
- sk_sp<SkImage> v_image_;
- SkMatrix v_matrix_;
- sk_sp<SkImageShader> v_shader_;
-
- typedef SkShaderBase INHERITED;
-};
-
-#endif // COBALT_RENDERER_RASTERIZER_SKIA_SKIA_SRC_EFFECTS_SKYUV2RGBSHADER_H_
diff --git a/src/cobalt/updater/updater_module.cc b/src/cobalt/updater/updater_module.cc
index ee9b712..4cba4f3 100644
--- a/src/cobalt/updater/updater_module.cc
+++ b/src/cobalt/updater/updater_module.cc
@@ -145,8 +145,13 @@
updater_observer_.reset();
update_client_ = nullptr;
- updater_configurator_->GetPrefService()->CommitPendingWrite(
- base::BindOnce(&QuitLoop, base::Bind(base::DoNothing::Repeatedly())));
+ if (updater_configurator_ != nullptr) {
+ auto pref_service = updater_configurator_->GetPrefService();
+ if (pref_service != nullptr) {
+ pref_service->CommitPendingWrite(
+ base::BindOnce(&QuitLoop, base::Bind(base::DoNothing::Repeatedly())));
+ }
+ }
updater_configurator_ = nullptr;
}
diff --git a/src/starboard/android/apk/app/src/app/AndroidManifest.xml b/src/starboard/android/apk/app/src/app/AndroidManifest.xml
index 7337495..bceef34 100644
--- a/src/starboard/android/apk/app/src/app/AndroidManifest.xml
+++ b/src/starboard/android/apk/app/src/app/AndroidManifest.xml
@@ -67,4 +67,9 @@
</application>
+ <queries>
+ <!-- This is needed to access the speech recognition service in SDK 30 -->
+ <package android:name="com.google.android.katniss" />
+ </queries>
+
</manifest>
diff --git a/src/starboard/android/apk/app/src/main/java/dev/cobalt/coat/StarboardBridge.java b/src/starboard/android/apk/app/src/main/java/dev/cobalt/coat/StarboardBridge.java
index bf21be7..fc4907a 100644
--- a/src/starboard/android/apk/app/src/main/java/dev/cobalt/coat/StarboardBridge.java
+++ b/src/starboard/android/apk/app/src/main/java/dev/cobalt/coat/StarboardBridge.java
@@ -537,7 +537,16 @@
return false;
}
- int[] supportedHdrTypes = defaultDisplay.getHdrCapabilities().getSupportedHdrTypes();
+ Display.HdrCapabilities hdrCapabilities = defaultDisplay.getHdrCapabilities();
+ if (hdrCapabilities == null) {
+ return false;
+ }
+
+ int[] supportedHdrTypes = hdrCapabilities.getSupportedHdrTypes();
+ if (supportedHdrTypes == null) {
+ return false;
+ }
+
for (int supportedType : supportedHdrTypes) {
if (supportedType == hdrType) {
return true;
diff --git a/src/starboard/android/apk/app/src/main/java/dev/cobalt/media/MediaCodecBridge.java b/src/starboard/android/apk/app/src/main/java/dev/cobalt/media/MediaCodecBridge.java
index 547c67c..e3d0c3c 100644
--- a/src/starboard/android/apk/app/src/main/java/dev/cobalt/media/MediaCodecBridge.java
+++ b/src/starboard/android/apk/app/src/main/java/dev/cobalt/media/MediaCodecBridge.java
@@ -523,7 +523,7 @@
MediaCrypto crypto) {
MediaCodec mediaCodec = null;
try {
- String decoderName = MediaCodecUtil.findAudioDecoder(mime, 0);
+ String decoderName = MediaCodecUtil.findAudioDecoder(mime, 0, false);
if (decoderName.equals("")) {
Log.e(TAG, String.format("Failed to find decoder: %s, isSecure: %s", mime, isSecure));
return null;
diff --git a/src/starboard/android/apk/app/src/main/java/dev/cobalt/media/MediaCodecUtil.java b/src/starboard/android/apk/app/src/main/java/dev/cobalt/media/MediaCodecUtil.java
index be473bb..5318110 100644
--- a/src/starboard/android/apk/app/src/main/java/dev/cobalt/media/MediaCodecUtil.java
+++ b/src/starboard/android/apk/app/src/main/java/dev/cobalt/media/MediaCodecUtil.java
@@ -397,10 +397,19 @@
int frameHeight,
int bitrate,
int fps,
- boolean mustSupportHdr) {
+ boolean mustSupportHdr,
+ boolean mustSupportTunnelMode) {
FindVideoDecoderResult findVideoDecoderResult =
findVideoDecoder(
- mimeType, secure, frameWidth, frameHeight, bitrate, fps, mustSupportHdr, false, false);
+ mimeType,
+ secure,
+ frameWidth,
+ frameHeight,
+ bitrate,
+ fps,
+ mustSupportHdr,
+ false,
+ mustSupportTunnelMode);
return !findVideoDecoderResult.name.equals("")
&& (!mustSupportHdr || isHdrCapableVideoDecoder(mimeType, findVideoDecoderResult));
}
@@ -411,8 +420,9 @@
*/
@SuppressWarnings("unused")
@UsedByNative
- public static boolean hasAudioDecoderFor(String mimeType, int bitrate) {
- return !findAudioDecoder(mimeType, bitrate).equals("");
+ public static boolean hasAudioDecoderFor(
+ String mimeType, int bitrate, boolean mustSupportTunnelMode) {
+ return !findAudioDecoder(mimeType, bitrate, mustSupportTunnelMode).equals("");
}
/**
@@ -438,15 +448,6 @@
return isHdrCapableVideoDecoder(mimeType, findVideoDecoderResult);
}
- /** Determine whether the system support tunneled playback */
- @SuppressWarnings("unused")
- @UsedByNative
- public static boolean hasTunneledCapableDecoder(String mimeType, boolean isSecure) {
- FindVideoDecoderResult findVideoDecoderResult =
- findVideoDecoder(mimeType, isSecure, 0, 0, 0, 0, false, false, true);
- return !findVideoDecoderResult.name.equals("");
- }
-
/** Determine whether findVideoDecoderResult is capable of playing HDR */
public static boolean isHdrCapableVideoDecoder(
String mimeType, FindVideoDecoderResult findVideoDecoderResult) {
@@ -723,7 +724,8 @@
* The same as hasAudioDecoderFor, only return the name of the audio decoder if it is found, and
* "" otherwise.
*/
- public static String findAudioDecoder(String mimeType, int bitrate) {
+ public static String findAudioDecoder(
+ String mimeType, int bitrate, boolean requireTunneledPlayback) {
// Note: MediaCodecList is sorted by the framework such that the best decoders come first.
for (MediaCodecInfo info : new MediaCodecList(MediaCodecList.ALL_CODECS).getCodecInfos()) {
if (info.isEncoder()) {
@@ -734,13 +736,21 @@
continue;
}
String name = info.getName();
- AudioCapabilities audioCapabilities =
- info.getCapabilitiesForType(supportedType).getAudioCapabilities();
+ CodecCapabilities codecCapabilities = info.getCapabilitiesForType(supportedType);
+ AudioCapabilities audioCapabilities = codecCapabilities.getAudioCapabilities();
Range<Integer> bitrateRange =
Range.create(0, audioCapabilities.getBitrateRange().getUpper());
if (!bitrateRange.contains(bitrate)) {
continue;
}
+ if (requireTunneledPlayback
+ && !codecCapabilities.isFeatureSupported(CodecCapabilities.FEATURE_TunneledPlayback)) {
+ continue;
+ }
+ // TODO: Determine if we can safely check if an audio codec requires the tunneled playback
+ // feature. i.e., reject when |requireTunneledPlayback| == false
+ // and codecCapabilities.isFeatureRequired(CodecCapabilities.FEATURE_TunneledPlayback) ==
+ // true.
return name;
}
}
diff --git a/src/starboard/android/apk/build.id b/src/starboard/android/apk/build.id
deleted file mode 100644
index 57a90bb..0000000
--- a/src/starboard/android/apk/build.id
+++ /dev/null
@@ -1 +0,0 @@
-300523
\ No newline at end of file
diff --git a/src/starboard/android/shared/media_is_audio_supported.cc b/src/starboard/android/shared/media_is_audio_supported.cc
index e47aaaf..fe8b4ec 100644
--- a/src/starboard/android/shared/media_is_audio_supported.cc
+++ b/src/starboard/android/shared/media_is_audio_supported.cc
@@ -16,6 +16,7 @@
#include "starboard/android/shared/jni_utils.h"
#include "starboard/android/shared/media_common.h"
+#include "starboard/audio_sink.h"
#include "starboard/configuration.h"
#include "starboard/configuration_constants.h"
#include "starboard/media.h"
@@ -47,14 +48,36 @@
if (!enable_audio_routing_parameter_value.empty() &&
enable_audio_routing_parameter_value != "true" &&
enable_audio_routing_parameter_value != "false") {
- SB_LOG(WARNING) << "Invalid value for enableaudiorouting: "
- << enable_audio_routing_parameter_value << ".";
+ SB_LOG(INFO)
+ << "Invalid value for audio mime parameter \"enableaudiorouting\": "
+ << enable_audio_routing_parameter_value << ".";
return false;
}
+ // Allows for enabling tunneled playback. Disabled by default.
+ // (https://source.android.com/devices/tv/multimedia-tunneling)
+ auto enable_tunnel_mode_parameter_value =
+ mime_type.GetParamStringValue("tunnelmode", "");
+ if (!enable_tunnel_mode_parameter_value.empty() &&
+ enable_tunnel_mode_parameter_value != "true" &&
+ enable_tunnel_mode_parameter_value != "false") {
+ SB_LOG(INFO) << "Invalid value for audio mime parameter \"tunnelmode\": "
+ << enable_tunnel_mode_parameter_value << ".";
+ return false;
+ } else if (enable_tunnel_mode_parameter_value == "true" &&
+ !SbAudioSinkIsAudioSampleTypeSupported(
+ kSbMediaAudioSampleTypeInt16Deprecated)) {
+ SB_LOG(WARNING)
+ << "Tunnel mode is rejected because int16 sample is required "
+ "but not supported.";
+ return false;
+ }
+
JniEnvExt* env = JniEnvExt::Get();
ScopedLocalJavaRef<jstring> j_mime(env->NewStringStandardUTFOrAbort(mime));
+ const bool must_support_tunnel_mode =
+ enable_tunnel_mode_parameter_value == "true";
return env->CallStaticBooleanMethodOrAbort(
"dev/cobalt/media/MediaCodecUtil", "hasAudioDecoderFor",
- "(Ljava/lang/String;I)Z", j_mime.Get(),
- static_cast<jint>(bitrate)) == JNI_TRUE;
+ "(Ljava/lang/String;IZ)Z", j_mime.Get(),
+ static_cast<jint>(bitrate), must_support_tunnel_mode) == JNI_TRUE;
}
diff --git a/src/starboard/android/shared/media_is_video_supported.cc b/src/starboard/android/shared/media_is_video_supported.cc
index a0c42d0..332e4b2 100644
--- a/src/starboard/android/shared/media_is_video_supported.cc
+++ b/src/starboard/android/shared/media_is_video_supported.cc
@@ -20,11 +20,13 @@
#include "starboard/configuration.h"
#include "starboard/media.h"
#include "starboard/shared/starboard/media/media_util.h"
+#include "starboard/shared/starboard/media/mime_type.h"
using starboard::android::shared::JniEnvExt;
using starboard::android::shared::ScopedLocalJavaRef;
using starboard::android::shared::SupportedVideoCodecToMimeType;
using starboard::shared::starboard::media::IsSDRVideo;
+using starboard::shared::starboard::media::MimeType;
namespace {
@@ -93,13 +95,38 @@
if (!mime) {
return false;
}
+ MimeType mime_type(content_type);
+ // Allows for enabling tunneled playback. Disabled by default.
+ // (https://source.android.com/devices/tv/multimedia-tunneling)
+ auto enable_tunnel_mode_parameter_value =
+ mime_type.GetParamStringValue("tunnelmode", "");
+ if (!enable_tunnel_mode_parameter_value.empty() &&
+ enable_tunnel_mode_parameter_value != "true" &&
+ enable_tunnel_mode_parameter_value != "false") {
+ SB_LOG(INFO) << "Invalid value for video mime parameter \"tunnelmode\": "
+ << enable_tunnel_mode_parameter_value << ".";
+ return false;
+ } else if (enable_tunnel_mode_parameter_value == "true" &&
+ decode_to_texture_required) {
+ SB_LOG(WARNING) << "Tunnel mode is rejected because output mode decode to "
+ "texture is required but not supported.";
+ return false;
+ }
JniEnvExt* env = JniEnvExt::Get();
ScopedLocalJavaRef<jstring> j_mime(env->NewStringStandardUTFOrAbort(mime));
- bool must_support_hdr = (transfer_id != kSbMediaTransferIdBt709 &&
- transfer_id != kSbMediaTransferIdUnspecified);
+ const bool must_support_hdr = (transfer_id != kSbMediaTransferIdBt709 &&
+ transfer_id != kSbMediaTransferIdUnspecified);
+ const bool must_support_tunnel_mode =
+ enable_tunnel_mode_parameter_value == "true";
+ // We assume that if a device supports a format for clear playback, it will
+ // also support it for encrypted playback. However, some devices require
+ // tunneled playback to be encrypted, so we must align the tunnel mode
+ // requirement with the secure playback requirement.
+ const bool require_secure_playback = must_support_tunnel_mode;
return env->CallStaticBooleanMethodOrAbort(
"dev/cobalt/media/MediaCodecUtil", "hasVideoDecoderFor",
- "(Ljava/lang/String;ZIIIIZ)Z", j_mime.Get(), false, frame_width,
- frame_height, static_cast<jint>(bitrate), fps,
- must_support_hdr) == JNI_TRUE;
+ "(Ljava/lang/String;ZIIIIZZ)Z", j_mime.Get(),
+ require_secure_playback, frame_width, frame_height,
+ static_cast<jint>(bitrate), fps, must_support_hdr,
+ must_support_tunnel_mode) == JNI_TRUE;
}
diff --git a/src/starboard/android/shared/player_components_factory.h b/src/starboard/android/shared/player_components_factory.h
index c771391..5e1b078 100644
--- a/src/starboard/android/shared/player_components_factory.h
+++ b/src/starboard/android/shared/player_components_factory.h
@@ -27,6 +27,7 @@
#include "starboard/android/shared/video_decoder.h"
#include "starboard/atomic.h"
#include "starboard/common/log.h"
+#include "starboard/common/media.h"
#include "starboard/common/ref_counted.h"
#include "starboard/common/scoped_ptr.h"
#include "starboard/media.h"
@@ -46,9 +47,8 @@
namespace android {
namespace shared {
-// Tunnel mode is disabled by default. Set the following variable to true to
-// enable tunnel mode.
-constexpr bool kTunnelModeEnabled = false;
+using starboard::shared::starboard::media::MimeType;
+
// On some platforms tunnel mode is only supported in the secure pipeline. Set
// the following variable to true to force creating a secure pipeline in tunnel
// mode, even for clear content.
@@ -162,8 +162,43 @@
SB_DCHECK(error_message);
int tunnel_mode_audio_session_id = -1;
+ bool enable_tunnel_mode = false;
+ if (creation_parameters.audio_codec() != kSbMediaAudioCodecNone &&
+ creation_parameters.video_codec() != kSbMediaVideoCodecNone) {
+ MimeType audio_mime_type(creation_parameters.audio_mime());
+ MimeType video_mime_type(creation_parameters.video_mime());
+ auto enable_tunnel_mode_audio_parameter_value =
+ audio_mime_type.GetParamStringValue("tunnelmode", "");
+ auto enable_tunnel_mode_video_parameter_value =
+ video_mime_type.GetParamStringValue("tunnelmode", "");
+ if (enable_tunnel_mode_audio_parameter_value == "true" &&
+ enable_tunnel_mode_video_parameter_value == "true") {
+ enable_tunnel_mode = true;
+ } else {
+ if (enable_tunnel_mode_audio_parameter_value.empty()) {
+ enable_tunnel_mode_audio_parameter_value = "not provided";
+ }
+ if (enable_tunnel_mode_video_parameter_value.empty()) {
+ enable_tunnel_mode_video_parameter_value = "not provided";
+ }
+ SB_LOG(INFO) << "Tunnel mode is disabled. Audio mime parameter "
+ "\"tunnelmode\" value: "
+ << enable_tunnel_mode_audio_parameter_value
+ << ", video mime parameter \"tunnelmode\" value: "
+ << enable_tunnel_mode_video_parameter_value << ".";
+ }
+ } else {
+ SB_LOG(INFO) << "Tunnel mode requires both an audio and video stream. "
+ << "Audio codec: "
+ << GetMediaAudioCodecName(creation_parameters.audio_codec())
+ << ", Video codec: "
+ << GetMediaVideoCodecName(creation_parameters.video_codec())
+ << ". Tunnel mode is disabled.";
+ }
+
bool force_secure_pipeline_under_tunnel_mode = false;
- if (IsTunnelModeSupported(creation_parameters,
+ if (enable_tunnel_mode &&
+ IsTunnelModeSupported(creation_parameters,
&force_secure_pipeline_under_tunnel_mode)) {
tunnel_mode_audio_session_id =
GenerateAudioSessionId(creation_parameters);
@@ -205,16 +240,15 @@
GetExtendedDrmSystem(creation_parameters.drm_system()),
decoder_creator));
bool enable_audio_routing = true;
- starboard::shared::starboard::media::MimeType mime_type(
- creation_parameters.audio_mime());
+ MimeType audio_mime_type(creation_parameters.audio_mime());
auto enable_audio_routing_parameter_value =
- mime_type.GetParamStringValue("enableaudiorouting", "");
+ audio_mime_type.GetParamStringValue("enableaudiorouting", "");
if (enable_audio_routing_parameter_value.empty() ||
enable_audio_routing_parameter_value == "true") {
SB_LOG(INFO) << "AudioRouting is enabled.";
} else {
enable_audio_routing = false;
- SB_LOG(INFO) << "Mime attribute enableaudiorouting is set to: "
+ SB_LOG(INFO) << "Mime attribute \"enableaudiorouting\" is set to: "
<< enable_audio_routing_parameter_value
<< ". AudioRouting is disabled.";
}
@@ -297,11 +331,6 @@
SB_DCHECK(force_secure_pipeline_under_tunnel_mode);
*force_secure_pipeline_under_tunnel_mode = false;
- if (!kTunnelModeEnabled) {
- SB_LOG(INFO) << "Tunnel mode is disabled globally.";
- return false;
- }
-
if (!SbAudioSinkIsAudioSampleTypeSupported(
kSbMediaAudioSampleTypeInt16Deprecated)) {
SB_LOG(INFO) << "Disable tunnel mode because int16 sample is required "
@@ -341,8 +370,9 @@
bool is_encrypted = !!j_media_crypto;
if (env->CallStaticBooleanMethodOrAbort(
- "dev/cobalt/media/MediaCodecUtil", "hasTunneledCapableDecoder",
- "(Ljava/lang/String;Z)Z", j_mime.Get(), is_encrypted) == JNI_TRUE) {
+ "dev/cobalt/media/MediaCodecUtil", "hasVideoDecoderFor",
+ "(Ljava/lang/String;ZIIIIZZ)Z", j_mime.Get(), is_encrypted, 0, 0, 0,
+ 0, false, true) == JNI_TRUE) {
return true;
}
@@ -350,8 +380,9 @@
const bool kIsEncrypted = true;
auto support_tunnel_mode_under_secure_pipeline =
env->CallStaticBooleanMethodOrAbort(
- "dev/cobalt/media/MediaCodecUtil", "hasTunneledCapableDecoder",
- "(Ljava/lang/String;Z)Z", j_mime.Get(), kIsEncrypted) == JNI_TRUE;
+ "dev/cobalt/media/MediaCodecUtil", "hasVideoDecoderFor",
+ "(Ljava/lang/String;ZIIIIZZ)Z", j_mime.Get(), kIsEncrypted, 0, 0,
+ 0, 0, false, true) == JNI_TRUE;
if (support_tunnel_mode_under_secure_pipeline) {
*force_secure_pipeline_under_tunnel_mode = true;
return true;
diff --git a/src/starboard/doc/evergreen/cobalt_evergreen_overview.md b/src/starboard/doc/evergreen/cobalt_evergreen_overview.md
index c8a3272..247d19f 100644
--- a/src/starboard/doc/evergreen/cobalt_evergreen_overview.md
+++ b/src/starboard/doc/evergreen/cobalt_evergreen_overview.md
@@ -435,6 +435,8 @@
├── installation_store_<APP_KEY>.pb
└── icu (default location shared by installation slots, to be explained below)
```
+Note that after the Cobalt binary is loaded by the loader_app, `kSbSystemPathContentDirectory` points to the
+content directory of the running binary, as stated in Starboard Module Reference of system.h.
#### App metadata
Each Cobalt Evergreen application has a set of unique metadata to track slot
diff --git a/src/starboard/shared/starboard/player/filter/filter_based_player_worker_handler.cc b/src/starboard/shared/starboard/player/filter/filter_based_player_worker_handler.cc
index a3c0d50..c931500 100644
--- a/src/starboard/shared/starboard/player/filter/filter_based_player_worker_handler.cc
+++ b/src/starboard/shared/starboard/player/filter/filter_based_player_worker_handler.cc
@@ -506,7 +506,7 @@
double playback_rate;
auto media_time = media_time_provider_->GetCurrentMediaTime(
&is_playing, &is_eos_played, &is_underflow, &playback_rate);
- update_media_info_cb_(media_time, dropped_frames, is_underflow);
+ update_media_info_cb_(media_time, dropped_frames, !is_underflow);
}
update_job_token_ = Schedule(update_job_, kUpdateInterval);
diff --git a/src/starboard/shared/starboard/player/player_internal.cc b/src/starboard/shared/starboard/player/player_internal.cc
index c273223..5a6b20b 100644
--- a/src/starboard/shared/starboard/player/player_internal.cc
+++ b/src/starboard/shared/starboard/player/player_internal.cc
@@ -29,9 +29,9 @@
using std::placeholders::_3;
using std::placeholders::_4;
-SbTime GetMediaTime(SbTime media_time,
- SbTimeMonotonic media_time_update_time,
- double playback_rate) {
+SbTime CalculateMediaTime(SbTime media_time,
+ SbTimeMonotonic media_time_update_time,
+ double playback_rate) {
SbTimeMonotonic elapsed = SbTimeGetMonotonicNow() - media_time_update_time;
return media_time + static_cast<SbTime>(elapsed * playback_rate);
}
@@ -61,9 +61,8 @@
worker_ = starboard::make_scoped_ptr(PlayerWorker::CreateInstance(
audio_codec, video_codec, player_worker_handler.Pass(),
std::bind(&SbPlayerPrivate::UpdateMediaInfo, this, _1, _2, _3, _4),
- decoder_status_func, player_status_func,
- player_error_func,
- this, context));
+ decoder_status_func, player_status_func, player_error_func, this,
+ context));
++number_of_players_;
SB_DLOG(INFO) << "Creating SbPlayerPrivate. There are " << number_of_players_
@@ -83,9 +82,8 @@
starboard::scoped_ptr<PlayerWorker::Handler> player_worker_handler) {
SbPlayerPrivate* ret = new SbPlayerPrivate(
audio_codec, video_codec, audio_sample_info, sample_deallocate_func,
- decoder_status_func, player_status_func,
- player_error_func,
- context, player_worker_handler.Pass());
+ decoder_status_func, player_status_func, player_error_func, context,
+ player_worker_handler.Pass());
if (ret && ret->worker_) {
return ret;
@@ -100,6 +98,7 @@
SB_DCHECK(ticket_ != ticket);
media_time_ = seek_to_time;
media_time_updated_at_ = SbTimeGetMonotonicNow();
+ is_progressing_ = false;
ticket_ = ticket;
}
@@ -159,11 +158,11 @@
starboard::ScopedLock lock(mutex_);
out_player_info->duration = SB_PLAYER_NO_DURATION;
- if (is_paused_ || underflow_) {
+ if (is_paused_ || !is_progressing_) {
out_player_info->current_media_timestamp = media_time_;
} else {
out_player_info->current_media_timestamp =
- GetMediaTime(media_time_, media_time_updated_at_, playback_rate_);
+ CalculateMediaTime(media_time_, media_time_updated_at_, playback_rate_);
}
out_player_info->frame_width = frame_width_;
@@ -194,13 +193,13 @@
void SbPlayerPrivate::UpdateMediaInfo(SbTime media_time,
int dropped_video_frames,
int ticket,
- bool underflow) {
+ bool is_progressing) {
starboard::ScopedLock lock(mutex_);
if (ticket_ != ticket) {
return;
}
media_time_ = media_time;
- underflow_ = underflow;
+ is_progressing_ = is_progressing;
media_time_updated_at_ = SbTimeGetMonotonicNow();
dropped_video_frames_ = dropped_video_frames;
}
diff --git a/src/starboard/shared/starboard/player/player_internal.h b/src/starboard/shared/starboard/player/player_internal.h
index 4a94236..559531f 100644
--- a/src/starboard/shared/starboard/player/player_internal.h
+++ b/src/starboard/shared/starboard/player/player_internal.h
@@ -82,7 +82,7 @@
void UpdateMediaInfo(SbTime media_time,
int dropped_video_frames,
int ticket,
- bool underflow);
+ bool is_progressing);
SbPlayerDeallocateSampleFunc sample_deallocate_func_;
void* context_;
@@ -101,7 +101,9 @@
double volume_ = 1.0;
int total_video_frames_ = 0;
int dropped_video_frames_ = 0;
- bool underflow_ = false;
+ // Used to determine if |worker_| is progressing with playback so that
+ // we may extrapolate the media time in GetInfo().
+ bool is_progressing_ = false;
starboard::scoped_ptr<PlayerWorker> worker_;
diff --git a/src/starboard/shared/starboard/player/player_worker.cc b/src/starboard/shared/starboard/player/player_worker.cc
index c4f3110..1a1a557 100644
--- a/src/starboard/shared/starboard/player/player_worker.cc
+++ b/src/starboard/shared/starboard/player/player_worker.cc
@@ -68,12 +68,10 @@
SbPlayerErrorFunc player_error_func,
SbPlayer player,
void* context) {
-
- PlayerWorker* ret = new PlayerWorker(audio_codec, video_codec, handler.Pass(),
- update_media_info_cb,
- decoder_status_func, player_status_func,
- player_error_func,
- player, context);
+ PlayerWorker* ret =
+ new PlayerWorker(audio_codec, video_codec, handler.Pass(),
+ update_media_info_cb, decoder_status_func,
+ player_status_func, player_error_func, player, context);
if (ret && SbThreadIsValid(ret->thread_)) {
return ret;
@@ -139,8 +137,9 @@
void PlayerWorker::UpdateMediaInfo(SbTime time,
int dropped_video_frames,
- bool underflow) {
- update_media_info_cb_(time, dropped_video_frames, ticket_, underflow);
+ bool is_progressing) {
+ SB_DCHECK(player_state_ == kSbPlayerStatePresenting);
+ update_media_info_cb_(time, dropped_video_frames, ticket_, is_progressing);
}
void PlayerWorker::UpdatePlayerState(SbPlayerState player_state) {
diff --git a/src/starboard/shared/starboard/player/player_worker.h b/src/starboard/shared/starboard/player/player_worker.h
index 6c70552..3539c31 100644
--- a/src/starboard/shared/starboard/player/player_worker.h
+++ b/src/starboard/shared/starboard/player/player_worker.h
@@ -46,7 +46,7 @@
typedef std::function<void(SbTime media_time,
int dropped_video_frames,
int ticket,
- bool underflow)>
+ bool is_progressing)>
UpdateMediaInfoCB;
struct Bounds {
@@ -61,7 +61,7 @@
class Handler {
public:
typedef std::function<
- void(SbTime media_time, int dropped_video_frames, bool underflow)>
+ void(SbTime media_time, int dropped_video_frames, bool is_progressing)>
UpdateMediaInfoCB;
typedef std::function<SbPlayerState()> GetPlayerStateCB;
typedef std::function<void(SbPlayerState player_state)> UpdatePlayerStateCB;