Import Cobalt 21.master.0.270962

Includes the following patches:
  https://cobalt-review.googlesource.com/c/cobalt/+/5690
    by n1214.hwang@samsung.com
diff --git a/src/starboard/shared/ffmpeg/ffmpeg_audio_decoder_impl.cc b/src/starboard/shared/ffmpeg/ffmpeg_audio_decoder_impl.cc
index 3d8f090..f4b931d 100644
--- a/src/starboard/shared/ffmpeg/ffmpeg_audio_decoder_impl.cc
+++ b/src/starboard/shared/ffmpeg/ffmpeg_audio_decoder_impl.cc
@@ -18,9 +18,7 @@
 #include "starboard/shared/ffmpeg/ffmpeg_audio_decoder_impl.h"
 
 #include "starboard/audio_sink.h"
-#if SB_API_VERSION >= 11
-#include "starboard/format_string.h"
-#endif  // SB_API_VERSION >= 11
+#include "starboard/common/format_string.h"
 #include "starboard/common/log.h"
 #include "starboard/common/string.h"
 #include "starboard/memory.h"
diff --git a/src/starboard/shared/ffmpeg/ffmpeg_video_decoder_impl.cc b/src/starboard/shared/ffmpeg/ffmpeg_video_decoder_impl.cc
index 0509caa..9c1f321 100644
--- a/src/starboard/shared/ffmpeg/ffmpeg_video_decoder_impl.cc
+++ b/src/starboard/shared/ffmpeg/ffmpeg_video_decoder_impl.cc
@@ -17,9 +17,7 @@
 
 #include "starboard/shared/ffmpeg/ffmpeg_video_decoder_impl.h"
 
-#if SB_API_VERSION >= 11
-#include "starboard/format_string.h"
-#endif  // SB_API_VERSION >= 11
+#include "starboard/common/format_string.h"
 #include "starboard/common/string.h"
 #include "starboard/linux/shared/decode_target_internal.h"
 #include "starboard/memory.h"
diff --git a/src/starboard/shared/libaom/aom_video_decoder.cc b/src/starboard/shared/libaom/aom_video_decoder.cc
index 711ea24..23a63e6 100644
--- a/src/starboard/shared/libaom/aom_video_decoder.cc
+++ b/src/starboard/shared/libaom/aom_video_decoder.cc
@@ -14,9 +14,7 @@
 
 #include "starboard/shared/libaom/aom_video_decoder.h"
 
-#if SB_API_VERSION >= 11
-#include "starboard/format_string.h"
-#endif  // SB_API_VERSION >= 11
+#include "starboard/common/format_string.h"
 #include "starboard/common/log.h"
 #include "starboard/common/string.h"
 #include "starboard/linux/shared/decode_target_internal.h"
diff --git a/src/starboard/shared/libdav1d/dav1d_video_decoder.cc b/src/starboard/shared/libdav1d/dav1d_video_decoder.cc
index d063310..6aee08e 100644
--- a/src/starboard/shared/libdav1d/dav1d_video_decoder.cc
+++ b/src/starboard/shared/libdav1d/dav1d_video_decoder.cc
@@ -16,9 +16,7 @@
 
 #include <string>
 
-#if SB_API_VERSION >= 11
-#include "starboard/format_string.h"
-#endif  // SB_API_VERSION >= 11
+#include "starboard/common/format_string.h"
 #include "starboard/common/log.h"
 #include "starboard/common/string.h"
 #include "starboard/memory.h"
diff --git a/src/starboard/shared/libde265/de265_video_decoder.cc b/src/starboard/shared/libde265/de265_video_decoder.cc
index 931e5ab..87fefcb 100644
--- a/src/starboard/shared/libde265/de265_video_decoder.cc
+++ b/src/starboard/shared/libde265/de265_video_decoder.cc
@@ -14,9 +14,7 @@
 
 #include "starboard/shared/libde265/de265_video_decoder.h"
 
-#if SB_API_VERSION >= 11
-#include "starboard/format_string.h"
-#endif  // SB_API_VERSION >= 11
+#include "starboard/common/format_string.h"
 #include "starboard/linux/shared/decode_target_internal.h"
 #include "starboard/shared/libde265/de265_library_loader.h"
 #include "starboard/string.h"
diff --git a/src/starboard/shared/libvpx/vpx_video_decoder.cc b/src/starboard/shared/libvpx/vpx_video_decoder.cc
index 6bd1488..be2a918 100644
--- a/src/starboard/shared/libvpx/vpx_video_decoder.cc
+++ b/src/starboard/shared/libvpx/vpx_video_decoder.cc
@@ -14,9 +14,7 @@
 
 #include "starboard/shared/libvpx/vpx_video_decoder.h"
 
-#if SB_API_VERSION >= 11
-#include "starboard/format_string.h"
-#endif  // SB_API_VERSION >= 11
+#include "starboard/common/format_string.h"
 #include "starboard/common/string.h"
 #include "starboard/linux/shared/decode_target_internal.h"
 #include "starboard/shared/libvpx/vpx_library_loader.h"
diff --git a/src/starboard/shared/linux/cpu_features_get.cc b/src/starboard/shared/linux/cpu_features_get.cc
index 8659a64..fe460e2 100644
--- a/src/starboard/shared/linux/cpu_features_get.cc
+++ b/src/starboard/shared/linux/cpu_features_get.cc
@@ -24,8 +24,6 @@
 // On X86/X86_64, we read CPU version strings from /proc/cpuinfo. We get other
 // CPU version information and feature flags by CPUID instruction, which gives
 // more precise and complete information than reading from /proc/cpuinfo.
