Merge "Eliminate single-process mode. Bug: 5010576"
diff --git a/include/media/stagefright/CameraSource.h b/include/media/stagefright/CameraSource.h
index 80b7c1c..8c1c593 100644
--- a/include/media/stagefright/CameraSource.h
+++ b/include/media/stagefright/CameraSource.h
@@ -197,6 +197,12 @@
status_t init(const sp<ICamera>& camera, const sp<ICameraRecordingProxy>& proxy,
int32_t cameraId, Size videoSize, int32_t frameRate,
bool storeMetaDataInVideoBuffers);
+
+ status_t initWithCameraAccess(
+ const sp<ICamera>& camera, const sp<ICameraRecordingProxy>& proxy,
+ int32_t cameraId, Size videoSize, int32_t frameRate,
+ bool storeMetaDataInVideoBuffers);
+
status_t isCameraAvailable(const sp<ICamera>& camera,
const sp<ICameraRecordingProxy>& proxy,
int32_t cameraId);
diff --git a/include/media/stagefright/MPEG4Writer.h b/include/media/stagefright/MPEG4Writer.h
index 904ce2a..77166ed 100644
--- a/include/media/stagefright/MPEG4Writer.h
+++ b/include/media/stagefright/MPEG4Writer.h
@@ -71,7 +71,8 @@
bool mUse32BitOffset;
bool mIsFileSizeLimitExplicitlyRequested;
bool mPaused;
- bool mStarted;
+ bool mStarted; // Writer thread + track threads started successfully
+ bool mWriterThreadStarted; // Only writer thread started successfully
off64_t mOffset;
off_t mMdatOffset;
uint8_t *mMoovBoxBuffer;
@@ -182,6 +183,7 @@
void writeLatitude(int degreex10000);
void writeLongitude(int degreex10000);
void sendSessionSummary();
+ void release();
MPEG4Writer(const MPEG4Writer &);
MPEG4Writer &operator=(const MPEG4Writer &);
diff --git a/media/libstagefright/CameraSource.cpp b/media/libstagefright/CameraSource.cpp
index ed8149a..c7e7ced 100644
--- a/media/libstagefright/CameraSource.cpp
+++ b/media/libstagefright/CameraSource.cpp
@@ -158,12 +158,10 @@
mVideoSize.width = -1;
mVideoSize.height = -1;
- int64_t token = IPCThreadState::self()->clearCallingIdentity();
mInitCheck = init(camera, proxy, cameraId,
videoSize, frameRate,
storeMetaDataInVideoBuffers);
if (mInitCheck != OK) releaseCamera();
- IPCThreadState::self()->restoreCallingIdentity(token);
}
status_t CameraSource::initCheck() const {
@@ -463,6 +461,22 @@
bool storeMetaDataInVideoBuffers) {
status_t err = OK;
+ int64_t token = IPCThreadState::self()->clearCallingIdentity();
+ err = initWithCameraAccess(camera, proxy, cameraId,
+ videoSize, frameRate,
+ storeMetaDataInVideoBuffers);
+ IPCThreadState::self()->restoreCallingIdentity(token);
+ return err;
+}
+
+status_t CameraSource::initWithCameraAccess(
+ const sp<ICamera>& camera,
+ const sp<ICameraRecordingProxy>& proxy,
+ int32_t cameraId,
+ Size videoSize,
+ int32_t frameRate,
+ bool storeMetaDataInVideoBuffers) {
+ status_t err = OK;
if ((err = isCameraAvailable(camera, proxy, cameraId)) != OK) {
LOGE("Camera connection could not be established.");
@@ -525,6 +539,11 @@
CameraSource::~CameraSource() {
if (mStarted) {
stop();
+ } else if (mInitCheck == OK) {
+ // Camera is initialized but because start() is never called,
+ // the lock on Camera is never released(). This makes sure
+ // Camera's lock is released in this case.
+ releaseCamera();
}
}
@@ -571,6 +590,7 @@
void CameraSource::releaseCamera() {
LOGV("releaseCamera");
if (mCamera != 0) {
+ int64_t token = IPCThreadState::self()->clearCallingIdentity();
if ((mCameraFlags & FLAGS_HOT_CAMERA) == 0) {
LOGV("Camera was cold when we started, stopping preview");
mCamera->stopPreview();
@@ -580,6 +600,7 @@
mCamera->unlock();
}
mCamera.clear();
+ IPCThreadState::self()->restoreCallingIdentity(token);
}
if (mCameraRecordingProxy != 0) {
mCameraRecordingProxy->asBinder()->unlinkToDeath(mDeathNotifier);
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
index f075699..eaad2c3 100644
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
@@ -246,6 +246,7 @@
mIsFileSizeLimitExplicitlyRequested(false),
mPaused(false),
mStarted(false),
+ mWriterThreadStarted(false),
mOffset(0),
mMdatOffset(0),
mEstimatedMoovBoxSize(0),
@@ -269,6 +270,7 @@
mIsFileSizeLimitExplicitlyRequested(false),
mPaused(false),
mStarted(false),
+ mWriterThreadStarted(false),
mOffset(0),
mMdatOffset(0),
mEstimatedMoovBoxSize(0),
@@ -538,6 +540,9 @@
void MPEG4Writer::stopWriterThread() {
LOGD("Stopping writer thread");
+ if (!mWriterThreadStarted) {
+ return;
+ }
{
Mutex::Autolock autolock(mLock);
@@ -548,6 +553,7 @@
void *dummy;
pthread_join(mThread, &dummy);
+ mWriterThreadStarted = false;
LOGD("Writer thread stopped");
}
@@ -603,10 +609,25 @@
writeInt32(0x40000000); // w
}
+void MPEG4Writer::release() {
+ close(mFd);
+ mFd = -1;
+ mInitCheck = NO_INIT;
+ mStarted = false;
+}
status_t MPEG4Writer::stop() {
if (mInitCheck != OK) {
return OK;
+ } else {
+ if (!mWriterThreadStarted ||
+ !mStarted) {
+ if (mWriterThreadStarted) {
+ stopWriterThread();
+ }
+ release();
+ return OK;
+ }
}
status_t err = OK;
@@ -637,10 +658,7 @@
// Do not write out movie header on error.
if (err != OK) {
- close(mFd);
- mFd = -1;
- mInitCheck = NO_INIT;
- mStarted = false;
+ release();
return err;
}
@@ -688,11 +706,7 @@
CHECK(mBoxes.empty());
- close(mFd);
- mFd = -1;
- mInitCheck = NO_INIT;
- mStarted = false;
-
+ release();
return err;
}
@@ -1415,6 +1429,7 @@
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
pthread_create(&mThread, &attr, ThreadWrapper, this);
pthread_attr_destroy(&attr);
+ mWriterThreadStarted = true;
return OK;
}
diff --git a/media/mtp/MtpServer.cpp b/media/mtp/MtpServer.cpp
index bc04e8c..9085f10 100644
--- a/media/mtp/MtpServer.cpp
+++ b/media/mtp/MtpServer.cpp
@@ -871,6 +871,14 @@
// check space first
if (mSendObjectFileSize > storage->getFreeSpace())
return MTP_RESPONSE_STORAGE_FULL;
+ uint64_t maxFileSize = storage->getMaxFileSize();
+ // check storage max file size
+ if (maxFileSize != 0) {
+ // if mSendObjectFileSize is 0xFFFFFFFF, then all we know is the file size
+ // is >= 0xFFFFFFFF
+ if (mSendObjectFileSize > maxFileSize || mSendObjectFileSize == 0xFFFFFFFF)
+ return MTP_RESPONSE_OBJECT_TOO_LARGE;
+ }
LOGD("path: %s parent: %d storageID: %08X", (const char*)path, parent, storageID);
MtpObjectHandle handle = mDatabase->beginSendObject((const char*)path,
diff --git a/media/mtp/MtpStorage.cpp b/media/mtp/MtpStorage.cpp
index fef8066..941e303 100644
--- a/media/mtp/MtpStorage.cpp
+++ b/media/mtp/MtpStorage.cpp
@@ -33,11 +33,13 @@
namespace android {
MtpStorage::MtpStorage(MtpStorageID id, const char* filePath,
- const char* description, uint64_t reserveSpace, bool removable)
+ const char* description, uint64_t reserveSpace,
+ bool removable, uint64_t maxFileSize)
: mStorageID(id),
mFilePath(filePath),
mDescription(description),
mMaxCapacity(0),
+ mMaxFileSize(maxFileSize),
mReserveSpace(reserveSpace),
mRemovable(removable)
{
diff --git a/media/mtp/MtpStorage.h b/media/mtp/MtpStorage.h
index 3e4f40d..e5a2e57 100644
--- a/media/mtp/MtpStorage.h
+++ b/media/mtp/MtpStorage.h
@@ -31,6 +31,7 @@
MtpString mFilePath;
MtpString mDescription;
uint64_t mMaxCapacity;
+ uint64_t mMaxFileSize;
// amount of free space to leave unallocated
uint64_t mReserveSpace;
bool mRemovable;
@@ -38,7 +39,7 @@
public:
MtpStorage(MtpStorageID id, const char* filePath,
const char* description, uint64_t reserveSpace,
- bool removable);
+ bool removable, uint64_t maxFileSize);
virtual ~MtpStorage();
inline MtpStorageID getStorageID() const { return mStorageID; }
@@ -50,6 +51,7 @@
const char* getDescription() const;
inline const char* getPath() const { return (const char *)mFilePath; }
inline bool isRemovable() const { return mRemovable; }
+ inline uint64_t getMaxFileSize() const { return mMaxFileSize; }
};
}; // namespace android