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

Commit 7ea6ebe7 authored by James Dong's avatar James Dong Committed by Android (Google) Code Review
Browse files

Merge "Move Camera specific logic out from StagefrightRecorder to CameraSource"

parents b154dfe7 0c128b67
Loading
Loading
Loading
Loading
+79 −4
Original line number Diff line number Diff line
@@ -20,25 +20,71 @@

#include <media/stagefright/MediaBuffer.h>
#include <media/stagefright/MediaSource.h>
#include <camera/ICamera.h>
#include <camera/CameraParameters.h>
#include <utils/List.h>
#include <utils/RefBase.h>

namespace android {

class ICamera;
class IMemory;
class Camera;
class Surface;

class CameraSource : public MediaSource, public MediaBufferObserver {
public:
    /**
     * Factory method to create a new CameraSource using the current
     * settings (such as video size, frame rate, color format, etc)
     * from the default camera.
     *
     * @return NULL on error.
     */
    static CameraSource *Create();
    static CameraSource *CreateFromCamera(const sp<Camera> &camera);

    /**
     * Factory method to create a new CameraSource.
     *
     * @param camera the video input frame data source. If it is NULL,
     *          we will try to connect to the camera with the given
     *          cameraId.
     *
     * @param cameraId the id of the camera that the source will connect
     *          to if camera is NULL; otherwise ignored.
     *
     * @param videoSize the dimension (in pixels) of the video frame
     * @param frameRate the target frames per second
     * @param surface the preview surface for display where preview
     *          frames are sent to
     *
     * @return NULL on error.
     */
    static CameraSource *CreateFromCamera(const sp<ICamera> &camera,
                                          int32_t cameraId,
                                          Size videoSize,
                                          int32_t frameRate,
                                          const sp<Surface>& surface);

    virtual ~CameraSource();

    virtual status_t start(MetaData *params = NULL);
    virtual status_t stop();

    /**
     * Check whether a CameraSource object is properly initialized.
     * Must call this method before stop().
     * @return OK if initialization has successfully completed.
     */
    virtual status_t initCheck() const;

    /**
     * Returns the MetaData associated with the CameraSource,
     * including:
     * kKeyColorFormat: YUV color format of the video frames
     * kKeyWidth, kKeyHeight: dimension (in pixels) of the video frames
     * kKeySampleRate: frame rate in frames per second
     * kKeyMimeType: always fixed
     */
    virtual sp<MetaData> getFormat();

    virtual status_t read(
@@ -47,7 +93,19 @@ public:
    virtual void signalBufferReturned(MediaBuffer* buffer);

protected:
    enum CameraFlags {
        FLAGS_SET_CAMERA = 1L << 0,
        FLAGS_HOT_CAMERA = 1L << 1,
    };

    int32_t  mCameraFlags;
    Size     mVideoSize;
    int32_t  mVideoFrameRate;
    int32_t  mColorFormat;
    status_t mInitCheck;

    sp<Camera>   mCamera;
    sp<Surface>  mSurface;
    sp<MetaData> mMeta;

    int64_t mStartTimeUs;
@@ -55,7 +113,9 @@ protected:
    int64_t mLastFrameTimestampUs;
    bool mStarted;

    CameraSource(const sp<Camera> &camera);
    CameraSource(const sp<ICamera>& camera, int32_t cameraId,
                 Size videoSize, int32_t frameRate,
                 const sp<Surface>& surface);

    virtual void startCameraRecording();
    virtual void stopCameraRecording();
@@ -91,6 +151,21 @@ private:
    void releaseQueuedFrames();
    void releaseOneRecordingFrame(const sp<IMemory>& frame);


    status_t init(const sp<ICamera>& camera, int32_t cameraId,
                Size videoSize, int32_t frameRate);
    status_t isCameraAvailable(const sp<ICamera>& camera, int32_t cameraId);
    status_t isCameraColorFormatSupported(const CameraParameters& params);
    status_t configureCamera(CameraParameters* params,
                    int32_t width, int32_t height,
                    int32_t frameRate);

    status_t checkVideoSize(const CameraParameters& params,
                    int32_t width, int32_t height);

    status_t checkFrameRate(const CameraParameters& params,
                    int32_t frameRate);

    CameraSource(const CameraSource &);
    CameraSource &operator=(const CameraSource &);
};
+14 −13
Original line number Diff line number Diff line
@@ -31,15 +31,13 @@ class Camera;

class CameraSourceTimeLapse : public CameraSource {
public:
    static CameraSourceTimeLapse *Create(
        int64_t timeBetweenTimeLapseFrameCaptureUs,
        int32_t width, int32_t height,
        int32_t videoFrameRate);

