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 //#define LOG_NDEBUG 0
18 #define LOG_TAG "Stats"
19
20 #include <ctime>
21 #include <iostream>
22 #include <stdint.h>
23 #include <fstream>
24
25 #include "Stats.h"
26
27 /**
28 * Dumps the stats of the operation for a given input media.
29 *
30 * \param operation describes the operation performed on the input media
31 * (i.e. extract/mux/decode/encode)
32 * \param inputReference input media
33 * \param durationUs is a duration of the input media in microseconds.
34 * \param componentName describes the codecName/muxFormat/mimeType.
35 * \param mode the operating mode: sync/async.
36 * \param statsFile the file where the stats data is to be written.
37 */
dumpStatistics(string operation,string inputReference,int64_t durationUs,string componentName,string mode,string statsFile)38 void Stats::dumpStatistics(string operation, string inputReference, int64_t durationUs,
39 string componentName, string mode, string statsFile) {
40 ALOGV("In %s", __func__);
41 if (!mOutputTimer.size()) {
42 ALOGE("No output produced");
43 return;
44 }
45 nsecs_t totalTimeTakenNs = getTotalTime();
46 nsecs_t timeTakenPerSec = (totalTimeTakenNs * 1000000) / durationUs;
47 nsecs_t timeToFirstFrameNs = *mOutputTimer.begin() - mStartTimeNs;
48 int32_t size = std::accumulate(mFrameSizes.begin(), mFrameSizes.end(), 0);
49 // get min and max output intervals.
50 nsecs_t intervalNs;
51 nsecs_t minTimeTakenNs = INT64_MAX;
52 nsecs_t maxTimeTakenNs = 0;
53 nsecs_t prevIntervalNs = mStartTimeNs;
54 for (int32_t idx = 0; idx < mOutputTimer.size() - 1; idx++) {
55 intervalNs = mOutputTimer.at(idx) - prevIntervalNs;
56 prevIntervalNs = mOutputTimer.at(idx);
57 if (minTimeTakenNs > intervalNs) minTimeTakenNs = intervalNs;
58 else if (maxTimeTakenNs < intervalNs) maxTimeTakenNs = intervalNs;
59 }
60
61 // Write the stats data to file.
62 int64_t dataSize = size;
63 int64_t bytesPerSec = ((int64_t)dataSize * 1000000000) / totalTimeTakenNs;
64 string rowData = "";
65 rowData.append(to_string(systemTime(CLOCK_MONOTONIC)) + ", ");
66 rowData.append(inputReference + ", ");
67 rowData.append(operation + ", ");
68 rowData.append(componentName + ", ");
69 rowData.append("NDK, ");
70 rowData.append(mode + ", ");
71 rowData.append(to_string(mInitTimeNs) + ", ");
72 rowData.append(to_string(mDeInitTimeNs) + ", ");
73 rowData.append(to_string(minTimeTakenNs) + ", ");
74 rowData.append(to_string(maxTimeTakenNs) + ", ");
75 rowData.append(to_string(totalTimeTakenNs / mOutputTimer.size()) + ", ");
76 rowData.append(to_string(timeTakenPerSec) + ", ");
77 rowData.append(to_string(bytesPerSec) + ", ");
78 rowData.append(to_string(timeToFirstFrameNs) + ", ");
79 rowData.append(to_string(size) + ",");
80 rowData.append(to_string(totalTimeTakenNs) + ",\n");
81
82 ofstream out(statsFile, ios::out | ios::app);
83 if(out.bad()) {
84 ALOGE("Failed to open stats file for writing!");
85 return;
86 }
87 out << rowData;
88 out.close();
89 }
90