diff options
author | Andreas Huber <andih@google.com> | 2010-01-25 15:30:31 -0800 |
---|---|---|
committer | Andreas Huber <andih@google.com> | 2010-01-26 09:10:33 -0800 |
commit | 996dddff64f90d8469e24107c44bfd618cf0c2dd (patch) | |
tree | a36bea1e23eef4f6d5af0c6f5ef29dc4a23d22a9 | |
parent | 03b58bdf0e97f9e3bd247cb731b69fa87a845eeb (diff) | |
download | frameworks_base-996dddff64f90d8469e24107c44bfd618cf0c2dd.zip frameworks_base-996dddff64f90d8469e24107c44bfd618cf0c2dd.tar.gz frameworks_base-996dddff64f90d8469e24107c44bfd618cf0c2dd.tar.bz2 |
Support for audio recording into AMR NB/WB files as well as audio tracks in MPEG4 files.
related-to-bug: 2295449
-rw-r--r-- | include/media/stagefright/AMRWriter.h | 13 | ||||
-rw-r--r-- | include/media/stagefright/MPEG4Writer.h | 12 | ||||
-rw-r--r-- | include/media/stagefright/MediaWriter.h | 45 | ||||
-rw-r--r-- | media/libmediaplayerservice/StagefrightRecorder.cpp | 104 | ||||
-rw-r--r-- | media/libmediaplayerservice/StagefrightRecorder.h | 9 | ||||
-rw-r--r-- | media/libstagefright/AMRWriter.cpp | 9 | ||||
-rw-r--r-- | media/libstagefright/MPEG4Writer.cpp | 4 |
7 files changed, 177 insertions, 19 deletions
diff --git a/include/media/stagefright/AMRWriter.h b/include/media/stagefright/AMRWriter.h index 6ee9869..372909a 100644 --- a/include/media/stagefright/AMRWriter.h +++ b/include/media/stagefright/AMRWriter.h @@ -20,23 +20,23 @@ #include <stdio.h> -#include <utils/RefBase.h> +#include <media/stagefright/MediaWriter.h> #include <utils/threads.h> namespace android { struct MediaSource; -struct AMRWriter : public RefBase { +struct AMRWriter : public MediaWriter { AMRWriter(const char *filename); AMRWriter(int fd); status_t initCheck() const; - status_t addSource(const sp<MediaSource> &source); - - status_t start(); - void stop(); + virtual status_t addSource(const sp<MediaSource> &source); + virtual bool reachedEOS(); + virtual status_t start(); + virtual void stop(); protected: virtual ~AMRWriter(); @@ -49,6 +49,7 @@ private: sp<MediaSource> mSource; bool mStarted; volatile bool mDone; + bool mReachedEOS; pthread_t mThread; static void *ThreadWrapper(void *); diff --git a/include/media/stagefright/MPEG4Writer.h b/include/media/stagefright/MPEG4Writer.h index 2ca04fa..6b93f19 100644 --- a/include/media/stagefright/MPEG4Writer.h +++ b/include/media/stagefright/MPEG4Writer.h @@ -20,8 +20,8 @@ #include <stdio.h> +#include <media/stagefright/MediaWriter.h> #include <utils/List.h> -#include <utils/RefBase.h> #include <utils/threads.h> namespace android { @@ -30,15 +30,15 @@ class MediaBuffer; class MediaSource; class MetaData; -class MPEG4Writer : public RefBase { +class MPEG4Writer : public MediaWriter { public: MPEG4Writer(const char *filename); MPEG4Writer(int fd); - void addSource(const sp<MediaSource> &source); - status_t start(); - bool reachedEOS(); - void stop(); + virtual status_t addSource(const sp<MediaSource> &source); + virtual status_t start(); + virtual bool reachedEOS(); + virtual void stop(); void beginBox(const char *fourcc); void writeInt8(int8_t x); diff --git a/include/media/stagefright/MediaWriter.h b/include/media/stagefright/MediaWriter.h new file mode 100644 index 0000000..b8232c6 --- /dev/null +++ b/include/media/stagefright/MediaWriter.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2010 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. + */ + +#ifndef MEDIA_WRITER_H_ + +#define MEDIA_WRITER_H_ + +#include <utils/RefBase.h> + +namespace android { + +struct MediaSource; + +struct MediaWriter : public RefBase { + MediaWriter() {} + + virtual status_t addSource(const sp<MediaSource> &source) = 0; + virtual bool reachedEOS() = 0; + virtual status_t start() = 0; + virtual void stop() = 0; + +protected: + virtual ~MediaWriter() {} + +private: + MediaWriter(const MediaWriter &); + MediaWriter &operator=(const MediaWriter &); +}; + +} // namespace android + +#endif // MEDIA_WRITER_H_ diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp index a55273d..6383f0c 100644 --- a/media/libmediaplayerservice/StagefrightRecorder.cpp +++ b/media/libmediaplayerservice/StagefrightRecorder.cpp @@ -20,6 +20,8 @@ #include "StagefrightRecorder.h" +#include <media/stagefright/AudioSource.h> +#include <media/stagefright/AMRWriter.h> #include <media/stagefright/CameraSource.h> #include <media/stagefright/MPEG4Writer.h> #include <media/stagefright/MediaDebug.h> @@ -146,7 +148,90 @@ status_t StagefrightRecorder::start() { return UNKNOWN_ERROR; } - if (mVideoSource == VIDEO_SOURCE_CAMERA) { + switch (mOutputFormat) { + case OUTPUT_FORMAT_DEFAULT: + case OUTPUT_FORMAT_THREE_GPP: + case OUTPUT_FORMAT_MPEG_4: + return startMPEG4Recording(); + + case OUTPUT_FORMAT_AMR_NB: + case OUTPUT_FORMAT_AMR_WB: + return startAMRRecording(); + + default: + return UNKNOWN_ERROR; + } +} + +sp<MediaSource> StagefrightRecorder::createAMRAudioSource() { + uint32_t sampleRate = + mAudioEncoder == AUDIO_ENCODER_AMR_NB ? 8000 : 16000; + + sp<AudioSource> audioSource = + new AudioSource( + mAudioSource, + sampleRate, + AudioSystem::CHANNEL_IN_MONO); + + status_t err = audioSource->initCheck(); + + if (err != OK) { + return NULL; + } + + sp<MetaData> encMeta = new MetaData; + encMeta->setCString( + kKeyMIMEType, + mAudioEncoder == AUDIO_ENCODER_AMR_NB + ? MEDIA_MIMETYPE_AUDIO_AMR_NB : MEDIA_MIMETYPE_AUDIO_AMR_WB); + + encMeta->setInt32(kKeyChannelCount, 1); + encMeta->setInt32(kKeySampleRate, sampleRate); + + OMXClient client; + CHECK_EQ(client.connect(), OK); + + sp<MediaSource> audioEncoder = + OMXCodec::Create(client.interface(), encMeta, + true /* createEncoder */, audioSource); + + return audioEncoder; +} + +status_t StagefrightRecorder::startAMRRecording() { + if (mAudioSource == AUDIO_SOURCE_LIST_END + || mVideoSource != VIDEO_SOURCE_LIST_END) { + return UNKNOWN_ERROR; + } + + if (mOutputFormat == OUTPUT_FORMAT_AMR_NB + && mAudioEncoder != AUDIO_ENCODER_DEFAULT + && mAudioEncoder != AUDIO_ENCODER_AMR_NB) { + return UNKNOWN_ERROR; + } else if (mOutputFormat == OUTPUT_FORMAT_AMR_WB + && mAudioEncoder != AUDIO_ENCODER_AMR_WB) { + return UNKNOWN_ERROR; + } + + sp<MediaSource> audioEncoder = createAMRAudioSource(); + + if (audioEncoder == NULL) { + return UNKNOWN_ERROR; + } + + CHECK(mOutputFd >= 0); + mWriter = new AMRWriter(dup(mOutputFd)); + mWriter->addSource(audioEncoder); + mWriter->start(); + + return OK; +} + +status_t StagefrightRecorder::startMPEG4Recording() { + mWriter = new MPEG4Writer(dup(mOutputFd)); + + if (mVideoSource == VIDEO_SOURCE_DEFAULT + || mVideoSource == VIDEO_SOURCE_CAMERA) { CHECK(mCamera != NULL); sp<CameraSource> cameraSource = @@ -193,11 +278,20 @@ status_t StagefrightRecorder::start() { true /* createEncoder */, cameraSource); CHECK(mOutputFd >= 0); - mWriter = new MPEG4Writer(dup(mOutputFd)); mWriter->addSource(encoder); - mWriter->start(); } + if (mAudioSource != AUDIO_SOURCE_LIST_END) { + sp<MediaSource> audioEncoder = createAMRAudioSource(); + + if (audioEncoder == NULL) { + return UNKNOWN_ERROR; + } + + mWriter->addSource(audioEncoder); + } + + mWriter->start(); return OK; } @@ -235,7 +329,9 @@ status_t StagefrightRecorder::reset() { } status_t StagefrightRecorder::getMaxAmplitude(int *max) { - return UNKNOWN_ERROR; + *max = 0; + + return OK; } } // namespace android diff --git a/media/libmediaplayerservice/StagefrightRecorder.h b/media/libmediaplayerservice/StagefrightRecorder.h index 56c4e0e..7ec412d 100644 --- a/media/libmediaplayerservice/StagefrightRecorder.h +++ b/media/libmediaplayerservice/StagefrightRecorder.h @@ -23,7 +23,8 @@ namespace android { -class MPEG4Writer; +struct MediaSource; +struct MediaWriter; struct StagefrightRecorder : public MediaRecorderBase { StagefrightRecorder(); @@ -54,7 +55,7 @@ private: sp<ICamera> mCamera; sp<ISurface> mPreviewSurface; sp<IMediaPlayerClient> mListener; - sp<MPEG4Writer> mWriter; + sp<MediaWriter> mWriter; audio_source mAudioSource; video_source mVideoSource; @@ -66,6 +67,10 @@ private: String8 mParams; int mOutputFd; + status_t startMPEG4Recording(); + status_t startAMRRecording(); + sp<MediaSource> createAMRAudioSource(); + StagefrightRecorder(const StagefrightRecorder &); StagefrightRecorder &operator=(const StagefrightRecorder &); }; diff --git a/media/libstagefright/AMRWriter.cpp b/media/libstagefright/AMRWriter.cpp index 7b681f1..caff452 100644 --- a/media/libstagefright/AMRWriter.cpp +++ b/media/libstagefright/AMRWriter.cpp @@ -115,6 +115,7 @@ status_t AMRWriter::start() { pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); + mReachedEOS = false; mDone = false; pthread_create(&mThread, &attr, ThreadWrapper, this); @@ -179,6 +180,14 @@ void AMRWriter::threadFunc() { break; } } + + Mutex::Autolock autoLock(mLock); + mReachedEOS = true; +} + +bool AMRWriter::reachedEOS() { + Mutex::Autolock autoLock(mLock); + return mReachedEOS; } } // namespace android diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp index 367459f..aee4d15 100644 --- a/media/libstagefright/MPEG4Writer.cpp +++ b/media/libstagefright/MPEG4Writer.cpp @@ -92,9 +92,11 @@ MPEG4Writer::~MPEG4Writer() { mTracks.clear(); } -void MPEG4Writer::addSource(const sp<MediaSource> &source) { +status_t MPEG4Writer::addSource(const sp<MediaSource> &source) { Track *track = new Track(this, source); mTracks.push_back(track); + + return OK; } status_t MPEG4Writer::start() { |