-//
-// TODO: Mips/Mips64 and Ppc/Ppc64
 
 #include "starboard/cpu_features.h"
 
diff --git a/src/starboard/shared/opus/opus_audio_decoder.cc b/src/starboard/shared/opus/opus_audio_decoder.cc
index 8555023..cf7b132 100644
--- a/src/starboard/shared/opus/opus_audio_decoder.cc
+++ b/src/starboard/shared/opus/opus_audio_decoder.cc
@@ -14,9 +14,7 @@
 
 #include "starboard/shared/opus/opus_audio_decoder.h"
 
-#if SB_API_VERSION >= 11
-#include "starboard/format_string.h"
-#endif  // SB_API_VERSION >= 11
+#include "starboard/common/format_string.h"
 #include "starboard/common/log.h"
 #include "starboard/common/string.h"
 #include "starboard/memory.h"
diff --git a/src/starboard/shared/pthread/thread_context_internal.cc b/src/starboard/shared/pthread/thread_context_internal.cc
index e17c5b5..2d40ca0 100644
--- a/src/starboard/shared/pthread/thread_context_internal.cc
+++ b/src/starboard/shared/pthread/thread_context_internal.cc
@@ -16,7 +16,7 @@
 
 #if SB_API_VERSION >= 11
 
-#if !defined(__gnu_linux__)  // Note: __linux__ is undef'd for Starboard builds.
+#if !defined(__linux__)
 #error "SbThreadContext is only implemented for Linux"
 #endif
 
diff --git a/src/starboard/shared/starboard/audio_sink/audio_sink_create.cc b/src/starboard/shared/starboard/audio_sink/audio_sink_create.cc
index dd9d555..e0f30f5 100644
--- a/src/starboard/shared/starboard/audio_sink/audio_sink_create.cc
+++ b/src/starboard/shared/starboard/audio_sink/audio_sink_create.cc
@@ -27,85 +27,12 @@
     SbAudioSinkUpdateSourceStatusFunc update_source_status_func,
     SbAudioSinkConsumeFramesFunc consume_frames_func,
     void* context) {
-  if (channels <= 0 || channels > SbAudioSinkGetMaxChannels()) {
-    SB_LOG(WARNING) << "Invalid audio channels " << channels;
-    return kSbAudioSinkInvalid;
-  }
-
-  if (sampling_frequency_hz <= 0) {
-    SB_LOG(WARNING) << "Invalid audio sampling frequency "
-                    << sampling_frequency_hz;
-    return kSbAudioSinkInvalid;
-  }
-
-  if (!SbAudioSinkIsAudioSampleTypeSupported(audio_sample_type)) {
-    SB_LOG(WARNING) << "Invalid audio sample type " << audio_sample_type;
-    return kSbAudioSinkInvalid;
-  }
-
-  if (!SbAudioSinkIsAudioFrameStorageTypeSupported(audio_frame_storage_type)) {
-    SB_LOG(WARNING) << "Invalid audio frame storage type "
-                    << audio_frame_storage_type;
-    return kSbAudioSinkInvalid;
-  }
-
-  if (frame_buffers == NULL) {
-    SB_LOG(WARNING) << "Pointer to frame buffers cannot be NULL";
-    return kSbAudioSinkInvalid;
-  }
-
-  if (frame_buffers_size_in_frames <= 0) {
-    SB_LOG(WARNING) << "Invalid frame buffer size "
-                    << frame_buffers_size_in_frames;
-    return kSbAudioSinkInvalid;
-  }
-
-  if (update_source_status_func == NULL) {
-    SB_LOG(WARNING) << "update_source_status_func cannot be NULL";
-    return kSbAudioSinkInvalid;
-  }
-
-  if (consume_frames_func == NULL) {
-    SB_LOG(WARNING) << "consume_frames_func cannot be NULL";
-    return kSbAudioSinkInvalid;
-  }
-
-  auto audio_sink_type = SbAudioSinkPrivate::GetPreferredType();
-  if (!audio_sink_type) {
-    SB_LOG(WARNING) << "Preferred Sink Type is invalid.";
-    return kSbAudioSinkInvalid;
-  }
-
-  SbAudioSink audio_sink = audio_sink_type->Create(
+  return SbAudioSinkPrivate::Create(
       channels, sampling_frequency_hz, audio_sample_type,
       audio_frame_storage_type, frame_buffers, frame_buffers_size_in_frames,
-      update_source_status_func,
-      SbAudioSinkPrivate::GetConsumeFramesFunc(consume_frames_func),
+      update_source_status_func, consume_frames_func,
 #if SB_API_VERSION >= 12
       NULL /*error_func*/,
 #endif  // SB_API_VERSION >= 12
       context);
-  if (audio_sink_type->IsValid(audio_sink)) {
-    return audio_sink;
-  }
-  audio_sink_type->Destroy(audio_sink);
-  auto fallback_audio_sink_type = SbAudioSinkPrivate::GetFallbackType();
-  if (!fallback_audio_sink_type) {
-    SB_LOG(WARNING) << "Fallback Sink Type is invalid.";
-    return kSbAudioSinkInvalid;
-  }
-  audio_sink = fallback_audio_sink_type->Create(
-      channels, sampling_frequency_hz, audio_sample_type,
-      audio_frame_storage_type, frame_buffers, frame_buffers_size_in_frames,
-      update_source_status_func,
-      SbAudioSinkPrivate::GetConsumeFramesFunc(consume_frames_func),
-#if SB_API_VERSION >= 12
-      NULL /*error_func*/,
-#endif  // SB_API_VERSION >= 12
-      context);
-  if (fallback_audio_sink_type->IsValid(audio_sink)) {
-    return audio_sink;
-  }
-  fallback_audio_sink_type->Destroy(audio_sink);
-  return kSbAudioSinkInvalid;
 }
diff --git a/src/starboard/shared/starboard/audio_sink/audio_sink_internal.cc b/src/starboard/shared/starboard/audio_sink/audio_sink_internal.cc
index a3f4f08..0d4ae83 100644
--- a/src/starboard/shared/starboard/audio_sink/audio_sink_internal.cc
+++ b/src/starboard/shared/starboard/audio_sink/audio_sink_internal.cc
@@ -16,6 +16,7 @@
 
 #include <functional>
 
+#include "starboard/common/log.h"
 #include "starboard/shared/starboard/application.h"
 #include "starboard/shared/starboard/audio_sink/stub_audio_sink_type.h"
 #include "starboard/shared/starboard/command_line.h"
@@ -107,9 +108,124 @@
   return audio_sink_type;
 }
 
