GraphicBufferSource.h revision 6d332d2cdf6e62c2c20ebff220868fe9e3ed7f44
1/* 2 * Copyright (C) 2013 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 GRAPHIC_BUFFER_SOURCE_H_ 18 19#define GRAPHIC_BUFFER_SOURCE_H_ 20 21#include <gui/IGraphicBufferProducer.h> 22#include <gui/BufferQueue.h> 23#include <utils/RefBase.h> 24 25#include <VideoAPI.h> 26#include <media/IOMX.h> 27#include <media/OMXFenceParcelable.h> 28#include <media/stagefright/foundation/ABase.h> 29#include <media/stagefright/foundation/AHandlerReflector.h> 30#include <media/stagefright/foundation/ALooper.h> 31 32#include <android/BnGraphicBufferSource.h> 33#include <android/BnOMXBufferSource.h> 34 35namespace android { 36 37using ::android::binder::Status; 38 39struct FrameDropper; 40 41/* 42 * This class is used to feed OMX codecs from a Surface via BufferQueue. 43 * 44 * Instances of the class don't run on a dedicated thread. Instead, 45 * various events trigger data movement: 46 * 47 * - Availability of a new frame of data from the BufferQueue (notified 48 * via the onFrameAvailable callback). 49 * - The return of a codec buffer (via OnEmptyBufferDone). 50 * - Application signaling end-of-stream. 51 * - Transition to or from "executing" state. 52 * 53 * Frames of data (and, perhaps, the end-of-stream indication) can arrive 54 * before the codec is in the "executing" state, so we need to queue 55 * things up until we're ready to go. 56 */ 57class GraphicBufferSource : public BnGraphicBufferSource, 58 public BnOMXBufferSource, 59 public BufferQueue::ConsumerListener { 60public: 61 GraphicBufferSource( 62 const sp<IOMX> &omx, 63 IOMX::node_id nodeID, 64 uint32_t bufferWidth, 65 uint32_t bufferHeight, 66 uint32_t bufferCount, 67 uint32_t consumerUsage, 68 const sp<IGraphicBufferConsumer> &consumer = NULL 69 ); 70 71 virtual ~GraphicBufferSource(); 72 73 // We can't throw an exception if the constructor fails, so we just set 74 // this and require that the caller test the value. 75 status_t initCheck() const { 76 return mInitCheck; 77 } 78 79 // Returns the handle to the producer side of the BufferQueue. Buffers 80 // queued on this will be received by GraphicBufferSource. 81 sp<IGraphicBufferProducer> getIGraphicBufferProducer() const { 82 return mProducer; 83 } 84 85 // Sets the default buffer data space 86 void setDefaultDataSpace(android_dataspace dataSpace); 87 88 // This is called when OMX transitions to OMX_StateExecuting, which means 89 // we can start handing it buffers. If we already have buffers of data 90 // sitting in the BufferQueue, this will send them to the codec. 91 Status onOmxExecuting() override; 92 93 // This is called when OMX transitions to OMX_StateIdle, indicating that 94 // the codec is meant to return all buffers back to the client for them 95 // to be freed. Do NOT submit any more buffers to the component. 96 Status onOmxIdle() override; 97 98 // This is called when OMX transitions to OMX_StateLoaded, indicating that 99 // we are shutting down. 100 Status onOmxLoaded() override; 101 102 // A "codec buffer", i.e. a buffer that can be used to pass data into 103 // the encoder, has been allocated. (This call does not call back into 104 // OMXNodeInstance.) 105 Status onInputBufferAdded(int32_t bufferID) override; 106 107 // Called from OnEmptyBufferDone. If we have a BQ buffer available, 108 // fill it with a new frame of data; otherwise, just mark it as available. 109 Status onInputBufferEmptied( 110 int32_t bufferID, const OMXFenceParcelable& fenceParcel) override; 111 112 // This is called after the last input frame has been submitted. We 113 // need to submit an empty buffer with the EOS flag set. If we don't 114 // have a codec buffer ready, we just set the mEndOfStream flag. 115 Status signalEndOfInputStream() override; 116 117 // If suspend is true, all incoming buffers (including those currently 118 // in the BufferQueue) will be discarded until the suspension is lifted. 119 Status setSuspend(bool suspend) override; 120 121 // Specifies the interval after which we requeue the buffer previously 122 // queued to the encoder. This is useful in the case of surface flinger 123 // providing the input surface if the resulting encoded stream is to 124 // be displayed "live". If we were not to push through the extra frame 125 // the decoder on the remote end would be unable to decode the latest frame. 126 // This API must be called before transitioning the encoder to "executing" 127 // state and once this behaviour is specified it cannot be reset. 128 Status setRepeatPreviousFrameDelayUs(int64_t repeatAfterUs) override; 129 130 // When set, the timestamp fed to the encoder will be modified such that 131 // the gap between two adjacent frames is capped at maxGapUs. Timestamp 132 // will be restored to the original when the encoded frame is returned to 133 // the client. 134 // This is to solve a problem in certain real-time streaming case, where 135 // encoder's rate control logic produces huge frames after a long period 136 // of suspension on input. 137 Status setMaxTimestampGapUs(int64_t maxGapUs) override; 138 139 // Sets the input buffer timestamp offset. 140 // When set, the sample's timestamp will be adjusted with the timeOffsetUs. 141 Status setTimeOffsetUs(int64_t timeOffsetUs) override; 142 143 // When set, the max frame rate fed to the encoder will be capped at maxFps. 144 Status setMaxFps(float maxFps) override; 145 146 // Sets the time lapse (or slow motion) parameters. 147 // When set, the sample's timestamp will be modified to playback framerate, 148 // and capture timestamp will be modified to capture rate. 149 Status setTimeLapseConfig(int64_t timePerFrameUs, int64_t timePerCaptureUs) override; 150 151 // Sets the start time us (in system time), samples before which should 152 // be dropped and not submitted to encoder 153 Status setStartTimeUs(int64_t startTimeUs) override; 154 155 // Sets the desired color aspects, e.g. to be used when producer does not specify a dataspace. 156 Status setColorAspects(int32_t aspectsPacked) override; 157 158protected: 159 // BufferQueue::ConsumerListener interface, called when a new frame of 160 // data is available. If we're executing and a codec buffer is 161 // available, we acquire the buffer, copy the GraphicBuffer reference 162 // into the codec buffer, and call Empty[This]Buffer. If we're not yet 163 // executing or there's no codec buffer available, we just increment 164 // mNumFramesAvailable and return. 165 void onFrameAvailable(const BufferItem& item) override; 166 167 // BufferQueue::ConsumerListener interface, called when the client has 168 // released one or more GraphicBuffers. We clear out the appropriate 169 // set of mBufferSlot entries. 170 void onBuffersReleased() override; 171 172 // BufferQueue::ConsumerListener interface, called when the client has 173 // changed the sideband stream. GraphicBufferSource doesn't handle sideband 174 // streams so this is a no-op (and should never be called). 175 void onSidebandStreamChanged() override; 176 177private: 178 // PersistentProxyListener is similar to BufferQueue::ProxyConsumerListener 179 // except that it returns (acquire/detach/re-attache/release) buffers 180 // in onFrameAvailable() if the actual consumer object is no longer valid. 181 // 182 // This class is used in persistent input surface case to prevent buffer 183 // loss when onFrameAvailable() is received while we don't have a valid 184 // consumer around. 185 class PersistentProxyListener : public BnConsumerListener { 186 public: 187 PersistentProxyListener( 188 const wp<IGraphicBufferConsumer> &consumer, 189 const wp<ConsumerListener>& consumerListener); 190 virtual ~PersistentProxyListener(); 191 virtual void onFrameAvailable(const BufferItem& item) override; 192 virtual void onFrameReplaced(const BufferItem& item) override; 193 virtual void onBuffersReleased() override; 194 virtual void onSidebandStreamChanged() override; 195 private: 196 // mConsumerListener is a weak reference to the IConsumerListener. 197 wp<ConsumerListener> mConsumerListener; 198 // mConsumer is a weak reference to the IGraphicBufferConsumer, use 199 // a weak ref to avoid circular ref between mConsumer and this class 200 wp<IGraphicBufferConsumer> mConsumer; 201 }; 202 203 // Keep track of codec input buffers. They may either be available 204 // (mGraphicBuffer == NULL) or in use by the codec. 205 struct CodecBuffer { 206 IOMX::buffer_id mBufferID; 207 208 // buffer producer's frame-number for buffer 209 uint64_t mFrameNumber; 210 211 // buffer producer's buffer slot for buffer 212 int mSlot; 213 214 sp<GraphicBuffer> mGraphicBuffer; 215 }; 216 217 // Returns the index of an available codec buffer. If none are 218 // available, returns -1. Mutex must be held by caller. 219 int findAvailableCodecBuffer_l(); 220 221 // Returns true if a codec buffer is available. 222 bool isCodecBufferAvailable_l() { 223 return findAvailableCodecBuffer_l() >= 0; 224 } 225 226 // Finds the mCodecBuffers entry that matches. Returns -1 if not found. 227 int findMatchingCodecBuffer_l(IOMX::buffer_id bufferID); 228 229 // Fills a codec buffer with a frame from the BufferQueue. This must 230 // only be called when we know that a frame of data is ready (i.e. we're 231 // in the onFrameAvailable callback, or if we're in codecBufferEmptied 232 // and mNumFramesAvailable is nonzero). Returns without doing anything if 233 // we don't have a codec buffer available. 234 // 235 // Returns true if we successfully filled a codec buffer with a BQ buffer. 236 bool fillCodecBuffer_l(); 237 238 // Marks the mCodecBuffers entry as in-use, copies the GraphicBuffer 239 // reference into the codec buffer, and submits the data to the codec. 240 status_t submitBuffer_l(const BufferItem &item, int cbi); 241 242 // Submits an empty buffer, with the EOS flag set. Returns without 243 // doing anything if we don't have a codec buffer available. 244 void submitEndOfInputStream_l(); 245 246 // Release buffer to the consumer 247 void releaseBuffer( 248 int &id, uint64_t frameNum, 249 const sp<GraphicBuffer> buffer, const sp<Fence> &fence); 250 251 void setLatestBuffer_l(const BufferItem &item, bool dropped); 252 bool repeatLatestBuffer_l(); 253 bool getTimestamp(const BufferItem &item, int64_t *timeUs, int64_t *codecTimeUs); 254 255 // called when the data space of the input buffer changes 256 void onDataSpaceChanged_l(android_dataspace dataSpace, android_pixel_format pixelFormat); 257 258 // Lock, covers all member variables. 259 mutable Mutex mMutex; 260 261 // Used to report constructor failure. 262 status_t mInitCheck; 263 264 // Pointer back to the IOMX that created us. We send buffers here. 265 sp<IOMX> mOMX; 266 IOMX::node_id mNodeID; 267 268 // Set by omxExecuting() / omxIdling(). 269 bool mExecuting; 270 271 bool mSuspended; 272 273 // Last dataspace seen 274 android_dataspace mLastDataSpace; 275 276 // Our BufferQueue interfaces. mProducer is passed to the producer through 277 // getIGraphicBufferProducer, and mConsumer is used internally to retrieve 278 // the buffers queued by the producer. 279 bool mIsPersistent; 280 sp<IGraphicBufferProducer> mProducer; 281 sp<IGraphicBufferConsumer> mConsumer; 282 283 // Number of frames pending in BufferQueue that haven't yet been 284 // forwarded to the codec. 285 size_t mNumFramesAvailable; 286 287 // Number of frames acquired from consumer (debug only) 288 int32_t mNumBufferAcquired; 289 290 // Set to true if we want to send end-of-stream after we run out of 291 // frames in BufferQueue. 292 bool mEndOfStream; 293 bool mEndOfStreamSent; 294 295 // Cache of GraphicBuffers from the buffer queue. When the codec 296 // is done processing a GraphicBuffer, we can use this to map back 297 // to a slot number. 298 sp<GraphicBuffer> mBufferSlot[BufferQueue::NUM_BUFFER_SLOTS]; 299 int32_t mBufferUseCount[BufferQueue::NUM_BUFFER_SLOTS]; 300 301 // Tracks codec buffers. 302 Vector<CodecBuffer> mCodecBuffers; 303 304 //// 305 friend struct AHandlerReflector<GraphicBufferSource>; 306 307 enum { 308 kWhatRepeatLastFrame, 309 }; 310 enum { 311 kRepeatLastFrameCount = 10, 312 }; 313 314 int64_t mMaxTimestampGapUs; 315 int64_t mPrevOriginalTimeUs; 316 int64_t mPrevModifiedTimeUs; 317 int64_t mSkipFramesBeforeNs; 318 319 sp<FrameDropper> mFrameDropper; 320 321 sp<ALooper> mLooper; 322 sp<AHandlerReflector<GraphicBufferSource> > mReflector; 323 324 int64_t mRepeatAfterUs; 325 int32_t mRepeatLastFrameGeneration; 326 int64_t mRepeatLastFrameTimestamp; 327 int32_t mRepeatLastFrameCount; 328 329 int mLatestBufferId; 330 uint64_t mLatestBufferFrameNum; 331 sp<Fence> mLatestBufferFence; 332 333 // The previous buffer should've been repeated but 334 // no codec buffer was available at the time. 335 bool mRepeatBufferDeferred; 336 337 // Time lapse / slow motion configuration 338 int64_t mTimePerCaptureUs; 339 int64_t mTimePerFrameUs; 340 int64_t mPrevCaptureUs; 341 int64_t mPrevFrameUs; 342 343 int64_t mInputBufferTimeOffsetUs; 344 345 MetadataBufferType mMetadataBufferType; 346 ColorAspects mColorAspects; 347 348 void onMessageReceived(const sp<AMessage> &msg); 349 350 DISALLOW_EVIL_CONSTRUCTORS(GraphicBufferSource); 351}; 352 353} // namespace android 354 355#endif // GRAPHIC_BUFFER_SOURCE_H_ 356