• 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 package com.android.media.benchmark.tests;
17 
18 import com.android.media.benchmark.R;
19 import com.android.media.benchmark.library.Extractor;
20 import com.android.media.benchmark.library.Muxer;
21 import com.android.media.benchmark.library.Native;
22 import com.android.media.benchmark.library.Stats;
23 
24 import androidx.test.platform.app.InstrumentationRegistry;
25 
26 import android.content.Context;
27 import android.media.MediaCodec;
28 import android.media.MediaFormat;
29 import android.media.MediaMuxer;
30 import android.util.Log;
31 
32 import org.junit.BeforeClass;
33 import org.junit.Test;
34 import org.junit.runner.RunWith;
35 import org.junit.runners.Parameterized;
36 
37 import java.io.File;
38 import java.io.FileDescriptor;
39 import java.io.FileInputStream;
40 import java.io.FileOutputStream;
41 import java.io.IOException;
42 import java.nio.ByteBuffer;
43 import java.util.ArrayList;
44 import java.util.Arrays;
45 import java.util.Collection;
46 import java.util.Hashtable;
47 import java.util.Map;
48 
49 import static org.junit.Assert.assertTrue;
50 import static org.junit.Assert.assertEquals;
51 import static org.junit.Assert.assertNotEquals;
52 
53 import static org.junit.Assert.assertTrue;
54 
55 @RunWith(Parameterized.class)
56 public class MuxerTest {
57     private static Context mContext =
58             InstrumentationRegistry.getInstrumentation().getTargetContext();
59     private static final String mInputFilePath = mContext.getString(R.string.input_file_path);
60     private static final String mStatsFile =
61             mContext.getExternalFilesDir(null) + "/Muxer." + System.currentTimeMillis() + ".csv";
62     private static final String TAG = "MuxerTest";
63     private static final Map<String, Integer> mMapFormat = new Hashtable<String, Integer>() {
64         {
65             put("mp4", MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);
66             put("webm", MediaMuxer.OutputFormat.MUXER_OUTPUT_WEBM);
67             put("3gpp", MediaMuxer.OutputFormat.MUXER_OUTPUT_3GPP);
68             put("ogg", MediaMuxer.OutputFormat.MUXER_OUTPUT_OGG);
69         }
70     };
71     private String mInputFileName;
72     private String mFormat;
73 
74     @Parameterized.Parameters
inputFiles()75     public static Collection<Object[]> inputFiles() {
76         return Arrays.asList(new Object[][]{
77                 /* Parameters: filename, format */
78                 {"crowd_1920x1080_25fps_4000kbps_vp8.webm", "webm"},
79                 {"crowd_1920x1080_25fps_4000kbps_vp9.webm", "webm"},
80                 {"crowd_1920x1080_25fps_6000kbps_mpeg4.mp4", "mp4"},
81                 {"crowd_352x288_25fps_6000kbps_h263.3gp", "mp4"},
82                 {"crowd_1920x1080_25fps_6700kbps_h264.ts", "mp4"},
83                 {"crowd_1920x1080_25fps_4000kbps_h265.mkv", "mp4"},
84                 {"crowd_1920x1080_25fps_6000kbps_mpeg4.mp4", "3gpp"},
85                 {"crowd_352x288_25fps_6000kbps_h263.3gp", "3gpp"},
86                 {"crowd_1920x1080_25fps_6700kbps_h264.ts", "3gpp"},
87                 {"crowd_1920x1080_25fps_4000kbps_h265.mkv", "3gpp"},
88                 {"bbb_48000hz_2ch_100kbps_opus_5mins.webm", "ogg"},
89                 {"bbb_44100hz_2ch_80kbps_vorbis_5mins.webm", "webm"},
90                 {"bbb_48000hz_2ch_100kbps_opus_5mins.webm", "webm"},
91                 {"bbb_44100hz_2ch_128kbps_aac_5mins.mp4", "mp4"},
92                 {"bbb_8000hz_1ch_8kbps_amrnb_5mins.3gp", "mp4"},
93                 {"bbb_16000hz_1ch_9kbps_amrwb_5mins.3gp", "mp4"},
94                 {"bbb_44100hz_2ch_128kbps_aac_5mins.mp4", "3gpp"},
95                 {"bbb_8000hz_1ch_8kbps_amrnb_5mins.3gp", "3gpp"},
96                 {"bbb_16000hz_1ch_9kbps_amrwb_5mins.3gp", "3gpp"}});
97     }
98 
MuxerTest(String filename, String outputFormat)99     public MuxerTest(String filename, String outputFormat) {
100         this.mInputFileName = filename;
101         this.mFormat = outputFormat;
102     }
103 
104     @BeforeClass
writeStatsHeaderToFile()105     public static void writeStatsHeaderToFile() throws IOException {
106         Stats mStats = new Stats();
107         boolean status = mStats.writeStatsHeader(mStatsFile);
108         assertTrue("Unable to open stats file for writing!", status);
109         Log.d(TAG, "Saving Benchmark results in: " + mStatsFile);
110     }
111 
112     @Test
testMuxer()113     public void testMuxer() throws IOException {
114         File inputFile = new File(mInputFilePath + mInputFileName);
115         assertTrue("Cannot find " + mInputFileName + " in directory " + mInputFilePath,
116                 inputFile.exists());
117         FileInputStream fileInput = new FileInputStream(inputFile);
118         FileDescriptor fileDescriptor = fileInput.getFD();
119         ArrayList<ByteBuffer> inputBuffer = new ArrayList<>();
120         ArrayList<MediaCodec.BufferInfo> inputBufferInfo = new ArrayList<>();
121         Extractor extractor = new Extractor();
122         int trackCount = extractor.setUpExtractor(fileDescriptor);
123         for (int currentTrack = 0; currentTrack < trackCount; currentTrack++) {
124             extractor.selectExtractorTrack(currentTrack);
125             while (true) {
126                 int sampleSize = extractor.getFrameSample();
127                 MediaCodec.BufferInfo bufferInfo = extractor.getBufferInfo();
128                 MediaCodec.BufferInfo tempBufferInfo = new MediaCodec.BufferInfo();
129                 tempBufferInfo
130                         .set(bufferInfo.offset, bufferInfo.size, bufferInfo.presentationTimeUs,
131                                 bufferInfo.flags);
132                 inputBufferInfo.add(tempBufferInfo);
133                 ByteBuffer tempSampleBuffer = ByteBuffer.allocate(tempBufferInfo.size);
134                 tempSampleBuffer.put(extractor.getFrameBuffer().array(), 0, bufferInfo.size);
135                 inputBuffer.add(tempSampleBuffer);
136                 if (sampleSize < 0) {
137                     break;
138                 }
139             }
140             MediaFormat format = extractor.getFormat(currentTrack);
141             int outputFormat = mMapFormat.getOrDefault(mFormat, -1);
142             assertNotEquals("Test failed for " + mInputFileName + ". Returned invalid " +
143                     "output format for given " + mFormat + " format.", -1, outputFormat);
144             Muxer muxer = new Muxer();
145             int trackIndex = muxer.setUpMuxer(mContext, outputFormat, format);
146             int status = muxer.mux(trackIndex, inputBuffer, inputBufferInfo);
147             assertEquals("Cannot perform write operation for " + mInputFileName, 0, status);
148             Log.i(TAG, "Muxed " + mInputFileName + " successfully.");
149             muxer.deInitMuxer();
150             muxer.dumpStatistics(mInputFileName, mFormat, extractor.getClipDuration(), mStatsFile);
151             muxer.resetMuxer();
152             extractor.unselectExtractorTrack(currentTrack);
153             inputBufferInfo.clear();
154             inputBuffer.clear();
155 
156         }
157         extractor.deinitExtractor();
158         fileInput.close();
159     }
160 
161     @Test
testNativeMuxer()162     public void testNativeMuxer() {
163         Native nativeMuxer = new Native();
164         File inputFile = new File(mInputFilePath + mInputFileName);
165         assertTrue("Cannot find " + mInputFileName + " in directory " + mInputFilePath,
166                 inputFile.exists());
167         int tid = android.os.Process.myTid();
168         String mMuxOutputFile = (mContext.getFilesDir() + "/mux_" + tid + ".out");
169         int status = nativeMuxer.Mux(
170                 mInputFilePath, mInputFileName, mMuxOutputFile, mStatsFile, mFormat);
171         assertEquals("Cannot perform write operation for " + mInputFileName, 0, status);
172         Log.i(TAG, "Muxed " + mInputFileName + " successfully.");
173         File muxedFile = new File(mMuxOutputFile);
174         // Cleanup temporary output file
175         if (muxedFile.exists()) {
176             assertTrue("Unable to delete" + mMuxOutputFile + " file.",
177                     muxedFile.delete());
178         }
179     }
180 }
181