diff options
author | Chong Zhang <chz@google.com> | 2015-05-01 12:36:13 -0700 |
---|---|---|
committer | Chong Zhang <chz@google.com> | 2015-05-01 19:18:49 -0700 |
commit | e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049 (patch) | |
tree | 8060421e6bb2732c1b84d0810f5e83a57a7d25ea /media | |
parent | d291c222357303b9611cab89d0c3b047584ef377 (diff) | |
download | frameworks_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.cpp | 19 | ||||
-rw-r--r-- | media/libmedia/mediarecorder.cpp | 19 | ||||
-rw-r--r-- | media/libmediaplayerservice/MediaRecorderClient.cpp | 10 | ||||
-rw-r--r-- | media/libmediaplayerservice/MediaRecorderClient.h | 1 | ||||
-rw-r--r-- | media/libmediaplayerservice/StagefrightRecorder.cpp | 11 | ||||
-rw-r--r-- | media/libmediaplayerservice/StagefrightRecorder.h | 3 | ||||
-rw-r--r-- | media/libstagefright/MediaCodecSource.cpp | 21 |
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; |