GraphicBufferSource.h revision 0c37f9d1320bb87fd242f9425c67dacd6ce20112
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 88protected: 89 // BufferQueue::ConsumerListener interface, called when a new frame of 90 // data is available. If we're executing and a codec buffer is 91 // available, we acquire the buffer, copy the GraphicBuffer reference 92 // into the codec buffer, and call Empty[This]Buffer. If we're not yet 93 // executing or there's no codec buffer available, we just increment 94 // mNumFramesAvailable and return. 95 virtual void onFrameAvailable(); 96 97 // BufferQueue::ConsumerListener interface, called when the client has 98 // released one or more GraphicBuffers. We clear out the appropriate 99 // set of mBufferSlot entries. 100 virtual void onBuffersReleased(); 101 102private: 103 // Keep track of codec input buffers. They may either be available 104 // (mGraphicBuffer == NULL) or in use by the codec. 105 struct CodecBuffer { 106 OMX_BUFFERHEADERTYPE* mHeader; 107 sp<GraphicBuffer> mGraphicBuffer; 108 }; 109 110 // Returns the index of an available codec buffer. If none are 111 // available, returns -1. Mutex must be held by caller. 112 int findAvailableCodecBuffer_l(); 113 114 // Returns true if a codec buffer is available. 115 bool isCodecBufferAvailable_l() { 116 return findAvailableCodecBuffer_l() >= 0; 117 } 118 119 // Finds the mCodecBuffers entry that matches. Returns -1 if not found. 120 int findMatchingCodecBuffer_l(const OMX_BUFFERHEADERTYPE* header); 121 122 // Fills a codec buffer with a frame from the BufferQueue. This must 123 // only be called when we know that a frame of data is ready (i.e. we're 124 // in the onFrameAvailable callback, or if we're in codecBufferEmptied 125 // and mNumFramesAvailable is nonzero). Returns without doing anything if 126 // we don't have a codec buffer available. 127 // 128 // Returns true if we successfully filled a codec buffer with a BQ buffer. 129 bool fillCodecBuffer_l(); 130 131 // Marks the mCodecBuffers entry as in-use, copies the GraphicBuffer 132 // reference into the codec buffer, and submits the data to the codec. 133 status_t submitBuffer_l(sp<GraphicBuffer>& graphicBuffer, 134 int64_t timestamp, int cbi); 135 136 // Submits an empty buffer, with the EOS flag set. Returns without 137 // doing anything if we don't have a codec buffer available. 138 void submitEndOfInputStream_l(); 139 140 // Lock, covers all member variables. 141 mutable Mutex mMutex; 142 143 // Used to report constructor failure. 144 status_t mInitCheck; 145 146 // Pointer back to the object that contains us. We send buffers here. 147 OMXNodeInstance* mNodeInstance; 148 149 // Set by omxExecuting() / omxIdling(). 150 bool mExecuting; 151 152 // We consume graphic buffers from this. 153 sp<BufferQueue> mBufferQueue; 154 155 // Number of frames pending in BufferQueue that haven't yet been 156 // forwarded to the codec. 157 size_t mNumFramesAvailable; 158 159 // Set to true if we want to send end-of-stream after we run out of 160 // frames in BufferQueue. 161 bool mEndOfStream; 162 bool mEndOfStreamSent; 163 164 // Cache of GraphicBuffers from the buffer queue. When the codec 165 // is done processing a GraphicBuffer, we can use this to map back 166 // to a slot number. 167 sp<GraphicBuffer> mBufferSlot[BufferQueue::NUM_BUFFER_SLOTS]; 168 169 // Tracks codec buffers. 170 Vector<CodecBuffer> mCodecBuffers; 171 172 DISALLOW_EVIL_CONSTRUCTORS(GraphicBufferSource); 173}; 174 175} // namespace android 176 177#endif // GRAPHIC_BUFFER_SOURCE_H_ 178