• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2022 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 package com.google.android.exoplayer2.transformer;
17 
18 import androidx.annotation.Nullable;
19 import com.google.android.exoplayer2.C;
20 import org.json.JSONException;
21 import org.json.JSONObject;
22 
23 /** A test only class for holding the details of a test transformation. */
24 public class TransformationTestResult {
25   /** Represents an unset or unknown SSIM score. */
26   public static final double SSIM_UNSET = -1.0d;
27 
28   /** A builder for {@link TransformationTestResult}. */
29   public static class Builder {
30     private final TransformationResult transformationResult;
31 
32     @Nullable private String filePath;
33     @Nullable private Exception analysisException;
34     private long elapsedTimeMs;
35     private double ssim;
36 
37     /** Creates a new {@link Builder}. */
Builder(TransformationResult transformationResult)38     public Builder(TransformationResult transformationResult) {
39       this.transformationResult = transformationResult;
40       this.elapsedTimeMs = C.TIME_UNSET;
41       this.ssim = SSIM_UNSET;
42     }
43 
44     /**
45      * Sets the file path of the output file.
46      *
47      * <p>{@code null} represents an unset or unknown value.
48      *
49      * @param filePath The path.
50      * @return This {@link Builder}.
51      */
setFilePath(@ullable String filePath)52     public Builder setFilePath(@Nullable String filePath) {
53       this.filePath = filePath;
54       return this;
55     }
56 
57     /**
58      * Sets the amount of time taken to perform the transformation in milliseconds. {@link
59      * C#TIME_UNSET} if unset.
60      *
61      * <p>{@link C#TIME_UNSET} represents an unset or unknown value.
62      *
63      * @param elapsedTimeMs The time, in ms.
64      * @return This {@link Builder}.
65      */
setElapsedTimeMs(long elapsedTimeMs)66     public Builder setElapsedTimeMs(long elapsedTimeMs) {
67       this.elapsedTimeMs = elapsedTimeMs;
68       return this;
69     }
70 
71     /**
72      * Sets the SSIM of the output file, compared to input file.
73      *
74      * <p>{@link #SSIM_UNSET} represents an unset or unknown value.
75      *
76      * @param ssim The structural similarity index.
77      * @return This {@link Builder}.
78      */
setSsim(double ssim)79     public Builder setSsim(double ssim) {
80       this.ssim = ssim;
81       return this;
82     }
83 
84     /**
85      * Sets an {@link Exception} that occurred during post-transformation analysis.
86      *
87      * <p>{@code null} represents an unset or unknown value.
88      *
89      * @param analysisException The {@link Exception} thrown during analysis.
90      * @return This {@link Builder}.
91      */
setAnalysisException(@ullable Exception analysisException)92     public Builder setAnalysisException(@Nullable Exception analysisException) {
93       this.analysisException = analysisException;
94       return this;
95     }
96 
97     /** Builds the {@link TransformationTestResult} instance. */
build()98     public TransformationTestResult build() {
99       return new TransformationTestResult(
100           transformationResult, filePath, elapsedTimeMs, ssim, analysisException);
101     }
102   }
103 
104   public final TransformationResult transformationResult;
105   @Nullable public final String filePath;
106   /**
107    * The average rate (per second) at which frames are processed by the transformer, or {@link
108    * C#RATE_UNSET} if unset or unknown.
109    */
110   public final float throughputFps;
111   /**
112    * The amount of time taken to perform the transformation in milliseconds. {@link C#TIME_UNSET} if
113    * unset.
114    */
115   public final long elapsedTimeMs;
116   /** The SSIM score of the transformation, {@link #SSIM_UNSET} if unavailable. */
117   public final double ssim;
118   /**
119    * The {@link Exception} that was thrown during post-transformation analysis, or {@code null} if
120    * nothing was thrown.
121    */
122   @Nullable public final Exception analysisException;
123 
124   /** Returns a {@link JSONObject} representing all the values in {@code this}. */
asJsonObject()125   public JSONObject asJsonObject() throws JSONException {
126     JSONObject jsonObject = new JSONObject();
127     if (transformationResult.durationMs != C.LENGTH_UNSET) {
128       jsonObject.put("durationMs", transformationResult.durationMs);
129     }
130     if (transformationResult.fileSizeBytes != C.LENGTH_UNSET) {
131       jsonObject.put("fileSizeBytes", transformationResult.fileSizeBytes);
132     }
133     if (transformationResult.averageAudioBitrate != C.RATE_UNSET_INT) {
134       jsonObject.put("averageAudioBitrate", transformationResult.averageAudioBitrate);
135     }
136     if (transformationResult.averageVideoBitrate != C.RATE_UNSET_INT) {
137       jsonObject.put("averageVideoBitrate", transformationResult.averageVideoBitrate);
138     }
139     if (transformationResult.videoFrameCount > 0) {
140       jsonObject.put("videoFrameCount", transformationResult.videoFrameCount);
141     }
142     if (throughputFps != C.RATE_UNSET) {
143       jsonObject.put("throughputFps", throughputFps);
144     }
145     if (elapsedTimeMs != C.TIME_UNSET) {
146       jsonObject.put("elapsedTimeMs", elapsedTimeMs);
147     }
148     if (ssim != TransformationTestResult.SSIM_UNSET) {
149       jsonObject.put("ssim", ssim);
150     }
151     if (analysisException != null) {
152       jsonObject.put("analysisException", AndroidTestUtil.exceptionAsJsonObject(analysisException));
153     }
154     return jsonObject;
155   }
156 
TransformationTestResult( TransformationResult transformationResult, @Nullable String filePath, long elapsedTimeMs, double ssim, @Nullable Exception analysisException)157   private TransformationTestResult(
158       TransformationResult transformationResult,
159       @Nullable String filePath,
160       long elapsedTimeMs,
161       double ssim,
162       @Nullable Exception analysisException) {
163     this.transformationResult = transformationResult;
164     this.filePath = filePath;
165     this.elapsedTimeMs = elapsedTimeMs;
166     this.ssim = ssim;
167     this.analysisException = analysisException;
168     this.throughputFps =
169         elapsedTimeMs != C.TIME_UNSET && transformationResult.videoFrameCount > 0
170             ? 1000f * transformationResult.videoFrameCount / elapsedTimeMs
171             : C.RATE_UNSET;
172   }
173 }
174