diff options
Diffstat (limited to 'media/libmediaplayerservice/StagefrightRecorder.cpp')
-rw-r--r-- | media/libmediaplayerservice/StagefrightRecorder.cpp | 160 |
1 files changed, 159 insertions, 1 deletions
diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp index 57b0ec2..aa25eff 100644 --- a/media/libmediaplayerservice/StagefrightRecorder.cpp +++ b/media/libmediaplayerservice/StagefrightRecorder.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2009 The Android Open Source Project + * Copyright (c) 2010 - 2012, The Linux Foundation. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,6 +30,10 @@ #include <media/stagefright/AudioSource.h> #include <media/stagefright/AMRWriter.h> #include <media/stagefright/AACWriter.h> +#ifdef QCOM_HARDWARE +#include <media/stagefright/ExtendedWriter.h> +#include <media/stagefright/WAVEWriter.h> +#endif #include <media/stagefright/CameraSource.h> #include <media/stagefright/CameraSourceTimeLapse.h> #include <media/stagefright/MPEG2TSWriter.h> @@ -49,6 +54,9 @@ #include <unistd.h> #include <system/audio.h> +#ifdef QCOM_HARDWARE +#include <QCMediaDefs.h> +#endif #include "ARTPWriter.h" @@ -159,6 +167,26 @@ status_t StagefrightRecorder::setAudioEncoder(audio_encoder ae) { mAudioEncoder = ae; } +#ifdef QCOM_HARDWARE + // Use default values if appropriate setparam's weren't called. + if(mAudioEncoder == AUDIO_ENCODER_AAC) { + mSampleRate = mSampleRate ? mSampleRate : 48000; + mAudioChannels = mAudioChannels ? mAudioChannels : 2; + mAudioBitRate = mAudioBitRate ? mAudioBitRate : 156000; + } else if(mAudioEncoder == AUDIO_ENCODER_LPCM) { + mSampleRate = mSampleRate ? mSampleRate : 48000; + mAudioChannels = mAudioChannels ? mAudioChannels : 2; + mAudioBitRate = mAudioBitRate ? mAudioBitRate : 4608000; + } else if(mAudioEncoder == AUDIO_ENCODER_AMR_WB) { + mSampleRate = 16000; + mAudioChannels = 1; + mAudioBitRate = 23850; + } else { + mSampleRate = mSampleRate ? mSampleRate : 8000; + mAudioChannels = mAudioChannels ? mAudioChannels : 1; + mAudioBitRate = mAudioBitRate ? mAudioBitRate : 12200; + } +#endif return OK; } @@ -768,7 +796,15 @@ status_t StagefrightRecorder::start() { case OUTPUT_FORMAT_MPEG2TS: status = startMPEG2TSRecording(); break; +#ifdef QCOM_HARDWARE + case OUTPUT_FORMAT_QCP: + status = startExtendedRecording( ); + break; + case OUTPUT_FORMAT_WAVE: + status = startWAVERecording( ); + break; +#endif default: ALOGE("Unsupported output file format: %d", mOutputFormat); status = UNKNOWN_ERROR; @@ -809,6 +845,11 @@ sp<MediaSource> StagefrightRecorder::createAudioSource() { sp<MetaData> encMeta = new MetaData; const char *mime; switch (mAudioEncoder) { +#ifdef QCOM_HARDWARE + case AUDIO_ENCODER_LPCM: + mime = MEDIA_MIMETYPE_AUDIO_RAW; + break; +#endif case AUDIO_ENCODER_AMR_NB: case AUDIO_ENCODER_DEFAULT: mime = MEDIA_MIMETYPE_AUDIO_AMR_NB; @@ -828,6 +869,14 @@ sp<MediaSource> StagefrightRecorder::createAudioSource() { mime = MEDIA_MIMETYPE_AUDIO_AAC; encMeta->setInt32(kKeyAACProfile, OMX_AUDIO_AACObjectELD); break; +#ifdef QCOM_HARDWARE + case AUDIO_ENCODER_EVRC: + mime = MEDIA_MIMETYPE_AUDIO_EVRC; + break; + case AUDIO_ENCODER_QCELP: + mime = MEDIA_MIMETYPE_AUDIO_QCELP; + break; +#endif default: ALOGE("Unknown audio encoder: %d", mAudioEncoder); @@ -852,6 +901,17 @@ sp<MediaSource> StagefrightRecorder::createAudioSource() { sp<MediaSource> audioEncoder = OMXCodec::Create(client.interface(), encMeta, true /* createEncoder */, audioSource); +#ifdef QCOM_HARDWARE + // If encoder could not be created (as in LPCM), then + // use the AudioSource directly as the MediaSource. + if (audioEncoder == NULL && AUDIO_ENCODER_LPCM) { + ALOGD("No encoder is needed, use the AudioSource directly as the MediaSource for LPCM format"); + audioEncoder = audioSource; + } + if (mAudioSourceNode != NULL) { + mAudioSourceNode.clear(); + } +#endif mAudioSourceNode = audioSource; return audioEncoder; @@ -888,13 +948,35 @@ status_t StagefrightRecorder::startAMRRecording() { mAudioEncoder); return BAD_VALUE; } +#ifdef QCOM_HARDWARE + if (mSampleRate != 8000) { + ALOGE("Invalid sampling rate %d used for AMRNB recording", + mSampleRate); + return BAD_VALUE; + } +#endif } else { // mOutputFormat must be OUTPUT_FORMAT_AMR_WB if (mAudioEncoder != AUDIO_ENCODER_AMR_WB) { ALOGE("Invlaid encoder %d used for AMRWB recording", mAudioEncoder); return BAD_VALUE; } +#ifdef QCOM_HARDWARE + if (mSampleRate != 16000) { + ALOGE("Invalid sample rate %d used for AMRWB recording", + mSampleRate); + return BAD_VALUE; + } +#endif + } + +#ifdef QCOM_HARDWARE + if (mAudioChannels != 1) { + ALOGE("Invalid number of audio channels %d used for amr recording", + mAudioChannels); + return BAD_VALUE; } +#endif mWriter = new AMRWriter(mOutputFd); status_t status = startRawAudioRecording(); @@ -905,6 +987,24 @@ status_t StagefrightRecorder::startAMRRecording() { return status; } +#ifdef QCOM_HARDWARE +status_t StagefrightRecorder::startWAVERecording() { + CHECK(mOutputFormat == OUTPUT_FORMAT_WAVE); + + CHECK(mAudioEncoder == AUDIO_ENCODER_LPCM); + CHECK(mAudioSource != AUDIO_SOURCE_CNT); + + mWriter = new WAVEWriter(mOutputFd); + status_t status = startRawAudioRecording(); + if (status != OK) { + mWriter.clear(); + mWriter = NULL; + } + + return status; +} +#endif + status_t StagefrightRecorder::startRawAudioRecording() { if (mAudioSource >= AUDIO_SOURCE_CNT) { ALOGE("Invalid audio source: %d", mAudioSource); @@ -1450,6 +1550,9 @@ status_t StagefrightRecorder::setupAudioEncoder(const sp<MediaWriter>& writer) { case AUDIO_ENCODER_AAC: case AUDIO_ENCODER_HE_AAC: case AUDIO_ENCODER_AAC_ELD: +#ifdef QCOM_HARDWARE + case AUDIO_ENCODER_LPCM: +#endif break; default: @@ -1611,7 +1714,12 @@ status_t StagefrightRecorder::stop() { ::close(mOutputFd); mOutputFd = -1; } - +#ifdef QCOM_HARDWARE + if (mAudioSourceNode != NULL) { + mAudioSourceNode.clear(); + mAudioSourceNode = NULL; + } +#endif if (mStarted) { mStarted = false; @@ -1653,9 +1761,15 @@ status_t StagefrightRecorder::reset() { mVideoHeight = 144; mFrameRate = -1; mVideoBitRate = 192000; +#ifdef QCOM_HARDWARE + mSampleRate = 0; + mAudioChannels = 0; + mAudioBitRate = 0; +#else mSampleRate = 8000; mAudioChannels = 1; mAudioBitRate = 12200; +#endif mInterleaveDurationUs = 0; mIFramesIntervalSec = 1; mAudioSourceNode = 0; @@ -1767,4 +1881,48 @@ status_t StagefrightRecorder::dump( ::write(fd, result.string(), result.size()); return OK; } + +#ifdef QCOM_HARDWARE +status_t StagefrightRecorder::startExtendedRecording() { + CHECK(mOutputFormat == OUTPUT_FORMAT_QCP); + + if (mSampleRate != 8000) { + ALOGE("Invalid sampling rate %d used for recording", + mSampleRate); + return BAD_VALUE; + } + if (mAudioChannels != 1) { + ALOGE("Invalid number of audio channels %d used for recording", + mAudioChannels); + return BAD_VALUE; + } + + if (mAudioSource >= AUDIO_SOURCE_CNT) { + ALOGE("Invalid audio source: %d", mAudioSource); + return BAD_VALUE; + } + + sp<MediaSource> audioEncoder = createAudioSource(); + + if (audioEncoder == NULL) { + ALOGE("AudioEncoder NULL"); + return UNKNOWN_ERROR; + } + + mWriter = new ExtendedWriter(dup(mOutputFd)); + mWriter->addSource(audioEncoder); + + if (mMaxFileDurationUs != 0) { + mWriter->setMaxFileDuration(mMaxFileDurationUs); + } + if (mMaxFileSizeBytes != 0) { + mWriter->setMaxFileSize(mMaxFileSizeBytes); + } + mWriter->setListener(mListener); + mWriter->start(); + + return OK; +} +#endif + } // namespace android |