Merge "Transcoding: Test api with actual service."
This commit is contained in:
@@ -260,6 +260,21 @@ public final class MediaTranscodeManager {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTranscodingStarted(int jobId) throws RemoteException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTranscodingPaused(int jobId) throws RemoteException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTranscodingResumed(int jobId) throws RemoteException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTranscodingFinished(int jobId, TranscodingResultParcel result)
|
||||
throws RemoteException {
|
||||
@@ -306,6 +321,7 @@ public final class MediaTranscodeManager {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static final class TranscodingRequest {
|
||||
/** Uri of the source media file. */
|
||||
private @NonNull Uri mSourceUri;
|
||||
@@ -344,7 +360,7 @@ public final class MediaTranscodeManager {
|
||||
private @Nullable MediaFormat mImageFormat = null;
|
||||
|
||||
@VisibleForTesting
|
||||
private int mProcessingDelayMs = 0;
|
||||
private TranscodingTestConfig mTestConfig = null;
|
||||
|
||||
private TranscodingRequest(Builder b) {
|
||||
mSourceUri = b.mSourceUri;
|
||||
@@ -354,7 +370,7 @@ public final class MediaTranscodeManager {
|
||||
mVideoTrackFormat = b.mVideoTrackFormat;
|
||||
mAudioTrackFormat = b.mAudioTrackFormat;
|
||||
mImageFormat = b.mImageFormat;
|
||||
mProcessingDelayMs = b.mProcessingDelayMs;
|
||||
mTestConfig = b.mTestConfig;
|
||||
}
|
||||
|
||||
/** Return the type of the transcoding. */
|
||||
@@ -397,10 +413,9 @@ public final class MediaTranscodeManager {
|
||||
parcel.transcodingType = mType;
|
||||
parcel.sourceFilePath = mSourceUri.getPath();
|
||||
parcel.destinationFilePath = mDestinationUri.getPath();
|
||||
if (mProcessingDelayMs != 0) {
|
||||
if (mTestConfig != null) {
|
||||
parcel.isForTesting = true;
|
||||
parcel.testConfig = new TranscodingTestConfig();
|
||||
parcel.testConfig.processingDelayMs = mProcessingDelayMs;
|
||||
parcel.testConfig = mTestConfig;
|
||||
}
|
||||
return parcel;
|
||||
}
|
||||
@@ -417,7 +432,7 @@ public final class MediaTranscodeManager {
|
||||
private @Nullable MediaFormat mVideoTrackFormat;
|
||||
private @Nullable MediaFormat mAudioTrackFormat;
|
||||
private @Nullable MediaFormat mImageFormat;
|
||||
private int mProcessingDelayMs = 0;
|
||||
private TranscodingTestConfig mTestConfig;
|
||||
|
||||
/**
|
||||
* Specifies the uri of source media file.
|
||||
@@ -525,12 +540,12 @@ public final class MediaTranscodeManager {
|
||||
|
||||
/**
|
||||
* Sets the delay in processing this request.
|
||||
* @param processingDelayMs delay in milliseconds.
|
||||
* @param config test config.
|
||||
* @return The same builder instance.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
public Builder setProcessingDelayMs(int processingDelayMs) {
|
||||
mProcessingDelayMs = processingDelayMs;
|
||||
public Builder setTestConfig(TranscodingTestConfig config) {
|
||||
mTestConfig = config;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,162 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.mediatranscodingtest;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.media.MediaFormat;
|
||||
import android.media.MediaTranscodeManager;
|
||||
import android.media.MediaTranscodeManager.TranscodingJob;
|
||||
import android.media.MediaTranscodeManager.TranscodingRequest;
|
||||
import android.media.TranscodingTestConfig;
|
||||
import android.net.Uri;
|
||||
import android.test.ActivityInstrumentationTestCase2;
|
||||
import android.util.Log;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Semaphore;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/*
|
||||
* Functional tests for MediaTranscodeManager in the media framework.
|
||||
* The test uses actual media.Transcoding service as backend to fully
|
||||
* test the API functionality.
|
||||
*
|
||||
* To run this test suite:
|
||||
make frameworks/base/media/tests/MediaTranscodingTest
|
||||
make mediatranscodingtest
|
||||
|
||||
adb install -r testcases/mediatranscodingtest/arm64/mediatranscodingtest.apk
|
||||
|
||||
adb shell am instrument -e class \
|
||||
com.android.mediatranscodingtest.MediaTranscodeManagerTest \
|
||||
-w com.android.mediatranscodingtest/.MediaTranscodingTestRunner
|
||||
*
|
||||
*/
|
||||
public class MediaTranscodeManagerTest
|
||||
extends ActivityInstrumentationTestCase2<MediaTranscodingTest> {
|
||||
private static final String TAG = "MediaTranscodeManagerTest";
|
||||
/** The time to wait for the transcode operation to complete before failing the test. */
|
||||
private static final int TRANSCODE_TIMEOUT_SECONDS = 2;
|
||||
private Context mContext;
|
||||
private MediaTranscodeManager mMediaTranscodeManager = null;
|
||||
private Uri mSourceHEVCVideoUri = null;
|
||||
private Uri mDestinationUri = null;
|
||||
|
||||
// Setting for transcoding to H.264.
|
||||
private static final String MIME_TYPE = MediaFormat.MIMETYPE_VIDEO_AVC;
|
||||
private static final int BIT_RATE = 2000000; // 2Mbps
|
||||
private static final int WIDTH = 1920;
|
||||
private static final int HEIGHT = 1080;
|
||||
|
||||
public MediaTranscodeManagerTest() {
|
||||
super("com.android.MediaTranscodeManagerTest", MediaTranscodingTest.class);
|
||||
}
|
||||
|
||||
|
||||
private static Uri resourceToUri(Context context, int resId) {
|
||||
Uri uri = new Uri.Builder()
|
||||
.scheme(ContentResolver.SCHEME_ANDROID_RESOURCE)
|
||||
.authority(context.getResources().getResourcePackageName(resId))
|
||||
.appendPath(context.getResources().getResourceTypeName(resId))
|
||||
.appendPath(context.getResources().getResourceEntryName(resId))
|
||||
.build();
|
||||
return uri;
|
||||
}
|
||||
|
||||
private static Uri generateNewUri(Context context, String filename) {
|
||||
File outFile = new File(context.getExternalCacheDir(), filename);
|
||||
return Uri.fromFile(outFile);
|
||||
}
|
||||
|
||||
// Generates a invalid uri which will let the mock service return transcoding failure.
|
||||
private static Uri generateInvalidTranscodingUri(Context context) {
|
||||
File outFile = new File(context.getExternalCacheDir(), "InvalidUri.mp4");
|
||||
return Uri.fromFile(outFile);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a MediaFormat with the basic set of values.
|
||||
*/
|
||||
private static MediaFormat createMediaFormat() {
|
||||
MediaFormat format = MediaFormat.createVideoFormat(MIME_TYPE, WIDTH, HEIGHT);
|
||||
format.setInteger(MediaFormat.KEY_BIT_RATE, BIT_RATE);
|
||||
return format;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
Log.d(TAG, "setUp");
|
||||
super.setUp();
|
||||
mContext = getInstrumentation().getContext();
|
||||
mMediaTranscodeManager = MediaTranscodeManager.getInstance(mContext);
|
||||
assertNotNull(mMediaTranscodeManager);
|
||||
|
||||
// Setup source HEVC file uri.
|
||||
mSourceHEVCVideoUri = resourceToUri(mContext, R.raw.VideoOnlyHEVC);
|
||||
|
||||
// Setup destination file.
|
||||
mDestinationUri = generateNewUri(mContext, "transcoded.mp4");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tearDown() throws Exception {
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTranscodingOneVideo() throws Exception {
|
||||
Log.d(TAG, "Starting: testMediaTranscodeManager");
|
||||
|
||||
Semaphore transcodeCompleteSemaphore = new Semaphore(0);
|
||||
TranscodingTestConfig testConfig = new TranscodingTestConfig();
|
||||
testConfig.passThroughMode = true;
|
||||
testConfig.processingTotalTimeMs = 300; // minimum time spent on transcoding.
|
||||
|
||||
TranscodingRequest request =
|
||||
new TranscodingRequest.Builder()
|
||||
.setSourceUri(mSourceHEVCVideoUri)
|
||||
.setDestinationUri(mDestinationUri)
|
||||
.setType(MediaTranscodeManager.TRANSCODING_TYPE_VIDEO)
|
||||
.setPriority(MediaTranscodeManager.PRIORITY_REALTIME)
|
||||
.setVideoTrackFormat(createMediaFormat())
|
||||
.setTestConfig(testConfig)
|
||||
.build();
|
||||
Executor listenerExecutor = Executors.newSingleThreadExecutor();
|
||||
|
||||
TranscodingJob job = mMediaTranscodeManager.enqueueRequest(request, listenerExecutor,
|
||||
transcodingJob -> {
|
||||
Log.d(TAG, "Transcoding completed with result: " + transcodingJob.getResult());
|
||||
assertEquals(transcodingJob.getResult(), TranscodingJob.RESULT_SUCCESS);
|
||||
transcodeCompleteSemaphore.release();
|
||||
});
|
||||
assertNotNull(job);
|
||||
|
||||
if (job != null) {
|
||||
Log.d(TAG, "testMediaTranscodeManager - Waiting for transcode to complete.");
|
||||
boolean finishedOnTime = transcodeCompleteSemaphore.tryAcquire(
|
||||
TRANSCODE_TIMEOUT_SECONDS, TimeUnit.SECONDS);
|
||||
assertTrue("Transcode failed to complete in time.", finishedOnTime);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ import android.media.MediaTranscodeManager.TranscodingRequest;
|
||||
import android.media.TranscodingJobParcel;
|
||||
import android.media.TranscodingRequestParcel;
|
||||
import android.media.TranscodingResultParcel;
|
||||
import android.media.TranscodingTestConfig;
|
||||
import android.net.Uri;
|
||||
import android.os.RemoteException;
|
||||
import android.test.ActivityInstrumentationTestCase2;
|
||||
@@ -144,7 +145,7 @@ public class MediaTranscodeManagerWithMockServiceTest
|
||||
new ProcessingJobRunnable(callback, outjob,
|
||||
mPendingTranscodingJobs),
|
||||
inRequest.testConfig == null ? 0
|
||||
: inRequest.testConfig.processingDelayMs,
|
||||
: inRequest.testConfig.processingTotalTimeMs,
|
||||
TimeUnit.MILLISECONDS);
|
||||
mPendingTranscodingJobs.put(outjob.jobId, transcodingFuture);
|
||||
} catch (RejectedExecutionException e) {
|
||||
@@ -353,6 +354,10 @@ public class MediaTranscodeManagerWithMockServiceTest
|
||||
Log.d(TAG, "Starting: testMediaTranscodeManager");
|
||||
|
||||
Semaphore transcodeCompleteSemaphore = new Semaphore(0);
|
||||
TranscodingTestConfig testConfig = new TranscodingTestConfig();
|
||||
testConfig.passThroughMode = true;
|
||||
testConfig.processingTotalTimeMs = 300; // minimum time spent on transcoding.
|
||||
|
||||
TranscodingRequest request =
|
||||
new TranscodingRequest.Builder()
|
||||
.setSourceUri(mSourceHEVCVideoUri)
|
||||
@@ -360,7 +365,7 @@ public class MediaTranscodeManagerWithMockServiceTest
|
||||
.setType(MediaTranscodeManager.TRANSCODING_TYPE_VIDEO)
|
||||
.setPriority(MediaTranscodeManager.PRIORITY_REALTIME)
|
||||
.setVideoTrackFormat(createMediaFormat())
|
||||
.setProcessingDelayMs(300 /* delayMs */)
|
||||
.setTestConfig(testConfig)
|
||||
.build();
|
||||
Executor listenerExecutor = Executors.newSingleThreadExecutor();
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@ public class MediaTranscodingTestRunner extends InstrumentationTestRunner {
|
||||
@Override
|
||||
public TestSuite getAllTests() {
|
||||
TestSuite suite = new InstrumentationTestSuite(this);
|
||||
suite.addTestSuite(MediaTranscodeManagerTest.class);
|
||||
suite.addTestSuite(MediaTranscodeManagerWithMockServiceTest.class);
|
||||
return suite;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user