Import Cobalt 22.lts.1.304063
diff --git a/src/cobalt/build/build.id b/src/cobalt/build/build.id
index f5670fb..6446170 100644
--- a/src/cobalt/build/build.id
+++ b/src/cobalt/build/build.id
@@ -1 +1 @@
-303694
\ No newline at end of file
+304063
\ No newline at end of file
diff --git a/src/cobalt/build/save_build_id.py b/src/cobalt/build/save_build_id.py
index 014e80d..fc81ab9 100755
--- a/src/cobalt/build/save_build_id.py
+++ b/src/cobalt/build/save_build_id.py
@@ -63,7 +63,12 @@
return 0
if not options.build_id:
- options.build_id = gyp_utils.GetBuildNumber()
+ build_id_server_url = os.environ.get('BUILD_ID_SERVER_URL')
+ if build_id_server_url:
+ options.build_id = gyp_utils.GetBuildNumber(
+ version_server=build_id_server_url)
+ else:
+ options.build_id = gyp_utils.GetBuildNumber()
if not options.build_id:
logging.error('Unable to retrieve build id.')
diff --git a/src/cobalt/content/fonts/BUILD.gn b/src/cobalt/content/fonts/BUILD.gn
index 87b11ff..8b99258 100644
--- a/src/cobalt/content/fonts/BUILD.gn
+++ b/src/cobalt/content/fonts/BUILD.gn
@@ -30,7 +30,7 @@
"-i",
rebase_path(font_xml, root_build_dir),
"-o",
- outputs[0],
+ rebase_path(outputs[0], root_out_dir),
] + package_categories
}
diff --git a/src/cobalt/dom/performance.cc b/src/cobalt/dom/performance.cc
index 7554005..8154cc1 100644
--- a/src/cobalt/dom/performance.cc
+++ b/src/cobalt/dom/performance.cc
@@ -76,8 +76,6 @@
tick_clock_(base::DefaultTickClock::GetInstance()),
timing_(new PerformanceTiming(clock, time_origin_)),
memory_(new MemoryInfo()),
- lifecycle_timing_(
- new PerformanceLifecycleTiming("lifecycle timing", time_origin_)),
resource_timing_buffer_size_limit_(
Performance::kMaxResourceTimingBufferSize),
resource_timing_buffer_current_size_(0),
@@ -87,6 +85,8 @@
add_to_performance_entry_buffer_flag_(false) {
unix_at_zero_monotonic_ = GetUnixAtZeroMonotonic(
base::DefaultClock::GetInstance(), tick_clock_);
+ lifecycle_timing_ = base::MakeRefCounted<PerformanceLifecycleTiming>(
+ "lifecycle timing", time_origin());
QueuePerformanceEntry(lifecycle_timing_);
}
diff --git a/src/cobalt/dom/performance_high_resolution_time.h b/src/cobalt/dom/performance_high_resolution_time.h
index 5033e5b..0684e41 100644
--- a/src/cobalt/dom/performance_high_resolution_time.h
+++ b/src/cobalt/dom/performance_high_resolution_time.h
@@ -39,7 +39,7 @@
return (time - base::TimeTicks()).InMillisecondsF();
}
-// Clamp customized minimum clock resolution.
+// Clamp customized minimum clock resolution in milliseconds.
// https://w3c.github.io/hr-time/#clock-resolution
inline DOMHighResTimeStamp ClampTimeStampMinimumResolution(
base::TimeTicks ticks,
@@ -49,13 +49,13 @@
(microseconds % min_resolution_in_microseconds)).InMillisecondsF();
}
-// Clamp customized minimum clock resolution.
+// Clamp customized minimum clock resolution in milliseconds.
// https://w3c.github.io/hr-time/#clock-resolution
inline DOMHighResTimeStamp ClampTimeStampMinimumResolution(base::TimeDelta delta,
int64_t min_resolution_in_microseconds) {
int64_t microseconds = delta.InMicroseconds();
return base::TimeDelta::FromMicroseconds(microseconds -
- (microseconds % min_resolution_in_microseconds)).InMicrosecondsF();
+ (microseconds % min_resolution_in_microseconds)).InMillisecondsF();
}
} // namespace dom
diff --git a/src/cobalt/dom/performance_lifecycle_timing.cc b/src/cobalt/dom/performance_lifecycle_timing.cc
index 08f47d4..f09fee0 100644
--- a/src/cobalt/dom/performance_lifecycle_timing.cc
+++ b/src/cobalt/dom/performance_lifecycle_timing.cc
@@ -41,23 +41,22 @@
}
DOMHighResTimeStamp ConvertSbTimeMonotonicToDOMHiResTimeStamp(
- base::TimeTicks time_origin, SbTimeMonotonic monotonic_time) {
+ const DOMHighResTimeStamp time_origin, SbTimeMonotonic monotonic_time) {
SbTimeMonotonic time_delta = SbTimeGetNow() - SbTimeGetMonotonicNow();
base::Time base_time = base::Time::FromSbTime(time_delta + monotonic_time);
base::TimeTicks time_ticks =
base::TimeTicks::FromInternalValue(static_cast<int64_t>(
base_time.ToJsTime()));
- return Performance::MonotonicTimeToDOMHighResTimeStamp(
- time_origin, time_ticks);
+ return ClampTimeStampMinimumResolution(time_ticks,
+ Performance::kPerformanceTimerMinResolutionInMicroseconds) - time_origin;
}
} // namespace
PerformanceLifecycleTiming::PerformanceLifecycleTiming(
- const std::string& name, base::TimeTicks time_origin)
+ const std::string& name, const DOMHighResTimeStamp time_origin)
: PerformanceEntry(name, 0.0, 0.0), time_origin_(time_origin) {}
-
DOMHighResTimeStamp PerformanceLifecycleTiming::app_preload() const {
return ReportDOMHighResTimeStamp(lifecycle_timing_info_.app_preload);
}
diff --git a/src/cobalt/dom/performance_lifecycle_timing.h b/src/cobalt/dom/performance_lifecycle_timing.h
index 9baa10c..01e3c79 100644
--- a/src/cobalt/dom/performance_lifecycle_timing.h
+++ b/src/cobalt/dom/performance_lifecycle_timing.h
@@ -31,7 +31,7 @@
class PerformanceLifecycleTiming : public PerformanceEntry {
public:
PerformanceLifecycleTiming(const std::string& name,
- base::TimeTicks time_origin);
+ const DOMHighResTimeStamp time_origin);
// Web API.
DOMHighResTimeStamp app_preload() const;
@@ -83,7 +83,7 @@
LifecycleTimingInfo lifecycle_timing_info_;
- base::TimeTicks time_origin_;
+ DOMHighResTimeStamp time_origin_;
DISALLOW_COPY_AND_ASSIGN(PerformanceLifecycleTiming);
};
diff --git a/src/cobalt/loader/image/image_decoder.cc b/src/cobalt/loader/image/image_decoder.cc
index a499c63..68782a3 100644
--- a/src/cobalt/loader/image/image_decoder.cc
+++ b/src/cobalt/loader/image/image_decoder.cc
@@ -54,25 +54,6 @@
result->append(message);
}
-// Determine the ImageType of an image from its signature.
-ImageDecoder::ImageType DetermineImageType(const uint8* header) {
- if (!memcmp(header, "\xFF\xD8\xFF", 3)) {
- return ImageDecoder::kImageTypeJPEG;
- } else if (!memcmp(header, "GIF87a", 6) || !memcmp(header, "GIF89a", 6)) {
- return ImageDecoder::kImageTypeGIF;
- } else if (!memcmp(header, "{", 1)) {
- // TODO: Improve heuristics for determining whether the file contains valid
- // Lottie JSON.
- return ImageDecoder::kImageTypeJSON;
- } else if (!memcmp(header, "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A", 8)) {
- return ImageDecoder::kImageTypePNG;
- } else if (!memcmp(header, "RIFF", 4) && !memcmp(header + 8, "WEBPVP", 6)) {
- return ImageDecoder::kImageTypeWebP;
- } else {
- return ImageDecoder::kImageTypeInvalid;
- }
-}
-
// Returns true if the ResourceProvider is ResourceProviderStub.
bool IsResourceProviderStub(render_tree::ResourceProvider* resource_provider) {
return resource_provider->GetTypeId() ==
@@ -81,6 +62,39 @@
} // namespace
+// Determine the ImageType of an image from its signature.
+ImageDecoder::ImageType DetermineImageType(const uint8* header) {
+ if (!memcmp(header, "\xFF\xD8\xFF", 3)) {
+ return ImageDecoder::kImageTypeJPEG;
+ } else if (!memcmp(header, "GIF87a", 6) || !memcmp(header, "GIF89a", 6)) {
+ return ImageDecoder::kImageTypeGIF;
+ } else if (!memcmp(header, "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A", 8)) {
+ return ImageDecoder::kImageTypePNG;
+ } else if (!memcmp(header, "RIFF", 4) && !memcmp(header + 8, "WEBPVP", 6)) {
+ return ImageDecoder::kImageTypeWebP;
+ } else {
+ const std::string header_str = reinterpret_cast<const char*>(header);
+ std::string::size_type first_non_white_space_pos =
+ header_str.find_first_not_of(" \t\r\n");
+ if (first_non_white_space_pos + 1 < header_str.size()) {
+ if (header_str[first_non_white_space_pos] == '{' ||
+ header_str[first_non_white_space_pos] ==
+ '[') { // json can start with either object hash or an array
+ std::string::size_type second_non_white_space_pos =
+ header_str.find_first_not_of(" \t\r\n",
+ first_non_white_space_pos + 1);
+ if (second_non_white_space_pos + 1 < header_str.size()) {
+ if (header_str[second_non_white_space_pos] == '"' &&
+ isalnum(header_str[second_non_white_space_pos + 1])) {
+ return ImageDecoder::kImageTypeJSON;
+ }
+ }
+ }
+ }
+ return ImageDecoder::kImageTypeInvalid;
+ }
+}
+
ImageDecoder::ImageDecoder(
render_tree::ResourceProvider* resource_provider,
const base::DebuggerHooks& debugger_hooks,
diff --git a/src/cobalt/loader/image/image_decoder.h b/src/cobalt/loader/image/image_decoder.h
index cb80ce6..89b4d6b 100644
--- a/src/cobalt/loader/image/image_decoder.h
+++ b/src/cobalt/loader/image/image_decoder.h
@@ -122,6 +122,8 @@
bool use_failure_image_decoder_ = false;
};
+ImageDecoder::ImageType DetermineImageType(const uint8* header);
+
} // namespace image
} // namespace loader
} // namespace cobalt
diff --git a/src/cobalt/loader/image/image_decoder_unit_test.cc b/src/cobalt/loader/image/image_decoder_unit_test.cc
new file mode 100644
index 0000000..a6dfc5d
--- /dev/null
+++ b/src/cobalt/loader/image/image_decoder_unit_test.cc
@@ -0,0 +1,68 @@
+// Copyright 2021 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/loader/image/image_decoder.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace cobalt {
+namespace loader {
+namespace image {
+
+TEST(ImageDecoderUnitTest, ValidImageType) {
+ EXPECT_EQ(DetermineImageType(reinterpret_cast<const uint8*>("\xFF\xD8\xFF")),
+ ImageDecoder::kImageTypeJPEG);
+ EXPECT_EQ(DetermineImageType(reinterpret_cast<const uint8*>("GIF87a")),
+ ImageDecoder::kImageTypeGIF);
+ EXPECT_EQ(DetermineImageType(reinterpret_cast<const uint8*>("GIF89a")),
+ ImageDecoder::kImageTypeGIF);
+ EXPECT_EQ(DetermineImageType(reinterpret_cast<const uint8*>(
+ "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A")),
+ ImageDecoder::kImageTypePNG);
+ EXPECT_EQ(
+ DetermineImageType(reinterpret_cast<const uint8*>("RIFF WEBPVP")),
+ ImageDecoder::kImageTypeWebP);
+ EXPECT_EQ(
+ DetermineImageType(reinterpret_cast<const uint8*>("{\"v\":\"4.6.8\"")),
+ ImageDecoder::kImageTypeJSON);
+ EXPECT_EQ(DetermineImageType(
+ reinterpret_cast<const uint8*>(" {\t\"v\":\"4.6.8\"")),
+ ImageDecoder::kImageTypeJSON);
+ EXPECT_EQ(DetermineImageType(
+ reinterpret_cast<const uint8*>("\r [ \"v\":\"4.6.8\"")),
+ ImageDecoder::kImageTypeJSON);
+}
+
+TEST(ImageDecoderUnitTest, InvalidImageType) {
+ EXPECT_EQ(DetermineImageType(reinterpret_cast<const uint8*>(
+ "\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x01"
+ "\x00")),
+ ImageDecoder::kImageTypeInvalid);
+ EXPECT_EQ(
+ DetermineImageType(reinterpret_cast<const uint8*>("{}\0\0\0\0\0\0")),
+ ImageDecoder::kImageTypeInvalid);
+ EXPECT_EQ(
+ DetermineImageType(reinterpret_cast<const uint8*>("{a\0\0\0\0\0\0")),
+ ImageDecoder::kImageTypeInvalid);
+ EXPECT_EQ(
+ DetermineImageType(reinterpret_cast<const uint8*>("{\"\"\0\0\0\0\0")),
+ ImageDecoder::kImageTypeInvalid);
+ EXPECT_EQ(
+ DetermineImageType(reinterpret_cast<const uint8*>("{\"{\0\0\0\0\0")),
+ ImageDecoder::kImageTypeInvalid);
+}
+
+} // namespace image
+} // namespace loader
+} // namespace cobalt
diff --git a/src/cobalt/loader/loader.gyp b/src/cobalt/loader/loader.gyp
index 3a213f3..8f14dfd 100644
--- a/src/cobalt/loader/loader.gyp
+++ b/src/cobalt/loader/loader.gyp
@@ -142,6 +142,7 @@
'file_fetcher_test.cc',
'font/typeface_decoder_test.cc',
'image/image_decoder_test.cc',
+ 'image/image_decoder_unit_test.cc',
'mesh/mesh_decoder_test.cc',
'loader_test.cc',
'text_decoder_test.cc',
diff --git a/src/cobalt/media_session/media_session_client.cc b/src/cobalt/media_session/media_session_client.cc
index 1a18649..99097ef 100644
--- a/src/cobalt/media_session/media_session_client.cc
+++ b/src/cobalt/media_session/media_session_client.cc
@@ -33,6 +33,9 @@
// Delay to re-query position state after an action has been invoked.
const base::TimeDelta kUpdateDelay = base::TimeDelta::FromMilliseconds(250);
+// Delay to check if the media session state is not active.
+const base::TimeDelta kMaybeFreezeDelay = base::TimeDelta::FromMilliseconds(1500);
+
// Guess the media position state for the media session.
void GuessMediaPositionState(MediaSessionState* session_state,
const media::WebMediaPlayer** guess_player,
@@ -67,7 +70,8 @@
MediaSessionClient::MediaSessionClient(MediaSession* media_session)
: media_session_(media_session),
- platform_playback_state_(kMediaSessionPlaybackStateNone) {
+ platform_playback_state_(kMediaSessionPlaybackStateNone),
+ sequence_number_(0) {
extension_ = static_cast<const CobaltExtensionMediaSessionApi*>(
SbSystemGetExtension(kCobaltExtensionMediaSessionName));
if (extension_) {
@@ -186,6 +190,17 @@
UpdateMediaSessionState();
}
+ if (!is_active()) {
+ media_session_->task_runner_->PostDelayedTask(
+ FROM_HERE, base::Bind(&MediaSessionClient::RunMaybeFreezeCallback,
+ base::Unretained(this), ++sequence_number_),
+ kMaybeFreezeDelay);
+ }
+}
+
+void MediaSessionClient::RunMaybeFreezeCallback(int sequence_number) {
+ if (sequence_number != sequence_number_) return;
+
if (!is_active() && !maybe_freeze_callback_.is_null()) {
maybe_freeze_callback_.Run();
}
diff --git a/src/cobalt/media_session/media_session_client.h b/src/cobalt/media_session/media_session_client.h
index 3e37d1f..115b852 100644
--- a/src/cobalt/media_session/media_session_client.h
+++ b/src/cobalt/media_session/media_session_client.h
@@ -95,6 +95,10 @@
media_session_ = media_session;
}
+ // If the media session is not active, then run MaybeFreezeCallback to
+ // suspend the App.
+ void RunMaybeFreezeCallback(int sequence_number);
+
private:
THREAD_CHECKER(thread_checker_);
MediaSession* media_session_;
@@ -133,6 +137,10 @@
base::Closure maybe_freeze_callback_;
+ // This is for checking the sequence number of PostDelayedTask. It should be
+ // aligned with a single thread.
+ int sequence_number_;
+
DISALLOW_COPY_AND_ASSIGN(MediaSessionClient);
};
diff --git a/src/cobalt/renderer/rasterizer/egl/textured_mesh_renderer.cc b/src/cobalt/renderer/rasterizer/egl/textured_mesh_renderer.cc
index a9305ef..076aaf8 100644
--- a/src/cobalt/renderer/rasterizer/egl/textured_mesh_renderer.cc
+++ b/src/cobalt/renderer/rasterizer/egl/textured_mesh_renderer.cc
@@ -20,6 +20,7 @@
#include <string>
#include <vector>
+#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "cobalt/extension/graphics.h"
#include "cobalt/math/size.h"
@@ -364,28 +365,31 @@
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] << ");";
+ std::string buffer;
+ buffer = " vec4 scale0 = vec4(" +
+ base::NumberToString(color_adjustment.rgba0_scale[0]) + "," +
+ base::NumberToString(color_adjustment.rgba0_scale[1]) + "," +
+ base::NumberToString(color_adjustment.rgba0_scale[2]) + "," +
+ base::NumberToString(color_adjustment.rgba0_scale[3]) + ");" +
+ " vec4 scale1 = vec4(" +
+ base::NumberToString(color_adjustment.rgba1_scale[0]) + "," +
+ base::NumberToString(color_adjustment.rgba1_scale[1]) + "," +
+ base::NumberToString(color_adjustment.rgba1_scale[2]) + "," +
+ base::NumberToString(color_adjustment.rgba1_scale[3]) + ");" +
+ " vec4 scale2 = vec4(" +
+ base::NumberToString(color_adjustment.rgba2_scale[0]) + "," +
+ base::NumberToString(color_adjustment.rgba2_scale[1]) + "," +
+ base::NumberToString(color_adjustment.rgba2_scale[2]) + "," +
+ base::NumberToString(color_adjustment.rgba2_scale[3]) + ");" +
+ " vec4 scale3 = vec4(" +
+ base::NumberToString(color_adjustment.rgba3_scale[0]) + "," +
+ base::NumberToString(color_adjustment.rgba3_scale[1]) + "," +
+ base::NumberToString(color_adjustment.rgba3_scale[2]) + "," +
+ base::NumberToString(color_adjustment.rgba3_scale[3]) + ");";
blit_fragment_shader_source +=
" vec4 color2 = color * color;"
" vec4 color3 = color2 * color;" +
- buffer.str() +
+ buffer +
" color = scale0 + scale1*color + scale2*color2 + scale3*color3;"
" gl_FragColor = clamp(color, vec4(0.0), vec4(1.0));"
"}";
diff --git a/src/cobalt/renderer/rasterizer/skia/skia/skia.gyp b/src/cobalt/renderer/rasterizer/skia/skia/skia.gyp
index dfefca6..5fe1b23 100644
--- a/src/cobalt/renderer/rasterizer/skia/skia/skia.gyp
+++ b/src/cobalt/renderer/rasterizer/skia/skia/skia.gyp
@@ -28,6 +28,7 @@
'target_name': 'skia_library',
'type': 'static_library',
'dependencies': [
+ '<(DEPTH)/base/base.gyp:base',
'skia_library_no_asan',
],
'includes': [
@@ -65,7 +66,6 @@
'target_name': 'filter_fuzz_stub',
'type': 'executable',
'dependencies': [
- '<(DEPTH)/base/base.gyp:base',
'skia',
],
'sources': [
diff --git a/src/cobalt/site/docs/development/setup-android.md b/src/cobalt/site/docs/development/setup-android.md
index 61849d8..f999d81 100644
--- a/src/cobalt/site/docs/development/setup-android.md
+++ b/src/cobalt/site/docs/development/setup-android.md
@@ -9,7 +9,7 @@
## Preliminary Setup
<aside class="note">
-<b>Note:</b> Before proceeding further, refer to the documentation for <a href="setup-linux.md">"Set up your environment - Linux"</a>. Complete the section **Set up your workstation**, then return and complete the following steps.
+<b>Note:</b> Before proceeding further, refer to the documentation for <a href="setup-linux.html">"Set up your environment - Linux"</a>. Complete the section **Set up your workstation**, then return and complete the following steps.
</aside>
1. Additional build dependencies may need to be installed:
@@ -224,7 +224,9 @@
run that on a device, it needs to be packaged into an APK, which is done by the
associated "deploy" target (e.g. nplb_deploy). The Starboard test runner does
all this for you, so just use that to build and run tests. For example, to
-build and run "devel" NPLB on an ARM64 device, from the top 'src' directory:
+build and run "devel" NPLB on an ARM64 device, from the top 'src' directory
+(if you've unnested the 'src' directory, just run this from your top-level
+directory):
```
starboard/tools/testing/test_runner.py -p android-arm64 -c devel -b -r -t nplb
diff --git a/src/cobalt/site/docs/development/setup-linux.md b/src/cobalt/site/docs/development/setup-linux.md
index 6b9df7e..9e40a3e 100644
--- a/src/cobalt/site/docs/development/setup-linux.md
+++ b/src/cobalt/site/docs/development/setup-linux.md
@@ -55,10 +55,29 @@
$ git clone https://cobalt.googlesource.com/cobalt
```
+### Set up Developer Tools
+
+Cobalt's developer tools require a different file structure which we are in the
+process of moving to. For now, if you want to use these tools, you must unnest
+the `src/` directory like so:
+
+```
+$ cd cobalt
+$ git mv src/* ./
+$ git mv src/.* ./
+```
+
+Once you do that, you'll be able to follow the following two steps to have C++
+and Python linting and formatting as well as other helpful checks enabled. Keep
+in mind that after doing this, you'll want to run following commands in the
+top-level directory instead of the `src/` subdirectory.
+
+Git will track this as a large change, we recommend that you create a commit
+for it and rebase that commit of our upstream continuously for now.
+
1. Create a Python 3 virtual environment for working on Cobalt (feel free to use `virtualenvwrapper` instead):
```
- $ cd cobalt
$ python -m venv ~/.virtualenvs/cobalt_dev
$ source ~/.virtualenvs/cobalt_dev
$ pip install -r requirements.txt
diff --git a/src/cobalt/site/docs/development/setup-raspi.md b/src/cobalt/site/docs/development/setup-raspi.md
index 75d43cc..0e58a7d 100644
--- a/src/cobalt/site/docs/development/setup-raspi.md
+++ b/src/cobalt/site/docs/development/setup-raspi.md
@@ -54,7 +54,7 @@
## Set up your workstation
<aside class="note">
-<b>Note:</b> Before proceeding further, refer to the documentation for <a href="setup-linux.md">"Set up your environment - Linux"</a>. Complete the section **Set up your workstation**, then return and complete the following steps.
+<b>Note:</b> Before proceeding further, refer to the documentation for <a href="setup-linux.html">"Set up your environment - Linux"</a>. Complete the section **Set up your workstation**, then return and complete the following steps.
</aside>
The following steps install the cross-compiling toolchain on your workstation.
@@ -106,6 +106,11 @@
## Build, install, and run Cobalt for Raspberry Pi
+<aside class="note">
+<b>Note:</b> If you've unnested the 'src' directory, build and compile the code
+in your top-level checkout of Cobalt instead of the 'src' subdirectory.
+</aside>
+
1. Build the code by navigating to the src directory in your cobalt directory and run the
following command :
diff --git a/src/cobalt/site/docs/reference/starboard/modules/13/media.md b/src/cobalt/site/docs/reference/starboard/modules/13/media.md
index 9b4d7bb..6b46874 100644
--- a/src/cobalt/site/docs/reference/starboard/modules/13/media.md
+++ b/src/cobalt/site/docs/reference/starboard/modules/13/media.md
@@ -682,24 +682,6 @@
bool SbMediaIsBufferUsingMemoryPool()
```
-### SbMediaIsSupported ###
-
-Indicates whether this platform supports decoding `video_codec` and
-`audio_codec` along with decrypting using `key_system`. If `video_codec` is
-`kSbMediaVideoCodecNone` or if `audio_codec` is `kSbMediaAudioCodecNone`, this
-function should return `true` as long as `key_system` is supported on the
-platform to decode any supported input formats.
-
-`video_codec`: The `SbMediaVideoCodec` being checked for platform compatibility.
-`audio_codec`: The `SbMediaAudioCodec` being checked for platform compatibility.
-`key_system`: The key system being checked for platform compatibility.
-
-#### Declaration ####
-
-```
-bool SbMediaIsSupported(SbMediaVideoCodec video_codec, SbMediaAudioCodec audio_codec, const char *key_system)
-```
-
### SbMediaSetAudioWriteDuration ###
Communicate to the platform how far past `current_playback_position` the app
diff --git a/src/cobalt/site/docs/reference/starboard/modules/media.md b/src/cobalt/site/docs/reference/starboard/modules/media.md
index 4ad1e16..6b46874 100644
--- a/src/cobalt/site/docs/reference/starboard/modules/media.md
+++ b/src/cobalt/site/docs/reference/starboard/modules/media.md
@@ -682,12 +682,6 @@
bool SbMediaIsBufferUsingMemoryPool()
```
-#### Declaration ####
-
-```
-bool SbMediaIsSupported(SbMediaVideoCodec video_codec, SbMediaAudioCodec audio_codec, const char *key_system)
-```
-
### SbMediaSetAudioWriteDuration ###
Communicate to the platform how far past `current_playback_position` the app
diff --git a/src/cobalt/updater/network_fetcher.cc b/src/cobalt/updater/network_fetcher.cc
index fb7ea98..1dfbc7c 100644
--- a/src/cobalt/updater/network_fetcher.cc
+++ b/src/cobalt/updater/network_fetcher.cc
@@ -129,6 +129,13 @@
url_fetcher_->Start();
}
+void NetworkFetcher::CancelDownloadToFile() {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+
+ SB_LOG(INFO) << "Canceling DownloadToFile";
+ url_fetcher_.reset();
+}
+
void NetworkFetcher::OnURLFetchResponseStarted(const net::URLFetcher* source) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
std::move(response_started_callback_)
diff --git a/src/cobalt/updater/network_fetcher.h b/src/cobalt/updater/network_fetcher.h
index 1ff2675..17b8909 100644
--- a/src/cobalt/updater/network_fetcher.h
+++ b/src/cobalt/updater/network_fetcher.h
@@ -69,6 +69,7 @@
ProgressCallback progress_callback,
DownloadToFileCompleteCallback
download_to_file_complete_callback) override;
+ void CancelDownloadToFile() override;
// net::URLFetcherDelegate interface.
void OnURLFetchResponseStarted(const net::URLFetcher* source) override;
diff --git a/src/cobalt/updater/updater_module.cc b/src/cobalt/updater/updater_module.cc
index 8f5663f..3941cb6 100644
--- a/src/cobalt/updater/updater_module.cc
+++ b/src/cobalt/updater/updater_module.cc
@@ -174,6 +174,7 @@
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
update_client_->RemoveObserver(updater_observer_.get());
updater_observer_.reset();
+ update_client_->Stop();
update_client_ = nullptr;
if (updater_configurator_ != nullptr) {
diff --git a/src/components/update_client/component.cc b/src/components/update_client/component.cc
index 787ec2e..421dc40 100644
--- a/src/components/update_client/component.cc
+++ b/src/components/update_client/component.cc
@@ -300,6 +300,13 @@
base::BindOnce(&Component::ChangeState, base::Unretained(this)));
}
+#if defined(STARBOARD)
+void Component::Cancel() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ state_->Cancel();
+}
+#endif
+
void Component::ChangeState(std::unique_ptr<State> next_state) {
DCHECK(thread_checker_.CalledOnValidThread());
@@ -532,6 +539,14 @@
DoHandle();
}
+#if defined(STARBOARD)
+void Component::State::Cancel() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ // Further work may be needed to ensure cancelation during any state results
+ // in a clear result and no memory leaks.
+}
+#endif
+
void Component::State::TransitionState(std::unique_ptr<State> next_state) {
DCHECK(thread_checker_.CalledOnValidThread());
DCHECK(next_state);
@@ -726,6 +741,13 @@
DCHECK(thread_checker_.CalledOnValidThread());
}
+#if defined(STARBOARD)
+void Component::StateDownloadingDiff::Cancel() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ crx_downloader_->CancelDownload();
+}
+#endif
+
void Component::StateDownloadingDiff::DoHandle() {
DCHECK(thread_checker_.CalledOnValidThread());
@@ -800,6 +822,13 @@
DCHECK(thread_checker_.CalledOnValidThread());
}
+#if defined(STARBOARD)
+void Component::StateDownloading::Cancel() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ crx_downloader_->CancelDownload();
+}
+#endif
+
void Component::StateDownloading::DoHandle() {
DCHECK(thread_checker_.CalledOnValidThread());
diff --git a/src/components/update_client/component.h b/src/components/update_client/component.h
index 4058985..f6cc035 100644
--- a/src/components/update_client/component.h
+++ b/src/components/update_client/component.h
@@ -55,6 +55,12 @@
// to the next component state before |callback_handle_complete_| is invoked.
void Handle(CallbackHandleComplete callback_handle_complete);
+#if defined(STARBOARD)
+ // Stops update progress for the component and may clean resources used in its
+ // current state.
+ void Cancel();
+#endif
+
CrxUpdateItem GetCrxUpdateItem() const;
// Sets the uninstall state for this component.
@@ -156,6 +162,11 @@
// by the outer component, after the current state is fully handled.
void Handle(CallbackNextState callback);
+#if defined(STARBOARD)
+ // Stops update progress and may clean resources used in the current state.
+ virtual void Cancel();
+#endif
+
ComponentState state() const { return state_; }
protected:
@@ -247,6 +258,9 @@
public:
explicit StateDownloadingDiff(Component* component);
~StateDownloadingDiff() override;
+#if defined(STARBOARD)
+ void Cancel() override;
+#endif
private:
// State overrides.
@@ -270,6 +284,9 @@
public:
explicit StateDownloading(Component* component);
~StateDownloading() override;
+#if defined(STARBOARD)
+ void Cancel() override;
+#endif
private:
// State overrides.
diff --git a/src/components/update_client/crx_downloader.cc b/src/components/update_client/crx_downloader.cc
index fe83b57..8f2bffa 100644
--- a/src/components/update_client/crx_downloader.cc
+++ b/src/components/update_client/crx_downloader.cc
@@ -120,6 +120,12 @@
DoStartDownload(*current_url_);
}
+#if defined(STARBOARD)
+void CrxDownloader::CancelDownload() {
+ DoCancelDownload();
+}
+#endif
+
void CrxDownloader::OnDownloadComplete(
bool is_handled,
const Result& result,
diff --git a/src/components/update_client/crx_downloader.h b/src/components/update_client/crx_downloader.h
index 6378d03..ae19a4a 100644
--- a/src/components/update_client/crx_downloader.h
+++ b/src/components/update_client/crx_downloader.h
@@ -122,6 +122,10 @@
const std::string& expected_hash,
DownloadCallback download_callback);
+#if defined(STARBOARD)
+ void CancelDownload();
+#endif
+
const std::vector<DownloadMetrics> download_metrics() const;
protected:
@@ -151,6 +155,9 @@
private:
virtual void DoStartDownload(const GURL& url) = 0;
+#if defined(STARBOARD)
+ virtual void DoCancelDownload() = 0;
+#endif
void VerifyResponse(bool is_handled,
Result result,
diff --git a/src/components/update_client/network.h b/src/components/update_client/network.h
index daed162..dec108f 100644
--- a/src/components/update_client/network.h
+++ b/src/components/update_client/network.h
@@ -63,6 +63,9 @@
ResponseStartedCallback response_started_callback,
ProgressCallback progress_callback,
DownloadToFileCompleteCallback download_to_file_complete_callback) = 0;
+#if defined(STARBOARD)
+ virtual void CancelDownloadToFile() = 0;
+#endif
protected:
NetworkFetcher() = default;
diff --git a/src/components/update_client/task_update.cc b/src/components/update_client/task_update.cc
index ab445b5..0129e4c 100644
--- a/src/components/update_client/task_update.cc
+++ b/src/components/update_client/task_update.cc
@@ -36,13 +36,25 @@
return;
}
+#if defined(STARBOARD)
+ update_engine_->Update(is_foreground_, ids_, std::move(crx_data_callback_),
+ base::BindOnce(&TaskUpdate::TaskComplete, this),
+ cancelation_closure_);
+#else
update_engine_->Update(is_foreground_, ids_, std::move(crx_data_callback_),
base::BindOnce(&TaskUpdate::TaskComplete, this));
+#endif
}
void TaskUpdate::Cancel() {
DCHECK(thread_checker_.CalledOnValidThread());
+#if defined(STARBOARD)
+ if (cancelation_closure_) { // The engine's picked up the task.
+ std::move(cancelation_closure_).Run();
+ }
+#endif
+
TaskComplete(Error::UPDATE_CANCELED);
}
diff --git a/src/components/update_client/task_update.h b/src/components/update_client/task_update.h
index 4df796b..74c0a6a 100644
--- a/src/components/update_client/task_update.h
+++ b/src/components/update_client/task_update.h
@@ -57,6 +57,9 @@
const std::vector<std::string> ids_;
UpdateClient::CrxDataCallback crx_data_callback_;
Callback callback_;
+#if defined(STARBOARD)
+ base::OnceClosure cancelation_closure_;
+#endif
DISALLOW_COPY_AND_ASSIGN(TaskUpdate);
};
diff --git a/src/components/update_client/update_client.cc b/src/components/update_client/update_client.cc
index 369c6d3..6ce65bf 100644
--- a/src/components/update_client/update_client.cc
+++ b/src/components/update_client/update_client.cc
@@ -201,6 +201,16 @@
is_stopped_ = true;
+ // Cancel the pending tasks. These tasks are safe to cancel and delete since
+ // they have not picked up by the update engine, and not shared with any
+ // task runner yet.
+ while (!task_queue_.empty()) {
+ auto task = task_queue_.front();
+ task_queue_.pop_front();
+ task->Cancel();
+ }
+
+#if !defined(STARBOARD)
// In the current implementation it is sufficient to cancel the pending
// tasks only. The tasks that are run by the update engine will stop
// making progress naturally, as the main task runner stops running task
@@ -210,15 +220,15 @@
// area, to cancel the running tasks by canceling the current action update.
// This behavior would be expected, correct, and result in no resource leaks
// in all cases, in shutdown or not.
- //
- // Cancel the pending tasks. These tasks are safe to cancel and delete since
- // they have not picked up by the update engine, and not shared with any
- // task runner yet.
- while (!task_queue_.empty()) {
- auto task = task_queue_.front();
- task_queue_.pop_front();
+#else
+ // For Cobalt it's not sufficient to just let the tasks already picked up by
+ // the update engine stop naturally, as this can result in resource leaks and
+ // crashes. These tasks are also canceled so that any necessary cleanup can be
+ // done.
+ for (auto task : tasks_) {
task->Cancel();
}
+#endif
}
void UpdateClientImpl::SendUninstallPing(const std::string& id,
diff --git a/src/components/update_client/update_engine.cc b/src/components/update_client/update_engine.cc
index a6d6920..29c260b 100644
--- a/src/components/update_client/update_engine.cc
+++ b/src/components/update_client/update_engine.cc
@@ -72,10 +72,19 @@
DCHECK(thread_checker_.CalledOnValidThread());
}
+#if !defined(STARBOARD)
void UpdateEngine::Update(bool is_foreground,
const std::vector<std::string>& ids,
UpdateClient::CrxDataCallback crx_data_callback,
Callback callback) {
+#else
+void UpdateEngine::Update(bool is_foreground,
+ const std::vector<std::string>& ids,
+ UpdateClient::CrxDataCallback crx_data_callback,
+ Callback callback,
+ base::OnceClosure& cancelation_closure) {
+
+#endif
DCHECK(thread_checker_.CalledOnValidThread());
if (ids.empty()) {
@@ -100,6 +109,10 @@
config_, is_foreground, ids, std::move(crx_data_callback),
notify_observers_callback_, std::move(callback), crx_downloader_factory_);
DCHECK(!update_context->session_id.empty());
+#if defined(STARBOARD)
+ cancelation_closure = base::BindOnce(&UpdateEngine::Cancel, this,
+ update_context->session_id, ids);
+#endif
const auto result = update_contexts_.insert(
std::make_pair(update_context->session_id, update_context));
@@ -405,6 +418,17 @@
now < throttle_updates_until_;
}
+#if defined(STARBOARD)
+void UpdateEngine::Cancel(const std::string& update_context_session_id,
+ const std::vector<std::string>& crx_component_ids) {
+ const auto& context = update_contexts_.at(update_context_session_id);
+ for (const auto& crx_component_id : crx_component_ids) {
+ auto& component = context->components.at(crx_component_id);
+ component->Cancel();
+ }
+}
+#endif
+
void UpdateEngine::SendUninstallPing(const std::string& id,
const base::Version& version,
int reason,
diff --git a/src/components/update_client/update_engine.h b/src/components/update_client/update_engine.h
index 9601873..4384fa8 100644
--- a/src/components/update_client/update_engine.h
+++ b/src/components/update_client/update_engine.h
@@ -56,10 +56,20 @@
// is not found.
bool GetUpdateState(const std::string& id, CrxUpdateItem* update_state);
+#if !defined(STARBOARD)
void Update(bool is_foreground,
const std::vector<std::string>& ids,
UpdateClient::CrxDataCallback crx_data_callback,
Callback update_callback);
+#else
+ // |cancelation_closure| is populated with a closure that can be run to cancel
+ // the update requested by the caller.
+ void Update(bool is_foreground,
+ const std::vector<std::string>& ids,
+ UpdateClient::CrxDataCallback crx_data_callback,
+ Callback update_callback,
+ base::OnceClosure& cancelation_closure);
+#endif
void SendUninstallPing(const std::string& id,
const base::Version& version,
@@ -96,6 +106,14 @@
// occurs too soon.
bool IsThrottled(bool is_foreground) const;
+#if defined(STARBOARD)
+ // Cancels updates currently handled by the engine for each component
+ // identified by one of |crx_component_ids| for the update context identified
+ // by the |update_context_session_id|.
+ void Cancel(const std::string& update_context_session_id,
+ const std::vector<std::string>& crx_component_ids);
+#endif
+
base::ThreadChecker thread_checker_;
scoped_refptr<Configurator> config_;
UpdateChecker::Factory update_checker_factory_;
diff --git a/src/components/update_client/url_fetcher_downloader.cc b/src/components/update_client/url_fetcher_downloader.cc
index 83c5727..078c275 100644
--- a/src/components/update_client/url_fetcher_downloader.cc
+++ b/src/components/update_client/url_fetcher_downloader.cc
@@ -144,6 +144,13 @@
#endif
}
+#if defined(STARBOARD)
+void UrlFetcherDownloader::DoCancelDownload() {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ network_fetcher_->CancelDownloadToFile();
+}
+#endif
+
void UrlFetcherDownloader::CreateDownloadDir() {
base::CreateNewTempDirectory(FILE_PATH_LITERAL("chrome_url_fetcher_"),
&download_dir_);
diff --git a/src/components/update_client/url_fetcher_downloader.h b/src/components/update_client/url_fetcher_downloader.h
index e5c240d..3880efc 100644
--- a/src/components/update_client/url_fetcher_downloader.h
+++ b/src/components/update_client/url_fetcher_downloader.h
@@ -42,6 +42,9 @@
private:
// Overrides for CrxDownloader.
void DoStartDownload(const GURL& url) override;
+#if defined(STARBOARD)
+ void DoCancelDownload() override;
+#endif
void CreateDownloadDir();
void StartURLFetch(const GURL& url);
diff --git a/src/starboard/android/apk/app/src/main/java/dev/cobalt/media/AudioOutputManager.java b/src/starboard/android/apk/app/src/main/java/dev/cobalt/media/AudioOutputManager.java
index 0e1d66b..18418e8 100644
--- a/src/starboard/android/apk/app/src/main/java/dev/cobalt/media/AudioOutputManager.java
+++ b/src/starboard/android/apk/app/src/main/java/dev/cobalt/media/AudioOutputManager.java
@@ -18,6 +18,7 @@
import android.content.Context;
import android.media.AudioAttributes;
+import android.media.AudioDeviceCallback;
import android.media.AudioDeviceInfo;
import android.media.AudioFormat;
import android.media.AudioManager;
@@ -29,12 +30,16 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
/** Creates and destroys AudioTrackBridge and handles the volume change. */
public class AudioOutputManager implements CobaltMediaSession.UpdateVolumeListener {
private List<AudioTrackBridge> audioTrackBridgeList;
private Context context;
+ AtomicBoolean hasAudioDeviceChanged = new AtomicBoolean(false);
+ boolean hasRegisteredAudioDeviceCallback = false;
+
public AudioOutputManager(Context context) {
this.context = context;
audioTrackBridgeList = new ArrayList<AudioTrackBridge>();
@@ -54,7 +59,7 @@
int sampleRate,
int channelCount,
int preferredBufferSizeInBytes,
- boolean enableAudioRouting,
+ boolean enableAudioDeviceCallback,
int tunnelModeAudioSessionId) {
AudioTrackBridge audioTrackBridge =
new AudioTrackBridge(
@@ -62,13 +67,58 @@
sampleRate,
channelCount,
preferredBufferSizeInBytes,
- enableAudioRouting,
tunnelModeAudioSessionId);
if (!audioTrackBridge.isAudioTrackValid()) {
Log.e(TAG, "AudioTrackBridge has invalid audio track");
return null;
}
audioTrackBridgeList.add(audioTrackBridge);
+ hasAudioDeviceChanged.set(false);
+
+ if (Build.VERSION.SDK_INT < 23
+ || hasRegisteredAudioDeviceCallback
+ || !enableAudioDeviceCallback) {
+ return audioTrackBridge;
+ }
+
+ AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+ audioManager.registerAudioDeviceCallback(
+ new AudioDeviceCallback() {
+ // Since registering a callback triggers an immediate call to onAudioDevicesAdded() with
+ // current devices, don't set |hasAudioDeviceChanged| for this initial call.
+ private boolean initialDevicesAdded = false;
+
+ private void handleConnectedDeviceChange(AudioDeviceInfo[] devices) {
+ for (AudioDeviceInfo info : devices) {
+ // TODO: Determine if AudioDeviceInfo.TYPE_HDMI_EARC should be checked in API 31.
+ if (info.isSink()
+ && (info.getType() == AudioDeviceInfo.TYPE_BLUETOOTH_A2DP
+ || info.getType() == AudioDeviceInfo.TYPE_HDMI_ARC
+ || info.getType() == AudioDeviceInfo.TYPE_HDMI)) {
+ // TODO: Avoid destroying the AudioTrack if the new devices can support the current
+ // AudioFormat.
+ hasAudioDeviceChanged.set(true);
+ break;
+ }
+ }
+ }
+
+ @Override
+ public void onAudioDevicesAdded(AudioDeviceInfo[] addedDevices) {
+ if (initialDevicesAdded) {
+ handleConnectedDeviceChange(addedDevices);
+ return;
+ }
+ initialDevicesAdded = true;
+ }
+
+ @Override
+ public void onAudioDevicesRemoved(AudioDeviceInfo[] removedDevices) {
+ handleConnectedDeviceChange(removedDevices);
+ }
+ },
+ null);
+ hasRegisteredAudioDeviceCallback = true;
return audioTrackBridge;
}
@@ -307,50 +357,95 @@
encoding, Build.VERSION.SDK_INT));
return false;
}
- if (hasPassthroughSupportForV23(encoding)) {
+
+ AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+ AudioDeviceInfo[] deviceInfos = audioManager.getDevices(AudioManager.GET_DEVICES_OUTPUTS);
+
+ // Some devices have issues on reporting playback capability and managing routing when Bluetooth
+ // output is connected. So e/ac3 support is disabled when Bluetooth output device is connected.
+ for (AudioDeviceInfo info : deviceInfos) {
+ if (info.getType() == AudioDeviceInfo.TYPE_BLUETOOTH_A2DP) {
+ Log.i(
+ TAG,
+ String.format(
+ "Passthrough on encoding %d is disabled because Bluetooth output device is"
+ + " connected.",
+ encoding));
+ return false;
+ }
+ }
+
+ // Sample rate is not provided when the function is called, assume it is 48000.
+ final int DEFAULT_SURROUND_SAMPLE_RATE = 48000;
+
+ if (hasPassthroughSupportForV23(deviceInfos, encoding)) {
Log.i(
TAG,
String.format(
"Passthrough on encoding %d is supported, as hasPassthroughSupportForV23() returns"
+ " true.",
encoding));
- return true;
- }
- if (Build.VERSION.SDK_INT < 29) {
- Log.i(
- TAG,
- String.format(
- "Passthrough on encoding %d is rejected, as"
- + " hasDirectSurroundingPlaybackSupportForV29() is not called for api %d.",
- encoding, Build.VERSION.SDK_INT));
- return false;
- }
- if (hasDirectSurroundingPlaybackSupportForV29(encoding)) {
- Log.i(
- TAG,
- String.format(
- "Passthrough on encoding %d is supported, as"
- + " hasDirectSurroundingPlaybackSupportForV29() returns true.",
- encoding));
- return true;
+ } else {
+ if (Build.VERSION.SDK_INT < 29) {
+ Log.i(
+ TAG,
+ String.format(
+ "Passthrough on encoding %d is rejected, as"
+ + " hasDirectSurroundPlaybackSupportForV29() is not called for api %d.",
+ encoding, Build.VERSION.SDK_INT));
+ return false;
+ }
+ if (hasDirectSurroundPlaybackSupportForV29(encoding, DEFAULT_SURROUND_SAMPLE_RATE)) {
+ Log.i(
+ TAG,
+ String.format(
+ "Passthrough on encoding %d is supported, as"
+ + " hasDirectSurroundPlaybackSupportForV29() returns true.",
+ encoding));
+ } else {
+ Log.i(
+ TAG,
+ String.format(
+ "Passthrough on encoding %d is not supported, as"
+ + " hasDirectSurroundPlaybackSupportForV29() returns false.",
+ encoding));
+ return false;
+ }
}
- Log.i(
- TAG,
- String.format(
- "Passthrough on encoding %d is not supported, as"
- + " hasDirectSurroundingPlaybackSupportForV29() returns false.",
- encoding));
- return false;
+ Log.i(TAG, "Verify passthrough support by creating an AudioTrack.");
+
+ try {
+ AudioTrack audioTrack =
+ new AudioTrack(
+ getDefaultAudioAttributes(),
+ getPassthroughAudioFormatFor(encoding, DEFAULT_SURROUND_SAMPLE_RATE),
+ AudioTrack.getMinBufferSize(48000, AudioFormat.CHANNEL_OUT_5POINT1, encoding),
+ AudioTrack.MODE_STREAM,
+ AudioManager.AUDIO_SESSION_ID_GENERATE);
+ audioTrack.release();
+ } catch (Exception e) {
+ // AudioTrack creation can fail if the audio is routed to an unexpected device. For example,
+ // when the user has Bluetooth headphones connected, or when the encoding is EAC3 and both
+ // HDMI and SPDIF are connected, where the output should fallback to AC3.
+ Log.w(
+ TAG,
+ String.format(
+ "Passthrough on encoding %d is disabled because creating AudioTrack raises"
+ + " exception: ",
+ encoding),
+ e);
+ return false;
+ }
+
+ Log.i(TAG, "AudioTrack creation succeeded, passthrough support verified.");
+
+ return true;
}
/** Returns whether passthrough on `encoding` is supported for API 23 and above. */
@RequiresApi(23)
- private boolean hasPassthroughSupportForV23(int encoding) {
- AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
- AudioDeviceInfo[] deviceInfos = audioManager.getDevices(AudioManager.GET_DEVICES_OUTPUTS);
-
- // TODO: Verify the follow code returns false if non-surrounding BT device is routed.
+ private boolean hasPassthroughSupportForV23(final AudioDeviceInfo[] deviceInfos, int encoding) {
for (AudioDeviceInfo info : deviceInfos) {
final int type = info.getType();
if (type != AudioDeviceInfo.TYPE_HDMI && type != AudioDeviceInfo.TYPE_HDMI_ARC) {
@@ -394,39 +489,50 @@
}
@RequiresApi(29)
- /**
- * Returns whether direct playback on surrounding `encoding` is supported for API 29 and above.
- */
- private boolean hasDirectSurroundingPlaybackSupportForV29(int encoding) {
+ /** Returns whether direct playback on surround `encoding` is supported for API 29 and above. */
+ private boolean hasDirectSurroundPlaybackSupportForV29(int encoding, int sampleRate) {
if (encoding != AudioFormat.ENCODING_AC3
&& encoding != AudioFormat.ENCODING_E_AC3
&& encoding != AudioFormat.ENCODING_E_AC3_JOC) {
Log.w(
TAG,
String.format(
- "hasDirectSurroundingPlaybackSupportForV29() encountered unsupported encoding %d.",
+ "hasDirectSurroundPlaybackSupportForV29() encountered unsupported encoding %d.",
encoding));
return false;
}
- // Sample rate is not provided when the function is called, assume it is 48000.
- final int DEFAULT_SURROUNDING_SAMPLE_RATE = 48000;
- AudioFormat format =
- new AudioFormat.Builder()
- .setChannelMask(AudioFormat.CHANNEL_OUT_5POINT1)
- .setEncoding(encoding)
- .setSampleRate(DEFAULT_SURROUNDING_SAMPLE_RATE)
- .build();
- AudioAttributes attributes =
- new AudioAttributes.Builder()
- .setUsage(AudioAttributes.USAGE_MEDIA)
- .setContentType(AudioAttributes.CONTENT_TYPE_MOVIE)
- .build();
- final boolean supported = AudioTrack.isDirectPlaybackSupported(format, attributes);
+ boolean supported =
+ AudioTrack.isDirectPlaybackSupported(
+ getPassthroughAudioFormatFor(encoding, sampleRate), getDefaultAudioAttributes());
Log.i(
TAG,
String.format(
"isDirectPlaybackSupported() for encoding %d returned %b.", encoding, supported));
return supported;
}
+
+ // TODO: Move utility functions into a separate class.
+ /** Returns AudioFormat for surround `encoding` and `sampleRate`. */
+ static AudioFormat getPassthroughAudioFormatFor(int encoding, int sampleRate) {
+ return new AudioFormat.Builder()
+ .setChannelMask(AudioFormat.CHANNEL_OUT_5POINT1)
+ .setEncoding(encoding)
+ .setSampleRate(sampleRate)
+ .build();
+ }
+
+ /** Returns default AudioAttributes for surround playbacks. */
+ static AudioAttributes getDefaultAudioAttributes() {
+ // TODO: Turn this into a static variable after it is moved into a separate class.
+ return new AudioAttributes.Builder()
+ .setUsage(AudioAttributes.USAGE_MEDIA)
+ .setContentType(AudioAttributes.CONTENT_TYPE_MOVIE)
+ .build();
+ }
+
+ @UsedByNative
+ private boolean getAndResetHasAudioDeviceChanged() {
+ return hasAudioDeviceChanged.getAndSet(false);
+ }
}
diff --git a/src/starboard/android/apk/app/src/main/java/dev/cobalt/media/AudioTrackBridge.java b/src/starboard/android/apk/app/src/main/java/dev/cobalt/media/AudioTrackBridge.java
index 7441984..0001fde 100644
--- a/src/starboard/android/apk/app/src/main/java/dev/cobalt/media/AudioTrackBridge.java
+++ b/src/starboard/android/apk/app/src/main/java/dev/cobalt/media/AudioTrackBridge.java
@@ -17,11 +17,8 @@
import static dev.cobalt.media.Log.TAG;
import android.media.AudioAttributes;
-import android.media.AudioDeviceInfo;
import android.media.AudioFormat;
import android.media.AudioManager;
-import android.media.AudioRouting;
-import android.media.AudioRouting.OnRoutingChangedListener;
import android.media.AudioTimestamp;
import android.media.AudioTrack;
import android.os.Build;
@@ -30,8 +27,6 @@
import dev.cobalt.util.UsedByNative;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
-import java.util.Arrays;
-import java.util.concurrent.atomic.AtomicBoolean;
/**
* A wrapper of the android AudioTrack class. Android AudioTrack would not start playing until the
@@ -51,10 +46,6 @@
private ByteBuffer avSyncHeader;
private int avSyncPacketBytesRemaining;
- private AtomicBoolean newAudioDeviceAdded = new AtomicBoolean(false);
- private AudioDeviceInfo currentRoutedDevice;
- private OnRoutingChangedListener onRoutingChangedListener;
-
private static int getBytesPerSample(int audioFormat) {
switch (audioFormat) {
case AudioFormat.ENCODING_PCM_16BIT:
@@ -73,10 +64,7 @@
int sampleRate,
int channelCount,
int preferredBufferSizeInBytes,
- boolean enableAudioRouting,
int tunnelModeAudioSessionId) {
- // TODO: Re-enable audio routing when all related bugs are fixed.
- enableAudioRouting = false;
tunnelModeEnabled = tunnelModeAudioSessionId != -1;
int channelConfig;
@@ -121,15 +109,15 @@
.build();
} else {
// TODO: Support ENCODING_E_AC3_JOC for api level 28 or later.
- final boolean is_surrounding =
+ final boolean is_surround =
sampleType == AudioFormat.ENCODING_AC3 || sampleType == AudioFormat.ENCODING_E_AC3;
- // TODO: We start to enforce |CONTENT_TYPE_MOVIE| for surrounding playback, investigate if we
- // can use |CONTENT_TYPE_MOVIE| for all non-surrounding AudioTrack used by video
+ // TODO: We start to enforce |CONTENT_TYPE_MOVIE| for surround playback, investigate if we
+ // can use |CONTENT_TYPE_MOVIE| for all non-surround AudioTrack used by video
// playback.
attributes =
new AudioAttributes.Builder()
.setContentType(
- is_surrounding
+ is_surround
? AudioAttributes.CONTENT_TYPE_MOVIE
: AudioAttributes.CONTENT_TYPE_MUSIC)
.setUsage(AudioAttributes.USAGE_MEDIA)
@@ -176,31 +164,6 @@
audioTrackBufferSize,
preferredBufferSizeInBytes,
AudioTrack.getMinBufferSize(sampleRate, channelConfig, sampleType)));
- if (audioTrack != null && enableAudioRouting && Build.VERSION.SDK_INT >= 24) {
- Log.i(TAG, "Audio routing enabled.");
- currentRoutedDevice = audioTrack.getRoutedDevice();
- onRoutingChangedListener =
- new AudioRouting.OnRoutingChangedListener() {
- @Override
- public void onRoutingChanged(AudioRouting router) {
- AudioDeviceInfo newRoutedDevice = router.getRoutedDevice();
- if (currentRoutedDevice == null && newRoutedDevice != null) {
- if (!areAudioDevicesEqual(currentRoutedDevice, newRoutedDevice)) {
- Log.v(
- TAG,
- String.format(
- "New audio device %s added to AudioTrackAudioSink.",
- newRoutedDevice.getProductName()));
- newAudioDeviceAdded.set(true);
- }
- }
- currentRoutedDevice = newRoutedDevice;
- }
- };
- audioTrack.addOnRoutingChangedListener(onRoutingChangedListener, null);
- } else {
- Log.i(TAG, "Audio routing disabled.");
- }
}
public Boolean isAudioTrackValid() {
@@ -209,9 +172,6 @@
public void release() {
if (audioTrack != null) {
- if (Build.VERSION.SDK_INT >= 24 && onRoutingChangedListener != null) {
- audioTrack.removeOnRoutingChangedListener(onRoutingChangedListener);
- }
audioTrack.release();
}
audioTrack = null;
@@ -424,26 +384,4 @@
}
return audioTrack.getUnderrunCount();
}
-
- @RequiresApi(23)
- private boolean areAudioDevicesEqual(AudioDeviceInfo device1, AudioDeviceInfo device2) {
- if (device1.getId() == device2.getId()
- && device1.getType() == device2.getType()
- && device1.getType() == AudioDeviceInfo.TYPE_BUILTIN_SPEAKER) {
- // This is a workaround for the emulator, which triggers an error callback when switching
- // between devices with different hash codes that are otherwise identical.
- return Arrays.equals(device1.getChannelCounts(), device2.getChannelCounts())
- && Arrays.equals(device1.getChannelIndexMasks(), device2.getChannelIndexMasks())
- && Arrays.equals(device1.getChannelMasks(), device2.getChannelMasks())
- && Arrays.equals(device1.getEncodings(), device2.getEncodings())
- && Arrays.equals(device1.getSampleRates(), device2.getSampleRates())
- && device1.getProductName().equals(device2.getProductName());
- }
- return device1.equals(device2);
- }
-
- @UsedByNative
- private boolean getAndResetHasNewAudioDeviceAdded() {
- return newAudioDeviceAdded.getAndSet(false);
- }
}
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 4bf638b..0ca198c 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
@@ -33,6 +33,7 @@
import dev.cobalt.util.Log;
import dev.cobalt.util.UsedByNative;
import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
/** A wrapper of the MediaCodec class. */
@SuppressWarnings("unused")
@@ -364,9 +365,7 @@
// This logic is inspired by
// https://github.com/google/ExoPlayer/blob/deb9b301b2c7ef66fdd7d8a3e58298a79ba9c619/library/core/src/main/java/com/google/android/exoplayer2/extractor/mkv/MatroskaExtractor.java#L1803.
- byte[] hdrStaticInfoData = new byte[25];
- ByteBuffer hdrStaticInfo = ByteBuffer.wrap(hdrStaticInfoData);
-
+ ByteBuffer hdrStaticInfo = ByteBuffer.allocateDirect(25).order(ByteOrder.LITTLE_ENDIAN);
hdrStaticInfo.put((byte) 0);
hdrStaticInfo.putShort((short) ((primaryRChromaticityX * MAX_CHROMATICITY) + 0.5f));
hdrStaticInfo.putShort((short) ((primaryRChromaticityY * MAX_CHROMATICITY) + 0.5f));
diff --git a/src/starboard/android/arm/platform_configuration/configuration.gni b/src/starboard/android/arm/platform_configuration/configuration.gni
index 92e7a77..a4cf9ff 100644
--- a/src/starboard/android/arm/platform_configuration/configuration.gni
+++ b/src/starboard/android/arm/platform_configuration/configuration.gni
@@ -15,4 +15,5 @@
import("//starboard/android/shared/platform_configuration/configuration.gni")
android_abi = "armeabi-v7a"
+arm_version = 7
sabi_path = "//starboard/sabi/arm/softfp/sabi-v$sb_api_version.json"
diff --git a/src/starboard/android/arm64/platform_configuration/configuration.gni b/src/starboard/android/arm64/platform_configuration/configuration.gni
index 13ca22c..efade93 100644
--- a/src/starboard/android/arm64/platform_configuration/configuration.gni
+++ b/src/starboard/android/arm64/platform_configuration/configuration.gni
@@ -15,4 +15,5 @@
import("//starboard/android/shared/platform_configuration/configuration.gni")
android_abi = "arm64-v8a"
+arm_version = 8
sabi_path = "//starboard/sabi/arm64/sabi-v$sb_api_version.json"
diff --git a/src/starboard/android/arm64/vulkan/platform_configuration/configuration.gni b/src/starboard/android/arm64/vulkan/platform_configuration/configuration.gni
index c6d6f73..b90be0f 100644
--- a/src/starboard/android/arm64/vulkan/platform_configuration/configuration.gni
+++ b/src/starboard/android/arm64/vulkan/platform_configuration/configuration.gni
@@ -15,6 +15,7 @@
import("//starboard/android/shared/platform_configuration/configuration.gni")
android_abi = "arm64-v8a"
+arm_version = 8
sabi_path = "//starboard/sabi/arm64/sabi-v$sb_api_version.json"
enable_vulkan = true
diff --git a/src/starboard/android/shared/audio_renderer_passthrough.cc b/src/starboard/android/shared/audio_renderer_passthrough.cc
index 4f2820d..1f0849c 100644
--- a/src/starboard/android/shared/audio_renderer_passthrough.cc
+++ b/src/starboard/android/shared/audio_renderer_passthrough.cc
@@ -34,8 +34,6 @@
constexpr SbTime kAudioTrackUpdateInternal = kSbTimeMillisecond * 5;
constexpr int kPreferredBufferSizeInBytes = 16 * 1024;
-// TODO: Enable audio routing and link it to client side experiment.
-constexpr bool kEnableAudioRouting = false;
// TODO: Enable passthrough with tunnel mode.
constexpr int kTunnelModeAudioSessionId = -1;
@@ -75,8 +73,10 @@
AudioRendererPassthrough::AudioRendererPassthrough(
const SbMediaAudioSampleInfo& audio_sample_info,
- SbDrmSystem drm_system)
- : audio_sample_info_(audio_sample_info) {
+ SbDrmSystem drm_system,
+ bool enable_audio_device_callback)
+ : audio_sample_info_(audio_sample_info),
+ enable_audio_device_callback_(enable_audio_device_callback) {
SB_DCHECK(audio_sample_info_.codec == kSbMediaAudioCodecAc3 ||
audio_sample_info_.codec == kSbMediaAudioCodecEac3);
if (SbDrmSystemIsValid(drm_system)) {
@@ -384,7 +384,7 @@
optional<SbMediaAudioSampleType>(), // Not required in passthrough mode
audio_sample_info_.number_of_channels,
audio_sample_info_.samples_per_second, kPreferredBufferSizeInBytes,
- kEnableAudioRouting, kTunnelModeAudioSessionId));
+ enable_audio_device_callback_, kTunnelModeAudioSessionId));
if (!audio_track_bridge->is_valid()) {
error_cb_(kSbPlayerErrorDecode, "Error creating AudioTrackBridge");
@@ -436,6 +436,16 @@
SB_DCHECK(error_cb_);
SB_DCHECK(audio_track_bridge_);
+ if (enable_audio_device_callback_ &&
+ audio_track_bridge_->GetAndResetHasAudioDeviceChanged()) {
+ SB_LOG(INFO) << "Audio device changed, raising a capability changed error "
+ "to restart playback.";
+ error_cb_(kSbPlayerErrorCapabilityChanged,
+ "Audio device capability changed");
+ audio_track_bridge_->PauseAndFlush();
+ return;
+ }
+
AudioTrackState current_state;
{
@@ -499,15 +509,21 @@
sample_buffer, samples_to_write, sync_time);
// Error code returned as negative value, like kAudioTrackErrorDeadObject.
if (samples_written < 0) {
- // `kSbPlayerErrorDecode` is used for general SbPlayer error, there is
- // no error code corresponding to audio sink.
- auto error = kSbPlayerErrorDecode;
if (samples_written == AudioTrackBridge::kAudioTrackErrorDeadObject) {
// Inform the audio end point change.
- error = kSbPlayerErrorCapabilityChanged;
+ SB_LOG(INFO)
+ << "Write error for dead audio track, audio device capability "
+ "has likely changed. Restarting playback.";
+ error_cb_(kSbPlayerErrorCapabilityChanged,
+ "Audio device capability changed");
+ audio_track_bridge_->PauseAndFlush();
+ return;
}
- error_cb_(error, FormatString("Error while writing frames: %d",
- samples_written));
+ // `kSbPlayerErrorDecode` is used for general SbPlayer error, there is
+ // no error code corresponding to audio sink.
+ error_cb_(
+ kSbPlayerErrorDecode,
+ FormatString("Error while writing frames: %d", samples_written));
}
decoded_audio_writing_offset_ += samples_written;
diff --git a/src/starboard/android/shared/audio_renderer_passthrough.h b/src/starboard/android/shared/audio_renderer_passthrough.h
index 6d9a050..58a073c 100644
--- a/src/starboard/android/shared/audio_renderer_passthrough.h
+++ b/src/starboard/android/shared/audio_renderer_passthrough.h
@@ -49,7 +49,8 @@
private ::starboard::shared::starboard::player::JobQueue::JobOwner {
public:
AudioRendererPassthrough(const SbMediaAudioSampleInfo& audio_sample_info,
- SbDrmSystem drm_system);
+ SbDrmSystem drm_system,
+ bool enable_audio_device_callback);
~AudioRendererPassthrough() override;
bool is_valid() const { return decoder_ != nullptr; }
@@ -96,8 +97,9 @@
void OnDecoderConsumed();
void OnDecoderOutput();
- // The following two variables are set in the ctor.
+ // The following three variables are set in the ctor.
const SbMediaAudioSampleInfo audio_sample_info_;
+ const bool enable_audio_device_callback_;
// The AudioDecoder is used as a decryptor when the stream is encrypted.
// TODO: Revisit to encapsulate the AudioDecoder as a SbDrmSystemPrivate
// instead. This would need to turn SbDrmSystemPrivate::Decrypt() into
diff --git a/src/starboard/android/shared/audio_track_audio_sink_type.cc b/src/starboard/android/shared/audio_track_audio_sink_type.cc
index 4c46710..57e9aed 100644
--- a/src/starboard/android/shared/audio_track_audio_sink_type.cc
+++ b/src/starboard/android/shared/audio_track_audio_sink_type.cc
@@ -82,7 +82,7 @@
SbAudioSinkPrivate::ErrorFunc error_func,
SbTime start_time,
int tunnel_mode_audio_session_id,
- bool enable_audio_routing,
+ bool enable_audio_device_callback,
void* context)
: type_(type),
channels_(channels),
@@ -105,7 +105,7 @@
channels,
sampling_frequency_hz,
preferred_buffer_size_in_bytes,
- enable_audio_routing,
+ enable_audio_device_callback,
tunnel_mode_audio_session_id) {
SB_DCHECK(update_source_status_func_);
SB_DCHECK(consume_frames_func_);
@@ -178,10 +178,11 @@
while (!quit_) {
int playback_head_position = 0;
SbTime frames_consumed_at = 0;
- if (bridge_.GetAndResetHasNewAudioDeviceAdded(env)) {
- SB_LOG(INFO) << "New audio device added.";
- error_func_(kSbPlayerErrorCapabilityChanged, "New audio device added.",
- context_);
+ if (bridge_.GetAndResetHasAudioDeviceChanged(env)) {
+ SB_LOG(INFO) << "Audio device changed, raising a capability changed "
+ "error to restart playback.";
+ error_func_(kSbPlayerErrorCapabilityChanged,
+ "Audio device capability changed", context_);
break;
}
@@ -328,6 +329,7 @@
capabilities_changed,
FormatString("Error while writing frames: %d", written_frames),
context_);
+ SB_LOG(INFO) << "Restarting playback.";
break;
} else if (written_frames > 0) {
last_written_succeeded_at = now;
@@ -418,13 +420,15 @@
SbAudioSinkPrivate::ErrorFunc error_func,
void* context) {
const SbTime kStartTime = 0;
- const int kTunnelModeAudioSessionId = -1; // disable tunnel mode
- const bool kEnableAudioRouting = true;
+ // Disable tunnel mode.
+ const int kTunnelModeAudioSessionId = -1;
+ // Disable AudioDeviceCallback for WebAudio.
+ const bool kEnableAudioDeviceCallback = false;
return Create(channels, sampling_frequency_hz, audio_sample_type,
audio_frame_storage_type, frame_buffers, frames_per_channel,
update_source_status_func, consume_frames_func, error_func,
- kStartTime, kTunnelModeAudioSessionId, kEnableAudioRouting,
- context);
+ kStartTime, kTunnelModeAudioSessionId,
+ kEnableAudioDeviceCallback, context);
}
SbAudioSink AudioTrackAudioSinkType::Create(
@@ -439,7 +443,7 @@
SbAudioSinkPrivate::ErrorFunc error_func,
SbTime start_media_time,
int tunnel_mode_audio_session_id,
- bool enable_audio_routing,
+ bool enable_audio_device_callback,
void* context) {
int min_required_frames = SbAudioSinkGetMinBufferSizeInFrames(
channels, audio_sample_type, sampling_frequency_hz);
@@ -450,8 +454,8 @@
this, channels, sampling_frequency_hz, audio_sample_type, frame_buffers,
frames_per_channel, preferred_buffer_size_in_bytes,
update_source_status_func, consume_frames_func, error_func,
- start_media_time, tunnel_mode_audio_session_id, enable_audio_routing,
- context);
+ start_media_time, tunnel_mode_audio_session_id,
+ enable_audio_device_callback, context);
if (!audio_sink->IsAudioTrackValid()) {
SB_DLOG(ERROR)
<< "AudioTrackAudioSinkType::Create failed to create audio track";
diff --git a/src/starboard/android/shared/audio_track_audio_sink_type.h b/src/starboard/android/shared/audio_track_audio_sink_type.h
index 5ae9f7b..adf050d 100644
--- a/src/starboard/android/shared/audio_track_audio_sink_type.h
+++ b/src/starboard/android/shared/audio_track_audio_sink_type.h
@@ -68,7 +68,7 @@
SbAudioSinkPrivate::ErrorFunc error_func,
SbTime start_time,
int tunnel_mode_audio_session_id,
- bool enable_audio_routing,
+ bool enable_audio_device_callback,
void* context);
bool IsValid(SbAudioSink audio_sink) override {
@@ -111,7 +111,7 @@
SbAudioSinkPrivate::ErrorFunc error_func,
SbTime start_media_time,
int tunnel_mode_audio_session_id,
- bool enable_audio_routing,
+ bool enable_audio_device_callback,
void* context);
~AudioTrackAudioSink() override;
diff --git a/src/starboard/android/shared/audio_track_bridge.cc b/src/starboard/android/shared/audio_track_bridge.cc
index 572e759..79fe83f 100644
--- a/src/starboard/android/shared/audio_track_bridge.cc
+++ b/src/starboard/android/shared/audio_track_bridge.cc
@@ -39,7 +39,7 @@
int channels,
int sampling_frequency_hz,
int preferred_buffer_size_in_bytes,
- bool enable_audio_routing,
+ bool enable_audio_device_callback,
int tunnel_mode_audio_session_id) {
if (coding_type == kSbMediaAudioCodingTypePcm) {
SB_DCHECK(SbAudioSinkIsAudioSampleTypeSupported(sample_type.value()));
@@ -65,7 +65,7 @@
j_audio_output_manager.Get(), "createAudioTrackBridge",
"(IIIIZI)Ldev/cobalt/media/AudioTrackBridge;",
GetAudioFormatSampleType(coding_type, sample_type), sampling_frequency_hz,
- channels, preferred_buffer_size_in_bytes, enable_audio_routing,
+ channels, preferred_buffer_size_in_bytes, enable_audio_device_callback,
tunnel_mode_audio_session_id);
if (!j_audio_track_bridge) {
// One of the cases that this may hit is when output happened to be switched
@@ -272,13 +272,17 @@
"J");
}
-bool AudioTrackBridge::GetAndResetHasNewAudioDeviceAdded(
+bool AudioTrackBridge::GetAndResetHasAudioDeviceChanged(
JniEnvExt* env /*= JniEnvExt::Get()*/) {
SB_DCHECK(env);
SB_DCHECK(is_valid());
+ ScopedLocalJavaRef<jobject> j_audio_output_manager(
+ env->CallStarboardObjectMethodOrAbort(
+ "getAudioOutputManager", "()Ldev/cobalt/media/AudioOutputManager;"));
+
return env->CallBooleanMethodOrAbort(
- j_audio_track_bridge_, "getAndResetHasNewAudioDeviceAdded", "()Z");
+ j_audio_output_manager.Get(), "getAndResetHasAudioDeviceChanged", "()Z");
}
int AudioTrackBridge::GetUnderrunCount(JniEnvExt* env /*= JniEnvExt::Get()*/) {
diff --git a/src/starboard/android/shared/audio_track_bridge.h b/src/starboard/android/shared/audio_track_bridge.h
index e18e498..607837d 100644
--- a/src/starboard/android/shared/audio_track_bridge.h
+++ b/src/starboard/android/shared/audio_track_bridge.h
@@ -41,7 +41,7 @@
int channels,
int sampling_frequency_hz,
int preferred_buffer_size_in_bytes,
- bool enable_audio_routing,
+ bool enable_audio_device_callback,
int tunnel_mode_audio_session_id);
~AudioTrackBridge();
@@ -79,7 +79,7 @@
// updated on return. It can be nullptr.
int64_t GetPlaybackHeadPosition(SbTime* updated_at,
JniEnvExt* env = JniEnvExt::Get());
- bool GetAndResetHasNewAudioDeviceAdded(JniEnvExt* env = JniEnvExt::Get());
+ bool GetAndResetHasAudioDeviceChanged(JniEnvExt* env = JniEnvExt::Get());
int GetUnderrunCount(JniEnvExt* env = JniEnvExt::Get());
private:
diff --git a/src/starboard/android/shared/gyp_configuration.py b/src/starboard/android/shared/gyp_configuration.py
index e38efdf..018dbb6 100644
--- a/src/starboard/android/shared/gyp_configuration.py
+++ b/src/starboard/android/shared/gyp_configuration.py
@@ -277,52 +277,6 @@
# A map of failing or crashing tests per target.
__FILTERED_TESTS = { # pylint: disable=invalid-name
'player_filter_tests': [
- # All e/ac3 related decoder tests are disabled. They will be
- # re-enabled soon once we can filter out audio decoder tests for
- # passthrough decoders.
- 'AdaptiveAudioDecoderTests/AdaptiveAudioDecoderTest.SingleInput/12',
- 'AdaptiveAudioDecoderTests/AdaptiveAudioDecoderTest.SingleInput/26',
- 'AdaptiveAudioDecoderTests/AdaptiveAudioDecoderTest.SingleInput/40',
- 'AdaptiveAudioDecoderTests/AdaptiveAudioDecoderTest.SingleInput/54',
- 'AdaptiveAudioDecoderTests/AdaptiveAudioDecoderTest.SingleInput/68',
- 'AdaptiveAudioDecoderTests/AdaptiveAudioDecoderTest.SingleInput/82',
- 'AdaptiveAudioDecoderTests/AdaptiveAudioDecoderTest.SingleInput/84',
- 'AdaptiveAudioDecoderTests/AdaptiveAudioDecoderTest.SingleInput/86',
- 'AdaptiveAudioDecoderTests/AdaptiveAudioDecoderTest.SingleInput/88',
- 'AdaptiveAudioDecoderTests/AdaptiveAudioDecoderTest.SingleInput/90',
- 'AdaptiveAudioDecoderTests/AdaptiveAudioDecoderTest.SingleInput/92',
- 'AdaptiveAudioDecoderTests/AdaptiveAudioDecoderTest.SingleInput/94',
- 'AdaptiveAudioDecoderTests/AdaptiveAudioDecoderTest.SingleInput/96',
- 'AdaptiveAudioDecoderTests/AdaptiveAudioDecoderTest.SingleInput/98',
- 'AdaptiveAudioDecoderTests/AdaptiveAudioDecoderTest.SingleInput/100',
- 'AdaptiveAudioDecoderTests/AdaptiveAudioDecoderTest.SingleInput/102',
- 'AdaptiveAudioDecoderTests/AdaptiveAudioDecoderTest.SingleInput/104',
- 'AdaptiveAudioDecoderTests/AdaptiveAudioDecoderTest.MultipleInput/12',
- 'AdaptiveAudioDecoderTests/AdaptiveAudioDecoderTest.MultipleInput/26',
- 'AdaptiveAudioDecoderTests/AdaptiveAudioDecoderTest.MultipleInput/40',
- 'AdaptiveAudioDecoderTests/AdaptiveAudioDecoderTest.MultipleInput/54',
- 'AdaptiveAudioDecoderTests/AdaptiveAudioDecoderTest.MultipleInput/68',
- 'AdaptiveAudioDecoderTests/AdaptiveAudioDecoderTest.MultipleInput/82',
- 'AdaptiveAudioDecoderTests/AdaptiveAudioDecoderTest.MultipleInput/84',
- 'AdaptiveAudioDecoderTests/AdaptiveAudioDecoderTest.MultipleInput/86',
- 'AdaptiveAudioDecoderTests/AdaptiveAudioDecoderTest.MultipleInput/88',
- 'AdaptiveAudioDecoderTests/AdaptiveAudioDecoderTest.MultipleInput/90',
- 'AdaptiveAudioDecoderTests/AdaptiveAudioDecoderTest.MultipleInput/92',
- 'AdaptiveAudioDecoderTests/AdaptiveAudioDecoderTest.MultipleInput/94',
- 'AdaptiveAudioDecoderTests/AdaptiveAudioDecoderTest.MultipleInput/96',
- 'AdaptiveAudioDecoderTests/AdaptiveAudioDecoderTest.MultipleInput/98',
- 'AdaptiveAudioDecoderTests/AdaptiveAudioDecoderTest.' +
- 'MultipleInput/100',
- 'AdaptiveAudioDecoderTests/AdaptiveAudioDecoderTest.' +
- 'MultipleInput/102',
- 'AdaptiveAudioDecoderTests/AdaptiveAudioDecoderTest.' +
- 'MultipleInput/104',
- 'AudioDecoderTests/AudioDecoderTest.SingleInput/12',
- 'AudioDecoderTests/AudioDecoderTest.ResetBeforeInput/12',
- 'AudioDecoderTests/AudioDecoderTest.MultipleInputs/12',
- 'AudioDecoderTests/AudioDecoderTest.LimitedInput/12',
- 'AudioDecoderTests/AudioDecoderTest.ContinuedLimitedInput/12',
-
# GetMaxNumberOfCachedFrames() on Android is device dependent,
# and Android doesn't provide an API to get it. So, this function
# doesn't make sense on Android. But HoldFramesUntilFull tests depend
diff --git a/src/starboard/android/shared/media_is_audio_supported.cc b/src/starboard/android/shared/media_is_audio_supported.cc
index 334c7dd..e7b04de 100644
--- a/src/starboard/android/shared/media_is_audio_supported.cc
+++ b/src/starboard/android/shared/media_is_audio_supported.cc
@@ -46,17 +46,17 @@
return false;
}
MimeType mime_type(content_type);
- // Allows for disabling the use of the AudioRouting API to detect when audio
- // peripherals are connected. Enabled by default.
- // (https://developer.android.com/reference/android/media/AudioRouting)
- auto enable_audio_routing_parameter_value =
- mime_type.GetParamStringValue("enableaudiorouting", "");
- if (!enable_audio_routing_parameter_value.empty() &&
- enable_audio_routing_parameter_value != "true" &&
- enable_audio_routing_parameter_value != "false") {
- SB_LOG(INFO)
- << "Invalid value for audio mime parameter \"enableaudiorouting\": "
- << enable_audio_routing_parameter_value << ".";
+ // Allows for disabling the use of the AudioDeviceCallback API to detect when
+ // audio peripherals are connected. Enabled by default.
+ // (https://developer.android.com/reference/android/media/AudioDeviceCallback)
+ auto enable_audio_device_callback_parameter_value =
+ mime_type.GetParamStringValue("enableaudiodevicecallback", "");
+ if (!enable_audio_device_callback_parameter_value.empty() &&
+ enable_audio_device_callback_parameter_value != "true" &&
+ enable_audio_device_callback_parameter_value != "false") {
+ SB_LOG(INFO) << "Invalid value for audio mime parameter "
+ "\"enableaudiodevicecallback\": "
+ << enable_audio_device_callback_parameter_value << ".";
return false;
}
// Allows for enabling tunneled playback. Disabled by default.
@@ -78,6 +78,23 @@
return false;
}
+ auto audio_passthrough_parameter_value =
+ mime_type.GetParamStringValue("audiopassthrough", "");
+ if (!audio_passthrough_parameter_value.empty() &&
+ audio_passthrough_parameter_value != "true" &&
+ audio_passthrough_parameter_value != "false") {
+ SB_LOG(INFO) << "Invalid value for audio mime parameter "
+ "\"audiopassthrough\": "
+ << audio_passthrough_parameter_value
+ << ". Passthrough is disabled.";
+ return false;
+ }
+ if (audio_passthrough_parameter_value == "false" && is_passthrough) {
+ SB_LOG(INFO) << "Passthrough is rejected because audio mime parameter "
+ "\"audiopassthrough\" == false.";
+ return false;
+ }
+
JniEnvExt* env = JniEnvExt::Get();
ScopedLocalJavaRef<jstring> j_mime(env->NewStringStandardUTFOrAbort(mime));
const bool must_support_tunnel_mode =
diff --git a/src/starboard/android/shared/player_components_factory.h b/src/starboard/android/shared/player_components_factory.h
index fa64270..b2cbfed 100644
--- a/src/starboard/android/shared/player_components_factory.h
+++ b/src/starboard/android/shared/player_components_factory.h
@@ -64,7 +64,7 @@
class AudioRendererSinkAndroid : public ::starboard::shared::starboard::player::
filter::AudioRendererSinkImpl {
public:
- explicit AudioRendererSinkAndroid(bool enable_audio_routing,
+ explicit AudioRendererSinkAndroid(bool enable_audio_device_callback,
int tunnel_mode_audio_session_id = -1)
: AudioRendererSinkImpl(
[=](SbTime start_media_time,
@@ -87,7 +87,8 @@
audio_frame_storage_type, frame_buffers,
frame_buffers_size_in_frames, update_source_status_func,
consume_frames_func, error_func, start_media_time,
- tunnel_mode_audio_session_id, enable_audio_routing, context);
+ tunnel_mode_audio_session_id, enable_audio_device_callback,
+ context);
}) {}
private:
@@ -182,9 +183,28 @@
return (value + alignment - 1) / alignment * alignment;
}
+ static bool IsAudioDeviceCallbackEnabled(
+ const CreationParameters& creation_parameters) {
+ using starboard::shared::starboard::media::MimeType;
+
+ MimeType mime_type(creation_parameters.audio_mime());
+ auto enable_audio_device_callback_parameter_value =
+ mime_type.GetParamStringValue("enableaudiodevicecallback", "");
+ if (enable_audio_device_callback_parameter_value.empty() ||
+ enable_audio_device_callback_parameter_value == "true") {
+ SB_LOG(INFO) << "AudioDeviceCallback is enabled.";
+ return true;
+ }
+ SB_LOG(INFO) << "Mime attribute \"enableaudiodevicecallback\" is set to: "
+ << enable_audio_device_callback_parameter_value
+ << ". AudioDeviceCallback is disabled.";
+ return false;
+ }
+
scoped_ptr<PlayerComponents> CreateComponents(
const CreationParameters& creation_parameters,
std::string* error_message) override {
+ using starboard::shared::starboard::media::MimeType;
SB_DCHECK(error_message);
if (creation_parameters.audio_codec() != kSbMediaAudioCodecAc3 &&
@@ -194,12 +214,21 @@
error_message);
}
+ MimeType audio_mime_type(creation_parameters.audio_mime());
+ if (audio_mime_type.GetParamStringValue("audiopassthrough", "") ==
+ "false") {
+ SB_LOG(INFO) << "Mime attribute \"audiopassthrough\" is set to: "
+ "false. Passthrough is disabled.";
+ return scoped_ptr<PlayerComponents>();
+ }
+
SB_LOG(INFO) << "Creating passthrough components.";
// TODO: Enable tunnel mode for passthrough
scoped_ptr<AudioRendererPassthrough> audio_renderer;
audio_renderer.reset(new AudioRendererPassthrough(
creation_parameters.audio_sample_info(),
- GetExtendedDrmSystem(creation_parameters.drm_system())));
+ GetExtendedDrmSystem(creation_parameters.drm_system()),
+ IsAudioDeviceCallbackEnabled(creation_parameters)));
if (!audio_renderer->is_valid()) {
return scoped_ptr<PlayerComponents>();
}
@@ -328,30 +357,20 @@
creation_parameters.audio_sample_info(),
GetExtendedDrmSystem(creation_parameters.drm_system()),
decoder_creator));
- bool enable_audio_routing = true;
- MimeType audio_mime_type(creation_parameters.audio_mime());
- auto enable_audio_routing_parameter_value =
- 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: "
- << enable_audio_routing_parameter_value
- << ". AudioRouting is disabled.";
- }
+
+ bool enable_audio_device_callback =
+ IsAudioDeviceCallbackEnabled(creation_parameters);
if (tunnel_mode_audio_session_id != -1) {
*audio_renderer_sink = TryToCreateTunnelModeAudioRendererSink(
tunnel_mode_audio_session_id, creation_parameters,
- enable_audio_routing);
+ enable_audio_device_callback);
if (!*audio_renderer_sink) {
tunnel_mode_audio_session_id = -1;
}
}
if (!*audio_renderer_sink) {
audio_renderer_sink->reset(
- new AudioRendererSinkAndroid(enable_audio_routing));
+ new AudioRendererSinkAndroid(enable_audio_device_callback));
}
}
@@ -523,9 +542,9 @@
scoped_ptr<AudioRendererSink> TryToCreateTunnelModeAudioRendererSink(
int tunnel_mode_audio_session_id,
const CreationParameters& creation_parameters,
- bool enable_audio_routing) {
+ bool enable_audio_device_callback) {
scoped_ptr<AudioRendererSink> audio_sink(new AudioRendererSinkAndroid(
- enable_audio_routing, tunnel_mode_audio_session_id));
+ enable_audio_device_callback, tunnel_mode_audio_session_id));
// We need to double check if the audio sink can actually be created.
int max_cached_frames, min_frames_per_append;
GetAudioRendererParams(creation_parameters, &max_cached_frames,
diff --git a/src/starboard/build/platforms.gni b/src/starboard/build/platforms.gni
index 6a7adcb..b3793c2 100644
--- a/src/starboard/build/platforms.gni
+++ b/src/starboard/build/platforms.gni
@@ -53,4 +53,8 @@
name = "android-x86"
path = "starboard/android/x86"
},
+ {
+ name = "raspi-2"
+ path = "starboard/raspi/2"
+ },
]
diff --git a/src/starboard/linux/shared/BUILD.gn b/src/starboard/linux/shared/BUILD.gn
index 522b781..9ef03b9 100644
--- a/src/starboard/linux/shared/BUILD.gn
+++ b/src/starboard/linux/shared/BUILD.gn
@@ -398,6 +398,17 @@
]
deps = [ "//third_party/boringssl:crypto" ]
+ if (sb_api_version == 12) {
+ sources += [
+ "//starboard/shared/stub/speech_recognizer_cancel.cc",
+ "//starboard/shared/stub/speech_recognizer_create.cc",
+ "//starboard/shared/stub/speech_recognizer_destroy.cc",
+ "//starboard/shared/stub/speech_recognizer_is_supported.cc",
+ "//starboard/shared/stub/speech_recognizer_start.cc",
+ "//starboard/shared/stub/speech_recognizer_stop.cc",
+ ]
+ }
+
if (is_internal_build) {
sources += [
"//starboard/linux/shared/drm_create_system.cc",
diff --git a/src/starboard/linux/shared/gyp_configuration.py b/src/starboard/linux/shared/gyp_configuration.py
index b8f0949..4e4a96c 100644
--- a/src/starboard/linux/shared/gyp_configuration.py
+++ b/src/starboard/linux/shared/gyp_configuration.py
@@ -121,3 +121,10 @@
'VideoDecoderTests/VideoDecoderTest.*Invalid*',
],
}
+ # Conditionally disables tests that require ipv6
+ if os.getenv('IPV6_AVAILABLE', 1) == '0':
+ __FILTERED_TESTS['nplb'] = [
+ 'SbSocketAddressTypes/SbSocketGetInterfaceAddressTest.SunnyDayDestination/1',
+ 'SbSocketAddressTypes/SbSocketGetInterfaceAddressTest.SunnyDaySourceForDestination/1',
+ 'SbSocketAddressTypes/SbSocketGetInterfaceAddressTest.SunnyDaySourceNotLoopback/1',
+ ]
diff --git a/src/starboard/nplb/media_can_play_mime_and_key_system_test.cc b/src/starboard/nplb/media_can_play_mime_and_key_system_test.cc
index a117f3c..4c7457c 100644
--- a/src/starboard/nplb/media_can_play_mime_and_key_system_test.cc
+++ b/src/starboard/nplb/media_can_play_mime_and_key_system_test.cc
@@ -175,55 +175,57 @@
TEST(SbMediaCanPlayMimeAndKeySystem, MinimumSupport) {
// H.264 High Profile Level 4.2
SbMediaSupportType result = SbMediaCanPlayMimeAndKeySystem(
- "video/mp4; codecs=\"avc1.64402a\"; width=1920; height=1080; "
- "framerate=30; bitrate=20000",
+ "video/mp4; codecs=\"avc1.64002a\"; width=1920; height=1080; "
+ "framerate=30; bitrate=20000000",
"");
ASSERT_EQ(result, kSbMediaSupportTypeProbably);
// H.264 Main Profile Level 4.2
result = SbMediaCanPlayMimeAndKeySystem(
- "video/mp4; codecs=\"avc1.4d402a\"; width=1920; height=1080; "
+ "video/mp4; codecs=\"avc1.4d002a\"; width=1920; height=1080; "
"framerate=30;",
"");
ASSERT_EQ(result, kSbMediaSupportTypeProbably);
result = SbMediaCanPlayMimeAndKeySystem(
- "video/mp4; codecs=\"avc1.4d402a\"; width=0; height=0; "
+ "video/mp4; codecs=\"avc1.4d002a\"; width=0; height=0; "
"framerate=0; bitrate=0",
"");
ASSERT_EQ(result, kSbMediaSupportTypeProbably);
result = SbMediaCanPlayMimeAndKeySystem(
- "video/mp4; codecs=\"avc1.4d402a\"; width=-0; height=-0; "
+ "video/mp4; codecs=\"avc1.4d002a\"; width=-0; height=-0; "
"framerate=-0; bitrate=-0",
"");
ASSERT_EQ(result, kSbMediaSupportTypeProbably);
// H.264 Main Profile Level 2.1
result = SbMediaCanPlayMimeAndKeySystem(
- "video/mp4; codecs=\"avc1.4d4015\"; width=432; height=240; "
+ "video/mp4; codecs=\"avc1.4d0015\"; width=432; height=240; "
"framerate=15;",
"");
ASSERT_EQ(result, kSbMediaSupportTypeProbably);
// AV1 Main Profile 1080p
result = SbMediaCanPlayMimeAndKeySystem(
- "video/mp4; codecs=\"av01.0.05M.08\"; width=1920; height=1080; "
- "framerate=30; bitrate=20000",
+ "video/mp4; codecs=\"av01.0.09M.08\"; width=1920; height=1080; "
+ "framerate=30; bitrate=20000000",
"");
// VP9 1080p
result = SbMediaCanPlayMimeAndKeySystem(
- "video/webm; codecs=\"vp9\"; width=1920; height=1080; framerate=60", "");
+ "video/webm; codecs=\"vp9\"; width=1920; height=1080; framerate=60; "
+ "bitrate=20000000",
+ "");
// AAC-LC
result = SbMediaCanPlayMimeAndKeySystem(
- "audio/mp4; codecs=\"mp4a.40.2\"; channels=2; bitrate=256;", "");
+ "audio/mp4; codecs=\"mp4a.40.2\"; channels=2; bitrate=256000;", "");
ASSERT_EQ(result, kSbMediaSupportTypeProbably);
// HE-AAC
result = SbMediaCanPlayMimeAndKeySystem(
- "audio/mp4; codecs=\"mp4a.40.5\"; channels=2; bitrate=48;", "");
+ "audio/mp4; codecs=\"mp4a.40.5\"; channels=2; bitrate=48000;", "");
ASSERT_EQ(result, kSbMediaSupportTypeProbably);
}
@@ -286,6 +288,7 @@
}
}
+// TODO: Create an abstraction to shorten the length of this test.
TEST(SbMediaCanPlayMimeAndKeySystem, PrintMaximumSupport) {
// AVC
std::string avc_resolution = "Unsupported";
@@ -298,14 +301,14 @@
avc_resolution = "1080p";
// 2K
result = SbMediaCanPlayMimeAndKeySystem(
- "video/mp4; codecs=\"avc1.64402a\"; width=2560; height=1440; "
+ "video/mp4; codecs=\"avc1.64002a\"; width=2560; height=1440; "
"framerate=30",
"");
if (result == kSbMediaSupportTypeProbably) {
avc_resolution = "2K";
// 4K
result = SbMediaCanPlayMimeAndKeySystem(
- "video/mp4; codecs=\"avc1.64402a\"; width=3840; height=2160; "
+ "video/mp4; codecs=\"avc1.64002a\"; width=3840; height=2160; "
"framerate=30",
"");
if (result == kSbMediaSupportTypeProbably) {
@@ -392,7 +395,7 @@
// 1080p
result = SbMediaCanPlayMimeAndKeySystem(
"video/webm; codecs=\"vp09.02.51.10.01.09.16.09.00\"; width=1920; "
- "height=1080",
+ "height=1080; framerate=30",
"");
if (result == kSbMediaSupportTypeProbably) {
vp9_hdr_resolution = "1080p";
@@ -418,21 +421,21 @@
std::string av1_resolution = "Unsupported";
// 1080p
result = SbMediaCanPlayMimeAndKeySystem(
- "video/mp4; codecs=\"av01.0.08M.08\"; width=1920; "
+ "video/mp4; codecs=\"av01.0.09M.08\"; width=1920; "
"height=1080; framerate=30",
"");
if (result == kSbMediaSupportTypeProbably) {
av1_resolution = "1080p";
// 2K
result = SbMediaCanPlayMimeAndKeySystem(
- "video/mp4; codecs=\"av01.0.08M.08\"; width=2560; "
+ "video/mp4; codecs=\"av01.0.12M.08\"; width=2560; "
"height=1440; framerate=30",
"");
if (result == kSbMediaSupportTypeProbably) {
av1_resolution = "2K";
// 4K
result = SbMediaCanPlayMimeAndKeySystem(
- "video/mp4; codecs=\"av01.0.08M.08\"; width=3840; "
+ "video/mp4; codecs=\"av01.0.12M.08\"; width=3840; "
"height=2160; framerate=30",
"");
if (result == kSbMediaSupportTypeProbably) {
@@ -444,22 +447,22 @@
std::string av1_hfr_resolution = "Unsupported";
// 1080p
result = SbMediaCanPlayMimeAndKeySystem(
- "video/mp4; codecs=\"av01.0.08M.08\"; width=1920; "
- "height=1080; framerate=60",
+ "video/mp4; codecs=\"av01.0.09M.08\"; width=1920; height=1080; "
+ "framerate=60",
"");
if (result == kSbMediaSupportTypeProbably) {
av1_hfr_resolution = "1080p";
// 2K
result = SbMediaCanPlayMimeAndKeySystem(
- "video/mp4; codecs=\"av01.0.08M.08\"; width=2560; "
- "height=1440; framerate=60",
+ "video/mp4; codecs=\"av01.0.12M.08\"; width=2560; height=1440; "
+ "framerate=60",
"");
if (result == kSbMediaSupportTypeProbably) {
av1_hfr_resolution = "2K";
// 4K
result = SbMediaCanPlayMimeAndKeySystem(
- "video/mp4; codecs=\"av01.0.08M.08\"; width=3840; "
- "height=2160; framerate=60",
+ "video/mp4; codecs=\"av01.0.13M.08\"; width=3840; height=2160; "
+ "framerate=60",
"");
if (result == kSbMediaSupportTypeProbably) {
av1_hfr_resolution = "4K";
@@ -472,21 +475,21 @@
// 1080p
result = SbMediaCanPlayMimeAndKeySystem(
"video/mp4; codecs=\"av01.0.09M.10.0.110.09.16.09.0\"; width=1920; "
- "height=1080; framerate=30",
+ "height=1080",
"");
if (result == kSbMediaSupportTypeProbably) {
av1_hdr_resolution = "1080p";
// 2K
result = SbMediaCanPlayMimeAndKeySystem(
"video/mp4; codecs=\"av01.0.12M.10.0.110.09.16.09.0\"; width=2560; "
- "height=1440; framerate=30",
+ "height=1440",
"");
if (result == kSbMediaSupportTypeProbably) {
av1_hdr_resolution = "2K";
// 4K
result = SbMediaCanPlayMimeAndKeySystem(
"video/mp4; codecs=\"av01.0.13M.10.0.110.09.16.09.0\"; width=3840; "
- "height=2160; framerate=30",
+ "height=2160",
"");
if (result == kSbMediaSupportTypeProbably) {
av1_hdr_resolution = "4K";
@@ -514,7 +517,7 @@
std::string opus_support = "Unsupported";
result = SbMediaCanPlayMimeAndKeySystem(
"audio/webm; codecs=\"opus\"; "
- "channels=2; bitrate=576;",
+ "channels=2; bitrate=128000;",
"");
if (result == kSbMediaSupportTypeProbably) {
opus_support = "Supported";
@@ -524,7 +527,7 @@
std::string opus51_support = "Unsupported";
result = SbMediaCanPlayMimeAndKeySystem(
"audio/webm; codecs=\"opus\"; "
- "channels=6; bitrate=576;",
+ "channels=6; bitrate=576000;",
"");
if (result == kSbMediaSupportTypeProbably) {
opus51_support = "Supported";
@@ -533,7 +536,7 @@
// AC-3
std::string ac3_support = "Unsupported";
result = SbMediaCanPlayMimeAndKeySystem(
- "audio/mp4; codecs=\"ac-3\"; channels=2", "");
+ "audio/mp4; codecs=\"ac-3\"; channels=6; bitrate=512000", "");
if (result == kSbMediaSupportTypeProbably) {
ac3_support = "Supported";
}
@@ -541,7 +544,7 @@
// E-AC-3
std::string eac3_support = "Unsupported";
result = SbMediaCanPlayMimeAndKeySystem(
- "audio/mp4; codecs=\"ec-3\"; channels=2", "");
+ "audio/mp4; codecs=\"ec-3\"; channels=6; bitrate=512000", "");
if (result == kSbMediaSupportTypeProbably) {
eac3_support = "Supported";
}
@@ -561,59 +564,60 @@
<< "\n\tAC-3: " << ac3_support << "\n\tE-AC-3: " << eac3_support;
}
+// TODO: Create an abstraction to shorten the length of this test.
TEST(SbMediaCanPlayMimeAndKeySystem, ValidateQueriesUnderPeakCapability) {
// H.264 High Profile Level 4.2 1080p 25 fps
SbMediaSupportType result = SbMediaCanPlayMimeAndKeySystem(
- "video/mp4; codecs=\"avc1.64402a\"; width=1920; height=1080; "
+ "video/mp4; codecs=\"avc1.64002a\"; width=1920; height=1080; "
"framerate=25",
"");
ASSERT_EQ(result, kSbMediaSupportTypeProbably);
// H.264 High Profile Level 4.2 1080p 24 fps
result = SbMediaCanPlayMimeAndKeySystem(
- "video/mp4; codecs=\"avc1.64402a\"; width=1920; height=1080; "
+ "video/mp4; codecs=\"avc1.64002a\"; width=1920; height=1080; "
"framerate=24",
"");
ASSERT_EQ(result, kSbMediaSupportTypeProbably);
// H.264 High Profile Level 4.2 1920x818
result = SbMediaCanPlayMimeAndKeySystem(
- "video/mp4; codecs=\"avc1.64402a\"; width=1920; height=818; "
+ "video/mp4; codecs=\"avc1.64002a\"; width=1920; height=818; "
"framerate=30",
"");
ASSERT_EQ(result, kSbMediaSupportTypeProbably);
// H.264 High Profile Level 4.2 720p
result = SbMediaCanPlayMimeAndKeySystem(
- "video/mp4; codecs=\"avc1.64402a\"; width=1280; height=720; "
+ "video/mp4; codecs=\"avc1.64002a\"; width=1280; height=720; "
"framerate=30",
"");
ASSERT_EQ(result, kSbMediaSupportTypeProbably);
// H.264 High Profile Level 4.2 480p
result = SbMediaCanPlayMimeAndKeySystem(
- "video/mp4; codecs=\"avc1.64402a\"; width=640; height=480; "
+ "video/mp4; codecs=\"avc1.64002a\"; width=640; height=480; "
"framerate=30",
"");
ASSERT_EQ(result, kSbMediaSupportTypeProbably);
// H.264 High Profile Level 4.2 360p
result = SbMediaCanPlayMimeAndKeySystem(
- "video/mp4; codecs=\"avc1.64402a\"; width=480; height=360; "
+ "video/mp4; codecs=\"avc1.64002a\"; width=480; height=360; "
"framerate=30",
"");
ASSERT_EQ(result, kSbMediaSupportTypeProbably);
// H.264 High Profile Level 4.2 240p
result = SbMediaCanPlayMimeAndKeySystem(
- "video/mp4; codecs=\"avc1.64402a\"; width=352; height=240; "
+ "video/mp4; codecs=\"avc1.64002a\"; width=352; height=240; "
"framerate=30",
"");
ASSERT_EQ(result, kSbMediaSupportTypeProbably);
// H.264 High Profile Level 4.2 144p
result = SbMediaCanPlayMimeAndKeySystem(
- "video/mp4; codecs=\"avc1.64402a\"; width=256; height=144; "
+ "video/mp4; codecs=\"avc1.64002a\"; width=256; height=144; "
"framerate=30",
"");
ASSERT_EQ(result, kSbMediaSupportTypeProbably);
@@ -635,78 +639,78 @@
// AV1 Main Profile 4K
result = SbMediaCanPlayMimeAndKeySystem(
- "video/mp4; codecs=\"av01.0.13M.10.0.110.09.16.09.0\"; width=3840; "
- "height=2160; framerate=30",
+ "video/mp4; codecs=\"av01.0.12M.08\"; width=3840; height=2160; "
+ "framerate=30",
"");
if (result == kSbMediaSupportTypeProbably) {
// AV1 Main Profile 1440p
result = SbMediaCanPlayMimeAndKeySystem(
- "video/mp4; codecs=\"av01.0.12M.10.0.110.09.16.09.0\"; width=2560; "
- "height=1440; framerate=30",
+ "video/mp4; codecs=\"av01.0.12M.08\"; width=2560; height=1440; "
+ "framerate=30",
"");
ASSERT_EQ(result, kSbMediaSupportTypeProbably);
}
// AV1 Main Profile 1080p
result = SbMediaCanPlayMimeAndKeySystem(
- "video/mp4; codecs=\"av01.0.09M.08.0.110.09.16.09.0\"; width=1920; "
- "height=1080; framerate=30",
+ "video/mp4; codecs=\"av01.0.09M.08\"; width=1920; height=1080; "
+ "framerate=30",
"");
if (result == kSbMediaSupportTypeProbably) {
// AV1 Main Profile 1080p 25 fps
result = SbMediaCanPlayMimeAndKeySystem(
- "video/mp4; codecs=\"av01.0.09M.08.0.110.09.16.09.0\"; width=1920; "
- "height=1080; framerate=25",
+ "video/mp4; codecs=\"av01.0.09M.08\"; width=1920; height=1080; "
+ "framerate=25",
"");
ASSERT_EQ(result, kSbMediaSupportTypeProbably);
// AV1 Main Profile 1080p 24 fps
result = SbMediaCanPlayMimeAndKeySystem(
- "video/mp4; codecs=\"av01.0.09M.08.0.110.09.16.09.0\"; width=1920; "
- "height=1080; framerate=24",
+ "video/mp4; codecs=\"av01.0.09M.08\"; width=1920; height=1080; "
+ "framerate=24",
"");
ASSERT_EQ(result, kSbMediaSupportTypeProbably);
// AV1 Main Profile 1920x818
result = SbMediaCanPlayMimeAndKeySystem(
- "video/mp4; codecs=\"av01.0.09M.08.0.110.09.16.09.0\"; width=1920; "
- "height=818; framerate=30",
+ "video/mp4; codecs=\"av01.0.09M.08\"; width=1920; height=818; "
+ "framerate=30",
"");
ASSERT_EQ(result, kSbMediaSupportTypeProbably);
// AV1 Main Profile 720p
result = SbMediaCanPlayMimeAndKeySystem(
- "video/mp4; codecs=\"av01.0.08M.10.0.110.09.16.09.0\"; width=1280; "
- "height=720; framerate=30",
+ "video/mp4; codecs=\"av01.0.05M.08\"; width=1280; height=720; "
+ "framerate=30",
"");
ASSERT_EQ(result, kSbMediaSupportTypeProbably);
// AV1 Main Profile 480p
result = SbMediaCanPlayMimeAndKeySystem(
- "video/mp4; codecs=\"av01.0.04M.10.0.110.09.16.09.0\"; width=854; "
- "height=480; framerate=30",
+ "video/mp4; codecs=\"av01.0.04M.08\"; width=854; height=480; "
+ "framerate=30",
"");
ASSERT_EQ(result, kSbMediaSupportTypeProbably);
// AV1 Main Profile 360p
result = SbMediaCanPlayMimeAndKeySystem(
- "video/mp4; codecs=\"av01.0.01M.10.0.110.09.16.09.0\"; width=640; "
- "height=360; framerate=30",
+ "video/mp4; codecs=\"av01.0.01M.08\"; width=640; height=360; "
+ "framerate=30",
"");
ASSERT_EQ(result, kSbMediaSupportTypeProbably);
// AV1 Main Profile 240p
result = SbMediaCanPlayMimeAndKeySystem(
- "video/mp4; codecs=\"av01.0.00M.10.0.110.09.16.09.0\"; width=426; "
- "height=240; framerate=30",
+ "video/mp4; codecs=\"av01.0.00M.08\"; width=426; height=240; "
+ "framerate=30",
"");
ASSERT_EQ(result, kSbMediaSupportTypeProbably);
// AV1 Main Profile 144p
result = SbMediaCanPlayMimeAndKeySystem(
- "video/mp4; codecs=\"av01.0.00M.10.0.110.09.16.09.0\"; width=256; "
- "height=144; framerate=30",
+ "video/mp4; codecs=\"av01.0.00M.08\"; width=256; height=144; "
+ "framerate=30",
"");
ASSERT_EQ(result, kSbMediaSupportTypeProbably);
}
diff --git a/src/starboard/raspi/2/BUILD.gn b/src/starboard/raspi/2/BUILD.gn
new file mode 100644
index 0000000..3cf94e9
--- /dev/null
+++ b/src/starboard/raspi/2/BUILD.gn
@@ -0,0 +1,20 @@
+# Copyright 2021 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.
+
+static_library("starboard_platform") {
+ check_includes = false
+ configs += [ "//starboard/build/config:starboard_implementation" ]
+
+ public_deps = [ "//starboard/raspi/shared:starboard_platform" ]
+}
diff --git a/src/starboard/raspi/2/platform_configuration/BUILD.gn b/src/starboard/raspi/2/platform_configuration/BUILD.gn
new file mode 100644
index 0000000..ef03b60
--- /dev/null
+++ b/src/starboard/raspi/2/platform_configuration/BUILD.gn
@@ -0,0 +1,27 @@
+# Copyright 2021 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.
+
+config("platform_configuration") {
+ configs = [
+ "//starboard/build/config/sabi",
+ "//starboard/raspi/shared/platform_configuration",
+ ]
+ cflags = [
+ "-march=armv7-a",
+ "-mfpu=neon-vfpv4",
+ "-mfloat-abi=hard",
+ "-mcpu=cortex-a8",
+ "-mtune=cortex-a8",
+ ]
+}
diff --git a/src/starboard/raspi/2/platform_configuration/configuration.gni b/src/starboard/raspi/2/platform_configuration/configuration.gni
new file mode 100644
index 0000000..77ec5a9
--- /dev/null
+++ b/src/starboard/raspi/2/platform_configuration/configuration.gni
@@ -0,0 +1,20 @@
+# Copyright 2021 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.
+
+import("//starboard/raspi/shared/platform_configuration/configuration.gni")
+
+arm_float_abi = "hard"
+
+sb_evergreen_compatible_use_libunwind = true
+sb_is_evergreen_compatible = true
diff --git a/src/starboard/raspi/2/toolchain/BUILD.gn b/src/starboard/raspi/2/toolchain/BUILD.gn
new file mode 100644
index 0000000..57a35ca
--- /dev/null
+++ b/src/starboard/raspi/2/toolchain/BUILD.gn
@@ -0,0 +1,37 @@
+# Copyright 2021 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.
+
+import("//build/toolchain/gcc_toolchain.gni")
+
+_home_dir = getenv("HOME")
+_clang_base_path = "$_home_dir/starboard-toolchains/x86_64-linux-gnu-clang-chromium-365097-f7e52fbd-8"
+raspi_toolchain_path = "$_home_dir/raspi_tools/tools/arm-bcm2708/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf/bin"
+
+clang_toolchain("host") {
+ clang_base_path = _clang_base_path
+}
+
+gcc_toolchain("target") {
+ cc = "$raspi_toolchain_path/arm-linux-gnueabihf-gcc"
+ cxx = "$raspi_toolchain_path/arm-linux-gnueabihf-g++"
+ ld = cxx
+
+ # We use whatever 'ar' resolves to in gyp.
+ ar = "ar"
+ strip = "$raspi_toolchain_path/arm-linux-gnueabihf-strip"
+
+ toolchain_args = {
+ is_clang = false
+ }
+}
diff --git a/src/starboard/raspi/shared/BUILD.gn b/src/starboard/raspi/shared/BUILD.gn
new file mode 100644
index 0000000..37c97e7
--- /dev/null
+++ b/src/starboard/raspi/shared/BUILD.gn
@@ -0,0 +1,412 @@
+# Copyright 2021 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.
+import("//starboard/shared/starboard/player/buildfiles.gni")
+
+group("starboard_platform") {
+ public_deps = [ ":starboard_platform_sources" ]
+}
+
+static_library("starboard_platform_sources") {
+ sources = [
+ "//starboard/linux/shared/atomic_public.h",
+ "//starboard/linux/shared/configuration_constants.cc",
+ "//starboard/linux/shared/configuration_public.h",
+ "//starboard/linux/shared/netlink.cc",
+ "//starboard/linux/shared/netlink.h",
+ "//starboard/linux/shared/routes.cc",
+ "//starboard/linux/shared/routes.h",
+ "//starboard/linux/shared/system_get_connection_type.cc",
+ "//starboard/linux/shared/system_get_path.cc",
+ "//starboard/linux/shared/system_has_capability.cc",
+ "//starboard/raspi/shared/application_dispmanx.cc",
+ "//starboard/raspi/shared/audio_sink_type_dispatcher.cc",
+ "//starboard/raspi/shared/configuration.cc",
+ "//starboard/raspi/shared/configuration.h",
+ "//starboard/raspi/shared/dispmanx_util.cc",
+ "//starboard/raspi/shared/dispmanx_util.h",
+ "//starboard/raspi/shared/graphics.cc",
+ "//starboard/raspi/shared/graphics.h",
+ "//starboard/raspi/shared/main.cc",
+ "//starboard/raspi/shared/media_is_video_supported.cc",
+ "//starboard/raspi/shared/open_max/decode_target_create.cc",
+ "//starboard/raspi/shared/open_max/decode_target_create.h",
+ "//starboard/raspi/shared/open_max/decode_target_get_info.cc",
+ "//starboard/raspi/shared/open_max/decode_target_internal.h",
+ "//starboard/raspi/shared/open_max/decode_target_release.cc",
+ "//starboard/raspi/shared/open_max/dispmanx_resource_pool.cc",
+ "//starboard/raspi/shared/open_max/dispmanx_resource_pool.h",
+ "//starboard/raspi/shared/open_max/image_decode.cc",
+ "//starboard/raspi/shared/open_max/image_is_decode_supported.cc",
+ "//starboard/raspi/shared/open_max/open_max_component.cc",
+ "//starboard/raspi/shared/open_max/open_max_component.h",
+ "//starboard/raspi/shared/open_max/open_max_component_base.cc",
+ "//starboard/raspi/shared/open_max/open_max_component_base.h",
+ "//starboard/raspi/shared/open_max/open_max_egl_render_component.cc",
+ "//starboard/raspi/shared/open_max/open_max_egl_render_component.h",
+ "//starboard/raspi/shared/open_max/open_max_image_decode_component.cc",
+ "//starboard/raspi/shared/open_max/open_max_image_decode_component.h",
+ "//starboard/raspi/shared/open_max/open_max_video_decode_component.cc",
+ "//starboard/raspi/shared/open_max/open_max_video_decode_component.h",
+ "//starboard/raspi/shared/open_max/video_decoder.cc",
+ "//starboard/raspi/shared/open_max/video_decoder.h",
+ "//starboard/raspi/shared/player_components_factory.cc",
+ "//starboard/raspi/shared/system_get_device_type.cc",
+ "//starboard/raspi/shared/system_get_extensions.cc",
+ "//starboard/raspi/shared/system_get_property.cc",
+ "//starboard/raspi/shared/system_gles2.cc",
+ "//starboard/raspi/shared/thread_create_priority.cc",
+ "//starboard/raspi/shared/video_renderer_sink_impl.cc",
+ "//starboard/raspi/shared/video_renderer_sink_impl.h",
+ "//starboard/raspi/shared/window_create.cc",
+ "//starboard/raspi/shared/window_destroy.cc",
+ "//starboard/raspi/shared/window_get_platform_handle.cc",
+ "//starboard/raspi/shared/window_get_size.cc",
+ "//starboard/raspi/shared/window_internal.cc",
+ "//starboard/shared/alsa/alsa_audio_sink_type.cc",
+ "//starboard/shared/alsa/alsa_audio_sink_type.h",
+ "//starboard/shared/alsa/alsa_util.cc",
+ "//starboard/shared/alsa/alsa_util.h",
+ "//starboard/shared/dlmalloc/memory_map.cc",
+ "//starboard/shared/dlmalloc/memory_protect.cc",
+ "//starboard/shared/dlmalloc/memory_unmap.cc",
+ "//starboard/shared/egl/system_egl.cc",
+ "//starboard/shared/gcc/atomic_gcc_public.h",
+ "//starboard/shared/iso/character_is_alphanumeric.cc",
+ "//starboard/shared/iso/character_is_digit.cc",
+ "//starboard/shared/iso/character_is_hex_digit.cc",
+ "//starboard/shared/iso/character_is_space.cc",
+ "//starboard/shared/iso/character_is_upper.cc",
+ "//starboard/shared/iso/character_to_lower.cc",
+ "//starboard/shared/iso/character_to_upper.cc",
+ "//starboard/shared/iso/directory_close.cc",
+ "//starboard/shared/iso/directory_get_next.cc",
+ "//starboard/shared/iso/directory_open.cc",
+ "//starboard/shared/iso/double_absolute.cc",
+ "//starboard/shared/iso/double_exponent.cc",
+ "//starboard/shared/iso/double_floor.cc",
+ "//starboard/shared/iso/double_is_finite.cc",
+ "//starboard/shared/iso/double_is_nan.cc",
+ "//starboard/shared/iso/memory_allocate_unchecked.cc",
+ "//starboard/shared/iso/memory_compare.cc",
+ "//starboard/shared/iso/memory_copy.cc",
+ "//starboard/shared/iso/memory_find_byte.cc",
+ "//starboard/shared/iso/memory_free.cc",
+ "//starboard/shared/iso/memory_move.cc",
+ "//starboard/shared/iso/memory_reallocate_unchecked.cc",
+ "//starboard/shared/iso/memory_set.cc",
+ "//starboard/shared/iso/string_compare.cc",
+ "//starboard/shared/iso/string_compare_all.cc",
+ "//starboard/shared/iso/string_find_character.cc",
+ "//starboard/shared/iso/string_find_last_character.cc",
+ "//starboard/shared/iso/string_find_string.cc",
+ "//starboard/shared/iso/string_get_length.cc",
+ "//starboard/shared/iso/string_get_length_wide.cc",
+ "//starboard/shared/iso/string_parse_double.cc",
+ "//starboard/shared/iso/string_parse_signed_integer.cc",
+ "//starboard/shared/iso/string_parse_uint64.cc",
+ "//starboard/shared/iso/string_parse_unsigned_integer.cc",
+ "//starboard/shared/iso/string_scan.cc",
+ "//starboard/shared/iso/system_binary_search.cc",
+ "//starboard/shared/iso/system_sort.cc",
+ "//starboard/shared/libevent/socket_waiter_add.cc",
+ "//starboard/shared/libevent/socket_waiter_create.cc",
+ "//starboard/shared/libevent/socket_waiter_destroy.cc",
+ "//starboard/shared/libevent/socket_waiter_internal.cc",
+ "//starboard/shared/libevent/socket_waiter_remove.cc",
+ "//starboard/shared/libevent/socket_waiter_wait.cc",
+ "//starboard/shared/libevent/socket_waiter_wait_timed.cc",
+ "//starboard/shared/libevent/socket_waiter_wake_up.cc",
+ "//starboard/shared/linux/byte_swap.cc",
+ "//starboard/shared/linux/cpu_features_get.cc",
+ "//starboard/shared/linux/dev_input/dev_input.cc",
+ "//starboard/shared/linux/get_home_directory.cc",
+ "//starboard/shared/linux/memory_get_stack_bounds.cc",
+ "//starboard/shared/linux/page_internal.cc",
+ "//starboard/shared/linux/socket_get_interface_address.cc",
+ "//starboard/shared/linux/system_get_random_data.cc",
+ "//starboard/shared/linux/system_get_stack.cc",
+ "//starboard/shared/linux/system_get_total_cpu_memory.cc",
+ "//starboard/shared/linux/system_get_used_cpu_memory.cc",
+ "//starboard/shared/linux/system_is_debugger_attached.cc",
+ "//starboard/shared/linux/system_symbolize.cc",
+ "//starboard/shared/linux/thread_get_id.cc",
+ "//starboard/shared/linux/thread_get_name.cc",
+ "//starboard/shared/linux/thread_set_name.cc",
+ "//starboard/shared/nouser/user_get_current.cc",
+ "//starboard/shared/nouser/user_get_property.cc",
+ "//starboard/shared/nouser/user_get_signed_in.cc",
+ "//starboard/shared/nouser/user_internal.cc",
+ "//starboard/shared/opus/opus_audio_decoder.cc",
+ "//starboard/shared/opus/opus_audio_decoder.h",
+ "//starboard/shared/posix/directory_create.cc",
+ "//starboard/shared/posix/file_atomic_replace.cc",
+ "//starboard/shared/posix/file_can_open.cc",
+ "//starboard/shared/posix/file_close.cc",
+ "//starboard/shared/posix/file_delete.cc",
+ "//starboard/shared/posix/file_exists.cc",
+ "//starboard/shared/posix/file_flush.cc",
+ "//starboard/shared/posix/file_get_info.cc",
+ "//starboard/shared/posix/file_get_path_info.cc",
+ "//starboard/shared/posix/file_open.cc",
+ "//starboard/shared/posix/file_read.cc",
+ "//starboard/shared/posix/file_seek.cc",
+ "//starboard/shared/posix/file_truncate.cc",
+ "//starboard/shared/posix/file_write.cc",
+ "//starboard/shared/posix/log.cc",
+ "//starboard/shared/posix/log_flush.cc",
+ "//starboard/shared/posix/log_format.cc",
+ "//starboard/shared/posix/log_is_tty.cc",
+ "//starboard/shared/posix/log_raw.cc",
+ "//starboard/shared/posix/memory_allocate_aligned_unchecked.cc",
+ "//starboard/shared/posix/memory_flush.cc",
+ "//starboard/shared/posix/memory_free_aligned.cc",
+ "//starboard/shared/posix/set_non_blocking_internal.cc",
+ "//starboard/shared/posix/socket_accept.cc",
+ "//starboard/shared/posix/socket_bind.cc",
+ "//starboard/shared/posix/socket_clear_last_error.cc",
+ "//starboard/shared/posix/socket_connect.cc",
+ "//starboard/shared/posix/socket_create.cc",
+ "//starboard/shared/posix/socket_destroy.cc",
+ "//starboard/shared/posix/socket_free_resolution.cc",
+ "//starboard/shared/posix/socket_get_last_error.cc",
+ "//starboard/shared/posix/socket_get_local_address.cc",
+ "//starboard/shared/posix/socket_internal.cc",
+ "//starboard/shared/posix/socket_is_connected.cc",
+ "//starboard/shared/posix/socket_is_connected_and_idle.cc",
+ "//starboard/shared/posix/socket_is_ipv6_supported.cc",
+ "//starboard/shared/posix/socket_join_multicast_group.cc",
+ "//starboard/shared/posix/socket_listen.cc",
+ "//starboard/shared/posix/socket_receive_from.cc",
+ "//starboard/shared/posix/socket_resolve.cc",
+ "//starboard/shared/posix/socket_send_to.cc",
+ "//starboard/shared/posix/socket_set_broadcast.cc",
+ "//starboard/shared/posix/socket_set_receive_buffer_size.cc",
+ "//starboard/shared/posix/socket_set_reuse_address.cc",
+ "//starboard/shared/posix/socket_set_send_buffer_size.cc",
+ "//starboard/shared/posix/socket_set_tcp_keep_alive.cc",
+ "//starboard/shared/posix/socket_set_tcp_no_delay.cc",
+ "//starboard/shared/posix/socket_set_tcp_window_scaling.cc",
+ "//starboard/shared/posix/storage_write_record.cc",
+ "//starboard/shared/posix/string_compare_no_case.cc",
+ "//starboard/shared/posix/string_compare_no_case_n.cc",
+ "//starboard/shared/posix/string_compare_wide.cc",
+ "//starboard/shared/posix/string_format.cc",
+ "//starboard/shared/posix/string_format_wide.cc",
+ "//starboard/shared/posix/system_break_into_debugger.cc",
+ "//starboard/shared/posix/system_clear_last_error.cc",
+ "//starboard/shared/posix/system_get_error_string.cc",
+ "//starboard/shared/posix/system_get_last_error.cc",
+ "//starboard/shared/posix/system_get_locale_id.cc",
+ "//starboard/shared/posix/system_get_number_of_processors.cc",
+ "//starboard/shared/posix/thread_sleep.cc",
+ "//starboard/shared/posix/time_get_monotonic_now.cc",
+ "//starboard/shared/posix/time_get_monotonic_thread_now.cc",
+ "//starboard/shared/posix/time_get_now.cc",
+ "//starboard/shared/posix/time_is_time_thread_now_supported.cc",
+ "//starboard/shared/posix/time_zone_get_current.cc",
+ "//starboard/shared/posix/time_zone_get_name.cc",
+ "//starboard/shared/pthread/condition_variable_broadcast.cc",
+ "//starboard/shared/pthread/condition_variable_create.cc",
+ "//starboard/shared/pthread/condition_variable_destroy.cc",
+ "//starboard/shared/pthread/condition_variable_signal.cc",
+ "//starboard/shared/pthread/condition_variable_wait.cc",
+ "//starboard/shared/pthread/condition_variable_wait_timed.cc",
+ "//starboard/shared/pthread/mutex_acquire.cc",
+ "//starboard/shared/pthread/mutex_acquire_try.cc",
+ "//starboard/shared/pthread/mutex_create.cc",
+ "//starboard/shared/pthread/mutex_destroy.cc",
+ "//starboard/shared/pthread/mutex_release.cc",
+ "//starboard/shared/pthread/once.cc",
+ "//starboard/shared/pthread/thread_context_get_pointer.cc",
+ "//starboard/shared/pthread/thread_context_internal.cc",
+ "//starboard/shared/pthread/thread_context_internal.h",
+ "//starboard/shared/pthread/thread_create.cc",
+ "//starboard/shared/pthread/thread_create_local_key.cc",
+ "//starboard/shared/pthread/thread_create_priority.h",
+ "//starboard/shared/pthread/thread_destroy_local_key.cc",
+ "//starboard/shared/pthread/thread_detach.cc",
+ "//starboard/shared/pthread/thread_get_current.cc",
+ "//starboard/shared/pthread/thread_get_local_value.cc",
+ "//starboard/shared/pthread/thread_is_equal.cc",
+ "//starboard/shared/pthread/thread_join.cc",
+ "//starboard/shared/pthread/thread_sampler_create.cc",
+ "//starboard/shared/pthread/thread_sampler_destroy.cc",
+ "//starboard/shared/pthread/thread_sampler_freeze.cc",
+ "//starboard/shared/pthread/thread_sampler_internal.cc",
+ "//starboard/shared/pthread/thread_sampler_internal.h",
+ "//starboard/shared/pthread/thread_sampler_is_supported.cc",
+ "//starboard/shared/pthread/thread_sampler_thaw.cc",
+ "//starboard/shared/pthread/thread_set_local_value.cc",
+ "//starboard/shared/pthread/thread_yield.cc",
+ "//starboard/shared/signal/crash_signals.cc",
+ "//starboard/shared/signal/crash_signals.h",
+ "//starboard/shared/signal/suspend_signals.cc",
+ "//starboard/shared/signal/suspend_signals.h",
+ "//starboard/shared/signal/system_request_conceal.cc",
+ "//starboard/shared/signal/system_request_freeze.cc",
+ "//starboard/shared/signal/system_request_suspend.cc",
+ "//starboard/shared/starboard/application.cc",
+ "//starboard/shared/starboard/audio_sink/audio_sink_create.cc",
+ "//starboard/shared/starboard/audio_sink/audio_sink_destroy.cc",
+ "//starboard/shared/starboard/audio_sink/audio_sink_get_max_channels_5_1.cc",
+ "//starboard/shared/starboard/audio_sink/audio_sink_get_min_buffer_size_in_frames.cc",
+ "//starboard/shared/starboard/audio_sink/audio_sink_get_nearest_supported_sample_frequency.cc",
+ "//starboard/shared/starboard/audio_sink/audio_sink_internal.cc",
+ "//starboard/shared/starboard/audio_sink/audio_sink_internal.h",
+ "//starboard/shared/starboard/audio_sink/audio_sink_is_audio_frame_storage_type_supported_interleaved_only.cc",
+ "//starboard/shared/starboard/audio_sink/audio_sink_is_audio_sample_type_supported_float32_only.cc",
+ "//starboard/shared/starboard/audio_sink/audio_sink_is_valid.cc",
+ "//starboard/shared/starboard/audio_sink/stub_audio_sink_type.cc",
+ "//starboard/shared/starboard/audio_sink/stub_audio_sink_type.h",
+ "//starboard/shared/starboard/command_line.cc",
+ "//starboard/shared/starboard/command_line.h",
+ "//starboard/shared/starboard/crash_handler.cc",
+ "//starboard/shared/starboard/crash_handler.h",
+ "//starboard/shared/starboard/directory_can_open.cc",
+ "//starboard/shared/starboard/event_cancel.cc",
+ "//starboard/shared/starboard/event_schedule.cc",
+ "//starboard/shared/starboard/file_atomic_replace_write_file.cc",
+ "//starboard/shared/starboard/file_atomic_replace_write_file.h",
+ "//starboard/shared/starboard/file_mode_string_to_flags.cc",
+ "//starboard/shared/starboard/file_storage/storage_close_record.cc",
+ "//starboard/shared/starboard/file_storage/storage_delete_record.cc",
+ "//starboard/shared/starboard/file_storage/storage_get_record_size.cc",
+ "//starboard/shared/starboard/file_storage/storage_open_record.cc",
+ "//starboard/shared/starboard/file_storage/storage_read_record.cc",
+ "//starboard/shared/starboard/log_mutex.cc",
+ "//starboard/shared/starboard/log_mutex.h",
+ "//starboard/shared/starboard/log_raw_dump_stack.cc",
+ "//starboard/shared/starboard/log_raw_format.cc",
+ "//starboard/shared/starboard/media/media_can_play_mime_and_key_system.cc",
+ "//starboard/shared/starboard/media/media_get_audio_buffer_budget.cc",
+ "//starboard/shared/starboard/media/media_get_audio_configuration_5_1.cc",
+ "//starboard/shared/starboard/media/media_get_audio_output_count_single_audio_output.cc",
+ "//starboard/shared/starboard/media/media_get_buffer_alignment.cc",
+ "//starboard/shared/starboard/media/media_get_buffer_allocation_unit.cc",
+ "//starboard/shared/starboard/media/media_get_buffer_garbage_collection_duration_threshold.cc",
+ "//starboard/shared/starboard/media/media_get_buffer_padding.cc",
+ "//starboard/shared/starboard/media/media_get_buffer_storage_type.cc",
+ "//starboard/shared/starboard/media/media_get_initial_buffer_capacity.cc",
+ "//starboard/shared/starboard/media/media_get_max_buffer_capacity.cc",
+ "//starboard/shared/starboard/media/media_get_progressive_buffer_budget.cc",
+ "//starboard/shared/starboard/media/media_get_video_buffer_budget.cc",
+ "//starboard/shared/starboard/media/media_is_audio_supported_aac_and_opus.cc",
+ "//starboard/shared/starboard/media/media_is_buffer_pool_allocate_on_demand.cc",
+ "//starboard/shared/starboard/media/media_is_buffer_using_memory_pool.cc",
+ "//starboard/shared/starboard/media/media_is_transfer_characteristics_supported.cc",
+ "//starboard/shared/starboard/media/mime_type.cc",
+ "//starboard/shared/starboard/media/mime_type.h",
+ "//starboard/shared/starboard/memory.cc",
+ "//starboard/shared/starboard/new.cc",
+ "//starboard/shared/starboard/queue_application.cc",
+ "//starboard/shared/starboard/string_concat.cc",
+ "//starboard/shared/starboard/string_concat_wide.cc",
+ "//starboard/shared/starboard/string_copy.cc",
+ "//starboard/shared/starboard/string_copy_wide.cc",
+ "//starboard/shared/starboard/string_duplicate.cc",
+ "//starboard/shared/starboard/system_get_random_uint64.cc",
+ "//starboard/shared/starboard/system_request_blur.cc",
+ "//starboard/shared/starboard/system_request_focus.cc",
+ "//starboard/shared/starboard/system_request_pause.cc",
+ "//starboard/shared/starboard/system_request_reveal.cc",
+ "//starboard/shared/starboard/system_request_stop.cc",
+ "//starboard/shared/starboard/system_request_unpause.cc",
+ "//starboard/shared/starboard/system_supports_resume.cc",
+ "//starboard/shared/starboard/window_set_default_options.cc",
+ "//starboard/shared/stub/accessibility_get_caption_settings.cc",
+ "//starboard/shared/stub/accessibility_get_display_settings.cc",
+ "//starboard/shared/stub/accessibility_get_text_to_speech_settings.cc",
+ "//starboard/shared/stub/accessibility_set_captions_enabled.cc",
+ "//starboard/shared/stub/cryptography_create_transformer.cc",
+ "//starboard/shared/stub/cryptography_destroy_transformer.cc",
+ "//starboard/shared/stub/cryptography_get_tag.cc",
+ "//starboard/shared/stub/cryptography_set_authenticated_data.cc",
+ "//starboard/shared/stub/cryptography_set_initialization_vector.cc",
+ "//starboard/shared/stub/cryptography_transform.cc",
+ "//starboard/shared/stub/drm_close_session.cc",
+ "//starboard/shared/stub/drm_create_system.cc",
+ "//starboard/shared/stub/drm_destroy_system.cc",
+ "//starboard/shared/stub/drm_generate_session_update_request.cc",
+ "//starboard/shared/stub/drm_get_metrics.cc",
+ "//starboard/shared/stub/drm_is_server_certificate_updatable.cc",
+ "//starboard/shared/stub/drm_update_server_certificate.cc",
+ "//starboard/shared/stub/drm_update_session.cc",
+ "//starboard/shared/stub/media_is_supported.cc",
+ "//starboard/shared/stub/media_set_audio_write_duration.cc",
+ "//starboard/shared/stub/microphone_close.cc",
+ "//starboard/shared/stub/microphone_create.cc",
+ "//starboard/shared/stub/microphone_destroy.cc",
+ "//starboard/shared/stub/microphone_get_available.cc",
+ "//starboard/shared/stub/microphone_is_sample_rate_supported.cc",
+ "//starboard/shared/stub/microphone_open.cc",
+ "//starboard/shared/stub/microphone_read.cc",
+ "//starboard/shared/stub/speech_synthesis_cancel.cc",
+ "//starboard/shared/stub/speech_synthesis_is_supported.cc",
+ "//starboard/shared/stub/speech_synthesis_speak.cc",
+ "//starboard/shared/stub/system_get_total_gpu_memory.cc",
+ "//starboard/shared/stub/system_get_used_gpu_memory.cc",
+ "//starboard/shared/stub/system_hide_splash_screen.cc",
+ "//starboard/shared/stub/system_network_is_disconnected.cc",
+ "//starboard/shared/stub/system_raise_platform_error.cc",
+ "//starboard/shared/stub/system_sign_with_certification_secret_key.cc",
+ "//starboard/shared/stub/ui_nav_get_interface.cc",
+ "//starboard/shared/stub/window_blur_on_screen_keyboard.cc",
+ "//starboard/shared/stub/window_focus_on_screen_keyboard.cc",
+ "//starboard/shared/stub/window_get_diagonal_size_in_inches.cc",
+ "//starboard/shared/stub/window_get_on_screen_keyboard_bounding_rect.cc",
+ "//starboard/shared/stub/window_hide_on_screen_keyboard.cc",
+ "//starboard/shared/stub/window_is_on_screen_keyboard_shown.cc",
+ "//starboard/shared/stub/window_on_screen_keyboard_is_supported.cc",
+ "//starboard/shared/stub/window_on_screen_keyboard_suggestions_supported.cc",
+ "//starboard/shared/stub/window_set_on_screen_keyboard_keep_focus.cc",
+ "//starboard/shared/stub/window_show_on_screen_keyboard.cc",
+ "//starboard/shared/stub/window_update_on_screen_keyboard_suggestions.cc",
+ ]
+
+ sources += common_player_sources
+
+ configs += [ "//starboard/build/config:starboard_implementation" ]
+
+ public_deps = [
+ ":starboard_base_symbolize",
+ "//starboard:starboard_headers_only",
+ "//starboard/common/",
+ "//starboard/shared/ffmpeg:ffmpeg_linked",
+ "//starboard/shared/starboard/media:media_util",
+ "//starboard/shared/starboard/player/filter:filter_based_player_sources",
+ ]
+ if (sb_is_evergreen_compatible) {
+ public_deps += [ "//starboard/elf_loader:evergreen_config" ]
+ }
+ if (sb_is_evergreen_compatible && !sb_evergreen_compatible_enable_lite) {
+ public_deps += [ "//starboard/loader_app:pending_restart" ]
+ }
+
+ deps = [
+ "//third_party/libevent",
+ "//third_party/opus",
+ ]
+ if (sb_evergreen_compatible_use_libunwind) {
+ deps += [ "//third_party/llvm-project/libunwind:unwind_starboard" ]
+ }
+}
+
+static_library("starboard_base_symbolize") {
+ sources = [
+ "//base/third_party/symbolize/demangle.cc",
+ "//base/third_party/symbolize/symbolize.cc",
+ ]
+
+ public_deps = [ "//starboard/elf_loader:evergreen_info" ]
+}
diff --git a/src/starboard/raspi/shared/platform_configuration/BUILD.gn b/src/starboard/raspi/shared/platform_configuration/BUILD.gn
new file mode 100644
index 0000000..fbbab79
--- /dev/null
+++ b/src/starboard/raspi/shared/platform_configuration/BUILD.gn
@@ -0,0 +1,195 @@
+# Copyright 2021 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.
+
+declare_args() {
+ raspi_home = getenv("RASPI_HOME")
+}
+
+config("compiler_flags") {
+ cflags = []
+ cflags_c = []
+ cflags_cc = []
+ defines = []
+ ldflags = []
+
+ defines += [
+ # By default, <EGL/eglplatform.h> pulls in some X11 headers that have some
+ # nasty macros (|Status|, for example) that conflict with Chromium base.
+ "MESA_EGL_NO_X11_HEADERS",
+
+ # Cobalt on Linux flag
+ "COBALT_LINUX",
+ "__STDC_FORMAT_MACROS", # so that we get PRI*
+ "_GNU_SOURCE=1",
+ ]
+
+ if (is_debug) {
+ cflags += [ "-O0" ]
+ cflags_cc += [ "-frtti" ]
+ } else if (is_devel) {
+ cflags += [ "-O2" ]
+ cflags_cc += [ "-frtti" ]
+ } else {
+ cflags += [ "-Wno-unused-but-set-variable" ]
+ cflags_cc += [ "-fno-rtti" ]
+ }
+
+ ldflags += [
+ "--sysroot=$raspi_home/busterroot",
+
+ # This is a quirk of Raspbian, these are required to link any GL-related
+ # libraries.
+ "-L$raspi_home/busterroot/opt/vc/lib",
+ "-Wl,-rpath=$raspi_home/busterroot/opt/vc/lib",
+ "-L$raspi_home/busterroot/usr/lib/arm-linux-gnueabihf",
+ "-Wl,-rpath=$raspi_home/busterroot/usr/lib/arm-linux-gnueabihf",
+ "-L$raspi_home/busterroot/lib/arm-linux-gnueabihf",
+ "-Wl,-rpath=$raspi_home/busterroot/lib/arm-linux-gnueabihf",
+
+ # Cleanup unused sections
+ "-Wl,-gc-sections",
+ "-Wl,--unresolved-symbols=ignore-in-shared-libs",
+ ]
+
+ cflags += [
+ # Generated by Audio Renderer and Audio Sink implementations.
+ "-Wno-reorder",
+
+ # Generated by code in the raspi/shared/open_max.
+ "-Wno-sign-compare",
+
+ # Generated by many starboard implementation files.
+ "-Wno-unused-parameter",
+ "-Wno-unused-variable",
+ ]
+
+ cflags += [
+ # Force char to be signed.
+ "-fsigned-char",
+
+ # Disable strict aliasing.
+ "-fno-strict-aliasing",
+
+ # Allow Skia"s SkVx.h to convert between vectors of different element
+ # types or number of subparts.
+ "-flax-vector-conversions",
+
+ # To support large files
+ "-D_FILE_OFFSET_BITS=64",
+
+ # Suppress some warnings that will be hard to fix.
+ "-Wno-unused-local-typedefs",
+ "-Wno-unused-result",
+ "-Wno-unused-function",
+ "-Wno-deprecated-declarations",
+ "-Wno-missing-field-initializers",
+ "-Wno-extra",
+ "-Wno-comment", # Talk to my lawyer.
+ "-Wno-narrowing",
+ "-Wno-unknown-pragmas",
+ "-Wno-type-limits", # TODO: We should actually look into these.
+
+ # It"s OK not to use some input parameters. Note that the order
+ # matters: Wall implies Wunused-parameter and Wno-unused-parameter
+ # has no effect if specified before Wall.
+ "-Wno-unused-parameter",
+
+ # Specify the sysroot with all your include dependencies.
+ "--sysroot=$raspi_home/busterroot",
+
+ # This is a quirk of Raspbian, these are required to include any
+ # GL-related headers.
+ "-I$raspi_home/busterroot/opt/vc/include",
+ "-I$raspi_home/busterroot/opt/vc/include/interface/vcos/pthreads",
+ "-I$raspi_home/busterroot/opt/vc/include/interface/vmcs_host/linux",
+ "-I$raspi_home/busterroot/usr/include/arm-linux-gnueabihf",
+ ]
+
+ if (!cobalt_fastbuild && (is_debug || is_devel)) {
+ cflags += [ "-g" ]
+ }
+
+ cflags_c += [ "-std=c11" ]
+ cflags_cc += [
+ "-std=gnu++14",
+ "-Wno-literal-suffix",
+ ]
+
+ if (sb_pedantic_warnings) {
+ cflags += [
+ "-Wall",
+ "-Wextra",
+ "-Wunreachable-code",
+
+ # Raspi toolchain is based off an old version of gcc, which
+ # falsely flags some code. That same code does not warn with gcc 6.3.
+ # This decision should be revisited after raspi toolchain is upgraded.
+ "-Wno-maybe-uninitialized",
+
+ #TODO: Renable -Werror after fixing all warnings.
+ #"-Werror",
+ "-Wno-expansion-to-defined",
+ "-Wno-implicit-fallthrough",
+ ]
+ } else {
+ cflags += [
+ # Do not warn for implicit type conversions that may change a value.
+ "-Wno-conversion",
+ ]
+ }
+}
+
+config("platform_configuration") {
+ libs = [
+ "asound",
+ "avcodec",
+ "avformat",
+ "avutil",
+ ":libpthread.so.0",
+ "pthread",
+ "rt",
+ "openmaxil",
+ "bcm_host",
+ "vcos",
+ "vchiq_arm",
+ "brcmGLESv2",
+ "brcmEGL",
+
+ # Static libs must be last, to avoid __dlopen linker errors
+ "EGL_static",
+ "GLESv2_static",
+ ]
+
+ configs = [ "//starboard/raspi/shared/platform_configuration:compiler_flags" ]
+}
+
+config("speed") {
+ cflags = [
+ "-O2",
+
+ # Compile symbols in separate sections
+ "-ffunction-sections",
+ "-fdata-sections",
+ ]
+}
+
+config("size") {
+ cflags = [
+ "-Os",
+
+ # Compile symbols in separate sections
+ "-ffunction-sections",
+ "-fdata-sections",
+ ]
+}
diff --git a/src/starboard/raspi/shared/platform_configuration/configuration.gni b/src/starboard/raspi/shared/platform_configuration/configuration.gni
new file mode 100644
index 0000000..c96fc14
--- /dev/null
+++ b/src/starboard/raspi/shared/platform_configuration/configuration.gni
@@ -0,0 +1,20 @@
+# Copyright 2021 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.
+
+import("//starboard/build/config/base_configuration.gni")
+
+sb_pedantic_warnings = true
+sb_static_contents_output_data_dir = "$root_out_dir/content"
+
+sabi_path = "//starboard/sabi/arm/hardfp/sabi-v$sb_api_version.json"
diff --git a/src/starboard/shared/starboard/player/filter/testing/adaptive_audio_decoder_test.cc b/src/starboard/shared/starboard/player/filter/testing/adaptive_audio_decoder_test.cc
index dbb1d9e..5127ae4 100644
--- a/src/starboard/shared/starboard/player/filter/testing/adaptive_audio_decoder_test.cc
+++ b/src/starboard/shared/starboard/player/filter/testing/adaptive_audio_decoder_test.cc
@@ -362,8 +362,8 @@
return test_params;
}
- vector<const char*> supported_files =
- GetSupportedAudioTestFiles(kExcludeHeaac, 6);
+ vector<const char*> supported_files = GetSupportedAudioTestFiles(
+ kExcludeHeaac, 6, "audiopassthrough=\"false\"");
// Generate test cases. For example, we have |supported_files| [A, B, C].
// Add tests A->A, A->B, A->C, B->A, B->B, B->C, C->A, C->B and C->C.
diff --git a/src/starboard/shared/starboard/player/filter/testing/audio_decoder_test.cc b/src/starboard/shared/starboard/player/filter/testing/audio_decoder_test.cc
index 74b8adf..00933f3 100644
--- a/src/starboard/shared/starboard/player/filter/testing/audio_decoder_test.cc
+++ b/src/starboard/shared/starboard/player/filter/testing/audio_decoder_test.cc
@@ -635,7 +635,10 @@
INSTANTIATE_TEST_CASE_P(
AudioDecoderTests,
AudioDecoderTest,
- Combine(ValuesIn(GetSupportedAudioTestFiles(kIncludeHeaac, 6)), Bool()));
+ Combine(ValuesIn(GetSupportedAudioTestFiles(kIncludeHeaac,
+ 6,
+ "audiopassthrough=\"false\"")),
+ Bool()));
} // namespace
} // namespace testing
diff --git a/src/third_party/inspector_protocol/crdtp/json_platform.cc b/src/third_party/inspector_protocol/crdtp/json_platform.cc
index 59c8deb..21e26ce 100644
--- a/src/third_party/inspector_protocol/crdtp/json_platform.cc
+++ b/src/third_party/inspector_protocol/crdtp/json_platform.cc
@@ -16,6 +16,9 @@
namespace json {
namespace platform {
bool StrToD(const char* str, double* result) {
+#if SB_IS(EVERGREEN)
+#error "The std::locale::classic() is not supported for Evergreen. Please use base::StringToDouble()."
+#endif
std::istringstream is(str);
is.imbue(std::locale::classic());
is >> *result;
@@ -23,6 +26,9 @@
}
std::string DToStr(double value) {
+#if SB_IS(EVERGREEN)
+#error "The std::locale::classic() is not supported for Evergreen. Please use base::NumberToString()."
+#endif
std::stringstream ss;
ss.imbue(std::locale::classic());
ss << value;
diff --git a/src/third_party/libevent/evdns.c b/src/third_party/libevent/evdns.c
index 05fe594..d72fdaa 100644
--- a/src/third_party/libevent/evdns.c
+++ b/src/third_party/libevent/evdns.c
@@ -783,7 +783,6 @@
for(;;) {
u8 label_len;
- if (j >= length) return -1;
GET8(label_len);
if (!label_len) break;
if (label_len & 0xc0) {
@@ -804,6 +803,7 @@
*cp++ = '.';
}
if (cp + label_len >= end) return -1;
+ if (j + label_len > length) return -1;
memcpy(cp, packet + j, label_len);
cp += label_len;
j += label_len;
diff --git a/src/third_party/libxml/src/entities.c b/src/third_party/libxml/src/entities.c
index ea54cc3..4b41fe9 100644
--- a/src/third_party/libxml/src/entities.c
+++ b/src/third_party/libxml/src/entities.c
@@ -667,11 +667,25 @@
} else {
/*
* We assume we have UTF-8 input.
+ * It must match either:
+ * 110xxxxx 10xxxxxx
+ * 1110xxxx 10xxxxxx 10xxxxxx
+ * 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
+ * That is:
+ * cur[0] is 11xxxxxx
+ * cur[1] is 10xxxxxx
+ * cur[2] is 10xxxxxx if cur[0] is 111xxxxx
+ * cur[3] is 10xxxxxx if cur[0] is 1111xxxx
+ * cur[0] is not 11111xxx
*/
char buf[11], *ptr;
int val = 0, l = 1;
- if (*cur < 0xC0) {
+ if (((cur[0] & 0xC0) != 0xC0) ||
+ ((cur[1] & 0xC0) != 0x80) ||
+ (((cur[0] & 0xE0) == 0xE0) && ((cur[2] & 0xC0) != 0x80)) ||
+ (((cur[0] & 0xF0) == 0xF0) && ((cur[3] & 0xC0) != 0x80)) ||
+ (((cur[0] & 0xF8) == 0xF8))) {
xmlEntitiesErr(XML_CHECK_NOT_UTF8,
"xmlEncodeEntities: input not UTF-8");
if (doc != NULL)
diff --git a/src/third_party/skia/src/sksl/SkSLString.cpp b/src/third_party/skia/src/sksl/SkSLString.cpp
index 5cabe9f..b5a2605 100644
--- a/src/third_party/skia/src/sksl/SkSLString.cpp
+++ b/src/third_party/skia/src/sksl/SkSLString.cpp
@@ -16,6 +16,8 @@
#include <stdlib.h>
#include <string>
+#include "base/strings/string_number_conversions.h"
+
#if defined(STARBOARD)
#include "starboard/client_porting/poem/string_poem.h"
#endif
@@ -229,6 +231,24 @@
}
String to_string(double value) {
+#if defined(STARBOARD)
+ std::string s = base::NumberToString(value);
+ bool needsDotZero = true;
+ for (int i = s.size() - 1; i >= 0; --i) {
+ char c = s[i];
+ if (c == '.' || c == 'e') {
+ needsDotZero = false;
+ break;
+ }
+ }
+ if (needsDotZero) {
+ s += ".0";
+ }
+ if (s.size() > 0 && s[0] == '.') {
+ s = "0" + s;
+ }
+ return String(s.c_str());
+#else
std::stringstream buffer;
buffer.imbue(std::locale::classic());
buffer.precision(17);
@@ -246,6 +266,7 @@
buffer << ".0";
}
return String(buffer.str().c_str());
+#endif
}
SKSL_INT stoi(const String& s) {
@@ -258,6 +279,12 @@
}
SKSL_FLOAT stod(const String& s) {
+#if defined(STARBOARD)
+ double d;
+ bool res= base::StringToDouble(s.c_str(), &d);
+ SkASSERT(res);
+ return d;
+#else
double result;
std::string str(s.c_str(), s.size());
std::stringstream buffer(str);
@@ -265,6 +292,7 @@
buffer >> result;
SkASSERT(!buffer.fail());
return result;
+#endif
}
long stol(const String& s) {
diff --git a/src/third_party/zlib/BUILD.gn b/src/third_party/zlib/BUILD.gn
index abcbcb4..4c5e6b4 100644
--- a/src/third_party/zlib/BUILD.gn
+++ b/src/third_party/zlib/BUILD.gn
@@ -57,7 +57,9 @@
]
if (!is_debug) {
# Use optimize_speed (-O3) to output the _smallest_ code.
- configs -= [ "//build/config/compiler:default_optimization" ]
+ if(!is_starboard) {
+ configs -= [ "//build/config/compiler:default_optimization" ]
+ }
configs += [ "//build/config/compiler:optimize_speed" ]
}
}
@@ -76,7 +78,7 @@
# Disabled for iPhone, as described in DDI0487C_a_armv8_arm:
# "All implementations of the ARMv8.1 architecture are required to
# implement the CRC32* instructions. These are optional in ARMv8.0."
- if (!is_ios) {
+ if (!is_ios && arm_version >= 8) {
defines = [ "CRC32_ARMV8_CRC32" ]
if (is_android) {
defines += [ "ARMV8_OS_ANDROID" ]
@@ -121,7 +123,9 @@
]
if (!is_debug) {
- configs -= [ "//build/config/compiler:default_optimization" ]
+ if(!is_starboard) {
+ configs -= [ "//build/config/compiler:default_optimization" ]
+ }
configs += [ "//build/config/compiler:optimize_speed" ]
}
}
@@ -174,7 +178,9 @@
if (use_arm_neon_optimizations && !is_debug) {
# Here we trade better performance on newer/bigger ARMv8 cores
# for less perf on ARMv7, per crbug.com/772870#c40
- configs -= [ "//build/config/compiler:default_optimization" ]
+ if(!is_starboard) {
+ configs -= [ "//build/config/compiler:default_optimization" ]
+ }
configs += [ "//build/config/compiler:optimize_speed" ]
}
}
@@ -312,7 +318,10 @@
cflags_c += [ "-Wno-missing-braces" ]
deps += [ ":zlib_crc32_simd" ]
} else if (use_arm_neon_optimizations) {
- sources += [ "contrib/optimizations/slide_hash_neon.h" ]
+ sources += [
+ "contrib/optimizations/slide_hash_neon.c",
+ "contrib/optimizations/slide_hash_neon.h",
+ ]
deps += [ ":zlib_arm_crc32" ]
}
} else {
diff --git a/src/tools/format_ninja.py b/src/tools/format_ninja.py
index b0d1ba0..f18e622 100644
--- a/src/tools/format_ninja.py
+++ b/src/tools/format_ninja.py
@@ -33,6 +33,7 @@
from typing import List, Tuple
_ACTION_COMPONENTS = ['directory', 'command', 'file', 'output']
+STRIP = 0
def make_path_absolute(path: str, directory: str) -> str:
@@ -43,6 +44,9 @@
def remove_directory_path(path: str, directory: str) -> str:
+ if STRIP :
+ dirsplit = directory.split(os.path.sep)
+ directory = os.path.sep.join(dirsplit[:-(STRIP)])
if os.path.commonpath([path, directory]) != directory:
return path
@@ -113,7 +117,10 @@
parser = argparse.ArgumentParser()
parser.add_argument('json_filename', type=str)
parser.add_argument('-o', '--output', type=str)
+ parser.add_argument('-p', '--strip', type=int)
args = parser.parse_args()
+ if args.strip:
+ STRIP = int(args.strip)
output = args.output if args.output else 'normalized_' + os.path.basename(
args.json_filename)
main(args.json_filename, output)