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