Bug 908503: Change to stagefright demuxer; r=cpearce
☠☠ backed out by 299a5a0a5458 ☠ ☠
authorAnthony Jones <ajones@mozilla.com>
Mon, 12 May 2014 09:46:18 +1200
changeset 182498 1917418786902a900ff00ff637f80efee5638301
parent 182497 05fe24d0499a55e15dc521075dd9cf20e92c2347
child 182499 7f57690f5141b41fcfc3230e1fdc890b463f2ad0
push id43320
push userajones@mozilla.com
push dateSun, 11 May 2014 21:48:01 +0000
treeherdermozilla-inbound@f9b51826b2ff [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerscpearce
bugs908503
milestone32.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 908503: Change to stagefright demuxer; r=cpearce
content/media/fmp4/BlankDecoderModule.cpp
content/media/fmp4/MP4Reader.cpp
content/media/fmp4/MP4Reader.h
content/media/fmp4/ffmpeg/FFmpegAACDecoder.cpp
content/media/fmp4/ffmpeg/FFmpegAACDecoder.h
content/media/fmp4/ffmpeg/FFmpegDataDecoder.cpp
content/media/fmp4/ffmpeg/FFmpegDataDecoder.h
content/media/fmp4/ffmpeg/FFmpegH264Decoder.cpp
content/media/fmp4/ffmpeg/FFmpegH264Decoder.h
content/media/fmp4/moz.build
content/media/fmp4/wmf/WMFAudioOutputSource.cpp
content/media/fmp4/wmf/WMFDecoderModule.cpp
content/media/fmp4/wmf/WMFMediaDataDecoder.cpp
media/libstagefright/additional_headers
media/libstagefright/binding/Adts.cpp
media/libstagefright/binding/DecoderData.cpp
media/libstagefright/binding/include/mp4_demuxer/Adts.h
media/libstagefright/binding/include/mp4_demuxer/DecoderData.h
media/libstagefright/binding/include/mp4_demuxer/mp4_demuxer.h
media/libstagefright/binding/mp4_demuxer.cpp
media/libstagefright/checkout.sh
media/libstagefright/files.py
media/libstagefright/frameworks/av/include/media/stagefright/DataSource.h
media/libstagefright/frameworks/av/include/media/stagefright/MediaErrors.h
media/libstagefright/frameworks/av/include/media/stagefright/MediaExtractor.h
media/libstagefright/frameworks/av/include/media/stagefright/MetaData.h
media/libstagefright/frameworks/av/include/media/stagefright/Utils.h
media/libstagefright/frameworks/av/media/libstagefright/DataSource.cpp
media/libstagefright/frameworks/av/media/libstagefright/ESDS.cpp
media/libstagefright/frameworks/av/media/libstagefright/MPEG4Extractor.cpp
media/libstagefright/frameworks/av/media/libstagefright/MediaBufferGroup.cpp
media/libstagefright/frameworks/av/media/libstagefright/MetaData.cpp
media/libstagefright/frameworks/av/media/libstagefright/SampleIterator.cpp
media/libstagefright/frameworks/av/media/libstagefright/SampleTable.cpp
media/libstagefright/frameworks/av/media/libstagefright/Utils.cpp
media/libstagefright/frameworks/av/media/libstagefright/foundation/ABitReader.cpp
media/libstagefright/frameworks/av/media/libstagefright/foundation/AString.cpp
media/libstagefright/frameworks/av/media/libstagefright/foundation/hexdump.cpp
media/libstagefright/frameworks/av/media/libstagefright/id3/ID3.cpp
media/libstagefright/frameworks/av/media/libstagefright/include/SampleIterator.h
media/libstagefright/patches/frameworks/av.patch
media/libstagefright/patches/system/core.patch
media/libstagefright/ports/darwin/include/byteswap.h
media/libstagefright/ports/ics/include/log/log.h
media/libstagefright/ports/ics/include/utils/Condition.h
media/libstagefright/ports/ics/include/utils/Mutex.h
media/libstagefright/ports/jb/include/log/log.h
media/libstagefright/ports/win32/include/arpa/inet.h
media/libstagefright/ports/win32/include/byteswap.h
media/libstagefright/ports/win32/include/netinet/in.h
media/libstagefright/ports/win32/include/pthread.h
media/libstagefright/ports/win32/include/stdbool.h
media/libstagefright/ports/win32/include/sys/cdefs.h
media/libstagefright/ports/win32/include/sys/time.h
media/libstagefright/ports/win32/include/unistd.h
media/libstagefright/stubs/empty/ALooper.h
media/libstagefright/stubs/empty/ALooperRoster.h
media/libstagefright/stubs/empty/binder/Parcel.h
media/libstagefright/stubs/empty/hardware/audio.h
media/libstagefright/stubs/empty/media/AudioParameter.h
media/libstagefright/stubs/empty/media/AudioSystem.h
media/libstagefright/stubs/empty/media/MediaPlayerInterface.h
media/libstagefright/stubs/empty/sys/system_properties.h
media/libstagefright/stubs/empty/system/audio.h
media/libstagefright/stubs/include/cutils/atomic.h
media/libstagefright/stubs/include/media/stagefright/foundation/AMessage.h
media/libstagefright/stubs/include/sys/atomics.h
media/libstagefright/stubs/include/ui/GraphicBuffer.h
media/libstagefright/stubs/include/utils/threads.h
media/libstagefright/system/core/include/cutils/properties.h
media/libstagefright/system/core/include/log/log.h
media/libstagefright/system/core/include/log/logprint.h
media/libstagefright/system/core/include/utils/Condition.h
media/libstagefright/system/core/include/utils/List.h
media/libstagefright/system/core/include/utils/Mutex.h
media/libstagefright/system/core/include/utils/RefBase.h
media/libstagefright/system/core/include/utils/SortedVector.h
media/libstagefright/system/core/include/utils/String8.h
media/libstagefright/system/core/include/utils/TypeHelpers.h
media/libstagefright/system/core/include/utils/Unicode.h
media/libstagefright/system/core/include/utils/Vector.h
media/libstagefright/system/core/liblog/fake_log_device.c
media/libstagefright/system/core/liblog/logd_write.c
media/libstagefright/system/core/liblog/logprint.c
media/libstagefright/system/core/libutils/RefBase.cpp
media/libstagefright/system/core/libutils/String8.cpp
media/libstagefright/system/core/libutils/Unicode.cpp
media/libstagefright/update-patches.sh
--- a/content/media/fmp4/BlankDecoderModule.cpp
+++ b/content/media/fmp4/BlankDecoderModule.cpp
@@ -153,22 +153,18 @@ private:
   uint32_t mFrameWidth;
   uint32_t mFrameHeight;
   RefPtr<layers::ImageContainer> mImageContainer;
 };
 
 
 class BlankAudioDataCreator {
 public:
-  BlankAudioDataCreator(uint32_t aChannelCount,
-                        uint32_t aSampleRate,
-                        uint16_t aBitsPerSample)
-    : mFrameSum(0)
-    , mChannelCount(aChannelCount)
-    , mSampleRate(aSampleRate)
+  BlankAudioDataCreator(uint32_t aChannelCount, uint32_t aSampleRate)
+    : mFrameSum(0), mChannelCount(aChannelCount), mSampleRate(aSampleRate)
   {
   }
 
   MediaData* Create(Microseconds aDTS,
                     Microseconds aDuration,
                     int64_t aOffsetInStream)
   {
     // Convert duration to frames. We add 1 to duration to account for
@@ -214,32 +210,29 @@ public:
   }
 
   // Decode thread.
   virtual MediaDataDecoder* CreateH264Decoder(const mp4_demuxer::VideoDecoderConfig& aConfig,
                                               layers::LayersBackend aLayersBackend,
                                               layers::ImageContainer* aImageContainer,
                                               MediaTaskQueue* aVideoTaskQueue,
                                               MediaDataDecoderCallback* aCallback) MOZ_OVERRIDE {
-    BlankVideoDataCreator* decoder = new BlankVideoDataCreator(aConfig.visible_rect().width(),
-                                                               aConfig.visible_rect().height(),
-                                                               aImageContainer);
+    BlankVideoDataCreator* decoder = new BlankVideoDataCreator(
+      aConfig.display_width, aConfig.display_height, aImageContainer);
     return new BlankMediaDataDecoder<BlankVideoDataCreator>(decoder,
                                                             aVideoTaskQueue,
                                                             aCallback);
   }
 
   // Decode thread.
   virtual MediaDataDecoder* CreateAACDecoder(const mp4_demuxer::AudioDecoderConfig& aConfig,
                                              MediaTaskQueue* aAudioTaskQueue,
                                              MediaDataDecoderCallback* aCallback) MOZ_OVERRIDE {
-    BlankAudioDataCreator* decoder =
-      new BlankAudioDataCreator(ChannelLayoutToChannelCount(aConfig.channel_layout()),
-                                aConfig.samples_per_second(),
-                                aConfig.bits_per_channel());
+    BlankAudioDataCreator* decoder = new BlankAudioDataCreator(
+      aConfig.channel_count, aConfig.samples_per_second);
     return new BlankMediaDataDecoder<BlankAudioDataCreator>(decoder,
                                                             aAudioTaskQueue,
                                                             aCallback);
   }
 };
 
 PlatformDecoderModule* CreateBlankDecoderModule()
 {
--- a/content/media/fmp4/MP4Reader.cpp
+++ b/content/media/fmp4/MP4Reader.cpp
@@ -1,18 +1,16 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "MP4Reader.h"
 #include "MediaResource.h"
-#include "mp4_demuxer/mp4_demuxer.h"
-#include "mp4_demuxer/Streams.h"
 #include "nsSize.h"
 #include "VideoUtils.h"
 #include "mozilla/dom/HTMLMediaElement.h"
 #include "ImageContainer.h"
 #include "Layers.h"
 #include "SharedThreadPool.h"
 #include "mozilla/Preferences.h"
 
@@ -48,38 +46,41 @@ public:
   {
     MOZ_COUNT_CTOR(MP4Stream);
     MOZ_ASSERT(aResource);
   }
   virtual ~MP4Stream() {
     MOZ_COUNT_DTOR(MP4Stream);
   }
 
-  virtual bool ReadAt(int64_t aOffset,
-                      uint8_t* aBuffer,
-                      uint32_t aCount,
-                      uint32_t* aBytesRead) MOZ_OVERRIDE {
+  virtual bool ReadAt(int64_t aOffset, void* aBuffer, size_t aCount,
+                      size_t* aBytesRead) MOZ_OVERRIDE
+  {
     uint32_t sum = 0;
     do {
       uint32_t offset = aOffset + sum;
-      char* buffer = reinterpret_cast<char*>(aBuffer + sum);
+      char* buffer = reinterpret_cast<char*>(aBuffer) + sum;
       uint32_t toRead = aCount - sum;
       uint32_t bytesRead = 0;
       nsresult rv = mResource->ReadAt(offset, buffer, toRead, &bytesRead);
       if (NS_FAILED(rv)) {
         return false;
       }
       sum += bytesRead;
     } while (sum < aCount);
     *aBytesRead = sum;
     return true;
   }
 
-  virtual int64_t Length() const MOZ_OVERRIDE {
-    return mResource->GetLength();
+  virtual bool Length(int64_t* aSize) MOZ_OVERRIDE
+  {
+    if (mResource->GetLength() < 0)
+      return false;
+    *aSize = mResource->GetLength();
+    return true;
   }
 
 private:
   RefPtr<MediaResource> mResource;
 };
 
 MP4Reader::MP4Reader(AbstractMediaDecoder* aDecoder)
   : MediaDecoderReader(aDecoder)
@@ -115,16 +116,18 @@ MP4Reader::Shutdown()
     Flush(kVideo);
     mVideo.mDecoder->Shutdown();
     mVideo.mDecoder = nullptr;
   }
   if (mVideo.mTaskQueue) {
     mVideo.mTaskQueue->Shutdown();
     mVideo.mTaskQueue = nullptr;
   }
+  // Dispose of the queued sample before shutting down the demuxer
+  mQueuedVideoSample = nullptr;
 }
 
 void
 MP4Reader::InitLayersBackendType()
 {
   if (!IsVideoContentType(mDecoder->GetResource()->GetContentType())) {
     // Not playing video, we don't care about the layers backend type.
     return;
@@ -148,18 +151,17 @@ MP4Reader::InitLayersBackendType()
   mLayersBackendType = layerManager->GetCompositorBackendType();
 }
 
 nsresult
 MP4Reader::Init(MediaDecoderReader* aCloneDonor)
 {
   MOZ_ASSERT(NS_IsMainThread(), "Must be on main thread.");
   PlatformDecoderModule::Init();
-  mMP4Stream = new MP4Stream(mDecoder->GetResource());
-  mDemuxer = new MP4Demuxer(mMP4Stream);
+  mDemuxer = new MP4Demuxer(new MP4Stream(mDecoder->GetResource()));
 
   InitLayersBackendType();
 
   mAudio.mTaskQueue = new MediaTaskQueue(
     SharedThreadPool::Get(NS_LITERAL_CSTRING("MP4 Audio Decode")));
   NS_ENSURE_TRUE(mAudio.mTaskQueue, NS_ERROR_FAILURE);
 
   mVideo.mTaskQueue = new MediaTaskQueue(
@@ -171,50 +173,48 @@ MP4Reader::Init(MediaDecoderReader* aClo
 
 nsresult
 MP4Reader::ReadMetadata(MediaInfo* aInfo,
                         MetadataTags** aTags)
 {
   bool ok = mDemuxer->Init();
   NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE);
 
+  mInfo.mAudio.mHasAudio = mAudio.mActive = mDemuxer->HasValidAudio();
   const AudioDecoderConfig& audio = mDemuxer->AudioConfig();
-  mInfo.mAudio.mHasAudio = mAudio.mActive = mDemuxer->HasAudio() &&
-                                            audio.IsValidConfig();
   // If we have audio, we *only* allow AAC to be decoded.
-  if (HasAudio() && audio.codec() != kCodecAAC) {
+  if (mInfo.mAudio.mHasAudio && strcmp(audio.mime_type, "audio/mp4a-latm")) {
     return NS_ERROR_FAILURE;
   }
 
+  mInfo.mVideo.mHasVideo = mVideo.mActive = mDemuxer->HasValidVideo();
   const VideoDecoderConfig& video = mDemuxer->VideoConfig();
-  mInfo.mVideo.mHasVideo = mVideo.mActive = mDemuxer->HasVideo() &&
-                                            video.IsValidConfig();
   // If we have video, we *only* allow H.264 to be decoded.
-  if (HasVideo() && video.codec() != kCodecH264) {
+  if (mInfo.mVideo.mHasVideo && strcmp(video.mime_type, "video/avc")) {
     return NS_ERROR_FAILURE;
   }
 
   mPlatform = PlatformDecoderModule::Create();
   NS_ENSURE_TRUE(mPlatform, NS_ERROR_FAILURE);
 
   if (HasAudio()) {
-    mInfo.mAudio.mRate = audio.samples_per_second();
-    mInfo.mAudio.mChannels = ChannelLayoutToChannelCount(audio.channel_layout());
+    mInfo.mAudio.mRate = audio.samples_per_second;
+    mInfo.mAudio.mChannels = audio.channel_count;
     mAudio.mCallback = new DecoderCallback(this, kAudio);
     mAudio.mDecoder = mPlatform->CreateAACDecoder(audio,
                                                   mAudio.mTaskQueue,
                                                   mAudio.mCallback);
     NS_ENSURE_TRUE(mAudio.mDecoder != nullptr, NS_ERROR_FAILURE);
     nsresult rv = mAudio.mDecoder->Init();
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   if (HasVideo()) {
-    IntSize sz = video.natural_size();
-    mInfo.mVideo.mDisplay = nsIntSize(sz.width(), sz.height());
+    mInfo.mVideo.mDisplay =
+      nsIntSize(video.display_width, video.display_height);
     mVideo.mCallback = new  DecoderCallback(this, kVideo);
     mVideo.mDecoder = mPlatform->CreateH264Decoder(video,
                                                    mLayersBackendType,
                                                    mDecoder->GetImageContainer(),
                                                    mVideo.mTaskQueue,
                                                    mVideo.mCallback);
     NS_ENSURE_TRUE(mVideo.mDecoder != nullptr, NS_ERROR_FAILURE);
     nsresult rv = mVideo.mDecoder->Init();
@@ -224,17 +224,17 @@ MP4Reader::ReadMetadata(MediaInfo* aInfo
   // Get the duration, and report it to the decoder if we have it.
   Microseconds duration = mDemuxer->Duration();
   if (duration != -1) {
     ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
     mDecoder->SetMediaDuration(duration);
   }
   // We can seek if we get a duration *and* the reader reports that it's
   // seekable.
-  if (!mDemuxer->CanSeek()) {
+  if (!mDecoder->GetResource()->IsTransportSeekable() || !mDemuxer->CanSeek()) {
     mDecoder->SetMediaSeekable(false);
   }
 
   *aInfo = mInfo;
   *aTags = nullptr;
 
   return NS_OK;
 }
@@ -253,51 +253,38 @@ MP4Reader::HasVideo()
 
 MP4Reader::DecoderData&
 MP4Reader::GetDecoderData(TrackType aTrack)
 {
   MOZ_ASSERT(aTrack == kAudio || aTrack == kVideo);
   return (aTrack == kAudio) ? mAudio : mVideo;
 }
 
-MP4SampleQueue&
-MP4Reader::SampleQueue(TrackType aTrack)
-{
-  return GetDecoderData(aTrack).mDemuxedSamples;
-}
-
 MediaDataDecoder*
 MP4Reader::Decoder(TrackType aTrack)
 {
   return GetDecoderData(aTrack).mDecoder;
 }
 
 MP4Sample*
 MP4Reader::PopSample(TrackType aTrack)
 {
-  // Unfortunately the demuxer outputs in the order samples appear in the
-  // media, not on a per stream basis. We cache the samples we get from
-  // streams other than the one we want.
-  MP4SampleQueue& sampleQueue = SampleQueue(aTrack);
-  while (sampleQueue.empty()) {
-    nsAutoPtr<MP4Sample> sample;
-    bool eos = false;
-    bool ok = mDemuxer->Demux(&sample, &eos);
-    if (!ok || eos) {
-      MOZ_ASSERT(!sample);
+  switch (aTrack) {
+    case kAudio:
+      return mDemuxer->DemuxAudioSample();
+
+    case kVideo:
+      if (mQueuedVideoSample)
+        return mQueuedVideoSample.forget();
+
+      return mDemuxer->DemuxVideoSample();
+
+    default:
       return nullptr;
-    }
-    MOZ_ASSERT(sample);
-    MP4Sample* s = sample.forget();
-    SampleQueue(s->type).push_back(s);
   }
-  MOZ_ASSERT(!sampleQueue.empty());
-  MP4Sample* sample = sampleQueue.front();
-  sampleQueue.pop_front();
-  return sample;
 }
 
 // How async decoding works:
 //
 // When MP4Reader::Decode() is called:
 // * Lock the DecoderData. We assume the state machine wants
 //   output from the decoder (in future, we'll assume decoder wants input
 //   when the output MediaQueue isn't "full").
@@ -479,17 +466,17 @@ MP4Reader::SkipVideoDemuxToNextKeyFrame(
       // EOS, or error. Let the state machine know.
       return false;
     }
     parsed++;
     if (!compressed->is_sync_point ||
         compressed->composition_timestamp < aTimeThreshold) {
       continue;
     }
-    mVideo.mDemuxedSamples.push_front(compressed.forget());
+    mQueuedVideoSample = compressed;
     break;
   }
 
   return true;
 }
 
 bool
 MP4Reader::DecodeVideoFrame(bool &aKeyframeSkip,
@@ -526,15 +513,29 @@ MP4Reader::DecodeVideoFrame(bool &aKeyfr
 }
 
 nsresult
 MP4Reader::Seek(int64_t aTime,
                 int64_t aStartTime,
                 int64_t aEndTime,
                 int64_t aCurrentTime)
 {
-  if (!mDemuxer->CanSeek()) {
+  if (!mDecoder->GetResource()->IsTransportSeekable() || !mDemuxer->CanSeek()) {
     return NS_ERROR_FAILURE;
   }
-  return NS_ERROR_NOT_IMPLEMENTED;
+  Flush(kVideo);
+  Flush(kAudio);
+  ResetDecode();
+
+  mQueuedVideoSample = nullptr;
+  if (mDemuxer->HasValidVideo()) {
+    mDemuxer->SeekVideo(aTime);
+    mQueuedVideoSample = PopSample(kVideo);
+  }
+  if (mDemuxer->HasValidAudio()) {
+    mDemuxer->SeekAudio(
+      mQueuedVideoSample ? mQueuedVideoSample->composition_timestamp : aTime);
+  }
+
+  return NS_OK;
 }
 
 } // namespace mozilla
--- a/content/media/fmp4/MP4Reader.h
+++ b/content/media/fmp4/MP4Reader.h
@@ -6,17 +6,16 @@
 
 #if !defined(MP4Reader_h_)
 #define MP4Reader_h_
 
 #include "MediaDecoderReader.h"
 #include "nsAutoPtr.h"
 #include "PlatformDecoderModule.h"
 #include "mp4_demuxer/mp4_demuxer.h"
-#include "mp4_demuxer/box_definitions.h"
 #include "MediaTaskQueue.h"
 
 #include <deque>
 #include "mozilla/Monitor.h"
 
 namespace mozilla {
 
 namespace dom {
@@ -66,17 +65,16 @@ private:
 
   void Output(mp4_demuxer::TrackType aType, MediaData* aSample);
   void InputExhausted(mp4_demuxer::TrackType aTrack);
   void Error(mp4_demuxer::TrackType aTrack);
   bool Decode(mp4_demuxer::TrackType aTrack);
   void Flush(mp4_demuxer::TrackType aTrack);
 
   nsAutoPtr<mp4_demuxer::MP4Demuxer> mDemuxer;
-  nsAutoPtr<MP4Stream> mMP4Stream;
   nsAutoPtr<PlatformDecoderModule> mPlatform;
 
   class DecoderCallback : public MediaDataDecoderCallback {
   public:
     DecoderCallback(MP4Reader* aReader,
                     mp4_demuxer::TrackType aType)
       : mReader(aReader)
       , mType(aType)
@@ -107,19 +105,16 @@ private:
       , mInputExhausted(false)
       , mError(false)
       , mIsFlushing(false)
     {
     }
 
     // The platform decoder.
     RefPtr<MediaDataDecoder> mDecoder;
-    // Queue of input extracted by the demuxer, but not yet sent to the
-    // platform decoder.
-    MP4SampleQueue mDemuxedSamples;
     // TaskQueue on which decoder can choose to decode.
     // Only non-null up until the decoder is created.
     RefPtr<MediaTaskQueue> mTaskQueue;
     // Callback that receives output and error notifications from the decoder.
     nsAutoPtr<DecoderCallback> mCallback;
     // Monitor that protects all non-threadsafe state; the primitives
     // that follow.
     Monitor mMonitor;
@@ -129,16 +124,19 @@ private:
     // Whether this stream exists in the media.
     bool mActive;
     bool mInputExhausted;
     bool mError;
     bool mIsFlushing;
   };
   DecoderData mAudio;
   DecoderData mVideo;
+  // Queued frame extracted by the demuxer, but not yet sent to the platform
+  // decoder.
+  nsAutoPtr<mp4_demuxer::MP4Sample> mQueuedVideoSample;
 
   // The last number of decoded output frames that we've reported to
   // MediaDecoder::NotifyDecoded(). We diff the number of output video
   // frames every time that DecodeVideoData() is called, and report the
   // delta there.
   uint64_t mLastReportedNumDecodedFrames;
 
   DecoderData& GetDecoderData(mp4_demuxer::TrackType aTrack);
--- a/content/media/fmp4/ffmpeg/FFmpegAACDecoder.cpp
+++ b/content/media/fmp4/ffmpeg/FFmpegAACDecoder.cpp
@@ -68,42 +68,41 @@ void
 FFmpegAACDecoder::DecodePacket(MP4Sample* aSample)
 {
   nsAutoPtr<AVFrame> frame(avcodec_alloc_frame());
   avcodec_get_frame_defaults(frame);
 
   AVPacket packet;
   av_init_packet(&packet);
 
-  packet.data = &(*aSample->data)[0];
-  packet.size = aSample->data->size();
+  packet.data = aSample->data;
+  packet.size = aSample->size;
   packet.pos = aSample->byte_offset;
-  packet.dts = aSample->decode_timestamp;
 
   int decoded;
   int bytesConsumed =
     avcodec_decode_audio4(&mCodecContext, frame.get(), &decoded, &packet);
 
   if (bytesConsumed < 0 || !decoded) {
     NS_WARNING("FFmpeg audio decoder error.");
     mCallback->Error();
     return;
   }
 
-  NS_ASSERTION(bytesConsumed == (int)aSample->data->size(),
+  NS_ASSERTION(bytesConsumed == (int)aSample->size,
                "Only one audio packet should be received at a time.");
 
   uint32_t numChannels = mCodecContext.channels;
 
   nsAutoArrayPtr<AudioDataValue> audio(
     CopyAndPackAudio(frame.get(), numChannels, frame->nb_samples));
 
-  nsAutoPtr<AudioData> data(new AudioData(packet.pos, aSample->decode_timestamp,
-                                          aSample->duration, frame->nb_samples,
-                                          audio.forget(), numChannels));
+  nsAutoPtr<AudioData> data(
+    new AudioData(packet.pos, aSample->composition_timestamp, aSample->duration,
+                  frame->nb_samples, audio.forget(), numChannels));
 
   mCallback->Output(data.forget());
 
   if (mTaskQueue->IsEmpty()) {
     mCallback->InputExhausted();
   }
 }
 
--- a/content/media/fmp4/ffmpeg/FFmpegAACDecoder.h
+++ b/content/media/fmp4/ffmpeg/FFmpegAACDecoder.h
@@ -3,16 +3,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef __FFmpegAACDecoder_h__
 #define __FFmpegAACDecoder_h__
 
 #include "FFmpegDataDecoder.h"
+#include "mp4_demuxer/DecoderData.h"
 
 namespace mozilla
 {
 
 class FFmpegAACDecoder : public FFmpegDataDecoder
 {
 public:
   FFmpegAACDecoder(MediaTaskQueue* aTaskQueue,
--- a/content/media/fmp4/ffmpeg/FFmpegDataDecoder.cpp
+++ b/content/media/fmp4/ffmpeg/FFmpegDataDecoder.cpp
@@ -15,17 +15,17 @@
 
 namespace mozilla
 {
 
 bool FFmpegDataDecoder::sFFmpegInitDone = false;
 
 FFmpegDataDecoder::FFmpegDataDecoder(MediaTaskQueue* aTaskQueue,
                                      AVCodecID aCodecID)
-  : mTaskQueue(aTaskQueue), mCodecID(aCodecID)
+  : mExtraDataSize(0), mTaskQueue(aTaskQueue), mCodecID(aCodecID)
 {
   MOZ_COUNT_CTOR(FFmpegDataDecoder);
 }
 
 FFmpegDataDecoder::~FFmpegDataDecoder() {
   MOZ_COUNT_DTOR(FFmpegDataDecoder);
 }
 
@@ -82,16 +82,21 @@ FFmpegDataDecoder::Init()
   mCodecContext.opaque = this;
 
   // FFmpeg takes this as a suggestion for what format to use for audio samples.
   mCodecContext.request_sample_fmt = AV_SAMPLE_FMT_FLT;
 
   // FFmpeg will call back to this to negotiate a video pixel format.
   mCodecContext.get_format = ChoosePixelFormat;
 
+  if (mExtraData) {
+    mCodecContext.extradata = mExtraData;
+    mCodecContext.extradata_size = mExtraDataSize;
+  }
+
   AVDictionary* opts = nullptr;
   if (avcodec_open2(&mCodecContext, codec, &opts) < 0) {
     NS_WARNING("Couldn't initialise ffmpeg decoder");
     return NS_ERROR_FAILURE;
   }
 
   if (mCodecContext.codec_type == AVMEDIA_TYPE_AUDIO &&
       mCodecContext.sample_fmt != AV_SAMPLE_FMT_FLT &&
--- a/content/media/fmp4/ffmpeg/FFmpegDataDecoder.h
+++ b/content/media/fmp4/ffmpeg/FFmpegDataDecoder.h
@@ -2,18 +2,16 @@
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef __FFmpegDataDecoder_h__
 #define __FFmpegDataDecoder_h__
 
-#include "mp4_demuxer/mp4_demuxer.h"
-
 #include "FFmpegDecoderModule.h"
 #include "FFmpegRuntimeLinker.h"
 #include "FFmpegCompat.h"
 
 namespace mozilla
 {
 
 class FFmpegDataDecoder : public MediaDataDecoder
@@ -26,16 +24,18 @@ public:
 
   virtual nsresult Init() MOZ_OVERRIDE;
   virtual nsresult Input(mp4_demuxer::MP4Sample* aSample) = 0;
   virtual nsresult Flush() MOZ_OVERRIDE;
   virtual nsresult Drain() = 0;
   virtual nsresult Shutdown() MOZ_OVERRIDE;
 
 protected:
+  nsAutoArrayPtr<uint8_t> mExtraData;
+  size_t mExtraDataSize;
   MediaTaskQueue* mTaskQueue;
   AVCodecContext mCodecContext;
 
 private:
   static bool sFFmpegInitDone;
 
   AVCodecID mCodecID;
 };
--- a/content/media/fmp4/ffmpeg/FFmpegH264Decoder.cpp
+++ b/content/media/fmp4/ffmpeg/FFmpegH264Decoder.cpp
@@ -24,21 +24,25 @@ typedef mp4_demuxer::MP4Sample MP4Sample
 namespace mozilla
 {
 
 FFmpegH264Decoder::FFmpegH264Decoder(
   MediaTaskQueue* aTaskQueue, MediaDataDecoderCallback* aCallback,
   const mp4_demuxer::VideoDecoderConfig &aConfig,
   ImageContainer* aImageContainer)
   : FFmpegDataDecoder(aTaskQueue, AV_CODEC_ID_H264)
-  , mConfig(aConfig)
   , mCallback(aCallback)
   , mImageContainer(aImageContainer)
 {
   MOZ_COUNT_CTOR(FFmpegH264Decoder);
+
+  mExtraDataSize = aConfig.extra_data_size;
+  mExtraData = new uint8_t[mExtraDataSize + FF_INPUT_BUFFER_PADDING_SIZE];
+  memset(mExtraData, 0, mExtraDataSize + FF_INPUT_BUFFER_PADDING_SIZE);
+  memcpy(mExtraData, aConfig.extra_data, mExtraDataSize);
 }
 
 nsresult
 FFmpegH264Decoder::Init()
 {
   nsresult rv = FFmpegDataDecoder::Init();
   NS_ENSURE_SUCCESS(rv, rv);
 
@@ -48,19 +52,18 @@ FFmpegH264Decoder::Init()
 }
 
 void
 FFmpegH264Decoder::DecodeFrame(mp4_demuxer::MP4Sample* aSample)
 {
   AVPacket packet;
   av_init_packet(&packet);
 
-  packet.data = &(*aSample->data)[0];
-  packet.size = aSample->data->size();
-  packet.dts = aSample->decode_timestamp;
+  packet.data = aSample->data;
+  packet.size = aSample->size;
   packet.pts = aSample->composition_timestamp;
   packet.flags = aSample->is_sync_point ? AV_PKT_FLAG_KEY : 0;
   packet.pos = aSample->byte_offset;
 
   nsAutoPtr<AVFrame> frame(avcodec_alloc_frame());
   avcodec_get_frame_defaults(frame);
 
   int decoded;
@@ -233,21 +236,17 @@ FFmpegH264Decoder::OutputDelayedFrames()
 nsresult
 FFmpegH264Decoder::Drain()
 {
   // The maximum number of frames that can be waiting to be decoded is
   // max_b_frames + 1: One P frame and max_b_frames B frames.
   for (int32_t i = 0; i <= mCodecContext.max_b_frames; i++) {
     // An empty frame tells FFmpeg to decode the next delayed frame it has in
     // its queue, if it has any.
-    nsAutoPtr<MP4Sample> empty(new MP4Sample(0 /* dts */, 0 /* cts */,
-                                              0 /* duration */, 0 /* offset */,
-                                              new std::vector<uint8_t>(),
-                                              mp4_demuxer::kVideo, nullptr,
-                                              false));
+    nsAutoPtr<MP4Sample> empty(new MP4Sample());
 
     nsresult rv = Input(empty.forget());
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   mTaskQueue->Dispatch(
     NS_NewRunnableMethod(this, &FFmpegH264Decoder::OutputDelayedFrames));
 
--- a/content/media/fmp4/ffmpeg/FFmpegH264Decoder.h
+++ b/content/media/fmp4/ffmpeg/FFmpegH264Decoder.h
@@ -41,17 +41,16 @@ private:
    * non-hardware accelerated image format that FFmpeg's H264 decoder is
    * capable of outputting.
    */
   int AllocateYUV420PVideoBuffer(AVCodecContext* aCodecContext,
                                  AVFrame* aFrame);
 
   static int AllocateBufferCb(AVCodecContext* aCodecContext, AVFrame* aFrame);
 
-  mp4_demuxer::VideoDecoderConfig mConfig;
   MediaDataDecoderCallback* mCallback;
   nsRefPtr<ImageContainer> mImageContainer;
 
   /**
    * Pass Image back from the allocator to our DoDecode method.
    * We *should* return the image back through ffmpeg wrapped in an AVFrame like
    * we're meant to. However, if avcodec_decode_video2 fails, it returns a
    * completely different frame from the one holding our image and it will be
--- a/content/media/fmp4/moz.build
+++ b/content/media/fmp4/moz.build
@@ -5,52 +5,53 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 EXPORTS += [
     'MP4Decoder.h',
     'MP4Reader.h',
     'PlatformDecoderModule.h',
 ]
 
-EXPORTS.mp4_demuxer += [
-    'demuxer/aac.h',
-    'demuxer/audio_decoder_config.h',
-    'demuxer/avc.h',
-    'demuxer/basictypes.h',
-    'demuxer/bit_reader.h',
-    'demuxer/box_definitions.h',
-    'demuxer/box_reader.h',
-    'demuxer/cenc.h',
-    'demuxer/channel_layout.h',
-    'demuxer/decrypt_config.h',
-    'demuxer/es_descriptor.h',
-    'demuxer/fourccs.h',
-    'demuxer/mp4_demuxer.h',
-    'demuxer/Streams.h',
-    'demuxer/track_run_iterator.h',
-    'demuxer/video_decoder_config.h',
-    'demuxer/video_util.h',
-]
+#EXPORTS.mp4_demuxer += [
+#    'demuxer/aac.h',
+#    'demuxer/audio_decoder_config.h',
+#    'demuxer/avc.h',
+#    'demuxer/basictypes.h',
+#    'demuxer/bit_reader.h',
+#    'demuxer/box_definitions.h',
+#    'demuxer/box_reader.h',
+#    'demuxer/cenc.h',
+#    'demuxer/channel_layout.h',
+#    'demuxer/decrypt_config.h',
+#    'demuxer/es_descriptor.h',
+#    'demuxer/fourccs.h',
+#    'demuxer/mp4_demuxer.h',
+#    'demuxer/Streams.h',
+#    'demuxer/track_run_iterator.h',
+#    'demuxer/video_decoder_config.h',
+#    'demuxer/video_util.h',
+#]
 
-UNIFIED_SOURCES += [
+#UNIFIED_SOURCES += [
+SOURCES += [
     'BlankDecoderModule.cpp',
-    'demuxer/aac.cc',
-    'demuxer/audio_decoder_config.cc',
-    'demuxer/avc.cc',
-    'demuxer/bit_reader.cc',
-    'demuxer/box_definitions.cc',
-    'demuxer/box_reader.cc',
-    'demuxer/cenc.cc',
-    'demuxer/channel_layout.cc',
-    'demuxer/decrypt_config.cc',
-    'demuxer/es_descriptor.cc',
-    'demuxer/mp4_demuxer.cc',
-    'demuxer/track_run_iterator.cc',
-    'demuxer/video_decoder_config.cc',
-    'demuxer/video_util.cc',
+#    'demuxer/aac.cc',
+#    'demuxer/audio_decoder_config.cc',
+#    'demuxer/avc.cc',
+#    'demuxer/bit_reader.cc',
+#    'demuxer/box_definitions.cc',
+#    'demuxer/box_reader.cc',
+#    'demuxer/cenc.cc',
+#    'demuxer/channel_layout.cc',
+#    'demuxer/decrypt_config.cc',
+#    'demuxer/es_descriptor.cc',
+#    'demuxer/mp4_demuxer.cc',
+#    'demuxer/track_run_iterator.cc',
+#    'demuxer/video_decoder_config.cc',
+#    'demuxer/video_util.cc',
     'MP4Decoder.cpp',
     'MP4Reader.cpp',
     'PlatformDecoderModule.cpp',
 ]
 
 if CONFIG['MOZ_WMF']:
   EXPORTS += [
       'wmf/MFTDecoder.h',
--- a/content/media/fmp4/wmf/WMFAudioOutputSource.cpp
+++ b/content/media/fmp4/wmf/WMFAudioOutputSource.cpp
@@ -60,28 +60,29 @@ AACAudioSpecificConfigToUserData(const u
   WORD* w = (WORD*)heeInfo;
   w[0] = 0x1; // Payload type ADTS
   w[1] = 0xFE; // Profile level indication, none specified.
 
   aOutUserData.AppendElements(heeInfo, heeInfoLen);
   aOutUserData.AppendElements(aAudioSpecConfig, aConfigLength);
 }
 
-WMFAudioOutputSource::WMFAudioOutputSource(const mp4_demuxer::AudioDecoderConfig& aConfig)
-  : mAudioChannels(ChannelLayoutToChannelCount(aConfig.channel_layout()))
-  , mAudioBytesPerSample(aConfig.bits_per_channel() / 8)
-  , mAudioRate(aConfig.samples_per_second())
+WMFAudioOutputSource::WMFAudioOutputSource(
+  const mp4_demuxer::AudioDecoderConfig& aConfig)
+  : mAudioChannels(aConfig.channel_count)
+  , mAudioBytesPerSample(aConfig.bytes_per_sample)
+  , mAudioRate(aConfig.samples_per_second)
   , mAudioFrameOffset(0)
   , mAudioFrameSum(0)
   , mMustRecaptureAudioPosition(true)
 {
   MOZ_COUNT_CTOR(WMFAudioOutputSource);
-  AACAudioSpecificConfigToUserData(aConfig.extra_data(),
-                                   aConfig.extra_data_size(),
-                                   mUserData);
+  AACAudioSpecificConfigToUserData(
+    reinterpret_cast<const uint8_t*>(aConfig.extra_data),
+    aConfig.extra_data_size, mUserData);
 }
 
 WMFAudioOutputSource::~WMFAudioOutputSource()
 {
   MOZ_COUNT_DTOR(WMFAudioOutputSource);
 }
 
 TemporaryRef<MFTDecoder>
--- a/content/media/fmp4/wmf/WMFDecoderModule.cpp
+++ b/content/media/fmp4/wmf/WMFDecoderModule.cpp
@@ -6,17 +6,16 @@
 
 #include "WMF.h"
 #include "WMFDecoderModule.h"
 #include "WMFDecoder.h"
 #include "WMFVideoOutputSource.h"
 #include "WMFAudioOutputSource.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/DebugOnly.h"
-#include "mp4_demuxer/audio_decoder_config.h"
 #include "WMFMediaDataDecoder.h"
 
 namespace mozilla {
 
 bool WMFDecoderModule::sIsWMFEnabled = false;
 bool WMFDecoderModule::sDXVAEnabled = false;
 
 WMFDecoderModule::WMFDecoderModule()
--- a/content/media/fmp4/wmf/WMFMediaDataDecoder.cpp
+++ b/content/media/fmp4/wmf/WMFMediaDataDecoder.cpp
@@ -62,18 +62,18 @@ WMFMediaDataDecoder::Input(mp4_demuxer::
       &WMFMediaDataDecoder::ProcessDecode,
       nsAutoPtr<mp4_demuxer::MP4Sample>(aSample)));
   return NS_OK;
 }
 
 void
 WMFMediaDataDecoder::ProcessDecode(mp4_demuxer::MP4Sample* aSample)
 {
-  const uint8_t* data = &aSample->data->front();
-  uint32_t length = aSample->data->size();
+  const uint8_t* data = reinterpret_cast<const uint8_t*>(aSample->data);
+  uint32_t length = aSample->size;
   HRESULT hr = mDecoder->Input(data, length, aSample->composition_timestamp);
   if (FAILED(hr)) {
     NS_WARNING("WMFAudioDecoder failed to input data");
     mCallback->Error();
     return;
   }
 
   mLastStreamOffset = aSample->byte_offset;
new file mode 100644
--- /dev/null
+++ b/media/libstagefright/additional_headers
@@ -0,0 +1,57 @@
+frameworks/av/include/media/stagefright/foundation/AAtomizer.h
+frameworks/av/include/media/stagefright/foundation/ABase.h
+frameworks/av/include/media/stagefright/foundation/ABitReader.h
+frameworks/av/include/media/stagefright/foundation/ABuffer.h
+frameworks/av/include/media/stagefright/foundation/ADebug.h
+frameworks/av/include/media/stagefright/foundation/AHandler.h
+frameworks/av/include/media/stagefright/foundation/AString.h
+frameworks/av/include/media/stagefright/foundation/hexdump.h
+frameworks/av/include/media/stagefright/MediaBufferGroup.h
+frameworks/av/include/media/stagefright/MediaDefs.h
+frameworks/av/include/media/stagefright/MediaErrors.h
+frameworks/av/include/media/stagefright/MediaExtractor.h
+frameworks/av/include/media/stagefright/MediaSource.h
+frameworks/av/include/media/stagefright/MetaData.h
+frameworks/av/include/media/stagefright/MetaData.h
+frameworks/av/media/libstagefright/include/ESDS.h
+frameworks/av/media/libstagefright/include/ID3.h
+frameworks/av/media/libstagefright/include/MPEG4Extractor.h
+frameworks/av/media/libstagefright/include/SampleTable.h
+frameworks/av/media/libstagefright/include/SampleTable.h
+system/core/debuggerd/backtrace.h
+system/core/include/android/log.h
+system/core/include/corkscrew/backtrace.h
+system/core/include/corkscrew/map_info.h
+system/core/include/corkscrew/ptrace.h
+system/core/include/corkscrew/symbol_table.h
+system/core/include/cutils/jstring.h
+system/core/include/cutils/log.h
+system/core/include/cutils/sched_policy.h
+system/core/include/log/event_tag_map.h
+system/core/include/log/logd.h
+system/core/include/log/logger.h
+system/core/include/log/logprint.h
+system/core/include/log/uio.h
+system/core/include/system/graphics.h
+system/core/include/sysutils/List.h
+system/core/include/utils/Atomic.h
+system/core/include/utils/CallStack.h
+system/core/include/utils/Condition.h
+system/core/include/utils/Debug.h
+system/core/include/utils/Errors.h
+system/core/include/utils/KeyedVector.h
+system/core/include/utils/List.h
+system/core/include/utils/Log.h
+system/core/include/utils/Mutex.h
+system/core/include/utils/RWLock.h
+system/core/include/utils/SortedVector.h
+system/core/include/utils/String16.h
+system/core/include/utils/String8.h
+system/core/include/utils/Timers.h
+system/core/include/utils/Vector.h
+system/core/include/utils/VectorImpl.h
+system/core/libpixelflinger/codeflinger/tinyutils/Errors.h
+system/core/libpixelflinger/codeflinger/tinyutils/KeyedVector.h
+system/core/libpixelflinger/codeflinger/tinyutils/SortedVector.h
+system/core/libpixelflinger/codeflinger/tinyutils/Vector.h
+system/core/libpixelflinger/codeflinger/tinyutils/VectorImpl.h
new file mode 100644
--- /dev/null
+++ b/media/libstagefright/binding/Adts.cpp
@@ -0,0 +1,62 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "mp4_demuxer/Adts.h"
+#include "mp4_demuxer/DecoderData.h"
+#include "media/stagefright/MediaBuffer.h"
+
+namespace mp4_demuxer
+{
+
+int8_t
+Adts::GetFrequencyIndex(uint16_t aSamplesPerSecond)
+{
+  static const int freq_lookup[] = { 96000, 88200, 64000, 48000, 44100,
+                                     32000, 24000, 22050, 16000, 12000,
+                                     11025, 8000,  7350,  0 };
+
+  int8_t i = 0;
+  while (aSamplesPerSecond < freq_lookup[i]) {
+    i++;
+  }
+
+  if (!freq_lookup[i]) {
+    return -1;
+  }
+
+  return i;
+}
+
+bool
+Adts::ConvertEsdsToAdts(uint16_t aChannelCount, int8_t aFrequencyIndex,
+                        int8_t aProfile, MP4Sample* aSample)
+{
+  static const int kADTSHeaderSize = 7;
+
+  size_t newSize = aSample->size + kADTSHeaderSize;
+
+  // ADTS header uses 13 bits for packet size.
+  if (newSize > aSample->mMediaBuffer->size() || newSize >= (1 << 13) ||
+      aChannelCount < 0 || aChannelCount > 15 || aFrequencyIndex < 0 ||
+      aProfile < 1 || aProfile > 4)
+    return false;
+
+  // Create a new buffer that is big enough to hold the ADTS header
+  aSample->adts_buffer = new uint8_t[newSize];
+  memcpy(aSample->adts_buffer + kADTSHeaderSize, aSample->data, aSample->size);
+  aSample->data = aSample->adts_buffer;
+
+  aSample->size = newSize;
+  aSample->data[0] = 0xff;
+  aSample->data[1] = 0xf1;
+  aSample->data[2] =
+    ((aProfile - 1) << 6) + (aFrequencyIndex << 2) + (aChannelCount >> 2);
+  aSample->data[3] = ((aChannelCount & 0x3) << 6) + (newSize >> 11);
+  aSample->data[4] = (newSize & 0x7ff) >> 3;
+  aSample->data[5] = ((newSize & 7) << 5) + 0x1f;
+  aSample->data[6] = 0xfc;
+
+  return true;
+}
+}
new file mode 100644
--- /dev/null
+++ b/media/libstagefright/binding/DecoderData.cpp
@@ -0,0 +1,107 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "mp4_demuxer/Adts.h"
+#include "mp4_demuxer/DecoderData.h"
+#include "media/stagefright/MetaData.h"
+#include "media/stagefright/MediaBuffer.h"
+
+using namespace android;
+
+namespace mp4_demuxer
+{
+
+static int32_t
+FindInt32(sp<MetaData>& mMetaData, uint32_t mKey)
+{
+  int32_t value;
+  if (!mMetaData->findInt32(mKey, &value))
+    return 0;
+  return value;
+}
+
+static int64_t
+FindInt64(sp<MetaData>& mMetaData, uint32_t mKey)
+{
+  int64_t value;
+  if (!mMetaData->findInt64(mKey, &value))
+    return 0;
+  return value;
+}
+
+void
+AudioDecoderConfig::Update(sp<MetaData>& aMetaData, const char* aMimeType)
+{
+  // aMimeType points to a string from MediaDefs.cpp so we don't need to copy it
+  mime_type = aMimeType;
+  duration = FindInt64(aMetaData, kKeyDuration);
+  channel_count = FindInt32(aMetaData, kKeyChannelCount);
+  bytes_per_sample = FindInt32(aMetaData, kKeySampleSize);
+  samples_per_second = FindInt32(aMetaData, kKeySampleRate);
+  frequency_index = Adts::GetFrequencyIndex(samples_per_second);
+  aac_profile = FindInt32(aMetaData, kKeyAACProfile);
+
+  uint32_t type;
+  aMetaData->findData(kKeyAVCC, &type, &extra_data, &extra_data_size);
+}
+
+bool
+AudioDecoderConfig::IsValid()
+{
+  return duration > 0 && channel_count > 0 && samples_per_second > 0;
+}
+
+void
+VideoDecoderConfig::Update(sp<MetaData>& aMetaData, const char* aMimeType)
+{
+  // aMimeType points to a string from MediaDefs.cpp so we don't need to copy it
+  mime_type = aMimeType;
+  duration = FindInt64(aMetaData, kKeyDuration);
+  display_width = FindInt32(aMetaData, kKeyDisplayWidth);
+  display_height = FindInt32(aMetaData, kKeyDisplayHeight);
+
+  // Copy the extra data so we don't have to hang onto MetaData.
+  const void* meta_extra_data;
+  uint32_t type;
+  aMetaData->findData(kKeyAVCC, &type, &meta_extra_data, &extra_data_size);
+  extra_data = new uint8_t[extra_data_size];
+  memcpy(extra_data, meta_extra_data, extra_data_size);
+}
+
+bool
+VideoDecoderConfig::IsValid()
+{
+  return display_width > 0 && display_height > 0 && duration > 0;
+}
+
+MP4Sample::MP4Sample()
+  : mMediaBuffer(nullptr)
+  , composition_timestamp(0)
+  , duration(0)
+  , byte_offset(0)
+  , is_sync_point(0)
+  , data(nullptr)
+  , size(0)
+{
+}
+
+MP4Sample::~MP4Sample()
+{
+  if (mMediaBuffer) {
+    mMediaBuffer->release();
+  }
+}
+
+void
+MP4Sample::Update()
+{
+  sp<MetaData> m = mMediaBuffer->meta_data();
+  composition_timestamp = FindInt64(m, kKeyTime);
+  duration = FindInt64(m, kKeyDuration);
+  byte_offset = FindInt64(m, kKey64BitFileOffset);
+  is_sync_point = FindInt32(m, kKeyIsSyncFrame);
+  data = reinterpret_cast<uint8_t*>(mMediaBuffer->data());
+  size = mMediaBuffer->range_length();
+}
+}
new file mode 100644
--- /dev/null
+++ b/media/libstagefright/binding/include/mp4_demuxer/Adts.h
@@ -0,0 +1,24 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef ADTS_H_
+#define ADTS_H_
+
+#include <stdint.h>
+
+namespace mp4_demuxer
+{
+
+class MP4Sample;
+
+class Adts
+{
+public:
+  static int8_t GetFrequencyIndex(uint16_t aSamplesPerSecond);
+  static bool ConvertEsdsToAdts(uint16_t aChannelCount, int8_t aFrequencyIndex,
+                                int8_t aProfile, MP4Sample* aSample);
+};
+}
+
+#endif
new file mode 100644
--- /dev/null
+++ b/media/libstagefright/binding/include/mp4_demuxer/DecoderData.h
@@ -0,0 +1,106 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef DECODER_DATA_H_
+#define DECODER_DATA_H_
+
+#include "mozilla/Types.h"
+#include "nsAutoPtr.h"
+
+namespace android
+{
+template <typename T> class sp;
+class MetaData;
+class MediaBuffer;
+}
+
+namespace mp4_demuxer
+{
+
+class MP4Demuxer;
+class Adts;
+
+class AudioDecoderConfig
+{
+public:
+  AudioDecoderConfig()
+    : mime_type(nullptr)
+    , duration(0)
+    , channel_count(0)
+    , bytes_per_sample(0)
+    , samples_per_second(0)
+    , extra_data(nullptr)
+    , extra_data_size(0)
+    , aac_profile(0)
+  {
+  }
+
+  const char* mime_type;
+  int64_t duration;
+  uint32_t channel_count;
+  uint32_t bytes_per_sample;
+  uint32_t samples_per_second;
+  int8_t frequency_index;
+
+  // Decoder specific extra data which in the case of H.264 is the AVCC config
+  // for decoders which require AVCC format as opposed to Annex B format.
+  const void* extra_data;
+  size_t extra_data_size;
+
+  void Update(android::sp<android::MetaData>& aMetaData, const char* aMimeType);
+  bool IsValid();
+
+private:
+  friend class MP4Demuxer;
+  int8_t aac_profile;
+};
+
+class VideoDecoderConfig
+{
+public:
+  VideoDecoderConfig()
+    : mime_type(nullptr)
+    , duration(0)
+    , display_width(0)
+    , display_height(0)
+    , extra_data(nullptr)
+    , extra_data_size(0)
+  {
+  }
+
+  const char* mime_type;
+  int64_t duration;
+  int32_t display_width;
+  int32_t display_height;
+  nsAutoPtr<uint8_t> extra_data;
+  size_t extra_data_size;
+
+  void Update(android::sp<android::MetaData>& aMetaData, const char* aMimeType);
+  bool IsValid();
+};
+
+class MP4Sample
+{
+public:
+  MP4Sample();
+  ~MP4Sample();
+  void Update();
+
+  android::MediaBuffer* mMediaBuffer;
+
+  int64_t composition_timestamp;
+  int64_t duration;
+  int64_t byte_offset;
+  bool is_sync_point;
+
+  uint8_t* data;
+  size_t size;
+
+private:
+  friend class Adts;
+  nsAutoPtr<uint8_t> adts_buffer;
+};
+}
+
+#endif
new file mode 100644
--- /dev/null
+++ b/media/libstagefright/binding/include/mp4_demuxer/mp4_demuxer.h
@@ -0,0 +1,63 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef MP4_DEMUXER_H_
+#define MP4_DEMUXER_H_
+
+#include "nsAutoPtr.h"
+#include "mozilla/gfx/Rect.h"
+#include "mp4_demuxer/DecoderData.h"
+
+namespace mp4_demuxer
+{
+
+struct StageFrightPrivate;
+typedef int64_t Microseconds;
+
+class Stream
+{
+
+public:
+  virtual bool ReadAt(int64_t offset, void* data, size_t size,
+                      size_t* bytes_read) = 0;
+  virtual bool Length(int64_t* size) = 0;
+
+  virtual ~Stream() {}
+};
+
+enum TrackType { kVideo = 1, kAudio };
+
+class MP4Demuxer
+{
+public:
+  MP4Demuxer(Stream* aSource);
+  ~MP4Demuxer();
+
+  bool Init();
+  Microseconds Duration();
+  bool CanSeek();
+
+  bool HasValidAudio();
+  bool HasValidVideo();
+
+  void SeekAudio(Microseconds aTime);
+  void SeekVideo(Microseconds aTime);
+
+  // DemuxAudioSample and DemuxVideoSample functions return nullptr on end of
+  // stream or error.
+  MP4Sample* DemuxAudioSample();
+  MP4Sample* DemuxVideoSample();
+
+  const AudioDecoderConfig& AudioConfig() { return mAudioConfig; }
+  const VideoDecoderConfig& VideoConfig() { return mVideoConfig; }
+
+private:
+  AudioDecoderConfig mAudioConfig;
+  VideoDecoderConfig mVideoConfig;
+
+  nsAutoPtr<StageFrightPrivate> mPrivate;
+};
+}
+
+#endif
new file mode 100644
--- /dev/null
+++ b/media/libstagefright/binding/mp4_demuxer.cpp
@@ -0,0 +1,192 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "include/MPEG4Extractor.h"
+#include "media/stagefright/DataSource.h"
+#include "media/stagefright/MediaSource.h"
+#include "media/stagefright/MetaData.h"
+#include "mp4_demuxer/Adts.h"
+#include "mp4_demuxer/mp4_demuxer.h"
+
+#include <stdint.h>
+
+using namespace android;
+
+namespace mp4_demuxer
+{
+
+struct StageFrightPrivate
+{
+  sp<MPEG4Extractor> mExtractor;
+
+  sp<MediaSource> mAudio;
+  MediaSource::ReadOptions mAudioOptions;
+
+  sp<MediaSource> mVideo;
+  MediaSource::ReadOptions mVideoOptions;
+};
+
+class DataSourceAdapter : public DataSource
+{
+public:
+  DataSourceAdapter(Stream* aSource) : mSource(aSource) {}
+
+  ~DataSourceAdapter() {}
+
+  virtual status_t initCheck() const { return NO_ERROR; }
+
+  virtual ssize_t readAt(off64_t offset, void* data, size_t size)
+  {
+    MOZ_ASSERT(((ssize_t)size) >= 0);
+    size_t bytesRead;
+    if (!mSource->ReadAt(offset, data, size, &bytesRead))
+      return ERROR_IO;
+
+    if (bytesRead == 0)
+      return ERROR_END_OF_STREAM;
+
+    MOZ_ASSERT(((ssize_t)bytesRead) >= 0);
+    return bytesRead;
+  }
+
+  virtual status_t getSize(off64_t* size)
+  {
+    if (!mSource->Length(size))
+      return ERROR_UNSUPPORTED;
+    return NO_ERROR;
+  }
+
+  virtual uint32_t flags() { return kWantsPrefetching | kIsHTTPBasedSource; }
+
+  virtual status_t reconnectAtOffset(off64_t offset) { return NO_ERROR; }
+
+private:
+  nsAutoPtr<Stream> mSource;
+};
+
+MP4Demuxer::MP4Demuxer(Stream* source) : mPrivate(new StageFrightPrivate())
+{
+  mPrivate->mExtractor = new MPEG4Extractor(new DataSourceAdapter(source));
+}
+
+MP4Demuxer::~MP4Demuxer()
+{
+  if (mPrivate->mAudio.get()) {
+    mPrivate->mAudio->stop();
+  }
+  if (mPrivate->mVideo.get()) {
+    mPrivate->mVideo->stop();
+  }
+}
+
+bool
+MP4Demuxer::Init()
+{
+  sp<MediaExtractor> e = mPrivate->mExtractor;
+  for (size_t i = 0; i < e->countTracks(); i++) {
+    sp<MetaData> metaData = e->getTrackMetaData(i);
+
+    const char* mimeType;
+    if (!metaData->findCString(kKeyMIMEType, &mimeType))
+      continue;
+
+    if (!mPrivate->mAudio.get() && !strncmp(mimeType, "audio/", 6)) {
+      mPrivate->mAudio = e->getTrack(i);
+      mPrivate->mAudio->start();
+      mAudioConfig.Update(metaData, mimeType);
+    } else if (!mPrivate->mVideo.get() && !strncmp(mimeType, "video/", 6)) {
+      mPrivate->mVideo = e->getTrack(i);
+      mPrivate->mVideo->start();
+      mVideoConfig.Update(metaData, mimeType);
+    }
+  }
+
+  return mPrivate->mAudio.get() || mPrivate->mVideo.get();
+}
+
+bool
+MP4Demuxer::HasValidAudio()
+{
+  return mPrivate->mAudio.get() && mAudioConfig.IsValid();
+}
+
+bool
+MP4Demuxer::HasValidVideo()
+{
+  return mPrivate->mVideo.get() && mVideoConfig.IsValid();
+}
+
+Microseconds
+MP4Demuxer::Duration()
+{
+  return std::max(mVideoConfig.duration, mAudioConfig.duration);
+}
+
+bool
+MP4Demuxer::CanSeek()
+{
+  return mPrivate->mExtractor->flags() & MediaExtractor::CAN_SEEK;
+}
+
+void
+MP4Demuxer::SeekAudio(Microseconds aTime)
+{
+  mPrivate->mAudioOptions.setSeekTo(
+    aTime, MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC);
+}
+
+void
+MP4Demuxer::SeekVideo(Microseconds aTime)
+{
+  mPrivate->mVideoOptions.setSeekTo(
+    aTime, MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC);
+}
+
+MP4Sample*
+MP4Demuxer::DemuxAudioSample()
+{
+  nsAutoPtr<MP4Sample> sample(new MP4Sample());
+  status_t status =
+    mPrivate->mAudio->read(&sample->mMediaBuffer, &mPrivate->mAudioOptions);
+  mPrivate->mAudioOptions.clearSeekTo();
+
+  if (status < 0) {
+    return nullptr;
+  }
+
+  sample->Update();
+  if (!Adts::ConvertEsdsToAdts(mAudioConfig.channel_count,
+                               mAudioConfig.frequency_index,
+                               mAudioConfig.aac_profile, sample)) {
+    return nullptr;
+  }
+
+  return sample.forget();
+}
+
+MP4Sample*
+MP4Demuxer::DemuxVideoSample()
+{
+  nsAutoPtr<MP4Sample> sample(new MP4Sample());
+  status_t status =
+    mPrivate->mVideo->read(&sample->mMediaBuffer, &mPrivate->mVideoOptions);
+  mPrivate->mVideoOptions.clearSeekTo();
+
+  if (status < 0) {
+    return nullptr;
+  }
+
+  sample->Update();
+
+  // The stagefright demuxer outputs Annex B format but decoders such as ffmpeg
+  // want AVCC format so we clobber the 00 00 00 01 with the nalsize.
+  if (sample->size < sizeof(uint32_t)) {
+    return nullptr;
+  }
+  *reinterpret_cast<uint32_t*>(sample->data) =
+    htonl(sample->size - sizeof(uint32_t));
+
+  return sample.forget();
+}
+}
new file mode 100755
--- /dev/null
+++ b/media/libstagefright/checkout.sh
@@ -0,0 +1,52 @@
+#!/bin/bash -e
+set -o pipefail
+abort () {
+    errcode=$?
+    echo "Error: That didn't work..."
+    exit $errcode
+}
+trap abort ERR
+
+cd `dirname "$0"`
+
+SITE=https://android.googlesource.com/platform
+for TAGFILE in `find patches -name \*.tag` 
+do
+    REPO=${TAGFILE:8:-4}
+    DEST=android/${REPO}
+    if [[ ! -e ${DEST} ]]
+    then
+        mkdir -p `dirname ${DEST}`
+        echo Cloning from ${SITE}/${REPO}
+        git clone ${SITE}/${REPO} ${DEST}
+    fi
+
+    rm -fR ${REPO}
+    TAG=`cat $TAGFILE`
+    (cd $DEST && git reset --hard 2>&1 && git checkout ${TAG} 2>&1) > /dev/null
+done
+
+FILES=`python files.py`
+HEADERS=`cat additional_headers`
+for FILE in $FILES $HEADERS frameworks/av/media/libstagefright/include/AMRExtractor.h
+do
+    echo Copying ${FILE}
+    mkdir -p `dirname ${FILE}`
+    cp android/${FILE} ${FILE}
+done
+
+for PATCH in `find patches -name \*.patch` 
+do
+    REPO=${PATCH:8:-6}
+    echo Patching repo ${REPO}
+    for FILE in `grep -- '--- a/' ${PATCH} | colrm 1 6`
+    do
+        if [[ ! -e ${FILE} ]]
+        then
+            echo Copying ${REPO}/${FILE}
+            mkdir -p `dirname ${REPO}/${FILE}`
+            cp android/${REPO}/${FILE} ${REPO}/${FILE}
+        fi
+    done
+    (cd ${REPO} && patch -p1 || true) < $PATCH
+done
new file mode 100644
--- /dev/null
+++ b/media/libstagefright/files.py
@@ -0,0 +1,29 @@
+#!/usr/bin/python
+
+import os
+import sys
+
+DEFINES={}
+CONFIG={}
+CXXFLAGS=[]
+CONFIG['_MSC_VER'] = 0
+CONFIG['OS_TARGET'] = 0
+
+class Exports(object):
+    def __init__(self):
+        self.mp4_demuxer=[]
+
+EXPORTS=Exports()
+
+SOURCES=[]
+UNIFIED_SOURCES=[]
+LOCAL_INCLUDES=[]
+
+try:
+    execfile('moz.build')
+except:
+    sys.exit(1)
+
+for f in SOURCES+UNIFIED_SOURCES:
+    if not f.startswith('binding/'):
+        print f
--- a/media/libstagefright/frameworks/av/include/media/stagefright/DataSource.h
+++ b/media/libstagefright/frameworks/av/include/media/stagefright/DataSource.h
@@ -16,41 +16,31 @@
 
 #ifndef DATA_SOURCE_H_
 
 #define DATA_SOURCE_H_
 
 #include <sys/types.h>
 
 #include <media/stagefright/MediaErrors.h>
-#include <utils/Errors.h>
-#include <utils/KeyedVector.h>
-#include <utils/List.h>
 #include <utils/RefBase.h>
-#include <utils/threads.h>
-#include <drm/DrmManagerClient.h>
 
 namespace android {
 
-struct AMessage;
 class String8;
 
 class DataSource : public RefBase {
 public:
     enum Flags {
         kWantsPrefetching      = 1,
         kStreamedFromLocalHost = 2,
         kIsCachingDataSource   = 4,
         kIsHTTPBasedSource     = 8,
     };
 
-    static sp<DataSource> CreateFromURI(
-            const char *uri,
-            const KeyedVector<String8, String8> *headers = NULL);
-
     DataSource() {}
 
     virtual status_t initCheck() const = 0;
 
     virtual ssize_t readAt(off64_t offset, void *data, size_t size) = 0;
 
     // Convenience methods:
     bool getUInt16(off64_t offset, uint16_t *x);
@@ -64,16 +54,17 @@ public:
     virtual uint32_t flags() {
         return 0;
     }
 
     virtual status_t reconnectAtOffset(off64_t offset) {
         return ERROR_UNSUPPORTED;
     }
 
+#if 0
     ////////////////////////////////////////////////////////////////////////////
 
     bool sniff(String8 *mimeType, float *confidence, sp<AMessage> *meta);
 
     // The sniffer can optionally fill in "meta" with an AMessage containing
     // a dictionary of values that helps the corresponding extractor initialize
     // its state without duplicating effort already exerted by the sniffer.
     typedef bool (*SnifferFunc)(
@@ -87,25 +78,23 @@ public:
     virtual sp<DecryptHandle> DrmInitialization(const char *mime = NULL) {
         return NULL;
     }
     virtual void getDrmInfo(sp<DecryptHandle> &handle, DrmManagerClient **client) {};
 
     virtual String8 getUri() {
         return String8();
     }
+#endif
 
     virtual String8 getMIMEType() const;
 
 protected:
     virtual ~DataSource() {}
 
 private:
-    static Mutex gSnifferMutex;
-    static List<SnifferFunc> gSniffers;
-
     DataSource(const DataSource &);
     DataSource &operator=(const DataSource &);
 };
 
 }  // namespace android
 
 #endif  // DATA_SOURCE_H_
--- a/media/libstagefright/frameworks/av/include/media/stagefright/MediaErrors.h
+++ b/media/libstagefright/frameworks/av/include/media/stagefright/MediaErrors.h
@@ -17,55 +17,53 @@
 #ifndef MEDIA_ERRORS_H_
 
 #define MEDIA_ERRORS_H_
 
 #include <utils/Errors.h>
 
 namespace android {
 
-enum {
-    MEDIA_ERROR_BASE        = -1000,
+#define MEDIA_ERROR_BASE (-1000)
 
-    ERROR_ALREADY_CONNECTED = MEDIA_ERROR_BASE,
-    ERROR_NOT_CONNECTED     = MEDIA_ERROR_BASE - 1,
-    ERROR_UNKNOWN_HOST      = MEDIA_ERROR_BASE - 2,
-    ERROR_CANNOT_CONNECT    = MEDIA_ERROR_BASE - 3,
-    ERROR_IO                = MEDIA_ERROR_BASE - 4,
-    ERROR_CONNECTION_LOST   = MEDIA_ERROR_BASE - 5,
-    ERROR_MALFORMED         = MEDIA_ERROR_BASE - 7,
-    ERROR_OUT_OF_RANGE      = MEDIA_ERROR_BASE - 8,
-    ERROR_BUFFER_TOO_SMALL  = MEDIA_ERROR_BASE - 9,
-    ERROR_UNSUPPORTED       = MEDIA_ERROR_BASE - 10,
-    ERROR_END_OF_STREAM     = MEDIA_ERROR_BASE - 11,
+#define ERROR_ALREADY_CONNECTED (MEDIA_ERROR_BASE)
+#define ERROR_NOT_CONNECTED     (MEDIA_ERROR_BASE - 1)
+#define ERROR_UNKNOWN_HOST      (MEDIA_ERROR_BASE - 2)
+#define ERROR_CANNOT_CONNECT    (MEDIA_ERROR_BASE - 3)
+#define ERROR_IO                (MEDIA_ERROR_BASE - 4)
+#define ERROR_CONNECTION_LOST   (MEDIA_ERROR_BASE - 5)
+#define ERROR_MALFORMED         (MEDIA_ERROR_BASE - 7)
+#define ERROR_OUT_OF_RANGE      (MEDIA_ERROR_BASE - 8)
+#define ERROR_BUFFER_TOO_SMALL  (MEDIA_ERROR_BASE - 9)
+#define ERROR_UNSUPPORTED       (MEDIA_ERROR_BASE - 10)
+#define ERROR_END_OF_STREAM     (MEDIA_ERROR_BASE - 11)
 
-    // Not technically an error.
-    INFO_FORMAT_CHANGED    = MEDIA_ERROR_BASE - 12,
-    INFO_DISCONTINUITY     = MEDIA_ERROR_BASE - 13,
-    INFO_OUTPUT_BUFFERS_CHANGED = MEDIA_ERROR_BASE - 14,
+// Not technically an error.
+#define INFO_FORMAT_CHANGED    (MEDIA_ERROR_BASE - 12)
+#define INFO_DISCONTINUITY     (MEDIA_ERROR_BASE - 13)
+#define INFO_OUTPUT_BUFFERS_CHANGED (MEDIA_ERROR_BASE - 14)
 
-    // The following constant values should be in sync with
-    // drm/drm_framework_common.h
-    DRM_ERROR_BASE = -2000,
+// The following constant values should be in sync with
+// drm/drm_framework_common.h
+#define DRM_ERROR_BASE (-2000)
 
-    ERROR_DRM_UNKNOWN                       = DRM_ERROR_BASE,
-    ERROR_DRM_NO_LICENSE                    = DRM_ERROR_BASE - 1,
-    ERROR_DRM_LICENSE_EXPIRED               = DRM_ERROR_BASE - 2,
-    ERROR_DRM_SESSION_NOT_OPENED            = DRM_ERROR_BASE - 3,
-    ERROR_DRM_DECRYPT_UNIT_NOT_INITIALIZED  = DRM_ERROR_BASE - 4,
-    ERROR_DRM_DECRYPT                       = DRM_ERROR_BASE - 5,
-    ERROR_DRM_CANNOT_HANDLE                 = DRM_ERROR_BASE - 6,
-    ERROR_DRM_TAMPER_DETECTED               = DRM_ERROR_BASE - 7,
-    ERROR_DRM_NOT_PROVISIONED               = DRM_ERROR_BASE - 8,
-    ERROR_DRM_DEVICE_REVOKED                = DRM_ERROR_BASE - 9,
-    ERROR_DRM_RESOURCE_BUSY                 = DRM_ERROR_BASE - 10,
+#define ERROR_DRM_UNKNOWN                       (DRM_ERROR_BASE)
+#define ERROR_DRM_NO_LICENSE                    (DRM_ERROR_BASE - 1)
+#define ERROR_DRM_LICENSE_EXPIRED               (DRM_ERROR_BASE - 2)
+#define ERROR_DRM_SESSION_NOT_OPENED            (DRM_ERROR_BASE - 3)
+#define ERROR_DRM_DECRYPT_UNIT_NOT_INITIALIZED  (DRM_ERROR_BASE - 4)
+#define ERROR_DRM_DECRYPT                       (DRM_ERROR_BASE - 5)
+#define ERROR_DRM_CANNOT_HANDLE                 (DRM_ERROR_BASE - 6)
+#define ERROR_DRM_TAMPER_DETECTED               (DRM_ERROR_BASE - 7)
+#define ERROR_DRM_NOT_PROVISIONED               (DRM_ERROR_BASE - 8)
+#define ERROR_DRM_DEVICE_REVOKED                (DRM_ERROR_BASE - 9)
+#define ERROR_DRM_RESOURCE_BUSY                 (DRM_ERROR_BASE - 10)
 
-    ERROR_DRM_VENDOR_MAX                    = DRM_ERROR_BASE - 500,
-    ERROR_DRM_VENDOR_MIN                    = DRM_ERROR_BASE - 999,
+#define ERROR_DRM_VENDOR_MAX                    (DRM_ERROR_BASE - 500)
+#define ERROR_DRM_VENDOR_MIN                    (DRM_ERROR_BASE - 999)
 
-    // Heartbeat Error Codes
-    HEARTBEAT_ERROR_BASE = -3000,
-    ERROR_HEARTBEAT_TERMINATE_REQUESTED                     = HEARTBEAT_ERROR_BASE,
-};
+// Heartbeat Error Codes
+#define HEARTBEAT_ERROR_BASE (-3000)
+#define ERROR_HEARTBEAT_TERMINATE_REQUESTED     (HEARTBEAT_ERROR_BASE)
 
 }  // namespace android
 
 #endif  // MEDIA_ERRORS_H_
--- a/media/libstagefright/frameworks/av/include/media/stagefright/MediaExtractor.h
+++ b/media/libstagefright/frameworks/av/include/media/stagefright/MediaExtractor.h
@@ -37,28 +37,28 @@ public:
     enum GetTrackMetaDataFlags {
         kIncludeExtensiveMetaData = 1
     };
     virtual sp<MetaData> getTrackMetaData(
             size_t index, uint32_t flags = 0) = 0;
 
     // Return container specific meta-data. The default implementation
     // returns an empty metadata object.
-    virtual sp<MetaData> getMetaData();
+    virtual sp<MetaData> getMetaData() = 0;
 
     enum Flags {
         CAN_SEEK_BACKWARD  = 1,  // the "seek 10secs back button"
         CAN_SEEK_FORWARD   = 2,  // the "seek 10secs forward button"
         CAN_PAUSE          = 4,
         CAN_SEEK           = 8,  // the "seek bar"
     };
 
     // If subclasses do _not_ override this, the default is
     // CAN_SEEK_BACKWARD | CAN_SEEK_FORWARD | CAN_SEEK | CAN_PAUSE
-    virtual uint32_t flags() const;
+    virtual uint32_t flags() const = 0;
 
     // for DRM
     void setDrmFlag(bool flag) {
         mIsDrm = flag;
     };
     bool getDrmFlag() {
         return mIsDrm;
     }
--- a/media/libstagefright/frameworks/av/include/media/stagefright/MetaData.h
+++ b/media/libstagefright/frameworks/av/include/media/stagefright/MetaData.h
@@ -43,16 +43,17 @@ enum {
 
     kKeyRotation          = 'rotA',  // int32_t (angle in degrees)
     kKeyIFramesInterval   = 'ifiv',  // int32_t
     kKeyStride            = 'strd',  // int32_t
     kKeySliceHeight       = 'slht',  // int32_t
     kKeyChannelCount      = '#chn',  // int32_t
     kKeyChannelMask       = 'chnm',  // int32_t
     kKeySampleRate        = 'srte',  // int32_t (audio sampling rate Hz)
+    kKeySampleSize        = 'ssiz',  // int32_t (sample size in bytes)
     kKeyFrameRate         = 'frmR',  // int32_t (video frame rate fps)
     kKeyBitRate           = 'brte',  // int32_t (bps)
     kKeyESDS              = 'esds',  // raw data
     kKeyAACProfile        = 'aacp',  // int32_t
     kKeyAVCC              = 'avcc',  // raw data
     kKeyD263              = 'd263',  // raw data
     kKeyVorbisInfo        = 'vinf',  // raw data
     kKeyVorbisBooks       = 'vboo',  // raw data
--- a/media/libstagefright/frameworks/av/include/media/stagefright/Utils.h
+++ b/media/libstagefright/frameworks/av/include/media/stagefright/Utils.h
@@ -23,17 +23,17 @@
 #include <utils/Errors.h>
 #include <utils/RefBase.h>
 #include <system/audio.h>
 #include <media/MediaPlayerInterface.h>
 
 namespace android {
 
 #define FOURCC(c1, c2, c3, c4) \
-    (c1 << 24 | c2 << 16 | c3 << 8 | c4)
+    ((uint32_t) c1 << 24 | c2 << 16 | c3 << 8 | c4)
 
 uint16_t U16_AT(const uint8_t *ptr);
 uint32_t U32_AT(const uint8_t *ptr);
 uint64_t U64_AT(const uint8_t *ptr);
 
 uint16_t U16LE_AT(const uint8_t *ptr);
 uint32_t U32LE_AT(const uint8_t *ptr);
 uint64_t U64LE_AT(const uint8_t *ptr);
@@ -45,20 +45,11 @@ struct MetaData;
 struct AMessage;
 status_t convertMetaDataToMessage(
         const sp<MetaData> &meta, sp<AMessage> *format);
 void convertMessageToMetaData(
         const sp<AMessage> &format, sp<MetaData> &meta);
 
 AString MakeUserAgent();
 
-// Convert a MIME type to a AudioSystem::audio_format
-status_t mapMimeToAudioFormat(audio_format_t& format, const char* mime);
-
-// Send information from MetaData to the HAL via AudioSink
-status_t sendMetaDataToHal(sp<MediaPlayerBase::AudioSink>& sink, const sp<MetaData>& meta);
-
-// Check whether the stream defined by meta can be offloaded to hardware
-bool canOffloadStream(const sp<MetaData>& meta, bool hasVideo, bool isStreaming);
-
 }  // namespace android
 
 #endif  // UTILS_H_
--- a/media/libstagefright/frameworks/av/media/libstagefright/DataSource.cpp
+++ b/media/libstagefright/frameworks/av/media/libstagefright/DataSource.cpp
@@ -15,38 +15,20 @@
  */
 
 #include "include/AMRExtractor.h"
 
 #if CHROMIUM_AVAILABLE
 #include "include/chromium_http_stub.h"
 #endif
 
-#include "include/AACExtractor.h"
-#include "include/DRMExtractor.h"
-#include "include/FLACExtractor.h"
-#include "include/HTTPBase.h"
-#include "include/MP3Extractor.h"
-#include "include/MPEG2PSExtractor.h"
-#include "include/MPEG2TSExtractor.h"
 #include "include/MPEG4Extractor.h"
-#include "include/NuCachedSource2.h"
-#include "include/OggExtractor.h"
-#include "include/WAVExtractor.h"
-#include "include/WVMExtractor.h"
 
-#include "matroska/MatroskaExtractor.h"
-
-#include <media/stagefright/foundation/AMessage.h>
 #include <media/stagefright/DataSource.h>
-#include <media/stagefright/FileSource.h>
 #include <media/stagefright/MediaErrors.h>
-#include <utils/String8.h>
-
-#include <cutils/properties.h>
 
 namespace android {
 
 bool DataSource::getUInt16(off64_t offset, uint16_t *x) {
     *x = 0;
 
     uint8_t byte[2];
     if (readAt(offset, byte, 2) != 2) {
@@ -100,16 +82,18 @@ bool DataSource::getUInt64(off64_t offse
 status_t DataSource::getSize(off64_t *size) {
     *size = 0;
 
     return ERROR_UNSUPPORTED;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 
+#if 0
+
 Mutex DataSource::gSnifferMutex;
 List<DataSource::SnifferFunc> DataSource::gSniffers;
 
 bool DataSource::sniff(
         String8 *mimeType, float *confidence, sp<AMessage> *meta) {
     *mimeType = "";
     *confidence = 0.0f;
     meta->clear();
@@ -221,13 +205,15 @@ sp<DataSource> DataSource::CreateFromURI
 
     if (source == NULL || source->initCheck() != OK) {
         return NULL;
     }
 
     return source;
 }
 
+#endif
+
 String8 DataSource::getMIMEType() const {
     return String8("application/octet-stream");
 }
 
 }  // namespace android
--- a/media/libstagefright/frameworks/av/media/libstagefright/ESDS.cpp
+++ b/media/libstagefright/frameworks/av/media/libstagefright/ESDS.cpp
@@ -10,16 +10,17 @@
  * 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.
  */
 
 //#define LOG_NDEBUG 0
+#undef LOG_TAG
 #define LOG_TAG "ESDS"
 #include <utils/Log.h>
 
 #include "include/ESDS.h"
 
 #include <string.h>
 
 namespace android {
@@ -220,8 +221,9 @@ status_t ESDS::parseDecoderConfigDescrip
     mDecoderSpecificOffset = sub_offset;
     mDecoderSpecificLength = sub_size;
 
     return OK;
 }
 
 }  // namespace android
 
+#undef LOG_TAG
--- a/media/libstagefright/frameworks/av/media/libstagefright/MPEG4Extractor.cpp
+++ b/media/libstagefright/frameworks/av/media/libstagefright/MPEG4Extractor.cpp
@@ -10,16 +10,17 @@
  * 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.
  */
 
 //#define LOG_NDEBUG 0
+#undef LOG_TAG
 #define LOG_TAG "MPEG4Extractor"
 #include <utils/Log.h>
 
 #include "include/MPEG4Extractor.h"
 #include "include/SampleTable.h"
 #include "include/ESDS.h"
 
 #include <ctype.h>
@@ -1243,16 +1244,17 @@ status_t MPEG4Extractor::parseChunk(off6
             if (chunk_type != FOURCC('e', 'n', 'c', 'a')) {
                 // if the chunk type is enca, we'll get the type from the sinf/frma box later
                 mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type));
                 AdjustChannelsAndRate(chunk_type, &num_channels, &sample_rate);
             }
             ALOGV("*** coding='%s' %d channels, size %d, rate %d\n",
                    chunk, num_channels, sample_size, sample_rate);
             mLastTrack->meta->setInt32(kKeyChannelCount, num_channels);
+            mLastTrack->meta->setInt32(kKeySampleSize, sample_size);
             mLastTrack->meta->setInt32(kKeySampleRate, sample_rate);
 
             off64_t stop_offset = *offset + chunk_size;
             *offset = data_offset + sizeof(buffer);
             while (*offset < stop_offset) {
                 status_t err = parseChunk(offset, depth + 1);
                 if (err != OK) {
                     return err;
@@ -2273,16 +2275,20 @@ status_t MPEG4Extractor::updateAudioTrac
 
     ABitReader br(csd, csd_size);
     uint32_t objectType = br.getBits(5);
 
     if (objectType == 31) {  // AAC-ELD => additional 6 bits
         objectType = 32 + br.getBits(6);
     }
 
+    if (objectType >= 1 && objectType <= 4) {
+      mLastTrack->meta->setInt32(kKeyAACProfile, objectType);
+    }
+
     uint32_t freqIndex = br.getBits(4);
 
     int32_t sampleRate = 0;
     int32_t numChannels = 0;
     if (freqIndex == 15) {
         if (csd_size < 5) {
             return ERROR_MALFORMED;
         }
@@ -3149,16 +3155,17 @@ status_t MPEG4Source::read(
                 mBuffer = NULL;
 
                 return ERROR_IO;
             }
 
             CHECK(mBuffer != NULL);
             mBuffer->set_range(0, size);
             mBuffer->meta_data()->clear();
+            mBuffer->meta_data()->setInt64(kKey64BitFileOffset, offset);
             mBuffer->meta_data()->setInt64(
                     kKeyTime, ((int64_t)cts * 1000000) / mTimescale);
 
             if (targetSampleTimeUs >= 0) {
                 mBuffer->meta_data()->setInt64(
                         kKeyTargetTime, targetSampleTimeUs);
             }
 
@@ -3271,16 +3278,17 @@ status_t MPEG4Source::read(
                 dstOffset += nalLength;
             }
             CHECK_EQ(srcOffset, size);
             CHECK(mBuffer != NULL);
             mBuffer->set_range(0, dstOffset);
         }
 
         mBuffer->meta_data()->clear();
+        mBuffer->meta_data()->setInt64(kKey64BitFileOffset, offset);
         mBuffer->meta_data()->setInt64(
                 kKeyTime, ((int64_t)cts * 1000000) / mTimescale);
 
         if (targetSampleTimeUs >= 0) {
             mBuffer->meta_data()->setInt64(
                     kKeyTargetTime, targetSampleTimeUs);
         }
 
@@ -3621,16 +3629,17 @@ static bool isCompatibleBrand(uint32_t f
         if (kCompatibleBrands[i] == fourcc) {
             return true;
         }
     }
 
     return false;
 }
 
+#if 0
 // Attempt to actually parse the 'ftyp' atom and determine if a suitable
 // compatible brand is present.
 // Also try to identify where this file's metadata ends
 // (end of the 'moov' atom) and report it to the caller as part of
 // the metadata.
 static bool BetterSniffMPEG4(
         const sp<DataSource> &source, String8 *mimeType, float *confidence,
         sp<AMessage> *meta) {
@@ -3751,10 +3760,13 @@ bool SniffMPEG4(
 
     if (LegacySniffMPEG4(source, mimeType, confidence)) {
         ALOGW("Identified supported mpeg4 through LegacySniffMPEG4.");
         return true;
     }
 
     return false;
 }
+#endif
 
 }  // namespace android
+
+#undef LOG_TAG
--- a/media/libstagefright/frameworks/av/media/libstagefright/MediaBufferGroup.cpp
+++ b/media/libstagefright/frameworks/av/media/libstagefright/MediaBufferGroup.cpp
@@ -9,16 +9,17 @@
  *
  * 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.
  */
 
+#undef LOG_TAG
 #define LOG_TAG "MediaBufferGroup"
 #include <utils/Log.h>
 
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/MediaBuffer.h>
 #include <media/stagefright/MediaBufferGroup.h>
 
 namespace android {
@@ -79,8 +80,10 @@ exit:
 }
 
 void MediaBufferGroup::signalBufferReturned(MediaBuffer *) {
     Mutex::Autolock autoLock(mLock);
     mCondition.signal();
 }
 
 }  // namespace android
+
+#undef LOG_TAG
--- a/media/libstagefright/frameworks/av/media/libstagefright/MetaData.cpp
+++ b/media/libstagefright/frameworks/av/media/libstagefright/MetaData.cpp
@@ -10,16 +10,17 @@
  * 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.
  */
 
 //#define LOG_NDEBUG 0
+#undef LOG_TAG
 #define LOG_TAG "MetaData"
 #include <utils/Log.h>
 
 #include <stdlib.h>
 #include <string.h>
 
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/foundation/AString.h>
@@ -347,8 +348,9 @@ void MetaData::dumpToLog() const {
         MakeFourCCString(key, cc);
         const typed_data &item = mItems.valueAt(i);
         ALOGI("%s: %s", cc, item.asString().string());
     }
 }
 
 }  // namespace android
 
+#undef LOG_TAG
--- a/media/libstagefright/frameworks/av/media/libstagefright/SampleIterator.cpp
+++ b/media/libstagefright/frameworks/av/media/libstagefright/SampleIterator.cpp
@@ -9,16 +9,17 @@
  *
  * 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.
  */
 
+#undef LOG_TAG
 #define LOG_TAG "SampleIterator"
 //#define LOG_NDEBUG 0
 #include <utils/Log.h>
 
 #include "include/SampleIterator.h"
 
 #include <arpa/inet.h>
 
@@ -309,8 +310,9 @@ status_t SampleIterator::findSampleTime(
 
     *time += mTable->getCompositionTimeOffset(sampleIndex);
 
     return OK;
 }
 
 }  // namespace android
 
+#undef LOG_TAG
--- a/media/libstagefright/frameworks/av/media/libstagefright/SampleTable.cpp
+++ b/media/libstagefright/frameworks/av/media/libstagefright/SampleTable.cpp
@@ -9,16 +9,17 @@
  *
  * 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.
  */
 
+#undef LOG_TAG
 #define LOG_TAG "SampleTable"
 //#define LOG_NDEBUG 0
 #include <utils/Log.h>
 
 #include "include/SampleTable.h"
 #include "include/SampleIterator.h"
 
 #include <arpa/inet.h>
@@ -824,8 +825,9 @@ status_t SampleTable::getMetaDataForSamp
 }
 
 uint32_t SampleTable::getCompositionTimeOffset(uint32_t sampleIndex) {
     return mCompositionDeltaLookup->getCompositionTimeOffset(sampleIndex);
 }
 
 }  // namespace android
 
+#undef LOG_TAG
--- a/media/libstagefright/frameworks/av/media/libstagefright/Utils.cpp
+++ b/media/libstagefright/frameworks/av/media/libstagefright/Utils.cpp
@@ -10,16 +10,17 @@
  * 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.
  */
 
 //#define LOG_NDEBUG 0
+#undef LOG_TAG
 #define LOG_TAG "Utils"
 #include <utils/Log.h>
 
 #include "include/ESDS.h"
 
 #include <arpa/inet.h>
 #include <cutils/properties.h>
 #include <media/stagefright/foundation/ABuffer.h>
@@ -63,16 +64,17 @@ uint64_t U64LE_AT(const uint8_t *ptr) {
 uint64_t ntoh64(uint64_t x) {
     return ((uint64_t)ntohl(x & 0xffffffff) << 32) | ntohl(x >> 32);
 }
 
 uint64_t hton64(uint64_t x) {
     return ((uint64_t)htonl(x & 0xffffffff) << 32) | htonl(x >> 32);
 }
 
+#if 0
 status_t convertMetaDataToMessage(
         const sp<MetaData> &meta, sp<AMessage> *format) {
     format->clear();
 
     const char *mime;
     CHECK(meta->findCString(kKeyMIMEType, &mime));
 
     sp<AMessage> msg = new AMessage;
@@ -598,10 +600,13 @@ bool canOffloadStream(const sp<MetaData>
     info.has_video = hasVideo;
     info.is_streaming = isStreaming;
 
     // Check if offload is possible for given format, stream type, sample rate,
     // bit rate, duration, video and streaming
     return AudioSystem::isOffloadSupported(info);
 }
 
+#endif
+
 }  // namespace android
 
+#undef LOG_TAG
--- a/media/libstagefright/frameworks/av/media/libstagefright/foundation/ABitReader.cpp
+++ b/media/libstagefright/frameworks/av/media/libstagefright/foundation/ABitReader.cpp
@@ -11,16 +11,17 @@
  * 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 "ABitReader.h"
 
+#include <log/log.h>
 #include <media/stagefright/foundation/ADebug.h>
 
 namespace android {
 
 ABitReader::ABitReader(const uint8_t *data, size_t size)
     : mData(data),
       mSize(size),
       mReservoir(0),
--- a/media/libstagefright/frameworks/av/media/libstagefright/foundation/AString.cpp
+++ b/media/libstagefright/frameworks/av/media/libstagefright/foundation/AString.cpp
@@ -320,17 +320,23 @@ bool AString::endsWith(const char *suffi
     return !strcmp(mData + mSize - suffixLen, suffix);
 }
 
 AString StringPrintf(const char *format, ...) {
     va_list ap;
     va_start(ap, format);
 
     char *buffer;
+#ifdef _MSC_VER
+    int n = vsnprintf(NULL, 0, format, ap);
+    buffer = new char[n+1];
+    vsnprintf(buffer, n+1, format, ap);
+#else
     vasprintf(&buffer, format, ap);
+#endif
 
     va_end(ap);
 
     AString result(buffer);
 
     free(buffer);
     buffer = NULL;
 
--- a/media/libstagefright/frameworks/av/media/libstagefright/foundation/hexdump.cpp
+++ b/media/libstagefright/frameworks/av/media/libstagefright/foundation/hexdump.cpp
@@ -10,16 +10,17 @@
  * 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.
  */
 
 //#define LOG_NDEBUG 0
+#undef LOG_TAG
 #define LOG_TAG "hexdump"
 #include <utils/Log.h>
 
 #include "hexdump.h"
 
 #include "ADebug.h"
 #include "AString.h"
 
@@ -87,8 +88,9 @@ void hexdump(const void *_data, size_t s
         }
 
         offset += 16;
     }
 }
 
 }  // namespace android
 
+#undef LOG_TAG
--- a/media/libstagefright/frameworks/av/media/libstagefright/id3/ID3.cpp
+++ b/media/libstagefright/frameworks/av/media/libstagefright/id3/ID3.cpp
@@ -10,16 +10,17 @@
  * 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.
  */
 
 //#define LOG_NDEBUG 0
+#undef LOG_TAG
 #define LOG_TAG "ID3"
 #include <utils/Log.h>
 
 #include "../include/ID3.h"
 
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/DataSource.h>
 #include <media/stagefright/Utils.h>
@@ -893,8 +894,10 @@ bool ID3::parseV1(const sp<DataSource> &
     } else {
         mVersion = ID3_V1_1;
     }
 
     return true;
 }
 
 }  // namespace android
+
+#undef LOG_TAG
--- a/media/libstagefright/frameworks/av/media/libstagefright/include/SampleIterator.h
+++ b/media/libstagefright/frameworks/av/media/libstagefright/include/SampleIterator.h
@@ -9,16 +9,19 @@
  *
  * 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 SAMPLE_ITERATOR_H_
+#define SAMPLE_ITERATOR_H_
+
 #include <utils/Vector.h>
 
 namespace android {
 
 struct SampleTable;
 
 struct SampleIterator {
     SampleIterator(SampleTable *table);
@@ -68,8 +71,9 @@ private:
     status_t findSampleTime(uint32_t sampleIndex, uint32_t *time);
 
     SampleIterator(const SampleIterator &);
     SampleIterator &operator=(const SampleIterator &);
 };
 
 }  // namespace android
 
+#endif
new file mode 100644
--- /dev/null
+++ b/media/libstagefright/patches/frameworks/av.patch
@@ -0,0 +1,524 @@
+diff --git a/include/media/stagefright/DataSource.h b/include/media/stagefright/DataSource.h
+index 742bc0e..2a5e2f6 100644
+--- a/include/media/stagefright/DataSource.h
++++ b/include/media/stagefright/DataSource.h
+@@ -21,16 +21,10 @@
+ #include <sys/types.h>
+ 
+ #include <media/stagefright/MediaErrors.h>
+-#include <utils/Errors.h>
+-#include <utils/KeyedVector.h>
+-#include <utils/List.h>
+ #include <utils/RefBase.h>
+-#include <utils/threads.h>
+-#include <drm/DrmManagerClient.h>
+ 
+ namespace android {
+ 
+-struct AMessage;
+ class String8;
+ 
+ class DataSource : public RefBase {
+@@ -42,10 +36,6 @@ public:
+         kIsHTTPBasedSource     = 8,
+     };
+ 
+-    static sp<DataSource> CreateFromURI(
+-            const char *uri,
+-            const KeyedVector<String8, String8> *headers = NULL);
+-
+     DataSource() {}
+ 
+     virtual status_t initCheck() const = 0;
+@@ -69,6 +59,7 @@ public:
+         return ERROR_UNSUPPORTED;
+     }
+ 
++#if 0
+     ////////////////////////////////////////////////////////////////////////////
+ 
+     bool sniff(String8 *mimeType, float *confidence, sp<AMessage> *meta);
+@@ -92,6 +83,7 @@ public:
+     virtual String8 getUri() {
+         return String8();
+     }
++#endif
+ 
+     virtual String8 getMIMEType() const;
+ 
+@@ -99,9 +91,6 @@ protected:
+     virtual ~DataSource() {}
+ 
+ private:
+-    static Mutex gSnifferMutex;
+-    static List<SnifferFunc> gSniffers;
+-
+     DataSource(const DataSource &);
+     DataSource &operator=(const DataSource &);
+ };
+diff --git a/include/media/stagefright/MediaErrors.h b/include/media/stagefright/MediaErrors.h
+index 686f286..786522c 100644
+--- a/include/media/stagefright/MediaErrors.h
++++ b/include/media/stagefright/MediaErrors.h
+@@ -22,49 +22,47 @@
+ 
+ namespace android {
+ 
+-enum {
+-    MEDIA_ERROR_BASE        = -1000,
++#define MEDIA_ERROR_BASE (-1000)
+ 
+-    ERROR_ALREADY_CONNECTED = MEDIA_ERROR_BASE,
+-    ERROR_NOT_CONNECTED     = MEDIA_ERROR_BASE - 1,
+-    ERROR_UNKNOWN_HOST      = MEDIA_ERROR_BASE - 2,
+-    ERROR_CANNOT_CONNECT    = MEDIA_ERROR_BASE - 3,
+-    ERROR_IO                = MEDIA_ERROR_BASE - 4,
+-    ERROR_CONNECTION_LOST   = MEDIA_ERROR_BASE - 5,
+-    ERROR_MALFORMED         = MEDIA_ERROR_BASE - 7,
+-    ERROR_OUT_OF_RANGE      = MEDIA_ERROR_BASE - 8,
+-    ERROR_BUFFER_TOO_SMALL  = MEDIA_ERROR_BASE - 9,
+-    ERROR_UNSUPPORTED       = MEDIA_ERROR_BASE - 10,
+-    ERROR_END_OF_STREAM     = MEDIA_ERROR_BASE - 11,
++#define ERROR_ALREADY_CONNECTED (MEDIA_ERROR_BASE)
++#define ERROR_NOT_CONNECTED     (MEDIA_ERROR_BASE - 1)
++#define ERROR_UNKNOWN_HOST      (MEDIA_ERROR_BASE - 2)
++#define ERROR_CANNOT_CONNECT    (MEDIA_ERROR_BASE - 3)
++#define ERROR_IO                (MEDIA_ERROR_BASE - 4)
++#define ERROR_CONNECTION_LOST   (MEDIA_ERROR_BASE - 5)
++#define ERROR_MALFORMED         (MEDIA_ERROR_BASE - 7)
++#define ERROR_OUT_OF_RANGE      (MEDIA_ERROR_BASE - 8)
++#define ERROR_BUFFER_TOO_SMALL  (MEDIA_ERROR_BASE - 9)
++#define ERROR_UNSUPPORTED       (MEDIA_ERROR_BASE - 10)
++#define ERROR_END_OF_STREAM     (MEDIA_ERROR_BASE - 11)
+ 
+-    // Not technically an error.
+-    INFO_FORMAT_CHANGED    = MEDIA_ERROR_BASE - 12,
+-    INFO_DISCONTINUITY     = MEDIA_ERROR_BASE - 13,
+-    INFO_OUTPUT_BUFFERS_CHANGED = MEDIA_ERROR_BASE - 14,
++// Not technically an error.
++#define INFO_FORMAT_CHANGED    (MEDIA_ERROR_BASE - 12)
++#define INFO_DISCONTINUITY     (MEDIA_ERROR_BASE - 13)
++#define INFO_OUTPUT_BUFFERS_CHANGED (MEDIA_ERROR_BASE - 14)
+ 
+-    // The following constant values should be in sync with
+-    // drm/drm_framework_common.h
+-    DRM_ERROR_BASE = -2000,
++// The following constant values should be in sync with
++// drm/drm_framework_common.h
++#define DRM_ERROR_BASE (-2000)
+ 
+-    ERROR_DRM_UNKNOWN                       = DRM_ERROR_BASE,
+-    ERROR_DRM_NO_LICENSE                    = DRM_ERROR_BASE - 1,
+-    ERROR_DRM_LICENSE_EXPIRED               = DRM_ERROR_BASE - 2,
+-    ERROR_DRM_SESSION_NOT_OPENED            = DRM_ERROR_BASE - 3,
+-    ERROR_DRM_DECRYPT_UNIT_NOT_INITIALIZED  = DRM_ERROR_BASE - 4,
+-    ERROR_DRM_DECRYPT                       = DRM_ERROR_BASE - 5,
+-    ERROR_DRM_CANNOT_HANDLE                 = DRM_ERROR_BASE - 6,
+-    ERROR_DRM_TAMPER_DETECTED               = DRM_ERROR_BASE - 7,
+-    ERROR_DRM_NOT_PROVISIONED               = DRM_ERROR_BASE - 8,
+-    ERROR_DRM_DEVICE_REVOKED                = DRM_ERROR_BASE - 9,
+-    ERROR_DRM_RESOURCE_BUSY                 = DRM_ERROR_BASE - 10,
++#define ERROR_DRM_UNKNOWN                       (DRM_ERROR_BASE)
++#define ERROR_DRM_NO_LICENSE                    (DRM_ERROR_BASE - 1)
++#define ERROR_DRM_LICENSE_EXPIRED               (DRM_ERROR_BASE - 2)
++#define ERROR_DRM_SESSION_NOT_OPENED            (DRM_ERROR_BASE - 3)
++#define ERROR_DRM_DECRYPT_UNIT_NOT_INITIALIZED  (DRM_ERROR_BASE - 4)
++#define ERROR_DRM_DECRYPT                       (DRM_ERROR_BASE - 5)
++#define ERROR_DRM_CANNOT_HANDLE                 (DRM_ERROR_BASE - 6)
++#define ERROR_DRM_TAMPER_DETECTED               (DRM_ERROR_BASE - 7)
++#define ERROR_DRM_NOT_PROVISIONED               (DRM_ERROR_BASE - 8)
++#define ERROR_DRM_DEVICE_REVOKED                (DRM_ERROR_BASE - 9)
++#define ERROR_DRM_RESOURCE_BUSY                 (DRM_ERROR_BASE - 10)
+ 
+-    ERROR_DRM_VENDOR_MAX                    = DRM_ERROR_BASE - 500,
+-    ERROR_DRM_VENDOR_MIN                    = DRM_ERROR_BASE - 999,
++#define ERROR_DRM_VENDOR_MAX                    (DRM_ERROR_BASE - 500)
++#define ERROR_DRM_VENDOR_MIN                    (DRM_ERROR_BASE - 999)
+ 
+-    // Heartbeat Error Codes
+-    HEARTBEAT_ERROR_BASE = -3000,
+-    ERROR_HEARTBEAT_TERMINATE_REQUESTED                     = HEARTBEAT_ERROR_BASE,
+-};
++// Heartbeat Error Codes
++#define HEARTBEAT_ERROR_BASE (-3000)
++#define ERROR_HEARTBEAT_TERMINATE_REQUESTED     (HEARTBEAT_ERROR_BASE)
+ 
+ }  // namespace android
+ 
+diff --git a/include/media/stagefright/MediaExtractor.h b/include/media/stagefright/MediaExtractor.h
+index 3076a96..53072e8 100644
+--- a/include/media/stagefright/MediaExtractor.h
++++ b/include/media/stagefright/MediaExtractor.h
+@@ -42,7 +42,7 @@ public:
+ 
+     // Return container specific meta-data. The default implementation
+     // returns an empty metadata object.
+-    virtual sp<MetaData> getMetaData();
++    virtual sp<MetaData> getMetaData() = 0;
+ 
+     enum Flags {
+         CAN_SEEK_BACKWARD  = 1,  // the "seek 10secs back button"
+@@ -53,7 +53,7 @@ public:
+ 
+     // If subclasses do _not_ override this, the default is
+     // CAN_SEEK_BACKWARD | CAN_SEEK_FORWARD | CAN_SEEK | CAN_PAUSE
+-    virtual uint32_t flags() const;
++    virtual uint32_t flags() const = 0;
+ 
+     // for DRM
+     void setDrmFlag(bool flag) {
+diff --git a/include/media/stagefright/MetaData.h b/include/media/stagefright/MetaData.h
+index de3fc36..bebbda6 100644
+--- a/include/media/stagefright/MetaData.h
++++ b/include/media/stagefright/MetaData.h
+@@ -48,6 +48,7 @@ enum {
+     kKeyChannelCount      = '#chn',  // int32_t
+     kKeyChannelMask       = 'chnm',  // int32_t
+     kKeySampleRate        = 'srte',  // int32_t (audio sampling rate Hz)
++    kKeySampleSize        = 'ssiz',  // int32_t (sample size in bytes)
+     kKeyFrameRate         = 'frmR',  // int32_t (video frame rate fps)
+     kKeyBitRate           = 'brte',  // int32_t (bps)
+     kKeyESDS              = 'esds',  // raw data
+diff --git a/include/media/stagefright/Utils.h b/include/media/stagefright/Utils.h
+index c24f612..a580fec 100644
+--- a/include/media/stagefright/Utils.h
++++ b/include/media/stagefright/Utils.h
+@@ -28,7 +28,7 @@
+ namespace android {
+ 
+ #define FOURCC(c1, c2, c3, c4) \
+-    (c1 << 24 | c2 << 16 | c3 << 8 | c4)
++    ((uint32_t) c1 << 24 | c2 << 16 | c3 << 8 | c4)
+ 
+ uint16_t U16_AT(const uint8_t *ptr);
+ uint32_t U32_AT(const uint8_t *ptr);
+@@ -50,15 +50,6 @@ void convertMessageToMetaData(
+ 
+ AString MakeUserAgent();
+ 
+-// Convert a MIME type to a AudioSystem::audio_format
+-status_t mapMimeToAudioFormat(audio_format_t& format, const char* mime);
+-
+-// Send information from MetaData to the HAL via AudioSink
+-status_t sendMetaDataToHal(sp<MediaPlayerBase::AudioSink>& sink, const sp<MetaData>& meta);
+-
+-// Check whether the stream defined by meta can be offloaded to hardware
+-bool canOffloadStream(const sp<MetaData>& meta, bool hasVideo, bool isStreaming);
+-
+ }  // namespace android
+ 
+ #endif  // UTILS_H_
+diff --git a/media/libstagefright/DataSource.cpp b/media/libstagefright/DataSource.cpp
+index fc6fd9c..172bb53 100644
+--- a/media/libstagefright/DataSource.cpp
++++ b/media/libstagefright/DataSource.cpp
+@@ -20,28 +20,10 @@
+ #include "include/chromium_http_stub.h"
+ #endif
+ 
+-#include "include/AACExtractor.h"
+-#include "include/DRMExtractor.h"
+-#include "include/FLACExtractor.h"
+-#include "include/HTTPBase.h"
+-#include "include/MP3Extractor.h"
+-#include "include/MPEG2PSExtractor.h"
+-#include "include/MPEG2TSExtractor.h"
+ #include "include/MPEG4Extractor.h"
+-#include "include/NuCachedSource2.h"
+-#include "include/OggExtractor.h"
+-#include "include/WAVExtractor.h"
+-#include "include/WVMExtractor.h"
+ 
+-#include "matroska/MatroskaExtractor.h"
+-
+-#include <media/stagefright/foundation/AMessage.h>
+ #include <media/stagefright/DataSource.h>
+-#include <media/stagefright/FileSource.h>
+ #include <media/stagefright/MediaErrors.h>
+-#include <utils/String8.h>
+-
+-#include <cutils/properties.h>
+ 
+ namespace android {
+ 
+@@ -105,6 +87,8 @@ status_t DataSource::getSize(off64_t *size) {
+ 
+ ////////////////////////////////////////////////////////////////////////////////
+ 
++#if 0
++
+ Mutex DataSource::gSnifferMutex;
+ List<DataSource::SnifferFunc> DataSource::gSniffers;
+ 
+@@ -226,6 +210,8 @@ sp<DataSource> DataSource::CreateFromURI(
+     return source;
+ }
+ 
++#endif
++
+ String8 DataSource::getMIMEType() const {
+     return String8("application/octet-stream");
+ }
+diff --git a/media/libstagefright/ESDS.cpp b/media/libstagefright/ESDS.cpp
+index 4a0c35c..0366960 100644
+--- a/media/libstagefright/ESDS.cpp
++++ b/media/libstagefright/ESDS.cpp
+@@ -15,6 +15,7 @@
+  */
+ 
+ //#define LOG_NDEBUG 0
++#undef LOG_TAG
+ #define LOG_TAG "ESDS"
+ #include <utils/Log.h>
+ 
+@@ -225,3 +226,4 @@ status_t ESDS::parseDecoderConfigDescriptor(size_t offset, size_t size) {
+ 
+ }  // namespace android
+ 
++#undef LOG_TAG
+diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp
+index ad985ee..17a90cb 100644
+--- a/media/libstagefright/MPEG4Extractor.cpp
++++ b/media/libstagefright/MPEG4Extractor.cpp
+@@ -15,6 +15,7 @@
+  */
+ 
+ //#define LOG_NDEBUG 0
++#undef LOG_TAG
+ #define LOG_TAG "MPEG4Extractor"
+ #include <utils/Log.h>
+ 
+@@ -1248,6 +1249,7 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) {
+             ALOGV("*** coding='%s' %d channels, size %d, rate %d\n",
+                    chunk, num_channels, sample_size, sample_rate);
+             mLastTrack->meta->setInt32(kKeyChannelCount, num_channels);
++            mLastTrack->meta->setInt32(kKeySampleSize, sample_size);
+             mLastTrack->meta->setInt32(kKeySampleRate, sample_rate);
+ 
+             off64_t stop_offset = *offset + chunk_size;
+@@ -2278,6 +2280,10 @@ status_t MPEG4Extractor::updateAudioTrackInfoFromESDS_MPEG4Audio(
+         objectType = 32 + br.getBits(6);
+     }
+ 
++    if (objectType >= 1 && objectType <= 4) {
++      mLastTrack->meta->setInt32(kKeyAACProfile, objectType);
++    }
++
+     uint32_t freqIndex = br.getBits(4);
+ 
+     int32_t sampleRate = 0;
+@@ -3154,6 +3160,7 @@ status_t MPEG4Source::read(
+             CHECK(mBuffer != NULL);
+             mBuffer->set_range(0, size);
+             mBuffer->meta_data()->clear();
++            mBuffer->meta_data()->setInt64(kKey64BitFileOffset, offset);
+             mBuffer->meta_data()->setInt64(
+                     kKeyTime, ((int64_t)cts * 1000000) / mTimescale);
+ 
+@@ -3276,6 +3283,7 @@ status_t MPEG4Source::read(
+         }
+ 
+         mBuffer->meta_data()->clear();
++        mBuffer->meta_data()->setInt64(kKey64BitFileOffset, offset);
+         mBuffer->meta_data()->setInt64(
+                 kKeyTime, ((int64_t)cts * 1000000) / mTimescale);
+ 
+@@ -3626,6 +3634,7 @@ static bool isCompatibleBrand(uint32_t fourcc) {
+     return false;
+ }
+ 
++#if 0
+ // Attempt to actually parse the 'ftyp' atom and determine if a suitable
+ // compatible brand is present.
+ // Also try to identify where this file's metadata ends
+@@ -3756,5 +3765,8 @@ bool SniffMPEG4(
+ 
+     return false;
+ }
++#endif
+ 
+ }  // namespace android
++
++#undef LOG_TAG
+diff --git a/media/libstagefright/MediaBufferGroup.cpp b/media/libstagefright/MediaBufferGroup.cpp
+index 80aae51..1ae12cf 100644
+--- a/media/libstagefright/MediaBufferGroup.cpp
++++ b/media/libstagefright/MediaBufferGroup.cpp
+@@ -14,6 +14,7 @@
+  * limitations under the License.
+  */
+ 
++#undef LOG_TAG
+ #define LOG_TAG "MediaBufferGroup"
+ #include <utils/Log.h>
+ 
+@@ -84,3 +85,5 @@ void MediaBufferGroup::signalBufferReturned(MediaBuffer *) {
+ }
+ 
+ }  // namespace android
++
++#undef LOG_TAG
+diff --git a/media/libstagefright/MetaData.cpp b/media/libstagefright/MetaData.cpp
+index ae6ae2d..050dbac 100644
+--- a/media/libstagefright/MetaData.cpp
++++ b/media/libstagefright/MetaData.cpp
+@@ -15,6 +15,7 @@
+  */
+ 
+ //#define LOG_NDEBUG 0
++#undef LOG_TAG
+ #define LOG_TAG "MetaData"
+ #include <utils/Log.h>
+ 
+@@ -352,3 +353,4 @@ void MetaData::dumpToLog() const {
+ 
+ }  // namespace android
+ 
++#undef LOG_TAG
+diff --git a/media/libstagefright/SampleIterator.cpp b/media/libstagefright/SampleIterator.cpp
+index eae721b..58dbdc3 100644
+--- a/media/libstagefright/SampleIterator.cpp
++++ b/media/libstagefright/SampleIterator.cpp
+@@ -14,6 +14,7 @@
+  * limitations under the License.
+  */
+ 
++#undef LOG_TAG
+ #define LOG_TAG "SampleIterator"
+ //#define LOG_NDEBUG 0
+ #include <utils/Log.h>
+@@ -314,3 +315,4 @@ status_t SampleIterator::findSampleTime(
+ 
+ }  // namespace android
+ 
++#undef LOG_TAG
+diff --git a/media/libstagefright/SampleTable.cpp b/media/libstagefright/SampleTable.cpp
+index d9858d7..8e637fb 100644
+--- a/media/libstagefright/SampleTable.cpp
++++ b/media/libstagefright/SampleTable.cpp
+@@ -14,6 +14,7 @@
+  * limitations under the License.
+  */
+ 
++#undef LOG_TAG
+ #define LOG_TAG "SampleTable"
+ //#define LOG_NDEBUG 0
+ #include <utils/Log.h>
+@@ -829,3 +830,4 @@ uint32_t SampleTable::getCompositionTimeOffset(uint32_t sampleIndex) {
+ 
+ }  // namespace android
+ 
++#undef LOG_TAG
+diff --git a/media/libstagefright/Utils.cpp b/media/libstagefright/Utils.cpp
+index 4db8e80..bdbb000 100644
+--- a/media/libstagefright/Utils.cpp
++++ b/media/libstagefright/Utils.cpp
+@@ -15,6 +15,7 @@
+  */
+ 
+ //#define LOG_NDEBUG 0
++#undef LOG_TAG
+ #define LOG_TAG "Utils"
+ #include <utils/Log.h>
+ 
+@@ -68,6 +69,7 @@ uint64_t hton64(uint64_t x) {
+     return ((uint64_t)htonl(x & 0xffffffff) << 32) | htonl(x >> 32);
+ }
+ 
++#if 0
+ status_t convertMetaDataToMessage(
+         const sp<MetaData> &meta, sp<AMessage> *format) {
+     format->clear();
+@@ -603,5 +605,8 @@ bool canOffloadStream(const sp<MetaData>& meta, bool hasVideo, bool isStreaming)
+     return AudioSystem::isOffloadSupported(info);
+ }
+ 
++#endif
++
+ }  // namespace android
+ 
++#undef LOG_TAG
+diff --git a/media/libstagefright/foundation/ABitReader.cpp b/media/libstagefright/foundation/ABitReader.cpp
+index 5499c32..59330ab 100644
+--- a/media/libstagefright/foundation/ABitReader.cpp
++++ b/media/libstagefright/foundation/ABitReader.cpp
+@@ -16,6 +16,7 @@
+ 
+ #include "ABitReader.h"
+ 
++#include <log/log.h>
+ #include <media/stagefright/foundation/ADebug.h>
+ 
+ namespace android {
+diff --git a/media/libstagefright/foundation/AString.cpp b/media/libstagefright/foundation/AString.cpp
+index dee786d..7f68fd3 100644
+--- a/media/libstagefright/foundation/AString.cpp
++++ b/media/libstagefright/foundation/AString.cpp
+@@ -325,7 +325,13 @@ AString StringPrintf(const char *format, ...) {
+     va_start(ap, format);
+ 
+     char *buffer;
++#ifdef _MSC_VER
++    int n = vsnprintf(NULL, 0, format, ap);
++    buffer = new char[n+1];
++    vsnprintf(buffer, n+1, format, ap);
++#else
+     vasprintf(&buffer, format, ap);
++#endif
+ 
+     va_end(ap);
+ 
+diff --git a/media/libstagefright/foundation/hexdump.cpp b/media/libstagefright/foundation/hexdump.cpp
+index a44d832..e4f25aa 100644
+--- a/media/libstagefright/foundation/hexdump.cpp
++++ b/media/libstagefright/foundation/hexdump.cpp
+@@ -15,6 +15,7 @@
+  */
+ 
+ //#define LOG_NDEBUG 0
++#undef LOG_TAG
+ #define LOG_TAG "hexdump"
+ #include <utils/Log.h>
+ 
+@@ -92,3 +93,4 @@ void hexdump(const void *_data, size_t size, size_t indent, AString *appendTo) {
+ 
+ }  // namespace android
+ 
++#undef LOG_TAG
+diff --git a/media/libstagefright/id3/ID3.cpp b/media/libstagefright/id3/ID3.cpp
+index 34d671a..abe88a4 100644
+--- a/media/libstagefright/id3/ID3.cpp
++++ b/media/libstagefright/id3/ID3.cpp
+@@ -15,6 +15,7 @@
+  */
+ 
+ //#define LOG_NDEBUG 0
++#undef LOG_TAG
+ #define LOG_TAG "ID3"
+ #include <utils/Log.h>
+ 
+@@ -898,3 +899,5 @@ bool ID3::parseV1(const sp<DataSource> &source) {
+ }
+ 
+ }  // namespace android
++
++#undef LOG_TAG
+diff --git a/media/libstagefright/include/SampleIterator.h b/media/libstagefright/include/SampleIterator.h
+index b5a043c..3775d9e 100644
+--- a/media/libstagefright/include/SampleIterator.h
++++ b/media/libstagefright/include/SampleIterator.h
+@@ -14,6 +14,9 @@
+  * limitations under the License.
+  */
+ 
++#ifndef SAMPLE_ITERATOR_H_
++#define SAMPLE_ITERATOR_H_
++
+ #include <utils/Vector.h>
+ 
+ namespace android {
+@@ -73,3 +76,4 @@ private:
+ 
+ }  // namespace android
+ 
++#endif
new file mode 100644
--- /dev/null
+++ b/media/libstagefright/patches/system/core.patch
@@ -0,0 +1,797 @@
+diff --git a/include/cutils/properties.h b/include/cutils/properties.h
+index 2c70165..c380d5d 100644
+--- a/include/cutils/properties.h
++++ b/include/cutils/properties.h
+@@ -19,7 +19,6 @@
+ 
+ #include <sys/cdefs.h>
+ #include <stddef.h>
+-#include <sys/system_properties.h>
+ 
+ #ifdef __cplusplus
+ extern "C" {
+diff --git a/include/log/log.h b/include/log/log.h
+index 7faddea..6131f01 100644
+--- a/include/log/log.h
++++ b/include/log/log.h
+@@ -25,6 +25,16 @@
+ // supports O_APPEND.  These calls have mutex-protected data structures
+ // and so are NOT reentrant.  Do not use LOG in a signal handler.
+ //
++
++/*
++ * This is the local tag used for the following simplified
++ * logging macros.  You can change this preprocessor definition
++ * before using the other macros to change the tag.
++ */
++#ifndef LOG_TAG
++#define LOG_TAG NULL
++#endif
++
+ #ifndef _LIBS_LOG_LOG_H
+ #define _LIBS_LOG_LOG_H
+ 
+@@ -40,6 +50,10 @@
+ #include <log/uio.h>
+ #include <log/logd.h>
+ 
++#ifdef _MSC_VER
++#define __builtin_expect(X, Y) (X)
++#endif
++
+ #ifdef __cplusplus
+ extern "C" {
+ #endif
+@@ -59,15 +73,6 @@ extern "C" {
+ #endif
+ #endif
+ 
+-/*
+- * This is the local tag used for the following simplified
+- * logging macros.  You can change this preprocessor definition
+- * before using the other macros to change the tag.
+- */
+-#ifndef LOG_TAG
+-#define LOG_TAG NULL
+-#endif
+-
+ // ---------------------------------------------------------------------
+ 
+ /*
+@@ -498,11 +503,11 @@ typedef enum {
+  * The stuff in the rest of this file should not be used directly.
+  */
+ 
+-#define android_printLog(prio, tag, fmt...) \
+-    __android_log_print(prio, tag, fmt)
++#define android_printLog(prio, tag, ...) \
++    __android_log_print(prio, tag, __VA_ARGS__)
+ 
+-#define android_vprintLog(prio, cond, tag, fmt...) \
+-    __android_log_vprint(prio, tag, fmt)
++#define android_vprintLog(prio, cond, tag, ...) \
++    __android_log_vprint(prio, tag, __VA_ARGS__)
+ 
+ /* XXX Macros to work around syntax errors in places where format string
+  * arg is not passed to ALOG_ASSERT, LOG_ALWAYS_FATAL or LOG_ALWAYS_FATAL_IF
+@@ -519,9 +524,9 @@ typedef enum {
+  */
+ #define __android_rest(first, ...)               , ## __VA_ARGS__
+ 
+-#define android_printAssert(cond, tag, fmt...) \
++#define android_printAssert(cond, tag, ...) \
+     __android_log_assert(cond, tag, \
+-        __android_second(0, ## fmt, NULL) __android_rest(fmt))
++        __android_second(0, ## __VA_ARGS__, NULL) __android_rest(__VA_ARGS__))
+ 
+ #define android_writeLog(prio, tag, text) \
+     __android_log_write(prio, tag, text)
+diff --git a/include/log/logprint.h b/include/log/logprint.h
+index 481c96e..9b57e0e 100644
+--- a/include/log/logprint.h
++++ b/include/log/logprint.h
+@@ -20,7 +20,6 @@
+ #include <log/log.h>
+ #include <log/logger.h>
+ #include <log/event_tag_map.h>
+-#include <pthread.h>
+ 
+ #ifdef __cplusplus
+ extern "C" {
+diff --git a/include/utils/Condition.h b/include/utils/Condition.h
+index e63ba7e..73fe3fc 100644
+--- a/include/utils/Condition.h
++++ b/include/utils/Condition.h
+@@ -138,6 +138,18 @@ inline void Condition::broadcast() {
+     pthread_cond_broadcast(&mCond);
+ }
+ 
++#else
++
++inline Condition::Condition() {}
++inline Condition::Condition(int type) {}
++inline Condition::~Condition() {}
++inline status_t Condition::wait(Mutex& mutex) { return OK; }
++inline status_t Condition::waitRelative(Mutex& mutex, nsecs_t reltime) {
++    return OK;
++}
++inline void Condition::signal() {}
++inline void Condition::broadcast() {}
++
+ #endif // HAVE_PTHREADS
+ 
+ // ---------------------------------------------------------------------------
+diff --git a/include/utils/List.h b/include/utils/List.h
+index 403cd7f..cf3d10c 100644
+--- a/include/utils/List.h
++++ b/include/utils/List.h
+@@ -56,9 +56,11 @@ protected:
+         inline void setVal(const T& val) { mVal = val; }
+         inline void setPrev(_Node* ptr) { mpPrev = ptr; }
+         inline void setNext(_Node* ptr) { mpNext = ptr; }
++#ifndef _MSC_VER
+     private:
+         friend class List;
+         friend class _ListIterator;
++#endif
+         T           mVal;
+         _Node*      mpPrev;
+         _Node*      mpNext;
+diff --git a/include/utils/Mutex.h b/include/utils/Mutex.h
+index dd201c8..d381805 100644
+--- a/include/utils/Mutex.h
++++ b/include/utils/Mutex.h
+@@ -118,6 +118,17 @@ inline status_t Mutex::tryLock() {
+     return -pthread_mutex_trylock(&mMutex);
+ }
+ 
++#else
++
++inline Mutex::Mutex() {}
++inline Mutex::Mutex(const char* name) {}
++inline Mutex::Mutex(int type, const char* name) {}
++inline Mutex::~Mutex() {}
++inline status_t Mutex::lock() { return OK; }
++inline void Mutex::unlock() {}
++inline status_t Mutex::tryLock() { return OK; }
++inline void Mutex::_init() {}
++
+ #endif // HAVE_PTHREADS
+ 
+ // ---------------------------------------------------------------------------
+diff --git a/include/utils/RefBase.h b/include/utils/RefBase.h
+index cbfe13a..a0baa2c 100644
+--- a/include/utils/RefBase.h
++++ b/include/utils/RefBase.h
+@@ -27,6 +27,10 @@
+ #include <utils/StrongPointer.h>
+ #include <utils/TypeHelpers.h>
+ 
++#ifdef _MSC_VER
++#define __attribute__(X)
++#endif
++
+ // ---------------------------------------------------------------------------
+ namespace android {
+ 
+@@ -541,6 +545,10 @@ void move_backward_type(wp<TYPE>* d, wp<TYPE> const* s, size_t n) {
+ 
+ }; // namespace android
+ 
++#ifdef _MSC_VER
++#undef __attribute__
++#endif
++
+ // ---------------------------------------------------------------------------
+ 
+ #endif // ANDROID_REF_BASE_H
+diff --git a/include/utils/SortedVector.h b/include/utils/SortedVector.h
+index 2d3e82a..450f8f3 100644
+--- a/include/utils/SortedVector.h
++++ b/include/utils/SortedVector.h
+@@ -48,7 +48,6 @@ public:
+     virtual                 ~SortedVector();
+ 
+     /*! copy operator */
+-    const SortedVector<TYPE>&   operator = (const SortedVector<TYPE>& rhs) const;    
+     SortedVector<TYPE>&         operator = (const SortedVector<TYPE>& rhs);    
+ 
+     /*
+@@ -168,12 +167,6 @@ SortedVector<TYPE>& SortedVector<TYPE>::operator = (const SortedVector<TYPE>& rh
+ }
+ 
+ template<class TYPE> inline
+-const SortedVector<TYPE>& SortedVector<TYPE>::operator = (const SortedVector<TYPE>& rhs) const {
+-    SortedVectorImpl::operator = (rhs);
+-    return *this; 
+-}
+-
+-template<class TYPE> inline
+ const TYPE* SortedVector<TYPE>::array() const {
+     return static_cast<const TYPE *>(arrayImpl());
+ }
+diff --git a/include/utils/String8.h b/include/utils/String8.h
+index ef59470..71f7275 100644
+--- a/include/utils/String8.h
++++ b/include/utils/String8.h
+@@ -27,6 +27,10 @@
+ 
+ // ---------------------------------------------------------------------------
+ 
++#ifdef _MSC_VER
++#define __attribute__(X)
++#endif
++
+ namespace android {
+ 
+ class String16;
+@@ -390,6 +394,10 @@ inline String8::operator const char*() const
+ 
+ }  // namespace android
+ 
++#ifdef _MSC_VER
++#undef __attribute__
++#endif
++
+ // ---------------------------------------------------------------------------
+ 
+ #endif // ANDROID_STRING8_H
+diff --git a/include/utils/TypeHelpers.h b/include/utils/TypeHelpers.h
+index 13c9081..e63904a 100644
+--- a/include/utils/TypeHelpers.h
++++ b/include/utils/TypeHelpers.h
+@@ -201,7 +201,7 @@ void move_backward_type(TYPE* d, const TYPE* s, size_t n = 1) {
+     if ((traits<TYPE>::has_trivial_dtor && traits<TYPE>::has_trivial_copy) 
+             || traits<TYPE>::has_trivial_move) 
+     {
+-        memmove(d,s,n*sizeof(TYPE));
++        memmove((void*)d,(void*)s,n*sizeof(TYPE));
+     } else {
+         while (n--) {
+             if (!traits<TYPE>::has_trivial_copy) {
+diff --git a/include/utils/Unicode.h b/include/utils/Unicode.h
+index c8c87c3..b76a5e2 100644
+--- a/include/utils/Unicode.h
++++ b/include/utils/Unicode.h
+@@ -22,9 +22,6 @@
+ 
+ extern "C" {
+ 
+-typedef uint32_t char32_t;
+-typedef uint16_t char16_t;
+-
+ // Standard string functions on char16_t strings.
+ int strcmp16(const char16_t *, const char16_t *);
+ int strncmp16(const char16_t *s1, const char16_t *s2, size_t n);
+diff --git a/include/utils/Vector.h b/include/utils/Vector.h
+index ed7b725..e487b7f 100644
+--- a/include/utils/Vector.h
++++ b/include/utils/Vector.h
+@@ -55,10 +55,8 @@ public:
+     virtual                 ~Vector();
+ 
+     /*! copy operator */
+-            const Vector<TYPE>&     operator = (const Vector<TYPE>& rhs) const;
+             Vector<TYPE>&           operator = (const Vector<TYPE>& rhs);    
+ 
+-            const Vector<TYPE>&     operator = (const SortedVector<TYPE>& rhs) const;
+             Vector<TYPE>&           operator = (const SortedVector<TYPE>& rhs);
+ 
+             /*
+@@ -171,8 +169,12 @@ public:
+      typedef int (*compar_t)(const TYPE* lhs, const TYPE* rhs);
+      typedef int (*compar_r_t)(const TYPE* lhs, const TYPE* rhs, void* state);
+      
+-     inline status_t        sort(compar_t cmp);
+-     inline status_t        sort(compar_r_t cmp, void* state);
++     inline status_t        sort(compar_t cmp) {
++         return VectorImpl::sort((VectorImpl::compar_t)cmp);
++     }
++     inline status_t        sort(compar_r_t cmp, void* state) {
++         return VectorImpl::sort((VectorImpl::compar_r_t)cmp, state);
++     }
+ 
+      // for debugging only
+      inline size_t getItemSize() const { return itemSize(); }
+@@ -247,24 +249,12 @@ Vector<TYPE>& Vector<TYPE>::operator = (const Vector<TYPE>& rhs) {
+ }
+ 
+ template<class TYPE> inline
+-const Vector<TYPE>& Vector<TYPE>::operator = (const Vector<TYPE>& rhs) const {
+-    VectorImpl::operator = (static_cast<const VectorImpl&>(rhs));
+-    return *this;
+-}
+-
+-template<class TYPE> inline
+ Vector<TYPE>& Vector<TYPE>::operator = (const SortedVector<TYPE>& rhs) {
+     VectorImpl::operator = (static_cast<const VectorImpl&>(rhs));
+     return *this;
+ }
+ 
+ template<class TYPE> inline
+-const Vector<TYPE>& Vector<TYPE>::operator = (const SortedVector<TYPE>& rhs) const {
+-    VectorImpl::operator = (rhs);
+-    return *this; 
+-}
+-
+-template<class TYPE> inline
+ const TYPE* Vector<TYPE>::array() const {
+     return static_cast<const TYPE *>(arrayImpl());
+ }
+@@ -373,16 +363,6 @@ ssize_t Vector<TYPE>::removeItemsAt(size_t index, size_t count) {
+     return VectorImpl::removeItemsAt(index, count);
+ }
+ 
+-template<class TYPE> inline
+-status_t Vector<TYPE>::sort(Vector<TYPE>::compar_t cmp) {
+-    return VectorImpl::sort((VectorImpl::compar_t)cmp);
+-}
+-
+-template<class TYPE> inline
+-status_t Vector<TYPE>::sort(Vector<TYPE>::compar_r_t cmp, void* state) {
+-    return VectorImpl::sort((VectorImpl::compar_r_t)cmp, state);
+-}
+-
+ // ---------------------------------------------------------------------------
+ 
+ template<class TYPE>
+diff --git a/liblog/fake_log_device.c b/liblog/fake_log_device.c
+index 5283619..a34838c 100644
+--- a/liblog/fake_log_device.c
++++ b/liblog/fake_log_device.c
+@@ -31,6 +31,34 @@
+ #include <pthread.h>
+ #endif
+ 
++#ifdef _MSC_VER
++#include <io.h>
++#include <process.h>
++#include <nspr/prprf.h>
++#define snprintf PR_snprintf
++
++/* We don't want to indent large blocks because it causes unnecessary merge
++ * conflicts */
++#define UNINDENTED_BLOCK_START {
++#define UNINDENTED_BLOCK_END }
++#else
++#define UNINDENTED_BLOCK_START
++#define UNINDENTED_BLOCK_END
++#endif
++
++#ifdef _MSC_VER
++#include <io.h>
++#include <process.h>
++
++/* We don't want to indent large blocks because it causes unnecessary merge
++ * conflicts */
++#define UNINDENTED_BLOCK_START {
++#define UNINDENTED_BLOCK_END }
++#else
++#define UNINDENTED_BLOCK_START
++#define UNINDENTED_BLOCK_END
++#endif
++
+ #define kMaxTagLen  16      /* from the long-dead utils/Log.cpp */
+ 
+ #define kTagSetSize 16      /* arbitrary */
+@@ -191,6 +219,7 @@ static void configureInitialState(const char* pathName, LogState* logState)
+     /*
+      * This is based on the the long-dead utils/Log.cpp code.
+      */
++    UNINDENTED_BLOCK_START
+     const char* tags = getenv("ANDROID_LOG_TAGS");
+     TRACE("Found ANDROID_LOG_TAGS='%s'\n", tags);
+     if (tags != NULL) {
+@@ -264,11 +293,12 @@ static void configureInitialState(const char* pathName, LogState* logState)
+             }
+         }
+     }
+-
++    UNINDENTED_BLOCK_END
+ 
+     /*
+      * Taken from the long-dead utils/Log.cpp
+      */
++    UNINDENTED_BLOCK_START
+     const char* fstr = getenv("ANDROID_PRINTF_LOG");
+     LogFormat format;
+     if (fstr == NULL) {
+@@ -293,6 +323,7 @@ static void configureInitialState(const char* pathName, LogState* logState)
+     }
+ 
+     logState->outputFormat = format;
++    UNINDENTED_BLOCK_END
+ }
+ 
+ /*
+@@ -321,7 +352,7 @@ static const char* getPriorityString(int priority)
+  */
+ static ssize_t fake_writev(int fd, const struct iovec *iov, int iovcnt) {
+     int result = 0;
+-    struct iovec* end = iov + iovcnt;
++    const struct iovec* end = iov + iovcnt;
+     for (; iov < end; iov++) {
+         int w = write(fd, iov->iov_base, iov->iov_len);
+         if (w != iov->iov_len) {
+@@ -354,7 +385,11 @@ static void showLog(LogState *state,
+     char prefixBuf[128], suffixBuf[128];
+     char priChar;
+     time_t when;
++#ifdef _MSC_VER
++    int pid, tid;
++#else
+     pid_t pid, tid;
++#endif
+ 
+     TRACE("LOG %d: %s %s", logPrio, tag, msg);
+ 
+@@ -382,6 +417,7 @@ static void showLog(LogState *state,
+     /*
+      * Construct a buffer containing the log header and log message.
+      */
++    UNINDENTED_BLOCK_START
+     size_t prefixLen, suffixLen;
+ 
+     switch (state->outputFormat) {
+@@ -431,6 +467,7 @@ static void showLog(LogState *state,
+     /*
+      * Figure out how many lines there will be.
+      */
++    UNINDENTED_BLOCK_START
+     const char* end = msg + strlen(msg);
+     size_t numLines = 0;
+     const char* p = msg;
+@@ -443,7 +480,8 @@ static void showLog(LogState *state,
+      * Create an array of iovecs large enough to write all of
+      * the lines with a prefix and a suffix.
+      */
+-    const size_t INLINE_VECS = 6;
++    UNINDENTED_BLOCK_START
++    #define INLINE_VECS 6
+     const size_t MAX_LINES   = ((size_t)~0)/(3*sizeof(struct iovec*));
+     struct iovec stackVec[INLINE_VECS];
+     struct iovec* vec = stackVec;
+@@ -467,6 +505,7 @@ static void showLog(LogState *state,
+      * Fill in the iovec pointers.
+      */
+     p = msg;
++    UNINDENTED_BLOCK_START
+     struct iovec* v = vec;
+     int totalLen = 0;
+     while (numLines > 0 && p < end) {
+@@ -476,6 +515,7 @@ static void showLog(LogState *state,
+             totalLen += prefixLen;
+             v++;
+         }
++        UNINDENTED_BLOCK_START
+         const char* start = p;
+         while (p < end && *p != '\n') p++;
+         if ((p-start) > 0) {
+@@ -492,6 +532,7 @@ static void showLog(LogState *state,
+             v++;
+         }
+         numLines -= 1;
++        UNINDENTED_BLOCK_END
+     }
+     
+     /*
+@@ -529,6 +570,10 @@ static void showLog(LogState *state,
+     /* if we allocated storage for the iovecs, free it */
+     if (vec != stackVec)
+         free(vec);
++    UNINDENTED_BLOCK_END
++    UNINDENTED_BLOCK_END
++    UNINDENTED_BLOCK_END
++    UNINDENTED_BLOCK_END
+ }
+ 
+ 
+@@ -567,6 +612,7 @@ static ssize_t logWritev(int fd, const struct iovec* vector, int count)
+     }
+ 
+     /* pull out the three fields */
++    UNINDENTED_BLOCK_START
+     int logPrio = *(const char*)vector[0].iov_base;
+     const char* tag = (const char*) vector[1].iov_base;
+     const char* msg = (const char*) vector[2].iov_base;
+@@ -590,6 +636,7 @@ static ssize_t logWritev(int fd, const struct iovec* vector, int count)
+     } else {
+         //TRACE("+++ NOLOG(%d): %s %s", logPrio, tag, msg);
+     }
++    UNINDENTED_BLOCK_END
+ 
+ bail:
+     unlock();
+@@ -683,3 +730,6 @@ ssize_t fakeLogWritev(int fd, const struct iovec* vector, int count)
+     /* Assume that open() was called first. */
+     return redirectWritev(fd, vector, count);
+ }
++
++#undef UNINDENTED_BLOCK_START
++#undef UNINDENTED_BLOCK_END
+diff --git a/liblog/logd_write.c b/liblog/logd_write.c
+index fff7cc4..a194a9c 100644
+--- a/liblog/logd_write.c
++++ b/liblog/logd_write.c
+@@ -33,7 +33,19 @@
+ 
+ #define LOG_BUF_SIZE	1024
+ 
++#ifdef _MSC_VER
++#include <nspr/prprf.h>
++#define snprintf PR_snprintf
++#define __builtin_trap abort
++static int W_OK = 0;
++static int access(char* c, int i) { return -1; }
++#endif
++
+ #if FAKE_LOG_DEVICE
++int fakeLogOpen(const char *pathName, int flags);
++ssize_t fakeLogWritev(int fd, const struct iovec* vector, int count);
++int fakeLogClose(int fd);
++
+ // This will be defined when building for the host.
+ #define log_open(pathname, flags) fakeLogOpen(pathname, flags)
+ #define log_writev(filedes, vector, count) fakeLogWritev(filedes, vector, count)
+@@ -258,7 +270,11 @@ void __android_log_assert(const char *cond, const char *tag,
+ 
+     __android_log_write(ANDROID_LOG_FATAL, tag, buf);
+ 
++#ifdef _MSC_VER
++    abort();
++#else
+     __builtin_trap(); /* trap so we have a chance to debug the situation */
++#endif
+ }
+ 
+ int __android_log_bwrite(int32_t tag, const void *payload, size_t len)
+diff --git a/liblog/logprint.c b/liblog/logprint.c
+index 508c825..6b229df 100644
+--- a/liblog/logprint.c
++++ b/liblog/logprint.c
+@@ -29,6 +29,35 @@
+ #include <log/logd.h>
+ #include <log/logprint.h>
+ 
++#ifdef _MSC_VER
++#include <nspr/prprf.h>
++#define snprintf PR_snprintf
++#define inline
++/* We don't want to indent large blocks because it causes unnecessary merge
++ * conflicts */
++#define UNINDENTED_BLOCK_START {
++#define UNINDENTED_BLOCK_END }
++
++static char *
++strsep(char **stringp, const char *delim)
++{
++    char* res = *stringp;
++    while (**stringp) {
++        const char *c;
++        for (c = delim; *c; c++) {
++            if (**stringp == *c) {
++                **stringp++ = 0;
++                return res;
++            }
++        }
++    }
++    return res;
++}
++#else
++#define UNINDENTED_BLOCK_START
++#define UNINDENTED_BLOCK_END
++#endif
++
+ typedef struct FilterInfo_t {
+     char *mTag;
+     android_LogPriority mPri;
+@@ -268,6 +297,7 @@ int android_log_addFilterRule(AndroidLogFormat *p_format,
+             pri = ANDROID_LOG_VERBOSE;
+         }
+ 
++        UNINDENTED_BLOCK_START
+         char *tagName;
+ 
+ // Presently HAVE_STRNDUP is never defined, so the second case is always taken
+@@ -280,11 +310,14 @@ int android_log_addFilterRule(AndroidLogFormat *p_format,
+         tagName[tagNameLength] = '\0';
+ #endif /*HAVE_STRNDUP*/
+ 
++        UNINDENTED_BLOCK_START
+         FilterInfo *p_fi = filterinfo_new(tagName, pri);
+         free(tagName);
+ 
+         p_fi->p_next = p_format->filters;
+         p_format->filters = p_fi;
++        UNINDENTED_BLOCK_END
++        UNINDENTED_BLOCK_END
+     }
+ 
+     return 0;
+@@ -373,6 +406,7 @@ int android_log_processLogBuffer(struct logger_entry *buf,
+         return -1;
+     }
+ 
++    UNINDENTED_BLOCK_START
+     int msgStart = -1;
+     int msgEnd = -1;
+ 
+@@ -404,6 +438,7 @@ int android_log_processLogBuffer(struct logger_entry *buf,
+     entry->messageLen = msgEnd - msgStart;
+ 
+     return 0;
++    UNINDENTED_BLOCK_END
+ }
+ 
+ /*
+@@ -621,11 +656,7 @@ int android_log_processBinaryLogBuffer(struct logger_entry *buf,
+     eventData += 4;
+     inCount -= 4;
+ 
+-    if (map != NULL) {
+-        entry->tag = android_lookupEventTag(map, tagIndex);
+-    } else {
+-        entry->tag = NULL;
+-    }
++    entry->tag = NULL;
+ 
+     /*
+      * If we don't have a map, or didn't find the tag number in the map,
+@@ -644,6 +675,7 @@ int android_log_processBinaryLogBuffer(struct logger_entry *buf,
+     /*
+      * Format the event log data into the buffer.
+      */
++    UNINDENTED_BLOCK_START
+     char* outBuf = messageBuf;
+     size_t outRemaining = messageBufLen-1;      /* leave one for nul byte */
+     int result;
+@@ -687,6 +719,7 @@ int android_log_processBinaryLogBuffer(struct logger_entry *buf,
+     entry->message = messageBuf;
+ 
+     return 0;
++    UNINDENTED_BLOCK_END
+ }
+ 
+ /**
+@@ -737,6 +770,7 @@ char *android_log_formatLogLine (
+     /*
+      * Construct a buffer containing the log header and log message.
+      */
++    UNINDENTED_BLOCK_START
+     size_t prefixLen, suffixLen;
+ 
+     switch (p_format->format) {
+@@ -807,6 +841,7 @@ char *android_log_formatLogLine (
+ 
+     /* the following code is tragically unreadable */
+ 
++    UNINDENTED_BLOCK_START
+     size_t numLines;
+     size_t i;
+     char *p;
+@@ -882,6 +917,8 @@ char *android_log_formatLogLine (
+     }
+ 
+     return ret;
++    UNINDENTED_BLOCK_END
++    UNINDENTED_BLOCK_END
+ }
+ 
+ /**
+@@ -1014,3 +1051,6 @@ void logprint_run_tests()
+     fprintf(stderr, "tests complete\n");
+ #endif
+ }
++
++#undef UNINDENTED_BLOCK_START
++#undef UNINDENTED_BLOCK_END
+diff --git a/libutils/RefBase.cpp b/libutils/RefBase.cpp
+index f398a82..be0306f 100644
+--- a/libutils/RefBase.cpp
++++ b/libutils/RefBase.cpp
+@@ -20,7 +20,14 @@
+ #include <utils/RefBase.h>
+ 
+ #include <utils/Atomic.h>
++#ifdef _MSC_VER
++class CallStack {
++public:
++    CallStack(int x) {}
++};
++#else
+ #include <utils/CallStack.h>
++#endif
+ #include <utils/Log.h>
+ #include <utils/threads.h>
+ 
+@@ -40,7 +47,7 @@
+ #define DEBUG_REFS_ENABLED_BY_DEFAULT   0
+ 
+ // whether callstack are collected (significantly slows things down)
+-#define DEBUG_REFS_CALLSTACK_ENABLED    1
++#define DEBUG_REFS_CALLSTACK_ENABLED    0
+ 
+ // folder where stack traces are saved when DEBUG_REFS is enabled
+ // this folder needs to exist and be writable
+diff --git a/libutils/String8.cpp b/libutils/String8.cpp
+index e852d77..255dd23 100644
+--- a/libutils/String8.cpp
++++ b/libutils/String8.cpp
+@@ -138,17 +138,8 @@ static char* allocFromUTF32(const char32_t* in, size_t len)
+ // ---------------------------------------------------------------------------
+ 
+ String8::String8()
+-    : mString(getEmptyString())
+-{
+-}
+-
+-String8::String8(StaticLinkage)
+     : mString(0)
+ {
+-    // this constructor is used when we can't rely on the static-initializers
+-    // having run. In this case we always allocate an empty string. It's less
+-    // efficient than using getEmptyString(), but we assume it's uncommon.
+-
+     char* data = static_cast<char*>(
+             SharedBuffer::alloc(sizeof(char))->data());
+     data[0] = 0;
+@@ -324,16 +315,27 @@ status_t String8::appendFormat(const char* fmt, ...)
+ status_t String8::appendFormatV(const char* fmt, va_list args)
+ {
+     int result = NO_ERROR;
++#ifndef _MSC_VER
++    va_list o;
++    va_copy(o, args);
++#endif
+     int n = vsnprintf(NULL, 0, fmt, args);
+     if (n != 0) {
+         size_t oldLength = length();
+         char* buf = lockBuffer(oldLength + n);
+         if (buf) {
++#ifdef _MSC_VER
+             vsnprintf(buf + oldLength, n + 1, fmt, args);
++#else
++            vsnprintf(buf + oldLength, n + 1, fmt, o);
++#endif
+         } else {
+             result = NO_MEMORY;
+         }
+     }
++#ifndef _MSC_VER
++    va_end(o);
++#endif
+     return result;
+ }
+ 
+diff --git a/libutils/Unicode.cpp b/libutils/Unicode.cpp
+index a66e3bb..b8aae5e 100644
+--- a/libutils/Unicode.cpp
++++ b/libutils/Unicode.cpp
+@@ -576,8 +576,8 @@ void utf8_to_utf16(const uint8_t* u8str, size_t u8len, char16_t* u16str) {
+ char16_t* utf8_to_utf16_n(const uint8_t* src, size_t srcLen, char16_t* dst, size_t dstLen) {
+     const uint8_t* const u8end = src + srcLen;
+     const uint8_t* u8cur = src;
+-    const uint16_t* const u16end = dst + dstLen;
+-    char16_t* u16cur = dst;
++    const uint16_t* const u16end = (const uint16_t* const) dst + dstLen;
++    uint16_t* u16cur = (uint16_t*) dst;
+ 
+     while (u8cur < u8end && u16cur < u16end) {
+         size_t u8len = utf8_codepoint_len(*u8cur);
+@@ -593,14 +593,14 @@ char16_t* utf8_to_utf16_n(const uint8_t* src, size_t srcLen, char16_t* dst, size
+             *u16cur++ = (char16_t) ((codepoint >> 10) + 0xD800);
+             if (u16cur >= u16end) {
+                 // Ooops...  not enough room for this surrogate pair.
+-                return u16cur-1;
++                return (char16_t*) u16cur-1;
+             }
+             *u16cur++ = (char16_t) ((codepoint & 0x3FF) + 0xDC00);
+         }
+ 
+         u8cur += u8len;
+     }
+-    return u16cur;
++    return (char16_t*) u16cur;
+ }
+ 
+ }
new file mode 100644
--- /dev/null
+++ b/media/libstagefright/ports/darwin/include/byteswap.h
@@ -0,0 +1,10 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+#ifndef BYTESWAP_H_
+#define BYTESWAP_H_
+
+#include <libkern/OSByteOrder.h>
+#define bswap_16 OSSwapInt16
+
+#endif
new file mode 100644
--- /dev/null
+++ b/media/libstagefright/ports/ics/include/log/log.h
@@ -0,0 +1,1 @@
+#include "android/log.h"
new file mode 100644
--- /dev/null
+++ b/media/libstagefright/ports/ics/include/utils/Condition.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * 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 _LIBS_UTILS_CONDITION_H
+#define _LIBS_UTILS_CONDITION_H
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <time.h>
+
+#include <utils/Errors.h>
+#include <utils/Mutex.h>
+#include <utils/Timers.h>
+
+// ---------------------------------------------------------------------------
+namespace android {
+// ---------------------------------------------------------------------------
+
+/*
+ * Condition variable class.  The implementation is system-dependent.
+ *
+ * Condition variables are paired up with mutexes.  Lock the mutex,
+ * call wait(), then either re-wait() if things aren't quite what you want,
+ * or unlock the mutex and continue.  All threads calling wait() must
+ * use the same mutex for a given Condition.
+ */
+class Condition {
+public:
+    enum {
+        PRIVATE = 0,
+        SHARED = 1
+    };
+
+    enum WakeUpType {
+        WAKE_UP_ONE = 0,
+        WAKE_UP_ALL = 1
+    };
+
+    Condition();
+    Condition(int type);
+    ~Condition();
+    // Wait on the condition variable.  Lock the mutex before calling.
+    status_t wait(Mutex& mutex);
+    // same with relative timeout
+    status_t waitRelative(Mutex& mutex, nsecs_t reltime);
+    // Signal the condition variable, allowing one thread to continue.
+    void signal();
+    // Signal the condition variable, allowing one or all threads to continue.
+    void signal(WakeUpType type) {
+        if (type == WAKE_UP_ONE) {
+            signal();
+        } else {
+            broadcast();
+        }
+    }
+    // Signal the condition variable, allowing all threads to continue.
+    void broadcast();
+};
+
+// ---------------------------------------------------------------------------
+
+inline Condition::Condition() {
+}
+inline Condition::Condition(int type) {
+}
+inline Condition::~Condition() {
+}
+inline status_t Condition::wait(Mutex& mutex) {
+    return OK;
+}
+inline status_t Condition::waitRelative(Mutex& mutex, nsecs_t reltime) {
+    return OK;
+}
+inline void Condition::signal() {
+}
+inline void Condition::broadcast() {
+}
+
+// ---------------------------------------------------------------------------
+}; // namespace android
+// ---------------------------------------------------------------------------
+
+#endif // _LIBS_UTILS_CONDITON_H
new file mode 100644
--- /dev/null
+++ b/media/libstagefright/ports/ics/include/utils/Mutex.h
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * 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 _LIBS_UTILS_MUTEX_H
+#define _LIBS_UTILS_MUTEX_H
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <time.h>
+
+#include <utils/Errors.h>
+
+#ifdef _MSC_VER
+#define __attribute__(X)
+#endif
+
+// ---------------------------------------------------------------------------
+namespace android {
+// ---------------------------------------------------------------------------
+
+class Condition;
+
+/*
+ * Simple mutex class.  The implementation is system-dependent.
+ *
+ * The mutex must be unlocked by the thread that locked it.  They are not
+ * recursive, i.e. the same thread can't lock it multiple times.
+ */
+class Mutex {
+public:
+    enum {
+        PRIVATE = 0,
+        SHARED = 1
+    };
+    
+                Mutex();
+                Mutex(const char* name);
+                Mutex(int type, const char* name = NULL);
+                ~Mutex();
+
+    // lock or unlock the mutex
+    status_t    lock();
+    void        unlock();
+
+    // lock if possible; returns 0 on success, error otherwise
+    status_t    tryLock();
+
+    // Manages the mutex automatically. It'll be locked when Autolock is
+    // constructed and released when Autolock goes out of scope.
+    class Autolock {
+    public:
+        inline Autolock(Mutex& mutex) : mLock(mutex)  { mLock.lock(); }
+        inline Autolock(Mutex* mutex) : mLock(*mutex) { mLock.lock(); }
+        inline ~Autolock() { mLock.unlock(); }
+    private:
+        Mutex& mLock;
+    };
+
+private:
+    friend class Condition;
+    
+    // A mutex cannot be copied
+                Mutex(const Mutex&);
+    Mutex&      operator = (const Mutex&);
+};
+
+// ---------------------------------------------------------------------------
+
+inline Mutex::Mutex() {
+}
+inline Mutex::Mutex(__attribute__((unused)) const char* name) {
+}
+inline Mutex::Mutex(int type, __attribute__((unused)) const char* name) {
+}
+inline Mutex::~Mutex() {
+}
+inline status_t Mutex::lock() {
+  return OK;
+}
+inline void Mutex::unlock() {
+}
+inline status_t Mutex::tryLock() {
+  return OK;
+}
+
+// ---------------------------------------------------------------------------
+
+/*
+ * Automatic mutex.  Declare one of these at the top of a function.
+ * When the function returns, it will go out of scope, and release the
+ * mutex.
+ */
+ 
+typedef Mutex::Autolock AutoMutex;
+
+// ---------------------------------------------------------------------------
+}; // namespace android
+// ---------------------------------------------------------------------------
+
+#ifdef _MSC_VER
+#undef __attribute__
+#endif
+
+#endif // _LIBS_UTILS_MUTEX_H
new file mode 100644
--- /dev/null
+++ b/media/libstagefright/ports/jb/include/log/log.h
@@ -0,0 +1,4 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+#include "android/log.h"
new file mode 100644
--- /dev/null
+++ b/media/libstagefright/ports/win32/include/arpa/inet.h
@@ -0,0 +1,9 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+#ifndef INET_H_
+#define INET_H_
+
+#include <netinet/in.h>
+
+#endif
new file mode 100644
--- /dev/null
+++ b/media/libstagefright/ports/win32/include/byteswap.h
@@ -0,0 +1,10 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+#ifndef BYTESWAP_H_
+#define BYTESWAP_H_
+
+#include <stdlib.h>
+#define bswap_16 _byteswap_ushort
+
+#endif
new file mode 100644
--- /dev/null
+++ b/media/libstagefright/ports/win32/include/netinet/in.h
@@ -0,0 +1,39 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+#ifndef IN_H_
+#define IN_H_
+
+#include <stdint.h>
+
+#if defined(_M_IX86)
+
+static uint32_t
+ntohl(uint32_t x)
+{
+  return x << 24 | (x << 8 & 0xff0000) | (x >> 8 & 0xff00) | x >> 24;
+}
+
+static uint16_t
+ntohs(uint16_t x)
+{
+  return x << 8 | x >> 8;
+}
+
+static uint32_t
+htonl(uint32_t x)
+{
+  return x << 24 | (x << 8 & 0xff0000) | (x >> 8 & 0xff00) | x >> 24;
+}
+
+static uint16_t
+htons(uint16_t x)
+{
+  return x << 8 | x >> 8;
+}
+
+#else
+#error Unsupported architecture
+#endif
+
+#endif
new file mode 100644
--- /dev/null
+++ b/media/libstagefright/ports/win32/include/pthread.h
@@ -0,0 +1,1 @@
+// Intentionally left blank
new file mode 100644
--- /dev/null
+++ b/media/libstagefright/ports/win32/include/stdbool.h
@@ -0,0 +1,1 @@
+// Intentionally left blank
new file mode 100644
--- /dev/null
+++ b/media/libstagefright/ports/win32/include/sys/cdefs.h
@@ -0,0 +1,1 @@
+// Intentionally left blank
new file mode 100644
--- /dev/null
+++ b/media/libstagefright/ports/win32/include/sys/time.h
@@ -0,0 +1,9 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+#ifndef TIME_H_
+#define TIME_H_
+
+#include <time.h>
+
+#endif
new file mode 100644
--- /dev/null
+++ b/media/libstagefright/ports/win32/include/unistd.h
@@ -0,0 +1,1 @@
+// Intentionally left blank
new file mode 100644
new file mode 100644
new file mode 100644
new file mode 100644
new file mode 100644
new file mode 100644
new file mode 100644
new file mode 100644
new file mode 100644
new file mode 100644
--- /dev/null
+++ b/media/libstagefright/stubs/include/cutils/atomic.h
@@ -0,0 +1,51 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+#ifndef ATOMIC_H_
+#define ATOMIC_H_
+
+#include <stdint.h>
+
+// This implements the atomic primatives without any atomicity guarantees. This
+// makes the totally unsafe. However we're only using the demuxer in a single
+// thread.
+
+static inline int32_t
+android_atomic_dec(volatile int32_t* aValue)
+{
+  return (*aValue)--;
+}
+
+static inline int32_t
+android_atomic_inc(volatile int32_t* aValue)
+{
+  return (*aValue)++;
+}
+
+static inline int32_t
+android_atomic_or(int32_t aModifier, volatile int32_t* aValue)
+{
+  int32_t ret = *aValue;
+  *aValue |= aModifier;
+  return ret;
+}
+
+static inline int32_t
+android_atomic_add(int32_t aModifier, volatile int32_t* aValue)
+{
+  int32_t ret = *aValue;
+  *aValue += aModifier;
+  return ret;
+}
+
+static inline int32_t
+android_atomic_cmpxchg(int32_t aOld, int32_t aNew, volatile int32_t* aValue)
+{
+  if (*aValue == aOld)
+  {
+    return *aValue = aNew;
+  }
+  return aOld;
+}
+
+#endif
new file mode 100644
--- /dev/null
+++ b/media/libstagefright/stubs/include/media/stagefright/foundation/AMessage.h
@@ -0,0 +1,16 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+#ifndef A_MESSAGE_H_
+#define A_MESSAGE_H_
+
+namespace android {
+
+struct AMessage : public RefBase {
+public:
+    void post() {}
+};
+
+}
+
+#endif
new file mode 100644
--- /dev/null
+++ b/media/libstagefright/stubs/include/sys/atomics.h
@@ -0,0 +1,10 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+#ifndef ATOMICS_H_
+#define ATOMICS_H_
+
+#define __atomic_dec android_atomic_dec
+#define __atomic_inc android_atomic_inc
+
+#endif
new file mode 100644
--- /dev/null
+++ b/media/libstagefright/stubs/include/ui/GraphicBuffer.h
@@ -0,0 +1,14 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+#ifndef GRAPHIC_BUFFER_H_
+#define GRAPHIC_BUFFER_H_
+
+namespace android {
+
+class GraphicBuffer : public RefBase {
+};
+
+}
+
+#endif
new file mode 100644
--- /dev/null
+++ b/media/libstagefright/stubs/include/utils/threads.h
@@ -0,0 +1,5 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+#include <utils/Condition.h>
+#include <utils/Mutex.h>
--- a/media/libstagefright/system/core/include/cutils/properties.h
+++ b/media/libstagefright/system/core/include/cutils/properties.h
@@ -14,17 +14,16 @@
  * limitations under the License.
  */
 
 #ifndef __CUTILS_PROPERTIES_H
 #define __CUTILS_PROPERTIES_H
 
 #include <sys/cdefs.h>
 #include <stddef.h>
-#include <sys/system_properties.h>
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
 /* System properties are *small* name value pairs managed by the
 ** property service.  If your data doesn't fit in the provided
 ** space it is not appropriate for a system property.
--- a/media/libstagefright/system/core/include/log/log.h
+++ b/media/libstagefright/system/core/include/log/log.h
@@ -20,31 +20,45 @@
 // We'd like these to be available from C code (in case we import some from
 // somewhere), so this has a C interface.
 //
 // The output will be correct when the log file is shared between multiple
 // threads and/or multiple processes so long as the operating system
 // supports O_APPEND.  These calls have mutex-protected data structures
 // and so are NOT reentrant.  Do not use LOG in a signal handler.
 //
+
+/*
+ * This is the local tag used for the following simplified
+ * logging macros.  You can change this preprocessor definition
+ * before using the other macros to change the tag.
+ */
+#ifndef LOG_TAG
+#define LOG_TAG NULL
+#endif
+
 #ifndef _LIBS_LOG_LOG_H
 #define _LIBS_LOG_LOG_H
 
 #include <stdio.h>
 #include <time.h>
 #include <sys/types.h>
 #include <unistd.h>
 #ifdef HAVE_PTHREADS
 #include <pthread.h>
 #endif
 #include <stdarg.h>
 
 #include <log/uio.h>
 #include <log/logd.h>
 
+#ifdef _MSC_VER
+#define __builtin_expect(X, Y) (X)
+#endif
+
 #ifdef __cplusplus
 extern "C" {
 #endif
 
 // ---------------------------------------------------------------------
 
 /*
  * Normally we strip ALOGV (VERBOSE messages) from release builds.
@@ -54,25 +68,16 @@ extern "C" {
 #ifndef LOG_NDEBUG
 #ifdef NDEBUG
 #define LOG_NDEBUG 1
 #else
 #define LOG_NDEBUG 0
 #endif
 #endif
 
-/*
- * This is the local tag used for the following simplified
- * logging macros.  You can change this preprocessor definition
- * before using the other macros to change the tag.
- */
-#ifndef LOG_TAG
-#define LOG_TAG NULL
-#endif
-
 // ---------------------------------------------------------------------
 
 /*
  * Simplified macro to send a verbose log message using the current LOG_TAG.
  */
 #ifndef ALOGV
 #if LOG_NDEBUG
 #define ALOGV(...)   ((void)0)
@@ -493,40 +498,40 @@ typedef enum {
 /* TODO: something for LIST */
 
 /*
  * ===========================================================================
  *
  * The stuff in the rest of this file should not be used directly.
  */
 
-#define android_printLog(prio, tag, fmt...) \
-    __android_log_print(prio, tag, fmt)
+#define android_printLog(prio, tag, ...) \
+    __android_log_print(prio, tag, __VA_ARGS__)
 
-#define android_vprintLog(prio, cond, tag, fmt...) \
-    __android_log_vprint(prio, tag, fmt)
+#define android_vprintLog(prio, cond, tag, ...) \
+    __android_log_vprint(prio, tag, __VA_ARGS__)
 
 /* XXX Macros to work around syntax errors in places where format string
  * arg is not passed to ALOG_ASSERT, LOG_ALWAYS_FATAL or LOG_ALWAYS_FATAL_IF
  * (happens only in debug builds).
  */
 
 /* Returns 2nd arg.  Used to substitute default value if caller's vararg list
  * is empty.
  */
 #define __android_second(dummy, second, ...)     second
 
 /* If passed multiple args, returns ',' followed by all but 1st arg, otherwise
  * returns nothing.
  */
 #define __android_rest(first, ...)               , ## __VA_ARGS__
 
-#define android_printAssert(cond, tag, fmt...) \
+#define android_printAssert(cond, tag, ...) \
     __android_log_assert(cond, tag, \
-        __android_second(0, ## fmt, NULL) __android_rest(fmt))
+        __android_second(0, ## __VA_ARGS__, NULL) __android_rest(__VA_ARGS__))
 
 #define android_writeLog(prio, tag, text) \
     __android_log_write(prio, tag, text)
 
 #define android_bWriteLog(tag, payload, len) \
     __android_log_bwrite(tag, payload, len)
 #define android_btWriteLog(tag, type, payload, len) \
     __android_log_btwrite(tag, type, payload, len)
--- a/media/libstagefright/system/core/include/log/logprint.h
+++ b/media/libstagefright/system/core/include/log/logprint.h
@@ -15,17 +15,16 @@
  */
 
 #ifndef _LOGPRINT_H
 #define _LOGPRINT_H
 
 #include <log/log.h>
 #include <log/logger.h>
 #include <log/event_tag_map.h>
-#include <pthread.h>
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
 typedef enum {
     FORMAT_OFF = 0,
     FORMAT_BRIEF,
--- a/media/libstagefright/system/core/include/utils/Condition.h
+++ b/media/libstagefright/system/core/include/utils/Condition.h
@@ -133,15 +133,27 @@ inline status_t Condition::waitRelative(
 }
 inline void Condition::signal() {
     pthread_cond_signal(&mCond);
 }
 inline void Condition::broadcast() {
     pthread_cond_broadcast(&mCond);
 }
 
+#else
+
+inline Condition::Condition() {}
+inline Condition::Condition(int type) {}
+inline Condition::~Condition() {}
+inline status_t Condition::wait(Mutex& mutex) { return OK; }
+inline status_t Condition::waitRelative(Mutex& mutex, nsecs_t reltime) {
+    return OK;
+}
+inline void Condition::signal() {}
+inline void Condition::broadcast() {}
+
 #endif // HAVE_PTHREADS
 
 // ---------------------------------------------------------------------------
 }; // namespace android
 // ---------------------------------------------------------------------------
 
 #endif // _LIBS_UTILS_CONDITON_H
--- a/media/libstagefright/system/core/include/utils/List.h
+++ b/media/libstagefright/system/core/include/utils/List.h
@@ -51,19 +51,21 @@ protected:
         ~_Node() {}
         inline T& getRef() { return mVal; }
         inline const T& getRef() const { return mVal; }
         inline _Node* getPrev() const { return mpPrev; }
         inline _Node* getNext() const { return mpNext; }
         inline void setVal(const T& val) { mVal = val; }
         inline void setPrev(_Node* ptr) { mpPrev = ptr; }
         inline void setNext(_Node* ptr) { mpNext = ptr; }
+#ifndef _MSC_VER
     private:
         friend class List;
         friend class _ListIterator;
+#endif
         T           mVal;
         _Node*      mpPrev;
         _Node*      mpNext;
     };
 
     /*
      * Iterator for walking through the list.
      */
--- a/media/libstagefright/system/core/include/utils/Mutex.h
+++ b/media/libstagefright/system/core/include/utils/Mutex.h
@@ -113,16 +113,27 @@ inline status_t Mutex::lock() {
 }
 inline void Mutex::unlock() {
     pthread_mutex_unlock(&mMutex);
 }
 inline status_t Mutex::tryLock() {
     return -pthread_mutex_trylock(&mMutex);
 }
 
+#else
+
+inline Mutex::Mutex() {}
+inline Mutex::Mutex(const char* name) {}
+inline Mutex::Mutex(int type, const char* name) {}
+inline Mutex::~Mutex() {}
+inline status_t Mutex::lock() { return OK; }
+inline void Mutex::unlock() {}
+inline status_t Mutex::tryLock() { return OK; }
+inline void Mutex::_init() {}
+
 #endif // HAVE_PTHREADS
 
 // ---------------------------------------------------------------------------
 
 /*
  * Automatic mutex.  Declare one of these at the top of a function.
  * When the function returns, it will go out of scope, and release the
  * mutex.
--- a/media/libstagefright/system/core/include/utils/RefBase.h
+++ b/media/libstagefright/system/core/include/utils/RefBase.h
@@ -22,16 +22,20 @@
 #include <stdint.h>
 #include <sys/types.h>
 #include <stdlib.h>
 #include <string.h>
 
 #include <utils/StrongPointer.h>
 #include <utils/TypeHelpers.h>
 
+#ifdef _MSC_VER
+#define __attribute__(X)
+#endif
+
 // ---------------------------------------------------------------------------
 namespace android {
 
 class TextOutput;
 TextOutput& printWeakPointer(TextOutput& to, const void* val);
 
 // ---------------------------------------------------------------------------
 
@@ -536,11 +540,15 @@ void move_forward_type(wp<TYPE>* d, wp<T
 template<typename TYPE> inline
 void move_backward_type(wp<TYPE>* d, wp<TYPE> const* s, size_t n) {
     ReferenceMover::move_references(d, s, n);
 }
 
 
 }; // namespace android
 
+#ifdef _MSC_VER
+#undef __attribute__
+#endif
+
 // ---------------------------------------------------------------------------
 
 #endif // ANDROID_REF_BASE_H
--- a/media/libstagefright/system/core/include/utils/SortedVector.h
+++ b/media/libstagefright/system/core/include/utils/SortedVector.h
@@ -43,17 +43,16 @@ public:
      * Constructors and destructors
      */
     
                             SortedVector();
                             SortedVector(const SortedVector<TYPE>& rhs);
     virtual                 ~SortedVector();
 
     /*! copy operator */
-    const SortedVector<TYPE>&   operator = (const SortedVector<TYPE>& rhs) const;    
     SortedVector<TYPE>&         operator = (const SortedVector<TYPE>& rhs);    
 
     /*
      * empty the vector
      */
 
     inline  void            clear()             { VectorImpl::clear(); }
 
@@ -163,22 +162,16 @@ SortedVector<TYPE>::~SortedVector() {
 
 template<class TYPE> inline
 SortedVector<TYPE>& SortedVector<TYPE>::operator = (const SortedVector<TYPE>& rhs) {
     SortedVectorImpl::operator = (rhs);
     return *this; 
 }
 
 template<class TYPE> inline
-const SortedVector<TYPE>& SortedVector<TYPE>::operator = (const SortedVector<TYPE>& rhs) const {
-    SortedVectorImpl::operator = (rhs);
-    return *this; 
-}
-
-template<class TYPE> inline
 const TYPE* SortedVector<TYPE>::array() const {
     return static_cast<const TYPE *>(arrayImpl());
 }
 
 template<class TYPE> inline
 TYPE* SortedVector<TYPE>::editArray() {
     return static_cast<TYPE *>(editArrayImpl());
 }
--- a/media/libstagefright/system/core/include/utils/String8.h
+++ b/media/libstagefright/system/core/include/utils/String8.h
@@ -22,16 +22,20 @@
 #include <utils/Unicode.h>
 #include <utils/TypeHelpers.h>
 
 #include <string.h> // for strcmp
 #include <stdarg.h>
 
 // ---------------------------------------------------------------------------
 
+#ifdef _MSC_VER
+#define __attribute__(X)
+#endif
+
 namespace android {
 
 class String16;
 class TextOutput;
 
 //! This is a string holding UTF-8 characters. Does not allow the value more
 // than 0x10FFFF, which is not valid unicode codepoint.
 class String8
@@ -385,11 +389,15 @@ inline bool String8::operator>(const cha
 
 inline String8::operator const char*() const
 {
     return mString;
 }
 
 }  // namespace android
 
+#ifdef _MSC_VER
+#undef __attribute__
+#endif
+
 // ---------------------------------------------------------------------------
 
 #endif // ANDROID_STRING8_H
--- a/media/libstagefright/system/core/include/utils/TypeHelpers.h
+++ b/media/libstagefright/system/core/include/utils/TypeHelpers.h
@@ -196,17 +196,17 @@ void move_forward_type(TYPE* d, const TY
     }
 }
 
 template<typename TYPE> inline
 void move_backward_type(TYPE* d, const TYPE* s, size_t n = 1) {
     if ((traits<TYPE>::has_trivial_dtor && traits<TYPE>::has_trivial_copy) 
             || traits<TYPE>::has_trivial_move) 
     {
-        memmove(d,s,n*sizeof(TYPE));
+        memmove((void*)d,(void*)s,n*sizeof(TYPE));
     } else {
         while (n--) {
             if (!traits<TYPE>::has_trivial_copy) {
                 new(d) TYPE(*s);
             } else {
                 *d = *s;   
             }
             if (!traits<TYPE>::has_trivial_dtor) {
--- a/media/libstagefright/system/core/include/utils/Unicode.h
+++ b/media/libstagefright/system/core/include/utils/Unicode.h
@@ -17,19 +17,16 @@
 #ifndef ANDROID_UNICODE_H
 #define ANDROID_UNICODE_H
 
 #include <sys/types.h>
 #include <stdint.h>
 
 extern "C" {
 
-typedef uint32_t char32_t;
-typedef uint16_t char16_t;
-
 // Standard string functions on char16_t strings.
 int strcmp16(const char16_t *, const char16_t *);
 int strncmp16(const char16_t *s1, const char16_t *s2, size_t n);
 size_t strlen16(const char16_t *);
 size_t strnlen16(const char16_t *, size_t);
 char16_t *strcpy16(char16_t *, const char16_t *);
 char16_t *strncpy16(char16_t *, const char16_t *, size_t);
 
--- a/media/libstagefright/system/core/include/utils/Vector.h
+++ b/media/libstagefright/system/core/include/utils/Vector.h
@@ -50,20 +50,18 @@ public:
      */
     
                             Vector();
                             Vector(const Vector<TYPE>& rhs);
     explicit                Vector(const SortedVector<TYPE>& rhs);
     virtual                 ~Vector();
 
     /*! copy operator */
-            const Vector<TYPE>&     operator = (const Vector<TYPE>& rhs) const;
             Vector<TYPE>&           operator = (const Vector<TYPE>& rhs);    
 
-            const Vector<TYPE>&     operator = (const SortedVector<TYPE>& rhs) const;
             Vector<TYPE>&           operator = (const SortedVector<TYPE>& rhs);
 
             /*
      * empty the vector
      */
 
     inline  void            clear()             { VectorImpl::clear(); }
 
@@ -166,18 +164,22 @@ public:
 
     /*!
      * sort (stable) the array
      */
      
      typedef int (*compar_t)(const TYPE* lhs, const TYPE* rhs);
      typedef int (*compar_r_t)(const TYPE* lhs, const TYPE* rhs, void* state);
      
-     inline status_t        sort(compar_t cmp);
-     inline status_t        sort(compar_r_t cmp, void* state);
+     inline status_t        sort(compar_t cmp) {
+         return VectorImpl::sort((VectorImpl::compar_t)cmp);
+     }
+     inline status_t        sort(compar_r_t cmp, void* state) {
+         return VectorImpl::sort((VectorImpl::compar_r_t)cmp, state);
+     }
 
      // for debugging only
      inline size_t getItemSize() const { return itemSize(); }
 
 
      /*
       * these inlines add some level of compatibility with STL. eventually
       * we should probably turn things around.
@@ -242,34 +244,22 @@ Vector<TYPE>::~Vector() {
 
 template<class TYPE> inline
 Vector<TYPE>& Vector<TYPE>::operator = (const Vector<TYPE>& rhs) {
     VectorImpl::operator = (rhs);
     return *this; 
 }
 
 template<class TYPE> inline
-const Vector<TYPE>& Vector<TYPE>::operator = (const Vector<TYPE>& rhs) const {
-    VectorImpl::operator = (static_cast<const VectorImpl&>(rhs));
-    return *this;
-}
-
-template<class TYPE> inline
 Vector<TYPE>& Vector<TYPE>::operator = (const SortedVector<TYPE>& rhs) {
     VectorImpl::operator = (static_cast<const VectorImpl&>(rhs));
     return *this;
 }
 
 template<class TYPE> inline
-const Vector<TYPE>& Vector<TYPE>::operator = (const SortedVector<TYPE>& rhs) const {
-    VectorImpl::operator = (rhs);
-    return *this; 
-}
-
-template<class TYPE> inline
 const TYPE* Vector<TYPE>::array() const {
     return static_cast<const TYPE *>(arrayImpl());
 }
 
 template<class TYPE> inline
 TYPE* Vector<TYPE>::editArray() {
     return static_cast<TYPE *>(editArrayImpl());
 }
@@ -368,26 +358,16 @@ ssize_t Vector<TYPE>::replaceAt(size_t i
     return VectorImpl::replaceAt(index);
 }
 
 template<class TYPE> inline
 ssize_t Vector<TYPE>::removeItemsAt(size_t index, size_t count) {
     return VectorImpl::removeItemsAt(index, count);
 }
 
-template<class TYPE> inline
-status_t Vector<TYPE>::sort(Vector<TYPE>::compar_t cmp) {
-    return VectorImpl::sort((VectorImpl::compar_t)cmp);
-}
-
-template<class TYPE> inline
-status_t Vector<TYPE>::sort(Vector<TYPE>::compar_r_t cmp, void* state) {
-    return VectorImpl::sort((VectorImpl::compar_r_t)cmp, state);
-}
-
 // ---------------------------------------------------------------------------
 
 template<class TYPE>
 void Vector<TYPE>::do_construct(void* storage, size_t num) const {
     construct_type( reinterpret_cast<TYPE*>(storage), num );
 }
 
 template<class TYPE>
--- a/media/libstagefright/system/core/liblog/fake_log_device.c
+++ b/media/libstagefright/system/core/liblog/fake_log_device.c
@@ -26,16 +26,44 @@
 #include <ctype.h>
 #include <errno.h>
 #include <fcntl.h>
 
 #ifdef HAVE_PTHREADS
 #include <pthread.h>
 #endif
 
+#ifdef _MSC_VER
+#include <io.h>
+#include <process.h>
+#include <nspr/prprf.h>
+#define snprintf PR_snprintf
+
+/* We don't want to indent large blocks because it causes unnecessary merge
+ * conflicts */
+#define UNINDENTED_BLOCK_START {
+#define UNINDENTED_BLOCK_END }
+#else
+#define UNINDENTED_BLOCK_START
+#define UNINDENTED_BLOCK_END
+#endif
+
+#ifdef _MSC_VER
+#include <io.h>
+#include <process.h>
+
+/* We don't want to indent large blocks because it causes unnecessary merge
+ * conflicts */
+#define UNINDENTED_BLOCK_START {
+#define UNINDENTED_BLOCK_END }
+#else
+#define UNINDENTED_BLOCK_START
+#define UNINDENTED_BLOCK_END
+#endif
+
 #define kMaxTagLen  16      /* from the long-dead utils/Log.cpp */
 
 #define kTagSetSize 16      /* arbitrary */
 
 #if 0
 #define TRACE(...) printf("fake_log_device: " __VA_ARGS__)
 #else
 #define TRACE(...) ((void)0)
@@ -186,16 +214,17 @@ static void configureInitialState(const 
     }
 
     /* global min priority defaults to "info" level */
     logState->globalMinPriority = ANDROID_LOG_INFO;
 
     /*
      * This is based on the the long-dead utils/Log.cpp code.
      */
+    UNINDENTED_BLOCK_START
     const char* tags = getenv("ANDROID_LOG_TAGS");
     TRACE("Found ANDROID_LOG_TAGS='%s'\n", tags);
     if (tags != NULL) {
         int entry = 0;
 
         while (*tags != '\0') {
             char tagName[kMaxTagLen];
             int i, minPrio;
@@ -259,21 +288,22 @@ static void configureInitialState(const 
                 TRACE("+++ entry %d: %s:%d\n",
                     entry,
                     logState->tagSet[entry].tag,
                     logState->tagSet[entry].minPriority);
                 entry++;
             }
         }
     }
-
+    UNINDENTED_BLOCK_END
 
     /*
      * Taken from the long-dead utils/Log.cpp
      */
+    UNINDENTED_BLOCK_START
     const char* fstr = getenv("ANDROID_PRINTF_LOG");
     LogFormat format;
     if (fstr == NULL) {
         format = FORMAT_BRIEF;
     } else {
         if (strcmp(fstr, "brief") == 0)
             format = FORMAT_BRIEF;
         else if (strcmp(fstr, "process") == 0)
@@ -288,16 +318,17 @@ static void configureInitialState(const 
             format = FORMAT_PROCESS;
         else if (strcmp(fstr, "long") == 0)
             format = FORMAT_PROCESS;
         else
             format = (LogFormat) atoi(fstr);        // really?!
     }
 
     logState->outputFormat = format;
+    UNINDENTED_BLOCK_END
 }
 
 /*
  * Return a human-readable string for the priority level.  Always returns
  * a valid string.
  */
 static const char* getPriorityString(int priority)
 {
@@ -316,17 +347,17 @@ static const char* getPriorityString(int
 
 #ifndef HAVE_WRITEV
 /*
  * Some platforms like WIN32 do not have writev().
  * Make up something to replace it.
  */
 static ssize_t fake_writev(int fd, const struct iovec *iov, int iovcnt) {
     int result = 0;
-    struct iovec* end = iov + iovcnt;
+    const struct iovec* end = iov + iovcnt;
     for (; iov < end; iov++) {
         int w = write(fd, iov->iov_base, iov->iov_len);
         if (w != iov->iov_len) {
             if (w < 0)
                 return w;
             return result + w;
         }
         result += w;
@@ -349,17 +380,21 @@ static void showLog(LogState *state,
 #if defined(HAVE_LOCALTIME_R)
     struct tm tmBuf;
 #endif
     struct tm* ptm;
     char timeBuf[32];
     char prefixBuf[128], suffixBuf[128];
     char priChar;
     time_t when;
+#ifdef _MSC_VER
+    int pid, tid;
+#else
     pid_t pid, tid;
+#endif
 
     TRACE("LOG %d: %s %s", logPrio, tag, msg);
 
     priChar = getPriorityString(logPrio)[0];
     when = time(NULL);
     pid = tid = getpid();       // find gettid()?
 
     /*
@@ -377,16 +412,17 @@ static void showLog(LogState *state,
     ptm = localtime(&when);
 #endif
     //strftime(timeBuf, sizeof(timeBuf), "%Y-%m-%d %H:%M:%S", ptm);
     strftime(timeBuf, sizeof(timeBuf), "%m-%d %H:%M:%S", ptm);
 
     /*
      * Construct a buffer containing the log header and log message.
      */
+    UNINDENTED_BLOCK_START
     size_t prefixLen, suffixLen;
 
     switch (state->outputFormat) {
     case FORMAT_TAG:
         prefixLen = snprintf(prefixBuf, sizeof(prefixBuf),
             "%c/%-8s: ", priChar, tag);
         strcpy(suffixBuf, "\n"); suffixLen = 1;
         break;
@@ -426,29 +462,31 @@ static void showLog(LogState *state,
             "%c/%-8s(%5d): ", priChar, tag, pid);
         strcpy(suffixBuf, "\n"); suffixLen = 1;
         break;
      }
 
     /*
      * Figure out how many lines there will be.
      */
+    UNINDENTED_BLOCK_START
     const char* end = msg + strlen(msg);
     size_t numLines = 0;
     const char* p = msg;
     while (p < end) {
         if (*p++ == '\n') numLines++;
     }
     if (p > msg && *(p-1) != '\n') numLines++;
 
     /*
      * Create an array of iovecs large enough to write all of
      * the lines with a prefix and a suffix.
      */
-    const size_t INLINE_VECS = 6;
+    UNINDENTED_BLOCK_START
+    #define INLINE_VECS 6
     const size_t MAX_LINES   = ((size_t)~0)/(3*sizeof(struct iovec*));
     struct iovec stackVec[INLINE_VECS];
     struct iovec* vec = stackVec;
     size_t numVecs;
 
     if (numLines > MAX_LINES)
         numLines = MAX_LINES;
 
@@ -462,41 +500,44 @@ static void showLog(LogState *state,
             vec = stackVec;
         }
     }
 
     /*
      * Fill in the iovec pointers.
      */
     p = msg;
+    UNINDENTED_BLOCK_START
     struct iovec* v = vec;
     int totalLen = 0;
     while (numLines > 0 && p < end) {
         if (prefixLen > 0) {
             v->iov_base = prefixBuf;
             v->iov_len = prefixLen;
             totalLen += prefixLen;
             v++;
         }
+        UNINDENTED_BLOCK_START
         const char* start = p;
         while (p < end && *p != '\n') p++;
         if ((p-start) > 0) {
             v->iov_base = (void*)start;
             v->iov_len = p-start;
             totalLen += p-start;
             v++;
         }
         if (*p == '\n') p++;
         if (suffixLen > 0) {
             v->iov_base = suffixBuf;
             v->iov_len = suffixLen;
             totalLen += suffixLen;
             v++;
         }
         numLines -= 1;
+        UNINDENTED_BLOCK_END
     }
     
     /*
      * Write the entire message to the log file with a single writev() call.
      * We need to use this rather than a collection of printf()s on a FILE*
      * because of multi-threading and multi-process issues.
      *
      * If the file was not opened with O_APPEND, this will produce interleaved
@@ -524,16 +565,20 @@ static void showLog(LogState *state,
             fprintf(stderr, "+++ LOG: write partial (%d of %d)\n", cc, totalLen);
             break;
         }
     }
 
     /* if we allocated storage for the iovecs, free it */
     if (vec != stackVec)
         free(vec);
+    UNINDENTED_BLOCK_END
+    UNINDENTED_BLOCK_END
+    UNINDENTED_BLOCK_END
+    UNINDENTED_BLOCK_END
 }
 
 
 /*
  * Receive a log message.  We happen to know that "vector" has three parts:
  *
  *  priority (1 byte)
  *  tag (N bytes -- null-terminated ASCII string)
@@ -562,16 +607,17 @@ static ssize_t logWritev(int fd, const s
 
     if (count != 3) {
         TRACE("%s: writevLog with count=%d not expected\n",
             state->debugName, count);
         goto error;
     }
 
     /* pull out the three fields */
+    UNINDENTED_BLOCK_START
     int logPrio = *(const char*)vector[0].iov_base;
     const char* tag = (const char*) vector[1].iov_base;
     const char* msg = (const char*) vector[2].iov_base;
 
     /* see if this log tag is configured */
     int i;
     int minPrio = state->globalMinPriority;
     for (i = 0; i < kTagSetSize; i++) {
@@ -585,16 +631,17 @@ static ssize_t logWritev(int fd, const s
         }
     }
 
     if (logPrio >= minPrio) {
         showLog(state, logPrio, tag, msg);
     } else {
         //TRACE("+++ NOLOG(%d): %s %s", logPrio, tag, msg);
     }
+    UNINDENTED_BLOCK_END
 
 bail:
     unlock();
     return vector[0].iov_len + vector[1].iov_len + vector[2].iov_len;
 error:
     unlock();
     return -1;
 }
@@ -678,8 +725,11 @@ int fakeLogClose(int fd)
     return redirectClose(fd);
 }
 
 ssize_t fakeLogWritev(int fd, const struct iovec* vector, int count)
 {
     /* Assume that open() was called first. */
     return redirectWritev(fd, vector, count);
 }
+
+#undef UNINDENTED_BLOCK_START
+#undef UNINDENTED_BLOCK_END
--- a/media/libstagefright/system/core/liblog/logd_write.c
+++ b/media/libstagefright/system/core/liblog/logd_write.c
@@ -28,17 +28,29 @@
 #include <sys/stat.h>
 
 #include <log/logger.h>
 #include <log/logd.h>
 #include <log/log.h>
 
 #define LOG_BUF_SIZE	1024
 
+#ifdef _MSC_VER
+#include <nspr/prprf.h>
+#define snprintf PR_snprintf
+#define __builtin_trap abort
+static int W_OK = 0;
+static int access(char* c, int i) { return -1; }
+#endif
+
 #if FAKE_LOG_DEVICE
+int fakeLogOpen(const char *pathName, int flags);
+ssize_t fakeLogWritev(int fd, const struct iovec* vector, int count);
+int fakeLogClose(int fd);
+
 // This will be defined when building for the host.
 #define log_open(pathname, flags) fakeLogOpen(pathname, flags)
 #define log_writev(filedes, vector, count) fakeLogWritev(filedes, vector, count)
 #define log_close(filedes) fakeLogClose(filedes)
 #else
 #define log_open(pathname, flags) open(pathname, (flags) | O_CLOEXEC)
 #define log_writev(filedes, vector, count) writev(filedes, vector, count)
 #define log_close(filedes) close(filedes)
@@ -253,17 +265,21 @@ void __android_log_assert(const char *co
         if (cond)
             snprintf(buf, LOG_BUF_SIZE, "Assertion failed: %s", cond);
         else
             strcpy(buf, "Unspecified assertion failed");
     }
 
     __android_log_write(ANDROID_LOG_FATAL, tag, buf);
 
+#ifdef _MSC_VER
+    abort();
+#else
     __builtin_trap(); /* trap so we have a chance to debug the situation */
+#endif
 }
 
 int __android_log_bwrite(int32_t tag, const void *payload, size_t len)
 {
     struct iovec vec[2];
 
     vec[0].iov_base = &tag;
     vec[0].iov_len = sizeof(tag);
--- a/media/libstagefright/system/core/liblog/logprint.c
+++ b/media/libstagefright/system/core/liblog/logprint.c
@@ -24,16 +24,45 @@
 #include <stdint.h>
 #include <string.h>
 #include <assert.h>
 #include <arpa/inet.h>
 
 #include <log/logd.h>
 #include <log/logprint.h>
 
+#ifdef _MSC_VER
+#include <nspr/prprf.h>
+#define snprintf PR_snprintf
+#define inline
+/* We don't want to indent large blocks because it causes unnecessary merge
+ * conflicts */
+#define UNINDENTED_BLOCK_START {
+#define UNINDENTED_BLOCK_END }
+
+static char *
+strsep(char **stringp, const char *delim)
+{
+    char* res = *stringp;
+    while (**stringp) {
+        const char *c;
+        for (c = delim; *c; c++) {
+            if (**stringp == *c) {
+                **stringp++ = 0;
+                return res;
+            }
+        }
+    }
+    return res;
+}
+#else
+#define UNINDENTED_BLOCK_START
+#define UNINDENTED_BLOCK_END
+#endif
+
 typedef struct FilterInfo_t {
     char *mTag;
     android_LogPriority mPri;
     struct FilterInfo_t *p_next;
 } FilterInfo;
 
 struct AndroidLogFormat_t {
     android_LogPriority global_pri;
@@ -263,33 +292,37 @@ int android_log_addFilterRule(AndroidLog
         p_format->global_pri = pri;
     } else {
         // for filter expressions that don't refer to the global
         // filter, the default is verbose if the priority is unspecified
         if (pri == ANDROID_LOG_DEFAULT) {
             pri = ANDROID_LOG_VERBOSE;
         }
 
+        UNINDENTED_BLOCK_START
         char *tagName;
 
 // Presently HAVE_STRNDUP is never defined, so the second case is always taken
 // Darwin doesn't have strnup, everything else does
 #ifdef HAVE_STRNDUP
         tagName = strndup(filterExpression, tagNameLength);
 #else
         //a few extra bytes copied...
         tagName = strdup(filterExpression);
         tagName[tagNameLength] = '\0';
 #endif /*HAVE_STRNDUP*/
 
+        UNINDENTED_BLOCK_START
         FilterInfo *p_fi = filterinfo_new(tagName, pri);
         free(tagName);
 
         p_fi->p_next = p_format->filters;
         p_format->filters = p_fi;
+        UNINDENTED_BLOCK_END
+        UNINDENTED_BLOCK_END
     }
 
     return 0;
 error:
     return -1;
 }
 
 
@@ -368,16 +401,17 @@ int android_log_processLogBuffer(struct 
      */
     if (buf->len < 3) {
         // An well-formed entry must consist of at least a priority
         // and two null characters
         fprintf(stderr, "+++ LOG: entry too small\n");
         return -1;
     }
 
+    UNINDENTED_BLOCK_START
     int msgStart = -1;
     int msgEnd = -1;
 
     int i;
     for (i = 1; i < buf->len; i++) {
         if (buf->msg[i] == '\0') {
             if (msgStart == -1) {
                 msgStart = i + 1;
@@ -399,16 +433,17 @@ int android_log_processLogBuffer(struct 
     }
 
     entry->priority = buf->msg[0];
     entry->tag = buf->msg + 1;
     entry->message = buf->msg + msgStart;
     entry->messageLen = msgEnd - msgStart;
 
     return 0;
+    UNINDENTED_BLOCK_END
 }
 
 /*
  * Extract a 4-byte value from a byte stream.
  */
 static inline uint32_t get4LE(const uint8_t* src)
 {
     return src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24);
@@ -616,21 +651,17 @@ int android_log_processBinaryLogBuffer(s
     eventData = (const unsigned char*) buf->msg;
     inCount = buf->len;
     if (inCount < 4)
         return -1;
     tagIndex = get4LE(eventData);
     eventData += 4;
     inCount -= 4;
 
-    if (map != NULL) {
-        entry->tag = android_lookupEventTag(map, tagIndex);
-    } else {
-        entry->tag = NULL;
-    }
+    entry->tag = NULL;
 
     /*
      * If we don't have a map, or didn't find the tag number in the map,
      * stuff a generated tag value into the start of the output buffer and
      * shift the buffer pointers down.
      */
     if (entry->tag == NULL) {
         int tagLen;
@@ -639,16 +670,17 @@ int android_log_processBinaryLogBuffer(s
         entry->tag = messageBuf;
         messageBuf += tagLen+1;
         messageBufLen -= tagLen+1;
     }
 
     /*
      * Format the event log data into the buffer.
      */
+    UNINDENTED_BLOCK_START
     char* outBuf = messageBuf;
     size_t outRemaining = messageBufLen-1;      /* leave one for nul byte */
     int result;
     result = android_log_printBinaryEvent(&eventData, &inCount, &outBuf,
                 &outRemaining);
     if (result < 0) {
         fprintf(stderr, "Binary log entry conversion failed\n");
         return -1;
@@ -682,16 +714,17 @@ int android_log_processBinaryLogBuffer(s
      */
     *outBuf = '\0';
     entry->messageLen = outBuf - messageBuf;
     assert(entry->messageLen == (messageBufLen-1) - outRemaining);
 
     entry->message = messageBuf;
 
     return 0;
+    UNINDENTED_BLOCK_END
 }
 
 /**
  * Formats a log message into a buffer
  *
  * Uses defaultBuffer if it can, otherwise malloc()'s a new buffer
  * If return value != defaultBuffer, caller must call free()
  * Returns NULL on malloc error
@@ -732,16 +765,17 @@ char *android_log_formatLogLine (
     ptm = localtime(&(entry->tv_sec));
 #endif
     //strftime(timeBuf, sizeof(timeBuf), "%Y-%m-%d %H:%M:%S", ptm);
     strftime(timeBuf, sizeof(timeBuf), "%m-%d %H:%M:%S", ptm);
 
     /*
      * Construct a buffer containing the log header and log message.
      */
+    UNINDENTED_BLOCK_START
     size_t prefixLen, suffixLen;
 
     switch (p_format->format) {
         case FORMAT_TAG:
             prefixLen = snprintf(prefixBuf, sizeof(prefixBuf),
                 "%c/%-8s: ", priChar, entry->tag);
             strcpy(suffixBuf, "\n"); suffixLen = 1;
             break;
@@ -802,16 +836,17 @@ char *android_log_formatLogLine (
      */
     if(prefixLen >= sizeof(prefixBuf))
         prefixLen = sizeof(prefixBuf) - 1;
     if(suffixLen >= sizeof(suffixBuf))
         suffixLen = sizeof(suffixBuf) - 1;
 
     /* the following code is tragically unreadable */
 
+    UNINDENTED_BLOCK_START
     size_t numLines;
     size_t i;
     char *p;
     size_t bufferSize;
     const char *pm;
 
     if (prefixSuffixIsHeaderFooter) {
         // we're just wrapping message with a header/footer
@@ -877,16 +912,18 @@ char *android_log_formatLogLine (
         }
     }
 
     if (p_outLength != NULL) {
         *p_outLength = p - ret;
     }
 
     return ret;
+    UNINDENTED_BLOCK_END
+    UNINDENTED_BLOCK_END
 }
 
 /**
  * Either print or do not print log line, based on filter
  *
  * Returns count bytes written
  */
 
@@ -1009,8 +1046,11 @@ void logprint_run_tests()
         defaultBuffer, sizeof(defaultBuffer), 0, ANDROID_LOG_ERROR, 123,
         123, 123, "random", "nofile", strlen("Hello"), "Hello", NULL);
 #endif
 
 
     fprintf(stderr, "tests complete\n");
 #endif
 }
+
+#undef UNINDENTED_BLOCK_START
+#undef UNINDENTED_BLOCK_END
--- a/media/libstagefright/system/core/libutils/RefBase.cpp
+++ b/media/libstagefright/system/core/libutils/RefBase.cpp
@@ -15,17 +15,24 @@
  */
 
 #define LOG_TAG "RefBase"
 // #define LOG_NDEBUG 0
 
 #include <utils/RefBase.h>
 
 #include <utils/Atomic.h>
+#ifdef _MSC_VER
+class CallStack {
+public:
+    CallStack(int x) {}
+};
+#else
 #include <utils/CallStack.h>
+#endif
 #include <utils/Log.h>
 #include <utils/threads.h>
 
 #include <stdlib.h>
 #include <stdio.h>
 #include <typeinfo>
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -35,17 +42,17 @@
 // compile with refcounting debugging enabled
 #define DEBUG_REFS                      0
 
 // whether ref-tracking is enabled by default, if not, trackMe(true, false)
 // needs to be called explicitly
 #define DEBUG_REFS_ENABLED_BY_DEFAULT   0
 
 // whether callstack are collected (significantly slows things down)
-#define DEBUG_REFS_CALLSTACK_ENABLED    1
+#define DEBUG_REFS_CALLSTACK_ENABLED    0
 
 // folder where stack traces are saved when DEBUG_REFS is enabled
 // this folder needs to exist and be writable
 #define DEBUG_REFS_CALLSTACK_PATH       "/data/debug"
 
 // log all reference counting operations
 #define PRINT_REFS                      0
 
--- a/media/libstagefright/system/core/libutils/String8.cpp
+++ b/media/libstagefright/system/core/libutils/String8.cpp
@@ -133,27 +133,18 @@ static char* allocFromUTF32(const char32
     utf32_to_utf8(in, len, str);
 
     return str;
 }
 
 // ---------------------------------------------------------------------------
 
 String8::String8()
-    : mString(getEmptyString())
-{
-}
-
-String8::String8(StaticLinkage)
     : mString(0)
 {
-    // this constructor is used when we can't rely on the static-initializers
-    // having run. In this case we always allocate an empty string. It's less
-    // efficient than using getEmptyString(), but we assume it's uncommon.
-
     char* data = static_cast<char*>(
             SharedBuffer::alloc(sizeof(char))->data());
     data[0] = 0;
     mString = data;
 }
 
 String8::String8(const String8& o)
     : mString(o.mString)
@@ -319,26 +310,37 @@ status_t String8::appendFormat(const cha
 
     va_end(args);
     return result;
 }
 
 status_t String8::appendFormatV(const char* fmt, va_list args)
 {
     int result = NO_ERROR;
+#ifndef _MSC_VER
+    va_list o;
+    va_copy(o, args);
+#endif
     int n = vsnprintf(NULL, 0, fmt, args);
     if (n != 0) {
         size_t oldLength = length();
         char* buf = lockBuffer(oldLength + n);
         if (buf) {
+#ifdef _MSC_VER
             vsnprintf(buf + oldLength, n + 1, fmt, args);
+#else
+            vsnprintf(buf + oldLength, n + 1, fmt, o);
+#endif
         } else {
             result = NO_MEMORY;
         }
     }
+#ifndef _MSC_VER
+    va_end(o);
+#endif
     return result;
 }
 
 status_t String8::real_append(const char* other, size_t otherLen)
 {
     const size_t myLen = bytes();
     
     SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
--- a/media/libstagefright/system/core/libutils/Unicode.cpp
+++ b/media/libstagefright/system/core/libutils/Unicode.cpp
@@ -571,36 +571,36 @@ char16_t* utf8_to_utf16_no_null_terminat
 void utf8_to_utf16(const uint8_t* u8str, size_t u8len, char16_t* u16str) {
     char16_t* end = utf8_to_utf16_no_null_terminator(u8str, u8len, u16str);
     *end = 0;
 }
 
 char16_t* utf8_to_utf16_n(const uint8_t* src, size_t srcLen, char16_t* dst, size_t dstLen) {
     const uint8_t* const u8end = src + srcLen;
     const uint8_t* u8cur = src;
-    const uint16_t* const u16end = dst + dstLen;
-    char16_t* u16cur = dst;
+    const uint16_t* const u16end = (const uint16_t* const) dst + dstLen;
+    uint16_t* u16cur = (uint16_t*) dst;
 
     while (u8cur < u8end && u16cur < u16end) {
         size_t u8len = utf8_codepoint_len(*u8cur);
         uint32_t codepoint = utf8_to_utf32_codepoint(u8cur, u8len);
 
         // Convert the UTF32 codepoint to one or more UTF16 codepoints
         if (codepoint <= 0xFFFF) {
             // Single UTF16 character
             *u16cur++ = (char16_t) codepoint;
         } else {
             // Multiple UTF16 characters with surrogates
             codepoint = codepoint - 0x10000;
             *u16cur++ = (char16_t) ((codepoint >> 10) + 0xD800);
             if (u16cur >= u16end) {
                 // Ooops...  not enough room for this surrogate pair.
-                return u16cur-1;
+                return (char16_t*) u16cur-1;
             }
             *u16cur++ = (char16_t) ((codepoint & 0x3FF) + 0xDC00);
         }
 
         u8cur += u8len;
     }
-    return u16cur;
+    return (char16_t*) u16cur;
 }
 
 }
new file mode 100755
--- /dev/null
+++ b/media/libstagefright/update-patches.sh
@@ -0,0 +1,13 @@
+#!/bin/bash -e
+cd `dirname "$0"`
+rm -fR patches
+for DIR in `find android/ -name .git`
+do
+    DIR=`dirname ${DIR}`
+    DST=patches/${DIR:8}
+    echo ${DST}
+    mkdir -p `dirname ${DST}`
+    cp -a ${DIR:8} `dirname ${DIR}`
+    (cd ${DIR} && git diff) > ${DST}.patch
+    (cd ${DIR} && git rev-parse HEAD) > ${DST}.tag
+done