Merge "Avoid copying for input recording frames in CameraSource" into kraken
This commit is contained in:
@@ -19,7 +19,6 @@
|
|||||||
#define CAMERA_SOURCE_H_
|
#define CAMERA_SOURCE_H_
|
||||||
|
|
||||||
#include <media/stagefright/MediaBuffer.h>
|
#include <media/stagefright/MediaBuffer.h>
|
||||||
#include <media/stagefright/MediaBufferGroup.h>
|
|
||||||
#include <media/stagefright/MediaSource.h>
|
#include <media/stagefright/MediaSource.h>
|
||||||
#include <utils/List.h>
|
#include <utils/List.h>
|
||||||
#include <utils/RefBase.h>
|
#include <utils/RefBase.h>
|
||||||
@@ -31,7 +30,7 @@ class ICamera;
|
|||||||
class IMemory;
|
class IMemory;
|
||||||
class Camera;
|
class Camera;
|
||||||
|
|
||||||
class CameraSource : public MediaSource {
|
class CameraSource : public MediaSource, public MediaBufferObserver {
|
||||||
public:
|
public:
|
||||||
static CameraSource *Create();
|
static CameraSource *Create();
|
||||||
static CameraSource *CreateFromCamera(const sp<Camera> &camera);
|
static CameraSource *CreateFromCamera(const sp<Camera> &camera);
|
||||||
@@ -46,6 +45,8 @@ public:
|
|||||||
virtual status_t read(
|
virtual status_t read(
|
||||||
MediaBuffer **buffer, const ReadOptions *options = NULL);
|
MediaBuffer **buffer, const ReadOptions *options = NULL);
|
||||||
|
|
||||||
|
virtual void signalBufferReturned(MediaBuffer* buffer);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class CameraSourceListener;
|
friend class CameraSourceListener;
|
||||||
|
|
||||||
@@ -53,7 +54,9 @@ private:
|
|||||||
|
|
||||||
Mutex mLock;
|
Mutex mLock;
|
||||||
Condition mFrameAvailableCondition;
|
Condition mFrameAvailableCondition;
|
||||||
List<sp<IMemory> > mFrames;
|
Condition mFrameCompleteCondition;
|
||||||
|
List<sp<IMemory> > mFramesReceived;
|
||||||
|
List<sp<IMemory> > mFramesBeingEncoded;
|
||||||
List<int64_t> mFrameTimes;
|
List<int64_t> mFrameTimes;
|
||||||
|
|
||||||
int mWidth, mHeight;
|
int mWidth, mHeight;
|
||||||
@@ -62,7 +65,6 @@ private:
|
|||||||
int32_t mNumFramesReceived;
|
int32_t mNumFramesReceived;
|
||||||
int32_t mNumFramesEncoded;
|
int32_t mNumFramesEncoded;
|
||||||
int32_t mNumFramesDropped;
|
int32_t mNumFramesDropped;
|
||||||
MediaBufferGroup *mBufferGroup;
|
|
||||||
bool mStarted;
|
bool mStarted;
|
||||||
|
|
||||||
CameraSource(const sp<Camera> &camera);
|
CameraSource(const sp<Camera> &camera);
|
||||||
|
|||||||
@@ -104,7 +104,6 @@ CameraSource::CameraSource(const sp<Camera> &camera)
|
|||||||
mNumFramesReceived(0),
|
mNumFramesReceived(0),
|
||||||
mNumFramesEncoded(0),
|
mNumFramesEncoded(0),
|
||||||
mNumFramesDropped(0),
|
mNumFramesDropped(0),
|
||||||
mBufferGroup(NULL),
|
|
||||||
mStarted(false) {
|
mStarted(false) {
|
||||||
String8 s = mCamera->getParameters();
|
String8 s = mCamera->getParameters();
|
||||||
printf("params: \"%s\"\n", s.string());
|
printf("params: \"%s\"\n", s.string());
|
||||||
@@ -139,8 +138,12 @@ status_t CameraSource::stop() {
|
|||||||
mCamera->stopRecording();
|
mCamera->stopRecording();
|
||||||
|
|
||||||
releaseQueuedFrames();
|
releaseQueuedFrames();
|
||||||
delete mBufferGroup;
|
|
||||||
mBufferGroup = NULL;
|
while (!mFramesBeingEncoded.empty()) {
|
||||||
|
LOGI("Number of outstanding frames is being encoded: %d", mFramesBeingEncoded.size());
|
||||||
|
mFrameCompleteCondition.wait(mLock);
|
||||||
|
}
|
||||||
|
|
||||||
LOGI("Frames received/encoded/dropped: %d/%d/%d, timestamp (us) last/first: %lld/%lld",
|
LOGI("Frames received/encoded/dropped: %d/%d/%d, timestamp (us) last/first: %lld/%lld",
|
||||||
mNumFramesReceived, mNumFramesEncoded, mNumFramesDropped,
|
mNumFramesReceived, mNumFramesEncoded, mNumFramesDropped,
|
||||||
mLastFrameTimestampUs, mFirstFrameTimeUs);
|
mLastFrameTimestampUs, mFirstFrameTimeUs);
|
||||||
@@ -151,10 +154,10 @@ status_t CameraSource::stop() {
|
|||||||
|
|
||||||
void CameraSource::releaseQueuedFrames() {
|
void CameraSource::releaseQueuedFrames() {
|
||||||
List<sp<IMemory> >::iterator it;
|
List<sp<IMemory> >::iterator it;
|
||||||
while (!mFrames.empty()) {
|
while (!mFramesReceived.empty()) {
|
||||||
it = mFrames.begin();
|
it = mFramesReceived.begin();
|
||||||
mCamera->releaseRecordingFrame(*it);
|
mCamera->releaseRecordingFrame(*it);
|
||||||
mFrames.erase(it);
|
mFramesReceived.erase(it);
|
||||||
++mNumFramesDropped;
|
++mNumFramesDropped;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -169,6 +172,23 @@ sp<MetaData> CameraSource::getFormat() {
|
|||||||
return meta;
|
return meta;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CameraSource::signalBufferReturned(MediaBuffer *buffer) {
|
||||||
|
LOGV("signalBufferReturned: %p", buffer->data());
|
||||||
|
for (List<sp<IMemory> >::iterator it = mFramesBeingEncoded.begin();
|
||||||
|
it != mFramesBeingEncoded.end(); ++it) {
|
||||||
|
if ((*it)->pointer() == buffer->data()) {
|
||||||
|
mCamera->releaseRecordingFrame((*it));
|
||||||
|
mFramesBeingEncoded.erase(it);
|
||||||
|
++mNumFramesEncoded;
|
||||||
|
buffer->setObserver(0);
|
||||||
|
buffer->release();
|
||||||
|
mFrameCompleteCondition.signal();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CHECK_EQ(0, "signalBufferReturned: bogus buffer");
|
||||||
|
}
|
||||||
|
|
||||||
status_t CameraSource::read(
|
status_t CameraSource::read(
|
||||||
MediaBuffer **buffer, const ReadOptions *options) {
|
MediaBuffer **buffer, const ReadOptions *options) {
|
||||||
LOGV("read");
|
LOGV("read");
|
||||||
@@ -185,33 +205,24 @@ status_t CameraSource::read(
|
|||||||
|
|
||||||
{
|
{
|
||||||
Mutex::Autolock autoLock(mLock);
|
Mutex::Autolock autoLock(mLock);
|
||||||
while (mStarted && mFrames.empty()) {
|
while (mStarted && mFramesReceived.empty()) {
|
||||||
mFrameAvailableCondition.wait(mLock);
|
mFrameAvailableCondition.wait(mLock);
|
||||||
}
|
}
|
||||||
if (!mStarted) {
|
if (!mStarted) {
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
frame = *mFrames.begin();
|
frame = *mFramesReceived.begin();
|
||||||
mFrames.erase(mFrames.begin());
|
mFramesReceived.erase(mFramesReceived.begin());
|
||||||
|
|
||||||
frameTime = *mFrameTimes.begin();
|
frameTime = *mFrameTimes.begin();
|
||||||
mFrameTimes.erase(mFrameTimes.begin());
|
mFrameTimes.erase(mFrameTimes.begin());
|
||||||
++mNumFramesEncoded;
|
|
||||||
|
mFramesBeingEncoded.push_back(frame);
|
||||||
|
*buffer = new MediaBuffer(frame->pointer(), frame->size());
|
||||||
|
(*buffer)->setObserver(this);
|
||||||
|
(*buffer)->add_ref();
|
||||||
|
(*buffer)->meta_data()->setInt64(kKeyTime, frameTime);
|
||||||
}
|
}
|
||||||
if (mBufferGroup == NULL) {
|
|
||||||
mBufferGroup = new MediaBufferGroup();
|
|
||||||
CHECK(mBufferGroup != NULL);
|
|
||||||
mBufferGroup->add_buffer(new MediaBuffer(frame->size()));
|
|
||||||
}
|
|
||||||
|
|
||||||
mBufferGroup->acquire_buffer(buffer);
|
|
||||||
memcpy((*buffer)->data(), frame->pointer(), frame->size());
|
|
||||||
(*buffer)->set_range(0, frame->size());
|
|
||||||
mCamera->releaseRecordingFrame(frame);
|
|
||||||
|
|
||||||
(*buffer)->meta_data()->clear();
|
|
||||||
(*buffer)->meta_data()->setInt64(kKeyTime, frameTime);
|
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -232,7 +243,7 @@ void CameraSource::dataCallbackTimestamp(int64_t timestampUs,
|
|||||||
}
|
}
|
||||||
++mNumFramesReceived;
|
++mNumFramesReceived;
|
||||||
|
|
||||||
mFrames.push_back(data);
|
mFramesReceived.push_back(data);
|
||||||
mFrameTimes.push_back(timestampUs - mFirstFrameTimeUs);
|
mFrameTimes.push_back(timestampUs - mFirstFrameTimeUs);
|
||||||
mFrameAvailableCondition.signal();
|
mFrameAvailableCondition.signal();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user