GraphicBufferSource.h revision 8bd4d16aa5636e98522c07ae31236420788aa749
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    // Called when omx_message::FILL_BUFFER_DONE is received. (Currently the
91    // buffer source will fix timestamp in the header if needed.)
92    void codecBufferFilled(OMX_BUFFERHEADERTYPE* header);
93
94    // This is called after the last input frame has been submitted.  We
95    // need to submit an empty buffer with the EOS flag set.  If we don't
96    // have a codec buffer ready, we just set the mEndOfStream flag.
97    status_t signalEndOfInputStream();
98
99    // If suspend is true, all incoming buffers (including those currently
100    // in the BufferQueue) will be discarded until the suspension is lifted.
101    void suspend(bool suspend);
102
103    // Specifies the interval after which we requeue the buffer previously
104    // queued to the encoder. This is useful in the case of surface flinger
105    // providing the input surface if the resulting encoded stream is to
106    // be displayed "live". If we were not to push through the extra frame
107    // the decoder on the remote end would be unable to decode the latest frame.
108    // This API must be called before transitioning the encoder to "executing"
109    // state and once this behaviour is specified it cannot be reset.
110    status_t setRepeatPreviousFrameDelayUs(int64_t repeatAfterUs);
111
112    // When set, the timestamp fed to the encoder will be modified such that
113    // the gap between two adjacent frames is capped at maxGapUs. Timestamp
114    // will be restored to the original when the encoded frame is returned to
115    // the client.
116    // This is to solve a problem in certain real-time streaming case, where
117    // encoder's rate control logic produces huge frames after a long period
118    // of suspension on input.
119    status_t setMaxTimestampGapUs(int64_t maxGapUs);
120
121protected:
122    // BufferQueue::ConsumerListener interface, called when a new frame of
123    // data is available.  If we're executing and a codec buffer is
124    // available, we acquire the buffer, copy the GraphicBuffer reference
125    // into the codec buffer, and call Empty[This]Buffer.  If we're not yet
126    // executing or there's no codec buffer available, we just increment
127    // mNumFramesAvailable and return.
128    virtual void onFrameAvailable();
129
130    // BufferQueue::ConsumerListener interface, called when the client has
131    // released one or more GraphicBuffers.  We clear out the appropriate
132    // set of mBufferSlot entries.
133    virtual void onBuffersReleased();
134
135private:
136    // Keep track of codec input buffers.  They may either be available
137    // (mGraphicBuffer == NULL) or in use by the codec.
138    struct CodecBuffer {
139        OMX_BUFFERHEADERTYPE* mHeader;
140
141        // buffer producer's frame-number for buffer
142        uint64_t mFrameNumber;
143
144        // buffer producer's buffer slot for buffer
145        int mBuf;
146
147        sp<GraphicBuffer> mGraphicBuffer;
148    };
149
150    // Returns the index of an available codec buffer.  If none are
151    // available, returns -1.  Mutex must be held by caller.
152    int findAvailableCodecBuffer_l();
153
154    // Returns true if a codec buffer is available.
155    bool isCodecBufferAvailable_l() {
156        return findAvailableCodecBuffer_l() >= 0;
157    }
158
159    // Finds the mCodecBuffers entry that matches.  Returns -1 if not found.
160    int findMatchingCodecBuffer_l(const OMX_BUFFERHEADERTYPE* header);
161
162    // Fills a codec buffer with a frame from the BufferQueue.  This must
163    // only be called when we know that a frame of data is ready (i.e. we're
164    // in the onFrameAvailable callback, or if we're in codecBufferEmptied
165    // and mNumFramesAvailable is nonzero).  Returns without doing anything if
166    // we don't have a codec buffer available.
167    //
168    // Returns true if we successfully filled a codec buffer with a BQ buffer.
169    bool fillCodecBuffer_l();
170
171    // Marks the mCodecBuffers entry as in-use, copies the GraphicBuffer
172    // reference into the codec buffer, and submits the data to the codec.
173    status_t submitBuffer_l(const BufferQueue::BufferItem &item, int cbi);
174
175    // Submits an empty buffer, with the EOS flag set.   Returns without
176    // doing anything if we don't have a codec buffer available.
177    void submitEndOfInputStream_l();
178
179    void setLatestSubmittedBuffer_l(const BufferQueue::BufferItem &item);
180    bool repeatLatestSubmittedBuffer_l();
181    int64_t getTimestamp(const BufferQueue::BufferItem &item);
182
183    // Lock, covers all member variables.
184    mutable Mutex mMutex;
185
186    // Used to report constructor failure.
187    status_t mInitCheck;
188
189    // Pointer back to the object that contains us.  We send buffers here.
190    OMXNodeInstance* mNodeInstance;
191
192    // Set by omxExecuting() / omxIdling().
193    bool mExecuting;
194
195    bool mSuspended;
196
197    // We consume graphic buffers from this.
198    sp<BufferQueue> mBufferQueue;
199
200    // Number of frames pending in BufferQueue that haven't yet been
201    // forwarded to the codec.
202    size_t mNumFramesAvailable;
203
204    // Set to true if we want to send end-of-stream after we run out of
205    // frames in BufferQueue.
206    bool mEndOfStream;
207    bool mEndOfStreamSent;
208
209    // Cache of GraphicBuffers from the buffer queue.  When the codec
210    // is done processing a GraphicBuffer, we can use this to map back
211    // to a slot number.
212    sp<GraphicBuffer> mBufferSlot[BufferQueue::NUM_BUFFER_SLOTS];
213
214    // Tracks codec buffers.
215    Vector<CodecBuffer> mCodecBuffers;
216
217    ////
218    friend class AHandlerReflector<GraphicBufferSource>;
219
220    enum {
221        kWhatRepeatLastFrame,
222    };
223    enum {
224        kRepeatLastFrameCount = 10,
225    };
226    int64_t mRepeatAfterUs;
227    int64_t mMaxTimestampGapUs;
228
229    KeyedVector<int64_t, int64_t> mOriginalTimeUs;
230    int64_t mPrevOriginalTimeUs;
231    int64_t mPrevModifiedTimeUs;
232
233    sp<ALooper> mLooper;
234    sp<AHandlerReflector<GraphicBufferSource> > mReflector;
235
236    int32_t mRepeatLastFrameGeneration;
237    int64_t mRepeatLastFrameTimestamp;
238    int32_t mRepeatLastFrameCount;
239
240    int mLatestSubmittedBufferId;
241    uint64_t mLatestSubmittedBufferFrameNum;
242    int32_t mLatestSubmittedBufferUseCount;
243
244    // The previously submitted buffer should've been repeated but
245    // no codec buffer was available at the time.
246    bool mRepeatBufferDeferred;
247
248    void onMessageReceived(const sp<AMessage> &msg);
249
250    DISALLOW_EVIL_CONSTRUCTORS(GraphicBufferSource);
251};
252
253}  // namespace android
254
255#endif  // GRAPHIC_BUFFER_SOURCE_H_
256