Merge changes I140d291e,Id443ec5c
* changes:
remove files that moved to frameworks/native
fixup hardcoded include paths for new project
diff --git a/cmds/stagefright/codec.cpp b/cmds/stagefright/codec.cpp
index fbf800c..0414b98 100644
--- a/cmds/stagefright/codec.cpp
+++ b/cmds/stagefright/codec.cpp
@@ -35,7 +35,8 @@
static void usage(const char *me) {
fprintf(stderr, "usage: %s [-a] use audio\n"
"\t\t[-v] use video\n"
- "\t\t[-p] playback\n", me);
+ "\t\t[-p] playback\n"
+ "\t\t[-S] allocate buffers from a surface\n", me);
exit(1);
}
@@ -49,6 +50,9 @@
Vector<sp<ABuffer> > mInBuffers;
Vector<sp<ABuffer> > mOutBuffers;
bool mSawOutputEOS;
+ int64_t mNumBuffersDecoded;
+ int64_t mNumBytesDecoded;
+ bool mIsAudio;
};
} // namespace android
@@ -57,9 +61,12 @@
const android::sp<android::ALooper> &looper,
const char *path,
bool useAudio,
- bool useVideo) {
+ bool useVideo,
+ const android::sp<android::Surface> &surface) {
using namespace android;
+ static int64_t kTimeout = 500ll;
+
sp<NuMediaExtractor> extractor = new NuMediaExtractor;
if (extractor->setDataSource(path) != OK) {
fprintf(stderr, "unable to instantiate extractor.\n");
@@ -78,11 +85,12 @@
AString mime;
CHECK(format->findString("mime", &mime));
- if (useAudio && !haveAudio
- && !strncasecmp(mime.c_str(), "audio/", 6)) {
+ bool isAudio = !strncasecmp(mime.c_str(), "audio/", 6);
+ bool isVideo = !strncasecmp(mime.c_str(), "video/", 6);
+
+ if (useAudio && !haveAudio && isAudio) {
haveAudio = true;
- } else if (useVideo && !haveVideo
- && !strncasecmp(mime.c_str(), "video/", 6)) {
+ } else if (useVideo && !haveVideo && isVideo) {
haveVideo = true;
} else {
continue;
@@ -96,13 +104,17 @@
CodecState *state =
&stateByTrack.editValueAt(stateByTrack.add(i, CodecState()));
+ state->mNumBytesDecoded = 0;
+ state->mNumBuffersDecoded = 0;
+ state->mIsAudio = isAudio;
+
state->mCodec = MediaCodec::CreateByType(
looper, mime.c_str(), false /* encoder */);
CHECK(state->mCodec != NULL);
err = state->mCodec->configure(
- format, NULL /* surfaceTexture */, 0 /* flags */);
+ format, isVideo ? surface : NULL, 0 /* flags */);
CHECK_EQ(err, (status_t)OK);
@@ -122,6 +134,8 @@
CHECK(!stateByTrack.isEmpty());
+ int64_t startTimeUs = ALooper::GetNowUs();
+
for (size_t i = 0; i < stateByTrack.size(); ++i) {
CodecState *state = &stateByTrack.editValueAt(i);
@@ -137,13 +151,7 @@
while (state->mCSDIndex < state->mCSD.size()) {
size_t index;
- status_t err = codec->dequeueInputBuffer(&index);
-
- if (err == -EAGAIN) {
- usleep(10000);
- continue;
- }
-
+ status_t err = codec->dequeueInputBuffer(&index, -1ll);
CHECK_EQ(err, (status_t)OK);
const sp<ABuffer> &srcBuffer =
@@ -179,7 +187,7 @@
for (;;) {
size_t index;
- err = state->mCodec->dequeueInputBuffer(&index);
+ err = state->mCodec->dequeueInputBuffer(&index, kTimeout);
if (err == -EAGAIN) {
continue;
@@ -204,7 +212,7 @@
CodecState *state = &stateByTrack.editValueFor(trackIndex);
size_t index;
- err = state->mCodec->dequeueInputBuffer(&index);
+ err = state->mCodec->dequeueInputBuffer(&index, kTimeout);
if (err == OK) {
ALOGV("filling input buffer %d", index);
@@ -261,12 +269,15 @@
uint32_t flags;
status_t err = state->mCodec->dequeueOutputBuffer(
&index, &offset, &size, &presentationTimeUs, &flags,
- 10000ll);
+ kTimeout);
if (err == OK) {
ALOGV("draining output buffer %d, time = %lld us",
index, presentationTimeUs);
+ ++state->mNumBuffersDecoded;
+ state->mNumBytesDecoded += size;
+
err = state->mCodec->releaseOutputBuffer(index);
CHECK_EQ(err, (status_t)OK);
@@ -292,10 +303,27 @@
}
}
+ int64_t elapsedTimeUs = ALooper::GetNowUs() - startTimeUs;
+
for (size_t i = 0; i < stateByTrack.size(); ++i) {
CodecState *state = &stateByTrack.editValueAt(i);
CHECK_EQ((status_t)OK, state->mCodec->release());
+
+ if (state->mIsAudio) {
+ printf("track %d: %lld bytes received. %.2f KB/sec\n",
+ i,
+ state->mNumBytesDecoded,
+ state->mNumBytesDecoded * 1E6 / 1024 / elapsedTimeUs);
+ } else {
+ printf("track %d: %lld frames decoded, %.2f fps. %lld bytes "
+ "received. %.2f KB/sec\n",
+ i,
+ state->mNumBuffersDecoded,
+ state->mNumBuffersDecoded * 1E6 / elapsedTimeUs,
+ state->mNumBytesDecoded,
+ state->mNumBytesDecoded * 1E6 / 1024 / elapsedTimeUs);
+ }
}
return 0;
@@ -309,9 +337,10 @@
bool useAudio = false;
bool useVideo = false;
bool playback = false;
+ bool useSurface = false;
int res;
- while ((res = getopt(argc, argv, "havp")) >= 0) {
+ while ((res = getopt(argc, argv, "havpS")) >= 0) {
switch (res) {
case 'a':
{
@@ -331,6 +360,12 @@
break;
}
+ case 'S':
+ {
+ useSurface = true;
+ break;
+ }
+
case '?':
case 'h':
default:
@@ -358,8 +393,12 @@
sp<ALooper> looper = new ALooper;
looper->start();
- if (playback) {
- sp<SurfaceComposerClient> composerClient = new SurfaceComposerClient;
+ sp<SurfaceComposerClient> composerClient;
+ sp<SurfaceControl> control;
+ sp<Surface> surface;
+
+ if (playback || (useSurface && useVideo)) {
+ composerClient = new SurfaceComposerClient;
CHECK_EQ(composerClient->initCheck(), (status_t)OK);
ssize_t displayWidth = composerClient->getDisplayWidth(0);
@@ -367,14 +406,13 @@
ALOGV("display is %ld x %ld\n", displayWidth, displayHeight);
- sp<SurfaceControl> control =
- composerClient->createSurface(
- String8("A Surface"),
- 0,
- displayWidth,
- displayHeight,
- PIXEL_FORMAT_RGB_565,
- 0);
+ control = composerClient->createSurface(
+ String8("A Surface"),
+ 0,
+ displayWidth,
+ displayHeight,
+ PIXEL_FORMAT_RGB_565,
+ 0);
CHECK(control != NULL);
CHECK(control->isValid());
@@ -384,9 +422,11 @@
CHECK_EQ(control->show(), (status_t)OK);
SurfaceComposerClient::closeGlobalTransaction();
- sp<Surface> surface = control->getSurface();
+ surface = control->getSurface();
CHECK(surface != NULL);
+ }
+ if (playback) {
sp<SimplePlayer> player = new SimplePlayer;
looper->registerHandler(player);
@@ -396,10 +436,12 @@
sleep(60);
player->stop();
player->reset();
-
- composerClient->dispose();
} else {
- decode(looper, argv[0], useAudio, useVideo);
+ decode(looper, argv[0], useAudio, useVideo, surface);
+ }
+
+ if (playback || (useSurface && useVideo)) {
+ composerClient->dispose();
}
looper->stop();
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/vop.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/vop.cpp
index 74fe478..b3c350f 100644
--- a/media/libstagefright/codecs/m4v_h263/dec/src/vop.cpp
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/vop.cpp
@@ -1041,7 +1041,7 @@
/* Marker Bit */
if (!BitstreamRead1Bits(stream))
{
- mp4dec_log("DecodeShortHeader(): Market bit wrong.\n");
+ mp4dec_log("DecodeShortHeader(): Marker bit wrong.\n");
status = PV_FAIL;
goto return_point;
}
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 032406e..fd7418c 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -1462,7 +1462,9 @@
// Assumes constructor is called by AudioFlinger with it's mLock held,
// but it would be safer to explicitly pass initial masterVolume as parameter
mMasterVolume(audioFlinger->masterVolumeSW_l()),
- mLastWriteTime(0), mNumWrites(0), mNumDelayedWrites(0), mInWrite(false)
+ mLastWriteTime(0), mNumWrites(0), mNumDelayedWrites(0), mInWrite(false),
+ // mMixerStatus
+ mPrevMixerStatus(MIXER_IDLE)
{
snprintf(mName, kNameLength, "AudioOut_%X", id);
@@ -1922,7 +1924,6 @@
: PlaybackThread(audioFlinger, output, id, device, type)
{
mAudioMixer = new AudioMixer(mFrameCount, mSampleRate);
- mPrevMixerStatus = MIXER_IDLE;
// FIXME - Current mixer implementation only supports stereo output
if (mChannelCount == 1) {
ALOGE("Invalid audio hardware channel count");
@@ -2043,11 +2044,7 @@
processConfigEvents();
-if (mType == DIRECT) {
- activeTrack.clear();
-}
-
- mixerStatus = MIXER_IDLE;
+ mMixerStatus = MIXER_IDLE;
{ // scope for mLock
Mutex::Autolock _l(mLock);
@@ -2102,9 +2099,7 @@
ALOGV("Thread %p type %d TID %d waking up", this, mType, gettid());
acquireWakeLock_l();
-if (mType == MIXER || mType == DUPLICATING) {
mPrevMixerStatus = MIXER_IDLE;
-}
checkSilentMode_l();
@@ -2126,11 +2121,11 @@
}
}
- mixerStatus = prepareTracks_l(&tracksToRemove);
- // see FIXME in AudioFlinger.h
- if (mixerStatus == MIXER_CONTINUE) {
- continue;
- }
+ mixer_state newMixerStatus = prepareTracks_l(&tracksToRemove);
+ // Shift in the new status; this could be a queue if it's
+ // useful to filter the mixer status over several cycles.
+ mPrevMixerStatus = mMixerStatus;
+ mMixerStatus = newMixerStatus;
// prevent any changes in effect chain list and in each effect chain
// during mixing and effect process as the audio buffers could be deleted
@@ -2138,11 +2133,7 @@
lockEffectChains_l(effectChains);
}
-if (mType == DIRECT) {
- // For DirectOutputThread, this test is equivalent to "activeTrack != 0"
-}
-
- if (CC_LIKELY(mixerStatus == MIXER_TRACKS_READY)) {
+ if (CC_LIKELY(mMixerStatus == MIXER_TRACKS_READY)) {
threadLoop_mix();
} else {
threadLoop_sleepTime();
@@ -2196,10 +2187,6 @@
// same lock.
tracksToRemove.clear();
-// FIXME merge these
-if (mType == DIRECT) {
- activeTrack.clear();
-}
// FIXME I don't understand the need for this here;
// it was in the original code but maybe the
// assignment in saveOutputTracks() makes this unnecessary?
@@ -2283,7 +2270,7 @@
// If no tracks are ready, sleep once for the duration of an output
// buffer size, then write 0s to the output
if (sleepTime == 0) {
- if (mixerStatus == MIXER_TRACKS_ENABLED) {
+ if (mMixerStatus == MIXER_TRACKS_ENABLED) {
sleepTime = activeSleepTime >> sleepTimeShift;
if (sleepTime < kMinThreadSleepTimeUs) {
sleepTime = kMinThreadSleepTimeUs;
@@ -2299,10 +2286,10 @@
sleepTime = idleSleepTime;
}
} else if (mBytesWritten != 0 ||
- (mixerStatus == MIXER_TRACKS_ENABLED && longStandbyExit)) {
+ (mMixerStatus == MIXER_TRACKS_ENABLED && longStandbyExit)) {
memset (mMixBuffer, 0, mixBufferSize);
sleepTime = 0;
- ALOGV_IF((mBytesWritten == 0 && (mixerStatus == MIXER_TRACKS_ENABLED && longStandbyExit)), "anticipated start");
+ ALOGV_IF((mBytesWritten == 0 && (mMixerStatus == MIXER_TRACKS_ENABLED && longStandbyExit)), "anticipated start");
}
// TODO add standby time extension fct of effect tail
}
@@ -2558,7 +2545,6 @@
memset(mMixBuffer, 0, mFrameCount * mChannelCount * sizeof(int16_t));
}
- mPrevMixerStatus = mixerStatus;
return mixerStatus;
}
@@ -2825,15 +2811,13 @@
{
sp<Track> trackToRemove;
- // FIXME Temporarily renamed to avoid confusion with the member "mixerStatus"
- mixer_state mixerStatus_ = MIXER_IDLE;
+ mixer_state mixerStatus = MIXER_IDLE;
// find out which tracks need to be processed
if (mActiveTracks.size() != 0) {
sp<Track> t = mActiveTracks[0].promote();
- // see FIXME in AudioFlinger.h, return MIXER_IDLE might also work
- if (t == 0) return MIXER_CONTINUE;
- //if (t == 0) continue;
+ // The track died recently
+ if (t == 0) return MIXER_IDLE;
Track* const track = t.get();
audio_track_cblk_t* cblk = track->cblk();
@@ -2918,8 +2902,8 @@
// reset retry count
track->mRetryCount = kMaxTrackRetriesDirect;
- activeTrack = t;
- mixerStatus_ = MIXER_TRACKS_READY;
+ mActiveTrack = t;
+ mixerStatus = MIXER_TRACKS_READY;
} else {
//ALOGV("track %d u=%08x, s=%08x [NOT READY]", track->name(), cblk->user, cblk->server);
if (track->isStopped()) {
@@ -2936,7 +2920,7 @@
ALOGV("BUFFER TIMEOUT: remove(%d) from active list", track->name());
trackToRemove = track;
} else {
- mixerStatus_ = MIXER_TRACKS_ENABLED;
+ mixerStatus = MIXER_TRACKS_ENABLED;
}
}
}
@@ -2957,7 +2941,7 @@
}
}
- return mixerStatus_;
+ return mixerStatus;
}
void AudioFlinger::DirectOutputThread::threadLoop_mix()
@@ -2968,7 +2952,7 @@
// output audio to hardware
while (frameCount) {
buffer.frameCount = frameCount;
- activeTrack->getNextBuffer(&buffer);
+ mActiveTrack->getNextBuffer(&buffer);
if (CC_UNLIKELY(buffer.raw == NULL)) {
memset(curBuf, 0, frameCount * mFrameSize);
break;
@@ -2976,17 +2960,18 @@
memcpy(curBuf, buffer.raw, buffer.frameCount * mFrameSize);
frameCount -= buffer.frameCount;
curBuf += buffer.frameCount * mFrameSize;
- activeTrack->releaseBuffer(&buffer);
+ mActiveTrack->releaseBuffer(&buffer);
}
sleepTime = 0;
standbyTime = systemTime() + standbyDelay;
+ mActiveTrack.clear();
applyVolume();
}
void AudioFlinger::DirectOutputThread::threadLoop_sleepTime()
{
if (sleepTime == 0) {
- if (mixerStatus == MIXER_TRACKS_ENABLED) {
+ if (mMixerStatus == MIXER_TRACKS_ENABLED) {
sleepTime = activeSleepTime;
} else {
sleepTime = idleSleepTime;
@@ -3122,7 +3107,7 @@
void AudioFlinger::DuplicatingThread::threadLoop_sleepTime()
{
if (sleepTime == 0) {
- if (mixerStatus == MIXER_TRACKS_ENABLED) {
+ if (mMixerStatus == MIXER_TRACKS_ENABLED) {
sleepTime = activeSleepTime;
} else {
sleepTime = idleSleepTime;
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index e26466f..2e259c0 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -607,10 +607,6 @@
MIXER_TRACKS_READY // at least one active track, and at least one track has data
// standby mode does not have an enum value
// suspend by audio policy manager is orthogonal to mixer state
-#if 1
- // FIXME remove this hack for prepareTracks_l()
- , MIXER_CONTINUE // "continue;"
-#endif
};
// playback track
@@ -962,19 +958,17 @@
uint32_t activeSleepTime;
uint32_t idleSleepTime;
uint32_t sleepTime;
- // mixerStatus was local to the while !exitingPending loop
- mixer_state mixerStatus;
+
+ // mixer status returned by prepareTracks_l()
+ mixer_state mMixerStatus; // current cycle
+ mixer_state mPrevMixerStatus; // previous cycle
// FIXME move these declarations into the specific sub-class that needs them
// MIXER only
bool longStandbyExit;
uint32_t sleepTimeShift;
- // MIXER and DUPLICATING only
- mixer_state mPrevMixerStatus; // previous status returned by prepareTracks_l()
// DIRECT only
nsecs_t standbyDelay;
- // activeTrack was local to the while !exitingPending loop
- sp<Track> activeTrack;
// DUPLICATING only
uint32_t writeFrames;
};
@@ -1046,6 +1040,9 @@
private:
void applyVolume(); // FIXME inline into threadLoop_mix()
+
+ // prepareTracks_l() tells threadLoop_mix() the name of the single active track
+ sp<Track> mActiveTrack;
};
class DuplicatingThread : public MixerThread {