summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authorChong Zhang <chz@google.com>2015-05-01 12:36:13 -0700
committerChong Zhang <chz@google.com>2015-05-01 19:18:49 -0700
commite2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049 (patch)
tree8060421e6bb2732c1b84d0810f5e83a57a7d25ea /media
parentd291c222357303b9611cab89d0c3b047584ef377 (diff)
downloadframeworks_av-e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049.zip
frameworks_av-e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049.tar.gz
frameworks_av-e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049.tar.bz2
MediaRecorder: implement persistent input surface APIs
Bug: 19127604 Bug: 19489395 Change-Id: I7dd8015a8fe029f9867fcdb52322629c77eff50b
Diffstat (limited to 'media')
-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
7 files changed, 78 insertions, 6 deletions
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;