From 89fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5 Mon Sep 17 00:00:00 2001 From: The Android Open Source Project Date: Tue, 3 Mar 2009 19:31:44 -0800 Subject: auto import from //depot/cupcake/@135843 --- media/libmedia/mediarecorder.cpp | 617 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 617 insertions(+) create mode 100644 media/libmedia/mediarecorder.cpp (limited to 'media/libmedia/mediarecorder.cpp') diff --git a/media/libmedia/mediarecorder.cpp b/media/libmedia/mediarecorder.cpp new file mode 100644 index 0000000..98aac39 --- /dev/null +++ b/media/libmedia/mediarecorder.cpp @@ -0,0 +1,617 @@ +/* + ** + ** Copyright (c) 2008 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 "MediaRecorder" +#include +#include +#include +#include +#include +#include + +namespace android { + +status_t MediaRecorder::setCamera(const sp& camera) +{ + LOGV("setCamera(%p)", camera.get()); + if(mMediaRecorder == NULL) { + LOGE("media recorder is not initialized yet"); + return INVALID_OPERATION; + } + if (!(mCurrentState & MEDIA_RECORDER_IDLE)) { + LOGE("setCamera called in an invalid state(%d)", mCurrentState); + return INVALID_OPERATION; + } + + status_t ret = mMediaRecorder->setCamera(camera); + if (OK != ret) { + LOGV("setCamera failed: %d", ret); + mCurrentState = MEDIA_RECORDER_ERROR; + return UNKNOWN_ERROR; + } + return ret; +} + +status_t MediaRecorder::setPreviewSurface(const sp& surface) +{ + LOGV("setPreviewSurface(%p)", surface.get()); + if(mMediaRecorder == NULL) { + LOGE("media recorder is not initialized yet"); + return INVALID_OPERATION; + } + if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) { + LOGE("setPreviewSurface called in an invalid state(%d)", mCurrentState); + return INVALID_OPERATION; + } + if (!mIsVideoSourceSet) { + LOGE("try to set preview surface without setting the video source first"); + return INVALID_OPERATION; + } + + status_t ret = mMediaRecorder->setPreviewSurface(surface->getISurface()); + if (OK != ret) { + LOGV("setPreviewSurface failed: %d", ret); + mCurrentState = MEDIA_RECORDER_ERROR; + return UNKNOWN_ERROR; + } + return ret; +} + +status_t MediaRecorder::init() +{ + LOGV("init"); + if(mMediaRecorder == NULL) { + LOGE("media recorder is not initialized yet"); + return INVALID_OPERATION; + } + if (!(mCurrentState & MEDIA_RECORDER_IDLE)) { + LOGE("init called in an invalid state(%d)", mCurrentState); + return INVALID_OPERATION; + } + + status_t ret = mMediaRecorder->init(); + if (OK != ret) { + LOGV("init failed: %d", ret); + mCurrentState = MEDIA_RECORDER_ERROR; + return UNKNOWN_ERROR; + } + + ret = mMediaRecorder->setListener(this); + if (OK != ret) { + LOGV("setListener failed: %d", ret); + mCurrentState = MEDIA_RECORDER_ERROR; + return UNKNOWN_ERROR; + } + + mCurrentState = MEDIA_RECORDER_INITIALIZED; + return ret; +} + +status_t MediaRecorder::setVideoSource(int vs) +{ + LOGV("setVideoSource(%d)", vs); + if(mMediaRecorder == NULL) { + LOGE("media recorder is not initialized yet"); + return INVALID_OPERATION; + } + if (mIsVideoSourceSet) { + LOGE("video source has already been set"); + return INVALID_OPERATION; + } + if (mCurrentState & MEDIA_RECORDER_IDLE) { + LOGV("Call init() since the media recorder is not initialized yet"); + status_t ret = init(); + if (OK != ret) { + return ret; + } + } + if (!(mCurrentState & MEDIA_RECORDER_INITIALIZED)) { + LOGE("setVideoSource called in an invalid state(%d)", mCurrentState); + return INVALID_OPERATION; + } + + status_t ret = mMediaRecorder->setVideoSource(vs); + if (OK != ret) { + LOGV("setVideoSource failed: %d", ret); + mCurrentState = MEDIA_RECORDER_ERROR; + return UNKNOWN_ERROR; + } + mIsVideoSourceSet = true; + return ret; +} + +status_t MediaRecorder::setAudioSource(int as) +{ + LOGV("setAudioSource(%d)", as); + if(mMediaRecorder == NULL) { + LOGE("media recorder is not initialized yet"); + return INVALID_OPERATION; + } + if (mCurrentState & MEDIA_RECORDER_IDLE) { + LOGV("Call init() since the media recorder is not initialized yet"); + status_t ret = init(); + if (OK != ret) { + return ret; + } + } + if (mIsAudioSourceSet) { + LOGE("audio source has already been set"); + return INVALID_OPERATION; + } + if (!(mCurrentState & MEDIA_RECORDER_INITIALIZED)) { + LOGE("setAudioSource called in an invalid state(%d)", mCurrentState); + return INVALID_OPERATION; + } + + status_t ret = mMediaRecorder->setAudioSource(as); + if (OK != ret) { + LOGV("setAudioSource failed: %d", ret); + mCurrentState = MEDIA_RECORDER_ERROR; + return UNKNOWN_ERROR; + } + mIsAudioSourceSet = true; + return ret; +} + +status_t MediaRecorder::setOutputFormat(int of) +{ + LOGV("setOutputFormat(%d)", of); + if(mMediaRecorder == NULL) { + LOGE("media recorder is not initialized yet"); + return INVALID_OPERATION; + } + if (!(mCurrentState & MEDIA_RECORDER_INITIALIZED)) { + LOGE("setOutputFormat called in an invalid state: %d", mCurrentState); + return INVALID_OPERATION; + } + if (mIsVideoSourceSet && of >= OUTPUT_FORMAT_RAW_AMR) { + LOGE("output format (%d) is meant for audio recording only and incompatible with video recording", of); + return INVALID_OPERATION; + } + + status_t ret = mMediaRecorder->setOutputFormat(of); + if (OK != ret) { + LOGE("setOutputFormat failed: %d", ret); + mCurrentState = MEDIA_RECORDER_ERROR; + return UNKNOWN_ERROR; + } + mCurrentState = MEDIA_RECORDER_DATASOURCE_CONFIGURED; + return ret; +} + +status_t MediaRecorder::setVideoEncoder(int ve) +{ + LOGV("setVideoEncoder(%d)", ve); + if(mMediaRecorder == NULL) { + LOGE("media recorder is not initialized yet"); + return INVALID_OPERATION; + } + if (!mIsVideoSourceSet) { + LOGE("try to set the video encoder without setting the video source first"); + return INVALID_OPERATION; + } + if (mIsVideoEncoderSet) { + LOGE("video encoder has already been set"); + return INVALID_OPERATION; + } + if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) { + LOGE("setVideoEncoder called in an invalid state(%d)", mCurrentState); + return INVALID_OPERATION; + } + + status_t ret = mMediaRecorder->setVideoEncoder(ve); + if (OK != ret) { + LOGV("setVideoEncoder failed: %d", ret); + mCurrentState = MEDIA_RECORDER_ERROR; + return UNKNOWN_ERROR; + } + mIsVideoEncoderSet = true; + return ret; +} + +status_t MediaRecorder::setAudioEncoder(int ae) +{ + LOGV("setAudioEncoder(%d)", ae); + if(mMediaRecorder == NULL) { + LOGE("media recorder is not initialized yet"); + return INVALID_OPERATION; + } + if (!mIsAudioSourceSet) { + LOGE("try to set the audio encoder without setting the audio source first"); + return INVALID_OPERATION; + } + if (mIsAudioEncoderSet) { + LOGE("audio encoder has already been set"); + return INVALID_OPERATION; + } + if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) { + LOGE("setAudioEncoder called in an invalid state(%d)", mCurrentState); + return INVALID_OPERATION; + } + + status_t ret = mMediaRecorder->setAudioEncoder(ae); + if (OK != ret) { + LOGV("setAudioEncoder failed: %d", ret); + mCurrentState = MEDIA_RECORDER_ERROR; + return UNKNOWN_ERROR; + } + mIsAudioEncoderSet = true; + return ret; +} + +status_t MediaRecorder::setOutputFile(const char* path) +{ + LOGV("setOutputFile(%s)", path); + if(mMediaRecorder == NULL) { + LOGE("media recorder is not initialized yet"); + return INVALID_OPERATION; + } + if (mIsOutputFileSet) { + LOGE("output file has already been set"); + return INVALID_OPERATION; + } + if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) { + LOGE("setOutputFile called in an invalid state(%d)", mCurrentState); + return INVALID_OPERATION; + } + + status_t ret = mMediaRecorder->setOutputFile(path); + if (OK != ret) { + LOGV("setOutputFile failed: %d", ret); + mCurrentState = MEDIA_RECORDER_ERROR; + return UNKNOWN_ERROR; + } + mIsOutputFileSet = true; + return ret; +} + +status_t MediaRecorder::setOutputFile(int fd, int64_t offset, int64_t length) +{ + LOGV("setOutputFile(%d, %lld, %lld)", fd, offset, length); + if(mMediaRecorder == NULL) { + LOGE("media recorder is not initialized yet"); + return INVALID_OPERATION; + } + if (mIsOutputFileSet) { + LOGE("output file has already been set"); + return INVALID_OPERATION; + } + if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) { + LOGE("setOutputFile called in an invalid state(%d)", mCurrentState); + return INVALID_OPERATION; + } + + status_t ret = mMediaRecorder->setOutputFile(fd, offset, length); + if (OK != ret) { + LOGV("setOutputFile failed: %d", ret); + mCurrentState = MEDIA_RECORDER_ERROR; + return UNKNOWN_ERROR; + } + mIsOutputFileSet = true; + return ret; +} + +status_t MediaRecorder::setVideoSize(int width, int height) +{ + LOGV("setVideoSize(%d, %d)", width, height); + if(mMediaRecorder == NULL) { + LOGE("media recorder is not initialized yet"); + return INVALID_OPERATION; + } + if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) { + LOGE("setVideoSize called in an invalid state: %d", mCurrentState); + return INVALID_OPERATION; + } + if (!mIsVideoSourceSet) { + LOGE("try to set video size without setting video source first"); + return INVALID_OPERATION; + } + + status_t ret = mMediaRecorder->setVideoSize(width, height); + if (OK != ret) { + LOGE("setVideoSize failed: %d", ret); + mCurrentState = MEDIA_RECORDER_ERROR; + return UNKNOWN_ERROR; + } + return ret; +} + +status_t MediaRecorder::setVideoFrameRate(int frames_per_second) +{ + LOGV("setVideoFrameRate(%d)", frames_per_second); + if(mMediaRecorder == NULL) { + LOGE("media recorder is not initialized yet"); + return INVALID_OPERATION; + } + if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) { + LOGE("setVideoFrameRate called in an invalid state: %d", mCurrentState); + return INVALID_OPERATION; + } + if (!mIsVideoSourceSet) { + LOGE("try to set video frame rate without setting video source first"); + return INVALID_OPERATION; + } + + status_t ret = mMediaRecorder->setVideoFrameRate(frames_per_second); + if (OK != ret) { + LOGE("setVideoFrameRate failed: %d", ret); + mCurrentState = MEDIA_RECORDER_ERROR; + return UNKNOWN_ERROR; + } + return ret; +} + +status_t MediaRecorder::prepare() +{ + LOGV("prepare"); + if(mMediaRecorder == NULL) { + LOGE("media recorder is not initialized yet"); + return INVALID_OPERATION; + } + if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) { + LOGE("prepare called in an invalid state: %d", mCurrentState); + return INVALID_OPERATION; + } + if (mIsAudioSourceSet != mIsAudioEncoderSet) { + if (mIsAudioSourceSet) { + LOGE("audio source is set, but audio encoder is not set"); + } else { // must not happen, since setAudioEncoder checks this already + LOGE("audio encoder is set, but audio source is not set"); + } + return INVALID_OPERATION; + } + + if (mIsVideoSourceSet != mIsVideoEncoderSet) { + if (mIsVideoSourceSet) { + LOGE("video source is set, but video encoder is not set"); + } else { // must not happen, since setVideoEncoder checks this already + LOGE("video encoder is set, but video source is not set"); + } + return INVALID_OPERATION; + } + + status_t ret = mMediaRecorder->prepare(); + if (OK != ret) { + LOGE("prepare failed: %d", ret); + mCurrentState = MEDIA_RECORDER_ERROR; + return UNKNOWN_ERROR; + } + mCurrentState = MEDIA_RECORDER_PREPARED; + return ret; +} + +status_t MediaRecorder::getMaxAmplitude(int* max) +{ + LOGV("getMaxAmplitude"); + if(mMediaRecorder == NULL) { + LOGE("media recorder is not initialized yet"); + return INVALID_OPERATION; + } + if (mCurrentState & MEDIA_RECORDER_ERROR) { + LOGE("getMaxAmplitude called in an invalid state: %d", mCurrentState); + return INVALID_OPERATION; + } + + status_t ret = mMediaRecorder->getMaxAmplitude(max); + if (OK != ret) { + LOGE("getMaxAmplitude failed: %d", ret); + mCurrentState = MEDIA_RECORDER_ERROR; + return UNKNOWN_ERROR; + } + return ret; +} + +status_t MediaRecorder::start() +{ + LOGV("start"); + if (mMediaRecorder == NULL) { + LOGE("media recorder is not initialized yet"); + return INVALID_OPERATION; + } + if (!(mCurrentState & MEDIA_RECORDER_PREPARED)) { + LOGE("start called in an invalid state: %d", mCurrentState); + return INVALID_OPERATION; + } + + status_t ret = mMediaRecorder->start(); + if (OK != ret) { + LOGE("start failed: %d", ret); + mCurrentState = MEDIA_RECORDER_ERROR; + return UNKNOWN_ERROR; + } + mCurrentState = MEDIA_RECORDER_RECORDING; + return ret; +} + +status_t MediaRecorder::stop() +{ + LOGV("stop"); + if (mMediaRecorder == NULL) { + LOGE("media recorder is not initialized yet"); + return INVALID_OPERATION; + } + if (!(mCurrentState & MEDIA_RECORDER_RECORDING)) { + LOGE("stop called in an invalid state: %d", mCurrentState); + return INVALID_OPERATION; + } + + status_t ret = mMediaRecorder->stop(); + if (OK != ret) { + LOGE("stop failed: %d", ret); + mCurrentState = MEDIA_RECORDER_ERROR; + return UNKNOWN_ERROR; + } + mCurrentState = MEDIA_RECORDER_IDLE; + return ret; +} + +// Reset should be OK in any state +status_t MediaRecorder::reset() +{ + LOGV("reset"); + if (mMediaRecorder == NULL) { + LOGE("media recorder is not initialized yet"); + return INVALID_OPERATION; + } + + doCleanUp(); + status_t ret = UNKNOWN_ERROR; + switch(mCurrentState) { + case MEDIA_RECORDER_IDLE: + ret = OK; + break; + + case MEDIA_RECORDER_RECORDING: + case MEDIA_RECORDER_DATASOURCE_CONFIGURED: + case MEDIA_RECORDER_PREPARED: + case MEDIA_RECORDER_ERROR: { + ret = doReset(); + if (OK != ret) { + return ret; // No need to continue + } + } // Intentional fall through + case MEDIA_RECORDER_INITIALIZED: + ret = close(); + break; + + default: { + LOGE("Unexpected non-existing state: %d", mCurrentState); + break; + } + } + return ret; +} + +status_t MediaRecorder::close() +{ + LOGV("close"); + if (!(mCurrentState & MEDIA_RECORDER_INITIALIZED)) { + LOGE("close called in an invalid state: %d", mCurrentState); + return INVALID_OPERATION; + } + status_t ret = mMediaRecorder->close(); + if (OK != ret) { + LOGE("close failed: %d", ret); + mCurrentState = MEDIA_RECORDER_ERROR; + return UNKNOWN_ERROR; + } else { + mCurrentState = MEDIA_RECORDER_IDLE; + } + return ret; +} + +status_t MediaRecorder::doReset() +{ + LOGV("doReset"); + status_t ret = mMediaRecorder->reset(); + if (OK != ret) { + LOGE("doReset failed: %d", ret); + mCurrentState = MEDIA_RECORDER_ERROR; + return UNKNOWN_ERROR; + } else { + mCurrentState = MEDIA_RECORDER_INITIALIZED; + } + return ret; +} + +void MediaRecorder::doCleanUp() +{ + LOGV("doCleanUp"); + mIsAudioSourceSet = false; + mIsVideoSourceSet = false; + mIsAudioEncoderSet = false; + mIsVideoEncoderSet = false; + mIsOutputFileSet = false; +} + +// Release should be OK in any state +status_t MediaRecorder::release() +{ + LOGV("release"); + if (mMediaRecorder != NULL) { + return mMediaRecorder->release(); + } + return INVALID_OPERATION; +} + +MediaRecorder::MediaRecorder() +{ + LOGV("constructor"); + sp sm = defaultServiceManager(); + sp binder; + + do { + binder = sm->getService(String16("media.player")); + if (binder != NULL) { + break; + } + LOGW("MediaPlayerService not published, waiting..."); + usleep(500000); // 0.5 s + } while(true); + + sp service = interface_cast(binder); + if (service != NULL) { + mMediaRecorder = service->createMediaRecorder(getpid()); + } + if (mMediaRecorder != NULL) { + mCurrentState = MEDIA_RECORDER_IDLE; + } + doCleanUp(); +} + +status_t MediaRecorder::initCheck() +{ + return mMediaRecorder != 0 ? NO_ERROR : NO_INIT; +} + +MediaRecorder::~MediaRecorder() +{ + LOGV("destructor"); + if (mMediaRecorder != NULL) { + mMediaRecorder.clear(); + } +} + +status_t MediaRecorder::setListener(const sp& listener) +{ + LOGV("setListener"); + Mutex::Autolock _l(mLock); + mListener = listener; + + return NO_ERROR; +} + +void MediaRecorder::notify(int msg, int ext1, int ext2) +{ + LOGV("message received msg=%d, ext1=%d, ext2=%d", msg, ext1, ext2); + + sp listener; + mLock.lock(); + listener = mListener; + mLock.unlock(); + + if (listener != NULL) { + Mutex::Autolock _l(mNotifyLock); + LOGV("callback application"); + listener->notify(msg, ext1, ext2); + LOGV("back from callback"); + } +} + +}; // namespace android + -- cgit v1.1