summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/media/IMediaRecorder.h2
-rw-r--r--include/media/MediaRecorderBase.h2
-rw-r--r--include/media/mediarecorder.h2
-rw-r--r--include/media/stagefright/MediaCodecSource.h4
-rw-r--r--media/libmedia/IMediaRecorder.cpp19
-rw-r--r--media/libmedia/mediarecorder.cpp19
-rw-r--r--media/libmediaplayerservice/MediaRecorderClient.cpp10
-rw-r--r--media/libmediaplayerservice/MediaRecorderClient.h1
-rw-r--r--media/libmediaplayerservice/StagefrightRecorder.cpp11
-rw-r--r--media/libmediaplayerservice/StagefrightRecorder.h3
-rw-r--r--media/libstagefright/MediaCodecSource.cpp21
11 files changed, 88 insertions, 6 deletions
diff --git a/include/media/IMediaRecorder.h b/include/media/IMediaRecorder.h
index 509c06b..47de0ca 100644
--- a/include/media/IMediaRecorder.h
+++ b/include/media/IMediaRecorder.h
@@ -26,6 +26,7 @@ class Surface;
class ICamera;
class ICameraRecordingProxy;
class IMediaRecorderClient;
+class IGraphicBufferConsumer;
class IGraphicBufferProducer;
class IMediaRecorder: public IInterface
@@ -55,6 +56,7 @@ public:
virtual status_t init() = 0;
virtual status_t close() = 0;
virtual status_t release() = 0;
+ virtual status_t usePersistentSurface(const sp<IGraphicBufferConsumer>& surface) = 0;
virtual sp<IGraphicBufferProducer> querySurfaceMediaSource() = 0;
};
diff --git a/include/media/MediaRecorderBase.h b/include/media/MediaRecorderBase.h
index f9feede..9947309 100644
--- a/include/media/MediaRecorderBase.h
+++ b/include/media/MediaRecorderBase.h
@@ -26,6 +26,7 @@ namespace android {
class ICameraRecordingProxy;
class Surface;
+class IGraphicBufferConsumer;
class IGraphicBufferProducer;
struct MediaRecorderBase {
@@ -56,6 +57,7 @@ struct MediaRecorderBase {
virtual status_t reset() = 0;
virtual status_t getMaxAmplitude(int *max) = 0;
virtual status_t dump(int fd, const Vector<String16>& args) const = 0;
+ virtual status_t usePersistentSurface(const sp<IGraphicBufferConsumer>& surface) = 0;
virtual sp<IGraphicBufferProducer> querySurfaceMediaSource() const = 0;
diff --git a/include/media/mediarecorder.h b/include/media/mediarecorder.h
index 8e40c5d..9210feb 100644
--- a/include/media/mediarecorder.h
+++ b/include/media/mediarecorder.h
@@ -32,6 +32,7 @@ class IMediaRecorder;
class ICamera;
class ICameraRecordingProxy;
class IGraphicBufferProducer;
+struct PersistentSurface;
class Surface;
typedef void (*media_completion_f)(status_t status, void *cookie);
@@ -236,6 +237,7 @@ public:
status_t close();
status_t release();
void notify(int msg, int ext1, int ext2);
+ status_t usePersistentSurface(const sp<PersistentSurface>& surface);
sp<IGraphicBufferProducer> querySurfaceMediaSourceFromMediaServer();
private:
diff --git a/include/media/stagefright/MediaCodecSource.h b/include/media/stagefright/MediaCodecSource.h
index 9d1f222..a991b02 100644
--- a/include/media/stagefright/MediaCodecSource.h
+++ b/include/media/stagefright/MediaCodecSource.h
@@ -27,6 +27,7 @@ struct ALooper;
class AMessage;
struct AReplyToken;
class IGraphicBufferProducer;
+class IGraphicBufferConsumer;
class MediaCodec;
class MetaData;
@@ -41,6 +42,7 @@ struct MediaCodecSource : public MediaSource,
const sp<ALooper> &looper,
const sp<AMessage> &format,
const sp<MediaSource> &source,
+ const sp<IGraphicBufferConsumer> &consumer = NULL,
uint32_t flags = 0);
bool isVideo() const { return mIsVideo; }
@@ -79,6 +81,7 @@ private:
const sp<ALooper> &looper,
const sp<AMessage> &outputFormat,
const sp<MediaSource> &source,
+ const sp<IGraphicBufferConsumer> &consumer,
uint32_t flags = 0);
status_t onStart(MetaData *params);
@@ -107,6 +110,7 @@ private:
bool mDoMoreWorkPending;
sp<AMessage> mEncoderActivityNotify;
sp<IGraphicBufferProducer> mGraphicBufferProducer;
+ sp<IGraphicBufferConsumer> mGraphicBufferConsumer;
List<MediaBuffer *> mInputBufferQueue;
List<size_t> mAvailEncoderInputIndices;
List<int64_t> mDecodingTimeQueue; // decoding time (us) for video
diff --git a/media/libmedia/IMediaRecorder.cpp b/media/libmedia/IMediaRecorder.cpp
index 8ca256c..c7a1394 100644
--- a/media/libmedia/IMediaRecorder.cpp
+++ b/media/libmedia/IMediaRecorder.cpp
@@ -35,6 +35,7 @@ enum {
RELEASE = IBinder::FIRST_CALL_TRANSACTION,
INIT,
CLOSE,
+ USE_PERSISTENT_SURFACE,
QUERY_SURFACE_MEDIASOURCE,
RESET,
STOP,
@@ -75,6 +76,16 @@ public:
return reply.readInt32();
}
+ status_t usePersistentSurface(const sp<IGraphicBufferConsumer>& surface)
+ {
+ ALOGV("usePersistentSurface(%p)", surface.get());
+ Parcel data, reply;
+ data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
+ data.writeStrongBinder(IInterface::asBinder(surface));
+ remote()->transact(USE_PERSISTENT_SURFACE, data, &reply);
+ return reply.readInt32();
+ }
+
sp<IGraphicBufferProducer> querySurfaceMediaSource()
{
ALOGV("Query SurfaceMediaSource");
@@ -442,6 +453,14 @@ status_t BnMediaRecorder::onTransact(
reply->writeInt32(setCamera(camera, proxy));
return NO_ERROR;
} break;
+ case USE_PERSISTENT_SURFACE: {
+ ALOGV("USE_PERSISTENT_SURFACE");
+ CHECK_INTERFACE(IMediaRecorder, data, reply);
+ sp<IGraphicBufferConsumer> surface = interface_cast<IGraphicBufferConsumer>(
+ data.readStrongBinder());
+ reply->writeInt32(usePersistentSurface(surface));
+ return NO_ERROR;
+ } break;
case QUERY_SURFACE_MEDIASOURCE: {
ALOGV("QUERY_SURFACE_MEDIASOURCE");
CHECK_INTERFACE(IMediaRecorder, data, reply);
diff --git a/media/libmedia/mediarecorder.cpp b/media/libmedia/mediarecorder.cpp
index 9470936..1f8b1d3 100644
--- a/media/libmedia/mediarecorder.cpp
+++ b/media/libmedia/mediarecorder.cpp
@@ -27,6 +27,7 @@
#include <media/IMediaPlayerService.h>
#include <media/IMediaRecorder.h>
#include <media/mediaplayer.h> // for MEDIA_ERROR_SERVER_DIED
+#include <media/stagefright/PersistentSurface.h>
#include <gui/IGraphicBufferProducer.h>
namespace android {
@@ -344,6 +345,24 @@ sp<IGraphicBufferProducer> MediaRecorder::
+status_t MediaRecorder::usePersistentSurface(const sp<PersistentSurface>& surface)
+{
+ ALOGV("usePersistentSurface");
+ if (mMediaRecorder == NULL) {
+ ALOGE("media recorder is not initialized yet");
+ return INVALID_OPERATION;
+ }
+ bool isInvalidState = (mCurrentState &
+ (MEDIA_RECORDER_PREPARED |
+ MEDIA_RECORDER_RECORDING));
+ if (isInvalidState) {
+ ALOGE("usePersistentSurface is called in an invalid state: %d", mCurrentState);
+ return INVALID_OPERATION;
+ }
+
+ return mMediaRecorder->usePersistentSurface(surface->getBufferConsumer());
+}
+
status_t MediaRecorder::setVideoFrameRate(int frames_per_second)
{
ALOGV("setVideoFrameRate(%d)", frames_per_second);
diff --git a/media/libmediaplayerservice/MediaRecorderClient.cpp b/media/libmediaplayerservice/MediaRecorderClient.cpp
index 40e9d1c..ed442e3 100644
--- a/media/libmediaplayerservice/MediaRecorderClient.cpp
+++ b/media/libmediaplayerservice/MediaRecorderClient.cpp
@@ -55,6 +55,16 @@ static bool checkPermission(const char* permissionString) {
return ok;
}
+status_t MediaRecorderClient::usePersistentSurface(const sp<IGraphicBufferConsumer>& surface)
+{
+ ALOGV("usePersistentSurface");
+ Mutex::Autolock lock(mLock);
+ if (mRecorder == NULL) {
+ ALOGE("recorder is not initialized");
+ return NO_INIT;
+ }
+ return mRecorder->usePersistentSurface(surface);
+}
sp<IGraphicBufferProducer> MediaRecorderClient::querySurfaceMediaSource()
{
diff --git a/media/libmediaplayerservice/MediaRecorderClient.h b/media/libmediaplayerservice/MediaRecorderClient.h
index e03ec3f..7ac88cb 100644
--- a/media/libmediaplayerservice/MediaRecorderClient.h
+++ b/media/libmediaplayerservice/MediaRecorderClient.h
@@ -55,6 +55,7 @@ public:
virtual status_t close();
virtual status_t release();
virtual status_t dump(int fd, const Vector<String16>& args);
+ virtual status_t usePersistentSurface(const sp<IGraphicBufferConsumer>& surface);
virtual sp<IGraphicBufferProducer> querySurfaceMediaSource();
private:
diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp
index aa19a25..509a592 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.cpp
+++ b/media/libmediaplayerservice/StagefrightRecorder.cpp
@@ -243,6 +243,13 @@ status_t StagefrightRecorder::setPreviewSurface(const sp<IGraphicBufferProducer>
return OK;
}
+status_t StagefrightRecorder::usePersistentSurface(
+ const sp<IGraphicBufferConsumer>& surface) {
+ mPersistentSurface = surface;
+
+ return OK;
+}
+
status_t StagefrightRecorder::setOutputFile(int fd, int64_t offset, int64_t length) {
ALOGV("setOutputFile: %d, %lld, %lld", fd, offset, length);
// These don't make any sense, do they?
@@ -1560,8 +1567,8 @@ status_t StagefrightRecorder::setupVideoEncoder(
flags |= MediaCodecSource::FLAG_USE_SURFACE_INPUT;
}
- sp<MediaCodecSource> encoder =
- MediaCodecSource::Create(mLooper, format, cameraSource, flags);
+ sp<MediaCodecSource> encoder = MediaCodecSource::Create(
+ mLooper, format, cameraSource, mPersistentSurface, flags);
if (encoder == NULL) {
ALOGE("Failed to create video encoder");
// When the encoder fails to be created, we need
diff --git a/media/libmediaplayerservice/StagefrightRecorder.h b/media/libmediaplayerservice/StagefrightRecorder.h
index 1425f59..1a7b720 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.h
+++ b/media/libmediaplayerservice/StagefrightRecorder.h
@@ -35,6 +35,7 @@ struct MediaWriter;
class MetaData;
struct AudioSource;
class MediaProfiles;
+class IGraphicBufferConsumer;
class IGraphicBufferProducer;
class SurfaceMediaSource;
struct ALooper;
@@ -53,6 +54,7 @@ struct StagefrightRecorder : public MediaRecorderBase {
virtual status_t setVideoFrameRate(int frames_per_second);
virtual status_t setCamera(const sp<ICamera>& camera, const sp<ICameraRecordingProxy>& proxy);
virtual status_t setPreviewSurface(const sp<IGraphicBufferProducer>& surface);
+ virtual status_t usePersistentSurface(const sp<IGraphicBufferConsumer>& surface);
virtual status_t setOutputFile(int fd, int64_t offset, int64_t length);
virtual status_t setParameters(const String8& params);
virtual status_t setListener(const sp<IMediaRecorderClient>& listener);
@@ -72,6 +74,7 @@ private:
sp<ICamera> mCamera;
sp<ICameraRecordingProxy> mCameraProxy;
sp<IGraphicBufferProducer> mPreviewSurface;
+ sp<IGraphicBufferConsumer> mPersistentSurface;
sp<IMediaRecorderClient> mListener;
String16 mClientName;
uid_t mClientUid;
diff --git a/media/libstagefright/MediaCodecSource.cpp b/media/libstagefright/MediaCodecSource.cpp
index b272448..9b57733 100644
--- a/media/libstagefright/MediaCodecSource.cpp
+++ b/media/libstagefright/MediaCodecSource.cpp
@@ -20,6 +20,7 @@
#include <inttypes.h>
+#include <gui/IGraphicBufferConsumer.h>
#include <gui/IGraphicBufferProducer.h>
#include <gui/Surface.h>
#include <media/ICrypto.h>
@@ -29,10 +30,11 @@
#include <media/stagefright/foundation/AMessage.h>
#include <media/stagefright/MediaBuffer.h>
#include <media/stagefright/MediaCodec.h>
-#include <media/stagefright/MetaData.h>
+#include <media/stagefright/MediaCodecSource.h>
#include <media/stagefright/MediaErrors.h>
#include <media/stagefright/MediaSource.h>
-#include <media/stagefright/MediaCodecSource.h>
+#include <media/stagefright/MetaData.h>
+#include <media/stagefright/PersistentSurface.h>
#include <media/stagefright/Utils.h>
namespace android {
@@ -258,9 +260,10 @@ sp<MediaCodecSource> MediaCodecSource::Create(
const sp<ALooper> &looper,
const sp<AMessage> &format,
const sp<MediaSource> &source,
+ const sp<IGraphicBufferConsumer> &consumer,
uint32_t flags) {
sp<MediaCodecSource> mediaSource =
- new MediaCodecSource(looper, format, source, flags);
+ new MediaCodecSource(looper, format, source, consumer, flags);
if (mediaSource->init() == OK) {
return mediaSource;
@@ -328,6 +331,7 @@ MediaCodecSource::MediaCodecSource(
const sp<ALooper> &looper,
const sp<AMessage> &outputFormat,
const sp<MediaSource> &source,
+ const sp<IGraphicBufferConsumer> &consumer,
uint32_t flags)
: mLooper(looper),
mOutputFormat(outputFormat),
@@ -337,6 +341,7 @@ MediaCodecSource::MediaCodecSource(
mStarted(false),
mStopping(false),
mDoMoreWorkPending(false),
+ mGraphicBufferConsumer(consumer),
mFirstSampleTimeUs(-1ll),
mEncoderReachedEOS(false),
mErrorCode(OK) {
@@ -418,7 +423,15 @@ status_t MediaCodecSource::initEncoder() {
if (mFlags & FLAG_USE_SURFACE_INPUT) {
CHECK(mIsVideo);
- err = mEncoder->createInputSurface(&mGraphicBufferProducer);
+ if (mGraphicBufferConsumer != NULL) {
+ // When using persistent surface, we are only interested in the
+ // consumer, but have to use PersistentSurface as a wrapper to
+ // pass consumer over messages (similar to BufferProducerWrapper)
+ err = mEncoder->usePersistentInputSurface(
+ new PersistentSurface(NULL, mGraphicBufferConsumer));
+ } else {
+ err = mEncoder->createInputSurface(&mGraphicBufferProducer);
+ }
if (err != OK) {
return err;