diff options
Diffstat (limited to 'media/libmediaplayerservice')
-rw-r--r-- | media/libmediaplayerservice/MediaRecorderClient.cpp | 15 | ||||
-rw-r--r-- | media/libmediaplayerservice/MediaRecorderClient.h | 68 | ||||
-rw-r--r-- | media/libmediaplayerservice/StagefrightRecorder.cpp | 109 | ||||
-rw-r--r-- | media/libmediaplayerservice/StagefrightRecorder.h | 18 |
4 files changed, 160 insertions, 50 deletions
diff --git a/media/libmediaplayerservice/MediaRecorderClient.cpp b/media/libmediaplayerservice/MediaRecorderClient.cpp index 115db1a..905b885 100644 --- a/media/libmediaplayerservice/MediaRecorderClient.cpp +++ b/media/libmediaplayerservice/MediaRecorderClient.cpp @@ -41,6 +41,7 @@ #include "MediaPlayerService.h" #include "StagefrightRecorder.h" +#include <gui/ISurfaceTexture.h> namespace android { @@ -57,6 +58,20 @@ static bool checkPermission(const char* permissionString) { return ok; } + +sp<ISurfaceTexture> MediaRecorderClient::querySurfaceMediaSource() +{ + LOGV("Query SurfaceMediaSource"); + Mutex::Autolock lock(mLock); + if (mRecorder == NULL) { + LOGE("recorder is not initialized"); + return NULL; + } + return mRecorder->querySurfaceMediaSource(); +} + + + status_t MediaRecorderClient::setCamera(const sp<ICamera>& camera, const sp<ICameraRecordingProxy>& proxy) { diff --git a/media/libmediaplayerservice/MediaRecorderClient.h b/media/libmediaplayerservice/MediaRecorderClient.h index bbca529..c87a3c0 100644 --- a/media/libmediaplayerservice/MediaRecorderClient.h +++ b/media/libmediaplayerservice/MediaRecorderClient.h @@ -25,45 +25,51 @@ namespace android { class MediaRecorderBase; class MediaPlayerService; class ICameraRecordingProxy; +class ISurfaceTexture; class MediaRecorderClient : public BnMediaRecorder { public: - virtual status_t setCamera(const sp<ICamera>& camera, - const sp<ICameraRecordingProxy>& proxy); - virtual status_t setPreviewSurface(const sp<Surface>& surface); - virtual status_t setVideoSource(int vs); - virtual status_t setAudioSource(int as); - virtual status_t setOutputFormat(int of); - virtual status_t setVideoEncoder(int ve); - virtual status_t setAudioEncoder(int ae); - virtual status_t setOutputFile(const char* path); - virtual status_t setOutputFile(int fd, int64_t offset, int64_t length); - virtual status_t setOutputFileAuxiliary(int fd); - virtual status_t setVideoSize(int width, int height); - virtual status_t setVideoFrameRate(int frames_per_second); - virtual status_t setParameters(const String8& params); - virtual status_t setListener(const sp<IMediaRecorderClient>& listener); - virtual status_t prepare(); - virtual status_t getMaxAmplitude(int* max); - virtual status_t start(); - virtual status_t stop(); - virtual status_t reset(); - virtual status_t init(); - virtual status_t close(); - virtual status_t release(); + virtual status_t setCamera(const sp<ICamera>& camera, + const sp<ICameraRecordingProxy>& proxy); + virtual status_t setPreviewSurface(const sp<Surface>& surface); + virtual status_t setVideoSource(int vs); + virtual status_t setAudioSource(int as); + virtual status_t setOutputFormat(int of); + virtual status_t setVideoEncoder(int ve); + virtual status_t setAudioEncoder(int ae); + virtual status_t setOutputFile(const char* path); + virtual status_t setOutputFile(int fd, int64_t offset, + int64_t length); + virtual status_t setOutputFileAuxiliary(int fd); + virtual status_t setVideoSize(int width, int height); + virtual status_t setVideoFrameRate(int frames_per_second); + virtual status_t setParameters(const String8& params); + virtual status_t setListener( + const sp<IMediaRecorderClient>& listener); + virtual status_t prepare(); + virtual status_t getMaxAmplitude(int* max); + virtual status_t start(); + virtual status_t stop(); + virtual status_t reset(); + virtual status_t init(); + virtual status_t close(); + virtual status_t release(); + virtual status_t dump(int fd, const Vector<String16>& args) const; + virtual sp<ISurfaceTexture> querySurfaceMediaSource(); - virtual status_t dump(int fd, const Vector<String16>& args) const; private: - friend class MediaPlayerService; // for accessing private constructor + friend class MediaPlayerService; // for accessing private constructor - MediaRecorderClient(const sp<MediaPlayerService>& service, pid_t pid); - virtual ~MediaRecorderClient(); + MediaRecorderClient( + const sp<MediaPlayerService>& service, + pid_t pid); + virtual ~MediaRecorderClient(); - pid_t mPid; - Mutex mLock; - MediaRecorderBase *mRecorder; - sp<MediaPlayerService> mMediaPlayerService; + pid_t mPid; + Mutex mLock; + MediaRecorderBase *mRecorder; + sp<MediaPlayerService> mMediaPlayerService; }; }; // namespace android diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp index 223e0be..6427bb7 100644 --- a/media/libmediaplayerservice/StagefrightRecorder.cpp +++ b/media/libmediaplayerservice/StagefrightRecorder.cpp @@ -38,10 +38,12 @@ #include <media/stagefright/MetaData.h> #include <media/stagefright/OMXClient.h> #include <media/stagefright/OMXCodec.h> +#include <media/stagefright/SurfaceMediaSource.h> #include <media/MediaProfiles.h> #include <camera/ICamera.h> #include <camera/CameraParameters.h> #include <surfaceflinger/Surface.h> + #include <utils/Errors.h> #include <sys/types.h> #include <ctype.h> @@ -69,7 +71,7 @@ StagefrightRecorder::StagefrightRecorder() mOutputFd(-1), mOutputFdAux(-1), mAudioSource(AUDIO_SOURCE_CNT), mVideoSource(VIDEO_SOURCE_LIST_END), - mStarted(false) { + mStarted(false), mSurfaceMediaSource(NULL) { LOGV("Constructor"); reset(); @@ -85,6 +87,14 @@ status_t StagefrightRecorder::init() { return OK; } +// The client side of mediaserver asks it to creat a SurfaceMediaSource +// and return a interface reference. The client side will use that +// while encoding GL Frames +sp<ISurfaceTexture> StagefrightRecorder::querySurfaceMediaSource() const { + LOGV("Get SurfaceMediaSource"); + return mSurfaceMediaSource; +} + status_t StagefrightRecorder::setAudioSource(audio_source_t as) { LOGV("setAudioSource: %d", as); if (as < AUDIO_SOURCE_DEFAULT || @@ -1006,13 +1016,13 @@ status_t StagefrightRecorder::startRTPRecording() { source = createAudioSource(); } else { - sp<CameraSource> cameraSource; - status_t err = setupCameraSource(&cameraSource); + sp<MediaSource> mediaSource; + status_t err = setupMediaSource(&mediaSource); if (err != OK) { return err; } - err = setupVideoEncoder(cameraSource, mVideoBitRate, &source); + err = setupVideoEncoder(mediaSource, mVideoBitRate, &source); if (err != OK) { return err; } @@ -1042,20 +1052,19 @@ status_t StagefrightRecorder::startMPEG2TSRecording() { } } - if (mVideoSource == VIDEO_SOURCE_DEFAULT - || mVideoSource == VIDEO_SOURCE_CAMERA) { + if (mVideoSource < VIDEO_SOURCE_LIST_END) { if (mVideoEncoder != VIDEO_ENCODER_H264) { return ERROR_UNSUPPORTED; } - sp<CameraSource> cameraSource; - status_t err = setupCameraSource(&cameraSource); + sp<MediaSource> mediaSource; + status_t err = setupMediaSource(&mediaSource); if (err != OK) { return err; } sp<MediaSource> encoder; - err = setupVideoEncoder(cameraSource, mVideoBitRate, &encoder); + err = setupVideoEncoder(mediaSource, mVideoBitRate, &encoder); if (err != OK) { return err; @@ -1289,6 +1298,60 @@ void StagefrightRecorder::clipVideoFrameHeight() { } } +// Set up the appropriate MediaSource depending on the chosen option +status_t StagefrightRecorder::setupMediaSource( + sp<MediaSource> *mediaSource) { + if (mVideoSource == VIDEO_SOURCE_DEFAULT + || mVideoSource == VIDEO_SOURCE_CAMERA) { + sp<CameraSource> cameraSource; + status_t err = setupCameraSource(&cameraSource); + if (err != OK) { + return err; + } + *mediaSource = cameraSource; + } else if (mVideoSource == VIDEO_SOURCE_GRALLOC_BUFFER) { + // If using GRAlloc buffers, setup surfacemediasource. + // Later a handle to that will be passed + // to the client side when queried + status_t err = setupSurfaceMediaSource(); + if (err != OK) { + return err; + } + *mediaSource = mSurfaceMediaSource; + } else { + return INVALID_OPERATION; + } + return OK; +} + +// setupSurfaceMediaSource creates a source with the given +// width and height and framerate. +// TODO: This could go in a static function inside SurfaceMediaSource +// similar to that in CameraSource +status_t StagefrightRecorder::setupSurfaceMediaSource() { + status_t err = OK; + mSurfaceMediaSource = new SurfaceMediaSource(mVideoWidth, mVideoHeight); + if (mSurfaceMediaSource == NULL) { + return NO_INIT; + } + + if (mFrameRate == -1) { + int32_t frameRate = 0; + CHECK (mSurfaceMediaSource->getFormat()->findInt32( + kKeyFrameRate, &frameRate)); + LOGI("Frame rate is not explicitly set. Use the current frame " + "rate (%d fps)", frameRate); + mFrameRate = frameRate; + } else { + err = mSurfaceMediaSource->setFrameRate(mFrameRate); + } + CHECK(mFrameRate != -1); + + mIsMetaDataStoredInVideoBuffers = + mSurfaceMediaSource->isMetaDataStoredInVideoBuffers(); + return err; +} + status_t StagefrightRecorder::setupCameraSource( sp<CameraSource> *cameraSource) { status_t err = OK; @@ -1465,29 +1528,37 @@ status_t StagefrightRecorder::setupMPEG4Recording( status_t err = OK; sp<MediaWriter> writer = new MPEG4Writer(outputFd); - if (mVideoSource == VIDEO_SOURCE_DEFAULT - || mVideoSource == VIDEO_SOURCE_CAMERA) { + if (mVideoSource < VIDEO_SOURCE_LIST_END) { - sp<MediaSource> cameraMediaSource; + sp<MediaSource> mediaSource; if (useSplitCameraSource) { + // TODO: Check if there is a better way to handle this + if (mVideoSource == VIDEO_SOURCE_GRALLOC_BUFFER) { + LOGE("Cannot use split camera when encoding frames"); + return INVALID_OPERATION; + } LOGV("Using Split camera source"); - cameraMediaSource = mCameraSourceSplitter->createClient(); + mediaSource = mCameraSourceSplitter->createClient(); } else { - sp<CameraSource> cameraSource; - err = setupCameraSource(&cameraSource); - cameraMediaSource = cameraSource; + err = setupMediaSource(&mediaSource); } + if ((videoWidth != mVideoWidth) || (videoHeight != mVideoHeight)) { + // TODO: Might be able to handle downsampling even if using GRAlloc + if (mVideoSource == VIDEO_SOURCE_GRALLOC_BUFFER) { + LOGE("Cannot change size or Downsample when encoding frames"); + return INVALID_OPERATION; + } // Use downsampling from the original source. - cameraMediaSource = - new VideoSourceDownSampler(cameraMediaSource, videoWidth, videoHeight); + mediaSource = + new VideoSourceDownSampler(mediaSource, videoWidth, videoHeight); } if (err != OK) { return err; } sp<MediaSource> encoder; - err = setupVideoEncoder(cameraMediaSource, videoBitRate, &encoder); + err = setupVideoEncoder(mediaSource, videoBitRate, &encoder); if (err != OK) { return err; } diff --git a/media/libmediaplayerservice/StagefrightRecorder.h b/media/libmediaplayerservice/StagefrightRecorder.h index 034b373..1618b92 100644 --- a/media/libmediaplayerservice/StagefrightRecorder.h +++ b/media/libmediaplayerservice/StagefrightRecorder.h @@ -36,6 +36,8 @@ struct MediaWriter; class MetaData; struct AudioSource; class MediaProfiles; +class ISurfaceTexture; +class SurfaceMediaSource; struct StagefrightRecorder : public MediaRecorderBase { StagefrightRecorder(); @@ -64,6 +66,8 @@ struct StagefrightRecorder : public MediaRecorderBase { virtual status_t reset(); virtual status_t getMaxAmplitude(int *max); virtual status_t dump(int fd, const Vector<String16>& args) const; + // Querying a SurfaceMediaSourcer + virtual sp<ISurfaceTexture> querySurfaceMediaSource() const; private: sp<ICamera> mCamera; @@ -109,12 +113,18 @@ private: sp<MediaSourceSplitter> mCameraSourceSplitter; sp<CameraSourceTimeLapse> mCameraSourceTimeLapse; + String8 mParams; bool mIsMetaDataStoredInVideoBuffers; MediaProfiles *mEncoderProfiles; bool mStarted; + // Needed when GLFrames are encoded. + // An <ISurfaceTexture> pointer + // will be sent to the client side using which the + // frame buffers will be queued and dequeued + sp<SurfaceMediaSource> mSurfaceMediaSource; status_t setupMPEG4Recording( bool useSplitCameraSource, @@ -134,7 +144,14 @@ private: sp<MediaSource> createAudioSource(); status_t checkVideoEncoderCapabilities(); status_t checkAudioEncoderCapabilities(); + // Generic MediaSource set-up. Returns the appropriate + // source (CameraSource or SurfaceMediaSource) + // depending on the videosource type + status_t setupMediaSource(sp<MediaSource> *mediaSource); status_t setupCameraSource(sp<CameraSource> *cameraSource); + // setup the surfacemediasource for the encoder + status_t setupSurfaceMediaSource(); + status_t setupAudioEncoder(const sp<MediaWriter>& writer); status_t setupVideoEncoder( sp<MediaSource> cameraSource, @@ -176,6 +193,7 @@ private: void clipNumberOfAudioChannels(); void setDefaultProfileIfNecessary(); + StagefrightRecorder(const StagefrightRecorder &); StagefrightRecorder &operator=(const StagefrightRecorder &); }; |