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/IGraphicBufferProducer.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 28 #include <MetadataBufferType.h> 29 30 #include "foundation/ABase.h" 31 32 namespace android { 33 // ---------------------------------------------------------------------------- 34 35 class IGraphicBufferAlloc; 36 class String8; 37 class GraphicBuffer; 38 39 // ASSUMPTIONS 40 // 1. SurfaceMediaSource is initialized with width*height which 41 // can never change. However, deqeueue buffer does not currently 42 // enforce this as in BufferQueue, dequeue can be used by Surface 43 // which can modify the default width and heght. Also neither the width 44 // nor height can be 0. 45 // 2. setSynchronousMode is never used (basically no one should call 46 // setSynchronousMode(false) 47 // 3. setCrop, setTransform, setScalingMode should never be used 48 // 4. queueBuffer returns a filled buffer to the SurfaceMediaSource. In addition, a 49 // timestamp must be provided for the buffer. The timestamp is in 50 // nanoseconds, and must be monotonically increasing. Its other semantics 51 // (zero point, etc) are client-dependent and should be documented by the 52 // client. 53 // 5. Once disconnected, SurfaceMediaSource can be reused (can not 54 // connect again) 55 // 6. Stop is a hard stop, the last few frames held by the encoder 56 // may be dropped. It is possible to wait for the buffers to be 57 // returned (but not implemented) 58 59 #define DEBUG_PENDING_BUFFERS 0 60 61 class SurfaceMediaSource : public MediaSource, 62 public MediaBufferObserver, 63 protected ConsumerListener { 64 public: 65 enum { MIN_UNDEQUEUED_BUFFERS = 4}; 66 67 struct FrameAvailableListener : public virtual RefBase { 68 // onFrameAvailable() is called from queueBuffer() is the FIFO is 69 // empty. You can use SurfaceMediaSource::getQueuedCount() to 70 // figure out if there are more frames waiting. 71 // This is called without any lock held can be called concurrently by 72 // multiple threads. 73 virtual void onFrameAvailable() = 0; 74 }; 75 76 SurfaceMediaSource(uint32_t bufferWidth, uint32_t bufferHeight); 77 78 virtual ~SurfaceMediaSource(); 79 80 // For the MediaSource interface for use by StageFrightRecorder: 81 virtual status_t start(MetaData *params = NULL); 82 virtual status_t stop(); 83 virtual status_t read(MediaBuffer **buffer, 84 const ReadOptions *options = NULL); 85 virtual sp<MetaData> getFormat(); 86 87 // Get / Set the frame rate used for encoding. Default fps = 30 88 status_t setFrameRate(int32_t fps) ; 89 int32_t getFrameRate( ) const; 90 91 // The call for the StageFrightRecorder to tell us that 92 // it is done using the MediaBuffer data so that its state 93 // can be set to FREE for dequeuing 94 virtual void signalBufferReturned(MediaBuffer* buffer); 95 // end of MediaSource interface 96 97 // getTimestamp retrieves the timestamp associated with the image 98 // set by the most recent call to read() 99 // 100 // The timestamp is in nanoseconds, and is monotonically increasing. Its 101 // other semantics (zero point, etc) are source-dependent and should be 102 // documented by the source. 103 int64_t getTimestamp(); 104 105 // setFrameAvailableListener sets the listener object that will be notified 106 // when a new frame becomes available. 107 void setFrameAvailableListener(const sp<FrameAvailableListener>& listener); 108 109 // dump our state in a String 110 void dump(String8& result) const; 111 void dump(String8& result, const char* prefix, char* buffer, 112 size_t SIZE) const; 113 114 // metaDataStoredInVideoBuffers tells the encoder what kind of metadata 115 // is passed through the buffers. Currently, it is set to ANWBuffer 116 MetadataBufferType metaDataStoredInVideoBuffers() const; 117 getProducer()118 sp<IGraphicBufferProducer> getProducer() const { return mProducer; } 119 120 // To be called before start() 121 status_t setMaxAcquiredBufferCount(size_t count); 122 123 // To be called before start() 124 status_t setUseAbsoluteTimestamps(); 125 126 protected: 127 128 // Implementation of the BufferQueue::ConsumerListener interface. These 129 // calls are used to notify the Surface of asynchronous events in the 130 // BufferQueue. 131 virtual void onFrameAvailable(const BufferItem& item); 132 133 // Used as a hook to BufferQueue::disconnect() 134 // This is called by the client side when it is done 135 // TODO: Currently, this also sets mStopped to true which 136 // is needed for unblocking the encoder which might be 137 // waiting to read more frames. So if on the client side, 138 // the same thread supplies the frames and also calls stop 139 // on the encoder, the client has to call disconnect before 140 // it calls stop. 141 // In the case of the camera, 142 // that need not be required since the thread supplying the 143 // frames is separate than the one calling stop. 144 virtual void onBuffersReleased(); 145 146 // SurfaceMediaSource can't handle sideband streams, so this is not expected 147 // to ever be called. Does nothing. 148 virtual void onSidebandStreamChanged(); 149 150 static bool isExternalFormat(uint32_t format); 151 152 private: 153 // A BufferQueue, represented by these interfaces, is the exchange point 154 // between the producer and this consumer 155 sp<IGraphicBufferProducer> mProducer; 156 sp<IGraphicBufferConsumer> mConsumer; 157 158 struct SlotData { 159 sp<GraphicBuffer> mGraphicBuffer; 160 uint64_t mFrameNumber; 161 }; 162 163 // mSlots caches GraphicBuffers and frameNumbers from the buffer queue 164 SlotData mSlots[BufferQueue::NUM_BUFFER_SLOTS]; 165 166 // The permenent width and height of SMS buffers 167 int mWidth; 168 int mHeight; 169 170 // mCurrentSlot is the buffer slot index of the buffer that is currently 171 // being used by buffer consumer 172 // (e.g. StageFrightRecorder in the case of SurfaceMediaSource or GLTexture 173 // in the case of Surface). 174 // It is initialized to INVALID_BUFFER_SLOT, 175 // indicating that no buffer slot is currently bound to the texture. Note, 176 // however, that a value of INVALID_BUFFER_SLOT does not necessarily mean 177 // that no buffer is bound to the texture. A call to setBufferCount will 178 // reset mCurrentTexture to INVALID_BUFFER_SLOT. 179 int mCurrentSlot; 180 181 // mCurrentBuffers is a list of the graphic buffers that are being used by 182 // buffer consumer (i.e. the video encoder). It's possible that these 183 // buffers are not associated with any buffer slots, so we must track them 184 // separately. Buffers are added to this list in read, and removed from 185 // this list in signalBufferReturned 186 Vector<sp<GraphicBuffer> > mCurrentBuffers; 187 188 size_t mNumPendingBuffers; 189 190 #if DEBUG_PENDING_BUFFERS 191 Vector<MediaBuffer *> mPendingBuffers; 192 #endif 193 194 // mCurrentTimestamp is the timestamp for the current texture. It 195 // gets set to mLastQueuedTimestamp each time updateTexImage is called. 196 int64_t mCurrentTimestamp; 197 198 // mFrameAvailableListener is the listener object that will be called when a 199 // new frame becomes available. If it is not NULL it will be called from 200 // queueBuffer. 201 sp<FrameAvailableListener> mFrameAvailableListener; 202 203 // mMutex is the mutex used to prevent concurrent access to the member 204 // variables of SurfaceMediaSource objects. It must be locked whenever the 205 // member variables are accessed. 206 mutable Mutex mMutex; 207 208 ////////////////////////// For MediaSource 209 // Set to a default of 30 fps if not specified by the client side 210 int32_t mFrameRate; 211 212 // mStarted is a flag to check if the recording is going on 213 bool mStarted; 214 215 // mNumFramesReceived indicates the number of frames recieved from 216 // the client side 217 int mNumFramesReceived; 218 // mNumFramesEncoded indicates the number of frames passed on to the 219 // encoder 220 int mNumFramesEncoded; 221 222 // mFirstFrameTimestamp is the timestamp of the first received frame. 223 // It is used to offset the output timestamps so recording starts at time 0. 224 int64_t mFirstFrameTimestamp; 225 // mStartTimeNs is the start time passed into the source at start, used to 226 // offset timestamps. 227 int64_t mStartTimeNs; 228 229 size_t mMaxAcquiredBufferCount; 230 231 bool mUseAbsoluteTimestamps; 232 233 // mFrameAvailableCondition condition used to indicate whether there 234 // is a frame available for dequeuing 235 Condition mFrameAvailableCondition; 236 237 Condition mMediaBuffersAvailableCondition; 238 239 // Allocate and return a new MediaBuffer and pass the ANW buffer as metadata into it. 240 void passMetadataBuffer_l(MediaBuffer **buffer, ANativeWindowBuffer *bufferHandle) const; 241 242 // Avoid copying and equating and default constructor 243 DISALLOW_EVIL_CONSTRUCTORS(SurfaceMediaSource); 244 }; 245 246 // ---------------------------------------------------------------------------- 247 }; // namespace android 248 249 #endif // ANDROID_GUI_SURFACEMEDIASOURCE_H 250