• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 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 package com.android.media.benchmark.library;
18 
19 import android.util.Log;
20 
21 import java.io.File;
22 import java.io.FileDescriptor;
23 import java.io.FileOutputStream;
24 import java.io.IOException;
25 import java.util.ArrayList;
26 
27 /**
28  * Measures Performance.
29  */
30 public class Stats {
31     private static final String TAG = "Stats";
32     private long mInitTimeNs;
33     private long mDeInitTimeNs;
34     private long mStartTimeNs;
35     private ArrayList<Integer> mFrameSizes;
36     private ArrayList<Long> mInputTimer;
37     private ArrayList<Long> mOutputTimer;
38 
Stats()39     public Stats() {
40         mFrameSizes = new ArrayList<>();
41         mInputTimer = new ArrayList<>();
42         mOutputTimer = new ArrayList<>();
43         mInitTimeNs = 0;
44         mDeInitTimeNs = 0;
45     }
46 
getCurTime()47     public long getCurTime() { return System.nanoTime(); }
48 
setInitTime(long initTime)49     public void setInitTime(long initTime) { mInitTimeNs = initTime; }
50 
setDeInitTime(long deInitTime)51     public void setDeInitTime(long deInitTime) { mDeInitTimeNs = deInitTime; }
52 
setStartTime()53     public void setStartTime() { mStartTimeNs = System.nanoTime(); }
54 
addFrameSize(int size)55     public void addFrameSize(int size) { mFrameSizes.add(size); }
56 
addInputTime()57     public void addInputTime() { mInputTimer.add(System.nanoTime()); }
58 
addOutputTime()59     public void addOutputTime() { mOutputTimer.add(System.nanoTime()); }
60 
reset()61     public void reset() {
62         if (mFrameSizes.size() != 0) {
63             mFrameSizes.clear();
64         }
65 
66         if (mInputTimer.size() != 0) {
67             mInputTimer.clear();
68         }
69 
70         if (mOutputTimer.size() != 0) {
71             mOutputTimer.clear();
72         }
73     }
74 
getInitTime()75     public long getInitTime() { return mInitTimeNs; }
76 
getDeInitTime()77     public long getDeInitTime() { return mDeInitTimeNs; }
78 
getTimeDiff(long sTime, long eTime)79     public long getTimeDiff(long sTime, long eTime) { return (eTime - sTime); }
80 
getTotalTime()81     private long getTotalTime() {
82         if (mOutputTimer.size() == 0) {
83             return -1;
84         }
85         long lastTime = mOutputTimer.get(mOutputTimer.size() - 1);
86         return lastTime - mStartTimeNs;
87     }
88 
getTotalSize()89     private long getTotalSize() {
90         long totalSize = 0;
91         for (long size : mFrameSizes) {
92             totalSize += size;
93         }
94         return totalSize;
95     }
96 
97     /**
98      * Writes the stats header to a file
99      * <p>
100      * \param statsFile    file where the stats data is to be written
101      **/
writeStatsHeader(String statsFile)102     public boolean writeStatsHeader(String statsFile) throws IOException {
103         File outputFile = new File(statsFile);
104         FileOutputStream out = new FileOutputStream(outputFile, true);
105         if (!outputFile.exists())
106             return false;
107         String statsHeader =
108                 "currentTime, fileName, operation, componentName, NDK/SDK, sync/async, setupTime, "
109                         + "destroyTime, minimumTime, maximumTime, "
110                         + "averageTime, timeToProcess1SecContent, totalBytesProcessedPerSec, "
111                         + "timeToFirstFrame, totalSizeInBytes, totalTime\n";
112         out.write(statsHeader.getBytes());
113         out.close();
114         return true;
115     }
116 
117     /**
118      * Dumps the stats of the operation for a given input media.
119      * <p>
120      * \param inputReference input media
121      * \param operation      describes the operation performed on the input media
122      * (i.e. extract/mux/decode/encode)
123      * \param componentName  name of the codec/muxFormat/mime
124      * \param mode           the operating mode: sync/async.
125      * \param durationUs     is a duration of the input media in microseconds.
126      * \param statsFile      the file where the stats data is to be written.
127      */
dumpStatistics(String inputReference, String operation, String componentName, String mode, long durationUs, String statsFile)128     public void dumpStatistics(String inputReference, String operation, String componentName,
129             String mode, long durationUs, String statsFile) throws IOException {
130         if (mOutputTimer.size() == 0) {
131             Log.e(TAG, "No output produced");
132             return;
133         }
134         long totalTimeTakenNs = getTotalTime();
135         long timeTakenPerSec = (totalTimeTakenNs * 1000000) / durationUs;
136         long timeToFirstFrameNs = mOutputTimer.get(0) - mStartTimeNs;
137         long size = getTotalSize();
138         // get min and max output intervals.
139         long intervalNs;
140         long minTimeTakenNs = Long.MAX_VALUE;
141         long maxTimeTakenNs = 0;
142         long prevIntervalNs = mStartTimeNs;
143         for (int idx = 0; idx < mOutputTimer.size() - 1; idx++) {
144             intervalNs = mOutputTimer.get(idx) - prevIntervalNs;
145             prevIntervalNs = mOutputTimer.get(idx);
146             if (minTimeTakenNs > intervalNs) {
147                 minTimeTakenNs = intervalNs;
148             } else if (maxTimeTakenNs < intervalNs) {
149                 maxTimeTakenNs = intervalNs;
150             }
151         }
152 
153         // Write the stats row data to file
154         String rowData = "";
155         rowData += System.nanoTime() + ", ";
156         rowData += inputReference + ", ";
157         rowData += operation + ", ";
158         rowData += componentName + ", ";
159         rowData += "SDK, ";
160         rowData += mode + ", ";
161         rowData += mInitTimeNs + ", ";
162         rowData += mDeInitTimeNs + ", ";
163         rowData += minTimeTakenNs + ", ";
164         rowData += maxTimeTakenNs + ", ";
165         rowData += totalTimeTakenNs / mOutputTimer.size() + ", ";
166         rowData += timeTakenPerSec + ", ";
167         rowData += (size * 1000000000) / totalTimeTakenNs + ", ";
168         rowData += timeToFirstFrameNs + ", ";
169         rowData += size + ", ";
170         rowData += totalTimeTakenNs + "\n";
171 
172         File outputFile = new File(statsFile);
173         FileOutputStream out = new FileOutputStream(outputFile, true);
174         assert outputFile.exists() : "Failed to open the stats file for writing!";
175         out.write(rowData.getBytes());
176         out.close();
177     }
178 }
179