Loading media/tests/benchmark/MediaBenchmarkTest/Android.bp +1 −1 Original line number Diff line number Diff line Loading @@ -69,6 +69,6 @@ android_library { java_defaults { name: "MediaBenchmark-defaults", min_sdk_version: "28", min_sdk_version: "29", target_sdk_version: "30", } media/tests/benchmark/MediaBenchmarkTest/AndroidManifest.xml +1 −3 Original line number Diff line number Diff line Loading @@ -20,8 +20,6 @@ package="com.android.media.benchmark"> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_INTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_INTERNAL_STORAGE" /> <application tools:ignore="AllowBackup,GoogleAppIndexingWarning,MissingApplicationIcon" Loading media/tests/benchmark/MediaBenchmarkTest/build.gradle +2 −2 Original line number Diff line number Diff line Loading @@ -30,7 +30,7 @@ android { compileSdkVersion 30 defaultConfig { applicationId "com.android.media.benchmark" minSdkVersion 28 minSdkVersion 29 targetSdkVersion 30 versionCode 1 versionName "1.0" Loading media/tests/benchmark/MediaBenchmarkTest/src/main/java/com/android/media/benchmark/library/CodecUtils.java +43 −2 Original line number Diff line number Diff line Loading @@ -2,13 +2,12 @@ package com.android.media.benchmark.library; import android.media.MediaCodecInfo; import android.media.MediaCodecList; import android.media.MediaFormat; import android.os.Build; import java.util.ArrayList; public class CodecUtils { private CodecUtils() {} /** * Queries the MediaCodecList and returns codec names of supported codecs. * Loading Loading @@ -36,4 +35,46 @@ public class CodecUtils { } return supportedCodecs; } /** * Returns a decoder that supports the given MediaFormat along with the "features". * * @param format MediaFormat that the codec should support * @param isSoftware Specifies if this is a software / hardware decoder * @param isEncoder Specifies if the request is for encoders or not. * @param features is the feature that should be supported. * @return name of the codec. */ public static String getMediaCodec(MediaFormat format, boolean isSoftware, String[] features, boolean isEncoder) { MediaCodecList mcl = new MediaCodecList(MediaCodecList.ALL_CODECS); MediaCodecInfo[] codecInfos = mcl.getCodecInfos(); String mime = format.getString(MediaFormat.KEY_MIME); for (MediaCodecInfo codecInfo : codecInfos) { if (codecInfo.isEncoder() != isEncoder) continue; if (isSoftware != codecInfo.isSoftwareOnly()) continue; String[] types = codecInfo.getSupportedTypes(); for (String type : types) { if (type.equalsIgnoreCase(mime)) { boolean isOk = true; MediaCodecInfo.CodecCapabilities codecCapabilities = codecInfo.getCapabilitiesForType(type); if (!codecCapabilities.isFormatSupported(format)) { isOk = false; } if (features != null) { for (String feature : features) { if (!codecCapabilities.isFeatureSupported(feature)) { isOk = false; break; } } } if (isOk) { return codecInfo.getName(); } } } } return null; } } media/tests/benchmark/MediaBenchmarkTest/src/main/java/com/android/media/benchmark/library/Decoder.java +70 −9 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package com.android.media.benchmark.library; import android.view.Surface; import android.media.MediaCodec; import android.media.MediaCodec.BufferInfo; import android.media.MediaFormat; Loading @@ -28,13 +30,17 @@ import java.io.IOException; import java.nio.ByteBuffer; import java.util.ArrayList; public class Decoder { import com.android.media.benchmark.library.IBufferXfer; public class Decoder implements IBufferXfer.IReceiveBuffer { private static final String TAG = "Decoder"; private static final boolean DEBUG = false; private static final int kQueueDequeueTimeoutUs = 1000; private final Object mLock = new Object(); private MediaCodec mCodec; private Surface mSurface = null; private boolean mRender = false; private ArrayList<BufferInfo> mInputBufferInfo; private Stats mStats; Loading @@ -47,9 +53,29 @@ public class Decoder { private ArrayList<ByteBuffer> mInputBuffer; private FileOutputStream mOutputStream; private FrameReleaseQueue mFrameReleaseQueue = null; private IBufferXfer.ISendBuffer mIBufferSend = null; /* success for decoder */ public static final int DECODE_SUCCESS = 0; /* some error happened during decoding */ public static final int DECODE_DECODER_ERROR = -1; /* error while creating a decoder */ public static final int DECODE_CREATE_ERROR = -2; public Decoder() { mStats = new Stats(); } public Stats getStats() { return mStats; }; @Override public boolean receiveBuffer(IBufferXfer.BufferXferInfo info) { MediaCodec codec = (MediaCodec)info.obj; codec.releaseOutputBuffer(info.idx, mRender); return true; } @Override public boolean connect(IBufferXfer.ISendBuffer receiver) { Log.d(TAG,"Setting interface of the sender"); mIBufferSend = receiver; return true; } /** * Setup of decoder * Loading @@ -59,6 +85,17 @@ public class Decoder { mSignalledError = false; mOutputStream = outputStream; } public void setupDecoder(Surface surface, boolean render, boolean useFrameReleaseQueue, int frameRate) { mSignalledError = false; mOutputStream = null; mSurface = surface; mRender = render; if (useFrameReleaseQueue) { Log.i(TAG, "Using FrameReleaseQueue with frameRate " + frameRate); mFrameReleaseQueue = new FrameReleaseQueue(mRender, frameRate); } } private MediaCodec createCodec(String codecName, MediaFormat format) throws IOException { String mime = format.getString(MediaFormat.KEY_MIME); Loading Loading @@ -95,7 +132,8 @@ public class Decoder { * @param asyncMode Will run on async implementation if true * @param format For creating the decoder if codec name is empty and configuring it * @param codecName Will create the decoder with codecName * @return 0 if decode was successful , -1 for fail, -2 for decoder not created * @return DECODE_SUCCESS if decode was successful, DECODE_DECODER_ERROR for fail, * DECODE_CREATE_ERROR for decoder not created * @throws IOException if the codec cannot be created. */ public int decode(@NonNull ArrayList<ByteBuffer> inputBuffer, Loading @@ -112,7 +150,10 @@ public class Decoder { long sTime = mStats.getCurTime(); mCodec = createCodec(codecName, format); if (mCodec == null) { return -2; return DECODE_CREATE_ERROR; } if (mFrameReleaseQueue != null) { mFrameReleaseQueue.setMediaCodec(mCodec); } if (asyncMode) { mCodec.setCallback(new MediaCodec.Callback() { Loading Loading @@ -158,7 +199,7 @@ public class Decoder { if (DEBUG) { Log.d(TAG, "Media Format : " + format.toString()); } mCodec.configure(format, null, null, isEncoder); mCodec.configure(format, mSurface, null, isEncoder); mCodec.start(); Log.i(TAG, "Codec started "); long eTime = mStats.getCurTime(); Loading @@ -168,7 +209,7 @@ public class Decoder { try { synchronized (mLock) { mLock.wait(); } if (mSignalledError) { return -1; return DECODE_DECODER_ERROR; } } catch (InterruptedException e) { e.printStackTrace(); Loading Loading @@ -201,7 +242,7 @@ public class Decoder { Log.e(TAG, "MediaCodec.dequeueOutputBuffer" + " returned invalid index " + outputBufferId); return -1; return DECODE_DECODER_ERROR; } } else { mStats.addOutputTime(); Loading @@ -212,9 +253,13 @@ public class Decoder { } } } if (mFrameReleaseQueue != null) { Log.i(TAG, "Ending FrameReleaseQueue"); mFrameReleaseQueue.stopFrameRelease(); } mInputBuffer.clear(); mInputBufferInfo.clear(); return 0; return DECODE_SUCCESS; } /** Loading Loading @@ -290,7 +335,9 @@ public class Decoder { if (DEBUG) { Log.d(TAG, "In OutputBufferAvailable ," + " output frame number = " + mNumOutputFrame); + " output frame number = " + mNumOutputFrame + " timestamp = " + outputBufferInfo.presentationTimeUs + " size = " + outputBufferInfo.size); } if (mOutputStream != null) { try { Loading @@ -303,7 +350,21 @@ public class Decoder { Log.d(TAG, "Error Dumping File: Exception " + e.toString()); } } mediaCodec.releaseOutputBuffer(outputBufferId, false); if (mFrameReleaseQueue != null) { mFrameReleaseQueue.pushFrame(mNumOutputFrame, outputBufferId, outputBufferInfo.presentationTimeUs); } else if (mIBufferSend != null) { IBufferXfer.BufferXferInfo info = new IBufferXfer.BufferXferInfo(); info.buf = mediaCodec.getOutputBuffer(outputBufferId); info.idx = outputBufferId; info.obj = mediaCodec; info.bytesRead = outputBufferInfo.size; info.presentationTimeUs = outputBufferInfo.presentationTimeUs; info.flag = outputBufferInfo.flags; mIBufferSend.sendBuffer(this, info); } else { mediaCodec.releaseOutputBuffer(outputBufferId, mRender); } mSawOutputEOS = (outputBufferInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0; if (mSawOutputEOS) { Log.i(TAG, "Saw output EOS"); Loading Loading
media/tests/benchmark/MediaBenchmarkTest/Android.bp +1 −1 Original line number Diff line number Diff line Loading @@ -69,6 +69,6 @@ android_library { java_defaults { name: "MediaBenchmark-defaults", min_sdk_version: "28", min_sdk_version: "29", target_sdk_version: "30", }
media/tests/benchmark/MediaBenchmarkTest/AndroidManifest.xml +1 −3 Original line number Diff line number Diff line Loading @@ -20,8 +20,6 @@ package="com.android.media.benchmark"> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_INTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_INTERNAL_STORAGE" /> <application tools:ignore="AllowBackup,GoogleAppIndexingWarning,MissingApplicationIcon" Loading
media/tests/benchmark/MediaBenchmarkTest/build.gradle +2 −2 Original line number Diff line number Diff line Loading @@ -30,7 +30,7 @@ android { compileSdkVersion 30 defaultConfig { applicationId "com.android.media.benchmark" minSdkVersion 28 minSdkVersion 29 targetSdkVersion 30 versionCode 1 versionName "1.0" Loading
media/tests/benchmark/MediaBenchmarkTest/src/main/java/com/android/media/benchmark/library/CodecUtils.java +43 −2 Original line number Diff line number Diff line Loading @@ -2,13 +2,12 @@ package com.android.media.benchmark.library; import android.media.MediaCodecInfo; import android.media.MediaCodecList; import android.media.MediaFormat; import android.os.Build; import java.util.ArrayList; public class CodecUtils { private CodecUtils() {} /** * Queries the MediaCodecList and returns codec names of supported codecs. * Loading Loading @@ -36,4 +35,46 @@ public class CodecUtils { } return supportedCodecs; } /** * Returns a decoder that supports the given MediaFormat along with the "features". * * @param format MediaFormat that the codec should support * @param isSoftware Specifies if this is a software / hardware decoder * @param isEncoder Specifies if the request is for encoders or not. * @param features is the feature that should be supported. * @return name of the codec. */ public static String getMediaCodec(MediaFormat format, boolean isSoftware, String[] features, boolean isEncoder) { MediaCodecList mcl = new MediaCodecList(MediaCodecList.ALL_CODECS); MediaCodecInfo[] codecInfos = mcl.getCodecInfos(); String mime = format.getString(MediaFormat.KEY_MIME); for (MediaCodecInfo codecInfo : codecInfos) { if (codecInfo.isEncoder() != isEncoder) continue; if (isSoftware != codecInfo.isSoftwareOnly()) continue; String[] types = codecInfo.getSupportedTypes(); for (String type : types) { if (type.equalsIgnoreCase(mime)) { boolean isOk = true; MediaCodecInfo.CodecCapabilities codecCapabilities = codecInfo.getCapabilitiesForType(type); if (!codecCapabilities.isFormatSupported(format)) { isOk = false; } if (features != null) { for (String feature : features) { if (!codecCapabilities.isFeatureSupported(feature)) { isOk = false; break; } } } if (isOk) { return codecInfo.getName(); } } } } return null; } }
media/tests/benchmark/MediaBenchmarkTest/src/main/java/com/android/media/benchmark/library/Decoder.java +70 −9 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package com.android.media.benchmark.library; import android.view.Surface; import android.media.MediaCodec; import android.media.MediaCodec.BufferInfo; import android.media.MediaFormat; Loading @@ -28,13 +30,17 @@ import java.io.IOException; import java.nio.ByteBuffer; import java.util.ArrayList; public class Decoder { import com.android.media.benchmark.library.IBufferXfer; public class Decoder implements IBufferXfer.IReceiveBuffer { private static final String TAG = "Decoder"; private static final boolean DEBUG = false; private static final int kQueueDequeueTimeoutUs = 1000; private final Object mLock = new Object(); private MediaCodec mCodec; private Surface mSurface = null; private boolean mRender = false; private ArrayList<BufferInfo> mInputBufferInfo; private Stats mStats; Loading @@ -47,9 +53,29 @@ public class Decoder { private ArrayList<ByteBuffer> mInputBuffer; private FileOutputStream mOutputStream; private FrameReleaseQueue mFrameReleaseQueue = null; private IBufferXfer.ISendBuffer mIBufferSend = null; /* success for decoder */ public static final int DECODE_SUCCESS = 0; /* some error happened during decoding */ public static final int DECODE_DECODER_ERROR = -1; /* error while creating a decoder */ public static final int DECODE_CREATE_ERROR = -2; public Decoder() { mStats = new Stats(); } public Stats getStats() { return mStats; }; @Override public boolean receiveBuffer(IBufferXfer.BufferXferInfo info) { MediaCodec codec = (MediaCodec)info.obj; codec.releaseOutputBuffer(info.idx, mRender); return true; } @Override public boolean connect(IBufferXfer.ISendBuffer receiver) { Log.d(TAG,"Setting interface of the sender"); mIBufferSend = receiver; return true; } /** * Setup of decoder * Loading @@ -59,6 +85,17 @@ public class Decoder { mSignalledError = false; mOutputStream = outputStream; } public void setupDecoder(Surface surface, boolean render, boolean useFrameReleaseQueue, int frameRate) { mSignalledError = false; mOutputStream = null; mSurface = surface; mRender = render; if (useFrameReleaseQueue) { Log.i(TAG, "Using FrameReleaseQueue with frameRate " + frameRate); mFrameReleaseQueue = new FrameReleaseQueue(mRender, frameRate); } } private MediaCodec createCodec(String codecName, MediaFormat format) throws IOException { String mime = format.getString(MediaFormat.KEY_MIME); Loading Loading @@ -95,7 +132,8 @@ public class Decoder { * @param asyncMode Will run on async implementation if true * @param format For creating the decoder if codec name is empty and configuring it * @param codecName Will create the decoder with codecName * @return 0 if decode was successful , -1 for fail, -2 for decoder not created * @return DECODE_SUCCESS if decode was successful, DECODE_DECODER_ERROR for fail, * DECODE_CREATE_ERROR for decoder not created * @throws IOException if the codec cannot be created. */ public int decode(@NonNull ArrayList<ByteBuffer> inputBuffer, Loading @@ -112,7 +150,10 @@ public class Decoder { long sTime = mStats.getCurTime(); mCodec = createCodec(codecName, format); if (mCodec == null) { return -2; return DECODE_CREATE_ERROR; } if (mFrameReleaseQueue != null) { mFrameReleaseQueue.setMediaCodec(mCodec); } if (asyncMode) { mCodec.setCallback(new MediaCodec.Callback() { Loading Loading @@ -158,7 +199,7 @@ public class Decoder { if (DEBUG) { Log.d(TAG, "Media Format : " + format.toString()); } mCodec.configure(format, null, null, isEncoder); mCodec.configure(format, mSurface, null, isEncoder); mCodec.start(); Log.i(TAG, "Codec started "); long eTime = mStats.getCurTime(); Loading @@ -168,7 +209,7 @@ public class Decoder { try { synchronized (mLock) { mLock.wait(); } if (mSignalledError) { return -1; return DECODE_DECODER_ERROR; } } catch (InterruptedException e) { e.printStackTrace(); Loading Loading @@ -201,7 +242,7 @@ public class Decoder { Log.e(TAG, "MediaCodec.dequeueOutputBuffer" + " returned invalid index " + outputBufferId); return -1; return DECODE_DECODER_ERROR; } } else { mStats.addOutputTime(); Loading @@ -212,9 +253,13 @@ public class Decoder { } } } if (mFrameReleaseQueue != null) { Log.i(TAG, "Ending FrameReleaseQueue"); mFrameReleaseQueue.stopFrameRelease(); } mInputBuffer.clear(); mInputBufferInfo.clear(); return 0; return DECODE_SUCCESS; } /** Loading Loading @@ -290,7 +335,9 @@ public class Decoder { if (DEBUG) { Log.d(TAG, "In OutputBufferAvailable ," + " output frame number = " + mNumOutputFrame); + " output frame number = " + mNumOutputFrame + " timestamp = " + outputBufferInfo.presentationTimeUs + " size = " + outputBufferInfo.size); } if (mOutputStream != null) { try { Loading @@ -303,7 +350,21 @@ public class Decoder { Log.d(TAG, "Error Dumping File: Exception " + e.toString()); } } mediaCodec.releaseOutputBuffer(outputBufferId, false); if (mFrameReleaseQueue != null) { mFrameReleaseQueue.pushFrame(mNumOutputFrame, outputBufferId, outputBufferInfo.presentationTimeUs); } else if (mIBufferSend != null) { IBufferXfer.BufferXferInfo info = new IBufferXfer.BufferXferInfo(); info.buf = mediaCodec.getOutputBuffer(outputBufferId); info.idx = outputBufferId; info.obj = mediaCodec; info.bytesRead = outputBufferInfo.size; info.presentationTimeUs = outputBufferInfo.presentationTimeUs; info.flag = outputBufferInfo.flags; mIBufferSend.sendBuffer(this, info); } else { mediaCodec.releaseOutputBuffer(outputBufferId, mRender); } mSawOutputEOS = (outputBufferInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0; if (mSawOutputEOS) { Log.i(TAG, "Saw output EOS"); Loading