Import Cobalt 6.14838

Change-Id: I49864fe26f7f6fca3777d185823aa31251e8ae57
diff --git a/src/starboard/shared/dlmalloc/memory_map.cc b/src/starboard/shared/dlmalloc/memory_map.cc
index 59730fc..c5d3829 100644
--- a/src/starboard/shared/dlmalloc/memory_map.cc
+++ b/src/starboard/shared/dlmalloc/memory_map.cc
@@ -13,9 +13,11 @@
 // limitations under the License.
 
 #include "starboard/memory.h"
-
+#include "starboard/shared/starboard/memory_reporter_internal.h"
 #include "starboard/shared/dlmalloc/page_internal.h"
 
 void* SbMemoryMap(int64_t size_bytes, int flags, const char* name) {
-  return SbPageMap(size_bytes, flags, name);
+  void* memory = SbPageMap(size_bytes, flags, name);
+  SbMemoryReporterReportMappedMemory(memory, size_bytes);
+  return memory;
 }
diff --git a/src/starboard/shared/dlmalloc/memory_unmap.cc b/src/starboard/shared/dlmalloc/memory_unmap.cc
index ff45918..dc32164 100644
--- a/src/starboard/shared/dlmalloc/memory_unmap.cc
+++ b/src/starboard/shared/dlmalloc/memory_unmap.cc
@@ -13,9 +13,10 @@
 // limitations under the License.
 
 #include "starboard/memory.h"
-
+#include "starboard/shared/starboard/memory_reporter_internal.h"
 #include "starboard/shared/dlmalloc/page_internal.h"
 
 bool SbMemoryUnmap(void* virtual_address, int64_t size_bytes) {
+  SbMemoryReporterReportUnmappedMemory(virtual_address, size_bytes);
   return SbPageUnmap(virtual_address, size_bytes);
 }
diff --git a/src/starboard/shared/ffmpeg/ffmpeg_audio_decoder.cc b/src/starboard/shared/ffmpeg/ffmpeg_audio_decoder.cc
index 618b9e3..1444180 100644
--- a/src/starboard/shared/ffmpeg/ffmpeg_audio_decoder.cc
+++ b/src/starboard/shared/ffmpeg/ffmpeg_audio_decoder.cc
@@ -14,6 +14,7 @@
 
 #include "starboard/shared/ffmpeg/ffmpeg_audio_decoder.h"
 
