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 "muxer"
19 
20 #include <fstream>
21 #include <iostream>
22 
23 #include "Muxer.h"
24 
initMuxer(int32_t fd,MUXER_OUTPUT_T outputFormat)25 int32_t Muxer::initMuxer(int32_t fd, MUXER_OUTPUT_T outputFormat) {
26     if (!mFormat) mFormat = mExtractor->getFormat();
27     if (!mStats) mStats = new Stats();
28 
29     int64_t sTime = mStats->getCurTime();
30     mMuxer = AMediaMuxer_new(fd, (OutputFormat)outputFormat);
31     if (!mMuxer) {
32         ALOGV("Unable to create muxer");
33         return AMEDIA_ERROR_INVALID_OBJECT;
34     }
35     /*
36      * AMediaMuxer_addTrack returns the index of the new track or a negative value
37      * in case of failure, which can be interpreted as a media_status_t.
38      */
39     ssize_t index = AMediaMuxer_addTrack(mMuxer, mFormat);
40     if (index < 0) {
41         ALOGV("Format not supported");
42         return index;
43     }
44     AMediaMuxer_start(mMuxer);
45     int64_t eTime = mStats->getCurTime();
46     int64_t timeTaken = mStats->getTimeDiff(sTime, eTime);
47     mStats->setInitTime(timeTaken);
48     return AMEDIA_OK;
49 }
50 
deInitMuxer()51 void Muxer::deInitMuxer() {
52     if (mFormat) {
53         AMediaFormat_delete(mFormat);
54         mFormat = nullptr;
55     }
56     if (!mMuxer) return;
57     int64_t sTime = mStats->getCurTime();
58     AMediaMuxer_stop(mMuxer);
59     AMediaMuxer_delete(mMuxer);
60     int64_t eTime = mStats->getCurTime();
61     int64_t timeTaken = mStats->getTimeDiff(sTime, eTime);
62     mStats->setDeInitTime(timeTaken);
63 }
64 
resetMuxer()65 void Muxer::resetMuxer() {
66     if (mStats) mStats->reset();
67 }
68 
dumpStatistics(string inputReference,string componentName,string statsFile)69 void Muxer::dumpStatistics(string inputReference, string componentName, string statsFile) {
70     string operation = "mux";
71     mStats->dumpStatistics(operation, inputReference, mExtractor->getClipDuration(), componentName,
72                            "", statsFile);
73 }
74 
mux(uint8_t * inputBuffer,vector<AMediaCodecBufferInfo> & frameInfos)75 int32_t Muxer::mux(uint8_t *inputBuffer, vector<AMediaCodecBufferInfo> &frameInfos) {
76     // Mux frame data
77     size_t frameIdx = 0;
78     mStats->setStartTime();
79     while (frameIdx < frameInfos.size()) {
80         AMediaCodecBufferInfo info = frameInfos.at(frameIdx);
81         media_status_t status = AMediaMuxer_writeSampleData(mMuxer, 0, inputBuffer, &info);
82         if (status != 0) {
83             ALOGE("Error in AMediaMuxer_writeSampleData");
84             return status;
85         }
86         mStats->addOutputTime();
87         mStats->addFrameSize(info.size);
88         frameIdx++;
89     }
90     return AMEDIA_OK;
91 }
92