summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNipun Kwatra <nkwatra@google.com>2010-08-26 17:05:18 -0700
committerNipun Kwatra <nkwatra@google.com>2010-08-31 10:38:49 -0700
commit9c075bca0b75093ca0514a3c8f74d73c8e9e83fd (patch)
tree5669e5acd20c684e4ec8f28e68f883066c640600
parent6865ddb29fc7e7a14104d73c65b71074502bb6c7 (diff)
downloadframeworks_av-9c075bca0b75093ca0514a3c8f74d73c8e9e83fd.zip
frameworks_av-9c075bca0b75093ca0514a3c8f74d73c8e9e83fd.tar.gz
frameworks_av-9c075bca0b75093ca0514a3c8f74d73c8e9e83fd.tar.bz2
Adding support for parallel recording sessions.
- Added setOutputFileAuxiliary to pass the auxiliary file descriptor. The java interface through JNI will be checked in next. - renamed setupCameraSource to setupCamera as the function just sets the camera. - Added setupCameraSource which sets up the camera source. This functionality was in setupVideoEncoder before. - setupVideoEncoder now takes in a cameraSource instead of creating it on it own. - Refactored startMPEG4Recording() to use setupMPEG4Recording, setupMPEG4MetaData. - setupMPEG4Recording() takes in file descriptor, bitrates to setup a mpeg4 writer. This function can be called multiple times to setup multiple writers. - Added setupMPEG4MetaData() for setting up the meta data for mpeg4 writer. startMPEG4Recording() now calls setupMPEG4Recording, setupMPEG4MetaData for each recording session. Change-Id: I07f5334a1ff8e12a36f58e94129fcfa6add2208b
-rw-r--r--media/libmediaplayerservice/StagefrightRecorder.cpp202
-rw-r--r--media/libmediaplayerservice/StagefrightRecorder.h29
-rw-r--r--media/libstagefright/Android.mk3
3 files changed, 198 insertions, 36 deletions
diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp
index a24e56c..bbbf45c 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.cpp
+++ b/media/libmediaplayerservice/StagefrightRecorder.cpp
@@ -25,6 +25,7 @@
#include <media/stagefright/AMRWriter.h>
#include <media/stagefright/CameraSource.h>
#include <media/stagefright/CameraSourceTimeLapse.h>
+#include <media/stagefright/MediaSourceSplitter.h>
#include <media/stagefright/MPEG4Writer.h>
#include <media/stagefright/MediaDebug.h>
#include <media/stagefright/MediaDefs.h>
@@ -46,8 +47,8 @@
namespace android {
StagefrightRecorder::StagefrightRecorder()
- : mWriter(NULL),
- mOutputFd(-1) {
+ : mWriter(NULL), mWriterAux(NULL),
+ mOutputFd(-1), mOutputFdAux(-1) {
LOGV("Constructor");
reset();
@@ -235,6 +236,24 @@ status_t StagefrightRecorder::setOutputFile(int fd, int64_t offset, int64_t leng
return OK;
}
+status_t StagefrightRecorder::setOutputFileAuxiliary(int fd) {
+ LOGV("setOutputFileAuxiliary: %d", fd);
+
+ if (fd < 0) {
+ LOGE("Invalid file descriptor: %d", fd);
+ return -EBADF;
+ }
+
+ mCaptureAuxVideo = true;
+
+ if (mOutputFdAux >= 0) {
+ ::close(mOutputFdAux);
+ }
+ mOutputFdAux = dup(fd);
+
+ return OK;
+}
+
// Attempt to parse an int64 literal optionally surrounded by whitespace,
// returns true on success, false otherwise.
static bool safe_strtoi64(const char *s, int64_t *val) {
@@ -842,7 +861,14 @@ status_t StagefrightRecorder::startRTPRecording() {
if (mAudioSource != AUDIO_SOURCE_LIST_END) {
source = createAudioSource();
} else {
- status_t err = setupVideoEncoder(&source);
+
+ sp<CameraSource> cameraSource;
+ status_t err = setupCameraSource(&cameraSource);
+ if (err != OK) {
+ return err;
+ }
+
+ err = setupVideoEncoder(cameraSource, mVideoBitRate, &source);
if (err != OK) {
return err;
}
@@ -906,7 +932,7 @@ void StagefrightRecorder::clipVideoFrameWidth() {
}
}
-status_t StagefrightRecorder::setupCameraSource() {
+status_t StagefrightRecorder::setupCamera() {
if (!mCaptureTimeLapse) {
// Dont clip for time lapse capture as encoder will have enough
// time to encode because of slow capture rate of time lapse.
@@ -989,20 +1015,27 @@ void StagefrightRecorder::clipVideoFrameHeight() {
}
}
-status_t StagefrightRecorder::setupVideoEncoder(sp<MediaSource> *source) {
- source->clear();
-
- status_t err = setupCameraSource();
+status_t StagefrightRecorder::setupCameraSource(sp<CameraSource> *cameraSource) {
+ status_t err = setupCamera();
if (err != OK) return err;
- sp<CameraSource> cameraSource = (mCaptureTimeLapse) ?
+ *cameraSource = (mCaptureTimeLapse) ?
CameraSourceTimeLapse::CreateFromCamera(mCamera, mUseStillCameraForTimeLapse,
mTimeBetweenTimeLapseFrameCaptureUs, mVideoWidth, mVideoHeight, mFrameRate):
CameraSource::CreateFromCamera(mCamera);
- CHECK(cameraSource != NULL);
+ CHECK(*cameraSource != NULL);
+
+ return OK;
+}
+
+status_t StagefrightRecorder::setupVideoEncoder(
+ sp<MediaSource> cameraSource,
+ int32_t videoBitRate,
+ sp<MediaSource> *source) {
+ source->clear();
sp<MetaData> enc_meta = new MetaData;
- enc_meta->setInt32(kKeyBitRate, mVideoBitRate);
+ enc_meta->setInt32(kKeyBitRate, videoBitRate);
enc_meta->setInt32(kKeySampleRate, mFrameRate);
switch (mVideoEncoder) {
@@ -1087,51 +1120,128 @@ status_t StagefrightRecorder::setupAudioEncoder(const sp<MediaWriter>& writer) {
return OK;
}
-status_t StagefrightRecorder::startMPEG4Recording() {
- int32_t totalBitRate = 0;
+status_t StagefrightRecorder::setupMPEG4Recording(
+ bool useSplitCameraSource,
+ int outputFd, int32_t audioBitRate, int32_t videoBitRate,
+ int32_t *totalBitRate,
+ sp<MediaWriter> *mediaWriter) {
+ mediaWriter->clear();
+ *totalBitRate = 0;
status_t err = OK;
- sp<MediaWriter> writer = new MPEG4Writer(dup(mOutputFd));
+ sp<MediaWriter> writer = new MPEG4Writer(dup(outputFd));
// Add audio source first if it exists
if (!mCaptureTimeLapse && (mAudioSource != AUDIO_SOURCE_LIST_END)) {
err = setupAudioEncoder(writer);
if (err != OK) return err;
- totalBitRate += mAudioBitRate;
+ *totalBitRate += audioBitRate;
}
if (mVideoSource == VIDEO_SOURCE_DEFAULT
|| mVideoSource == VIDEO_SOURCE_CAMERA) {
+
+ sp<MediaSource> cameraMediaSource;
+ if (useSplitCameraSource) {
+ LOGV("Using Split camera source");
+ cameraMediaSource = mCameraSourceSplitter->createClient();
+ } else {
+ sp<CameraSource> cameraSource;
+ err = setupCameraSource(&cameraSource);
+ cameraMediaSource = cameraSource;
+ }
+ if (err != OK) {
+ return err;
+ }
+
sp<MediaSource> encoder;
- err = setupVideoEncoder(&encoder);
- if (err != OK) return err;
+ err = setupVideoEncoder(cameraMediaSource, videoBitRate, &encoder);
+ if (err != OK) {
+ return err;
+ }
+
writer->addSource(encoder);
- totalBitRate += mVideoBitRate;
+ *totalBitRate += videoBitRate;
}
if (mInterleaveDurationUs > 0) {
reinterpret_cast<MPEG4Writer *>(writer.get())->
setInterleaveDuration(mInterleaveDurationUs);
}
-
if (mMaxFileDurationUs != 0) {
writer->setMaxFileDuration(mMaxFileDurationUs);
}
if (mMaxFileSizeBytes != 0) {
writer->setMaxFileSize(mMaxFileSizeBytes);
}
- sp<MetaData> meta = new MetaData;
- meta->setInt64(kKeyTime, systemTime() / 1000);
- meta->setInt32(kKeyFileType, mOutputFormat);
- meta->setInt32(kKeyBitRate, totalBitRate);
- meta->setInt32(kKey64BitFileOffset, mUse64BitFileOffset);
+
+ writer->setListener(mListener);
+ *mediaWriter = writer;
+ return OK;
+}
+
+void StagefrightRecorder::setupMPEG4MetaData(int64_t startTimeUs, int32_t totalBitRate,
+ sp<MetaData> *meta) {
+ (*meta)->setInt64(kKeyTime, startTimeUs);
+ (*meta)->setInt32(kKeyFileType, mOutputFormat);
+ (*meta)->setInt32(kKeyBitRate, totalBitRate);
+ (*meta)->setInt32(kKey64BitFileOffset, mUse64BitFileOffset);
if (mMovieTimeScale > 0) {
- meta->setInt32(kKeyTimeScale, mMovieTimeScale);
+ (*meta)->setInt32(kKeyTimeScale, mMovieTimeScale);
}
if (mTrackEveryTimeDurationUs > 0) {
- meta->setInt64(kKeyTrackTimeStatus, mTrackEveryTimeDurationUs);
+ (*meta)->setInt64(kKeyTrackTimeStatus, mTrackEveryTimeDurationUs);
}
- writer->setListener(mListener);
- mWriter = writer;
- return mWriter->start(meta.get());
+}
+
+status_t StagefrightRecorder::startMPEG4Recording() {
+ if (mCaptureAuxVideo) {
+ LOGV("Creating MediaSourceSplitter");
+ sp<CameraSource> cameraSource;
+ status_t err = setupCameraSource(&cameraSource);
+ if (err != OK) {
+ return err;
+ }
+ mCameraSourceSplitter = new MediaSourceSplitter(cameraSource);
+ } else {
+ mCameraSourceSplitter = NULL;
+ }
+
+ int32_t totalBitRate;
+ status_t err = setupMPEG4Recording(mCaptureAuxVideo,
+ mOutputFd, mAudioBitRate, mVideoBitRate, &totalBitRate, &mWriter);
+ if (err != OK) {
+ return err;
+ }
+
+ int64_t startTimeUs = systemTime() / 1000;
+ sp<MetaData> meta = new MetaData;
+ setupMPEG4MetaData(startTimeUs, totalBitRate, &meta);
+
+ err = mWriter->start(meta.get());
+ if (err != OK) {
+ return err;
+ }
+
+ if (mCaptureAuxVideo) {
+ CHECK(mOutputFdAux >= 0);
+ if (mWriterAux != NULL) {
+ LOGE("Auxiliary File writer is not avaialble");
+ return UNKNOWN_ERROR;
+ }
+
+ int32_t totalBitrateAux;
+ err = setupMPEG4Recording(mCaptureAuxVideo,
+ mOutputFdAux, mAudioBitRateAux, mVideoBitRateAux, &totalBitrateAux, &mWriterAux);
+ if (err != OK) {
+ return err;
+ }
+
+ sp<MetaData> metaAux = new MetaData;
+ setupMPEG4MetaData(startTimeUs, totalBitrateAux, &metaAux);
+
+ return mWriterAux->start(metaAux.get());
+ }
+
+ return OK;
}
status_t StagefrightRecorder::pause() {
@@ -1140,12 +1250,28 @@ status_t StagefrightRecorder::pause() {
return UNKNOWN_ERROR;
}
mWriter->pause();
+
+ if (mCaptureAuxVideo) {
+ if (mWriterAux == NULL) {
+ return UNKNOWN_ERROR;
+ }
+ mWriterAux->pause();
+ }
+
return OK;
}
status_t StagefrightRecorder::stop() {
LOGV("stop");
status_t err = OK;
+
+ if (mCaptureAuxVideo) {
+ if (mWriterAux != NULL) {
+ mWriterAux->stop();
+ mWriterAux.clear();
+ }
+ }
+
if (mWriter != NULL) {
err = mWriter->stop();
mWriter.clear();
@@ -1169,6 +1295,13 @@ status_t StagefrightRecorder::stop() {
mOutputFd = -1;
}
+ if (mCaptureAuxVideo) {
+ if (mOutputFdAux >= 0) {
+ ::close(mOutputFdAux);
+ mOutputFdAux = -1;
+ }
+ }
+
return err;
}
@@ -1195,9 +1328,11 @@ status_t StagefrightRecorder::reset() {
mVideoHeight = 144;
mFrameRate = 20;
mVideoBitRate = 192000;
+ mVideoBitRateAux = 20000000;
mSampleRate = 8000;
mAudioChannels = 1;
mAudioBitRate = 12200;
+ mAudioBitRateAux = 12200;
mInterleaveDurationUs = 0;
mIFramesIntervalSec = 1;
mAudioSourceNode = 0;
@@ -1214,9 +1349,12 @@ status_t StagefrightRecorder::reset() {
mCaptureTimeLapse = false;
mUseStillCameraForTimeLapse = true;
mTimeBetweenTimeLapseFrameCaptureUs = -1;
+ mCaptureAuxVideo = false;
+ mCameraSourceSplitter = NULL;
mEncoderProfiles = MediaProfiles::getInstance();
mOutputFd = -1;
+ mOutputFdAux = -1;
mFlags = 0;
return OK;
@@ -1254,6 +1392,8 @@ status_t StagefrightRecorder::dump(
snprintf(buffer, SIZE, " Recorder: %p\n", this);
snprintf(buffer, SIZE, " Output file (fd %d):\n", mOutputFd);
result.append(buffer);
+ snprintf(buffer, SIZE, " Output file Auxiliary (fd %d):\n", mOutputFdAux);
+ result.append(buffer);
snprintf(buffer, SIZE, " File format: %d\n", mOutputFormat);
result.append(buffer);
snprintf(buffer, SIZE, " Max file size (bytes): %lld\n", mMaxFileSizeBytes);
@@ -1274,6 +1414,8 @@ status_t StagefrightRecorder::dump(
result.append(buffer);
snprintf(buffer, SIZE, " Bit rate (bps): %d\n", mAudioBitRate);
result.append(buffer);
+ snprintf(buffer, SIZE, " Bit rate auxiliary (bps): %d\n", mAudioBitRateAux);
+ result.append(buffer);
snprintf(buffer, SIZE, " Sampling rate (hz): %d\n", mSampleRate);
result.append(buffer);
snprintf(buffer, SIZE, " Number of channels: %d\n", mAudioChannels);
@@ -1302,6 +1444,8 @@ status_t StagefrightRecorder::dump(
result.append(buffer);
snprintf(buffer, SIZE, " Bit rate (bps): %d\n", mVideoBitRate);
result.append(buffer);
+ snprintf(buffer, SIZE, " Bit rate Auxiliary (bps): %d\n", mVideoBitRateAux);
+ result.append(buffer);
::write(fd, result.string(), result.size());
return OK;
}
diff --git a/media/libmediaplayerservice/StagefrightRecorder.h b/media/libmediaplayerservice/StagefrightRecorder.h
index 628e19b..d75a540 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.h
+++ b/media/libmediaplayerservice/StagefrightRecorder.h
@@ -24,8 +24,11 @@
namespace android {
class Camera;
+class CameraSource;
+class MediaSourceSplitter;
struct MediaSource;
struct MediaWriter;
+class MetaData;
struct AudioSource;
class MediaProfiles;
@@ -45,6 +48,7 @@ struct StagefrightRecorder : public MediaRecorderBase {
virtual status_t setPreviewSurface(const sp<Surface>& surface);
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 setParameters(const String8& params);
virtual status_t setListener(const sp<IMediaRecorderClient>& listener);
virtual status_t prepare();
@@ -65,7 +69,7 @@ private:
sp<Camera> mCamera;
sp<Surface> mPreviewSurface;
sp<IMediaRecorderClient> mListener;
- sp<MediaWriter> mWriter;
+ sp<MediaWriter> mWriter, mWriterAux;
sp<AudioSource> mAudioSourceNode;
audio_source mAudioSource;
@@ -76,8 +80,8 @@ private:
bool mUse64BitFileOffset;
int32_t mVideoWidth, mVideoHeight;
int32_t mFrameRate;
- int32_t mVideoBitRate;
- int32_t mAudioBitRate;
+ int32_t mVideoBitRate, mVideoBitRateAux;
+ int32_t mAudioBitRate, mAudioBitRateAux;
int32_t mAudioChannels;
int32_t mSampleRate;
int32_t mInterleaveDurationUs;
@@ -95,21 +99,34 @@ private:
bool mCaptureTimeLapse;
bool mUseStillCameraForTimeLapse;
int64_t mTimeBetweenTimeLapseFrameCaptureUs;
+ bool mCaptureAuxVideo;
+ sp<MediaSourceSplitter> mCameraSourceSplitter;
String8 mParams;
- int mOutputFd;
+ int mOutputFd, mOutputFdAux;
int32_t mFlags;
MediaProfiles *mEncoderProfiles;
+ status_t setupMPEG4Recording(
+ bool useAuxiliaryCameraSource,
+ int outputFd, int32_t audioBitRate, int32_t videoBitRate,
+ int32_t *totalBitRate,
+ sp<MediaWriter> *mediaWriter);
+ void setupMPEG4MetaData(int64_t startTimeUs, int32_t totalBitRate,
+ sp<MetaData> *meta);
status_t startMPEG4Recording();
status_t startAMRRecording();
status_t startAACRecording();
status_t startRTPRecording();
sp<MediaSource> createAudioSource();
- status_t setupCameraSource();
+ status_t setupCamera();
+ status_t setupCameraSource(sp<CameraSource> *cameraSource);
status_t setupAudioEncoder(const sp<MediaWriter>& writer);
- status_t setupVideoEncoder(sp<MediaSource> *source);
+ status_t setupVideoEncoder(
+ sp<MediaSource> cameraSource,
+ int32_t videoBitRate,
+ sp<MediaSource> *source);
// Encoding parameter handling utilities
status_t setParameter(const String8 &key, const String8 &value);
diff --git a/media/libstagefright/Android.mk b/media/libstagefright/Android.mk
index b5a6327..6b7947e 100644
--- a/media/libstagefright/Android.mk
+++ b/media/libstagefright/Android.mk
@@ -10,7 +10,7 @@ LOCAL_SRC_FILES:= \
AudioSource.cpp \
AwesomePlayer.cpp \
CameraSource.cpp \
- CameraSourceTimeLapse.cpp \
+ CameraSourceTimeLapse.cpp \
DataSource.cpp \
ESDS.cpp \
FileSource.cpp \
@@ -24,6 +24,7 @@ LOCAL_SRC_FILES:= \
MediaDefs.cpp \
MediaExtractor.cpp \
MediaSource.cpp \
+ MediaSourceSplitter.cpp \
MetaData.cpp \
NuCachedSource2.cpp \
NuHTTPDataSource.cpp \