blob: 6cbf85dc6916a1cbc7da4971dd96aecb0cf412cb [file] [log] [blame]
* Copyright 2015 The Android Open Source Project
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* See the License for the specific language governing permissions and
* limitations under the License.
#include <utils/RefBase.h>
#include <utils/Timers.h>
#include <system/window.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/AString.h>
#include <list>
namespace android {
class Fence;
class GraphicBuffer;
// Tracks the render information about a frame. Frames go through several states while
// the render information is tracked:
// 1. queued frame: mMediaTime and mGraphicBuffer are set for the frame. mFence is the
// queue fence (read fence). mIndex is negative, and mRenderTimeNs is invalid.
// Key characteristics: mFence is not NULL and mIndex is negative.
// 2. dequeued frame: mFence is updated with the dequeue fence (write fence). mIndex is set.
// Key characteristics: mFence is not NULL and mIndex is non-negative. mRenderTime is still
// invalid.
// 3. rendered frame or frame: mFence is cleared, mRenderTimeNs is set.
// Key characteristics: mFence is NULL.
struct RenderedFrameInfo {
// set by client during onFrameQueued or onFrameRendered
int64_t getMediaTimeUs() const { return mMediaTimeUs; }
// -1 if frame is not yet rendered
nsecs_t getRenderTimeNs() const { return mRenderTimeNs; }
// set by client during updateRenderInfoForDequeuedBuffer; -1 otherwise
ssize_t getIndex() const { return mIndex; }
// creates information for a queued frame
RenderedFrameInfo(int64_t mediaTimeUs, const sp<GraphicBuffer> &graphicBuffer,
const sp<Fence> &fence)
: mMediaTimeUs(mediaTimeUs),
mFence(fence) {
// creates information for a frame rendered on a tunneled surface
RenderedFrameInfo(int64_t mediaTimeUs, nsecs_t renderTimeNs)
: mMediaTimeUs(mediaTimeUs),
mFence(NULL) {
int64_t mMediaTimeUs;
nsecs_t mRenderTimeNs;
ssize_t mIndex; // to be used by client
sp<GraphicBuffer> mGraphicBuffer;
sp<Fence> mFence;
friend struct FrameRenderTracker;
struct FrameRenderTracker {
typedef RenderedFrameInfo Info;
void setComponentName(const AString &componentName);
// clears all tracked frames, and resets last render time
void clear(nsecs_t lastRenderTimeNs);
// called when |graphicBuffer| corresponding to |mediaTimeUs| is
// queued to the output surface using |fence|.
void onFrameQueued(
int64_t mediaTimeUs, const sp<GraphicBuffer> &graphicBuffer, const sp<Fence> &fence);
// Called when we have dequeued a buffer |buf| from the native window to track render info.
// |fenceFd| is the dequeue fence, and |index| is a positive buffer ID to be usable by the
// client to track this render info among the dequeued buffers.
// Returns pointer to the tracked info, or NULL if buffer is not tracked or if |index|
// is negative.
Info *updateInfoForDequeuedBuffer(ANativeWindowBuffer *buf, int fenceFd, int index);
// called when tunneled codec signals frame rendered event
// returns BAD_VALUE if systemNano is not monotonic. Otherwise, returns OK.
status_t onFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano);
// Checks to see if any frames have rendered up until |until|. If |until| is NULL or not a
// tracked info, this method searches the entire render queue.
// Returns list of rendered frames up-until the frame pointed to by |until| or the first
// unrendered frame, as well as any dropped frames (those with invalid fence) up-until |until|.
// These frames are removed from the render queue.
// If |dropIncomplete| is true, unrendered frames up-until |until| will also be dropped from the
// queue, allowing all rendered framed up till then to be notified of.
// (This will effectively clear the render queue up-until (and including) |until|.)
std::list<Info> checkFencesAndGetRenderedFrames(const Info *until, bool dropIncomplete);
// Stop tracking a queued frame (e.g. if the frame has been discarded). If |info| is NULL or is
// not tracked, this method is a no-op. If |index| is specified, all indices larger that |index|
// are decremented. This is useful if the untracked frame is deleted from the frame vector.
void untrackFrame(const Info *info, ssize_t index = SSIZE_MAX);
void dumpRenderQueue() const;
virtual ~FrameRenderTracker();
// Render information for buffers. Regular surface buffers are queued in the order of
// rendering. Tunneled buffers are queued in the order of receipt.
std::list<Info> mRenderQueue;
nsecs_t mLastRenderTimeNs;
AString mComponentName;
} // namespace android