diff options
-rw-r--r-- | include/media/IMediaRecorder.h | 2 | ||||
-rw-r--r-- | include/media/MediaRecorderBase.h | 2 | ||||
-rw-r--r-- | include/media/mediarecorder.h | 2 | ||||
-rw-r--r-- | include/media/stagefright/MediaCodecSource.h | 4 | ||||
-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 |
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; |