Squashed commit of the following:

commit 333057b355f8c260c549553b9a0634755c838b6a
Author: Andreas Huber <andih@google.com>
Date:   Fri Nov 13 15:35:48 2009 -0800

    Some more tweaks to AVC encoding on sholes.

commit 9981d0ee52ec5b8b0182aae733d1571e3ebb8390
Author: Andreas Huber <andih@google.com>
Date:   Thu Nov 12 16:36:57 2009 -0800

    Support for avc encoding, including sholes specific tweaks to pick the right colorspace for the camera to not require transcoding.

commit 5ba0ebbbd4efca51f3ae1f60e2ca31e7d2cf136d
Author: Andreas Huber <andih@google.com>
Date:   Wed Nov 11 09:50:03 2009 -0800

    Enable actual (camera) video-only recording using h.263 or mpeg4 encoding.

commit 3fd59c3526a37fe7c696f4a978925d1831c09313
Author: Andreas Huber <andih@google.com>
Date:   Tue Nov 10 14:57:48 2009 -0800

    Allow switching between the PV recorder implementation and one supported by stagefright.

    This is controlled through the property "media.stagefright.enable-record".
diff --git a/media/libmediaplayerservice/Android.mk b/media/libmediaplayerservice/Android.mk
index 6fc9fa2..4784b8e 100644
--- a/media/libmediaplayerservice/Android.mk
+++ b/media/libmediaplayerservice/Android.mk
@@ -19,8 +19,9 @@
 ifeq ($(BUILD_WITH_FULL_STAGEFRIGHT),true)
 
 LOCAL_SRC_FILES +=                      \
+    StagefrightMetadataRetriever.cpp    \
     StagefrightPlayer.cpp               \
-    StagefrightMetadataRetriever.cpp
+    StagefrightRecorder.cpp
 
 LOCAL_CFLAGS += -DBUILD_WITH_FULL_STAGEFRIGHT=1
 
diff --git a/media/libmediaplayerservice/MediaRecorderClient.cpp b/media/libmediaplayerservice/MediaRecorderClient.cpp
index 95ee3e4..2ea7cc3 100644
--- a/media/libmediaplayerservice/MediaRecorderClient.cpp
+++ b/media/libmediaplayerservice/MediaRecorderClient.cpp
@@ -24,6 +24,7 @@
 #include <unistd.h>
 #include <string.h>
 #include <cutils/atomic.h>
+#include <cutils/properties.h> // for property_get
 #include <android_runtime/ActivityManager.h>
 #include <binder/IPCThreadState.h>
 #include <binder/IServiceManager.h>
@@ -37,6 +38,8 @@
 #include "MediaRecorderClient.h"
 #include "MediaPlayerService.h"
 
