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 24 #include <media/stagefright/foundation/ADebug.h> 25 #include <media/stagefright/foundation/AString.h> 26 #include <ui/Fence.h> 27 #include <ui/GraphicBuffer.h> 28 29 #include <list> 30 31 struct ANativeWindowBuffer; 32 33 namespace android { 34 35 struct FrameRenderTracker { 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, 62 const sp<Fence> &fence) 63 : mMediaTimeUs(mediaTimeUs), 64 mRenderTimeNs(-1), 65 mIndex(-1), 66 mGraphicBuffer(graphicBuffer), 67 mFence(fence) { 68 } 69 70 // creates information for a frame rendered on a tunneled surface InfoFrameRenderTracker::Info71 Info(int64_t mediaTimeUs, nsecs_t renderTimeNs) 72 : mMediaTimeUs(mediaTimeUs), 73 mRenderTimeNs(renderTimeNs), 74 mIndex(-1), 75 mGraphicBuffer(NULL), 76 mFence(NULL) { 77 } 78 79 private: 80 int64_t mMediaTimeUs; 81 nsecs_t mRenderTimeNs; 82 ssize_t mIndex; // to be used by client 83 sp<GraphicBuffer> mGraphicBuffer; 84 sp<Fence> mFence; 85 86 friend struct FrameRenderTracker; 87 }; 88 89 FrameRenderTracker(); 90 91 void setComponentName(const AString &componentName); 92 93 // clears all tracked frames, and resets last render time 94 void clear(nsecs_t lastRenderTimeNs); 95 96 // called when |graphicBuffer| corresponding to |mediaTimeUs| is 97 // queued to the output surface using |fence|. 98 void onFrameQueued( 99 int64_t mediaTimeUs, const sp<GraphicBuffer> &graphicBuffer, const sp<Fence> &fence); 100 101 // Called when we have dequeued a buffer |buf| from the native window to track render info. 102 // |fenceFd| is the dequeue fence, and |index| is a positive buffer ID to be usable by the 103 // client to track this render info among the dequeued buffers. 104 // Returns pointer to the tracked info, or NULL if buffer is not tracked or if |index| 105 // is negative. 106 Info *updateInfoForDequeuedBuffer(ANativeWindowBuffer *buf, int fenceFd, int index); 107 108 // called when tunneled codec signals frame rendered event 109 // returns BAD_VALUE if systemNano is not monotonic. Otherwise, returns OK. 110 status_t onFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano); 111 112 // Checks to see if any frames have rendered up until |until|. If |until| is NULL or not a 113 // tracked info, this method searches the entire render queue. 114 // Returns list of rendered frames up-until the frame pointed to by |until| or the first 115 // unrendered frame, as well as any dropped frames (those with invalid fence) up-until |until|. 116 // These frames are removed from the render queue. 117 // If |dropIncomplete| is true, unrendered frames up-until |until| will also be dropped from the 118 // queue, allowing all rendered framed up till then to be notified of. 119 // (This will effectively clear the render queue up-until (and including) |until|.) 120 std::list<Info> checkFencesAndGetRenderedFrames(const Info *until, bool dropIncomplete); 121 122 // Stop tracking a queued frame (e.g. if the frame has been discarded). If |info| is NULL or is 123 // not tracked, this method is a no-op. If |index| is specified, all indices larger that |index| 124 // are decremented. This is useful if the untracked frame is deleted from the frame vector. 125 void untrackFrame(const Info *info, ssize_t index = SSIZE_MAX); 126 127 void dumpRenderQueue() const; 128 129 virtual ~FrameRenderTracker(); 130 131 private: 132 133 // Render information for buffers. Regular surface buffers are queued in the order of 134 // rendering. Tunneled buffers are queued in the order of receipt. 135 std::list<Info> mRenderQueue; 136 nsecs_t mLastRenderTimeNs; 137 AString mComponentName; 138 139 DISALLOW_EVIL_CONSTRUCTORS(FrameRenderTracker); 140 }; 141 142 } // namespace android 143 144 #endif // FRAME_RENDER_TRACKER_H_ 145