    static CameraSourceTimeLapse *CreateFromCamera(const sp<Camera> &camera,
        int64_t timeBetweenTimeLapseFrameCaptureUs,
        int32_t width, int32_t height,
        int32_t videoFrameRate);
    static CameraSourceTimeLapse *CreateFromCamera(
        const sp<ICamera> &camera,
        int32_t cameraId,
        Size videoSize,
        int32_t videoFrameRate,
        const sp<Surface>& surface,
        int64_t timeBetweenTimeLapseFrameCaptureUs);

    virtual ~CameraSourceTimeLapse();

@@ -132,10 +130,13 @@ private:
    // Status code for last read.
    status_t mLastReadStatus;

    CameraSourceTimeLapse(const sp<Camera> &camera,
        int64_t timeBetweenTimeLapseFrameCaptureUs,
        int32_t width, int32_t height,
        int32_t videoFrameRate);
    CameraSourceTimeLapse(
        const sp<ICamera> &camera,
        int32_t cameraId,
        Size videoSize,
        int32_t videoFrameRate,
        const sp<Surface>& surface,
        int64_t timeBetweenTimeLapseFrameCaptureUs);

    // Wrapper over CameraSource::signalBufferReturned() to implement quick stop.
    // It only handles the case when mLastReadBufferCopy is signalled. Otherwise
+11 −161
Original line number Diff line number Diff line
@@ -20,7 +20,6 @@

#include "StagefrightRecorder.h"

#include <binder/IPCThreadState.h>
#include <media/stagefright/AudioSource.h>
#include <media/stagefright/AMRWriter.h>
#include <media/stagefright/CameraSource.h>
@@ -35,7 +34,6 @@
#include <media/stagefright/OMXCodec.h>
#include <media/MediaProfiles.h>
#include <camera/ICamera.h>
#include <camera/Camera.h>
#include <camera/CameraParameters.h>
#include <surfaceflinger/Surface.h>
#include <utils/Errors.h>
@@ -184,22 +182,7 @@ status_t StagefrightRecorder::setCamera(const sp<ICamera> &camera) {
        return BAD_VALUE;
    }

    int64_t token = IPCThreadState::self()->clearCallingIdentity();
    mFlags &= ~FLAGS_HOT_CAMERA;
    mCamera = Camera::create(camera);
    if (mCamera == 0) {
        LOGE("Unable to connect to camera");
        IPCThreadState::self()->restoreCallingIdentity(token);
        return -EBUSY;
    }

    LOGV("Connected to camera");
    if (mCamera->previewEnabled()) {
        LOGV("camera is hot");
        mFlags |= FLAGS_HOT_CAMERA;
    }
    IPCThreadState::self()->restoreCallingIdentity(token);