+SbAudioSink SbAudioSinkPrivate::Create(
+    int channels,
+    int sampling_frequency_hz,
+    SbMediaAudioSampleType audio_sample_type,
+    SbMediaAudioFrameStorageType audio_frame_storage_type,
+    SbAudioSinkFrameBuffers frame_buffers,
+    int frame_buffers_size_in_frames,
+    SbAudioSinkUpdateSourceStatusFunc update_source_status_func,
+    ConsumeFramesFunc consume_frames_func,
+#if SB_API_VERSION >= 12
+    ErrorFunc error_func,
+#endif  // SB_API_VERSION >= 12
+    void* context) {
+  if (channels <= 0 || channels > SbAudioSinkGetMaxChannels()) {
+    SB_LOG(WARNING) << "Invalid audio channels " << channels;
+    return kSbAudioSinkInvalid;
+  }
+
+  if (sampling_frequency_hz <= 0) {
+    SB_LOG(WARNING) << "Invalid audio sampling frequency "
+                    << sampling_frequency_hz;
+    return kSbAudioSinkInvalid;
+  }
+
+  if (!SbAudioSinkIsAudioSampleTypeSupported(audio_sample_type)) {
+    SB_LOG(WARNING) << "Invalid audio sample type " << audio_sample_type;
+    return kSbAudioSinkInvalid;
+  }
+
+  if (!SbAudioSinkIsAudioFrameStorageTypeSupported(audio_frame_storage_type)) {
+    SB_LOG(WARNING) << "Invalid audio frame storage type "
+                    << audio_frame_storage_type;
+    return kSbAudioSinkInvalid;
+  }
+
+  if (frame_buffers == NULL) {
+    SB_LOG(WARNING) << "Pointer to frame buffers cannot be NULL";
+    return kSbAudioSinkInvalid;
+  }
+
+  if (frame_buffers_size_in_frames <= 0) {
+    SB_LOG(WARNING) << "Invalid frame buffer size "
+                    << frame_buffers_size_in_frames;
+    return kSbAudioSinkInvalid;
+  }
+
+  if (update_source_status_func == NULL) {
+    SB_LOG(WARNING) << "update_source_status_func cannot be NULL";
+    return kSbAudioSinkInvalid;
+  }
+
+  if (!consume_frames_func) {
+    SB_LOG(WARNING) << "consume_frames_func cannot be NULL";
+    return kSbAudioSinkInvalid;
+  }
+
+  if (auto audio_sink_type = GetPreferredType()) {
+    auto audio_sink = audio_sink_type->Create(
+        channels, sampling_frequency_hz, audio_sample_type,
+        audio_frame_storage_type, frame_buffers, frame_buffers_size_in_frames,
+        update_source_status_func, consume_frames_func,
+#if SB_API_VERSION >= 12
+        error_func,
+#endif  // SB_API_VERSION >= 12
+        context);
+    if (audio_sink_type->IsValid(audio_sink)) {
+      return audio_sink;
+    }
+    SB_LOG(ERROR) << "Failed to create SbAudioSink from preferred type.";
+    audio_sink_type->Destroy(audio_sink);
+  } else {
+    SB_LOG(WARNING) << "Preferred Sink Type is invalid.";
+  }
+
+  SB_LOG(WARNING) << "Try to create AudioSink using fallback type.";
+  if (auto fallback_type = SbAudioSinkPrivate::GetFallbackType()) {
+    auto audio_sink = fallback_type->Create(
+        channels, sampling_frequency_hz, audio_sample_type,
+        audio_frame_storage_type, frame_buffers, frame_buffers_size_in_frames,
+        update_source_status_func, consume_frames_func,
+#if SB_API_VERSION >= 12
+        error_func,
+#endif  // SB_API_VERSION >= 12
+        context);
+    if (fallback_type->IsValid(audio_sink)) {
+      return audio_sink;
+    }
+    SB_LOG(ERROR) << "Failed to create SbAudioSink from Fallback type.";
+    fallback_type->Destroy(audio_sink);
+  } else {
+    SB_LOG(WARNING) << "Fallback Sink Type is invalid.";
+  }
+  return kSbAudioSinkInvalid;
+}
+
 // static
