Merge "Fix issue 5355047: Automated effect tests fail."
diff --git a/cmds/stagefright/stagefright.cpp b/cmds/stagefright/stagefright.cpp
index 34f0a64..a126e83 100644
--- a/cmds/stagefright/stagefright.cpp
+++ b/cmds/stagefright/stagefright.cpp
@@ -133,6 +133,39 @@
}
}
+static void dumpSource(const sp<MediaSource> &source, const String8 &filename) {
+ FILE *out = fopen(filename.string(), "wb");
+
+ CHECK_EQ((status_t)OK, source->start());
+
+ status_t err;
+ for (;;) {
+ MediaBuffer *mbuf;
+ err = source->read(&mbuf);
+
+ if (err == INFO_FORMAT_CHANGED) {
+ continue;
+ } else if (err != OK) {
+ break;
+ }
+
+ CHECK_EQ(
+ fwrite((const uint8_t *)mbuf->data() + mbuf->range_offset(),
+ 1,
+ mbuf->range_length(),
+ out),
+ (ssize_t)mbuf->range_length());
+
+ mbuf->release();
+ mbuf = NULL;
+ }
+
+ CHECK_EQ((status_t)OK, source->stop());
+
+ fclose(out);
+ out = NULL;
+}
+
static void playSource(OMXClient *client, sp<MediaSource> &source) {
sp<MetaData> meta = source->getFormat();
@@ -578,6 +611,7 @@
"(video only)\n");
fprintf(stderr, " -S allocate buffers from a surface\n");
fprintf(stderr, " -T allocate buffers from a surface texture\n");
+ fprintf(stderr, " -d(ump) filename (raw stream data to a file)\n");
}
int main(int argc, char **argv) {
@@ -590,6 +624,8 @@
bool seekTest = false;
bool useSurfaceAlloc = false;
bool useSurfaceTexAlloc = false;
+ bool dumpStream = false;
+ String8 dumpStreamFilename;
gNumRepetitions = 1;
gMaxNumFrames = 0;
gReproduceBug = -1;
@@ -604,7 +640,7 @@
sp<LiveSession> liveSession;
int res;
- while ((res = getopt(argc, argv, "han:lm:b:ptsrow:kxST")) >= 0) {
+ while ((res = getopt(argc, argv, "han:lm:b:ptsrow:kxSTd:")) >= 0) {
switch (res) {
case 'a':
{
@@ -612,6 +648,13 @@
break;
}
+ case 'd':
+ {
+ dumpStream = true;
+ dumpStreamFilename.setTo(optarg);
+ break;
+ }
+
case 'l':
{
listComponents = true;
@@ -1062,6 +1105,8 @@
if (gWriteMP4) {
writeSourcesToMP4(mediaSources, syncInfoPresent);
+ } else if (dumpStream) {
+ dumpSource(mediaSource, dumpStreamFilename);
} else if (seekTest) {
performSeekTest(mediaSource);
} else {
diff --git a/drm/drmserver/DrmManager.cpp b/drm/drmserver/DrmManager.cpp
index 3e4fe8c..b2fa053 100644
--- a/drm/drmserver/DrmManager.cpp
+++ b/drm/drmserver/DrmManager.cpp
@@ -98,21 +98,27 @@
}
status_t DrmManager::loadPlugIns() {
+
+ String8 vendorPluginDirPath("/vendor/lib/drm");
+ loadPlugIns(vendorPluginDirPath);
+
String8 pluginDirPath("/system/lib/drm");
- return loadPlugIns(pluginDirPath);
+ loadPlugIns(pluginDirPath);
+ return DRM_NO_ERROR;
+
}
status_t DrmManager::loadPlugIns(const String8& plugInDirPath) {
- if (mSupportInfoToPlugInIdMap.isEmpty()) {
- mPlugInManager.loadPlugIns(plugInDirPath);
- Vector<String8> plugInPathList = mPlugInManager.getPlugInIdList();
- for (unsigned int i = 0; i < plugInPathList.size(); ++i) {
- String8 plugInPath = plugInPathList[i];
- DrmSupportInfo* info = mPlugInManager.getPlugIn(plugInPath).getSupportInfo(0);
- if (NULL != info) {
+ mPlugInManager.loadPlugIns(plugInDirPath);
+ Vector<String8> plugInPathList = mPlugInManager.getPlugInIdList();
+ for (unsigned int i = 0; i < plugInPathList.size(); ++i) {
+ String8 plugInPath = plugInPathList[i];
+ DrmSupportInfo* info = mPlugInManager.getPlugIn(plugInPath).getSupportInfo(0);
+ if (NULL != info) {
+ if (mSupportInfoToPlugInIdMap.indexOfKey(*info) < 0) {
mSupportInfoToPlugInIdMap.add(*info, plugInPath);
- delete info;
}
+ delete info;
}
}
return DRM_NO_ERROR;
diff --git a/include/camera/CameraParameters.h b/include/camera/CameraParameters.h
index 4a4bcfb..a520a6a 100644
--- a/include/camera/CameraParameters.h
+++ b/include/camera/CameraParameters.h
@@ -317,18 +317,13 @@
// recalculate exposure values). Changing exposure compensation
// settings will still affect the exposure settings while
// auto-exposure is locked. Stopping preview or taking a still
- // image will release the lock. However, the lock can be
- // re-enabled prior to preview being re-started, to keep the
- // exposure values from the previous lock. In conjunction with
+ // image will not change the lock. In conjunction with
// exposure compensation, this allows for capturing multi-exposure
// brackets with known relative exposure values. Locking
// auto-exposure after open but before the first call to
// startPreview may result in severely over- or under-exposed
- // images. The driver may independently enable the AE lock after
- // auto-focus completes. If it does so, this key must have its
- // value updated to reflect the lock's existence. Applications are
- // free to release such a lock, to re-enable AE without restarting
- // preview.
+ // images. The driver will not change the AE lock after
+ // auto-focus completes.
static const char KEY_AUTO_EXPOSURE_LOCK[];
// Whether locking the auto-exposure is supported. "true" means it is, and
// "false" or this key not existing means it is not supported.
@@ -339,18 +334,13 @@
// change white balance values. If auto-white balance is already
// locked, setting this to true again has no effect (the driver
// will not recalculate white balance values). Stopping preview or
- // taking a still image will release the lock. However, the lock
- // can be re-enabled prior to preview being re-started, to keep
- // the white balance values from the previous lock. In conjunction
+ // taking a still image will not change the lock. In conjunction
// with exposure compensation, this allows for capturing
// multi-exposure brackets with fixed white balance. Locking
// auto-white balance after open but before the first call to
// startPreview may result in severely incorrect color. The
- // driver may independently enable the AWB lock after auto-focus
- // completes. If it does so, this key must have its value updated
- // to reflect the lock's existence. Applications are free to
- // release such a lock, to re-enable AWB without restarting
- // preview.
+ // driver will not change the AWB lock after auto-focus
+ // completes.
static const char KEY_AUTO_WHITEBALANCE_LOCK[];
// Whether locking the auto-white balance is supported. "true"
// means it is, and "false" or this key not existing means it is
diff --git a/include/media/MediaProfiles.h b/include/media/MediaProfiles.h
index 4b023d1..eab7648 100644
--- a/include/media/MediaProfiles.h
+++ b/include/media/MediaProfiles.h
@@ -32,7 +32,8 @@
CAMCORDER_QUALITY_480P = 4,
CAMCORDER_QUALITY_720P = 5,
CAMCORDER_QUALITY_1080P = 6,
- CAMCORDER_QUALITY_LIST_END = 6,
+ CAMCORDER_QUALITY_QVGA = 7,
+ CAMCORDER_QUALITY_LIST_END = 7,
CAMCORDER_QUALITY_TIME_LAPSE_LIST_START = 1000,
CAMCORDER_QUALITY_TIME_LAPSE_LOW = 1000,
@@ -42,7 +43,8 @@
CAMCORDER_QUALITY_TIME_LAPSE_480P = 1004,
CAMCORDER_QUALITY_TIME_LAPSE_720P = 1005,
CAMCORDER_QUALITY_TIME_LAPSE_1080P = 1006,
- CAMCORDER_QUALITY_TIME_LAPSE_LIST_END = 1006,
+ CAMCORDER_QUALITY_TIME_LAPSE_QVGA = 1007,
+ CAMCORDER_QUALITY_TIME_LAPSE_LIST_END = 1007,
};
/**
diff --git a/media/libmedia/MediaProfiles.cpp b/media/libmedia/MediaProfiles.cpp
index 5a8bc60..ad55ff8 100644
--- a/media/libmedia/MediaProfiles.cpp
+++ b/media/libmedia/MediaProfiles.cpp
@@ -67,6 +67,7 @@
{"480p", CAMCORDER_QUALITY_480P},
{"720p", CAMCORDER_QUALITY_720P},
{"1080p", CAMCORDER_QUALITY_1080P},
+ {"qvga", CAMCORDER_QUALITY_QVGA},
{"timelapselow", CAMCORDER_QUALITY_TIME_LAPSE_LOW},
{"timelapsehigh", CAMCORDER_QUALITY_TIME_LAPSE_HIGH},
@@ -74,7 +75,8 @@
{"timelapsecif", CAMCORDER_QUALITY_TIME_LAPSE_CIF},
{"timelapse480p", CAMCORDER_QUALITY_TIME_LAPSE_480P},
{"timelapse720p", CAMCORDER_QUALITY_TIME_LAPSE_720P},
- {"timelapse1080p", CAMCORDER_QUALITY_TIME_LAPSE_1080P}
+ {"timelapse1080p", CAMCORDER_QUALITY_TIME_LAPSE_1080P},
+ {"timelapseqvga", CAMCORDER_QUALITY_TIME_LAPSE_QVGA},
};
/*static*/ void
@@ -1139,7 +1141,7 @@
if (index >= 0) {
offsetTimeMs = mStartTimeOffsets.valueFor(cameraId);
}
- LOGV("%s: offsetTime=%d ms and cameraId=%d", offsetTimeMs, cameraId);
+ LOGV("offsetTime=%d ms and cameraId=%d", offsetTimeMs, cameraId);
return offsetTimeMs;
}
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerStreamListener.h b/media/libmediaplayerservice/nuplayer/NuPlayerStreamListener.h
index df0935d..1874d80 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerStreamListener.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerStreamListener.h
@@ -41,8 +41,8 @@
private:
enum {
- kNumBuffers = 16,
- kBufferSize = 188 * 20
+ kNumBuffers = 8,
+ kBufferSize = 188 * 10
};
struct QueueEntry {
diff --git a/media/libstagefright/AVIExtractor.cpp b/media/libstagefright/AVIExtractor.cpp
index 4e46414..d47e5d1 100644
--- a/media/libstagefright/AVIExtractor.cpp
+++ b/media/libstagefright/AVIExtractor.cpp
@@ -18,6 +18,7 @@
#define LOG_TAG "AVIExtractor"
#include <utils/Log.h>
+#include "include/avc_utils.h"
#include "include/AVIExtractor.h"
#include <binder/ProcessState.h>
@@ -362,6 +363,13 @@
case FOURCC('X', 'V', 'I', 'X'):
return MEDIA_MIMETYPE_VIDEO_MPEG4;
+ // from http://wiki.multimedia.cx/index.php?title=H264
+ case FOURCC('a', 'v', 'c', '1'):
+ case FOURCC('d', 'a', 'v', 'c'):
+ case FOURCC('x', '2', '6', '4'):
+ case FOURCC('v', 's', 's', 'h'):
+ return MEDIA_MIMETYPE_VIDEO_AVC;
+
default:
return NULL;
}
@@ -406,6 +414,14 @@
return ERROR_MALFORMED;
}
+ if (mime == NULL) {
+ LOGW("Unsupported video format '%c%c%c%c'",
+ (char)(handler >> 24),
+ (char)((handler >> 16) & 0xff),
+ (char)((handler >> 8) & 0xff),
+ (char)(handler & 0xff));
+ }
+
kind = Track::VIDEO;
} else if (type == FOURCC('a', 'u', 'd', 's')) {
if (mime && strncasecmp(mime, "audio/", 6)) {
@@ -473,8 +489,11 @@
track->mMeta->setInt32(kKeyHeight, height);
} else {
uint32_t format = U16LE_AT(data);
+
if (format == 0x55) {
track->mMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG);
+ } else {
+ LOGW("Unsupported audio format = 0x%04x", format);
}
uint32_t numChannels = U16LE_AT(&data[2]);
@@ -646,21 +665,26 @@
AString mime = tmp;
- if (!strncasecmp("video/", mime.c_str(), 6)
- && track->mThumbnailSampleIndex >= 0) {
- int64_t thumbnailTimeUs;
- CHECK_EQ((status_t)OK,
- getSampleTime(i, track->mThumbnailSampleIndex,
- &thumbnailTimeUs));
+ if (!strncasecmp("video/", mime.c_str(), 6)) {
+ if (track->mThumbnailSampleIndex >= 0) {
+ int64_t thumbnailTimeUs;
+ CHECK_EQ((status_t)OK,
+ getSampleTime(i, track->mThumbnailSampleIndex,
+ &thumbnailTimeUs));
- track->mMeta->setInt64(kKeyThumbnailTime, thumbnailTimeUs);
+ track->mMeta->setInt64(kKeyThumbnailTime, thumbnailTimeUs);
+ }
+
+ status_t err = OK;
if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_VIDEO_MPEG4)) {
- status_t err = addMPEG4CodecSpecificData(i);
+ err = addMPEG4CodecSpecificData(i);
+ } else if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_VIDEO_AVC)) {
+ err = addH264CodecSpecificData(i);
+ }
- if (err != OK) {
- return err;
- }
+ if (err != OK) {
+ return err;
}
}
@@ -781,6 +805,63 @@
return OK;
}
+status_t AVIExtractor::addH264CodecSpecificData(size_t trackIndex) {
+ Track *track = &mTracks.editItemAt(trackIndex);
+
+ off64_t offset;
+ size_t size;
+ bool isKey;
+ int64_t timeUs;
+
+ // Extract codec specific data from the first non-empty sample.
+
+ size_t sampleIndex = 0;
+ for (;;) {
+ status_t err =
+ getSampleInfo(
+ trackIndex, sampleIndex, &offset, &size, &isKey, &timeUs);
+
+ if (err != OK) {
+ return err;
+ }
+
+ if (size > 0) {
+ break;
+ }
+
+ ++sampleIndex;
+ }
+
+ sp<ABuffer> buffer = new ABuffer(size);
+ ssize_t n = mDataSource->readAt(offset, buffer->data(), buffer->size());
+
+ if (n < (ssize_t)size) {
+ return n < 0 ? (status_t)n : ERROR_MALFORMED;
+ }
+
+ sp<MetaData> meta = MakeAVCCodecSpecificData(buffer);
+
+ if (meta == NULL) {
+ LOGE("Unable to extract AVC codec specific data");
+ return ERROR_MALFORMED;
+ }
+
+ int32_t width, height;
+ CHECK(meta->findInt32(kKeyWidth, &width));
+ CHECK(meta->findInt32(kKeyHeight, &height));
+
+ uint32_t type;
+ const void *csd;
+ size_t csdSize;
+ CHECK(meta->findData(kKeyAVCC, &type, &csd, &csdSize));
+
+ track->mMeta->setInt32(kKeyWidth, width);
+ track->mMeta->setInt32(kKeyHeight, width);
+ track->mMeta->setData(kKeyAVCC, type, csd, csdSize);
+
+ return OK;
+}
+
status_t AVIExtractor::getSampleInfo(
size_t trackIndex, size_t sampleIndex,
off64_t *offset, size_t *size, bool *isKey,
diff --git a/media/libstagefright/SurfaceMediaSource.cpp b/media/libstagefright/SurfaceMediaSource.cpp
index 306f1f6..2b27ee2 100644
--- a/media/libstagefright/SurfaceMediaSource.cpp
+++ b/media/libstagefright/SurfaceMediaSource.cpp
@@ -764,8 +764,8 @@
// If the loop was exited as a result of stopping the recording,
// it is OK
if (mStopped) {
- LOGV("Read: SurfaceMediaSource is stopped. Returning NO_INIT;");
- return NO_INIT;
+ LOGV("Read: SurfaceMediaSource is stopped. Returning ERROR_END_OF_STREAM.");
+ return ERROR_END_OF_STREAM;
}
// Update the current buffer info
diff --git a/media/libstagefright/avc_utils.cpp b/media/libstagefright/avc_utils.cpp
index 07aa140..153ee33 100644
--- a/media/libstagefright/avc_utils.cpp
+++ b/media/libstagefright/avc_utils.cpp
@@ -297,7 +297,7 @@
sp<MetaData> meta = new MetaData;
meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC);
- meta->setData(kKeyAVCC, 0, csd->data(), csd->size());
+ meta->setData(kKeyAVCC, kTypeAVCC, csd->data(), csd->size());
meta->setInt32(kKeyWidth, width);
meta->setInt32(kKeyHeight, height);
diff --git a/media/libstagefright/include/AVIExtractor.h b/media/libstagefright/include/AVIExtractor.h
index b575347..75ce68d 100644
--- a/media/libstagefright/include/AVIExtractor.h
+++ b/media/libstagefright/include/AVIExtractor.h
@@ -101,6 +101,7 @@
size_t *sampleIndex) const;
status_t addMPEG4CodecSpecificData(size_t trackIndex);
+ status_t addH264CodecSpecificData(size_t trackIndex);
static bool IsCorrectChunkType(
ssize_t trackIndex, Track::Kind kind, uint32_t chunkType);