SurfaceMediaSource.h revision a54dee4002624e0885b39451cb29028406f5bf8e
124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner/* 224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner * Copyright (C) 2011 The Android Open Source Project 324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner * 424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner * Licensed under the Apache License, Version 2.0 (the "License"); 524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner * you may not use this file except in compliance with the License. 624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner * You may obtain a copy of the License at 724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner * 824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner * http://www.apache.org/licenses/LICENSE-2.0 924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner * 1024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner * Unless required by applicable law or agreed to in writing, software 1124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner * distributed under the License is distributed on an "AS IS" BASIS, 1224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner * See the License for the specific language governing permissions and 1424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner * limitations under the License. 1524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner */ 1624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 1724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#ifndef ANDROID_GUI_SURFACEMEDIASOURCE_H 1824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#define ANDROID_GUI_SURFACEMEDIASOURCE_H 1924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 2024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include <gui/ISurfaceTexture.h> 2124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include <gui/BufferQueue.h> 2224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 2324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include <utils/threads.h> 2424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include <utils/Vector.h> 2524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include <media/stagefright/MediaSource.h> 2624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include <media/stagefright/MediaBuffer.h> 2724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 2824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnernamespace android { 2924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// ---------------------------------------------------------------------------- 3017dae081d7b88d24a7af6b07c10fc5981f81e2a9Greg Clayton 3124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerclass IGraphicBufferAlloc; 326bc0b5d69f6f5f46055be6cfea6f9a0eb11b1943Greg Claytonclass String8; 336bc0b5d69f6f5f46055be6cfea6f9a0eb11b1943Greg Claytonclass GraphicBuffer; 346bc0b5d69f6f5f46055be6cfea6f9a0eb11b1943Greg Clayton 3524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// ASSUMPTIONS 366bc0b5d69f6f5f46055be6cfea6f9a0eb11b1943Greg Clayton// 1. SurfaceMediaSource is initialized with width*height which 3724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// can never change. However, deqeueue buffer does not currently 3824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// enforce this as in BufferQueue, dequeue can be used by SurfaceTexture 3924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// which can modify the default width and heght. Also neither the width 4024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// nor height can be 0. 4124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 2. setSynchronousMode is never used (basically no one should call 4224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// setSynchronousMode(false) 4324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 3. setCrop, setTransform, setScalingMode should never be used 4424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 4. queueBuffer returns a filled buffer to the SurfaceMediaSource. In addition, a 4536da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton// timestamp must be provided for the buffer. The timestamp is in 4624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// nanoseconds, and must be monotonically increasing. Its other semantics 4724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// (zero point, etc) are client-dependent and should be documented by the 4836da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton// client. 495d81f49f0b45f8810cfaf1fa3437aa72bed0c3afGreg Clayton// 5. Once disconnected, SurfaceMediaSource can be reused (can not 505d81f49f0b45f8810cfaf1fa3437aa72bed0c3afGreg Clayton// connect again) 5117dae081d7b88d24a7af6b07c10fc5981f81e2a9Greg Clayton// 6. Stop is a hard stop, the last few frames held by the encoder 5217dae081d7b88d24a7af6b07c10fc5981f81e2a9Greg Clayton// may be dropped. It is possible to wait for the buffers to be 5317dae081d7b88d24a7af6b07c10fc5981f81e2a9Greg Clayton// returned (but not implemented) 546bc0b5d69f6f5f46055be6cfea6f9a0eb11b1943Greg Clayton 556bc0b5d69f6f5f46055be6cfea6f9a0eb11b1943Greg Clayton#define DEBUG_PENDING_BUFFERS 0 566bc0b5d69f6f5f46055be6cfea6f9a0eb11b1943Greg Clayton 576bc0b5d69f6f5f46055be6cfea6f9a0eb11b1943Greg Claytonclass SurfaceMediaSource : public MediaSource, 586bc0b5d69f6f5f46055be6cfea6f9a0eb11b1943Greg Clayton public MediaBufferObserver, 596bc0b5d69f6f5f46055be6cfea6f9a0eb11b1943Greg Clayton protected BufferQueue::ConsumerListener { 606bc0b5d69f6f5f46055be6cfea6f9a0eb11b1943Greg Claytonpublic: 616bc0b5d69f6f5f46055be6cfea6f9a0eb11b1943Greg Clayton enum { MIN_UNDEQUEUED_BUFFERS = 4}; 626bc0b5d69f6f5f46055be6cfea6f9a0eb11b1943Greg Clayton 636bc0b5d69f6f5f46055be6cfea6f9a0eb11b1943Greg Clayton struct FrameAvailableListener : public virtual RefBase { 646bc0b5d69f6f5f46055be6cfea6f9a0eb11b1943Greg Clayton // onFrameAvailable() is called from queueBuffer() is the FIFO is 65994b86bcbf78930c309ec0e38f2d980e8c338c04Enrico Granata // empty. You can use SurfaceMediaSource::getQueuedCount() to 66994b86bcbf78930c309ec0e38f2d980e8c338c04Enrico Granata // figure out if there are more frames waiting. 67994b86bcbf78930c309ec0e38f2d980e8c338c04Enrico Granata // This is called without any lock held can be called concurrently by 68994b86bcbf78930c309ec0e38f2d980e8c338c04Enrico Granata // multiple threads. 69994b86bcbf78930c309ec0e38f2d980e8c338c04Enrico Granata virtual void onFrameAvailable() = 0; 706bc0b5d69f6f5f46055be6cfea6f9a0eb11b1943Greg Clayton }; 716bc0b5d69f6f5f46055be6cfea6f9a0eb11b1943Greg Clayton 7217dae081d7b88d24a7af6b07c10fc5981f81e2a9Greg Clayton SurfaceMediaSource(uint32_t bufferWidth, uint32_t bufferHeight); 7324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 7424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner virtual ~SurfaceMediaSource(); 7524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 7624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // For the MediaSource interface for use by StageFrightRecorder: 7724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner virtual status_t start(MetaData *params = NULL); 7824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner virtual status_t stop(); 7924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner virtual status_t read(MediaBuffer **buffer, 8024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const ReadOptions *options = NULL); 8124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner virtual sp<MetaData> getFormat(); 8224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 8324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Get / Set the frame rate used for encoding. Default fps = 30 8424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner status_t setFrameRate(int32_t fps) ; 8524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner int32_t getFrameRate( ) const; 8624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 8724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // The call for the StageFrightRecorder to tell us that 8824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // it is done using the MediaBuffer data so that its state 8924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // can be set to FREE for dequeuing 9024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner virtual void signalBufferReturned(MediaBuffer* buffer); 9124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // end of MediaSource interface 9224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 9324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // getTimestamp retrieves the timestamp associated with the image 9424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // set by the most recent call to read() 9524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // 96 // The timestamp is in nanoseconds, and is monotonically increasing. Its 97 // other semantics (zero point, etc) are source-dependent and should be 98 // documented by the source. 99 int64_t getTimestamp(); 100 101 // setFrameAvailableListener sets the listener object that will be notified 102 // when a new frame becomes available. 103 void setFrameAvailableListener(const sp<FrameAvailableListener>& listener); 104 105 // dump our state in a String 106 void dump(String8& result) const; 107 void dump(String8& result, const char* prefix, char* buffer, 108 size_t SIZE) const; 109 110 // isMetaDataStoredInVideoBuffers tells the encoder whether we will 111 // pass metadata through the buffers. Currently, it is force set to true 112 bool isMetaDataStoredInVideoBuffers() const; 113 114 sp<BufferQueue> getBufferQueue() const { return mBufferQueue; } 115 116 // To be called before start() 117 status_t setMaxAcquiredBufferCount(size_t count); 118 119protected: 120 121 // Implementation of the BufferQueue::ConsumerListener interface. These 122 // calls are used to notify the SurfaceTexture of asynchronous events in the 123 // BufferQueue. 124 virtual void onFrameAvailable(); 125 126 // Used as a hook to BufferQueue::disconnect() 127 // This is called by the client side when it is done 128 // TODO: Currently, this also sets mStopped to true which 129 // is needed for unblocking the encoder which might be 130 // waiting to read more frames. So if on the client side, 131 // the same thread supplies the frames and also calls stop 132 // on the encoder, the client has to call disconnect before 133 // it calls stop. 134 // In the case of the camera, 135 // that need not be required since the thread supplying the 136 // frames is separate than the one calling stop. 137 virtual void onBuffersReleased(); 138 139 static bool isExternalFormat(uint32_t format); 140 141private: 142 // mBufferQueue is the exchange point between the producer and 143 // this consumer 144 sp<BufferQueue> mBufferQueue; 145 146 // mBufferSlot caches GraphicBuffers from the buffer queue 147 sp<GraphicBuffer> mBufferSlot[BufferQueue::NUM_BUFFER_SLOTS]; 148 149 150 // The permenent width and height of SMS buffers 151 int mWidth; 152 int mHeight; 153 154 // mCurrentSlot is the buffer slot index of the buffer that is currently 155 // being used by buffer consumer 156 // (e.g. StageFrightRecorder in the case of SurfaceMediaSource or GLTexture 157 // in the case of SurfaceTexture). 158 // It is initialized to INVALID_BUFFER_SLOT, 159 // indicating that no buffer slot is currently bound to the texture. Note, 160 // however, that a value of INVALID_BUFFER_SLOT does not necessarily mean 161 // that no buffer is bound to the texture. A call to setBufferCount will 162 // reset mCurrentTexture to INVALID_BUFFER_SLOT. 163 int mCurrentSlot; 164 165 // mCurrentBuffers is a list of the graphic buffers that are being used by 166 // buffer consumer (i.e. the video encoder). It's possible that these 167 // buffers are not associated with any buffer slots, so we must track them 168 // separately. Buffers are added to this list in read, and removed from 169 // this list in signalBufferReturned 170 Vector<sp<GraphicBuffer> > mCurrentBuffers; 171 172 size_t mNumPendingBuffers; 173 174#if DEBUG_PENDING_BUFFERS 175 Vector<MediaBuffer *> mPendingBuffers; 176#endif 177 178 // mCurrentTimestamp is the timestamp for the current texture. It 179 // gets set to mLastQueuedTimestamp each time updateTexImage is called. 180 int64_t mCurrentTimestamp; 181 182 // mFrameAvailableListener is the listener object that will be called when a 183 // new frame becomes available. If it is not NULL it will be called from 184 // queueBuffer. 185 sp<FrameAvailableListener> mFrameAvailableListener; 186 187 // mMutex is the mutex used to prevent concurrent access to the member 188 // variables of SurfaceMediaSource objects. It must be locked whenever the 189 // member variables are accessed. 190 mutable Mutex mMutex; 191 192 ////////////////////////// For MediaSource 193 // Set to a default of 30 fps if not specified by the client side 194 int32_t mFrameRate; 195 196 // mStarted is a flag to check if the recording is going on 197 bool mStarted; 198 199 // mNumFramesReceived indicates the number of frames recieved from 200 // the client side 201 int mNumFramesReceived; 202 // mNumFramesEncoded indicates the number of frames passed on to the 203 // encoder 204 int mNumFramesEncoded; 205 206 // mFirstFrameTimestamp is the timestamp of the first received frame. 207 // It is used to offset the output timestamps so recording starts at time 0. 208 int64_t mFirstFrameTimestamp; 209 // mStartTimeNs is the start time passed into the source at start, used to 210 // offset timestamps. 211 int64_t mStartTimeNs; 212 213 size_t mMaxAcquiredBufferCount; 214 215 // mFrameAvailableCondition condition used to indicate whether there 216 // is a frame available for dequeuing 217 Condition mFrameAvailableCondition; 218 219 Condition mMediaBuffersAvailableCondition; 220 221 // Avoid copying and equating and default constructor 222 DISALLOW_IMPLICIT_CONSTRUCTORS(SurfaceMediaSource); 223}; 224 225// ---------------------------------------------------------------------------- 226}; // namespace android 227 228#endif // ANDROID_GUI_SURFACEMEDIASOURCE_H 229