-SbAudioSinkPrivate::ConsumeFramesFunc SbAudioSinkPrivate::GetConsumeFramesFunc(
-    SbAudioSinkConsumeFramesFunc sb_consume_frames_func) {
-  return std::bind(&::WrapConsumeFramesFunc, sb_consume_frames_func, _1, _2,
-                   _3);
+SbAudioSink SbAudioSinkPrivate::Create(
+    int channels,
+    int sampling_frequency_hz,
+    SbMediaAudioSampleType audio_sample_type,
+    SbMediaAudioFrameStorageType audio_frame_storage_type,
+    SbAudioSinkFrameBuffers frame_buffers,
+    int frame_buffers_size_in_frames,
+    SbAudioSinkUpdateSourceStatusFunc update_source_status_func,
+    SbAudioSinkConsumeFramesFunc sb_consume_frames_func,
+#if SB_API_VERSION >= 12
+    ErrorFunc error_func,
+#endif  // SB_API_VERSION >= 12
+    void* context) {
+  return Create(channels, sampling_frequency_hz, audio_sample_type,
+                audio_frame_storage_type, frame_buffers,
+                frame_buffers_size_in_frames, update_source_status_func,
+                sb_consume_frames_func
+                    ? std::bind(&::WrapConsumeFramesFunc,
+                                sb_consume_frames_func, _1, _2, _3)
+                    : ConsumeFramesFunc(),
+#if SB_API_VERSION >= 12
+                error_func,
+#endif  // SB_API_VERSION >= 12
+                context);
 }
diff --git a/src/starboard/shared/starboard/audio_sink/audio_sink_internal.h b/src/starboard/shared/starboard/audio_sink/audio_sink_internal.h
index 322ea45..bffc40a 100644
--- a/src/starboard/shared/starboard/audio_sink/audio_sink_internal.h
+++ b/src/starboard/shared/starboard/audio_sink/audio_sink_internal.h
@@ -83,13 +83,38 @@
   // Fallback. If Fallback is not enabled, then returns NULL.
   static Type* GetPreferredType();
 
+  static SbAudioSink Create(
+      int channels,
+      int sampling_frequency_hz,
+      SbMediaAudioSampleType audio_sample_type,
+      SbMediaAudioFrameStorageType audio_frame_storage_type,
+      SbAudioSinkFrameBuffers frame_buffers,
+      int frame_buffers_size_in_frames,
+      SbAudioSinkUpdateSourceStatusFunc update_source_status_func,
+      ConsumeFramesFunc consume_frames_func,
+#if SB_API_VERSION >= 12
+      ErrorFunc error_func,
+#endif  // SB_API_VERSION >= 12
+      void* context);
+
+  static SbAudioSink Create(
+      int channels,
+      int sampling_frequency_hz,
+      SbMediaAudioSampleType audio_sample_type,
+      SbMediaAudioFrameStorageType audio_frame_storage_type,
+      SbAudioSinkFrameBuffers frame_buffers,
+      int frame_buffers_size_in_frames,
+      SbAudioSinkUpdateSourceStatusFunc update_source_status_func,
+      SbAudioSinkConsumeFramesFunc sb_consume_frames_func,
+#if SB_API_VERSION >= 12
+      ErrorFunc error_func,
+#endif  // SB_API_VERSION >= 12
+      void* context);
+
   // Individual implementation has to provide implementation of the following
   // functions, which will be called inside Initialize() and TearDown().
   static void PlatformInitialize();
   static void PlatformTearDown();
-
-  static ConsumeFramesFunc GetConsumeFramesFunc(
-      SbAudioSinkConsumeFramesFunc sb_consume_frames_func);
 };
 
 #endif  // STARBOARD_SHARED_STARBOARD_AUDIO_SINK_AUDIO_SINK_INTERNAL_H_
diff --git a/src/starboard/shared/starboard/media/video_capabilities.cc b/src/starboard/shared/starboard/media/video_capabilities.cc
index 78d8fd8..1b6ba44 100644
--- a/src/starboard/shared/starboard/media/video_capabilities.cc
+++ b/src/starboard/shared/starboard/media/video_capabilities.cc
@@ -14,8 +14,8 @@
 
 #include "starboard/shared/starboard/media/video_capabilities.h"
 
+#include "starboard/common/format_string.h"
 #include "starboard/common/log.h"
-#include "starboard/format_string.h"
 #include "starboard/shared/starboard/media/media_util.h"
 
 namespace starboard {
diff --git a/src/starboard/shared/starboard/player/filter/audio_renderer_internal_impl.cc b/src/starboard/shared/starboard/player/filter/audio_renderer_internal_impl.cc
index 7615d4d..90b7748 100644
--- a/src/starboard/shared/starboard/player/filter/audio_renderer_internal_impl.cc
+++ b/src/starboard/shared/starboard/player/filter/audio_renderer_internal_impl.cc
@@ -521,7 +521,7 @@
 
   // TODO: Support planar only audio sink.
   audio_renderer_sink_->Start(
-      channels_, destination_sample_rate, sink_sample_type_,
+      seeking_to_time_, channels_, destination_sample_rate, sink_sample_type_,
       kSbMediaAudioFrameStorageTypeInterleaved,
       reinterpret_cast<SbAudioSinkFrameBuffers>(frame_buffers_),
       max_cached_frames_, this);
diff --git a/src/starboard/shared/starboard/player/filter/audio_renderer_sink.h b/src/starboard/shared/starboard/player/filter/audio_renderer_sink.h
index 2d98c3e..7142d0a 100644
--- a/src/starboard/shared/starboard/player/filter/audio_renderer_sink.h
+++ b/src/starboard/shared/starboard/player/filter/audio_renderer_sink.h
@@ -56,7 +56,8 @@
       int sampling_frequency_hz) const = 0;
 
   virtual bool HasStarted() const = 0;
