GraphicBufferSource.h revision ad3b7e8d40bf1c97347f1538d30bba78ca371f67
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 <OMX_Core.h> 26#include "../include/OMXNodeInstance.h" 27#include <media/stagefright/foundation/ABase.h> 28#include <media/stagefright/foundation/AHandlerReflector.h> 29#include <media/stagefright/foundation/ALooper.h> 30 31namespace android { 32 33/* 34 * This class is used to feed OMX codecs from a Surface via BufferQueue. 35 * 36 * Instances of the class don't run on a dedicated thread. Instead, 37 * various events trigger data movement: 38 * 39 * - Availability of a new frame of data from the BufferQueue (notified 40 * via the onFrameAvailable callback). 41 * - The return of a codec buffer (via OnEmptyBufferDone). 42 * - Application signaling end-of-stream. 43 * - Transition to or from "executing" state. 44 * 45 * Frames of data (and, perhaps, the end-of-stream indication) can arrive 46 * before the codec is in the "executing" state, so we need to queue 47 * things up until we're ready to go. 48 */ 49class GraphicBufferSource : public BufferQueue::ConsumerListener { 50public: 51 GraphicBufferSource(OMXNodeInstance* nodeInstance, 52 uint32_t bufferWidth, uint32_t bufferHeight, uint32_t bufferCount); 53 virtual ~GraphicBufferSource(); 54 55 // We can't throw an exception if the constructor fails, so we just set 56 // this and require that the caller test the value. 57 status_t initCheck() const { 58 return mInitCheck; 59 } 60 61 // Returns the handle to the producer side of the BufferQueue. Buffers 62 // queued on this will be received by GraphicBufferSource. 63 sp<IGraphicBufferProducer> getIGraphicBufferProducer() const { 64 return mBufferQueue; 65 } 66 67 // This is called when OMX transitions to OMX_StateExecuting, which means 68 // we can start handing it buffers. If we already have buffers of data 69 // sitting in the BufferQueue, this will send them to the codec. 70 void omxExecuting(); 71 72 // This is called when OMX transitions to OMX_StateIdle, indicating that 73 // the codec is meant to return all buffers back to the client for them 74 // to be freed. Do NOT submit any more buffers to the component. 75 void omxIdle(); 76 77 // This is called when OMX transitions to OMX_StateLoaded, indicating that 78 // we are shutting down. 79 void omxLoaded(); 80 81 // A "codec buffer", i.e. a buffer that can be used to pass data into 82 // the encoder, has been allocated. (This call does not call back into 83 // OMXNodeInstance.) 84 void addCodecBuffer(OMX_BUFFERHEADERTYPE* header); 85 86 // Called from OnEmptyBufferDone. If we have a BQ buffer available, 87 // fill it with a new frame of data; otherwise, just mark it as available. 88 void codecBufferEmptied(OMX_BUFFERHEADERTYPE* header); 89 90 // This is called after the last input frame has been submitted. We 91 // need to submit an empty buffer with the EOS flag set. If we don't 92 // have a codec buffer ready, we just set the mEndOfStream flag. 93 status_t signalEndOfInputStream(); 94 95 // If suspend is true, all incoming buffers (including those currently 96 // in the BufferQueue) will be discarded until the suspension is lifted. 97 void suspend(bool suspend); 98 99 // Specifies the interval after which we requeue the buffer previously 100 // queued to the encoder. This is useful in the case of surface flinger 101 // providing the input surface if the resulting encoded stream is to 102 // be displayed "live". If we were not to push through the extra frame 103 // the decoder on the remote end would be unable to decode the latest frame. 104 // This API must be called before transitioning the encoder to "executing" 105 // state and once this behaviour is specified it cannot be reset. 106 status_t setRepeatPreviousFrameDelayUs(int64_t repeatAfterUs); 107 108protected: 109 // BufferQueue::ConsumerListener interface, called when a new frame of 110 // data is available. If we're executing and a codec buffer is 111 // available, we acquire the buffer, copy the GraphicBuffer reference 112 // into the codec buffer, and call Empty[This]Buffer. If we're not yet 113 // executing or there's no codec buffer available, we just increment 114 // mNumFramesAvailable and return. 115 virtual void onFrameAvailable(); 116 117 // BufferQueue::ConsumerListener interface, called when the client has 118 // released one or more GraphicBuffers. We clear out the appropriate 119 // set of mBufferSlot entries. 120 virtual void onBuffersReleased(); 121 122private: 123 // Keep track of codec input buffers. They may either be available 124 // (mGraphicBuffer == NULL) or in use by the codec. 125 struct CodecBuffer { 126 OMX_BUFFERHEADERTYPE* mHeader; 127 128 // buffer producer's frame-number for buffer 129 uint64_t mFrameNumber; 130 131 // buffer producer's buffer slot for buffer 132 int mBuf; 133 134 sp<GraphicBuffer> mGraphicBuffer; 135 }; 136 137 // Returns the index of an available codec buffer. If none are 138 // available, returns -1. Mutex must be held by caller. 139 int findAvailableCodecBuffer_l(); 140 141 // Returns true if a codec buffer is available. 142 bool isCodecBufferAvailable_l() { 143 return findAvailableCodecBuffer_l() >= 0; 144 } 145 146 // Finds the mCodecBuffers entry that matches. Returns -1 if not found. 147 int findMatchingCodecBuffer_l(const OMX_BUFFERHEADERTYPE* header); 148 149 // Fills a codec buffer with a frame from the BufferQueue. This must 150 // only be called when we know that a frame of data is ready (i.e. we're 151 // in the onFrameAvailable callback, or if we're in codecBufferEmptied 152 // and mNumFramesAvailable is nonzero). Returns without doing anything if 153 // we don't have a codec buffer available. 154 // 155 // Returns true if we successfully filled a codec buffer with a BQ buffer. 156 bool fillCodecBuffer_l(); 157 158 // Marks the mCodecBuffers entry as in-use, copies the GraphicBuffer 159 // reference into the codec buffer, and submits the data to the codec. 160 status_t submitBuffer_l(const BufferQueue::BufferItem &item, int cbi); 161 162 // Submits an empty buffer, with the EOS flag set. Returns without 163 // doing anything if we don't have a codec buffer available. 164 void submitEndOfInputStream_l(); 165 166 void setLatestSubmittedBuffer_l(const BufferQueue::BufferItem &item); 167 bool repeatLatestSubmittedBuffer_l(); 168 169 // Lock, covers all member variables. 170 mutable Mutex mMutex; 171 172 // Used to report constructor failure. 173 status_t mInitCheck; 174 175 // Pointer back to the object that contains us. We send buffers here. 176 OMXNodeInstance* mNodeInstance; 177 178 // Set by omxExecuting() / omxIdling(). 179 bool mExecuting; 180 181 bool mSuspended; 182 183 // We consume graphic buffers from this. 184 sp<BufferQueue> mBufferQueue; 185 186 // Number of frames pending in BufferQueue that haven't yet been 187 // forwarded to the codec. 188 size_t mNumFramesAvailable; 189 190 // Set to true if we want to send end-of-stream after we run out of 191 // frames in BufferQueue. 192 bool mEndOfStream; 193 bool mEndOfStreamSent; 194 195 // Cache of GraphicBuffers from the buffer queue. When the codec 196 // is done processing a GraphicBuffer, we can use this to map back 197 // to a slot number. 198 sp<GraphicBuffer> mBufferSlot[BufferQueue::NUM_BUFFER_SLOTS]; 199 200 // Tracks codec buffers. 201 Vector<CodecBuffer> mCodecBuffers; 202 203 //// 204 friend class AHandlerReflector<GraphicBufferSource>; 205 206 enum { 207 kWhatRepeatLastFrame, 208 }; 209 210 int64_t mRepeatAfterUs; 211 212 sp<ALooper> mLooper; 213 sp<AHandlerReflector<GraphicBufferSource> > mReflector; 214 215 int32_t mRepeatLastFrameGeneration; 216 217 int mLatestSubmittedBufferId; 218 uint64_t mLatestSubmittedBufferFrameNum; 219 int32_t mLatestSubmittedBufferUseCount; 220 221 // The previously submitted buffer should've been repeated but 222 // no codec buffer was available at the time. 223 bool mRepeatBufferDeferred; 224 225 void onMessageReceived(const sp<AMessage> &msg); 226 227 DISALLOW_EVIL_CONSTRUCTORS(GraphicBufferSource); 228}; 229 230} // namespace android 231 232#endif // GRAPHIC_BUFFER_SOURCE_H_ 233