diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2009-03-02 22:54:33 -0800 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2009-03-02 22:54:33 -0800 |
commit | 99ffda877980468a9ae31e013cd10fb3645df1b0 (patch) | |
tree | dbcbf90028d4e60763724ca1bac4a63af7170973 /media/libmedia | |
parent | 925a349b45d1d16eaaca6a1f4827191831271ca0 (diff) | |
download | frameworks_av-99ffda877980468a9ae31e013cd10fb3645df1b0.zip frameworks_av-99ffda877980468a9ae31e013cd10fb3645df1b0.tar.gz frameworks_av-99ffda877980468a9ae31e013cd10fb3645df1b0.tar.bz2 |
auto import from //depot/cupcake/@137055
Diffstat (limited to 'media/libmedia')
-rw-r--r-- | media/libmedia/AudioRecord.cpp | 25 | ||||
-rw-r--r-- | media/libmedia/AudioTrack.cpp | 13 | ||||
-rw-r--r-- | media/libmedia/IMediaRecorder.cpp | 22 | ||||
-rw-r--r-- | media/libmedia/mediarecorder.cpp | 75 |
4 files changed, 128 insertions, 7 deletions
diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp index e833c85..7594ff0 100644 --- a/media/libmedia/AudioRecord.cpp +++ b/media/libmedia/AudioRecord.cpp @@ -128,8 +128,23 @@ status_t AudioRecord::set( return BAD_VALUE; } - // TODO: Get input frame count from hardware. - int minFrameCount = 1024*2; + // validate framecount + size_t inputBuffSizeInBytes = -1; + if (AudioSystem::getInputBufferSize(sampleRate, format, channelCount, &inputBuffSizeInBytes) + != NO_ERROR) { + LOGE("AudioSystem could not query the input buffer size."); + return NO_INIT; + } + if (inputBuffSizeInBytes == 0) { + LOGE("Recording parameters are not supported: sampleRate %d, channelCount %d, format %d", + sampleRate, channelCount, format); + return BAD_VALUE; + } + int frameSizeInBytes = channelCount * (format == AudioSystem::PCM_16_BIT ? 2 : 1); + + // We use 2* size of input buffer for ping pong use of record buffer. + int minFrameCount = 2 * inputBuffSizeInBytes / frameSizeInBytes; + LOGV("AudioRecord::set() minFrameCount = %d", minFrameCount); if (frameCount == 0) { frameCount = minFrameCount; @@ -144,7 +159,11 @@ status_t AudioRecord::set( // open record channel status_t status; sp<IAudioRecord> record = audioFlinger->openRecord(getpid(), streamType, - sampleRate, format, channelCount, frameCount, flags, &status); + sampleRate, format, + channelCount, + frameCount, + ((uint16_t)flags) << 16, + &status); if (record == 0) { LOGE("AudioFlinger could not create record track, status: %d", status); return status; diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp index f8520a7..2274521 100644 --- a/media/libmedia/AudioTrack.cpp +++ b/media/libmedia/AudioTrack.cpp @@ -168,6 +168,8 @@ status_t AudioTrack::set( // Ensure that buffer depth covers at least audio hardware latency uint32_t minBufCount = afLatency / ((1000 * afFrameCount)/afSampleRate); + if (minBufCount < 2) minBufCount = 2; + // When playing from shared buffer, playback will start even if last audioflinger // block is partly filled. if (sharedBuffer != 0 && minBufCount > 1) { @@ -437,8 +439,8 @@ void AudioTrack::setSampleRate(int rate) return; } // Resampler implementation limits input sampling rate to 2 x output sampling rate. + if (rate <= 0) rate = 1; if (rate > afSamplingRate*2) rate = afSamplingRate*2; - if (rate > MAX_SAMPLE_RATE) rate = MAX_SAMPLE_RATE; mCblk->sampleRate = rate; @@ -466,10 +468,15 @@ status_t AudioTrack::setLoop(uint32_t loopStart, uint32_t loopEnd, int loopCount if (loopStart >= loopEnd || loopEnd - loopStart > mFrameCount) { - LOGW("setLoop invalid value: loopStart %d, loopEnd %d, loopCount %d, framecount %d, user %d", loopStart, loopEnd, loopCount, mFrameCount, cblk->user); + LOGE("setLoop invalid value: loopStart %d, loopEnd %d, loopCount %d, framecount %d, user %d", loopStart, loopEnd, loopCount, mFrameCount, cblk->user); return BAD_VALUE; } - // TODO handle shared buffer here: limit loop end to framecount + + if ((mSharedBuffer != 0) && (loopEnd > mFrameCount)) { + LOGE("setLoop invalid value: loop markers beyond data: loopStart %d, loopEnd %d, framecount %d", + loopStart, loopEnd, mFrameCount); + return BAD_VALUE; + } cblk->loopStart = loopStart; cblk->loopEnd = loopEnd; diff --git a/media/libmedia/IMediaRecorder.cpp b/media/libmedia/IMediaRecorder.cpp index 507d03e..f187bf5 100644 --- a/media/libmedia/IMediaRecorder.cpp +++ b/media/libmedia/IMediaRecorder.cpp @@ -21,6 +21,7 @@ #include <utils/Parcel.h> #include <ui/ISurface.h> #include <ui/ICamera.h> +#include <media/IMediaPlayerClient.h> #include <media/IMediaRecorder.h> namespace android { @@ -44,7 +45,8 @@ enum { SET_VIDEO_SIZE, SET_VIDEO_FRAMERATE, SET_PREVIEW_SURFACE, - SET_CAMERA + SET_CAMERA, + SET_LISTENER }; class BpMediaRecorder: public BpInterface<IMediaRecorder> @@ -176,6 +178,16 @@ public: return reply.readInt32(); } + status_t setListener(const sp<IMediaPlayerClient>& listener) + { + LOGV("setListener(%p)", listener.get()); + Parcel data, reply; + data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); + data.writeStrongBinder(listener->asBinder()); + remote()->transact(SET_LISTENER, data, &reply); + return reply.readInt32(); + } + status_t prepare() { LOGV("prepare"); @@ -373,6 +385,14 @@ status_t BnMediaRecorder::onTransact( reply->writeInt32(setVideoFrameRate(frames_per_second)); return NO_ERROR; } break; + case SET_LISTENER: { + LOGV("SET_LISTENER"); + CHECK_INTERFACE(IMediaRecorder, data, reply); + sp<IMediaPlayerClient> listener = + interface_cast<IMediaPlayerClient>(data.readStrongBinder()); + reply->writeInt32(setListener(listener)); + return NO_ERROR; + } break; case SET_PREVIEW_SURFACE: { LOGV("SET_PREVIEW_SURFACE"); CHECK_INTERFACE(IMediaRecorder, data, reply); diff --git a/media/libmedia/mediarecorder.cpp b/media/libmedia/mediarecorder.cpp index 4ab26ac..98aac39 100644 --- a/media/libmedia/mediarecorder.cpp +++ b/media/libmedia/mediarecorder.cpp @@ -58,6 +58,10 @@ status_t MediaRecorder::setPreviewSurface(const sp<Surface>& surface) 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) { @@ -86,6 +90,14 @@ status_t MediaRecorder::init() 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; } @@ -167,6 +179,10 @@ status_t MediaRecorder::setOutputFormat(int of) 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) { @@ -185,6 +201,10 @@ status_t MediaRecorder::setVideoEncoder(int ve) 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; @@ -211,6 +231,10 @@ status_t MediaRecorder::setAudioEncoder(int ae) 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; @@ -293,6 +317,10 @@ status_t MediaRecorder::setVideoSize(int width, int height) 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) { @@ -314,6 +342,10 @@ status_t MediaRecorder::setVideoFrameRate(int frames_per_second) 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) { @@ -335,6 +367,23 @@ status_t MediaRecorder::prepare() 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) { @@ -538,5 +587,31 @@ MediaRecorder::~MediaRecorder() } } +status_t MediaRecorder::setListener(const sp<MediaRecorderListener>& 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<MediaRecorderListener> 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 |