Merge "MediaFormat owns its strings"
diff --git a/cmds/stagefright/audioloop.cpp b/cmds/stagefright/audioloop.cpp
index ed7d6cb..96073f1 100644
--- a/cmds/stagefright/audioloop.cpp
+++ b/cmds/stagefright/audioloop.cpp
@@ -1,4 +1,18 @@
-#include "SineSource.h"
+/*
+ * Copyright (C) 2014 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.
+ */
#include <binder/ProcessState.h>
#include <media/mediarecorder.h>
@@ -10,41 +24,79 @@
#include <media/stagefright/MetaData.h>
#include <media/stagefright/OMXClient.h>
#include <media/stagefright/OMXCodec.h>
-
-#include <system/audio.h>
+#include "SineSource.h"
using namespace android;
-int main() {
- // We only have an AMR-WB encoder on sholes...
- static bool outputWBAMR = false;
- static const int32_t kSampleRate = outputWBAMR ? 16000 : 8000;
- static const int32_t kNumChannels = 1;
+static void usage(const char* name)
+{
+ fprintf(stderr, "Usage: %s [-d duration] [-m] [-w] [<output-file>]\n", name);
+ fprintf(stderr, "Encodes either a sine wave or microphone input to AMR format\n");
+ fprintf(stderr, " -d duration in seconds, default 5 seconds\n");
+ fprintf(stderr, " -m use microphone for input, default sine source\n");
+ fprintf(stderr, " -w use AMR wideband (default narrowband)\n");
+ fprintf(stderr, " <output-file> output file for AMR encoding,"
+ " if unspecified, decode to speaker.\n");
+}
+
+int main(int argc, char* argv[])
+{
+ static const int channels = 1; // not permitted to be stereo now
+ unsigned duration = 5;
+ bool useMic = false;
+ bool outputWBAMR = false;
+ bool playToSpeaker = true;
+ const char* fileOut = NULL;
+ int ch;
+ while ((ch = getopt(argc, argv, "d:mw")) != -1) {
+ switch (ch) {
+ case 'd':
+ duration = atoi(optarg);
+ break;
+ case 'm':
+ useMic = true;
+ break;
+ case 'w':
+ outputWBAMR = true;
+ break;
+ default:
+ usage(argv[0]);
+ return -1;
+ }
+ }
+ argc -= optind;
+ argv += optind;
+ if (argc == 1) {
+ fileOut = argv[0];
+ }
+ const int32_t kSampleRate = outputWBAMR ? 16000 : 8000;
+ const int32_t kBitRate = outputWBAMR ? 16000 : 8000;
android::ProcessState::self()->startThreadPool();
-
OMXClient client;
CHECK_EQ(client.connect(), (status_t)OK);
+ sp<MediaSource> source;
-#if 0
- sp<MediaSource> source = new SineSource(kSampleRate, kNumChannels);
-#else
- sp<MediaSource> source = new AudioSource(
- AUDIO_SOURCE_DEFAULT,
- kSampleRate,
- audio_channel_in_mask_from_count(kNumChannels));
-#endif
+ if (useMic) {
+ // talk into the appropriate microphone for the duration
+ source = new AudioSource(
+ AUDIO_SOURCE_MIC,
+ kSampleRate,
+ channels);
+ } else {
+ // use a sine source at 500 hz.
+ source = new SineSource(kSampleRate, channels);
+ }
sp<MetaData> meta = new MetaData;
-
meta->setCString(
kKeyMIMEType,
outputWBAMR ? MEDIA_MIMETYPE_AUDIO_AMR_WB
- : MEDIA_MIMETYPE_AUDIO_AMR_NB);
+ : MEDIA_MIMETYPE_AUDIO_AMR_NB);
- meta->setInt32(kKeyChannelCount, kNumChannels);
+ meta->setInt32(kKeyChannelCount, channels);
meta->setInt32(kKeySampleRate, kSampleRate);
-
+ meta->setInt32(kKeyBitRate, kBitRate);
int32_t maxInputSize;
if (source->getFormat()->findInt32(kKeyMaxInputSize, &maxInputSize)) {
meta->setInt32(kKeyMaxInputSize, maxInputSize);
@@ -55,47 +107,41 @@
meta, true /* createEncoder */,
source);
-#if 1
- sp<AMRWriter> writer = new AMRWriter("/sdcard/out.amr");
- writer->addSource(encoder);
- writer->start();
- sleep(10);
- writer->stop();
-#else
- sp<MediaSource> decoder = OMXCodec::Create(
- client.interface(),
- meta, false /* createEncoder */,
- encoder);
+ if (fileOut != NULL) {
+ // target file specified, write encoded AMR output
+ sp<AMRWriter> writer = new AMRWriter(fileOut);
+ writer->addSource(encoder);
+ writer->start();
+ sleep(duration);
+ writer->stop();
+ } else {
+ // otherwise decode to speaker
+ sp<MediaSource> decoder = OMXCodec::Create(
+ client.interface(),
+ meta, false /* createEncoder */,
+ encoder);
-#if 0
- AudioPlayer *player = new AudioPlayer(NULL);
- player->setSource(decoder);
-
- player->start();
-
- sleep(10);
-
- player->stop();
-
- delete player;
- player = NULL;
-#elif 0
- CHECK_EQ(decoder->start(), (status_t)OK);
-
- MediaBuffer *buffer;
- while (decoder->read(&buffer) == OK) {
- // do something with buffer
-
- putchar('.');
- fflush(stdout);
-
- buffer->release();
- buffer = NULL;
+ if (playToSpeaker) {
+ AudioPlayer *player = new AudioPlayer(NULL);
+ player->setSource(decoder);
+ player->start();
+ sleep(duration);
+ source->stop(); // must stop source otherwise delete player will hang
+ delete player; // there is no player->stop()...
+ } else {
+ CHECK_EQ(decoder->start(), (status_t)OK);
+ MediaBuffer* buffer;
+ while (decoder->read(&buffer) == OK) {
+ // do something with buffer (save it eventually?)
+ // need to stop after some count though...
+ putchar('.');
+ fflush(stdout);
+ buffer->release();
+ buffer = NULL;
+ }
+ CHECK_EQ(decoder->stop(), (status_t)OK);
+ }
}
- CHECK_EQ(decoder->stop(), (status_t)OK);
-#endif
-#endif
-
return 0;
}
diff --git a/cmds/stagefright/recordvideo.cpp b/cmds/stagefright/recordvideo.cpp
index 1d267f9..9f547c7 100644
--- a/cmds/stagefright/recordvideo.cpp
+++ b/cmds/stagefright/recordvideo.cpp
@@ -73,7 +73,7 @@
return meta;
}
- virtual status_t start(MetaData *params) {
+ virtual status_t start(MetaData *params __unused) {
mNumFramesOutput = 0;
return OK;
}
@@ -83,7 +83,7 @@
}
virtual status_t read(
- MediaBuffer **buffer, const MediaSource::ReadOptions *options) {
+ MediaBuffer **buffer, const MediaSource::ReadOptions *options __unused) {
if (mNumFramesOutput % 10 == 0) {
fprintf(stderr, ".");
@@ -100,8 +100,12 @@
// We don't care about the contents. we just test video encoder
// Also, by skipping the content generation, we can return from
// read() much faster.
- //char x = (char)((double)rand() / RAND_MAX * 255);
- //memset((*buffer)->data(), x, mSize);
+#if 0
+ // iterate through solid planes of color.
+ static unsigned char x = 0x60;
+ memset((*buffer)->data(), x, mSize);
+ x = x >= 0xa0 ? 0x60 : x + 1;
+#endif
(*buffer)->set_range(0, mSize);
(*buffer)->meta_data()->clear();
(*buffer)->meta_data()->setInt64(
@@ -163,7 +167,7 @@
int level = -1; // Encoder specific default
int profile = -1; // Encoder specific default
int codec = 0;
- char *fileName = "/sdcard/output.mp4";
+ const char *fileName = "/sdcard/output.mp4";
bool preferSoftwareCodec = false;
android::ProcessState::self()->startThreadPool();
diff --git a/services/audiopolicy/AudioPolicyService.cpp b/services/audiopolicy/AudioPolicyService.cpp
index 4a708a0..918c25c 100644
--- a/services/audiopolicy/AudioPolicyService.cpp
+++ b/services/audiopolicy/AudioPolicyService.cpp
@@ -270,6 +270,10 @@
if (!mAudioCommands.isEmpty()) {
release_wake_lock(mName.string());
}
+ for (size_t k=0; k < mAudioCommands.size(); k++) {
+ delete mAudioCommands[k]->mParam;
+ delete mAudioCommands[k];
+ }
mAudioCommands.clear();
delete mpToneGenerator;
}
@@ -441,7 +445,7 @@
ToneData *data = new ToneData();
data->mType = type;
data->mStream = stream;
- command->mParam = (void *)data;
+ command->mParam = data;
Mutex::Autolock _l(mLock);
insertCommand_l(command);
ALOGV("AudioCommandThread() adding tone start type %d, stream %d", type, stream);
@@ -542,7 +546,7 @@
data->mIO = output;
data->mStream = stream;
data->mSession = session;
- command->mParam = (void *)data;
+ command->mParam = data;
Mutex::Autolock _l(mLock);
insertCommand_l(command);
ALOGV("AudioCommandThread() adding stop output %d", output);
@@ -555,7 +559,7 @@
command->mCommand = RELEASE_OUTPUT;
ReleaseOutputData *data = new ReleaseOutputData();
data->mIO = output;
- command->mParam = (void *)data;
+ command->mParam = data;
Mutex::Autolock _l(mLock);
insertCommand_l(command);
ALOGV("AudioCommandThread() adding release output %d", output);
@@ -644,6 +648,10 @@
for (size_t k = i + 1; k < mAudioCommands.size(); k++) {
if (mAudioCommands[k] == removedCommands[j]) {
ALOGV("suppressing command: %d", mAudioCommands[k]->mCommand);
+ // for commands that are not filtered,
+ // command->mParam is deleted in threadLoop
+ delete mAudioCommands[k]->mParam;
+ delete mAudioCommands[k];
mAudioCommands.removeAt(k);
break;
}
diff --git a/services/audiopolicy/AudioPolicyService.h b/services/audiopolicy/AudioPolicyService.h
index cdc90d0..28e3a4b 100644
--- a/services/audiopolicy/AudioPolicyService.h
+++ b/services/audiopolicy/AudioPolicyService.h
@@ -198,6 +198,8 @@
void insertCommand_l(AudioCommand *command, int delayMs = 0);
private:
+ class AudioCommandData;
+
// descriptor for requested tone playback event
class AudioCommand {
@@ -212,41 +214,48 @@
Condition mCond; // condition for status return
status_t mStatus; // command status
bool mWaitStatus; // true if caller is waiting for status
- void *mParam; // command parameter (ToneData, VolumeData, ParametersData)
+ AudioCommandData *mParam; // command specific parameter data
};
- class ToneData {
+ class AudioCommandData {
+ public:
+ virtual ~AudioCommandData() {}
+ protected:
+ AudioCommandData() {}
+ };
+
+ class ToneData : public AudioCommandData {
public:
ToneGenerator::tone_type mType; // tone type (START_TONE only)
audio_stream_type_t mStream; // stream type (START_TONE only)
};
- class VolumeData {
+ class VolumeData : public AudioCommandData {
public:
audio_stream_type_t mStream;
float mVolume;
audio_io_handle_t mIO;
};
- class ParametersData {
+ class ParametersData : public AudioCommandData {
public:
audio_io_handle_t mIO;
String8 mKeyValuePairs;
};
- class VoiceVolumeData {
+ class VoiceVolumeData : public AudioCommandData {
public:
float mVolume;
};
- class StopOutputData {
+ class StopOutputData : public AudioCommandData {
public:
audio_io_handle_t mIO;
audio_stream_type_t mStream;
int mSession;
};
- class ReleaseOutputData {
+ class ReleaseOutputData : public AudioCommandData {
public:
audio_io_handle_t mIO;
};
diff --git a/services/camera/libcameraservice/device3/Camera3Stream.cpp b/services/camera/libcameraservice/device3/Camera3Stream.cpp
index abfb602..7645a2a 100644
--- a/services/camera/libcameraservice/device3/Camera3Stream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Stream.cpp
@@ -397,7 +397,7 @@
"must be set to NULL in camera3_device::ops", __FUNCTION__);
return INVALID_OPERATION;
} else {
- ALOGD("%s: Skipping NULL check for deprecated register_stream_buffers");
+ ALOGD("%s: Skipping NULL check for deprecated register_stream_buffers", __FUNCTION__);
}
return OK;