Merge "Optionally repeat the previously submitted frame to the encoder" into klp-dev
diff --git a/cmds/screenrecord/screenrecord.cpp b/cmds/screenrecord/screenrecord.cpp
index 28fc00f..923f781 100644
--- a/cmds/screenrecord/screenrecord.cpp
+++ b/cmds/screenrecord/screenrecord.cpp
@@ -36,6 +36,7 @@
#include <media/ICrypto.h>
#include <stdio.h>
+#include <fcntl.h>
#include <signal.h>
#include <getopt.h>
@@ -599,7 +600,19 @@
return 2;
}
- status_t err = recordScreen(argv[optind]);
+ // MediaMuxer tries to create the file in the constructor, but we don't
+ // learn about the failure until muxer.start(), which returns a generic
+ // error code without logging anything. We attempt to create the file
+ // now for better diagnostics.
+ const char* fileName = argv[optind];
+ int fd = open(fileName, O_CREAT | O_RDWR, 0644);
+ if (fd < 0) {
+ fprintf(stderr, "Unable to open '%s': %s\n", fileName, strerror(errno));
+ return 1;
+ }
+ close(fd);
+
+ status_t err = recordScreen(fileName);
ALOGD(err == NO_ERROR ? "success" : "failed");
return (int) err;
}
diff --git a/cmds/stagefright/Android.mk b/cmds/stagefright/Android.mk
index 1060131..561ce02 100644
--- a/cmds/stagefright/Android.mk
+++ b/cmds/stagefright/Android.mk
@@ -19,6 +19,8 @@
LOCAL_CFLAGS += -Wno-multichar
+LOCAL_MODULE_TAGS := optional
+
LOCAL_MODULE:= stagefright
include $(BUILD_EXECUTABLE)
diff --git a/include/media/AudioRecord.h b/include/media/AudioRecord.h
index f457261..62f0c64 100644
--- a/include/media/AudioRecord.h
+++ b/include/media/AudioRecord.h
@@ -423,14 +423,7 @@
nsecs_t processAudioBuffer(const sp<AudioRecordThread>& thread);
// caller must hold lock on mLock for all _l methods
- status_t openRecord_l(uint32_t sampleRate,
- audio_format_t format,
- size_t frameCount,
- audio_input_flags_t flags,
- audio_io_handle_t input,
- size_t epoch);
-
- audio_io_handle_t getInput_l();
+ status_t openRecord_l(size_t epoch);
// FIXME enum is faster than strcmp() for parameter 'from'
status_t restoreRecord_l(const char *from);
diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp
index 616c3d6..e934a3e 100644
--- a/media/libmedia/AudioRecord.cpp
+++ b/media/libmedia/AudioRecord.cpp
@@ -175,6 +175,7 @@
if (inputSource == AUDIO_SOURCE_DEFAULT) {
inputSource = AUDIO_SOURCE_MIC;
}
+ mInputSource = inputSource;
if (sampleRate == 0) {
ALOGE("Invalid sample rate %u", sampleRate);
@@ -210,28 +211,10 @@
// Assumes audio_is_linear_pcm(format), else sizeof(uint8_t)
mFrameSize = channelCount * audio_bytes_per_sample(format);
- if (sessionId == 0 ) {
- mSessionId = AudioSystem::newAudioSessionId();
- } else {
- mSessionId = sessionId;
- }
- ALOGV("set(): mSessionId %d", mSessionId);
-
- mFlags = flags;
-
- audio_io_handle_t input = AudioSystem::getInput(inputSource,
- sampleRate,
- format,
- channelMask,
- mSessionId);
- if (input == 0) {
- ALOGE("Could not get audio input for record source %d", inputSource);
- return BAD_VALUE;
- }
-
// validate framecount
size_t minFrameCount = 0;
- status_t status = getMinFrameCount(&minFrameCount, sampleRate, format, channelMask);
+ status_t status = AudioRecord::getMinFrameCount(&minFrameCount,
+ sampleRate, format, channelMask);
if (status != NO_ERROR) {
ALOGE("getMinFrameCount() failed; status %d", status);
return status;
@@ -244,13 +227,23 @@
ALOGE("frameCount %u < minFrameCount %u", frameCount, minFrameCount);
return BAD_VALUE;
}
+ mFrameCount = frameCount;
mNotificationFramesReq = notificationFrames;
mNotificationFramesAct = 0;
+ if (sessionId == 0 ) {
+ mSessionId = AudioSystem::newAudioSessionId();
+ } else {
+ mSessionId = sessionId;
+ }
+ ALOGV("set(): mSessionId %d", mSessionId);
+
+ mFlags = flags;
+
// create the IAudioRecord
- status = openRecord_l(sampleRate, format, frameCount, mFlags, input, 0 /*epoch*/);
- if (status != NO_ERROR) {
+ status = openRecord_l(0 /*epoch*/);
+ if (status) {
return status;
}
@@ -274,8 +267,6 @@
mMarkerReached = false;
mNewPosition = 0;
mUpdatePeriod = 0;
- mInputSource = inputSource;
- mInput = input;
AudioSystem::acquireAudioSessionId(mSessionId);
mSequence = 1;
mObservedSequence = mSequence;
@@ -429,13 +420,7 @@
// -------------------------------------------------------------------------
// must be called with mLock held
-status_t AudioRecord::openRecord_l(
- uint32_t sampleRate,
- audio_format_t format,
- size_t frameCount,
- audio_input_flags_t flags,
- audio_io_handle_t input,
- size_t epoch)
+status_t AudioRecord::openRecord_l(size_t epoch)
{
status_t status;
const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger();
@@ -449,12 +434,11 @@
// Client can only express a preference for FAST. Server will perform additional tests.
// The only supported use case for FAST is callback transfer mode.
- if (flags & AUDIO_INPUT_FLAG_FAST) {
+ if (mFlags & AUDIO_INPUT_FLAG_FAST) {
if ((mTransfer != TRANSFER_CALLBACK) || (mAudioRecordThread == 0)) {
ALOGW("AUDIO_INPUT_FLAG_FAST denied by client");
// once denied, do not request again if IAudioRecord is re-created
- flags = (audio_input_flags_t) (flags & ~AUDIO_INPUT_FLAG_FAST);
- mFlags = flags;
+ mFlags = (audio_input_flags_t) (mFlags & ~AUDIO_INPUT_FLAG_FAST);
} else {
trackFlags |= IAudioFlinger::TRACK_FAST;
tid = mAudioRecordThread->getTid();
@@ -463,18 +447,25 @@
mNotificationFramesAct = mNotificationFramesReq;
- if (!(flags & AUDIO_INPUT_FLAG_FAST)) {
+ if (!(mFlags & AUDIO_INPUT_FLAG_FAST)) {
// Make sure that application is notified with sufficient margin before overrun
- if (mNotificationFramesAct == 0 || mNotificationFramesAct > frameCount/2) {
- mNotificationFramesAct = frameCount/2;
+ if (mNotificationFramesAct == 0 || mNotificationFramesAct > mFrameCount/2) {
+ mNotificationFramesAct = mFrameCount/2;
}
}
+ audio_io_handle_t input = AudioSystem::getInput(mInputSource, mSampleRate, mFormat,
+ mChannelMask, mSessionId);
+ if (input == 0) {
+ ALOGE("Could not get audio input for record source %d", mInputSource);
+ return BAD_VALUE;
+ }
+
int originalSessionId = mSessionId;
sp<IAudioRecord> record = audioFlinger->openRecord(input,
- sampleRate, format,
+ mSampleRate, mFormat,
mChannelMask,
- frameCount,
+ mFrameCount,
&trackFlags,
tid,
&mSessionId,
@@ -484,6 +475,7 @@
if (record == 0) {
ALOGE("AudioFlinger could not create record track, status: %d", status);
+ AudioSystem::releaseInput(input);
return status;
}
sp<IMemory> iMem = record->getCblk();
@@ -495,27 +487,27 @@
mAudioRecord->asBinder()->unlinkToDeath(mDeathNotifier, this);
mDeathNotifier.clear();
}
+ mInput = input;
mAudioRecord = record;
mCblkMemory = iMem;
audio_track_cblk_t* cblk = static_cast<audio_track_cblk_t*>(iMem->pointer());
mCblk = cblk;
// FIXME missing fast track frameCount logic
mAwaitBoost = false;
- if (flags & AUDIO_INPUT_FLAG_FAST) {
+ if (mFlags & AUDIO_INPUT_FLAG_FAST) {
if (trackFlags & IAudioFlinger::TRACK_FAST) {
- ALOGV("AUDIO_INPUT_FLAG_FAST successful; frameCount %u", frameCount);
+ ALOGV("AUDIO_INPUT_FLAG_FAST successful; frameCount %u", mFrameCount);
mAwaitBoost = true;
// double-buffering is not required for fast tracks, due to tighter scheduling
- if (mNotificationFramesAct == 0 || mNotificationFramesAct > frameCount) {
- mNotificationFramesAct = frameCount;
+ if (mNotificationFramesAct == 0 || mNotificationFramesAct > mFrameCount) {
+ mNotificationFramesAct = mFrameCount;
}
} else {
- ALOGV("AUDIO_INPUT_FLAG_FAST denied by server; frameCount %u", frameCount);
+ ALOGV("AUDIO_INPUT_FLAG_FAST denied by server; frameCount %u", mFrameCount);
// once denied, do not request again if IAudioRecord is re-created
- flags = (audio_input_flags_t) (flags & ~AUDIO_INPUT_FLAG_FAST);
- mFlags = flags;
- if (mNotificationFramesAct == 0 || mNotificationFramesAct > frameCount/2) {
- mNotificationFramesAct = frameCount/2;
+ mFlags = (audio_input_flags_t) (mFlags & ~AUDIO_INPUT_FLAG_FAST);
+ if (mNotificationFramesAct == 0 || mNotificationFramesAct > mFrameCount/2) {
+ mNotificationFramesAct = mFrameCount/2;
}
}
}
@@ -524,7 +516,7 @@
void *buffers = (char*)cblk + sizeof(audio_track_cblk_t);
// update proxy
- mProxy = new AudioRecordClientProxy(cblk, buffers, frameCount, mFrameSize);
+ mProxy = new AudioRecordClientProxy(cblk, buffers, mFrameCount, mFrameSize);
mProxy->setEpoch(epoch);
mProxy->setMinimum(mNotificationFramesAct);
@@ -651,17 +643,6 @@
return mInput;
}
-// must be called with mLock held
-audio_io_handle_t AudioRecord::getInput_l()
-{
- mInput = AudioSystem::getInput(mInputSource,
- mSampleRate,
- mFormat,
- mChannelMask,
- mSessionId);
- return mInput;
-}
-
// -------------------------------------------------------------------------
ssize_t AudioRecord::read(void* buffer, size_t userSize)
@@ -949,7 +930,7 @@
// It will also delete the strong references on previous IAudioRecord and IMemory
size_t position = mProxy->getPosition();
mNewPosition = position + mUpdatePeriod;
- result = openRecord_l(mSampleRate, mFormat, mFrameCount, mFlags, getInput_l(), position);
+ result = openRecord_l(position);
if (result == NO_ERROR) {
if (mActive) {
// callback thread or sync event hasn't changed
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index cd67359..7b0bce0 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -4148,13 +4148,28 @@
if (params->findInt32("drop-input-frames", &dropInputFrames)) {
bool suspend = dropInputFrames != 0;
- CHECK_EQ((status_t)OK,
- mOMX->setInternalOption(
+ status_t err =
+ mOMX->setInternalOption(
mNode,
kPortIndexInput,
IOMX::INTERNAL_OPTION_SUSPEND,
&suspend,
- sizeof(suspend)));
+ sizeof(suspend));
+
+ if (err != OK) {
+ ALOGE("Failed to set parameter 'drop-input-frames' (err %d)", err);
+ return err;
+ }
+ }
+
+ int32_t dummy;
+ if (params->findInt32("request-sync", &dummy)) {
+ status_t err = requestIDRFrame();
+
+ if (err != OK) {
+ ALOGE("Requesting a sync frame failed w/ err %d", err);
+ return err;
+ }
}
return OK;