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