SurfaceMediaSource.h revision bdddc659a941afdb7f4958f582c6901c07246097
1/* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#ifndef ANDROID_GUI_SURFACEMEDIASOURCE_H 18#define ANDROID_GUI_SURFACEMEDIASOURCE_H 19 20#include <gui/ISurfaceTexture.h> 21#include <gui/BufferQueue.h> 22 23#include <utils/threads.h> 24#include <utils/Vector.h> 25#include <media/stagefright/MediaSource.h> 26#include <media/stagefright/MediaBuffer.h> 27 28namespace android { 29// ---------------------------------------------------------------------------- 30 31class IGraphicBufferAlloc; 32class String8; 33class GraphicBuffer; 34 35// ASSUMPTIONS 36// 1. SurfaceMediaSource is initialized with width*height which 37// can never change. However, deqeueue buffer does not currently 38// enforce this as in BufferQueue, dequeue can be used by SurfaceTexture 39// which can modify the default width and heght. Also neither the width 40// nor height can be 0. 41// 2. setSynchronousMode is never used (basically no one should call 42// setSynchronousMode(false) 43// 3. setCrop, setTransform, setScalingMode should never be used 44// 4. queueBuffer returns a filled buffer to the SurfaceMediaSource. In addition, a 45// timestamp must be provided for the buffer. The timestamp is in 46// nanoseconds, and must be monotonically increasing. Its other semantics 47// (zero point, etc) are client-dependent and should be documented by the 48// client. 49// 5. Once disconnected, SurfaceMediaSource can be reused (can not 50// connect again) 51// 6. Stop is a hard stop, the last few frames held by the encoder 52// may be dropped. It is possible to wait for the buffers to be 53// returned (but not implemented) 54 55class SurfaceMediaSource : public MediaSource, 56 public MediaBufferObserver, 57 protected BufferQueue::ConsumerListener { 58public: 59 enum { MIN_UNDEQUEUED_BUFFERS = 4}; 60 61 struct FrameAvailableListener : public virtual RefBase { 62 // onFrameAvailable() is called from queueBuffer() is the FIFO is 63 // empty. You can use SurfaceMediaSource::getQueuedCount() to 64 // figure out if there are more frames waiting. 65 // This is called without any lock held can be called concurrently by 66 // multiple threads. 67 virtual void onFrameAvailable() = 0; 68 }; 69 70 SurfaceMediaSource(uint32_t bufferWidth, uint32_t bufferHeight); 71 72 virtual ~SurfaceMediaSource(); 73 74 // For the MediaSource interface for use by StageFrightRecorder: 75 virtual status_t start(MetaData *params = NULL); 76 77 virtual status_t stop() { return reset(); } 78 virtual status_t read( 79 MediaBuffer **buffer, const ReadOptions *options = NULL); 80 virtual sp<MetaData> getFormat(); 81 82 // Pass the metadata over to the buffer, call when you have the lock 83 void passMetadataBufferLocked(MediaBuffer **buffer); 84 bool checkBufferMatchesSlot(int slot, MediaBuffer *buffer); 85 86 // Get / Set the frame rate used for encoding. Default fps = 30 87 status_t setFrameRate(int32_t fps) ; 88 int32_t getFrameRate( ) const; 89 90 // The call for the StageFrightRecorder to tell us that 91 // it is done using the MediaBuffer data so that its state 92 // can be set to FREE for dequeuing 93 virtual void signalBufferReturned(MediaBuffer* buffer); 94 // end of MediaSource interface 95 96 // getTimestamp retrieves the timestamp associated with the image 97 // set by the most recent call to read() 98 // 99 // The timestamp is in nanoseconds, and is monotonically increasing. Its 100 // other semantics (zero point, etc) are source-dependent and should be 101 // documented by the source. 102 int64_t getTimestamp(); 103 104 // setFrameAvailableListener sets the listener object that will be notified 105 // when a new frame becomes available. 106 void setFrameAvailableListener(const sp<FrameAvailableListener>& listener); 107 108 // getCurrentBuffer returns the buffer associated with the current image. 109 sp<GraphicBuffer> getCurrentBuffer() const; 110 111 // dump our state in a String 112 void dump(String8& result) const; 113 void dump(String8& result, const char* prefix, char* buffer, 114 size_t SIZE) const; 115 116 // isMetaDataStoredInVideoBuffers tells the encoder whether we will 117 // pass metadata through the buffers. Currently, it is force set to true 118 bool isMetaDataStoredInVideoBuffers() const; 119 120 sp<BufferQueue> getBufferQueue() const { return mBufferQueue; } 121 122protected: 123 124 // Implementation of the BufferQueue::ConsumerListener interface. These 125 // calls are used to notify the SurfaceTexture of asynchronous events in the 126 // BufferQueue. 127 virtual void onFrameAvailable(); 128 129 // Used as a hook to BufferQueue::disconnect() 130 // This is called by the client side when it is done 131 // TODO: Currently, this also sets mStopped to true which 132 // is needed for unblocking the encoder which might be 133 // waiting to read more frames. So if on the client side, 134 // the same thread supplies the frames and also calls stop 135 // on the encoder, the client has to call disconnect before 136 // it calls stop. 137 // In the case of the camera, 138 // that need not be required since the thread supplying the 139 // frames is separate than the one calling stop. 140 virtual void onBuffersReleased(); 141 142 static bool isExternalFormat(uint32_t format); 143 144private: 145 // mBufferQueue is the exchange point between the producer and 146 // this consumer 147 sp<BufferQueue> mBufferQueue; 148 149 // mBufferSlot caches GraphicBuffers from the buffer queue 150 sp<GraphicBuffer> mBufferSlot[BufferQueue::NUM_BUFFER_SLOTS]; 151 152 153 // The permenent width and height of SMS buffers 154 int mWidth; 155 int mHeight; 156 157 // mCurrentSlot is the buffer slot index of the buffer that is currently 158 // being used by buffer consumer 159 // (e.g. StageFrightRecorder in the case of SurfaceMediaSource or GLTexture 160 // in the case of SurfaceTexture). 161 // It is initialized to INVALID_BUFFER_SLOT, 162 // indicating that no buffer slot is currently bound to the texture. Note, 163 // however, that a value of INVALID_BUFFER_SLOT does not necessarily mean 164 // that no buffer is bound to the texture. A call to setBufferCount will 165 // reset mCurrentTexture to INVALID_BUFFER_SLOT. 166 int mCurrentSlot; 167 168 // mCurrentBuf is the graphic buffer of the current slot to be used by 169 // buffer consumer. It's possible that this buffer is not associated 170 // with any buffer slot, so we must track it separately in order to 171 // properly use IGraphicBufferAlloc::freeAllGraphicBuffersExcept. 172 sp<GraphicBuffer> mCurrentBuf; 173 174 // mCurrentTimestamp is the timestamp for the current texture. It 175 // gets set to mLastQueuedTimestamp each time updateTexImage is called. 176 int64_t mCurrentTimestamp; 177 178 // mFrameAvailableListener is the listener object that will be called when a 179 // new frame becomes available. If it is not NULL it will be called from 180 // queueBuffer. 181 sp<FrameAvailableListener> mFrameAvailableListener; 182 183 // mMutex is the mutex used to prevent concurrent access to the member 184 // variables of SurfaceMediaSource objects. It must be locked whenever the 185 // member variables are accessed. 186 mutable Mutex mMutex; 187 188 ////////////////////////// For MediaSource 189 // Set to a default of 30 fps if not specified by the client side 190 int32_t mFrameRate; 191 192 // mStopped is a flag to check if the recording is going on 193 bool mStopped; 194 195 // mNumFramesReceived indicates the number of frames recieved from 196 // the client side 197 int mNumFramesReceived; 198 // mNumFramesEncoded indicates the number of frames passed on to the 199 // encoder 200 int mNumFramesEncoded; 201 202 // mFirstFrameTimestamp is the timestamp of the first received frame. 203 // It is used to offset the output timestamps so recording starts at time 0. 204 int64_t mFirstFrameTimestamp; 205 // mStartTimeNs is the start time passed into the source at start, used to 206 // offset timestamps. 207 int64_t mStartTimeNs; 208 209 // mFrameAvailableCondition condition used to indicate whether there 210 // is a frame available for dequeuing 211 Condition mFrameAvailableCondition; 212 213 status_t reset(); 214 215 // Avoid copying and equating and default constructor 216 DISALLOW_IMPLICIT_CONSTRUCTORS(SurfaceMediaSource); 217}; 218 219// ---------------------------------------------------------------------------- 220}; // namespace android 221 222#endif // ANDROID_GUI_SURFACEMEDIASOURCE_H 223