+#include "StagefrightRecorder.h"
+
 namespace android {
 
 const char* cameraPermission = "android.permission.CAMERA";
@@ -286,7 +289,18 @@
 {
     LOGV("Client constructor");
     mPid = pid;
-    mRecorder = new PVMediaRecorder();
+
+#if BUILD_WITH_FULL_STAGEFRIGHT
+    char value[PROPERTY_VALUE_MAX];
+    if (property_get("media.stagefright.enable-record", value, NULL)
+        && (!strcmp(value, "1") || !strcasecmp(value, "true"))) {
+        mRecorder = new StagefrightRecorder;
+    } else
+#endif
+    {
+        mRecorder = new PVMediaRecorder();
+    }
+
     mMediaPlayerService = service;
 }
 
diff --git a/media/libmediaplayerservice/MediaRecorderClient.h b/media/libmediaplayerservice/MediaRecorderClient.h
index 6260441..e07306b 100644
--- a/media/libmediaplayerservice/MediaRecorderClient.h
+++ b/media/libmediaplayerservice/MediaRecorderClient.h
@@ -22,8 +22,7 @@
 
 namespace android {
 
-class PVMediaRecorder;
-class ISurface;
+class MediaRecorderBase;
 class MediaPlayerService;
 
 class MediaRecorderClient : public BnMediaRecorder
@@ -59,7 +58,7 @@
 
     pid_t			 mPid;
     Mutex			 mLock;
-    PVMediaRecorder              *mRecorder;
+    MediaRecorderBase            *mRecorder;
     sp<MediaPlayerService>       mMediaPlayerService;
 };
 
diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp
new file mode 100644
index 0000000..a55273d
--- /dev/null
+++ b/media/libmediaplayerservice/StagefrightRecorder.cpp
@@ -0,0 +1,241 @@
+/*
+ * Copyright (C) 2009 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.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "StagefrightRecorder"
+#include <utils/Log.h>
+
+#include "StagefrightRecorder.h"
+
+#include <media/stagefright/CameraSource.h>
+#include <media/stagefright/MPEG4Writer.h>
+#include <media/stagefright/MediaDebug.h>
+#include <media/stagefright/MediaDefs.h>
+#include <media/stagefright/MetaData.h>
+#include <media/stagefright/OMXClient.h>
+#include <media/stagefright/OMXCodec.h>
+#include <ui/ICamera.h>
+#include <ui/ISurface.h>
+#include <utils/Errors.h>
+
+namespace android {
+
+StagefrightRecorder::StagefrightRecorder() {
+    reset();
+}
+
+StagefrightRecorder::~StagefrightRecorder() {
+    stop();
+
+    if (mOutputFd >= 0) {
+        ::close(mOutputFd);
+        mOutputFd = -1;
+    }
+}
+
+status_t StagefrightRecorder::init() {
+    return OK;
+}
+
+status_t StagefrightRecorder::setAudioSource(audio_source as) {
+    mAudioSource = as;
+
+    return OK;
+}
+
+status_t StagefrightRecorder::setVideoSource(video_source vs) {
+    mVideoSource = vs;
+
+    return OK;
+}
+
+status_t StagefrightRecorder::setOutputFormat(output_format of) {
+    mOutputFormat = of;
+
+    return OK;
+}
+
+status_t StagefrightRecorder::setAudioEncoder(audio_encoder ae) {
+    mAudioEncoder = ae;
+
+    return OK;
+}
+
+status_t StagefrightRecorder::setVideoEncoder(video_encoder ve) {
+    mVideoEncoder = ve;
+
+    return OK;
+}
+
+status_t StagefrightRecorder::setVideoSize(int width, int height) {
+    mVideoWidth = width;
+    mVideoHeight = height;
+
+    return OK;
+}
+
+status_t StagefrightRecorder::setVideoFrameRate(int frames_per_second) {
+    mFrameRate = frames_per_second;
+
+    return OK;
+}
+
+status_t StagefrightRecorder::setCamera(const sp<ICamera> &camera) {
+    mCamera = camera;
+
+    return OK;
+}
+
+status_t StagefrightRecorder::setPreviewSurface(const sp<ISurface> &surface) {
+    mPreviewSurface = surface;
+
+    return OK;
+}
+
+status_t StagefrightRecorder::setOutputFile(const char *path) {
+    // We don't actually support this at all, as the media_server process
+    // no longer has permissions to create files.
+
+    return UNKNOWN_ERROR;
+}
+
+status_t StagefrightRecorder::setOutputFile(int fd, int64_t offset, int64_t length) {
+    // These don't make any sense, do they?
+    CHECK_EQ(offset, 0);
+    CHECK_EQ(length, 0);
+
+    if (mOutputFd >= 0) {
+        ::close(mOutputFd);
+    }
+    mOutputFd = dup(fd);
+
+    return OK;
+}
+
+status_t StagefrightRecorder::setParameters(const String8 &params) {
+    mParams = params;
+
+    return OK;
+}
+
+status_t StagefrightRecorder::setListener(const sp<IMediaPlayerClient> &listener) {
+    mListener = listener;
+
+    return OK;
+}
+
+status_t StagefrightRecorder::prepare() {
+    return OK;
+}
+
+status_t StagefrightRecorder::start() {
+    if (mWriter != NULL) {
+        return UNKNOWN_ERROR;
+    }
+
+    if (mVideoSource == VIDEO_SOURCE_CAMERA) {
+        CHECK(mCamera != NULL);
+
+        sp<CameraSource> cameraSource =
+            CameraSource::CreateFromICamera(mCamera);
+
+        CHECK(cameraSource != NULL);
+
+        cameraSource->setPreviewSurface(mPreviewSurface);
+
+        sp<MetaData> enc_meta = new MetaData;
+        switch (mVideoEncoder) {
+            case VIDEO_ENCODER_H263:
+                enc_meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_H263);
+                break;
+
+            case VIDEO_ENCODER_MPEG_4_SP:
+                enc_meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4);
+                break;
+
+            case VIDEO_ENCODER_H264:
+                enc_meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC);
+                break;
+
+            default:
+                CHECK(!"Should not be here, unsupported video encoding.");
+                break;
+        }
+
+        sp<MetaData> meta = cameraSource->getFormat();
+
+        int32_t width, height;
+        CHECK(meta->findInt32(kKeyWidth, &width));
+        CHECK(meta->findInt32(kKeyHeight, &height));
+
+        enc_meta->setInt32(kKeyWidth, width);
+        enc_meta->setInt32(kKeyHeight, height);
+
+        OMXClient client;
+        CHECK_EQ(client.connect(), OK);
+
+        sp<MediaSource> encoder =
+            OMXCodec::Create(
+                    client.interface(), enc_meta,
+                    true /* createEncoder */, cameraSource);
+
+        CHECK(mOutputFd >= 0);
+        mWriter = new MPEG4Writer(dup(mOutputFd));
+        mWriter->addSource(encoder);
+        mWriter->start();
+    }
+
+    return OK;
+}
+
+status_t StagefrightRecorder::stop() {
+    if (mWriter == NULL) {
+        return UNKNOWN_ERROR;
+    }
+
+    mWriter->stop();
+    mWriter = NULL;
+
+    return OK;
+}
+
+status_t StagefrightRecorder::close() {
+    stop();
+
+    return OK;
+}
+
+status_t StagefrightRecorder::reset() {
+    stop();
+
+    mAudioSource = AUDIO_SOURCE_LIST_END;
+    mVideoSource = VIDEO_SOURCE_LIST_END;
+    mOutputFormat = OUTPUT_FORMAT_LIST_END;
+    mAudioEncoder = AUDIO_ENCODER_LIST_END;
+    mVideoEncoder = VIDEO_ENCODER_LIST_END;
+    mVideoWidth = -1;
+    mVideoHeight = -1;
+    mFrameRate = -1;
+    mOutputFd = -1;
+
+    return OK;
+}
+
+status_t StagefrightRecorder::getMaxAmplitude(int *max) {
+    return UNKNOWN_ERROR;
+}
+
+}  // namespace android
diff --git a/media/libmediaplayerservice/StagefrightRecorder.h b/media/libmediaplayerservice/StagefrightRecorder.h
new file mode 100644
index 0000000..56c4e0e
--- /dev/null
+++ b/media/libmediaplayerservice/StagefrightRecorder.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2009 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 STAGEFRIGHT_RECORDER_H_
+
+#define STAGEFRIGHT_RECORDER_H_
+
+#include <media/MediaRecorderBase.h>
+#include <utils/String8.h>
+
+namespace android {
+
+class MPEG4Writer;
+
+struct StagefrightRecorder : public MediaRecorderBase {
+    StagefrightRecorder();
+    virtual ~StagefrightRecorder();
+
+    virtual status_t init();
+    virtual status_t setAudioSource(audio_source as);
+    virtual status_t setVideoSource(video_source vs);
+    virtual status_t setOutputFormat(output_format of);
+    virtual status_t setAudioEncoder(audio_encoder ae);
+    virtual status_t setVideoEncoder(video_encoder ve);
+    virtual status_t setVideoSize(int width, int height);
+    virtual status_t setVideoFrameRate(int frames_per_second);
+    virtual status_t setCamera(const sp<ICamera>& camera);
+    virtual status_t setPreviewSurface(const sp<ISurface>& surface);
+    virtual status_t setOutputFile(const char *path);
+    virtual status_t setOutputFile(int fd, int64_t offset, int64_t length);
+    virtual status_t setParameters(const String8& params);
+    virtual status_t setListener(const sp<IMediaPlayerClient>& listener);
+    virtual status_t prepare();
+    virtual status_t start();
+    virtual status_t stop();
+    virtual status_t close();
+    virtual status_t reset();
+    virtual status_t getMaxAmplitude(int *max);
+
+private:
+    sp<ICamera> mCamera;
+    sp<ISurface> mPreviewSurface;
+    sp<IMediaPlayerClient> mListener;
+    sp<MPEG4Writer> mWriter;
+
+    audio_source mAudioSource;
+    video_source mVideoSource;
+    output_format mOutputFormat;
+    audio_encoder mAudioEncoder;
+    video_encoder mVideoEncoder;
+    int mVideoWidth, mVideoHeight;
+    int mFrameRate;
+    String8 mParams;
+    int mOutputFd;
+
+    StagefrightRecorder(const StagefrightRecorder &);
+    StagefrightRecorder &operator=(const StagefrightRecorder &);
+};
+
+}  // namespace android
+
+#endif  // STAGEFRIGHT_RECORDER_H_
+