Video editing v3.0.0.7版本的 MD5 值为:2b508ef283a684171ac2c48470b3083c
以下内容为反编译后的 SequentialFrameView.java 源代码,内容仅作参考
package com.vivo.animationhelper.view;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.AssetManager;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.os.Build;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import androidx.appcompat.widget.AppCompatImageView;
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.util.List;
public class SequentialFrameView extends AppCompatImageView {
public static final boolean DEBUG_SWITCH = false;
public static final int INFINITE = 0;
public static final int INVALIDATE_INTERVAL_DEFAULT = 16;
public static final boolean IS_ENG = Build.TYPE.equals("eng");
public static final String KEY_VIVO_LOG_CTRL = "persist.sys.log.ctrl";
private static final String TAG = "SequentialFrameView";
private static final int THREADS_COUNT_MAX = 8;
private static final int THREADS_COUNT_MIN = 1;
private static final String VERSION = "1.0.0.6";
public static boolean sbLogEnable;
private final int MSG_INVALIDATE;
private Bitmap mBitmap;
private int mBitmapAndOptionCount;
private int mBitmapAndOptionCountMinus1;
private int mBitmapAndOptionDecodingIndex;
private BitmapFactory.Options mBitmapOptionForMeasure;
private BitmapFactory.Options[] mBitmapOptions;
private BitmapProvider mBitmapProvider;
private boolean mCanDraw;
private boolean mCanDrawLast;
private Context mContext;
private DecoderThread[] mDecoderThreads;
private int[] mDrawableIds;
private int mDrawingFrameId;
private long mEndTime;
private List<String> mFiles;
private int mFrameCount;
private boolean mHasStarted;
private int mInvalidateInterval;
private int mInvalidateIntervalDelay;
private int[] mInvalidateIntervalFromArray;
private long mLastOndrawTime;
private int mMeasureHeight;
private int mMeasureWidth;
private Paint mPaint;
private Rect mRectDst;
private Rect mRectSrc;
private int mRepeatCount;
private int mRepeatingTimes;
private SequentialFrameAnimationListener mSequentialFrameAnimationListener;
private long mStartTime;
private final WeakReference<SequentialFrameView> mThisWeakRef;
private int mThreadIndex;
private int mThreadsCount;
public static class BitmapProvider {
private AssetManager mAssetManager;
private boolean mIsFromAssets;
private Resources mRes;
public BitmapProvider(Context context, boolean z, boolean z2) {
this.mRes = null;
this.mAssetManager = null;
this.mIsFromAssets = true;
if (context != null) {
if (z) {
this.mIsFromAssets = z2;
if (this.mIsFromAssets) {
this.mAssetManager = context.getAssets();
return;
}
return;
}
this.mRes = context.getResources();
}
}
public Bitmap decodeBitmap(int i, BitmapFactory.Options options) {
return BitmapFactory.decodeResource(this.mRes, i, options);
}
public Bitmap decodeBitmap(String str, BitmapFactory.Options options) {
if (this.mIsFromAssets) {
return BitmapFactory.decodeStream(this.mAssetManager.open(str), null, options);
}
return BitmapFactory.decodeFile(str, options);
}
}
public interface SequentialFrameAnimationListener {
void onSequentialFrameAnimationEnd();
void onSequentialFrameAnimationStart();
}
static {
sbLogEnable = IS_ENG || Log.isLoggable(TAG, 2);
}
public SequentialFrameView(Context context, AttributeSet attributeSet) {
super(context, attributeSet);
this.MSG_INVALIDATE = 0;
this.mPaint = null;
this.mBitmapOptions = null;
this.mBitmapOptionForMeasure = new BitmapFactory.Options();
this.mStartTime = 0L;
this.mEndTime = 0L;
this.mThisWeakRef = new WeakReference<>(this);
this.mDrawableIds = null;
this.mFiles = null;
this.mFrameCount = 0;
this.mThreadsCount = 1;
this.mBitmapAndOptionCount = 2;
this.mBitmapAndOptionCountMinus1 = this.mBitmapAndOptionCount - 1;
this.mDrawingFrameId = 0;
this.mThreadIndex = 0;
this.mBitmapAndOptionDecodingIndex = this.mBitmapAndOptionCountMinus1;
this.mDecoderThreads = null;
this.mBitmapProvider = null;
this.mCanDraw = false;
this.mCanDrawLast = this.mCanDraw;
this.mHasStarted = false;
this.mContext = null;
this.mBitmap = null;
this.mRectSrc = null;
this.mRectDst = null;
this.mInvalidateInterval = 16;
this.mInvalidateIntervalDelay = -16;
this.mInvalidateIntervalFromArray = null;
this.mRepeatCount = 0;
this.mRepeatingTimes = 0;
this.mSequentialFrameAnimationListener = null;
this.mLastOndrawTime = 0L;
this.mMeasureWidth = Integer.MAX_VALUE;
this.mMeasureHeight = Integer.MAX_VALUE;
this.mContext = context;
Log.d(TAG, "SequentialFrameView constructor version:1.0.0.6");
this.mBitmapOptionForMeasure.inJustDecodeBounds = true;
}
private int getMeasureSize(int i, boolean z) {
int mode = View.MeasureSpec.getMode(i);
int size = View.MeasureSpec.getSize(i);
if (mode == 1073741824) {
return size;
}
if (z) {
return Math.min(this.mMeasureWidth, size);
}
return Math.min(this.mMeasureHeight, size);
}
@Override
protected void onDraw(Canvas canvas) {
Rect rect;
SequentialFrameAnimationListener sequentialFrameAnimationListener;
super.onDraw(canvas);
if (this.mCanDraw) {
if (!this.mCanDrawLast && (sequentialFrameAnimationListener = this.mSequentialFrameAnimationListener) != null) {
sequentialFrameAnimationListener.onSequentialFrameAnimationStart();
}
int i = this.mDrawingFrameId + this.mBitmapAndOptionCountMinus1;
int i2 = this.mFrameCount;
if (i >= i2) {
i -= i2;
}
int i3 = this.mThreadIndex + 1;
int i4 = this.mThreadsCount;
if (i3 >= i4) {
i3 -= i4;
}
if (sbLogEnable) {
this.mStartTime = System.currentTimeMillis();
}
try {
this.mBitmap = this.mDecoderThreads[i3].getDecodedBitmap();
} catch (InterruptedException e) {
e.printStackTrace();
}
Bitmap bitmap = this.mBitmap;
if (bitmap != null && (rect = this.mRectDst) != null) {
canvas.drawBitmap(bitmap, this.mRectSrc, rect, this.mPaint);
}
int[] iArr = this.mDrawableIds;
if (iArr != null) {
this.mDecoderThreads[this.mThreadIndex].decode(iArr[i], this.mBitmapOptions[this.mBitmapAndOptionDecodingIndex]);
} else {
this.mDecoderThreads[this.mThreadIndex].decode(this.mFiles.get(i), this.mBitmapOptions[this.mBitmapAndOptionDecodingIndex]);
}
if (sbLogEnable) {
this.mEndTime = System.currentTimeMillis();
Log.d(TAG, "SequentialFrameView onDraw version:1.0.0.6, mDrawingFrameId:" + this.mDrawingFrameId + ", decodingFrameId:" + i + ", obtainingBitmapThreadId:" + i3 + ", mThreadIndex:" + this.mThreadIndex + ", mFrameCount:" + this.mFrameCount + ", mThreadsCount:" + this.mThreadsCount + ", mBitmap:" + this.mBitmap + ", mRectDst" + this.mRectDst + ", mBitmapAndOptionDecodingIndex:" + this.mBitmapAndOptionDecodingIndex + ", decode take time:" + (this.mEndTime - this.mStartTime) + ", onDrawRealInterval:" + (this.mEndTime - this.mLastOndrawTime));
this.mLastOndrawTime = this.mEndTime;
}
this.mThreadIndex++;
int i5 = this.mThreadIndex;
int i6 = this.mThreadsCount;
if (i5 >= i6) {
this.mThreadIndex = i5 - i6;
}
this.mBitmapAndOptionDecodingIndex++;
int i7 = this.mBitmapAndOptionDecodingIndex;
int i8 = this.mBitmapAndOptionCount;
if (i7 >= i8) {
this.mBitmapAndOptionDecodingIndex = i7 - i8;
}
this.mDrawingFrameId++;
int i9 = this.mDrawingFrameId;
int i10 = this.mFrameCount;
if (i9 >= i10) {
this.mRepeatingTimes++;
this.mDrawingFrameId = i9 - i10;
int i11 = this.mRepeatCount;
if (i11 != 0 && this.mRepeatingTimes >= i11) {
this.mCanDrawLast = this.mCanDraw;
this.mCanDraw = false;
SequentialFrameAnimationListener sequentialFrameAnimationListener2 = this.mSequentialFrameAnimationListener;
if (sequentialFrameAnimationListener2 != null) {
sequentialFrameAnimationListener2.onSequentialFrameAnimationEnd();
}
}
}
this.mCanDrawLast = this.mCanDraw;
if (this.mInvalidateIntervalFromArray != null) {
this.mInvalidateIntervalDelay = r7[this.mDrawingFrameId] - 16;
} else {
this.mInvalidateIntervalDelay = this.mInvalidateInterval - 16;
}
int i12 = this.mInvalidateIntervalDelay;
if (i12 > 0) {
postInvalidateDelayed(i12);
} else {
invalidate();
}
}
}
@Override
@SuppressLint({"DrawAllocation"})
protected void onLayout(boolean z, int i, int i2, int i3, int i4) {
super.onLayout(z, i, i2, i3, i4);
if (this.mRectDst == null) {
this.mRectDst = new Rect(0, 0, getWidth(), getHeight());
}
Log.d(TAG, "SequentialFrameView onLayout mRectDst" + this.mRectDst);
}
@Override
protected void onMeasure(int i, int i2) {
super.onMeasure(i, i2);
int measureSize = getMeasureSize(i, true);
int measureSize2 = getMeasureSize(i2, false);
setMeasuredDimension(measureSize, measureSize2);
Log.d(TAG, "SequentialFrameView onMeasure widthMeasureSpec mode:" + View.MeasureSpec.getMode(i) + ", specSize:" + View.MeasureSpec.getSize(i) + ", heightMeasureSpec mode:" + View.MeasureSpec.getMode(i2) + ", specSize:" + View.MeasureSpec.getSize(i2) + ", setMeasuredDimension width:" + measureSize + ", height:" + measureSize2 + ", mMeasureWidth:" + this.mMeasureWidth + ", mMeasureHeight:" + this.mMeasureHeight);
}
public void release() {
if (this.mDecoderThreads != null) {
for (int i = 0; i < this.mThreadsCount; i++) {
DecoderThread[] decoderThreadArr = this.mDecoderThreads;
if (decoderThreadArr[i] != null) {
decoderThreadArr[i].terminate();
}
}
for (int i2 = 0; i2 < this.mThreadsCount; i2++) {
DecoderThread[] decoderThreadArr2 = this.mDecoderThreads;
if (decoderThreadArr2[i2] != null) {
decoderThreadArr2[i2].awaitTerminationDone();
this.mDecoderThreads[i2] = null;
}
}
}
if (this.mBitmapOptions != null) {
for (int i3 = 0; i3 < this.mBitmapAndOptionCount; i3++) {
BitmapFactory.Options[] optionsArr = this.mBitmapOptions;
if (optionsArr[i3] != null) {
optionsArr[i3].inBitmap = null;
optionsArr[i3] = null;
}
}
}
this.mDecoderThreads = null;
this.mPaint = null;
this.mBitmapOptions = null;
this.mBitmapOptionForMeasure = null;
this.mBitmap = null;
this.mSequentialFrameAnimationListener = null;
this.mDrawableIds = null;
this.mFiles = null;
this.mInvalidateIntervalFromArray = null;
}
public void setDrawArea(int i, int i2, int i3, int i4) {
if (i3 >= 0 && i4 >= 0) {
this.mRectDst = new Rect(i, i2, i + i3, i2 + i4);
}
Log.d(TAG, "SequentialFrameView setDrawArea left:" + i + ", top:" + i2 + ", width:" + i3 + ", height:" + i4 + ", mRectDst" + this.mRectDst);
}
public void setFiles(List<String> list, boolean z) {
if (list != null && this.mDecoderThreads == null) {
this.mBitmapProvider = new BitmapProvider(this.mContext, true, z);
this.mFiles = list;
this.mDrawableIds = null;
this.mFrameCount = this.mFiles.size();
try {
this.mBitmap = this.mBitmapProvider.decodeBitmap(this.mFiles.get(0), this.mBitmapOptionForMeasure);
} catch (IOException e) {
Log.e(TAG, "IOException when setFiles ! cause : " + e.getCause());
}
BitmapFactory.Options options = this.mBitmapOptionForMeasure;
this.mMeasureWidth = options.outWidth;
this.mMeasureHeight = options.outHeight;
Log.d(TAG, "SequentialFrameView setFiles mMeasureWidth:" + this.mMeasureWidth + ", mMeasureHeight:" + this.mMeasureHeight + ", mBitmap:" + this.mBitmap);
}
}
public void setFrameIds(int[] iArr) {
if (iArr != null && this.mDecoderThreads == null) {
this.mBitmapProvider = new BitmapProvider(this.mContext, false, false);
this.mDrawableIds = iArr;
this.mFiles = null;
int[] iArr2 = this.mDrawableIds;
this.mFrameCount = iArr2.length;
try {
this.mBitmap = this.mBitmapProvider.decodeBitmap(iArr2[0], this.mBitmapOptionForMeasure);
} catch (IOException e) {
Log.e(TAG, "IOException when setFrameIds ! cause : " + e.getCause());
}
BitmapFactory.Options options = this.mBitmapOptionForMeasure;
this.mMeasureWidth = options.outWidth;
this.mMeasureHeight = options.outHeight;
Log.d(TAG, "SequentialFrameView setFrameIds mMeasureWidth:" + this.mMeasureWidth + ", mMeasureHeight:" + this.mMeasureHeight + ", mBitmap:" + this.mBitmap);
}
}
public void setInvalidateInterval(int i) {
if (i > 0) {
this.mInvalidateInterval = i;
this.mInvalidateIntervalFromArray = null;
this.mInvalidateIntervalDelay = -16;
}
}
public void setInvalidateIntervalFromArray(int[] iArr) {
if (iArr != null) {
int i = this.mFrameCount;
if (i > 0 && i != iArr.length) {
this.mInvalidateIntervalFromArray = null;
} else {
this.mInvalidateIntervalFromArray = iArr;
this.mInvalidateInterval = 16;
}
}
}
public void setPaint(Paint paint) {
this.mPaint = paint;
}
public void setRepeatCount(int i) {
if (i < 0) {
i = 0;
}
this.mRepeatCount = i;
}
public void setSequentialFrameAnimationListener(SequentialFrameAnimationListener sequentialFrameAnimationListener) {
this.mSequentialFrameAnimationListener = sequentialFrameAnimationListener;
}
public void setThreadCount(int i) {
if (this.mDecoderThreads != null) {
return;
}
if (i >= 1 && i <= 8) {
this.mThreadsCount = i;
}
int i2 = this.mBitmapAndOptionCount;
int i3 = this.mThreadsCount;
if (i2 < i3) {
this.mBitmapAndOptionCount = i3;
}
this.mDecoderThreads = new DecoderThread[this.mThreadsCount];
for (int i4 = 0; i4 < this.mThreadsCount; i4++) {
this.mDecoderThreads[i4] = new DecoderThread(this.mThisWeakRef, i4);
this.mDecoderThreads[i4].start();
}
this.mBitmapOptions = new BitmapFactory.Options[this.mBitmapAndOptionCount];
for (int i5 = 0; i5 < this.mBitmapAndOptionCount; i5++) {
this.mBitmapOptions[i5] = new BitmapFactory.Options();
}
}
public void start() {
boolean z;
int i;
int[] iArr = this.mInvalidateIntervalFromArray;
if (iArr == null || (i = this.mFrameCount) <= 0 || iArr.length == i) {
if (this.mDecoderThreads == null) {
setThreadCount(1);
}
if ((this.mDrawableIds != null || this.mFiles != null) && !this.mHasStarted) {
int i2 = this.mFrameCount;
if (i2 > 0) {
this.mBitmapAndOptionCountMinus1 = this.mBitmapAndOptionCount - 1;
int[] iArr2 = this.mDrawableIds;
if (iArr2 != null) {
this.mDecoderThreads[0].decode(iArr2[(this.mDrawingFrameId + 0) % i2], this.mBitmapOptions[0]);
} else {
this.mDecoderThreads[0].decode(this.mFiles.get((this.mDrawingFrameId + 0) % i2), this.mBitmapOptions[0]);
}
try {
this.mBitmapOptions[0].inBitmap = this.mDecoderThreads[0].getDecodedBitmap();
if (this.mBitmapOptions[0].inBitmap == null) {
Log.e(TAG, "SequentialFrameView start mBitmapOptions[0].inBitmap is null");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
int i3 = this.mBitmapAndOptionCountMinus1;
this.mBitmapAndOptionDecodingIndex = i3;
this.mThreadIndex = i3;
int i4 = this.mThreadIndex;
int i5 = this.mThreadsCount;
if (i4 >= i5) {
this.mThreadIndex = i4 - i5;
}
for (int i6 = 0; i6 <= this.mBitmapAndOptionCountMinus1; i6++) {
BitmapFactory.Options[] optionsArr = this.mBitmapOptions;
optionsArr[i6].inBitmap = Bitmap.createBitmap(optionsArr[0].inBitmap.getWidth(), this.mBitmapOptions[0].inBitmap.getHeight(), this.mBitmapOptions[0].inBitmap.getConfig());
}
if (this.mDrawableIds != null) {
for (int i7 = 1; i7 < this.mBitmapAndOptionCountMinus1; i7++) {
this.mDecoderThreads[i7].decode(this.mDrawableIds[(this.mDrawingFrameId + i7) % this.mFrameCount], this.mBitmapOptions[i7]);
}
} else {
for (int i8 = 1; i8 < this.mBitmapAndOptionCountMinus1; i8++) {
this.mDecoderThreads[i8].decode(this.mFiles.get((this.mDrawingFrameId + i8) % this.mFrameCount), this.mBitmapOptions[i8]);
}
}
this.mCanDrawLast = this.mCanDraw;
this.mCanDraw = true;
this.mHasStarted = true;
this.mRepeatingTimes = 0;
postInvalidate();
return;
}
return;
}
if (!this.mHasStarted || (z = this.mCanDraw)) {
return;
}
this.mCanDrawLast = z;
this.mCanDraw = true;
this.mRepeatingTimes = 0;
postInvalidate();
}
}
public void stop() {
boolean z = this.mCanDraw;
if (z) {
this.mCanDrawLast = z;
this.mCanDraw = false;
SequentialFrameAnimationListener sequentialFrameAnimationListener = this.mSequentialFrameAnimationListener;
if (sequentialFrameAnimationListener != null) {
sequentialFrameAnimationListener.onSequentialFrameAnimationEnd();
}
}
}
public static class DecoderThread extends Thread {
private static final int DECODER_THREAD_FRAME_ID_UNINITIALIZED = -1;
private static final boolean LOG_THREADS = false;
private static final String TAG = "DecoderThread";
private WeakReference<SequentialFrameView> mSequentialFrameViewWeakRef;
private int mThreadId;
private final Object mSyncObject = new Object();
private int mFrameId = -1;
private String mFileName = null;
private boolean mNeedDecode = false;
private boolean mDecoded = false;
private boolean mExit = false;
private boolean mExited = false;
private Bitmap mBitmap = null;
private BitmapFactory.Options mOptions = null;
public DecoderThread(WeakReference<SequentialFrameView> weakReference, int i) {
this.mSequentialFrameViewWeakRef = weakReference;
this.mThreadId = i;
}
private void guardedRun() {
synchronized (this.mSyncObject) {
while (!this.mExit) {
if (!this.mNeedDecode) {
this.mSyncObject.wait();
}
SequentialFrameView sequentialFrameView = this.mSequentialFrameViewWeakRef.get();
if (sequentialFrameView == null) {
this.mSyncObject.notifyAll();
return;
}
if (this.mFileName != null) {
this.mBitmap = sequentialFrameView.mBitmapProvider.decodeBitmap(this.mFileName, this.mOptions);
} else if (this.mFrameId != -1) {
this.mBitmap = sequentialFrameView.mBitmapProvider.decodeBitmap(this.mFrameId, this.mOptions);
} else {
this.mBitmap = null;
}
this.mDecoded = true;
this.mNeedDecode = false;
this.mSyncObject.notifyAll();
}
}
}
public void awaitDecodeDone() {
synchronized (this.mSyncObject) {
while (!this.mDecoded) {
this.mSyncObject.wait();
}
}
}
public void awaitTerminationDone() {
synchronized (this.mSyncObject) {
this.mSyncObject.notifyAll();
while (!this.mExited) {
try {
this.mSyncObject.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.i(TAG, "tid=" + getId() + " awaitTerminationDone mThreadId:" + this.mThreadId + ", mFrameId:" + this.mFrameId + ", mFileName:" + this.mFileName + ", mExit:" + this.mExit + ", mNeedDecode:" + this.mNeedDecode + " mDecoded:" + this.mDecoded + ", mExited:" + this.mExited);
}
}
}
public void decode(int i, BitmapFactory.Options options) {
synchronized (this.mSyncObject) {
this.mFrameId = i;
this.mFileName = null;
this.mNeedDecode = true;
this.mDecoded = false;
this.mOptions = options;
this.mSyncObject.notifyAll();
}
}
public Bitmap getDecodedBitmap() {
synchronized (this.mSyncObject) {
while (!this.mDecoded) {
this.mSyncObject.wait();
}
}
return this.mBitmap;
}
@Override
public void run() {
setName("DecoderThread " + this.mThreadId);
Log.i(TAG, "starting tid=" + getId());
boolean z = true;
z = true;
try {
try {
guardedRun();
synchronized (this.mSyncObject) {
this.mDecoded = true;
this.mExited = true;
Object obj = this.mSyncObject;
obj.notifyAll();
z = obj;
}
} catch (IOException e) {
e.printStackTrace();
synchronized (this.mSyncObject) {
this.mDecoded = true;
this.mExited = true;
Object obj2 = this.mSyncObject;
obj2.notifyAll();
z = obj2;
}
} catch (InterruptedException e2) {
e2.printStackTrace();
synchronized (this.mSyncObject) {
this.mDecoded = true;
this.mExited = true;
Object obj3 = this.mSyncObject;
obj3.notifyAll();
z = obj3;
}
}
this.mSequentialFrameViewWeakRef = null;
} catch (Throwable th) {
synchronized (this.mSyncObject) {
this.mDecoded = z;
this.mExited = z;
this.mSyncObject.notifyAll();
this.mSequentialFrameViewWeakRef = null;
throw th;
}
}
}
public void terminate() {
this.mExit = true;
}
public void decode(String str, BitmapFactory.Options options) {
synchronized (this.mSyncObject) {
this.mFileName = str;
this.mFrameId = -1;
this.mNeedDecode = true;
this.mDecoded = false;
this.mOptions = options;
this.mSyncObject.notifyAll();
}
}
}
}