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;