Import Cobalt 24.lts.10.1032622
diff --git a/build/toolchain/win/msvc_toolchain.gni b/build/toolchain/win/msvc_toolchain.gni
index 92c98d4..01c3ebb 100644
--- a/build/toolchain/win/msvc_toolchain.gni
+++ b/build/toolchain/win/msvc_toolchain.gni
@@ -12,6 +12,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+assert(use_cobalt_customizations)
+
import("//build/toolchain/cc_wrapper.gni")
import("//build/toolchain/toolchain.gni")
@@ -19,15 +21,19 @@
template("msvc_toolchain") {
# Write the environment variables file in the out directory.
- required_environment_variables = ["SYSTEMROOT", "TEMP", "TMP"]
+ required_environment_variables = [
+ "SYSTEMROOT",
+ "TEMP",
+ "TMP",
+ ]
optional_environment_variables = [
"INCLUDE",
"LIB",
"PATH",
"PATHEXT",
- "XEDK", # TODO: What does this do?
- "IS_DOCKER", # needed for ninja to invoke docker-specific logic
- "IS_CI", # needed for ninja to exclude some logic on GKE
+ "XEDK", # TODO: What does this do?
+ "IS_DOCKER", # needed for ninja to invoke docker-specific logic
+ "IS_CI", # needed for ninja to exclude some logic on GKE
# The remaining variables should be explicitly enumerated.
# "cell_.*",
@@ -51,7 +57,11 @@
nul = "$0x00"
env_block = string_join(nul, environment_key_value_pairs) + nul
- write_file("$root_build_dir/environment.$target_cpu", env_block)
+
+ # If the default toolchain shares its name with another toolchain,
+ # there could be a deadlock where both toolchains try to write to the same environment file.
+ # See b/297227714 for more context.
+ write_file("$root_build_dir/$target_name/environment.$target_cpu", env_block)
toolchain(target_name) {
# When invoking this toolchain not as the default one, these args will be
@@ -70,8 +80,7 @@
# Object files go in this directory.
object_subdir = "{{target_out_dir}}/{{label_name}}"
- env = "environment.$target_cpu"
-
+ env = "$target_name/environment.$target_cpu"
cl = invoker.cl
lib = invoker.lib
link = invoker.link
@@ -119,7 +128,7 @@
tool("asm") {
description = "ASM {{output}}"
outputs = [ "$object_subdir/{{source_name_part}}.obj" ]
- command ="$env_wrapper$asm /nologo /Fo{{output}} /c {{defines}} {{include_dirs}} {{asmflags}} {{source}}"
+ command = "$env_wrapper$asm /nologo /Fo{{output}} /c {{defines}} {{include_dirs}} {{asmflags}} {{source}}"
}
sys_lib_flags = "${invoker.sys_lib_flags} " # Note trailing space.
@@ -163,9 +172,7 @@
]
link_output = libname
depend_output = libname
- runtime_outputs = [
- dllname,
- ]
+ runtime_outputs = [ dllname ]
# Since the above commands only updates the .lib file when it changes, ask
# Ninja to check if the timestamp actually changed to know if downstream
@@ -189,9 +196,7 @@
default_output_extension = ".dll"
default_output_dir = "{{root_out_dir}}"
description = "LINK_MODULE(DLL) {{output}}"
- outputs = [
- dllname,
- ]
+ outputs = [ dllname ]
runtime_outputs = outputs
# The use of inputs_newline is to work around a fixed per-line buffer
@@ -210,9 +215,7 @@
default_output_extension = ".exe"
default_output_dir = "{{root_out_dir}}"
description = "LINK {{output}}"
- outputs = [
- exename,
- ]
+ outputs = [ exename ]
runtime_outputs = outputs
# The use of inputs_newline is to work around a fixed per-line buffer
diff --git a/cobalt/version.h b/cobalt/version.h
index 517e7d5..bd8a169 100644
--- a/cobalt/version.h
+++ b/cobalt/version.h
@@ -35,6 +35,6 @@
// release is cut.
//.
-#define COBALT_VERSION "24.lts.5"
+#define COBALT_VERSION "24.lts.10"
#endif // COBALT_VERSION_H_
diff --git a/docker/docsite/Dockerfile b/docker/docsite/Dockerfile
index 2e164c8..6b1bd9d 100644
--- a/docker/docsite/Dockerfile
+++ b/docker/docsite/Dockerfile
@@ -46,10 +46,7 @@
RUN mkdir /project_out_dir \
&& chown ${USER:-defaultuser}:defaultgroup /project_out_dir
-<<<<<<< HEAD
RUN git config --global --add safe.directory /code
-=======
->>>>>>> 77f6a7c80d7 (Fix git config for /code in Linux containers (#611))
COPY Gemfile /app/Gemfile
# Note: This file was generated by running a working version of this Docker
diff --git a/starboard/android/apk/app/src/main/java/dev/cobalt/media/MediaCodecBridge.java b/starboard/android/apk/app/src/main/java/dev/cobalt/media/MediaCodecBridge.java
index 8b179c9..8db14f6 100644
--- a/starboard/android/apk/app/src/main/java/dev/cobalt/media/MediaCodecBridge.java
+++ b/starboard/android/apk/app/src/main/java/dev/cobalt/media/MediaCodecBridge.java
@@ -796,7 +796,7 @@
String codecName = mMediaCodec.getName();
Log.w(TAG, "calling MediaCodec.release() on " + codecName);
mMediaCodec.release();
- } catch (IllegalStateException e) {
+ } catch (Exception e) {
// The MediaCodec is stuck in a wrong state, possibly due to losing
// the surface.
Log.e(TAG, "Cannot release media codec", e);
@@ -875,7 +875,7 @@
}
try {
mMediaCodec.stop();
- } catch (IllegalStateException e) {
+ } catch (Exception e) {
Log.e(TAG, "Failed to stop MediaCodec", e);
}
}
diff --git a/starboard/android/apk/app/src/main/java/dev/cobalt/media/MediaDrmBridge.java b/starboard/android/apk/app/src/main/java/dev/cobalt/media/MediaDrmBridge.java
index ffcea69..d4a12a5 100644
--- a/starboard/android/apk/app/src/main/java/dev/cobalt/media/MediaDrmBridge.java
+++ b/starboard/android/apk/app/src/main/java/dev/cobalt/media/MediaDrmBridge.java
@@ -706,7 +706,6 @@
String.format("Successfully closed session (%s)", bytesToHexString(sessionId.array())));
}
mSessionIds.clear();
- mSessionIds = null;
// Close mMediaCryptoSession if it's open.
if (mMediaCryptoSession != null) {
diff --git a/starboard/android/shared/test_filters.py b/starboard/android/shared/test_filters.py
index 641ae2b..ae8fbb6 100644
--- a/starboard/android/shared/test_filters.py
+++ b/starboard/android/shared/test_filters.py
@@ -86,15 +86,9 @@
# TODO: Filter this test on a per-device basis.
'SbMediaCanPlayMimeAndKeySystem.MinimumSupport',
- # TODO: b/289281412 Make this test work on lab devices consistently.
- 'SbPlayerWriteSampleTests/SbPlayerWriteSampleTest.PartialAudio/*',
-
# TODO: b/292319097 Make this test work on lab devices consistently.
'SbPlayerTest.MaxVideoCapabilities',
- # TODO: b/292409536 Make this test fork on lab devices consistently.
- 'SbPlayerWriteSampleTests/SbPlayerWriteSampleTest.PartialAudioDiscardAll/*',
-
# TODO: b/280432564 Make this test work on lab devices consistently.
'SbAudioSinkTest.ContinuousAppend',
],
diff --git a/starboard/shared/starboard/player/filter/audio_frame_discarder.cc b/starboard/shared/starboard/player/filter/audio_frame_discarder.cc
index 7b8d192..b1ad4fb 100644
--- a/starboard/shared/starboard/player/filter/audio_frame_discarder.cc
+++ b/starboard/shared/starboard/player/filter/audio_frame_discarder.cc
@@ -23,13 +23,7 @@
namespace filter {
void AudioFrameDiscarder::OnInputBuffers(const InputBuffers& input_buffers) {
- if (input_buffer_infos_.size() >= kMaxNumberOfPendingInputBufferInfos) {
- // This shouldn't happen as it's DCHECKed at the end of this function. Add
- // an extra check here to ensure that |input_buffer_infos_| won't grow
- // without bound, which can lead to OOM in production.
- return;
- }
-
+ ScopedLock lock(mutex_);
for (auto&& input_buffer : input_buffers) {
SB_DCHECK(input_buffer);
SB_DCHECK(input_buffer->sample_type() == kSbMediaTypeAudio);
@@ -41,6 +35,8 @@
});
}
+ // Add a DCheck here to ensure that |input_buffer_infos_| won't grow
+ // without bound, which can lead to OOM.
SB_DCHECK(input_buffer_infos_.size() < kMaxNumberOfPendingInputBufferInfos);
}
@@ -49,32 +45,46 @@
scoped_refptr<DecodedAudio>* decoded_audio) {
SB_DCHECK(decoded_audio);
SB_DCHECK(*decoded_audio);
- // TODO: Comment out the SB_DCHECK due to b/274021285. We can re-enable it
- // after b/274021285 is resolved.
- // SB_DCHECK(!input_buffer_infos_.empty());
- if (input_buffer_infos_.empty()) {
- SB_LOG(WARNING) << "Inconsistent number of audio decoder outputs. Received "
- "outputs when input buffer list is empty.";
+ InputBufferInfo input_info;
+ {
+ ScopedLock lock(mutex_);
+ SB_DCHECK(!input_buffer_infos_.empty());
+
+ if (input_buffer_infos_.empty()) {
+ SB_LOG(WARNING)
+ << "Inconsistent number of audio decoder outputs. Received "
+ "outputs when input buffer list is empty.";
+ return;
+ }
+
+ input_info = input_buffer_infos_.front();
+ input_buffer_infos_.pop();
+ }
+
+ // We accept a small offset due to the precision of computation. If the
+ // outputs have different timestamps than inputs, discarded durations will be
+ // ignored.
+ const SbTimeMonotonic kTimestampOffset = 10;
+ if (std::abs(input_info.timestamp - (*decoded_audio)->timestamp()) >
+ kTimestampOffset) {
+ SB_LOG(WARNING) << "Inconsistent timestamps between InputBuffer (@"
+ << input_info.timestamp << ") and DecodedAudio (@"
+ << (*decoded_audio)->timestamp() << ").";
return;
}
- auto info = input_buffer_infos_.front();
- SB_LOG_IF(WARNING, info.timestamp != (*decoded_audio)->timestamp())
- << "Inconsistent timestamps between InputBuffer (@" << info.timestamp
- << ") and DecodedAudio (@" << (*decoded_audio)->timestamp() << ").";
- input_buffer_infos_.pop();
-
(*decoded_audio)
->AdjustForDiscardedDurations(sample_rate,
- info.discarded_duration_from_front,
- info.discarded_duration_from_back);
+ input_info.discarded_duration_from_front,
+ input_info.discarded_duration_from_back);
// `(*decoded_audio)->frames()` might be 0 here. We don't set it to nullptr
// in this case so the DecodedAudio instance is always valid (but might be
// empty).
}
void AudioFrameDiscarder::OnDecodedAudioEndOfStream() {
+ ScopedLock lock(mutex_);
// |input_buffer_infos_| can have extra elements when the decoder skip outputs
// due to errors (like invalid inputs).
SB_LOG_IF(INFO, !input_buffer_infos_.empty())
@@ -83,6 +93,7 @@
}
void AudioFrameDiscarder::Reset() {
+ ScopedLock lock(mutex_);
input_buffer_infos_ = std::queue<InputBufferInfo>();
}
diff --git a/starboard/shared/starboard/player/filter/audio_frame_discarder.h b/starboard/shared/starboard/player/filter/audio_frame_discarder.h
index a1f4f37..80f5fbe 100644
--- a/starboard/shared/starboard/player/filter/audio_frame_discarder.h
+++ b/starboard/shared/starboard/player/filter/audio_frame_discarder.h
@@ -17,6 +17,7 @@
#include <queue>
+#include "starboard/common/mutex.h"
#include "starboard/common/ref_counted.h"
#include "starboard/shared/internal_only.h"
#include "starboard/shared/starboard/player/decoded_audio_internal.h"
@@ -35,8 +36,6 @@
// corresponding InputBuffer object isn't available at the time.
// This class assumes that there is exact one DecodedAudio object produced for
// one InputBuffer object, which may not always be the case.
-// TODO(b/274021285): Ensure that the class works when there isn't a 1:1
-// relationship between DecodedAudio and InputBuffer.
class AudioFrameDiscarder {
public:
void OnInputBuffers(const InputBuffers& input_buffers);
@@ -55,6 +54,7 @@
static constexpr size_t kMaxNumberOfPendingInputBufferInfos = 128;
+ Mutex mutex_;
std::queue<InputBufferInfo> input_buffer_infos_;
};
diff --git a/starboard/shared/starboard/player/filter/testing/audio_decoder_test.cc b/starboard/shared/starboard/player/filter/testing/audio_decoder_test.cc
index b9500df..4b23321 100644
--- a/starboard/shared/starboard/player/filter/testing/audio_decoder_test.cc
+++ b/starboard/shared/starboard/player/filter/testing/audio_decoder_test.cc
@@ -185,6 +185,7 @@
last_input_buffer_ = GetAudioInputBuffer(index);
audio_decoder_->Decode({last_input_buffer_}, consumed_cb());
+ written_inputs_.push_back(last_input_buffer_);
}
void WriteSingleInput(size_t index,
@@ -200,6 +201,7 @@
last_input_buffer_ = GetAudioInputBuffer(
index, discarded_duration_from_front, discarded_duration_from_back);
audio_decoder_->Decode({last_input_buffer_}, consumed_cb());
+ written_inputs_.push_back(last_input_buffer_);
}
// This has to be called when OnOutput() is called.
@@ -228,6 +230,11 @@
ASSERT_LT(decoded_audios_.back()->timestamp(),
local_decoded_audio->timestamp());
}
+ if (!using_stub_decoder_ && invalid_inputs_.empty()) {
+ ASSERT_NEAR(local_decoded_audio->timestamp(),
+ written_inputs_.front()->timestamp(), 5);
+ written_inputs_.pop_front();
+ }
decoded_audios_.push_back(local_decoded_audio);
*decoded_audio = local_decoded_audio;
}
@@ -428,6 +435,7 @@
bool can_accept_more_input_ = true;
scoped_refptr<InputBuffer> last_input_buffer_;
+ std::deque<scoped_refptr<InputBuffer>> written_inputs_;
std::vector<scoped_refptr<DecodedAudio>> decoded_audios_;
bool eos_written_ = false;