From da050cf206afff082f2a3693a8103a5df67df397 Mon Sep 17 00:00:00 2001 From: Andreas Huber Date: Wed, 2 Sep 2009 14:01:43 -0700 Subject: Some work to make audio encoding work. --- cmds/stagefright/Android.mk | 1 + cmds/stagefright/JPEGSource.cpp | 2 +- cmds/stagefright/SineSource.cpp | 100 ++++++++++++++++++++++++++++++++++++++++ cmds/stagefright/SineSource.h | 39 ++++++++++++++++ cmds/stagefright/record.cpp | 63 ++++++++++++++++++++++++- 5 files changed, 203 insertions(+), 2 deletions(-) create mode 100644 cmds/stagefright/SineSource.cpp create mode 100644 cmds/stagefright/SineSource.h (limited to 'cmds/stagefright') diff --git a/cmds/stagefright/Android.mk b/cmds/stagefright/Android.mk index ef67611..51a0649 100644 --- a/cmds/stagefright/Android.mk +++ b/cmds/stagefright/Android.mk @@ -24,6 +24,7 @@ include $(BUILD_EXECUTABLE) include $(CLEAR_VARS) LOCAL_SRC_FILES:= \ + SineSource.cpp \ record.cpp LOCAL_SHARED_LIBRARIES := \ diff --git a/cmds/stagefright/JPEGSource.cpp b/cmds/stagefright/JPEGSource.cpp index a7994ed..4e9ca4e 100644 --- a/cmds/stagefright/JPEGSource.cpp +++ b/cmds/stagefright/JPEGSource.cpp @@ -102,7 +102,7 @@ sp JPEGSource::getFormat() { meta->setCString(kKeyMIMEType, "image/jpeg"); meta->setInt32(kKeyWidth, mWidth); meta->setInt32(kKeyHeight, mHeight); - meta->setInt32(kKeyCompressedSize, mSize); + meta->setInt32(kKeyMaxInputSize, mSize); return meta; } diff --git a/cmds/stagefright/SineSource.cpp b/cmds/stagefright/SineSource.cpp new file mode 100644 index 0000000..3c25a7f --- /dev/null +++ b/cmds/stagefright/SineSource.cpp @@ -0,0 +1,100 @@ +#include "SineSource.h" + +#include + +#include +#include +#include + +namespace android { + +SineSource::SineSource(int32_t sampleRate, int32_t numChannels) + : mStarted(false), + mSampleRate(sampleRate), + mNumChannels(numChannels), + mPhase(0), + mGroup(NULL) { + CHECK(numChannels == 1 || numChannels == 2); +} + +SineSource::~SineSource() { + if (mStarted) { + stop(); + } +} + +status_t SineSource::start(MetaData *params) { + CHECK(!mStarted); + + mGroup = new MediaBufferGroup; + mGroup->add_buffer(new MediaBuffer(kBufferSize)); + + mPhase = 0; + mStarted = true; + + return OK; +} + +status_t SineSource::stop() { + CHECK(mStarted); + + delete mGroup; + mGroup = NULL; + + mStarted = false; + + return OK; +} + +sp SineSource::getFormat() { + sp meta = new MetaData; + meta->setCString(kKeyMIMEType, "audio/raw"); + meta->setInt32(kKeyChannelCount, mNumChannels); + meta->setInt32(kKeySampleRate, mSampleRate); + + return meta; +} + +status_t SineSource::read( + MediaBuffer **out, const ReadOptions *options) { + *out = NULL; + + MediaBuffer *buffer; + status_t err = mGroup->acquire_buffer(&buffer); + + if (err != OK) { + return err; + } + + size_t frameSize = mNumChannels * sizeof(int16_t); + size_t numFramesPerBuffer = buffer->size() / frameSize; + + int16_t *ptr = (int16_t *)buffer->data(); + + const double k = kFrequency / mSampleRate * (2.0 * M_PI); + + double x = mPhase * k; + for (size_t i = 0; i < numFramesPerBuffer; ++i) { + int16_t amplitude = (int16_t)(32767.0 * sin(x)); + + *ptr++ = amplitude; + if (mNumChannels == 2) { + *ptr++ = amplitude; + } + + x += k; + } + + buffer->meta_data()->setInt32(kKeyTimeUnits, mPhase); + buffer->meta_data()->setInt32(kKeyTimeScale, mSampleRate); + + mPhase += numFramesPerBuffer; + + buffer->set_range(0, numFramesPerBuffer * frameSize); + + *out = buffer; + + return OK; +} + +} // namespace android diff --git a/cmds/stagefright/SineSource.h b/cmds/stagefright/SineSource.h new file mode 100644 index 0000000..76ab669 --- /dev/null +++ b/cmds/stagefright/SineSource.h @@ -0,0 +1,39 @@ +#ifndef SINE_SOURCE_H_ + +#define SINE_SOURCE_H_ + +#include + +namespace android { + +struct MediaBufferGroup; + +struct SineSource : public MediaSource { + SineSource(int32_t sampleRate, int32_t numChannels); + + virtual status_t start(MetaData *params); + virtual status_t stop(); + + virtual sp getFormat(); + + virtual status_t read( + MediaBuffer **out, const ReadOptions *options = NULL); + +protected: + virtual ~SineSource(); + +private: + enum { kBufferSize = 8192 }; + static const double kFrequency = 500.0; + + bool mStarted; + int32_t mSampleRate; + int32_t mNumChannels; + size_t mPhase; + + MediaBufferGroup *mGroup; +}; + +} // namespace android + +#endif // SINE_SOURCE_H_ diff --git a/cmds/stagefright/record.cpp b/cmds/stagefright/record.cpp index 4b44761..c049594 100644 --- a/cmds/stagefright/record.cpp +++ b/cmds/stagefright/record.cpp @@ -14,7 +14,10 @@ * limitations under the License. */ +#include "SineSource.h" + #include +#include #include #include #include @@ -24,9 +27,11 @@ #include #include #include +#include using namespace android; +#if 0 class DummySource : public MediaSource { public: DummySource(int width, int height) @@ -158,7 +163,7 @@ int main(int argc, char **argv) { OMXCodec::Create( client.interface(), enc_meta, true /* createEncoder */, decoder); -#if 1 +#if 0 sp writer = new MPEG4Writer("/sdcard/output.mp4"); writer->addSource(enc_meta, encoder); writer->start(); @@ -204,4 +209,60 @@ int main(int argc, char **argv) { return 0; } +#endif + +int main(int argc, char **argv) { + android::ProcessState::self()->startThreadPool(); + + OMXClient client; + CHECK_EQ(client.connect(), OK); + + const int32_t kSampleRate = 22050; + const int32_t kNumChannels = 2; + sp audioSource = new SineSource(kSampleRate, kNumChannels); + +#if 0 + sp audioSink; + AudioPlayer *player = new AudioPlayer(audioSink); + player->setSource(audioSource); + player->start(); + + sleep(10); + + player->stop(); +#endif + + sp encMeta = new MetaData; + encMeta->setCString(kKeyMIMEType, 1 ? "audio/3gpp" : "audio/mp4a-latm"); + encMeta->setInt32(kKeySampleRate, kSampleRate); + encMeta->setInt32(kKeyChannelCount, kNumChannels); + encMeta->setInt32(kKeyMaxInputSize, 8192); + + sp encoder = + OMXCodec::Create(client.interface(), encMeta, true, audioSource); + + encoder->start(); + + int32_t n = 0; + status_t err; + MediaBuffer *buffer; + while ((err = encoder->read(&buffer)) == OK) { + printf("."); + fflush(stdout); + + buffer->release(); + buffer = NULL; + + if (++n == 10000) { + break; + } + } + printf("$\n"); + + encoder->stop(); + + client.disconnect(); + + return 0; +} -- cgit v1.1