-  virtual void Start(int channels,
+  virtual void Start(SbTime media_start_time,
+                     int channels,
                      int sampling_frequency_hz,
                      SbMediaAudioSampleType audio_sample_type,
                      SbMediaAudioFrameStorageType audio_frame_storage_type,
diff --git a/src/starboard/shared/starboard/player/filter/audio_renderer_sink_impl.cc b/src/starboard/shared/starboard/player/filter/audio_renderer_sink_impl.cc
index 270f8a5..61a48db 100644
--- a/src/starboard/shared/starboard/player/filter/audio_renderer_sink_impl.cc
+++ b/src/starboard/shared/starboard/player/filter/audio_renderer_sink_impl.cc
@@ -14,7 +14,6 @@
 
 #include "starboard/shared/starboard/player/filter/audio_renderer_sink_impl.h"
 
-#include "starboard/audio_sink.h"
 #include "starboard/common/log.h"
 #include "starboard/configuration_constants.h"
 #include "starboard/shared/starboard/thread_checker.h"
@@ -26,10 +25,37 @@
 namespace filter {
 
 AudioRendererSinkImpl::AudioRendererSinkImpl()
-    : audio_sink_(kSbAudioSinkInvalid),
-      render_callback_(NULL),
-      playback_rate_(1.0),
-      volume_(1.0) {}
+    : create_audio_sink_func_(
+          [](SbTime start_media_time,
+             int channels,
+             int sampling_frequency_hz,
+             SbMediaAudioSampleType audio_sample_type,
+             SbMediaAudioFrameStorageType audio_frame_storage_type,
+             SbAudioSinkFrameBuffers frame_buffers,
+             int frame_buffers_size_in_frames,
+             SbAudioSinkUpdateSourceStatusFunc update_source_status_func,
+             SbAudioSinkPrivate::ConsumeFramesFunc consume_frames_func,
+#if SB_API_VERSION >= 12
+             SbAudioSinkPrivate::ErrorFunc error_func,
+#endif  // SB_API_VERSION >= 12
+             void* context) {
+            return SbAudioSinkPrivate::Create(
+                channels, sampling_frequency_hz, audio_sample_type,
+                audio_frame_storage_type, frame_buffers,
+                frame_buffers_size_in_frames, update_source_status_func,
+                consume_frames_func,
+#if SB_API_VERSION >= 12
+                error_func,
+#endif  // SB_API_VERSION >= 12
+                context);
+          }) {
+}
+
+AudioRendererSinkImpl::AudioRendererSinkImpl(
+    CreateAudioSinkFunc create_audio_sink_func)
+    : create_audio_sink_func_(create_audio_sink_func) {
+  SB_DCHECK(create_audio_sink_func_);
+}
 
 AudioRendererSinkImpl::~AudioRendererSinkImpl() {
   SB_DCHECK(thread_checker_.CalledOnValidThread());
@@ -57,6 +83,7 @@
 }
 
 void AudioRendererSinkImpl::Start(
+    SbTime media_start_time,
     int channels,
     int sampling_frequency_hz,
     SbMediaAudioSampleType audio_sample_type,
@@ -76,44 +103,15 @@
 
   Stop();
   render_callback_ = render_callback;
-  audio_sink_ = kSbAudioSinkInvalid;
-  SbAudioSinkPrivate::Type* audio_sink_type =
-      SbAudioSinkPrivate::GetPreferredType();
-  if (audio_sink_type) {
-    audio_sink_ = audio_sink_type->Create(
-        channels, sampling_frequency_hz, audio_sample_type,
-        audio_frame_storage_type, frame_buffers, frames_per_channel,
-        &AudioRendererSinkImpl::UpdateSourceStatusFunc,
-        &AudioRendererSinkImpl::ConsumeFramesFunc,
+  audio_sink_ = create_audio_sink_func_(
+      media_start_time, channels, sampling_frequency_hz, audio_sample_type,
+      audio_frame_storage_type, frame_buffers, frames_per_channel,
+      &AudioRendererSinkImpl::UpdateSourceStatusFunc,
+      &AudioRendererSinkImpl::ConsumeFramesFunc,
 #if SB_API_VERSION >= 12
-        &AudioRendererSinkImpl::ErrorFunc,
+      &AudioRendererSinkImpl::ErrorFunc,
 #endif  // SB_API_VERSION >= 12
-        this);
-    if (!audio_sink_type->IsValid(audio_sink_)) {
-      SB_LOG(WARNING) << "Created invalid SbAudioSink from "
-                         "SbAudioSinkPrivate::Type. Destroying and "
-                         "resetting.";
-      audio_sink_type->Destroy(audio_sink_);
-      audio_sink_ = kSbAudioSinkInvalid;
-      auto fallback_type = SbAudioSinkPrivate::GetFallbackType();
-      if (fallback_type) {
-        audio_sink_ = fallback_type->Create(
-            channels, sampling_frequency_hz, audio_sample_type,
-            audio_frame_storage_type, frame_buffers, frames_per_channel,
-            &AudioRendererSinkImpl::UpdateSourceStatusFunc,
-            &AudioRendererSinkImpl::ConsumeFramesFunc,
-#if SB_API_VERSION >= 12
-            &AudioRendererSinkImpl::ErrorFunc,
-#endif  // SB_API_VERSION >= 12
-            this);
-        if (!fallback_type->IsValid(audio_sink_)) {
-          SB_LOG(ERROR) << "Failed to create SbAudioSink from Fallback type.";
-          fallback_type->Destroy(audio_sink_);
-          audio_sink_ = kSbAudioSinkInvalid;
-        }
-      }
-    }
-  }
+      this);
   if (!SbAudioSinkIsValid(audio_sink_)) {
     return;
   }
diff --git a/src/starboard/shared/starboard/player/filter/audio_renderer_sink_impl.h b/src/starboard/shared/starboard/player/filter/audio_renderer_sink_impl.h
index 12fa6a6..239180f 100644
--- a/src/starboard/shared/starboard/player/filter/audio_renderer_sink_impl.h
+++ b/src/starboard/shared/starboard/player/filter/audio_renderer_sink_impl.h
@@ -15,6 +15,9 @@
 #ifndef STARBOARD_SHARED_STARBOARD_PLAYER_FILTER_AUDIO_RENDERER_SINK_IMPL_H_
 #define STARBOARD_SHARED_STARBOARD_PLAYER_FILTER_AUDIO_RENDERER_SINK_IMPL_H_
 
+#include <functional>
+
+#include "starboard/audio_sink.h"
 #include "starboard/shared/internal_only.h"
 #include "starboard/shared/starboard/audio_sink/audio_sink_internal.h"
 #include "starboard/shared/starboard/player/filter/audio_renderer_sink.h"
@@ -28,7 +31,24 @@
 
 class AudioRendererSinkImpl : public AudioRendererSink {
  public:
+  typedef std::function<SbAudioSink(
+      SbTime media_start_time,
+      int channels,
+      int sampling_frequency_hz,
+      SbMediaAudioSampleType audio_sample_type,
+      SbMediaAudioFrameStorageType audio_frame_storage_type,
+      SbAudioSinkFrameBuffers frame_buffers,
+      int frame_buffers_size_in_frames,
+      SbAudioSinkUpdateSourceStatusFunc update_source_status_func,
+      SbAudioSinkPrivate::ConsumeFramesFunc consume_frames_func,
+#if SB_API_VERSION >= 12
+      SbAudioSinkPrivate::ErrorFunc error_func,
+#endif  // SB_API_VERSION >= 12
+      void* context)>
+      CreateAudioSinkFunc;
+
   AudioRendererSinkImpl();
+  explicit AudioRendererSinkImpl(CreateAudioSinkFunc create_audio_sink_func);
   ~AudioRendererSinkImpl() override;
 
  private:
@@ -41,7 +61,8 @@
       override;
 
   bool HasStarted() const override;
-  void Start(int channels,
+  void Start(SbTime media_start_time,
+             int channels,
              int sampling_frequency_hz,
              SbMediaAudioSampleType audio_sample_type,
              SbMediaAudioFrameStorageType audio_frame_storage_type,
@@ -65,10 +86,12 @@
   static void ErrorFunc(bool capability_changed, void* context);
 
   ThreadChecker thread_checker_;
-  SbAudioSinkPrivate* audio_sink_;
-  RenderCallback* render_callback_;
-  double playback_rate_;
-  double volume_;
+  const CreateAudioSinkFunc create_audio_sink_func_;
+
+  SbAudioSinkPrivate* audio_sink_ = kSbAudioSinkInvalid;
+  RenderCallback* render_callback_ = NULL;
+  double playback_rate_ = 1.0;
+  double volume_ = 1.0;
 };
 
 }  // namespace filter
diff --git a/src/starboard/shared/starboard/player/filter/filter_based_player_worker_handler.cc b/src/starboard/shared/starboard/player/filter/filter_based_player_worker_handler.cc
index c8efd9b..196d422 100644
--- a/src/starboard/shared/starboard/player/filter/filter_based_player_worker_handler.cc
+++ b/src/starboard/shared/starboard/player/filter/filter_based_player_worker_handler.cc
@@ -15,9 +15,9 @@
 #include "starboard/shared/starboard/player/filter/filter_based_player_worker_handler.h"
 
 #include "starboard/audio_sink.h"
+#include "starboard/common/format_string.h"
 #include "starboard/common/log.h"
 #include "starboard/common/murmurhash2.h"
-#include "starboard/format_string.h"
 #include "starboard/memory.h"
 #include "starboard/shared/starboard/application.h"
 #include "starboard/shared/starboard/drm/drm_system_internal.h"
diff --git a/src/starboard/shared/starboard/player/filter/mock_audio_renderer_sink.h b/src/starboard/shared/starboard/player/filter/mock_audio_renderer_sink.h
index 9835a65..f56e21f 100644
--- a/src/starboard/shared/starboard/player/filter/mock_audio_renderer_sink.h
+++ b/src/starboard/shared/starboard/player/filter/mock_audio_renderer_sink.h
@@ -37,8 +37,9 @@
   MOCK_CONST_METHOD1(GetNearestSupportedSampleFrequency,
                      int(int sampling_frequency_hz));
   MOCK_CONST_METHOD0(HasStarted, bool());
-  MOCK_METHOD7(Start,
-               void(int channels,
+  MOCK_METHOD8(Start,
+               void(SbTime media_start_time,
+                    int channels,
                     int sampling_frequency_hz,
                     SbMediaAudioSampleType audio_sample_type,
                     SbMediaAudioFrameStorageType audio_frame_storage_type,
diff --git a/src/starboard/shared/starboard/player/filter/testing/audio_renderer_internal_test.cc b/src/starboard/shared/starboard/player/filter/testing/audio_renderer_internal_test.cc
index d5e9f2e..7fbff6c 100644
--- a/src/starboard/shared/starboard/player/filter/testing/audio_renderer_internal_test.cc
+++ b/src/starboard/shared/starboard/player/filter/testing/audio_renderer_internal_test.cc
@@ -77,11 +77,11 @@
         .WillByDefault(
             DoAll(SetArgPointee<0>(kDefaultSamplesPerSecond),
                   Return(scoped_refptr<DecodedAudio>(new DecodedAudio()))));
-    ON_CALL(*audio_renderer_sink_, Start(_, _, _, _, _, _, _))
+    ON_CALL(*audio_renderer_sink_, Start(_, _, _, _, _, _, _, _))
         .WillByDefault(DoAll(InvokeWithoutArgs([this]() {
                                audio_renderer_sink_->SetHasStarted(true);
                              }),
-                             SaveArg<6>(&renderer_callback_)));
+                             SaveArg<7>(&renderer_callback_)));
     ON_CALL(*audio_renderer_sink_, Stop())
         .WillByDefault(InvokeWithoutArgs([this]() {
           audio_renderer_sink_->SetHasStarted(false);
@@ -324,7 +324,7 @@
     EXPECT_CALL(*audio_renderer_sink_, Stop()).Times(AnyNumber());
     EXPECT_CALL(
         *audio_renderer_sink_,
-        Start(kDefaultNumberOfChannels, kDefaultSamplesPerSecond,
+        Start(0, kDefaultNumberOfChannels, kDefaultSamplesPerSecond,
               kDefaultAudioSampleType, kDefaultAudioFrameStorageType, _, _, _));
   }
 
@@ -406,7 +406,7 @@
     EXPECT_CALL(*audio_renderer_sink_, Stop()).Times(AnyNumber());
     EXPECT_CALL(
         *audio_renderer_sink_,
-        Start(kDefaultNumberOfChannels, kDefaultSamplesPerSecond,
+        Start(0, kDefaultNumberOfChannels, kDefaultSamplesPerSecond,
               kDefaultAudioSampleType, kDefaultAudioFrameStorageType, _, _, _));
   }
 
@@ -481,7 +481,7 @@
     EXPECT_CALL(*audio_renderer_sink_, Stop()).Times(AnyNumber());
     EXPECT_CALL(
         *audio_renderer_sink_,
-        Start(kDefaultNumberOfChannels, kDefaultSamplesPerSecond,
+        Start(0, kDefaultNumberOfChannels, kDefaultSamplesPerSecond,
               kDefaultAudioSampleType, kDefaultAudioFrameStorageType, _, _, _));
   }
 
@@ -546,7 +546,7 @@
     EXPECT_CALL(*audio_renderer_sink_, Stop()).Times(AnyNumber());
     EXPECT_CALL(
         *audio_renderer_sink_,
-        Start(kDefaultNumberOfChannels, kDefaultSamplesPerSecond,
+        Start(0, kDefaultNumberOfChannels, kDefaultSamplesPerSecond,
               kDefaultAudioSampleType, kDefaultAudioFrameStorageType, _, _, _));
   }
 
@@ -588,7 +588,7 @@
     EXPECT_CALL(*audio_renderer_sink_, Stop()).Times(AnyNumber());
     EXPECT_CALL(
         *audio_renderer_sink_,
-        Start(kDefaultNumberOfChannels, kDefaultSamplesPerSecond,
+        Start(0, kDefaultNumberOfChannels, kDefaultSamplesPerSecond,
               kDefaultAudioSampleType, kDefaultAudioFrameStorageType, _, _, _));
   }
 
@@ -636,7 +636,7 @@
     EXPECT_CALL(*audio_renderer_sink_, Stop()).Times(AnyNumber());
     EXPECT_CALL(
         *audio_renderer_sink_,
-        Start(kDefaultNumberOfChannels, kDefaultSamplesPerSecond,
+        Start(0, kDefaultNumberOfChannels, kDefaultSamplesPerSecond,
               kDefaultAudioSampleType, kDefaultAudioFrameStorageType, _, _, _));
   }
 
@@ -727,9 +727,9 @@
         .WillRepeatedly(Return(false));
     EXPECT_CALL(
         *audio_renderer_sink_,
-        Start(kDefaultNumberOfChannels, kDefaultSamplesPerSecond,
+        Start(0, kDefaultNumberOfChannels, kDefaultSamplesPerSecond,
               kDefaultAudioSampleType, kDefaultAudioFrameStorageType, _, _, _))
-        .WillOnce(SaveArg<6>(&renderer_callback_));
+        .WillOnce(SaveArg<7>(&renderer_callback_));
     EXPECT_CALL(*audio_renderer_sink_, HasStarted())
         .WillRepeatedly(Return(true));
   }
@@ -809,18 +809,20 @@
     return;
   }
 
+  const double kSeekTime = 0.5 * kSbTimeSecond;
+
   {
     ::testing::InSequence seq;
     EXPECT_CALL(*audio_renderer_sink_, Stop()).Times(AnyNumber());
     EXPECT_CALL(
         *audio_renderer_sink_,
-        Start(kDefaultNumberOfChannels, kDefaultSamplesPerSecond,
+        Start(0, kDefaultNumberOfChannels, kDefaultSamplesPerSecond,
               kDefaultAudioSampleType, kDefaultAudioFrameStorageType, _, _, _));
     EXPECT_CALL(*audio_renderer_sink_, Stop());
     EXPECT_CALL(*audio_decoder_, Reset());
     EXPECT_CALL(
         *audio_renderer_sink_,
-        Start(kDefaultNumberOfChannels, kDefaultSamplesPerSecond,
+        Start(kSeekTime, kDefaultNumberOfChannels, kDefaultSamplesPerSecond,
               kDefaultAudioSampleType, kDefaultAudioFrameStorageType, _, _, _));
   }
 
@@ -855,7 +857,6 @@
 
   // Consume frames in multiple batches, so we can test if
   // |GetCurrentMediaTime()| is incrementing in an expected manner.
-  const double seek_time = 0.5 * kSbTimeSecond;
   const int frames_to_consume = std::min(frames_written, frames_in_buffer) / 10;
   SbTime new_media_time;
 
@@ -865,13 +866,13 @@
   new_media_time = audio_renderer_->GetCurrentMediaTime(
       &is_playing, &is_eos_played, &is_underflow);
   EXPECT_GE(new_media_time, media_time);
-  Seek(seek_time);
+  Seek(kSeekTime);
 
-  frames_written += FillRendererWithDecodedAudioAndWriteEOS(seek_time);
+  frames_written += FillRendererWithDecodedAudioAndWriteEOS(kSeekTime);
 
   EXPECT_GE(audio_renderer_->GetCurrentMediaTime(&is_playing, &is_eos_played,
                                                  &is_underflow),
-            seek_time);
+            kSeekTime);
   EXPECT_TRUE(prerolled_);
 
   audio_renderer_->Play();
@@ -886,7 +887,7 @@
   renderer_callback_->ConsumeFrames(frames_in_buffer, SbTimeGetMonotonicNow());
   new_media_time = audio_renderer_->GetCurrentMediaTime(
       &is_playing, &is_eos_played, &is_underflow);
-  EXPECT_GE(new_media_time, seek_time);
+  EXPECT_GE(new_media_time, kSeekTime);
 
   EXPECT_TRUE(audio_renderer_->IsEndOfStreamPlayed());
 }
diff --git a/src/starboard/shared/starboard/player/filter/video_render_algorithm.h b/src/starboard/shared/starboard/player/filter/video_render_algorithm.h
index 5fd0c0e..94cac79 100644
--- a/src/starboard/shared/starboard/player/filter/video_render_algorithm.h
+++ b/src/starboard/shared/starboard/player/filter/video_render_algorithm.h
@@ -50,7 +50,8 @@
                       std::list<scoped_refptr<VideoFrame>>* frames,
                       VideoRendererSink::DrawFrameCB draw_frame_cb) = 0;
   // Called during seek to reset the internal states of VideoRenderAlgorithm.
-  virtual void Reset() = 0;
+  // |seek_to_time| will be set to the seek target.
+  virtual void Seek(SbTime seek_to_time) = 0;
   virtual int GetDroppedFrames() = 0;
 };
 
diff --git a/src/starboard/shared/starboard/player/filter/video_render_algorithm_impl.cc b/src/starboard/shared/starboard/player/filter/video_render_algorithm_impl.cc
index 78b6486..fb62882 100644
--- a/src/starboard/shared/starboard/player/filter/video_render_algorithm_impl.cc
+++ b/src/starboard/shared/starboard/player/filter/video_render_algorithm_impl.cc
@@ -134,7 +134,7 @@
 #endif  // SB_PLAYER_FILTER_ENABLE_STATE_CHECK
 }
 
-void VideoRenderAlgorithmImpl::Reset() {
+void VideoRenderAlgorithmImpl::Seek(SbTime seek_to_time) {
   if (get_refresh_rate_fn_) {
     last_frame_timestamp_ = -1;
     current_frame_rendered_times_ = -1;
diff --git a/src/starboard/shared/starboard/player/filter/video_render_algorithm_impl.h b/src/starboard/shared/starboard/player/filter/video_render_algorithm_impl.h
index 97e9980..ff8d474 100644
--- a/src/starboard/shared/starboard/player/filter/video_render_algorithm_impl.h
+++ b/src/starboard/shared/starboard/player/filter/video_render_algorithm_impl.h
@@ -46,7 +46,7 @@
   void Render(MediaTimeProvider* media_time_provider,
               std::list<scoped_refptr<VideoFrame>>* frames,
               VideoRendererSink::DrawFrameCB draw_frame_cb) override;
-  void Reset() override;
+  void Seek(SbTime seek_to_time) override;
   int GetDroppedFrames() override { return dropped_frames_; }
 
  private:
diff --git a/src/starboard/shared/starboard/player/filter/video_renderer_internal_impl.cc b/src/starboard/shared/starboard/player/filter/video_renderer_internal_impl.cc
index 6573840..c8a2a3a 100644
--- a/src/starboard/shared/starboard/player/filter/video_renderer_internal_impl.cc
+++ b/src/starboard/shared/starboard/player/filter/video_renderer_internal_impl.cc
@@ -182,7 +182,8 @@
   buffering_state_ = kWaitForBuffer;
 #endif  // SB_PLAYER_FILTER_ENABLE_STATE_CHECK
 
-  algorithm_->Reset();  // This is also guarded by sink_frames_mutex_.
+  // This is also guarded by |sink_frames_mutex_|.
+  algorithm_->Seek(seek_to_time);
 }
 
 bool VideoRendererImpl::CanAcceptMoreData() const {