Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 76a54294 authored by Android (Google) Code Review's avatar Android (Google) Code Review
Browse files

Merge change I155e2ad0 into eclair-mr2

* changes:
  Re-enable CameraSource.
parents 27123468 155e2ad0
Loading
Loading
Loading
Loading
+13 −13
Original line number Diff line number Diff line
@@ -26,12 +26,11 @@

namespace android {

class ICamera;
class ICameraClient;
class IMemory;
class ISurface;
class Camera;

class CameraSource : public MediaSource,
                     public MediaBufferObserver {
class CameraSource : public MediaSource {
public:
    static CameraSource *Create();

@@ -45,24 +44,25 @@ public:
    virtual status_t read(
            MediaBuffer **buffer, const ReadOptions *options = NULL);

    virtual void notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2);
    virtual void dataCallback(int32_t msgType, const sp<IMemory>& data);

    virtual void signalBufferReturned(MediaBuffer *buffer);

private:
    CameraSource(const sp<ICamera> &camera, const sp<ICameraClient> &client);
    friend class CameraSourceListener;

    sp<ICamera> mCamera;
    sp<ICameraClient> mCameraClient;
    sp<Camera> mCamera;

    Mutex mLock;
    Condition mFrameAvailableCondition;
    List<sp<IMemory> > mFrames;
    List<int64_t> mFrameTimes;

    int mNumFrames;
    int mWidth, mHeight;
    int64_t mFirstFrameTimeUs;
    int32_t mNumFrames;
    bool mStarted;

    CameraSource(const sp<Camera> &camera);

    void dataCallback(int32_t msgType, const sp<IMemory> &data);

    CameraSource(const CameraSource &);
    CameraSource &operator=(const CameraSource &);
};
+1 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@ ifeq ($(BUILD_WITH_FULL_STAGEFRIGHT),true)
LOCAL_SRC_FILES +=                \
        AMRExtractor.cpp          \
        CachingDataSource.cpp     \
        CameraSource.cpp          \
        DataSource.cpp            \
        FileSource.cpp            \
        HTTPDataSource.cpp        \
+107 −92
Original line number Diff line number Diff line
@@ -21,120 +21,142 @@
#include <binder/IServiceManager.h>
#include <media/stagefright/CameraSource.h>
#include <media/stagefright/MediaDebug.h>
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MediaErrors.h>
#include <media/stagefright/MetaData.h>
#include <ui/ICameraClient.h>
#include <ui/ICameraService.h>
#include <ui/Camera.h>
#include <ui/CameraParameters.h>
#include <ui/GraphicBuffer.h>
#include <ui/ISurface.h>
#include <ui/Overlay.h>
#include <utils/String16.h>
#include <utils/String8.h>

namespace android {

class CameraBuffer : public MediaBuffer {
public:
    CameraBuffer(const sp<IMemory> &frame)
        : MediaBuffer(frame->pointer(), frame->size()),
          mFrame(frame) {
    }
static int64_t getNowUs() {
    struct timeval tv;
    gettimeofday(&tv, NULL);

    sp<IMemory> releaseFrame() {
        sp<IMemory> frame = mFrame;
        mFrame.clear();
        return frame;
    return (int64_t)tv.tv_usec + tv.tv_sec * 1000000;
}

private:
    sp<IMemory> mFrame;
};
struct DummySurface : public BnSurface {
    DummySurface() {}

class CameraSourceClient : public BnCameraClient {
public:
    CameraSourceClient()
        : mSource(NULL) {
    virtual sp<GraphicBuffer> requestBuffer(int bufferIdx, int usage) {
        return NULL;
    }

    virtual void notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2) {
        CHECK(mSource != NULL);
        mSource->notifyCallback(msgType, ext1, ext2);
    virtual status_t registerBuffers(const BufferHeap &buffers) {
        return OK;
    }

    virtual void dataCallback(int32_t msgType, const sp<IMemory> &data) {
        CHECK(mSource != NULL);
        mSource->dataCallback(msgType, data);
    }
    virtual void postBuffer(ssize_t offset) {}
    virtual void unregisterBuffers() {}

    void setCameraSource(CameraSource *source) {
        mSource = source;
    virtual sp<OverlayRef> createOverlay(
            uint32_t w, uint32_t h, int32_t format) {
        return NULL;
    }

protected:
    virtual ~DummySurface() {}

    DummySurface(const DummySurface &);
    DummySurface &operator=(const DummySurface &);
};

struct CameraSourceListener : public CameraListener {
    CameraSourceListener(const sp<CameraSource> &source);

    virtual void notify(int32_t msgType, int32_t ext1, int32_t ext2);
    virtual void postData(int32_t msgType, const sp<IMemory> &dataPtr);

    virtual void postDataTimestamp(
            nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr);

protected:
    virtual ~CameraSourceListener();

private:
    CameraSource *mSource;
    wp<CameraSource> mSource;

    CameraSourceListener(const CameraSourceListener &);
    CameraSourceListener &operator=(const CameraSourceListener &);
};

class DummySurface : public BnSurface {
public:
    DummySurface() {}
CameraSourceListener::CameraSourceListener(const sp<CameraSource> &source)
    : mSource(source) {
}

    virtual status_t registerBuffers(const BufferHeap &buffers) {
        return OK;
CameraSourceListener::~CameraSourceListener() {
}

    virtual void postBuffer(ssize_t offset) {
void CameraSourceListener::notify(int32_t msgType, int32_t ext1, int32_t ext2) {
    LOGV("notify(%d, %d, %d)", msgType, ext1, ext2);
}

    virtual void unregisterBuffers() {
void CameraSourceListener::postData(int32_t msgType, const sp<IMemory> &dataPtr) {
    LOGV("postData(%d, ptr:%p, size:%d)",
         msgType, dataPtr->pointer(), dataPtr->size());

    sp<CameraSource> source = mSource.promote();
    if (source.get() != NULL) {
        source->dataCallback(msgType, dataPtr);
    }
}

    virtual sp<OverlayRef> createOverlay(
            uint32_t w, uint32_t h, int32_t format) {
        return NULL;
void CameraSourceListener::postDataTimestamp(
        nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr) {
    LOGV("postDataTimestamp(%lld, %d, ptr:%p, size:%d)",
         timestamp, msgType, dataPtr->pointer(), dataPtr->size());
}
};

// static
CameraSource *CameraSource::Create() {
    sp<IServiceManager> sm = defaultServiceManager();

    sp<ICameraService> service =
        interface_cast<ICameraService>(
                sm->getService(String16("media.camera")));

    sp<CameraSourceClient> client = new CameraSourceClient;
    sp<ICamera> camera = service->connect(client);
    sp<Camera> camera = Camera::connect();

    CameraSource *source = new CameraSource(camera, client);
    client->setCameraSource(source);
    if (camera.get() == NULL) {
        return NULL;
    }

    return source;
    return new CameraSource(camera);
}

CameraSource::CameraSource(
        const sp<ICamera> &camera, const sp<ICameraClient> &client)
CameraSource::CameraSource(const sp<Camera> &camera)
    : mCamera(camera),
      mCameraClient(client),
      mWidth(0),
      mHeight(0),
      mFirstFrameTimeUs(0),
      mNumFrames(0),
      mStarted(false) {
    printf("params: \"%s\"\n", mCamera->getParameters().string());
    String8 s = mCamera->getParameters();
    printf("params: \"%s\"\n", s.string());

    CameraParameters params(s);
    params.getPreviewSize(&mWidth, &mHeight);
}

CameraSource::~CameraSource() {
    if (mStarted) {
        stop();
    }

    mCamera->disconnect();
}

status_t CameraSource::start(MetaData *) {
    CHECK(!mStarted);

    status_t err = mCamera->lock();
    CHECK_EQ(err, OK);
    mCamera->setListener(new CameraSourceListener(this));

    err = mCamera->setPreviewDisplay(new DummySurface);
    sp<ISurface> dummy = new DummySurface;
    status_t err = mCamera->setPreviewDisplay(dummy);
    CHECK_EQ(err, OK);
    mCamera->setPreviewCallbackFlag(1);
    mCamera->startPreview();

    mCamera->setPreviewCallbackFlags(
            FRAME_CALLBACK_FLAG_ENABLE_MASK
            | FRAME_CALLBACK_FLAG_COPY_OUT_MASK);

    err = mCamera->startPreview();
    CHECK_EQ(err, OK);

    mStarted = true;
@@ -146,7 +168,6 @@ status_t CameraSource::stop() {
    CHECK(mStarted);

    mCamera->stopPreview();
    mCamera->unlock();

    mStarted = false;

@@ -157,8 +178,8 @@ sp<MetaData> CameraSource::getFormat() {
    sp<MetaData> meta = new MetaData;
    meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW);
    meta->setInt32(kKeyColorFormat, OMX_COLOR_FormatYUV420SemiPlanar);
    meta->setInt32(kKeyWidth, 480);
    meta->setInt32(kKeyHeight, 320);
    meta->setInt32(kKeyWidth, mWidth);
    meta->setInt32(kKeyHeight, mHeight);

    return meta;
}
@@ -175,6 +196,7 @@ status_t CameraSource::read(
    }

    sp<IMemory> frame;
    int64_t frameTime;

    {
        Mutex::Autolock autoLock(mLock);
@@ -184,40 +206,33 @@ status_t CameraSource::read(

        frame = *mFrames.begin();
        mFrames.erase(mFrames.begin());
    }

    int count = mNumFrames++;
        frameTime = *mFrameTimes.begin();
        mFrameTimes.erase(mFrameTimes.begin());
    }

    *buffer = new CameraBuffer(frame);
    *buffer = new MediaBuffer(frame->size());
    memcpy((*buffer)->data(), frame->pointer(), frame->size());
    (*buffer)->set_range(0, frame->size());

    (*buffer)->meta_data()->clear();
    (*buffer)->meta_data()->setInt64(kKeyTime, (count * 1000000) / 15);

    (*buffer)->add_ref();
    (*buffer)->setObserver(this);
    (*buffer)->meta_data()->setInt64(kKeyTime, frameTime);

    return OK;
}

void CameraSource::notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2) {
    printf("notifyCallback %d, %d, %d\n", msgType, ext1, ext2);
}

void CameraSource::dataCallback(int32_t msgType, const sp<IMemory> &data) {
    Mutex::Autolock autoLock(mLock);

    mFrames.push_back(data);
    mFrameAvailableCondition.signal();
    int64_t nowUs = getNowUs();
    if (mNumFrames == 0) {
        mFirstFrameTimeUs = nowUs;
    }
    ++mNumFrames;

void CameraSource::signalBufferReturned(MediaBuffer *_buffer) {
    CameraBuffer *buffer = static_cast<CameraBuffer *>(_buffer);

    mCamera->releaseRecordingFrame(buffer->releaseFrame());

    buffer->setObserver(NULL);
    buffer->release();
    buffer = NULL;
    mFrames.push_back(data);
    mFrameTimes.push_back(nowUs - mFirstFrameTimeUs);
    mFrameAvailableCondition.signal();
}

}  // namespace android