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 "BenchmarkCommon"
19 
20 #include "BenchmarkCommon.h"
21 #include <iostream>
22 
ioThread()23 void CallBackHandle::ioThread() {
24     ALOGV("In %s mIsDone : %d, mSawError : %d ", __func__, mIsDone, mSawError);
25     while (!mIsDone && !mSawError) {
26         auto task = mIOQueue.pop();
27         task();
28     }
29 }
30 
OnInputAvailableCB(AMediaCodec * codec,void * userdata,int32_t index)31 void OnInputAvailableCB(AMediaCodec *codec, void *userdata, int32_t index) {
32     ALOGV("OnInputAvailableCB: index(%d)", index);
33     CallBackHandle *self = (CallBackHandle *)userdata;
34     self->getStats()->addInputTime();
35     self->mIOQueue.push([self, codec, index]() { self->onInputAvailable(codec, index); });
36 }
37 
OnOutputAvailableCB(AMediaCodec * codec,void * userdata,int32_t index,AMediaCodecBufferInfo * bufferInfo)38 void OnOutputAvailableCB(AMediaCodec *codec, void *userdata, int32_t index,
39                          AMediaCodecBufferInfo *bufferInfo) {
40     ALOGV("OnOutputAvailableCB: index(%d), (%d, %d, %lld, 0x%x)", index, bufferInfo->offset,
41           bufferInfo->size, (long long)bufferInfo->presentationTimeUs, bufferInfo->flags);
42     CallBackHandle *self = (CallBackHandle *)userdata;
43     self->getStats()->addOutputTime();
44     AMediaCodecBufferInfo bufferInfoCopy = *bufferInfo;
45     self->mIOQueue.push([self, codec, index, bufferInfoCopy]() {
46         AMediaCodecBufferInfo bc = bufferInfoCopy;
47         self->onOutputAvailable(codec, index, &bc);
48     });
49 }
50 
OnFormatChangedCB(AMediaCodec * codec,void * userdata,AMediaFormat * format)51 void OnFormatChangedCB(AMediaCodec *codec, void *userdata, AMediaFormat *format) {
52     ALOGV("OnFormatChangedCB: format(%s)", AMediaFormat_toString(format));
53     CallBackHandle *self = (CallBackHandle *)userdata;
54     self->mIOQueue.push([self, codec, format]() { self->onFormatChanged(codec, format); });
55 }
56 
OnErrorCB(AMediaCodec * codec,void * userdata,media_status_t err,int32_t actionCode,const char * detail)57 void OnErrorCB(AMediaCodec *codec, void *userdata, media_status_t err, int32_t actionCode,
58                const char *detail) {
59     (void)codec;
60     ALOGE("OnErrorCB: err(%d), actionCode(%d), detail(%s)", err, actionCode, detail);
61     CallBackHandle *self = (CallBackHandle *)userdata;
62     self->mSawError = true;
63     self->mIOQueue.push([self, codec, err]() { self->onError(codec, err); });
64 }
65 
createMediaCodec(AMediaFormat * format,const char * mime,string codecName,bool isEncoder)66 AMediaCodec *createMediaCodec(AMediaFormat *format, const char *mime, string codecName,
67                               bool isEncoder) {
68     ALOGV("In %s", __func__);
69     if (!mime) {
70         ALOGE("Please specify a mime type to create codec");
71         return nullptr;
72     }
73 
74     AMediaCodec *codec;
75     if (!codecName.empty()) {
76         codec = AMediaCodec_createCodecByName(codecName.c_str());
77         if (!codec) {
78             ALOGE("Unable to create codec by name: %s", codecName.c_str());
79             return nullptr;
80         }
81     } else {
82         if (isEncoder) {
83             codec = AMediaCodec_createEncoderByType(mime);
84         } else {
85             codec = AMediaCodec_createDecoderByType(mime);
86         }
87         if (!codec) {
88             ALOGE("Unable to create codec by mime: %s", mime);
89             return nullptr;
90         }
91     }
92 
93     /* Configure codec with the given format*/
94     const char *s = AMediaFormat_toString(format);
95     ALOGI("Input format: %s\n", s);
96 
97     media_status_t status = AMediaCodec_configure(codec, format, nullptr, nullptr, isEncoder);
98     if (status != AMEDIA_OK) {
99         ALOGE("AMediaCodec_configure failed %d", status);
100         return nullptr;
101     }
102     return codec;
103 }
104