summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Huber <andih@google.com>2010-01-25 15:30:31 -0800
committerAndreas Huber <andih@google.com>2010-01-26 09:10:33 -0800
commit996dddff64f90d8469e24107c44bfd618cf0c2dd (patch)
treea36bea1e23eef4f6d5af0c6f5ef29dc4a23d22a9
parent03b58bdf0e97f9e3bd247cb731b69fa87a845eeb (diff)
downloadframeworks_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.h13
-rw-r--r--include/media/stagefright/MPEG4Writer.h12
-rw-r--r--include/media/stagefright/MediaWriter.h45
-rw-r--r--media/libmediaplayerservice/StagefrightRecorder.cpp104
-rw-r--r--media/libmediaplayerservice/StagefrightRecorder.h9
-rw-r--r--media/libstagefright/AMRWriter.cpp9
-rw-r--r--media/libstagefright/MPEG4Writer.cpp4
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() {