• 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.media.MediaCodec;
20 import android.media.MediaExtractor;
21 import android.media.MediaFormat;
22 import android.util.Log;
23 
24 import java.io.FileDescriptor;
25 import java.io.IOException;
26 import java.nio.ByteBuffer;
27 
28 public class Extractor {
29     private static final String TAG = "Extractor";
30     private static final int kMaxBufSize = 1024 * 1024 * 16;
31     private MediaExtractor mExtractor;
32     private ByteBuffer mFrameBuffer;
33     private MediaCodec.BufferInfo mBufferInfo;
34     private Stats mStats;
35     private long mDurationUs;
36 
Extractor()37     public Extractor() {
38         mFrameBuffer = ByteBuffer.allocate(kMaxBufSize);
39         mBufferInfo = new MediaCodec.BufferInfo();
40         mStats = new Stats();
41     }
42 
43     /**
44      * Creates a Media Extractor and sets data source(FileDescriptor)to use
45      *
46      * @param fileDescriptor FileDescriptor for the file which is to be extracted
47      * @return TrackCount of the sample
48      * @throws IOException If FileDescriptor is null
49      */
setUpExtractor(FileDescriptor fileDescriptor)50     public int setUpExtractor(FileDescriptor fileDescriptor) throws IOException {
51         long sTime = mStats.getCurTime();
52         mExtractor = new MediaExtractor();
53         mExtractor.setDataSource(fileDescriptor);
54         long eTime = mStats.getCurTime();
55         long timeTaken = mStats.getTimeDiff(sTime, eTime);
56         mStats.setInitTime(timeTaken);
57         return mExtractor.getTrackCount();
58     }
59 
60     /**
61      * Returns the track format of the specified index
62      *
63      * @param trackID Index of the track
64      * @return Format of the track
65      */
getFormat(int trackID)66     public MediaFormat getFormat(int trackID) { return mExtractor.getTrackFormat(trackID); }
67 
68     /**
69      * Returns the extracted buffer for the input clip
70      */
getFrameBuffer()71     public ByteBuffer getFrameBuffer() { return this.mFrameBuffer; }
72 
73     /**
74      * Returns the information of buffer related to sample
75      */
getBufferInfo()76     public MediaCodec.BufferInfo getBufferInfo() { return this.mBufferInfo; }
77 
78     /**
79      * Returns the duration of the sample
80      */
getClipDuration()81     public long getClipDuration() { return this.mDurationUs; }
82 
83     /**
84      * Retrieve the current sample and store it in the byte buffer
85      * Also, sets the information related to extracted sample and store it in buffer info
86      *
87      * @return Sample size of the extracted sample
88      */
getFrameSample()89     public int getFrameSample() {
90         int sampleSize = mExtractor.readSampleData(mFrameBuffer, 0);
91         if (sampleSize < 0) {
92             mBufferInfo.flags = MediaCodec.BUFFER_FLAG_END_OF_STREAM;
93             mBufferInfo.size = 0;
94         } else {
95             mBufferInfo.size = sampleSize;
96             mBufferInfo.offset = 0;
97             mBufferInfo.flags = mExtractor.getSampleFlags();
98             mBufferInfo.presentationTimeUs = mExtractor.getSampleTime();
99             mExtractor.advance();
100         }
101         return sampleSize;
102     }
103 
104     /**
105      * Setup the track format and get the duration of the sample
106      * Track is selected here for extraction
107      *
108      * @param trackId Track index to be selected
109      * @return 0 for valid track, otherwise -1
110      */
selectExtractorTrack(int trackId)111     public int selectExtractorTrack(int trackId) {
112         MediaFormat trackFormat = mExtractor.getTrackFormat(trackId);
113         mDurationUs = trackFormat.getLong(MediaFormat.KEY_DURATION);
114         if (mDurationUs < 0) {
115             Log.e(TAG, "Invalid Clip");
116             return -1;
117         }
118         mExtractor.selectTrack(trackId);
119         return 0;
120     }
121 
122     /**
123      * Unselect the track
124      *
125      * @param trackId Track Index to be unselected
126      */
unselectExtractorTrack(int trackId)127     public void unselectExtractorTrack(int trackId) { mExtractor.unselectTrack(trackId); }
128 
129     /**
130      * Free up the resources
131      */
deinitExtractor()132     public void deinitExtractor() {
133         long sTime = mStats.getCurTime();
134         mExtractor.release();
135         long eTime = mStats.getCurTime();
136         long timeTaken = mStats.getTimeDiff(sTime, eTime);
137         mStats.setDeInitTime(timeTaken);
138     }
139 
140     /**
141      * Performs extract operation
142      *
143      * @param currentTrack Track index to be extracted
144      * @return Status as 0 if extraction is successful, -1 otherwise
145      */
extractSample(int currentTrack)146     public int extractSample(int currentTrack) {
147         int status;
148         status = selectExtractorTrack(currentTrack);
149         if (status == -1) {
150             Log.e(TAG, "Failed to select track");
151             return -1;
152         }
153         mStats.setStartTime();
154         while (true) {
155             int readSampleSize = getFrameSample();
156             if (readSampleSize <= 0) {
157                 break;
158             }
159             mStats.addOutputTime();
160             mStats.addFrameSize(readSampleSize);
161         }
162         unselectExtractorTrack(currentTrack);
163         return 0;
164     }
165 
166     /**
167      * Write the benchmark logs for the given input file
168      *
169      * @param inputReference Name of the input file
170      * @param mimeType       Mime type of the muxed file
171      * @param statsFile      The output file where the stats data is written
172      */
dumpStatistics(String inputReference, String mimeType, String statsFile)173     public void dumpStatistics(String inputReference, String mimeType, String statsFile)
174             throws IOException {
175         String operation = "extract";
176         mStats.dumpStatistics(inputReference, operation, mimeType, "", mDurationUs, statsFile);
177     }
178 }
179