1 /* 2 * Copyright 2015 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 FRAME_RENDER_TRACKER_H_ 18 19 #define FRAME_RENDER_TRACKER_H_ 20 21 #include <utils/RefBase.h> 22 #include <utils/Timers.h> 23 #include <system/window.h> 24 25 #include <media/stagefright/foundation/ADebug.h> 26 #include <media/stagefright/foundation/AString.h> 27 28 #include <list> 29 30 namespace android { 31 32 class Fence; 33 class GraphicBuffer; 34 35 struct FrameRenderTracker : public RefBase { 36 // Tracks the render information about a frame. Frames go through several states while 37 // the render information is tracked: 38 // 39 // 1. queued frame: mMediaTime and mGraphicBuffer are set for the frame. mFence is the 40 // queue fence (read fence). mIndex is negative, and mRenderTimeNs is invalid. 41 // Key characteristics: mFence is not NULL and mIndex is negative. 42 // 43 // 2. dequeued frame: mFence is updated with the dequeue fence (write fence). mIndex is set. 44 // Key characteristics: mFence is not NULL and mIndex is non-negative. mRenderTime is still 45 // invalid. 46 // 47 // 3. rendered frame or frame: mFence is cleared, mRenderTimeNs is set. 48 // Key characteristics: mFence is NULL. 49 // 50 struct Info { 51 // set by client during onFrameQueued or onFrameRendered getMediaTimeUsFrameRenderTracker::Info52 int64_t getMediaTimeUs() const { return mMediaTimeUs; } 53 54 // -1 if frame is not yet rendered getRenderTimeNsFrameRenderTracker::Info55 nsecs_t getRenderTimeNs() const { return mRenderTimeNs; } 56 57 // set by client during updateRenderInfoForDequeuedBuffer; -1 otherwise getIndexFrameRenderTracker::Info58 ssize_t getIndex() const { return mIndex; } 59 60 // creates information for a queued frame InfoFrameRenderTracker::Info61 Info(int64_t mediaTimeUs, const sp<GraphicBuffer> &graphicBuffer, const sp<Fence> &fence) 62 : mMediaTimeUs(mediaTimeUs), 63 mRenderTimeNs(-1), 64 mIndex(-1), 65 mGraphicBuffer(graphicBuffer), 66 mFence(fence) { 67 } 68 69 // creates information for a frame rendered on a tunneled surface InfoFrameRenderTracker::Info70 Info(int64_t mediaTimeUs, nsecs_t renderTimeNs) 71 : mMediaTimeUs(mediaTimeUs), 72 mRenderTimeNs(renderTimeNs), 73 mIndex(-1), 74 mGraphicBuffer(NULL), 75 mFence(NULL) { 76 } 77 78 private: 79 int64_t mMediaTimeUs; 80 nsecs_t mRenderTimeNs; 81 ssize_t mIndex; // to be used by client 82 sp<GraphicBuffer> mGraphicBuffer; 83 sp<Fence> mFence; 84 85 friend class FrameRenderTracker; 86 }; 87 88 FrameRenderTracker(); 89 90 void setComponentName(const AString &componentName); 91 92 // clears all tracked frames, and resets last render time 93 void clear(nsecs_t lastRenderTimeNs); 94 95 // called when |graphicBuffer| corresponding to |mediaTimeUs| is 96 // queued to the output surface using |fence|. 97 void onFrameQueued( 98 int64_t mediaTimeUs, const sp<GraphicBuffer> &graphicBuffer, const sp<Fence> &fence); 99 100 // Called when we have dequeued a buffer |buf| from the native window to track render info. 101 // |fenceFd| is the dequeue fence, and |index| is a positive buffer ID to be usable by the 102 // client to track this render info among the dequeued buffers. 103 // Returns pointer to the tracked info, or NULL if buffer is not tracked or if |index| 104 // is negative. 105 Info *updateInfoForDequeuedBuffer(ANativeWindowBuffer *buf, int fenceFd, int index); 106 107 // called when tunneled codec signals frame rendered event 108 // returns BAD_VALUE if systemNano is not monotonic. Otherwise, returns OK. 109 status_t onFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano); 110 111 // Checks to see if any frames have rendered up until |until|. If |until| is NULL or not a 112 // tracked info, this method searches the entire render queue. 113 // Returns list of rendered frames up-until the frame pointed to by |until| or the first 114 // unrendered frame, as well as any dropped frames (those with invalid fence) up-until |until|. 115 // These frames are removed from the render queue. 116 // If |dropIncomplete| is true, unrendered frames up-until |until| will also be dropped from the 117 // queue, allowing all rendered framed up till then to be notified of. 118 // (This will effectively clear the render queue up-until (and including) |until|.) 119 std::list<Info> checkFencesAndGetRenderedFrames(const Info *until, bool dropIncomplete); 120 121 // Stop tracking a queued frame (e.g. if the frame has been discarded). If |info| is NULL or is 122 // not tracked, this method is a no-op. If |index| is specified, all indices larger that |index| 123 // are decremented. This is useful if the untracked frame is deleted from the frame vector. 124 void untrackFrame(const Info *info, ssize_t index = SSIZE_MAX); 125 126 void dumpRenderQueue() const; 127 128 virtual ~FrameRenderTracker(); 129 130 private: 131 132 // Render information for buffers. Regular surface buffers are queued in the order of 133 // rendering. Tunneled buffers are queued in the order of receipt. 134 std::list<Info> mRenderQueue; 135 nsecs_t mLastRenderTimeNs; 136 AString mComponentName; 137 138 DISALLOW_EVIL_CONSTRUCTORS(FrameRenderTracker); 139 }; 140 141 } // namespace android 142 143 #endif // FRAME_RENDER_TRACKER_H_ 144