    mCamera = camera;
    return OK;
}

@@ -966,66 +949,7 @@ void StagefrightRecorder::clipVideoFrameWidth() {
    }
}

/*
 * Check to see whether the requested video width and height is one
 * of the supported sizes. It returns true if so; otherwise, it
 * returns false.
 */
bool StagefrightRecorder::isVideoSizeSupported(
    const Vector<Size>& supportedSizes) const {

    LOGV("isVideoSizeSupported");
    for (size_t i = 0; i < supportedSizes.size(); ++i) {
        if (mVideoWidth  == supportedSizes[i].width &&
            mVideoHeight == supportedSizes[i].height) {
            return true;
        }
    }
    return false;
}

/*
 * If the preview and video output is separate, we only set the
 * the video size, and applications should set the preview size
 * to some proper value, and the recording framework will not
 * change the preview size; otherwise, if the video and preview
 * output is the same, we need to set the preview to be the same
 * as the requested video size.
 *
 * On return, it also returns whether the setVideoSize() is
 * supported.
 */
status_t StagefrightRecorder::setCameraVideoSize(
    CameraParameters* params,
    bool* isSetVideoSizeSupported) {
    LOGV("setCameraVideoSize: %dx%d", mVideoWidth, mVideoHeight);

    // Check whether the requested video size is supported
    Vector<Size> sizes;
    params->getSupportedVideoSizes(sizes);
    *isSetVideoSizeSupported = true;
    if (sizes.size() == 0) {
        LOGD("Camera does not support setVideoSize()");
        params->getSupportedPreviewSizes(sizes);
        *isSetVideoSizeSupported = false;
    }
    if (!isVideoSizeSupported(sizes)) {
        LOGE("Camera does not support video size (%dx%d)!",
            mVideoWidth, mVideoHeight);
        return BAD_VALUE;
    }

    // Actually set the video size
    if (isSetVideoSizeSupported) {
        params->setVideoSize(mVideoWidth, mVideoHeight);
    } else {
        params->setPreviewSize(mVideoWidth, mVideoHeight);
    }

    return OK;
}

status_t StagefrightRecorder::setupCamera() {
status_t StagefrightRecorder::checkVideoEncoderCapabilities() {
    if (!mCaptureTimeLapse) {
        // Dont clip for time lapse capture as encoder will have enough
        // time to encode because of slow capture rate of time lapse.
@@ -1034,67 +958,6 @@ status_t StagefrightRecorder::setupCamera() {
        clipVideoFrameWidth();
        clipVideoFrameHeight();
    }

    int64_t token = IPCThreadState::self()->clearCallingIdentity();
    if (mCamera == 0) {
        mCamera = Camera::connect(mCameraId);
        if (mCamera == 0) {
            LOGE("Camera connection could not be established.");
            return -EBUSY;
        }
        mFlags &= ~FLAGS_HOT_CAMERA;
        mCamera->lock();
    }

    // Set the actual video recording frame size
    CameraParameters params(mCamera->getParameters());

    // dont change the preview size because time lapse may be using still camera
    // as mVideoWidth, mVideoHeight may correspond to HD resolution not
    // supported by the video camera.
    bool isSetVideoSizeSupported = false;
    if (!mCaptureTimeLapse) {
        if (OK != setCameraVideoSize(&params, &isSetVideoSizeSupported)) {
            return BAD_VALUE;
        }
    }

    params.setPreviewFrameRate(mFrameRate);
    String8 s = params.flatten();
    if (OK != mCamera->setParameters(s)) {
        LOGE("Could not change settings."
             " Someone else is using camera %d?", mCameraId);
        return -EBUSY;
    }
    CameraParameters newCameraParams(mCamera->getParameters());

    // Check on video frame size
    int frameWidth = 0, frameHeight = 0;
    if (isSetVideoSizeSupported) {
        newCameraParams.getVideoSize(&frameWidth, &frameHeight);
    } else {
        newCameraParams.getPreviewSize(&frameWidth, &frameHeight);
    }
    if (!mCaptureTimeLapse &&
        (frameWidth  < 0 || frameWidth  != mVideoWidth ||
        frameHeight < 0 || frameHeight != mVideoHeight)) {
        LOGE("Failed to set the video frame size to %dx%d",
                mVideoWidth, mVideoHeight);
        IPCThreadState::self()->restoreCallingIdentity(token);
        return UNKNOWN_ERROR;
    }

    // Check on video frame rate
    int frameRate = newCameraParams.getPreviewFrameRate();
    if (frameRate < 0 || (frameRate - mFrameRate) != 0) {
        LOGE("Failed to set frame rate to %d fps. The actual "
             "frame rate is %d", mFrameRate, frameRate);
    }

    // This CHECK is good, since we just passed the lock/unlock
    // check earlier by calling mCamera->setParameters().
    CHECK_EQ(OK, mCamera->setPreviewDisplay(mPreviewSurface));
    IPCThreadState::self()->restoreCallingIdentity(token);
    return OK;
}

@@ -1116,15 +979,18 @@ void StagefrightRecorder::clipVideoFrameHeight() {
}

status_t StagefrightRecorder::setupCameraSource(sp<CameraSource> *cameraSource) {
    status_t err = setupCamera();
    if (err != OK) return err;

    Size videoSize;
    videoSize.width = mVideoWidth;
    videoSize.height = mVideoHeight;
    if (mCaptureTimeLapse) {
        mCameraSourceTimeLapse = CameraSourceTimeLapse::CreateFromCamera(mCamera,
                mTimeBetweenTimeLapseFrameCaptureUs, mVideoWidth, mVideoHeight, mFrameRate);
        mCameraSourceTimeLapse = CameraSourceTimeLapse::CreateFromCamera(
                mCamera, mCameraId,
                videoSize, mFrameRate, mPreviewSurface,
                mTimeBetweenTimeLapseFrameCaptureUs);
        *cameraSource = mCameraSourceTimeLapse;
    } else {
        *cameraSource = CameraSource::CreateFromCamera(mCamera);
        *cameraSource = CameraSource::CreateFromCamera(
                mCamera, mCameraId, videoSize, mFrameRate, mPreviewSurface);
    }
    CHECK(*cameraSource != NULL);

@@ -1411,19 +1277,6 @@ status_t StagefrightRecorder::stop() {
        mWriter.clear();
    }

    if (mCamera != 0) {
        LOGV("Disconnect camera");
        int64_t token = IPCThreadState::self()->clearCallingIdentity();
        if ((mFlags & FLAGS_HOT_CAMERA) == 0) {
            LOGV("Camera was cold when we started, stopping preview");
            mCamera->stopPreview();
        }
        mCamera->unlock();
        mCamera.clear();
        IPCThreadState::self()->restoreCallingIdentity(token);
        mFlags = 0;
    }

    if (mOutputFd >= 0) {
        ::close(mOutputFd);
        mOutputFd = -1;
@@ -1490,7 +1343,6 @@ status_t StagefrightRecorder::reset() {

    mOutputFd = -1;
    mOutputFdAux = -1;
    mFlags = 0;

    return OK;
}
@@ -1561,8 +1413,6 @@ status_t StagefrightRecorder::dump(
    result.append(buffer);
    snprintf(buffer, SIZE, "     Camera Id: %d\n", mCameraId);
    result.append(buffer);
    snprintf(buffer, SIZE, "     Camera flags: %d\n", mFlags);
    result.append(buffer);
    snprintf(buffer, SIZE, "     Encoder: %d\n", mVideoEncoder);
    result.append(buffer);
    snprintf(buffer, SIZE, "     Encoder profile: %d\n", mVideoEncoderProfile);
+2 −11
Original line number Diff line number Diff line
@@ -63,12 +63,7 @@ struct StagefrightRecorder : public MediaRecorderBase {
    virtual status_t dump(int fd, const Vector<String16>& args) const;

private:
    enum CameraFlags {
        FLAGS_SET_CAMERA = 1L << 0,
        FLAGS_HOT_CAMERA = 1L << 1,
    };

    sp<Camera> mCamera;
    sp<ICamera> mCamera;
    sp<Surface> mPreviewSurface;
    sp<IMediaRecorderClient> mListener;
    sp<MediaWriter> mWriter, mWriterAux;
@@ -107,7 +102,6 @@ private:

    String8 mParams;
    int mOutputFd, mOutputFdAux;
    int32_t mFlags;

    MediaProfiles *mEncoderProfiles;

@@ -125,10 +119,7 @@ private:
    status_t startAACRecording();
    status_t startRTPRecording();
    sp<MediaSource> createAudioSource();
    status_t setupCamera();
    bool     isVideoSizeSupported(const Vector<Size>& supportedSizes) const;
    status_t setCameraVideoSize(CameraParameters* params,
                bool *isSetVideoSizeSupported);
    status_t checkVideoEncoderCapabilities();
    status_t setupCameraSource(sp<CameraSource> *cameraSource);
    status_t setupAudioEncoder(const sp<MediaWriter>& writer);
    status_t setupVideoEncoder(
+345 −37

File changed.

Preview size limit exceeded, changes collapsed.

Loading