diff --git a/arm/arch-arm-armv7-a-neon/shared/vndk-core/libui.so b/arm/arch-arm-armv7-a-neon/shared/vndk-core/libui.so index c09a87255ca7924bcfe43d15b269dc880d0ff986..5cceaa24a41dd114ede8e5429a03dc1fa39da75e 100755 Binary files a/arm/arch-arm-armv7-a-neon/shared/vndk-core/libui.so and b/arm/arch-arm-armv7-a-neon/shared/vndk-core/libui.so differ diff --git a/arm/include/frameworks/av/media/libstagefright/include/media/stagefright/VideoRenderQualityTracker.h b/arm/include/frameworks/av/media/libstagefright/include/media/stagefright/VideoRenderQualityTracker.h index 5cf674fad13f6fd67000013564c4056f6eb07455..82ba81caa1708dbeebe736371dd8006802e112af 100644 --- a/arm/include/frameworks/av/media/libstagefright/include/media/stagefright/VideoRenderQualityTracker.h +++ b/arm/include/frameworks/av/media/libstagefright/include/media/stagefright/VideoRenderQualityTracker.h @@ -62,20 +62,37 @@ struct VideoRenderQualityMetrics { // A histogram of the durations of freezes due to dropped/skipped frames. MediaHistogram<int32_t> freezeDurationMsHistogram; - // The computed overall freeze score using the above histogram and score conversion table. + // The computed overall freeze score using the above histogram and score conversion table. The + // score is based on counts in the histogram bucket, multiplied by the value in the score + // conversion table for that bucket. For example, the impact of a short freeze may be minimal, + // but the impact of long freeze may be disproportionally worse. Therefore, the score + // multipliers for each bucket might increase exponentially instead of linearly. A score + // multiplier of zero would reflect that small freeze durations have near-zero impact to the + // user experience. int32_t freezeScore; // The computed percentage of total playback duration that was frozen. float freezeRate; + // The number of freeze events. + int32_t freezeEventCount; // A histogram of the durations between each freeze. MediaHistogram<int32_t> freezeDistanceMsHistogram; - // A histogram of the judder scores. + // A histogram of the judder scores - based on the error tolerance between actual render + // duration of each frame and the ideal render duration. MediaHistogram<int32_t> judderScoreHistogram; - // The computed overall judder score using the above histogram and score conversion table. + // The computed overall judder score using the above histogram and score conversion table. The + // score is based on counts in the histogram bucket, multiplied by the value in the score + // conversion table for that bucket. For example, the impact of minimal judder may be small, + // but the impact of large judder may be disproportionally worse. Therefore, the score + // multipliers for each bucket might increase exponentially instead of linearly. A score + // multiplier of zero would reflect that small judder errors have near-zero impact to the user + // experience. int32_t judderScore; // The computed percentage of total frames that had judder. float judderRate; + // The number of judder events. + int32_t judderEventCount; }; /////////////////////////////////////////////////////// @@ -101,6 +118,15 @@ public: // Configurable elements of the metrics algorithms class Configuration { public: + // system/server_configurable_flags/libflags/include/get_flags.h:GetServerConfigurableFlag + typedef std::string (*GetServerConfigurableFlagFn)( + const std::string& experiment_category_name, + const std::string& experiment_flag_name, + const std::string& default_value); + + static Configuration getFromServerConfigurableFlags( + GetServerConfigurableFlagFn getServerConfigurableFlagFn); + Configuration(); // Whether or not frame render quality is tracked. @@ -124,27 +150,107 @@ public: // skip forward in content time is due to frame drops. If the app-desired frame duration is // short, but the content frame duration is large, it is assumed the app is intentionally // seeking forward. - int32_t contentTimeAdvancedForLiveContentToleranceUs; + int32_t liveContentFrameDropToleranceUs; // Freeze configuration // // The values used to distribute freeze durations across a histogram. std::vector<int32_t> freezeDurationMsHistogramBuckets; - // The values used to compare against freeze duration counts when determining an overall - // score. + // + // The values used to multiply the counts in the histogram buckets above to compute an + // overall score. This allows the score to reflect disproportionate impact as freeze + // durations increase. std::vector<int64_t> freezeDurationMsHistogramToScore; + // // The values used to distribute distances between freezes across a histogram. std::vector<int32_t> freezeDistanceMsHistogramBuckets; + // + // The maximum number of freeze events to send back to the caller. + int32_t freezeEventMax; + // + // The maximum number of detail entries tracked per freeze event. + int32_t freezeEventDetailsMax; + // + // The maximum distance in time between two freeze occurrences such that both will be + // lumped into the same freeze event. + int32_t freezeEventDistanceToleranceMs; // Judder configuration // // A judder error lower than this value is not scored as judder. int32_t judderErrorToleranceUs; + // // The values used to distribute judder scores across a histogram. std::vector<int32_t> judderScoreHistogramBuckets; - // The values used to compare against judder score histogram counts when determining an - // overall score. - std::vector<int32_t> judderScoreHistogramToScore; + // + // The values used to multiply the counts in the histogram buckets above to compute an + // overall score. This allows the score to reflect disproportionate impact as judder scores + // increase. + std::vector<int64_t> judderScoreHistogramToScore; + // + // The maximum number of judder events to send back to the caller. + int32_t judderEventMax; + // + // The maximum number of detail entries tracked per judder event. + int32_t judderEventDetailsMax; + // + // The maximum distance in time between two judder occurrences such that both will be + // lumped into the same judder event. + int32_t judderEventDistanceToleranceMs; + }; + + struct FreezeEvent { + // Details are captured for each freeze up to a limited number. The arrays are guaranteed to + // have the same size. + struct Details { + /// The duration of the freeze. + std::vector<int32_t> durationMs; + // The distance between the beginning of this freeze and the end of the previous freeze. + std::vector<int32_t> distanceMs; + }; + // Whether or not the data in this structure is valid. + bool valid = false; + // The time at which the first freeze for this event was detected. + int64_t initialTimeUs; + // The total duration from the beginning of the first freeze to the end of the last freeze + // in this event. + int32_t durationMs; + // The number of freezes in this event. + int64_t count; + // The sum of all durations of all freezes in this event. + int64_t sumDurationMs; + // The sum of all distances between each freeze in this event. + int64_t sumDistanceMs; + // Detailed information for the first N freezes in this event. + Details details; + }; + + struct JudderEvent { + // Details are captured for each frame judder up to a limited number. The arrays are + // guaranteed to have the same size. + struct Details { + // The actual render duration of the frame for this judder occurrence. + std::vector<int32_t> actualRenderDurationUs; + // The content render duration of the frame for this judder occurrence. + std::vector<int32_t> contentRenderDurationUs; + // The distance from this judder occurrence and the previous judder occurrence. + std::vector<int32_t> distanceMs; + }; + // Whether or not the data in this structure is valid. + bool valid = false; + // The time at which the first judder occurrence for this event was detected. + int64_t initialTimeUs; + // The total duration from the first judder occurrence to the last judder occurrence in this + // event. + int32_t durationMs; + // The number of judder occurrences in this event. + int64_t count; + // The sum of all judder scores in this event. + int64_t sumScore; + // The sum of all distances between each judder occurrence in this event. + int64_t sumDistanceMs; + // Detailed information for the first N judder occurrences in this event. + Details details; }; VideoRenderQualityTracker(); @@ -164,7 +270,16 @@ public: void onFrameReleased(int64_t contentTimeUs, int64_t desiredRenderTimeNs); // Called when the system has detected that the frame has actually been rendered to the display. - void onFrameRendered(int64_t contentTimeUs, int64_t actualRenderTimeNs); + // Returns any freeze events or judder events that were detected. + void onFrameRendered(int64_t contentTimeUs, int64_t actualRenderTimeNs, + FreezeEvent *freezeEventOut = nullptr, + JudderEvent *judderEventOut = nullptr); + + // Gets and resets data for the current freeze event. + FreezeEvent getAndResetFreezeEvent(); + + // Gets and resets data for the current judder event. + JudderEvent getAndResetJudderEvent(); // Retrieve the metrics. const VideoRenderQualityMetrics &getMetrics(); @@ -233,13 +348,31 @@ private: // Process a frame freeze. static void processFreeze(int64_t actualRenderTimeUs, int64_t lastRenderTimeUs, - int64_t lastFreezeEndTimeUs, VideoRenderQualityMetrics &m); + int64_t lastFreezeEndTimeUs, FreezeEvent &e, + VideoRenderQualityMetrics &m, const Configuration &c); + + // Retrieve a freeze event if an event just finished. + static void maybeCaptureFreezeEvent(int64_t actualRenderTimeUs, int64_t lastFreezeEndTimeUs, + FreezeEvent &e, const VideoRenderQualityMetrics & m, + const Configuration &c, FreezeEvent *freezeEventOut); // Compute a judder score for the previously-rendered frame. static int64_t computePreviousJudderScore(const FrameDurationUs &actualRenderDurationUs, const FrameDurationUs &contentRenderDurationUs, const Configuration &c); + // Process a frame judder. + static void processJudder(int32_t judderScore, int64_t judderTimeUs, + int64_t lastJudderEndTimeUs, + const FrameDurationUs &contentDurationUs, + const FrameDurationUs &actualDurationUs, JudderEvent &e, + VideoRenderQualityMetrics &m, const Configuration &c); + + // Retrieve a judder event if an event just finished. + static void maybeCaptureJudderEvent(int64_t actualRenderTimeUs, int64_t lastJudderEndTimeUs, + JudderEvent &e, const VideoRenderQualityMetrics & m, + const Configuration &c, JudderEvent *judderEventOut); + // Check to see if a discontinuity has occurred by examining the content time and the // app-desired render time. If so, reset some internal state. bool resetIfDiscontinuity(int64_t contentTimeUs, int64_t desiredRenderTimeUs); @@ -252,7 +385,8 @@ private: // Update the metrics because a rendered frame was detected. void processMetricsForRenderedFrame(int64_t contentTimeUs, int64_t desiredRenderTimeUs, - int64_t actualRenderTimeUs); + int64_t actualRenderTimeUs, + FreezeEvent *freezeEventOut, JudderEvent *judderEventOut); // Configurable elements of the metrics algorithms. const Configuration mConfiguration; @@ -269,12 +403,21 @@ private: // The most recent timestamp of the first frame rendered after the freeze. int64_t mLastFreezeEndTimeUs; - // The previous video frame was dropped. - bool mWasPreviousFrameDropped; + // The most recent timestamp of frame judder. + int64_t mLastJudderEndTimeUs; // The render duration of the playback. int64_t mRenderDurationMs; + // True if the previous frame was dropped. + bool mWasPreviousFrameDropped; + + // The freeze event that's currently being tracked. + FreezeEvent mFreezeEvent; + + // The judder event that's currently being tracked. + JudderEvent mJudderEvent; + // Frames skipped at the end of playback shouldn't really be considered skipped, therefore keep // a list of the frames, and process them as skipped frames the next time a frame is rendered. std::list<int64_t> mPendingSkippedFrameContentTimeUsList; diff --git a/arm/include/frameworks/av/media/ndk/include/media/NdkImage.h b/arm/include/frameworks/av/media/ndk/include/media/NdkImage.h index 814a327e94a820f5514dfce296288b230583481c..76270d3069b1d49da928e7021d8daf8987af30d1 100644 --- a/arm/include/frameworks/av/media/ndk/include/media/NdkImage.h +++ b/arm/include/frameworks/av/media/ndk/include/media/NdkImage.h @@ -829,7 +829,7 @@ media_status_t AImage_getHardwareBuffer(const AImage* image, /*out*/AHardwareBuf /** * Query the dataspace of the input {@link AImage}. * - * Available since API level 33. + * Available since API level 34. * * @param image the {@link AImage} of interest. * @param dataSpace the dataspace of the image will be filled here if the method call succeeds. @@ -843,7 +843,7 @@ media_status_t AImage_getHardwareBuffer(const AImage* image, /*out*/AHardwareBuf * image has been deleted.</li></ul> */ media_status_t AImage_getDataSpace(const AImage* image, - /*out*/int32_t* dataSpace) __INTRODUCED_IN(33); + /*out*/int32_t* dataSpace) __INTRODUCED_IN(34); __END_DECLS diff --git a/arm/include/frameworks/av/media/ndk/include/media/NdkImageReader.h b/arm/include/frameworks/av/media/ndk/include/media/NdkImageReader.h index 992955bb4a8bc722694c7ff141ae787a550fedb2..b6dcaaed0eb1f2261056d112f3d5af3192be9a86 100644 --- a/arm/include/frameworks/av/media/ndk/include/media/NdkImageReader.h +++ b/arm/include/frameworks/av/media/ndk/include/media/NdkImageReader.h @@ -395,7 +395,7 @@ media_status_t AImageReader_newWithUsage( * the combination of {@code hardwareBufferFormat} and {@code dataSpace} for the * format of the Image that the reader will produce.</p> * - * Available since API level 33. + * Available since API level 34. * * @param width The default width in pixels of the Images that this reader will produce. * @param height The default height in pixels of the Images that this reader will produce. @@ -422,7 +422,7 @@ media_status_t AImageReader_newWithUsage( */ media_status_t AImageReader_newWithDataSpace(int32_t width, int32_t height, uint64_t usage, int32_t maxImages, uint32_t hardwareBufferFormat, int32_t dataSpace, - /*out*/ AImageReader** reader) __INTRODUCED_IN(33); + /*out*/ AImageReader** reader) __INTRODUCED_IN(34); /** * Acquire the next {@link AImage} from the image reader's queue asynchronously. diff --git a/arm64/arch-arm-armv8-a/shared/vndk-core/libui.so b/arm64/arch-arm-armv8-a/shared/vndk-core/libui.so index 2eee58660a64c14a0756e738ca52a6c14ab7aeec..7647c4bdcf064d3c817c38240add3743c02412f4 100755 Binary files a/arm64/arch-arm-armv8-a/shared/vndk-core/libui.so and b/arm64/arch-arm-armv8-a/shared/vndk-core/libui.so differ diff --git a/arm64/arch-arm64-armv8-a/shared/vndk-core/libui.so b/arm64/arch-arm64-armv8-a/shared/vndk-core/libui.so index d814dc3afaf3bc0ac4e741a5aaa3fa70b0d8e15c..2481260f2158cfc743144c4f7c1c0617be82f6ec 100755 Binary files a/arm64/arch-arm64-armv8-a/shared/vndk-core/libui.so and b/arm64/arch-arm64-armv8-a/shared/vndk-core/libui.so differ diff --git a/arm64/include/frameworks/av/media/libstagefright/include/media/stagefright/VideoRenderQualityTracker.h b/arm64/include/frameworks/av/media/libstagefright/include/media/stagefright/VideoRenderQualityTracker.h index 5cf674fad13f6fd67000013564c4056f6eb07455..82ba81caa1708dbeebe736371dd8006802e112af 100644 --- a/arm64/include/frameworks/av/media/libstagefright/include/media/stagefright/VideoRenderQualityTracker.h +++ b/arm64/include/frameworks/av/media/libstagefright/include/media/stagefright/VideoRenderQualityTracker.h @@ -62,20 +62,37 @@ struct VideoRenderQualityMetrics { // A histogram of the durations of freezes due to dropped/skipped frames. MediaHistogram<int32_t> freezeDurationMsHistogram; - // The computed overall freeze score using the above histogram and score conversion table. + // The computed overall freeze score using the above histogram and score conversion table. The + // score is based on counts in the histogram bucket, multiplied by the value in the score + // conversion table for that bucket. For example, the impact of a short freeze may be minimal, + // but the impact of long freeze may be disproportionally worse. Therefore, the score + // multipliers for each bucket might increase exponentially instead of linearly. A score + // multiplier of zero would reflect that small freeze durations have near-zero impact to the + // user experience. int32_t freezeScore; // The computed percentage of total playback duration that was frozen. float freezeRate; + // The number of freeze events. + int32_t freezeEventCount; // A histogram of the durations between each freeze. MediaHistogram<int32_t> freezeDistanceMsHistogram; - // A histogram of the judder scores. + // A histogram of the judder scores - based on the error tolerance between actual render + // duration of each frame and the ideal render duration. MediaHistogram<int32_t> judderScoreHistogram; - // The computed overall judder score using the above histogram and score conversion table. + // The computed overall judder score using the above histogram and score conversion table. The + // score is based on counts in the histogram bucket, multiplied by the value in the score + // conversion table for that bucket. For example, the impact of minimal judder may be small, + // but the impact of large judder may be disproportionally worse. Therefore, the score + // multipliers for each bucket might increase exponentially instead of linearly. A score + // multiplier of zero would reflect that small judder errors have near-zero impact to the user + // experience. int32_t judderScore; // The computed percentage of total frames that had judder. float judderRate; + // The number of judder events. + int32_t judderEventCount; }; /////////////////////////////////////////////////////// @@ -101,6 +118,15 @@ public: // Configurable elements of the metrics algorithms class Configuration { public: + // system/server_configurable_flags/libflags/include/get_flags.h:GetServerConfigurableFlag + typedef std::string (*GetServerConfigurableFlagFn)( + const std::string& experiment_category_name, + const std::string& experiment_flag_name, + const std::string& default_value); + + static Configuration getFromServerConfigurableFlags( + GetServerConfigurableFlagFn getServerConfigurableFlagFn); + Configuration(); // Whether or not frame render quality is tracked. @@ -124,27 +150,107 @@ public: // skip forward in content time is due to frame drops. If the app-desired frame duration is // short, but the content frame duration is large, it is assumed the app is intentionally // seeking forward. - int32_t contentTimeAdvancedForLiveContentToleranceUs; + int32_t liveContentFrameDropToleranceUs; // Freeze configuration // // The values used to distribute freeze durations across a histogram. std::vector<int32_t> freezeDurationMsHistogramBuckets; - // The values used to compare against freeze duration counts when determining an overall - // score. + // + // The values used to multiply the counts in the histogram buckets above to compute an + // overall score. This allows the score to reflect disproportionate impact as freeze + // durations increase. std::vector<int64_t> freezeDurationMsHistogramToScore; + // // The values used to distribute distances between freezes across a histogram. std::vector<int32_t> freezeDistanceMsHistogramBuckets; + // + // The maximum number of freeze events to send back to the caller. + int32_t freezeEventMax; + // + // The maximum number of detail entries tracked per freeze event. + int32_t freezeEventDetailsMax; + // + // The maximum distance in time between two freeze occurrences such that both will be + // lumped into the same freeze event. + int32_t freezeEventDistanceToleranceMs; // Judder configuration // // A judder error lower than this value is not scored as judder. int32_t judderErrorToleranceUs; + // // The values used to distribute judder scores across a histogram. std::vector<int32_t> judderScoreHistogramBuckets; - // The values used to compare against judder score histogram counts when determining an - // overall score. - std::vector<int32_t> judderScoreHistogramToScore; + // + // The values used to multiply the counts in the histogram buckets above to compute an + // overall score. This allows the score to reflect disproportionate impact as judder scores + // increase. + std::vector<int64_t> judderScoreHistogramToScore; + // + // The maximum number of judder events to send back to the caller. + int32_t judderEventMax; + // + // The maximum number of detail entries tracked per judder event. + int32_t judderEventDetailsMax; + // + // The maximum distance in time between two judder occurrences such that both will be + // lumped into the same judder event. + int32_t judderEventDistanceToleranceMs; + }; + + struct FreezeEvent { + // Details are captured for each freeze up to a limited number. The arrays are guaranteed to + // have the same size. + struct Details { + /// The duration of the freeze. + std::vector<int32_t> durationMs; + // The distance between the beginning of this freeze and the end of the previous freeze. + std::vector<int32_t> distanceMs; + }; + // Whether or not the data in this structure is valid. + bool valid = false; + // The time at which the first freeze for this event was detected. + int64_t initialTimeUs; + // The total duration from the beginning of the first freeze to the end of the last freeze + // in this event. + int32_t durationMs; + // The number of freezes in this event. + int64_t count; + // The sum of all durations of all freezes in this event. + int64_t sumDurationMs; + // The sum of all distances between each freeze in this event. + int64_t sumDistanceMs; + // Detailed information for the first N freezes in this event. + Details details; + }; + + struct JudderEvent { + // Details are captured for each frame judder up to a limited number. The arrays are + // guaranteed to have the same size. + struct Details { + // The actual render duration of the frame for this judder occurrence. + std::vector<int32_t> actualRenderDurationUs; + // The content render duration of the frame for this judder occurrence. + std::vector<int32_t> contentRenderDurationUs; + // The distance from this judder occurrence and the previous judder occurrence. + std::vector<int32_t> distanceMs; + }; + // Whether or not the data in this structure is valid. + bool valid = false; + // The time at which the first judder occurrence for this event was detected. + int64_t initialTimeUs; + // The total duration from the first judder occurrence to the last judder occurrence in this + // event. + int32_t durationMs; + // The number of judder occurrences in this event. + int64_t count; + // The sum of all judder scores in this event. + int64_t sumScore; + // The sum of all distances between each judder occurrence in this event. + int64_t sumDistanceMs; + // Detailed information for the first N judder occurrences in this event. + Details details; }; VideoRenderQualityTracker(); @@ -164,7 +270,16 @@ public: void onFrameReleased(int64_t contentTimeUs, int64_t desiredRenderTimeNs); // Called when the system has detected that the frame has actually been rendered to the display. - void onFrameRendered(int64_t contentTimeUs, int64_t actualRenderTimeNs); + // Returns any freeze events or judder events that were detected. + void onFrameRendered(int64_t contentTimeUs, int64_t actualRenderTimeNs, + FreezeEvent *freezeEventOut = nullptr, + JudderEvent *judderEventOut = nullptr); + + // Gets and resets data for the current freeze event. + FreezeEvent getAndResetFreezeEvent(); + + // Gets and resets data for the current judder event. + JudderEvent getAndResetJudderEvent(); // Retrieve the metrics. const VideoRenderQualityMetrics &getMetrics(); @@ -233,13 +348,31 @@ private: // Process a frame freeze. static void processFreeze(int64_t actualRenderTimeUs, int64_t lastRenderTimeUs, - int64_t lastFreezeEndTimeUs, VideoRenderQualityMetrics &m); + int64_t lastFreezeEndTimeUs, FreezeEvent &e, + VideoRenderQualityMetrics &m, const Configuration &c); + + // Retrieve a freeze event if an event just finished. + static void maybeCaptureFreezeEvent(int64_t actualRenderTimeUs, int64_t lastFreezeEndTimeUs, + FreezeEvent &e, const VideoRenderQualityMetrics & m, + const Configuration &c, FreezeEvent *freezeEventOut); // Compute a judder score for the previously-rendered frame. static int64_t computePreviousJudderScore(const FrameDurationUs &actualRenderDurationUs, const FrameDurationUs &contentRenderDurationUs, const Configuration &c); + // Process a frame judder. + static void processJudder(int32_t judderScore, int64_t judderTimeUs, + int64_t lastJudderEndTimeUs, + const FrameDurationUs &contentDurationUs, + const FrameDurationUs &actualDurationUs, JudderEvent &e, + VideoRenderQualityMetrics &m, const Configuration &c); + + // Retrieve a judder event if an event just finished. + static void maybeCaptureJudderEvent(int64_t actualRenderTimeUs, int64_t lastJudderEndTimeUs, + JudderEvent &e, const VideoRenderQualityMetrics & m, + const Configuration &c, JudderEvent *judderEventOut); + // Check to see if a discontinuity has occurred by examining the content time and the // app-desired render time. If so, reset some internal state. bool resetIfDiscontinuity(int64_t contentTimeUs, int64_t desiredRenderTimeUs); @@ -252,7 +385,8 @@ private: // Update the metrics because a rendered frame was detected. void processMetricsForRenderedFrame(int64_t contentTimeUs, int64_t desiredRenderTimeUs, - int64_t actualRenderTimeUs); + int64_t actualRenderTimeUs, + FreezeEvent *freezeEventOut, JudderEvent *judderEventOut); // Configurable elements of the metrics algorithms. const Configuration mConfiguration; @@ -269,12 +403,21 @@ private: // The most recent timestamp of the first frame rendered after the freeze. int64_t mLastFreezeEndTimeUs; - // The previous video frame was dropped. - bool mWasPreviousFrameDropped; + // The most recent timestamp of frame judder. + int64_t mLastJudderEndTimeUs; // The render duration of the playback. int64_t mRenderDurationMs; + // True if the previous frame was dropped. + bool mWasPreviousFrameDropped; + + // The freeze event that's currently being tracked. + FreezeEvent mFreezeEvent; + + // The judder event that's currently being tracked. + JudderEvent mJudderEvent; + // Frames skipped at the end of playback shouldn't really be considered skipped, therefore keep // a list of the frames, and process them as skipped frames the next time a frame is rendered. std::list<int64_t> mPendingSkippedFrameContentTimeUsList; diff --git a/arm64/include/frameworks/av/media/ndk/include/media/NdkImage.h b/arm64/include/frameworks/av/media/ndk/include/media/NdkImage.h index 814a327e94a820f5514dfce296288b230583481c..76270d3069b1d49da928e7021d8daf8987af30d1 100644 --- a/arm64/include/frameworks/av/media/ndk/include/media/NdkImage.h +++ b/arm64/include/frameworks/av/media/ndk/include/media/NdkImage.h @@ -829,7 +829,7 @@ media_status_t AImage_getHardwareBuffer(const AImage* image, /*out*/AHardwareBuf /** * Query the dataspace of the input {@link AImage}. * - * Available since API level 33. + * Available since API level 34. * * @param image the {@link AImage} of interest. * @param dataSpace the dataspace of the image will be filled here if the method call succeeds. @@ -843,7 +843,7 @@ media_status_t AImage_getHardwareBuffer(const AImage* image, /*out*/AHardwareBuf * image has been deleted.</li></ul> */ media_status_t AImage_getDataSpace(const AImage* image, - /*out*/int32_t* dataSpace) __INTRODUCED_IN(33); + /*out*/int32_t* dataSpace) __INTRODUCED_IN(34); __END_DECLS diff --git a/arm64/include/frameworks/av/media/ndk/include/media/NdkImageReader.h b/arm64/include/frameworks/av/media/ndk/include/media/NdkImageReader.h index 992955bb4a8bc722694c7ff141ae787a550fedb2..b6dcaaed0eb1f2261056d112f3d5af3192be9a86 100644 --- a/arm64/include/frameworks/av/media/ndk/include/media/NdkImageReader.h +++ b/arm64/include/frameworks/av/media/ndk/include/media/NdkImageReader.h @@ -395,7 +395,7 @@ media_status_t AImageReader_newWithUsage( * the combination of {@code hardwareBufferFormat} and {@code dataSpace} for the * format of the Image that the reader will produce.</p> * - * Available since API level 33. + * Available since API level 34. * * @param width The default width in pixels of the Images that this reader will produce. * @param height The default height in pixels of the Images that this reader will produce. @@ -422,7 +422,7 @@ media_status_t AImageReader_newWithUsage( */ media_status_t AImageReader_newWithDataSpace(int32_t width, int32_t height, uint64_t usage, int32_t maxImages, uint32_t hardwareBufferFormat, int32_t dataSpace, - /*out*/ AImageReader** reader) __INTRODUCED_IN(33); + /*out*/ AImageReader** reader) __INTRODUCED_IN(34); /** * Acquire the next {@link AImage} from the image reader's queue asynchronously. diff --git a/x86/arch-x86/shared/vndk-core/libui.so b/x86/arch-x86/shared/vndk-core/libui.so index da280ffd3127ac13225d7099152874c197060ff8..7822b01711ab7e66789be0b514a4ec6ffd751068 100755 Binary files a/x86/arch-x86/shared/vndk-core/libui.so and b/x86/arch-x86/shared/vndk-core/libui.so differ diff --git a/x86/include/frameworks/av/media/libstagefright/include/media/stagefright/VideoRenderQualityTracker.h b/x86/include/frameworks/av/media/libstagefright/include/media/stagefright/VideoRenderQualityTracker.h index 5cf674fad13f6fd67000013564c4056f6eb07455..82ba81caa1708dbeebe736371dd8006802e112af 100644 --- a/x86/include/frameworks/av/media/libstagefright/include/media/stagefright/VideoRenderQualityTracker.h +++ b/x86/include/frameworks/av/media/libstagefright/include/media/stagefright/VideoRenderQualityTracker.h @@ -62,20 +62,37 @@ struct VideoRenderQualityMetrics { // A histogram of the durations of freezes due to dropped/skipped frames. MediaHistogram<int32_t> freezeDurationMsHistogram; - // The computed overall freeze score using the above histogram and score conversion table. + // The computed overall freeze score using the above histogram and score conversion table. The + // score is based on counts in the histogram bucket, multiplied by the value in the score + // conversion table for that bucket. For example, the impact of a short freeze may be minimal, + // but the impact of long freeze may be disproportionally worse. Therefore, the score + // multipliers for each bucket might increase exponentially instead of linearly. A score + // multiplier of zero would reflect that small freeze durations have near-zero impact to the + // user experience. int32_t freezeScore; // The computed percentage of total playback duration that was frozen. float freezeRate; + // The number of freeze events. + int32_t freezeEventCount; // A histogram of the durations between each freeze. MediaHistogram<int32_t> freezeDistanceMsHistogram; - // A histogram of the judder scores. + // A histogram of the judder scores - based on the error tolerance between actual render + // duration of each frame and the ideal render duration. MediaHistogram<int32_t> judderScoreHistogram; - // The computed overall judder score using the above histogram and score conversion table. + // The computed overall judder score using the above histogram and score conversion table. The + // score is based on counts in the histogram bucket, multiplied by the value in the score + // conversion table for that bucket. For example, the impact of minimal judder may be small, + // but the impact of large judder may be disproportionally worse. Therefore, the score + // multipliers for each bucket might increase exponentially instead of linearly. A score + // multiplier of zero would reflect that small judder errors have near-zero impact to the user + // experience. int32_t judderScore; // The computed percentage of total frames that had judder. float judderRate; + // The number of judder events. + int32_t judderEventCount; }; /////////////////////////////////////////////////////// @@ -101,6 +118,15 @@ public: // Configurable elements of the metrics algorithms class Configuration { public: + // system/server_configurable_flags/libflags/include/get_flags.h:GetServerConfigurableFlag + typedef std::string (*GetServerConfigurableFlagFn)( + const std::string& experiment_category_name, + const std::string& experiment_flag_name, + const std::string& default_value); + + static Configuration getFromServerConfigurableFlags( + GetServerConfigurableFlagFn getServerConfigurableFlagFn); + Configuration(); // Whether or not frame render quality is tracked. @@ -124,27 +150,107 @@ public: // skip forward in content time is due to frame drops. If the app-desired frame duration is // short, but the content frame duration is large, it is assumed the app is intentionally // seeking forward. - int32_t contentTimeAdvancedForLiveContentToleranceUs; + int32_t liveContentFrameDropToleranceUs; // Freeze configuration // // The values used to distribute freeze durations across a histogram. std::vector<int32_t> freezeDurationMsHistogramBuckets; - // The values used to compare against freeze duration counts when determining an overall - // score. + // + // The values used to multiply the counts in the histogram buckets above to compute an + // overall score. This allows the score to reflect disproportionate impact as freeze + // durations increase. std::vector<int64_t> freezeDurationMsHistogramToScore; + // // The values used to distribute distances between freezes across a histogram. std::vector<int32_t> freezeDistanceMsHistogramBuckets; + // + // The maximum number of freeze events to send back to the caller. + int32_t freezeEventMax; + // + // The maximum number of detail entries tracked per freeze event. + int32_t freezeEventDetailsMax; + // + // The maximum distance in time between two freeze occurrences such that both will be + // lumped into the same freeze event. + int32_t freezeEventDistanceToleranceMs; // Judder configuration // // A judder error lower than this value is not scored as judder. int32_t judderErrorToleranceUs; + // // The values used to distribute judder scores across a histogram. std::vector<int32_t> judderScoreHistogramBuckets; - // The values used to compare against judder score histogram counts when determining an - // overall score. - std::vector<int32_t> judderScoreHistogramToScore; + // + // The values used to multiply the counts in the histogram buckets above to compute an + // overall score. This allows the score to reflect disproportionate impact as judder scores + // increase. + std::vector<int64_t> judderScoreHistogramToScore; + // + // The maximum number of judder events to send back to the caller. + int32_t judderEventMax; + // + // The maximum number of detail entries tracked per judder event. + int32_t judderEventDetailsMax; + // + // The maximum distance in time between two judder occurrences such that both will be + // lumped into the same judder event. + int32_t judderEventDistanceToleranceMs; + }; + + struct FreezeEvent { + // Details are captured for each freeze up to a limited number. The arrays are guaranteed to + // have the same size. + struct Details { + /// The duration of the freeze. + std::vector<int32_t> durationMs; + // The distance between the beginning of this freeze and the end of the previous freeze. + std::vector<int32_t> distanceMs; + }; + // Whether or not the data in this structure is valid. + bool valid = false; + // The time at which the first freeze for this event was detected. + int64_t initialTimeUs; + // The total duration from the beginning of the first freeze to the end of the last freeze + // in this event. + int32_t durationMs; + // The number of freezes in this event. + int64_t count; + // The sum of all durations of all freezes in this event. + int64_t sumDurationMs; + // The sum of all distances between each freeze in this event. + int64_t sumDistanceMs; + // Detailed information for the first N freezes in this event. + Details details; + }; + + struct JudderEvent { + // Details are captured for each frame judder up to a limited number. The arrays are + // guaranteed to have the same size. + struct Details { + // The actual render duration of the frame for this judder occurrence. + std::vector<int32_t> actualRenderDurationUs; + // The content render duration of the frame for this judder occurrence. + std::vector<int32_t> contentRenderDurationUs; + // The distance from this judder occurrence and the previous judder occurrence. + std::vector<int32_t> distanceMs; + }; + // Whether or not the data in this structure is valid. + bool valid = false; + // The time at which the first judder occurrence for this event was detected. + int64_t initialTimeUs; + // The total duration from the first judder occurrence to the last judder occurrence in this + // event. + int32_t durationMs; + // The number of judder occurrences in this event. + int64_t count; + // The sum of all judder scores in this event. + int64_t sumScore; + // The sum of all distances between each judder occurrence in this event. + int64_t sumDistanceMs; + // Detailed information for the first N judder occurrences in this event. + Details details; }; VideoRenderQualityTracker(); @@ -164,7 +270,16 @@ public: void onFrameReleased(int64_t contentTimeUs, int64_t desiredRenderTimeNs); // Called when the system has detected that the frame has actually been rendered to the display. - void onFrameRendered(int64_t contentTimeUs, int64_t actualRenderTimeNs); + // Returns any freeze events or judder events that were detected. + void onFrameRendered(int64_t contentTimeUs, int64_t actualRenderTimeNs, + FreezeEvent *freezeEventOut = nullptr, + JudderEvent *judderEventOut = nullptr); + + // Gets and resets data for the current freeze event. + FreezeEvent getAndResetFreezeEvent(); + + // Gets and resets data for the current judder event. + JudderEvent getAndResetJudderEvent(); // Retrieve the metrics. const VideoRenderQualityMetrics &getMetrics(); @@ -233,13 +348,31 @@ private: // Process a frame freeze. static void processFreeze(int64_t actualRenderTimeUs, int64_t lastRenderTimeUs, - int64_t lastFreezeEndTimeUs, VideoRenderQualityMetrics &m); + int64_t lastFreezeEndTimeUs, FreezeEvent &e, + VideoRenderQualityMetrics &m, const Configuration &c); + + // Retrieve a freeze event if an event just finished. + static void maybeCaptureFreezeEvent(int64_t actualRenderTimeUs, int64_t lastFreezeEndTimeUs, + FreezeEvent &e, const VideoRenderQualityMetrics & m, + const Configuration &c, FreezeEvent *freezeEventOut); // Compute a judder score for the previously-rendered frame. static int64_t computePreviousJudderScore(const FrameDurationUs &actualRenderDurationUs, const FrameDurationUs &contentRenderDurationUs, const Configuration &c); + // Process a frame judder. + static void processJudder(int32_t judderScore, int64_t judderTimeUs, + int64_t lastJudderEndTimeUs, + const FrameDurationUs &contentDurationUs, + const FrameDurationUs &actualDurationUs, JudderEvent &e, + VideoRenderQualityMetrics &m, const Configuration &c); + + // Retrieve a judder event if an event just finished. + static void maybeCaptureJudderEvent(int64_t actualRenderTimeUs, int64_t lastJudderEndTimeUs, + JudderEvent &e, const VideoRenderQualityMetrics & m, + const Configuration &c, JudderEvent *judderEventOut); + // Check to see if a discontinuity has occurred by examining the content time and the // app-desired render time. If so, reset some internal state. bool resetIfDiscontinuity(int64_t contentTimeUs, int64_t desiredRenderTimeUs); @@ -252,7 +385,8 @@ private: // Update the metrics because a rendered frame was detected. void processMetricsForRenderedFrame(int64_t contentTimeUs, int64_t desiredRenderTimeUs, - int64_t actualRenderTimeUs); + int64_t actualRenderTimeUs, + FreezeEvent *freezeEventOut, JudderEvent *judderEventOut); // Configurable elements of the metrics algorithms. const Configuration mConfiguration; @@ -269,12 +403,21 @@ private: // The most recent timestamp of the first frame rendered after the freeze. int64_t mLastFreezeEndTimeUs; - // The previous video frame was dropped. - bool mWasPreviousFrameDropped; + // The most recent timestamp of frame judder. + int64_t mLastJudderEndTimeUs; // The render duration of the playback. int64_t mRenderDurationMs; + // True if the previous frame was dropped. + bool mWasPreviousFrameDropped; + + // The freeze event that's currently being tracked. + FreezeEvent mFreezeEvent; + + // The judder event that's currently being tracked. + JudderEvent mJudderEvent; + // Frames skipped at the end of playback shouldn't really be considered skipped, therefore keep // a list of the frames, and process them as skipped frames the next time a frame is rendered. std::list<int64_t> mPendingSkippedFrameContentTimeUsList; diff --git a/x86/include/frameworks/av/media/ndk/include/media/NdkImage.h b/x86/include/frameworks/av/media/ndk/include/media/NdkImage.h index 814a327e94a820f5514dfce296288b230583481c..76270d3069b1d49da928e7021d8daf8987af30d1 100644 --- a/x86/include/frameworks/av/media/ndk/include/media/NdkImage.h +++ b/x86/include/frameworks/av/media/ndk/include/media/NdkImage.h @@ -829,7 +829,7 @@ media_status_t AImage_getHardwareBuffer(const AImage* image, /*out*/AHardwareBuf /** * Query the dataspace of the input {@link AImage}. * - * Available since API level 33. + * Available since API level 34. * * @param image the {@link AImage} of interest. * @param dataSpace the dataspace of the image will be filled here if the method call succeeds. @@ -843,7 +843,7 @@ media_status_t AImage_getHardwareBuffer(const AImage* image, /*out*/AHardwareBuf * image has been deleted.</li></ul> */ media_status_t AImage_getDataSpace(const AImage* image, - /*out*/int32_t* dataSpace) __INTRODUCED_IN(33); + /*out*/int32_t* dataSpace) __INTRODUCED_IN(34); __END_DECLS diff --git a/x86/include/frameworks/av/media/ndk/include/media/NdkImageReader.h b/x86/include/frameworks/av/media/ndk/include/media/NdkImageReader.h index 992955bb4a8bc722694c7ff141ae787a550fedb2..b6dcaaed0eb1f2261056d112f3d5af3192be9a86 100644 --- a/x86/include/frameworks/av/media/ndk/include/media/NdkImageReader.h +++ b/x86/include/frameworks/av/media/ndk/include/media/NdkImageReader.h @@ -395,7 +395,7 @@ media_status_t AImageReader_newWithUsage( * the combination of {@code hardwareBufferFormat} and {@code dataSpace} for the * format of the Image that the reader will produce.</p> * - * Available since API level 33. + * Available since API level 34. * * @param width The default width in pixels of the Images that this reader will produce. * @param height The default height in pixels of the Images that this reader will produce. @@ -422,7 +422,7 @@ media_status_t AImageReader_newWithUsage( */ media_status_t AImageReader_newWithDataSpace(int32_t width, int32_t height, uint64_t usage, int32_t maxImages, uint32_t hardwareBufferFormat, int32_t dataSpace, - /*out*/ AImageReader** reader) __INTRODUCED_IN(33); + /*out*/ AImageReader** reader) __INTRODUCED_IN(34); /** * Acquire the next {@link AImage} from the image reader's queue asynchronously. diff --git a/x86_64/arch-x86-x86_64/shared/vndk-core/libui.so b/x86_64/arch-x86-x86_64/shared/vndk-core/libui.so index ce3cdbd52e88b794b9fceb71e8816c8c18bc6ec6..fc0acebac47251e6a93f0048454ad56e2533b7e2 100755 Binary files a/x86_64/arch-x86-x86_64/shared/vndk-core/libui.so and b/x86_64/arch-x86-x86_64/shared/vndk-core/libui.so differ diff --git a/x86_64/arch-x86_64/shared/vndk-core/libui.so b/x86_64/arch-x86_64/shared/vndk-core/libui.so index 587d0d494cfdf17e176bf845395f56d249b453e4..82442f4d2f9f048d33f1e5dac7e1a9bab7315afe 100755 Binary files a/x86_64/arch-x86_64/shared/vndk-core/libui.so and b/x86_64/arch-x86_64/shared/vndk-core/libui.so differ diff --git a/x86_64/include/frameworks/av/media/libstagefright/include/media/stagefright/VideoRenderQualityTracker.h b/x86_64/include/frameworks/av/media/libstagefright/include/media/stagefright/VideoRenderQualityTracker.h index 5cf674fad13f6fd67000013564c4056f6eb07455..82ba81caa1708dbeebe736371dd8006802e112af 100644 --- a/x86_64/include/frameworks/av/media/libstagefright/include/media/stagefright/VideoRenderQualityTracker.h +++ b/x86_64/include/frameworks/av/media/libstagefright/include/media/stagefright/VideoRenderQualityTracker.h @@ -62,20 +62,37 @@ struct VideoRenderQualityMetrics { // A histogram of the durations of freezes due to dropped/skipped frames. MediaHistogram<int32_t> freezeDurationMsHistogram; - // The computed overall freeze score using the above histogram and score conversion table. + // The computed overall freeze score using the above histogram and score conversion table. The + // score is based on counts in the histogram bucket, multiplied by the value in the score + // conversion table for that bucket. For example, the impact of a short freeze may be minimal, + // but the impact of long freeze may be disproportionally worse. Therefore, the score + // multipliers for each bucket might increase exponentially instead of linearly. A score + // multiplier of zero would reflect that small freeze durations have near-zero impact to the + // user experience. int32_t freezeScore; // The computed percentage of total playback duration that was frozen. float freezeRate; + // The number of freeze events. + int32_t freezeEventCount; // A histogram of the durations between each freeze. MediaHistogram<int32_t> freezeDistanceMsHistogram; - // A histogram of the judder scores. + // A histogram of the judder scores - based on the error tolerance between actual render + // duration of each frame and the ideal render duration. MediaHistogram<int32_t> judderScoreHistogram; - // The computed overall judder score using the above histogram and score conversion table. + // The computed overall judder score using the above histogram and score conversion table. The + // score is based on counts in the histogram bucket, multiplied by the value in the score + // conversion table for that bucket. For example, the impact of minimal judder may be small, + // but the impact of large judder may be disproportionally worse. Therefore, the score + // multipliers for each bucket might increase exponentially instead of linearly. A score + // multiplier of zero would reflect that small judder errors have near-zero impact to the user + // experience. int32_t judderScore; // The computed percentage of total frames that had judder. float judderRate; + // The number of judder events. + int32_t judderEventCount; }; /////////////////////////////////////////////////////// @@ -101,6 +118,15 @@ public: // Configurable elements of the metrics algorithms class Configuration { public: + // system/server_configurable_flags/libflags/include/get_flags.h:GetServerConfigurableFlag + typedef std::string (*GetServerConfigurableFlagFn)( + const std::string& experiment_category_name, + const std::string& experiment_flag_name, + const std::string& default_value); + + static Configuration getFromServerConfigurableFlags( + GetServerConfigurableFlagFn getServerConfigurableFlagFn); + Configuration(); // Whether or not frame render quality is tracked. @@ -124,27 +150,107 @@ public: // skip forward in content time is due to frame drops. If the app-desired frame duration is // short, but the content frame duration is large, it is assumed the app is intentionally // seeking forward. - int32_t contentTimeAdvancedForLiveContentToleranceUs; + int32_t liveContentFrameDropToleranceUs; // Freeze configuration // // The values used to distribute freeze durations across a histogram. std::vector<int32_t> freezeDurationMsHistogramBuckets; - // The values used to compare against freeze duration counts when determining an overall - // score. + // + // The values used to multiply the counts in the histogram buckets above to compute an + // overall score. This allows the score to reflect disproportionate impact as freeze + // durations increase. std::vector<int64_t> freezeDurationMsHistogramToScore; + // // The values used to distribute distances between freezes across a histogram. std::vector<int32_t> freezeDistanceMsHistogramBuckets; + // + // The maximum number of freeze events to send back to the caller. + int32_t freezeEventMax; + // + // The maximum number of detail entries tracked per freeze event. + int32_t freezeEventDetailsMax; + // + // The maximum distance in time between two freeze occurrences such that both will be + // lumped into the same freeze event. + int32_t freezeEventDistanceToleranceMs; // Judder configuration // // A judder error lower than this value is not scored as judder. int32_t judderErrorToleranceUs; + // // The values used to distribute judder scores across a histogram. std::vector<int32_t> judderScoreHistogramBuckets; - // The values used to compare against judder score histogram counts when determining an - // overall score. - std::vector<int32_t> judderScoreHistogramToScore; + // + // The values used to multiply the counts in the histogram buckets above to compute an + // overall score. This allows the score to reflect disproportionate impact as judder scores + // increase. + std::vector<int64_t> judderScoreHistogramToScore; + // + // The maximum number of judder events to send back to the caller. + int32_t judderEventMax; + // + // The maximum number of detail entries tracked per judder event. + int32_t judderEventDetailsMax; + // + // The maximum distance in time between two judder occurrences such that both will be + // lumped into the same judder event. + int32_t judderEventDistanceToleranceMs; + }; + + struct FreezeEvent { + // Details are captured for each freeze up to a limited number. The arrays are guaranteed to + // have the same size. + struct Details { + /// The duration of the freeze. + std::vector<int32_t> durationMs; + // The distance between the beginning of this freeze and the end of the previous freeze. + std::vector<int32_t> distanceMs; + }; + // Whether or not the data in this structure is valid. + bool valid = false; + // The time at which the first freeze for this event was detected. + int64_t initialTimeUs; + // The total duration from the beginning of the first freeze to the end of the last freeze + // in this event. + int32_t durationMs; + // The number of freezes in this event. + int64_t count; + // The sum of all durations of all freezes in this event. + int64_t sumDurationMs; + // The sum of all distances between each freeze in this event. + int64_t sumDistanceMs; + // Detailed information for the first N freezes in this event. + Details details; + }; + + struct JudderEvent { + // Details are captured for each frame judder up to a limited number. The arrays are + // guaranteed to have the same size. + struct Details { + // The actual render duration of the frame for this judder occurrence. + std::vector<int32_t> actualRenderDurationUs; + // The content render duration of the frame for this judder occurrence. + std::vector<int32_t> contentRenderDurationUs; + // The distance from this judder occurrence and the previous judder occurrence. + std::vector<int32_t> distanceMs; + }; + // Whether or not the data in this structure is valid. + bool valid = false; + // The time at which the first judder occurrence for this event was detected. + int64_t initialTimeUs; + // The total duration from the first judder occurrence to the last judder occurrence in this + // event. + int32_t durationMs; + // The number of judder occurrences in this event. + int64_t count; + // The sum of all judder scores in this event. + int64_t sumScore; + // The sum of all distances between each judder occurrence in this event. + int64_t sumDistanceMs; + // Detailed information for the first N judder occurrences in this event. + Details details; }; VideoRenderQualityTracker(); @@ -164,7 +270,16 @@ public: void onFrameReleased(int64_t contentTimeUs, int64_t desiredRenderTimeNs); // Called when the system has detected that the frame has actually been rendered to the display. - void onFrameRendered(int64_t contentTimeUs, int64_t actualRenderTimeNs); + // Returns any freeze events or judder events that were detected. + void onFrameRendered(int64_t contentTimeUs, int64_t actualRenderTimeNs, + FreezeEvent *freezeEventOut = nullptr, + JudderEvent *judderEventOut = nullptr); + + // Gets and resets data for the current freeze event. + FreezeEvent getAndResetFreezeEvent(); + + // Gets and resets data for the current judder event. + JudderEvent getAndResetJudderEvent(); // Retrieve the metrics. const VideoRenderQualityMetrics &getMetrics(); @@ -233,13 +348,31 @@ private: // Process a frame freeze. static void processFreeze(int64_t actualRenderTimeUs, int64_t lastRenderTimeUs, - int64_t lastFreezeEndTimeUs, VideoRenderQualityMetrics &m); + int64_t lastFreezeEndTimeUs, FreezeEvent &e, + VideoRenderQualityMetrics &m, const Configuration &c); + + // Retrieve a freeze event if an event just finished. + static void maybeCaptureFreezeEvent(int64_t actualRenderTimeUs, int64_t lastFreezeEndTimeUs, + FreezeEvent &e, const VideoRenderQualityMetrics & m, + const Configuration &c, FreezeEvent *freezeEventOut); // Compute a judder score for the previously-rendered frame. static int64_t computePreviousJudderScore(const FrameDurationUs &actualRenderDurationUs, const FrameDurationUs &contentRenderDurationUs, const Configuration &c); + // Process a frame judder. + static void processJudder(int32_t judderScore, int64_t judderTimeUs, + int64_t lastJudderEndTimeUs, + const FrameDurationUs &contentDurationUs, + const FrameDurationUs &actualDurationUs, JudderEvent &e, + VideoRenderQualityMetrics &m, const Configuration &c); + + // Retrieve a judder event if an event just finished. + static void maybeCaptureJudderEvent(int64_t actualRenderTimeUs, int64_t lastJudderEndTimeUs, + JudderEvent &e, const VideoRenderQualityMetrics & m, + const Configuration &c, JudderEvent *judderEventOut); + // Check to see if a discontinuity has occurred by examining the content time and the // app-desired render time. If so, reset some internal state. bool resetIfDiscontinuity(int64_t contentTimeUs, int64_t desiredRenderTimeUs); @@ -252,7 +385,8 @@ private: // Update the metrics because a rendered frame was detected. void processMetricsForRenderedFrame(int64_t contentTimeUs, int64_t desiredRenderTimeUs, - int64_t actualRenderTimeUs); + int64_t actualRenderTimeUs, + FreezeEvent *freezeEventOut, JudderEvent *judderEventOut); // Configurable elements of the metrics algorithms. const Configuration mConfiguration; @@ -269,12 +403,21 @@ private: // The most recent timestamp of the first frame rendered after the freeze. int64_t mLastFreezeEndTimeUs; - // The previous video frame was dropped. - bool mWasPreviousFrameDropped; + // The most recent timestamp of frame judder. + int64_t mLastJudderEndTimeUs; // The render duration of the playback. int64_t mRenderDurationMs; + // True if the previous frame was dropped. + bool mWasPreviousFrameDropped; + + // The freeze event that's currently being tracked. + FreezeEvent mFreezeEvent; + + // The judder event that's currently being tracked. + JudderEvent mJudderEvent; + // Frames skipped at the end of playback shouldn't really be considered skipped, therefore keep // a list of the frames, and process them as skipped frames the next time a frame is rendered. std::list<int64_t> mPendingSkippedFrameContentTimeUsList; diff --git a/x86_64/include/frameworks/av/media/ndk/include/media/NdkImage.h b/x86_64/include/frameworks/av/media/ndk/include/media/NdkImage.h index 814a327e94a820f5514dfce296288b230583481c..76270d3069b1d49da928e7021d8daf8987af30d1 100644 --- a/x86_64/include/frameworks/av/media/ndk/include/media/NdkImage.h +++ b/x86_64/include/frameworks/av/media/ndk/include/media/NdkImage.h @@ -829,7 +829,7 @@ media_status_t AImage_getHardwareBuffer(const AImage* image, /*out*/AHardwareBuf /** * Query the dataspace of the input {@link AImage}. * - * Available since API level 33. + * Available since API level 34. * * @param image the {@link AImage} of interest. * @param dataSpace the dataspace of the image will be filled here if the method call succeeds. @@ -843,7 +843,7 @@ media_status_t AImage_getHardwareBuffer(const AImage* image, /*out*/AHardwareBuf * image has been deleted.</li></ul> */ media_status_t AImage_getDataSpace(const AImage* image, - /*out*/int32_t* dataSpace) __INTRODUCED_IN(33); + /*out*/int32_t* dataSpace) __INTRODUCED_IN(34); __END_DECLS diff --git a/x86_64/include/frameworks/av/media/ndk/include/media/NdkImageReader.h b/x86_64/include/frameworks/av/media/ndk/include/media/NdkImageReader.h index 992955bb4a8bc722694c7ff141ae787a550fedb2..b6dcaaed0eb1f2261056d112f3d5af3192be9a86 100644 --- a/x86_64/include/frameworks/av/media/ndk/include/media/NdkImageReader.h +++ b/x86_64/include/frameworks/av/media/ndk/include/media/NdkImageReader.h @@ -395,7 +395,7 @@ media_status_t AImageReader_newWithUsage( * the combination of {@code hardwareBufferFormat} and {@code dataSpace} for the * format of the Image that the reader will produce.</p> * - * Available since API level 33. + * Available since API level 34. * * @param width The default width in pixels of the Images that this reader will produce. * @param height The default height in pixels of the Images that this reader will produce. @@ -422,7 +422,7 @@ media_status_t AImageReader_newWithUsage( */ media_status_t AImageReader_newWithDataSpace(int32_t width, int32_t height, uint64_t usage, int32_t maxImages, uint32_t hardwareBufferFormat, int32_t dataSpace, - /*out*/ AImageReader** reader) __INTRODUCED_IN(33); + /*out*/ AImageReader** reader) __INTRODUCED_IN(34); /** * Acquire the next {@link AImage} from the image reader's queue asynchronously.