+#include "starboard/audio_sink.h"
 #include "starboard/log.h"
 
 namespace starboard {
@@ -22,15 +23,23 @@
 
 namespace {
 
-// The required output format for the decoder is interleaved float.  However
-// the output of the ffmpeg decoder can be in other formats.  So libavresample
-// is used to convert the output into the required format.
-void ConvertToInterleavedFloat(int source_sample_format,
-                               int channel_layout,
-                               int sample_rate,
-                               int samples_per_channel,
-                               uint8_t** input_buffer,
-                               uint8_t* output_buffer) {
+SbMediaAudioSampleType GetSupportedSampleType() {
+  if (SbAudioSinkIsAudioSampleTypeSupported(kSbMediaAudioSampleTypeFloat32)) {
+    return kSbMediaAudioSampleTypeFloat32;
+  }
+  return kSbMediaAudioSampleTypeInt16;
+}
+
+// The required output format and the output of the ffmpeg decoder can be
+// different.  In this case libavresample is used to convert the ffmpeg output
+// into the required format.
+void ConvertSamples(int source_sample_format,
+                    int target_sample_format,
+                    int channel_layout,
+                    int sample_rate,
+                    int samples_per_channel,
+                    uint8_t** input_buffer,
+                    uint8_t* output_buffer) {
   AVAudioResampleContext* context = avresample_alloc_context();
   SB_DCHECK(context != NULL);
 
@@ -39,7 +48,7 @@
   av_opt_set_int(context, "in_sample_rate", sample_rate, 0);
   av_opt_set_int(context, "out_sample_rate", sample_rate, 0);
   av_opt_set_int(context, "in_sample_fmt", source_sample_format, 0);
-  av_opt_set_int(context, "out_sample_fmt", AV_SAMPLE_FMT_FLT, 0);
+  av_opt_set_int(context, "out_sample_fmt", target_sample_format, 0);
   av_opt_set_int(context, "internal_sample_fmt", source_sample_format, 0);
 
   int result = avresample_open(context);
@@ -58,7 +67,8 @@
 
 AudioDecoder::AudioDecoder(SbMediaAudioCodec audio_codec,
                            const SbMediaAudioHeader& audio_header)
-    : codec_context_(NULL),
+    : sample_type_(GetSupportedSampleType()),
+      codec_context_(NULL),
       av_frame_(NULL),
       stream_ended_(false),
       audio_header_(audio_header) {
@@ -72,7 +82,7 @@
 }
 
 void AudioDecoder::Decode(const InputBuffer& input_buffer,
-                          std::vector<float>* output) {
+                          std::vector<uint8_t>* output) {
   SB_CHECK(output != NULL);
   SB_CHECK(codec_context_ != NULL);
 
@@ -105,11 +115,16 @@
   audio_header_.samples_per_second = codec_context_->sample_rate;
 
   if (decoded_audio_size > 0) {
-    output->resize(decoded_audio_size / sizeof(float));
-    ConvertToInterleavedFloat(
-        codec_context_->sample_fmt, codec_context_->channel_layout,
-        audio_header_.samples_per_second, av_frame_->nb_samples,
-        av_frame_->extended_data, reinterpret_cast<uint8_t*>(&(*output)[0]));
+    output->resize(codec_context_->channels * av_frame_->nb_samples *
+                   (sample_type_ == kSbMediaAudioSampleTypeInt16 ? 2 : 4));
+    if (codec_context_->sample_fmt == codec_context_->request_sample_fmt) {
+      memcpy(&(*output)[0], av_frame_->extended_data, output->size());
+    } else {
+      ConvertSamples(
+          codec_context_->sample_fmt, codec_context_->request_sample_fmt,
+          codec_context_->channel_layout, audio_header_.samples_per_second,
+          av_frame_->nb_samples, av_frame_->extended_data, &(*output)[0]);
+    }
   } else {
     // TODO: Consider fill it with silence.
     SB_LOG(ERROR) << "Decoded audio frame is empty.";
@@ -127,7 +142,11 @@
   stream_ended_ = false;
 }
 
-int AudioDecoder::GetSamplesPerSecond() {
+SbMediaAudioSampleType AudioDecoder::GetSampleType() const {
+  return sample_type_;
+}
+
+int AudioDecoder::GetSamplesPerSecond() const {
   return audio_header_.samples_per_second;
 }
 
@@ -144,7 +163,11 @@
   codec_context_->codec_type = AVMEDIA_TYPE_AUDIO;
   codec_context_->codec_id = AV_CODEC_ID_AAC;
   // Request_sample_fmt is set by us, but sample_fmt is set by the decoder.
-  codec_context_->request_sample_fmt = AV_SAMPLE_FMT_FLT;  // interleaved float
+  if (sample_type_ == kSbMediaAudioSampleTypeInt16) {
+    codec_context_->request_sample_fmt = AV_SAMPLE_FMT_S16;
+  } else {
+    codec_context_->request_sample_fmt = AV_SAMPLE_FMT_FLT;
+  }
 
   codec_context_->channels = audio_header_.number_of_channels;
   codec_context_->sample_rate = audio_header_.samples_per_second;
diff --git a/src/starboard/shared/ffmpeg/ffmpeg_audio_decoder.h b/src/starboard/shared/ffmpeg/ffmpeg_audio_decoder.h
index 3eda447..c2a78db 100644
--- a/src/starboard/shared/ffmpeg/ffmpeg_audio_decoder.h
+++ b/src/starboard/shared/ffmpeg/ffmpeg_audio_decoder.h
@@ -35,10 +35,11 @@
   ~AudioDecoder() SB_OVERRIDE;
 
   void Decode(const InputBuffer& input_buffer,
-              std::vector<float>* output) SB_OVERRIDE;
+              std::vector<uint8_t>* output) SB_OVERRIDE;
   void WriteEndOfStream() SB_OVERRIDE;
   void Reset() SB_OVERRIDE;
-  int GetSamplesPerSecond() SB_OVERRIDE;
+  SbMediaAudioSampleType GetSampleType() const SB_OVERRIDE;
+  int GetSamplesPerSecond() const SB_OVERRIDE;
 
   bool is_valid() const { return codec_context_ != NULL; }
 
@@ -46,6 +47,7 @@
   void InitializeCodec();
   void TeardownCodec();
 
+  SbMediaAudioSampleType sample_type_;
   AVCodecContext* codec_context_;
   AVFrame* av_frame_;
 
diff --git a/src/starboard/shared/ffmpeg/ffmpeg_video_decoder.cc b/src/starboard/shared/ffmpeg/ffmpeg_video_decoder.cc
index 0d04361..7b9efed 100644
--- a/src/starboard/shared/ffmpeg/ffmpeg_video_decoder.cc
+++ b/src/starboard/shared/ffmpeg/ffmpeg_video_decoder.cc
@@ -78,6 +78,8 @@
   frame->height = codec_context->height;
   frame->format = codec_context->pix_fmt;
 
+  frame->reordered_opaque = codec_context->reordered_opaque;
+
   return 0;
 }
 
@@ -180,6 +182,7 @@
       packet.data = const_cast<uint8_t*>(event.input_buffer.data());
       packet.size = event.input_buffer.size();
       packet.pts = event.input_buffer.pts();
+      codec_context_->reordered_opaque = packet.pts;
 
       DecodePacket(&packet);
       host_->OnDecoderStatusUpdate(kNeedMoreInput, NULL);
@@ -221,8 +224,9 @@
   int pitch = AlignUp(av_frame_->width, kAlignment * 2);
 
   VideoFrame frame = VideoFrame::CreateYV12Frame(
-      av_frame_->width, av_frame_->height, pitch, av_frame_->pkt_pts,
-      av_frame_->data[0], av_frame_->data[1], av_frame_->data[2]);
+      av_frame_->width, av_frame_->height, pitch,
+      codec_context_->reordered_opaque, av_frame_->data[0], av_frame_->data[1],
+      av_frame_->data[2]);
   host_->OnDecoderStatusUpdate(kBufferFull, &frame);
   return true;
 }
diff --git a/src/starboard/shared/ffmpeg/ffmpeg_video_decoder.h b/src/starboard/shared/ffmpeg/ffmpeg_video_decoder.h
index 8c5e99a..6fcc2f1 100644
--- a/src/starboard/shared/ffmpeg/ffmpeg_video_decoder.h
+++ b/src/starboard/shared/ffmpeg/ffmpeg_video_decoder.h
@@ -34,7 +34,7 @@
   typedef starboard::player::InputBuffer InputBuffer;
   typedef starboard::player::VideoFrame VideoFrame;
 
-  explicit VideoDecoder(SbMediaVideoCodec);
+  explicit VideoDecoder(SbMediaVideoCodec video_codec);
   ~VideoDecoder() SB_OVERRIDE;
 
   void SetHost(Host* host) SB_OVERRIDE;
diff --git a/src/starboard/shared/posix/time_get_monotonic_thread_now.cc b/src/starboard/shared/posix/time_get_monotonic_thread_now.cc
new file mode 100644
index 0000000..7050050
--- /dev/null
+++ b/src/starboard/shared/posix/time_get_monotonic_thread_now.cc
@@ -0,0 +1,30 @@
+// Copyright 2016 Google Inc. 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 "starboard/time.h"
+
+#include <time.h>
+
+#include "starboard/log.h"
+#include "starboard/shared/posix/time_internal.h"
+
+SbTimeMonotonic SbTimeGetMonotonicThreadNow() {
+  struct timespec time;
+  if (clock_gettime(CLOCK_THREAD_CPUTIME_ID, &time) != 0) {
+    SB_NOTREACHED() << "clock_gettime(CLOCK_THREAD_CPUTIME_ID) failed.";
+    return 0;
+  }
+
+  return FromTimespecDelta(&time);
+}
diff --git a/src/starboard/shared/pthread/thread_create.cc b/src/starboard/shared/pthread/thread_create.cc
index 8718ba4..f2ab13d 100644
--- a/src/starboard/shared/pthread/thread_create.cc
+++ b/src/starboard/shared/pthread/thread_create.cc
@@ -61,19 +61,19 @@
 int SbThreadPriorityToNice(SbThreadPriority priority) {
   switch (priority) {
     case kSbThreadPriorityLowest:
-      return 10;
+      return 19;
     case kSbThreadPriorityLow:
-      return 5;
+      return 18;
     case kSbThreadNoPriority:
     // Fall through on purpose to default to kThreadPriority_Normal.
     case kSbThreadPriorityNormal:
-      return -5;
+      return 10;
     case kSbThreadPriorityHigh:
-      return -15;
+      return 2;
     case kSbThreadPriorityHighest:
-      return -18;
+      return 1;
     case kSbThreadPriorityRealTime:
-      return -19;
+      return 0;
     default:
       SB_NOTREACHED();
       return 0;
diff --git a/src/starboard/shared/starboard/application.cc b/src/starboard/shared/starboard/application.cc
index 1adc590..96efbdb 100644
--- a/src/starboard/shared/starboard/application.cc
+++ b/src/starboard/shared/starboard/application.cc
@@ -130,7 +130,7 @@
 
 #if SB_HAS(PLAYER) && SB_IS(PLAYER_PUNCHED_OUT)
 void Application::HandleFrame(SbPlayer player,
-                              const player::VideoFrame& frame,
+                              const VideoFrame& frame,
                               int x,
                               int y,
                               int width,
diff --git a/src/starboard/shared/starboard/application.h b/src/starboard/shared/starboard/application.h
index 7328f2e..f8609ce 100644
--- a/src/starboard/shared/starboard/application.h
+++ b/src/starboard/shared/starboard/application.h
@@ -38,6 +38,8 @@
 // dispatching events to the Starboard event handler, SbEventHandle.
 class Application {
  public:
+  typedef player::VideoFrame VideoFrame;
+
   // You can use a void(void *) function to signal that a state-transition event
   // has completed.
   typedef SbEventDataDestructor EventHandledCallback;
@@ -200,7 +202,7 @@
   // used when the application needs to composite video frames with punch-out
   // video manually (should be rare). Will be called from an external thread.
   void HandleFrame(SbPlayer player,
-                   const player::VideoFrame& frame,
+                   const VideoFrame& frame,
                    int x,
                    int y,
                    int width,
@@ -222,7 +224,7 @@
   // Subclasses may override this method to accept video frames from the media
   // system. Will be called from an external thread.
   virtual void AcceptFrame(SbPlayer player,
-                           const player::VideoFrame& frame,
+                           const VideoFrame& frame,
                            int x,
                            int y,
                            int width,
diff --git a/src/starboard/shared/starboard/memory_reporter_internal.h b/src/starboard/shared/starboard/memory_reporter_internal.h
new file mode 100644
index 0000000..72b2bef
--- /dev/null
+++ b/src/starboard/shared/starboard/memory_reporter_internal.h
@@ -0,0 +1,40 @@
+// Copyright 2016 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef STARBOARD_SHARED_STARBOARD_MEMORY_REPORTER_INTERNAL_H_
+#define STARBOARD_SHARED_STARBOARD_MEMORY_REPORTER_INTERNAL_H_
+
+#include "starboard/export.h"
+#include "starboard/shared/internal_only.h"
+#include "starboard/types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Internal function used to track mapped memory. This is used internally by
+// implementations of SbMemoryMap().
+SB_EXPORT void SbMemoryReporterReportMappedMemory(const void* memory,
+                                                  size_t size);
+
+// Internal function used to track mapped memory. This is used internally by
+// implementations of SbMemoryUnmap().
+SB_EXPORT void SbMemoryReporterReportUnmappedMemory(const void* memory,
+                                                    size_t size);
+
+#ifdef __cplusplus
+}  // extern "C"
+#endif
+
+#endif  // STARBOARD_SHARED_STARBOARD_MEMORY_REPORTER_INTERNAL_H_
diff --git a/src/starboard/shared/starboard/player/filter/audio_decoder_internal.h b/src/starboard/shared/starboard/player/filter/audio_decoder_internal.h
index b8bdafe..cb1850c 100644
--- a/src/starboard/shared/starboard/player/filter/audio_decoder_internal.h
+++ b/src/starboard/shared/starboard/player/filter/audio_decoder_internal.h
@@ -20,6 +20,7 @@
 #include "starboard/media.h"
 #include "starboard/shared/internal_only.h"
 #include "starboard/shared/starboard/player/input_buffer_internal.h"
+#include "starboard/types.h"
 
 namespace starboard {
 namespace shared {
@@ -35,7 +36,7 @@
   // Decode the encoded audio data stored in |input_buffer| and store the
   // result in |output|.
   virtual void Decode(const InputBuffer& input_buffer,
-                      std::vector<float>* output) = 0;
+                      std::vector<uint8_t>* output) = 0;
   // Note that there won't be more input data unless Reset() is called.
   virtual void WriteEndOfStream() = 0;
   // Clear any cached buffer of the codec and reset the state of the codec.
@@ -43,10 +44,13 @@
   // data from previous buffers are cleared.
   virtual void Reset() = 0;
 
+  // Return the sample type of the decoded pcm data.
+  virtual SbMediaAudioSampleType GetSampleType() const = 0;
+
   // Return the sample rate of the incoming audio.  This should be used by the
   // audio renderer as the sample rate of the underlying audio stream can be
   // different than the sample rate stored in the meta data.
-  virtual int GetSamplesPerSecond() = 0;
+  virtual int GetSamplesPerSecond() const = 0;
 
   // Individual implementation has to implement this function to create an
   // audio decoder.
diff --git a/src/starboard/shared/starboard/player/filter/audio_renderer_internal.cc b/src/starboard/shared/starboard/player/filter/audio_renderer_internal.cc
index 3a53533..105e23f 100644
--- a/src/starboard/shared/starboard/player/filter/audio_renderer_internal.cc
+++ b/src/starboard/shared/starboard/player/filter/audio_renderer_internal.cc
@@ -33,10 +33,13 @@
 AudioRenderer::AudioRenderer(scoped_ptr<AudioDecoder> decoder,
                              const SbMediaAudioHeader& audio_header)
     : channels_(audio_header.number_of_channels),
+      bytes_per_frame_(
+          (decoder->GetSampleType() == kSbMediaAudioSampleTypeInt16 ? 2 : 4) *
+          channels_),
       paused_(true),
       seeking_(false),
       seeking_to_pts_(0),
-      frame_buffer_(kMaxCachedFrames * audio_header.number_of_channels),
+      frame_buffer_(kMaxCachedFrames * bytes_per_frame_),
       frames_in_buffer_(0),
       offset_in_frames_(0),
       frames_consumed_(0),
@@ -61,7 +64,7 @@
   }
 
   SbMediaTime input_pts = input_buffer.pts();
-  std::vector<float> decoded_audio;
+  std::vector<uint8_t> decoded_audio;
   decoder_->Decode(input_buffer, &decoded_audio);
   if (decoded_audio.empty()) {
     SB_DLOG(ERROR) << "decoded_audio contains no frames.";
@@ -76,9 +79,9 @@
       }
     }
 
-    AppendFrames(&decoded_audio[0], decoded_audio.size() / channels_);
+    AppendFrames(&decoded_audio[0], decoded_audio.size() / bytes_per_frame_);
 
-    if (seeking_ && frame_buffer_.size() > kPrerollFrames * channels_) {
+    if (seeking_ && frame_buffer_.size() > kPrerollFrames * bytes_per_frame_) {
       seeking_ = false;
     }
   }
@@ -91,7 +94,7 @@
               SbAudioSinkGetNearestSupportedSampleFrequency(sample_rate));
     // TODO: Handle sink creation failure.
     audio_sink_ = SbAudioSinkCreate(
-        channels_, sample_rate, kSbMediaAudioSampleTypeFloat32,
+        channels_, sample_rate, decoder_->GetSampleType(),
         kSbMediaAudioFrameStorageTypeInterleaved,
         reinterpret_cast<SbAudioSinkFrameBuffers>(frame_buffers_),
         kMaxCachedFrames, &AudioRenderer::UpdateSourceStatusFunc,
@@ -220,23 +223,23 @@
   frames_consumed_ += frames_consumed;
 }
 
-void AudioRenderer::AppendFrames(const float* source_buffer,
+void AudioRenderer::AppendFrames(const uint8_t* source_buffer,
                                  int frames_to_append) {
   SB_DCHECK(frames_in_buffer_ + frames_to_append <= kMaxCachedFrames);
 
   int offset_to_append =
       (offset_in_frames_ + frames_in_buffer_) % kMaxCachedFrames;
   if (frames_to_append > kMaxCachedFrames - offset_to_append) {
-    SbMemoryCopy(
-        &frame_buffer_[offset_to_append * channels_], source_buffer,
-        (kMaxCachedFrames - offset_to_append) * sizeof(float) * channels_);
-    source_buffer += (kMaxCachedFrames - offset_to_append) * channels_;
+    SbMemoryCopy(&frame_buffer_[offset_to_append * bytes_per_frame_],
+                 source_buffer,
+                 (kMaxCachedFrames - offset_to_append) * bytes_per_frame_);
+    source_buffer += (kMaxCachedFrames - offset_to_append) * bytes_per_frame_;
     frames_to_append -= kMaxCachedFrames - offset_to_append;
     frames_in_buffer_ += kMaxCachedFrames - offset_to_append;
     offset_to_append = 0;
   }
-  SbMemoryCopy(&frame_buffer_[offset_to_append * channels_], source_buffer,
-               frames_to_append * sizeof(float) * channels_);
+  SbMemoryCopy(&frame_buffer_[offset_to_append * bytes_per_frame_],
+               source_buffer, frames_to_append * bytes_per_frame_);
   frames_in_buffer_ += frames_to_append;
 }
 
diff --git a/src/starboard/shared/starboard/player/filter/audio_renderer_internal.h b/src/starboard/shared/starboard/player/filter/audio_renderer_internal.h
index c85f1fe..e14457c 100644
--- a/src/starboard/shared/starboard/player/filter/audio_renderer_internal.h
+++ b/src/starboard/shared/starboard/player/filter/audio_renderer_internal.h
@@ -25,6 +25,7 @@
 #include "starboard/shared/internal_only.h"
 #include "starboard/shared/starboard/player/filter/audio_decoder_internal.h"
 #include "starboard/shared/starboard/player/input_buffer_internal.h"
+#include "starboard/types.h"
 
 namespace starboard {
 namespace shared {
@@ -76,17 +77,18 @@
                           bool* is_eos_reached);
   void ConsumeFrames(int frames_consumed);
 
-  void AppendFrames(const float* source_buffer, int frames_to_append);
+  void AppendFrames(const uint8_t* source_buffer, int frames_to_append);
 
   const int channels_;
+  const int bytes_per_frame_;
 
   Mutex mutex_;
   bool paused_;
   bool seeking_;
   SbMediaTime seeking_to_pts_;
 
-  std::vector<float> frame_buffer_;
-  float* frame_buffers_[1];
+  std::vector<uint8_t> frame_buffer_;
+  uint8_t* frame_buffers_[1];
   int frames_in_buffer_;
   int offset_in_frames_;
 
diff --git a/src/starboard/shared/starboard/player/filter/video_renderer_internal.cc b/src/starboard/shared/starboard/player/filter/video_renderer_internal.cc
index 3898af5..65ee800 100644
--- a/src/starboard/shared/starboard/player/filter/video_renderer_internal.cc
+++ b/src/starboard/shared/starboard/player/filter/video_renderer_internal.cc
@@ -33,19 +33,24 @@
 }
 
 void VideoRenderer::WriteSample(const InputBuffer& input_buffer) {
-  ScopedLock lock(mutex_);
+  SB_DCHECK(thread_checker_.CalledOnValidThread());
 
   if (end_of_stream_written_) {
     SB_LOG(ERROR) << "Appending video sample at " << input_buffer.pts()
                   << " after EOS reached.";
     return;
   }
-  need_more_input_ = false;
+
+  {
+    ScopedLock lock(mutex_);
+    need_more_input_ = false;
+  }
+
   decoder_->WriteInputBuffer(input_buffer);
 }
 
 void VideoRenderer::WriteEndOfStream() {
-  ScopedLock lock(mutex_);
+  SB_DCHECK(thread_checker_.CalledOnValidThread());
 
   SB_LOG_IF(WARNING, end_of_stream_written_)
       << "Try to write EOS after EOS is reached";
@@ -57,6 +62,7 @@
 }
 
 void VideoRenderer::Seek(SbMediaTime seek_to_pts) {
+  SB_DCHECK(thread_checker_.CalledOnValidThread());
   SB_DCHECK(seek_to_pts >= 0);
 
   decoder_->Reset();
@@ -74,7 +80,7 @@
 }
 
 const VideoFrame& VideoRenderer::GetCurrentFrame(SbMediaTime media_time) {
-  ScopedLock lock(mutex_);
+  SB_DCHECK(thread_checker_.CalledOnValidThread());
 
   if (frames_.empty()) {
     return seeking_frame_;
@@ -89,18 +95,18 @@
 }
 
 bool VideoRenderer::IsEndOfStreamPlayed() const {
-  ScopedLock lock(mutex_);
+  SB_DCHECK(thread_checker_.CalledOnValidThread());
   return end_of_stream_written_ && frames_.size() <= 1;
 }
 
 bool VideoRenderer::CanAcceptMoreData() const {
-  ScopedLock lock(mutex_);
+  SB_DCHECK(thread_checker_.CalledOnValidThread());
   return frames_.size() < kMaxCachedFrames && !end_of_stream_written_ &&
          need_more_input_;
 }
 
 bool VideoRenderer::IsSeekingInProgress() const {
-  ScopedLock lock(mutex_);
+  SB_DCHECK(thread_checker_.CalledOnValidThread());
   return seeking_;
 }
 
diff --git a/src/starboard/shared/starboard/player/filter/video_renderer_internal.h b/src/starboard/shared/starboard/player/filter/video_renderer_internal.h
index 43f899b..8450e59 100644
--- a/src/starboard/shared/starboard/player/filter/video_renderer_internal.h
+++ b/src/starboard/shared/starboard/player/filter/video_renderer_internal.h
@@ -25,6 +25,7 @@
 #include "starboard/shared/starboard/player/filter/video_decoder_internal.h"
 #include "starboard/shared/starboard/player/input_buffer_internal.h"
 #include "starboard/shared/starboard/player/video_frame_internal.h"
+#include "starboard/shared/starboard/thread_checker.h"
 
 namespace starboard {
 namespace shared {
@@ -66,6 +67,7 @@
   void OnDecoderStatusUpdate(VideoDecoder::Status status,
                              VideoFrame* frame) SB_OVERRIDE;
 
+  ThreadChecker thread_checker_;
   ::starboard::Mutex mutex_;
 
   bool seeking_;
diff --git a/src/starboard/shared/starboard/player/player_create.cc b/src/starboard/shared/starboard/player/player_create.cc
index 5581ca8..c09f526 100644
--- a/src/starboard/shared/starboard/player/player_create.cc
+++ b/src/starboard/shared/starboard/player/player_create.cc
@@ -15,6 +15,7 @@
 #include "starboard/player.h"
 
 #include "starboard/configuration.h"
+#include "starboard/decode_target.h"
 #include "starboard/log.h"
 #include "starboard/shared/starboard/player/filter/filter_based_player_worker_handler.h"
 #include "starboard/shared/starboard/player/player_internal.h"
@@ -33,8 +34,16 @@
                         SbPlayerDeallocateSampleFunc sample_deallocate_func,
                         SbPlayerDecoderStatusFunc decoder_status_func,
                         SbPlayerStatusFunc player_status_func,
-                        void* context) {
+                        void* context
+#if SB_VERSION(3)
+                        ,
+                        SbDecodeTargetProvider* provider
+#endif
+                        ) {
   SB_UNREFERENCED_PARAMETER(window);
+#if SB_VERSION(3)
+  SB_UNREFERENCED_PARAMETER(provider);
+#endif
 
   if (audio_codec != kSbMediaAudioCodecAac) {
     SB_LOG(ERROR) << "Unsupported audio codec " << audio_codec;
diff --git a/src/starboard/shared/starboard/player/video_frame_internal.cc b/src/starboard/shared/starboard/player/video_frame_internal.cc
index d1a0099..793066d 100644
--- a/src/starboard/shared/starboard/player/video_frame_internal.cc
+++ b/src/starboard/shared/starboard/player/video_frame_internal.cc
@@ -183,6 +183,8 @@
 

   int y_plane_size_in_bytes = height * pitch_in_bytes;

   int uv_plane_size_in_bytes = uv_height * uv_pitch_in_bytes;

+  frame.pixel_buffer_.reserve(y_plane_size_in_bytes +

+                              uv_plane_size_in_bytes * 2);

   frame.pixel_buffer_.assign(y, y + y_plane_size_in_bytes);

   frame.pixel_buffer_.insert(frame.pixel_buffer_.end(), u,

                              u + uv_plane_size_in_bytes);

diff --git a/src/starboard/shared/stub/decode_target_is_opaque.cc b/src/starboard/shared/stub/decode_target_is_opaque.cc
new file mode 100644
index 0000000..1798975
--- /dev/null
+++ b/src/starboard/shared/stub/decode_target_is_opaque.cc
@@ -0,0 +1,24 @@
+// Copyright 2016 Google Inc. 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 "starboard/configuration.h"
+#include "starboard/decode_target.h"
+
+#if !(SB_VERSION(3) && SB_HAS(GRAPHICS))
+#error "SbDecodeTargetIsOpaque requires SB_VERSION(3) and SB_HAS(GRAPHICS)."
+#endif
+
+bool SbDecodeTargetIsOpaque(SbDecodeTarget decode_target) {
+  return false;
+}
diff --git a/src/starboard/shared/stub/image_decode.cc b/src/starboard/shared/stub/image_decode.cc
new file mode 100644
index 0000000..ca1ff97
--- /dev/null
+++ b/src/starboard/shared/stub/image_decode.cc
@@ -0,0 +1,28 @@
+// Copyright 2016 Google Inc. 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 "starboard/configuration.h"
+#include "starboard/image.h"
+
+#if !(SB_VERSION(3) && SB_HAS(GRAPHICS))
+#error "SbImageDecode requires SB_VERSION(3) and SB_HAS(GRAPHICS)."
+#endif
+
+SbDecodeTarget SbImageDecode(SbDecodeTargetProvider* provider,
+                             void* data,
+                             int data_size,
+                             const char* mime_type,
+                             SbDecodeTargetFormat format) {
+  return kSbDecodeTargetInvalid;
+}
diff --git a/src/starboard/shared/stub/image_is_decode_supported.cc b/src/starboard/shared/stub/image_is_decode_supported.cc
new file mode 100644
index 0000000..2b0b367
--- /dev/null
+++ b/src/starboard/shared/stub/image_is_decode_supported.cc
@@ -0,0 +1,25 @@
+// Copyright 2016 Google Inc. 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 "starboard/configuration.h"
+#include "starboard/image.h"
+
+#if !(SB_VERSION(3) && SB_HAS(GRAPHICS))
+#error "SbImageIsDecodeSupported requires SB_VERSION(3) and SB_HAS(GRAPHICS)."
+#endif
+
+bool SbImageIsDecodeSupported(const char* mime_type,
+                              SbDecodeTargetFormat format) {
+  return false;
+}
diff --git a/src/starboard/shared/stub/microphone_get_available.cc b/src/starboard/shared/stub/microphone_get_available.cc
index 126149d..5fdb309 100644
--- a/src/starboard/shared/stub/microphone_get_available.cc
+++ b/src/starboard/shared/stub/microphone_get_available.cc
@@ -18,7 +18,7 @@
 
 int SbMicrophoneGetAvailable(SbMicrophoneInfo* out_info_array,
                              int info_array_size) {
-  return -1;
+  return 0;
 }
 
 #endif  // SB_HAS(MICROPHONE) && SB_VERSION(2)
diff --git a/src/starboard/shared/stub/microphone_read.cc b/src/starboard/shared/stub/microphone_read.cc
index 430195f..2965831 100644
--- a/src/starboard/shared/stub/microphone_read.cc
+++ b/src/starboard/shared/stub/microphone_read.cc
@@ -19,7 +19,7 @@
 int SbMicrophoneRead(SbMicrophone microphone,
                      void* out_audio_data,
                      int audio_data_size) {
-  return 0;
+  return -1;
 }
 
 #endif  // SB_HAS(MICROPHONE) && SB_VERSION(2)
diff --git a/src/starboard/shared/stub/player_create.cc b/src/starboard/shared/stub/player_create.cc
index c9cb1e8..639315c 100644
--- a/src/starboard/shared/stub/player_create.cc
+++ b/src/starboard/shared/stub/player_create.cc
@@ -14,6 +14,10 @@
 
 #include "starboard/player.h"
 
+#if !SB_HAS(PLAYER)
+#error "SbPlayerCreate requires SB_HAS(PLAYER)."
+#endif
+
 SbPlayer SbPlayerCreate(SbWindow /*window*/,
                         SbMediaVideoCodec /*video_codec*/,
                         SbMediaAudioCodec /*audio_codec*/,
@@ -23,6 +27,11 @@
                         SbPlayerDeallocateSampleFunc /*sample_deallocate_func*/,
                         SbPlayerDecoderStatusFunc /*decoder_status_func*/,
                         SbPlayerStatusFunc /*player_status_func*/,
-                        void* /*context*/) {
+                        void* /*context*/
+#if SB_VERSION(3)
+                        ,
+                        SbDecodeTargetProvider* /*provider*/
+#endif
+                        ) {
   return kSbPlayerInvalid;
 }
diff --git a/src/starboard/shared/stub/speech_synthesis_cancel.cc b/src/starboard/shared/stub/speech_synthesis_cancel.cc
new file mode 100644
index 0000000..5a4cf19
--- /dev/null
+++ b/src/starboard/shared/stub/speech_synthesis_cancel.cc
@@ -0,0 +1,22 @@
+// Copyright 2016 Google Inc. 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 "starboard/speech_synthesis.h"
+
+#if !SB_HAS(SPEECH_SYNTHESIS) && SB_VERSION(3)
+#error If speech synthesis not enabled on this platform, please exclude it\
+       from the build
+#endif
+
+void SbSpeechSynthesisCancel() {}
diff --git a/src/starboard/shared/stub/speech_synthesis_set_language.cc b/src/starboard/shared/stub/speech_synthesis_set_language.cc
new file mode 100644
index 0000000..383239b
--- /dev/null
+++ b/src/starboard/shared/stub/speech_synthesis_set_language.cc
@@ -0,0 +1,24 @@
+// Copyright 2016 Google Inc. 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 "starboard/speech_synthesis.h"
+
+#if !SB_HAS(SPEECH_SYNTHESIS) && SB_VERSION(3)
+#error If speech synthesis not enabled on this platform, please exclude it\
+       from the build
+#endif
+
+bool SbSpeechSynthesisSetLanguage(const char* lang) {
+  return false;
+}
diff --git a/src/starboard/shared/stub/speech_synthesis_speak.cc b/src/starboard/shared/stub/speech_synthesis_speak.cc
new file mode 100644
index 0000000..53cd5f5
--- /dev/null
+++ b/src/starboard/shared/stub/speech_synthesis_speak.cc
@@ -0,0 +1,22 @@
+// Copyright 2016 Google Inc. 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 "starboard/speech_synthesis.h"
+
+#if !SB_HAS(SPEECH_SYNTHESIS) && SB_VERSION(3)
+#error If speech synthesis not enabled on this platform, please exclude it\
+       from the build
+#endif
+
+void SbSpeechSynthesisSpeak(const char* text) {}
diff --git a/src/starboard/shared/stub/time_get_monotonic_thread_now.cc b/src/starboard/shared/stub/time_get_monotonic_thread_now.cc
new file mode 100644
index 0000000..feee2b6
--- /dev/null
+++ b/src/starboard/shared/stub/time_get_monotonic_thread_now.cc
@@ -0,0 +1,19 @@
+// Copyright 2016 Google Inc. 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 "starboard/time.h"
+
+SbTimeMonotonic SbTimeGetMonotonicThreadNow() {
+  return SbTimeMonotonic(0);
+}