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 "NativeEncoder"
19 
20 #include <jni.h>
21 #include <sys/stat.h>
22 #include <fstream>
23 #include <iostream>
24 
25 #include <android/log.h>
26 
27 #include "Decoder.h"
28 #include "Encoder.h"
29 
30 #include <stdio.h>
31 
32 constexpr int32_t ENCODE_DEFAULT_FRAME_RATE = 25;
33 
Java_com_android_media_benchmark_library_Native_Encode(JNIEnv * env,jobject thiz,jstring jFilePath,jstring jFileName,jstring jStatsFile,jstring jCodecName,jstring jMime,jint jBitRate,jint jColorFormat,jint jFrameInterval,jint jWidth,jint jHeight,jint jProfile,jint jLevel,jint jSampleRate,jint jNumChannels)34 extern "C" JNIEXPORT int JNICALL Java_com_android_media_benchmark_library_Native_Encode(
35         JNIEnv *env, jobject thiz, jstring jFilePath, jstring jFileName, jstring jStatsFile,
36         jstring jCodecName, jstring jMime, jint jBitRate, jint jColorFormat, jint jFrameInterval,
37         jint jWidth, jint jHeight, jint jProfile, jint jLevel, jint jSampleRate,
38         jint jNumChannels) {
39     UNUSED(thiz);
40     const char *filePath = env->GetStringUTFChars(jFilePath, nullptr);
41     const char *fileName = env->GetStringUTFChars(jFileName, nullptr);
42     string inputFile = string(filePath) + string(fileName);
43     const char *codecName = env->GetStringUTFChars(jCodecName, nullptr);
44     string sCodecName = string(codecName);
45     const char *mime = env->GetStringUTFChars(jMime, nullptr);
46 
47     ifstream eleStream;
48     eleStream.open(inputFile, ifstream::binary | ifstream::ate);
49     if (!eleStream.is_open()) {
50         ALOGE("%s - File failed to open for reading!", fileName);
51         env->ReleaseStringUTFChars(jFileName, fileName);
52         return -1;
53     }
54 
55     bool asyncMode[2] = {true, false};
56     for (bool mode : asyncMode) {
57         size_t eleSize = eleStream.tellg();
58         eleStream.seekg(0, ifstream::beg);
59 
60         // Set encoder params
61         encParameter encParams;
62         encParams.width = jWidth;
63         encParams.height = jHeight;
64         encParams.bitrate = jBitRate;
65         encParams.iFrameInterval = jFrameInterval;
66         encParams.sampleRate = jSampleRate;
67         encParams.numChannels = jNumChannels;
68         encParams.frameRate = ENCODE_DEFAULT_FRAME_RATE;
69         encParams.colorFormat = jColorFormat;
70         encParams.profile = jProfile;
71         encParams.level = jLevel;
72 
73         Encoder *encoder = new Encoder();
74         encoder->setupEncoder();
75         auto status = encoder->encode(sCodecName, eleStream, eleSize, mode, encParams,
76                                       const_cast<char *>(mime));
77         if (status != AMEDIA_OK) {
78             ALOGE("Encoder returned error");
79             return -1;
80         }
81         ALOGV("Encoding complete with codec %s for asyncMode = %d", sCodecName.c_str(), mode);
82         encoder->deInitCodec();
83         const char *statsFile = env->GetStringUTFChars(jStatsFile, nullptr);
84         string inputReference;
85         int64_t clipDurationUs;
86         if (!strncmp(mime, "video/", 6)) {
87             inputReference = string(fileName) + "_" + to_string(jWidth) + "x" + to_string(jHeight) +
88                              "_" + to_string(jBitRate) + "bps";
89             int32_t frameSize = jWidth * jHeight * 3 / 2;
90             clipDurationUs =
91                     (((eleSize + frameSize - 1) / frameSize) / ENCODE_DEFAULT_FRAME_RATE) * 1000000;
92         } else {
93             inputReference = string(fileName) + "_" + to_string(jSampleRate) + "hz_" +
94                              to_string(jNumChannels) + "ch_" + to_string(jBitRate) + "bps";
95             clipDurationUs = (eleSize / (jSampleRate * jNumChannels)) * 1000000;
96         }
97         encoder->dumpStatistics(inputReference, clipDurationUs, sCodecName,
98                                 (mode ? "async" : "sync"), statsFile);
99         env->ReleaseStringUTFChars(jStatsFile, statsFile);
100         encoder->resetEncoder();
101         delete encoder;
102         encoder = nullptr;
103     }
104     eleStream.close();
105     env->ReleaseStringUTFChars(jFilePath, filePath);
106     env->ReleaseStringUTFChars(jFileName, fileName);
107     env->ReleaseStringUTFChars(jMime, mime);
108     env->ReleaseStringUTFChars(jCodecName, codecName);
109     return 0;
110 }
111