Improve gif play
This commit is contained in:
1 parent
c463714a9b
commit
25505bb0a9
6 files changed
+98
-41
No files matched your search
@@ -266,15 +266,11 @@ public class GifDecoder {
|
||||
*/
|
||||
public synchronized Bitmap getNextFrame() {
|
||||
if (header.frameCount <= 0 || framePointer < 0) {
|
||||
if (Log.isLoggable(TAG, Log.DEBUG)) {
|
||||
Log.d(TAG, "unable to decode frame, frameCount=" + header.frameCount + " framePointer=" + framePointer);
|
||||
}
|
||||
Log.d(TAG, "unable to decode frame, frameCount=" + header.frameCount + " framePointer=" + framePointer);
|
||||
status = STATUS_FORMAT_ERROR;
|
||||
}
|
||||
if (status == STATUS_FORMAT_ERROR || status == STATUS_READ_ERROR) {
|
||||
if (Log.isLoggable(TAG, Log.DEBUG)) {
|
||||
Log.d(TAG, "Unable to decode frame, status=" + status);
|
||||
}
|
||||
Log.d(TAG, "Unable to decode frame, status=" + status);
|
||||
return null;
|
||||
}
|
||||
status = STATUS_OK;
|
||||
@@ -305,9 +301,7 @@ public class GifDecoder {
|
||||
act[currentFrame.transIndex] = 0;
|
||||
}
|
||||
if (act == null) {
|
||||
if (Log.isLoggable(TAG, Log.DEBUG)) {
|
||||
Log.d(TAG, "No Valid Color Table");
|
||||
}
|
||||
Log.d(TAG, "No Valid Color Table");
|
||||
// No color table defined.
|
||||
status = STATUS_FORMAT_ERROR;
|
||||
return null;
|
||||
@@ -681,6 +675,7 @@ public class GifDecoder {
|
||||
readChunkIfNeeded();
|
||||
return workBuffer[workBufferPosition++] & 0xFF;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
status = STATUS_FORMAT_ERROR;
|
||||
return 0;
|
||||
}
|
||||
@@ -712,6 +707,7 @@ public class GifDecoder {
|
||||
System.arraycopy(workBuffer, 0, block, remaining, secondHalfRemaining);
|
||||
workBufferPosition += secondHalfRemaining;
|
||||
} else {
|
||||
Log.d(TAG, "Can't read block");
|
||||
status = STATUS_FORMAT_ERROR;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
||||
@@ -21,7 +21,6 @@ import android.support.annotation.NonNull;
|
||||
import android.util.Log;
|
||||
|
||||
import com.hippo.ehviewer.gallery.gifdecoder.GifDecoder;
|
||||
import com.hippo.ehviewer.gallery.ui.GLRoot;
|
||||
|
||||
public class GifTexture extends TiledTexture {
|
||||
|
||||
@@ -30,7 +29,6 @@ public class GifTexture extends TiledTexture {
|
||||
private static TiledTexture.Uploader sUploader;
|
||||
private static InfiniteThreadExecutor sThreadExecutor;
|
||||
|
||||
private GLRoot mGLRoot;
|
||||
private GifDecoder mGifDecoder;
|
||||
private boolean mRunning = false;
|
||||
|
||||
@@ -64,7 +62,7 @@ public class GifTexture extends TiledTexture {
|
||||
public void run() {
|
||||
GifDecoder gifDecoder = mGifDecoder;
|
||||
|
||||
while (mRunning) {
|
||||
while (mRunning && sUploader != null) {
|
||||
gifDecoder.advance();
|
||||
Bitmap bitmap = gifDecoder.getNextFrame();
|
||||
if (bitmap == null) {
|
||||
@@ -74,6 +72,9 @@ public class GifTexture extends TiledTexture {
|
||||
}
|
||||
|
||||
setBitmap(bitmap);
|
||||
if (sUploader == null) {
|
||||
break;
|
||||
}
|
||||
sUploader.addTexture(GifTexture.this);
|
||||
|
||||
long delay = gifDecoder.getNextDelay();
|
||||
@@ -92,6 +93,7 @@ public class GifTexture extends TiledTexture {
|
||||
mSleeping = false;
|
||||
}
|
||||
}
|
||||
mGifDecodeTask = null;
|
||||
|
||||
if (mClear) {
|
||||
gifDecoder.clear();
|
||||
@@ -99,41 +101,41 @@ public class GifTexture extends TiledTexture {
|
||||
}
|
||||
}
|
||||
|
||||
public GifTexture(@NonNull GifDecoder gifDecoder, @NonNull Bitmap bitmap, @NonNull GLRoot glRoot) {
|
||||
public GifTexture(@NonNull GifDecoder gifDecoder, @NonNull Bitmap bitmap) {
|
||||
super(bitmap);
|
||||
|
||||
mGifDecoder = gifDecoder;
|
||||
mGLRoot = glRoot;
|
||||
start();
|
||||
}
|
||||
|
||||
public void start() {
|
||||
mRunning = true;
|
||||
if (mGifDecodeTask == null) {
|
||||
mGifDecodeTask = new GifDecodeTask();
|
||||
sThreadExecutor.execute(mGifDecodeTask);
|
||||
if (!mRunning) {
|
||||
mRunning = true;
|
||||
if (mGifDecodeTask == null) {
|
||||
mGifDecodeTask = new GifDecodeTask();
|
||||
sThreadExecutor.execute(mGifDecodeTask);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
mRunning = false;
|
||||
mGifDecodeTask = null;
|
||||
if (mRunning) {
|
||||
mRunning = false;
|
||||
mGifDecodeTask = null;
|
||||
|
||||
mGifDecoder.resetFrameIndex();
|
||||
Bitmap bitmap = mGifDecoder.getNextFrame();
|
||||
if (bitmap != null) {
|
||||
setBitmap(bitmap);
|
||||
sUploader.addTexture(GifTexture.this);
|
||||
mGifDecoder.resetFrameIndex();
|
||||
mGifDecoder.advance();
|
||||
Bitmap bitmap = mGifDecoder.getNextFrame();
|
||||
if (bitmap != null) {
|
||||
setBitmap(bitmap);
|
||||
sUploader.addTexture(GifTexture.this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void recycle() {
|
||||
|
||||
Log.d(TAG, "recycle");
|
||||
|
||||
mRunning = false;
|
||||
if (mGifDecodeTask.isSleeping()) {
|
||||
if (mGifDecodeTask == null || mGifDecodeTask.isSleeping()) {
|
||||
mGifDecoder.clear();
|
||||
} else {
|
||||
mGifDecodeTask.clearByMyself();
|
||||
|
||||
@@ -67,6 +67,11 @@ public class GalleryPageView extends FrameView {
|
||||
updateSeen();
|
||||
}
|
||||
|
||||
public void setAnimateState(int position) {
|
||||
mImageView.setAnimateState(position);
|
||||
mImageView.setAnimateState(position);
|
||||
}
|
||||
|
||||
public boolean isLoaded() {
|
||||
return mImageView.isLoaded();
|
||||
}
|
||||
|
||||
@@ -59,6 +59,7 @@ public class GalleryView extends GLView implements GestureRecognizer.Listener {
|
||||
|
||||
private boolean mScale = false;
|
||||
private boolean mScroll = false;
|
||||
private boolean mTouched = false;
|
||||
|
||||
private int mDeltaX;
|
||||
private int[] mScrollRemain = new int[2];
|
||||
@@ -441,6 +442,7 @@ public class GalleryView extends GLView implements GestureRecognizer.Listener {
|
||||
|
||||
@Override
|
||||
public void onDown(float x, float y) {
|
||||
mTouched = true;
|
||||
mScale = false;
|
||||
mScroll = false;
|
||||
mSmoothScroller.forceStop();
|
||||
@@ -449,15 +451,29 @@ public class GalleryView extends GLView implements GestureRecognizer.Listener {
|
||||
|
||||
@Override
|
||||
public void onUp() {
|
||||
mTouched = false;
|
||||
mDeltaX = 0;
|
||||
mEdgeView.onRelease();
|
||||
|
||||
if ((mMode == Mode.LEFT_TO_RIGHT || mMode == Mode.RIGHT_TO_LEFT) && mLayoutOffset != 0) {
|
||||
// Scroll
|
||||
final float pageDelta = 7 * (float) Math.abs(mLayoutOffset) / (getWidth() + mInterval);
|
||||
int duration = (int) ((pageDelta + 1) * 100);
|
||||
duration = Math.min(duration, MAX_SETTLE_DURATION);
|
||||
mSmoothScroller.startSmoothScroll(-mLayoutOffset, 0, duration);
|
||||
if ((mMode == Mode.LEFT_TO_RIGHT || mMode == Mode.RIGHT_TO_LEFT)) {
|
||||
if (mLayoutOffset != 0) {
|
||||
// Scroll
|
||||
final float pageDelta = 7 * (float) Math.abs(mLayoutOffset) / (getWidth() + mInterval);
|
||||
int duration = (int) ((pageDelta + 1) * 100);
|
||||
duration = Math.min(duration, MAX_SETTLE_DURATION);
|
||||
mSmoothScroller.startSmoothScroll(-mLayoutOffset, 0, duration);
|
||||
} else {
|
||||
// Update AnimateState
|
||||
GalleryPageView page = mPageMap.get(mFirstShownIndex);
|
||||
if (page != null) {
|
||||
page.setAnimateState(ScaledImageView.ANIMATE_STATE_RUN);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
} else if (mMode == Mode.TOP_TO_BOTTOM) {
|
||||
// TODO
|
||||
}
|
||||
@@ -643,8 +659,9 @@ public class GalleryView extends GLView implements GestureRecognizer.Listener {
|
||||
mAttachedPage.clear();
|
||||
mUsedPage.clear();
|
||||
|
||||
// Update seen
|
||||
|
||||
for (int i = 0; i < getComponentCount(); i++) {
|
||||
// Update seen
|
||||
GalleryPageView page = (GalleryPageView) getComponent(i);
|
||||
LayoutParams lp = ((LayoutParams) page.getLayoutParams());
|
||||
int oldSeen = lp.seen;
|
||||
@@ -653,6 +670,15 @@ public class GalleryView extends GLView implements GestureRecognizer.Listener {
|
||||
if (oldSeen == UNKNOWN_SEEN || (oldSeen == SEEN && seen == UNSEEN)) {
|
||||
page.setScaleOffset(mScaleMode, mStartPosition, mLastScale);
|
||||
}
|
||||
|
||||
// Update AnimateState
|
||||
if (seen == UNSEEN) {
|
||||
page.setAnimateState(ScaledImageView.ANIMATE_STATE_STOP);
|
||||
} else if (!mTouched && mLayoutOffset == 0 && mFirstShownIndex == lp.index) {
|
||||
page.setAnimateState(ScaledImageView.ANIMATE_STATE_RUN);
|
||||
} else {
|
||||
page.setAnimateState(ScaledImageView.ANIMATE_STATE_DEFALUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
|
||||
import com.hippo.ehviewer.gallery.glrenderer.GLCanvas;
|
||||
import com.hippo.ehviewer.gallery.glrenderer.GifTexture;
|
||||
import com.hippo.ehviewer.gallery.glrenderer.TiledTexture;
|
||||
import com.hippo.yorozuya.MathUtils;
|
||||
|
||||
@@ -13,6 +14,12 @@ public class ScaledImageView extends GLView {
|
||||
private static final float SCALE_MIN = 1 / 10.0f;
|
||||
private static final float SCALE_MAX = 10.0f;
|
||||
|
||||
public static final int ANIMATE_STATE_DEFALUE = 0;
|
||||
public static final int ANIMATE_STATE_RUN = 1;
|
||||
public static final int ANIMATE_STATE_STOP = 2;
|
||||
|
||||
private int mAnimateState = ANIMATE_STATE_DEFALUE;
|
||||
|
||||
private TiledTexture mTiledTexture;
|
||||
|
||||
// Corresponding source is [0, 0, mTiledTexture.getWidth(), mTiledTexture.getHeight()]
|
||||
@@ -28,9 +35,33 @@ public class ScaledImageView extends GLView {
|
||||
private float mLastScale;
|
||||
private float mScale = 1f;
|
||||
|
||||
public void setAnimateState(int animateState) {
|
||||
if (mAnimateState != animateState) {
|
||||
mAnimateState = animateState;
|
||||
if (mTiledTexture instanceof GifTexture) {
|
||||
GifTexture gifTexture = (GifTexture) mTiledTexture;
|
||||
if (animateState == ANIMATE_STATE_RUN) {
|
||||
gifTexture.start();
|
||||
} else if (animateState == ANIMATE_STATE_STOP) {
|
||||
gifTexture.stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setTiledTexture(TiledTexture tiledTexture) {
|
||||
mTiledTexture = tiledTexture;
|
||||
setScaleOffset(mScaleMode, mStartPosition, mLastScale);
|
||||
|
||||
if (mTiledTexture instanceof GifTexture) {
|
||||
GifTexture gifTexture = (GifTexture) mTiledTexture;
|
||||
if (mAnimateState == ANIMATE_STATE_RUN) {
|
||||
gifTexture.start();
|
||||
} else if (mAnimateState == ANIMATE_STATE_STOP) {
|
||||
gifTexture.stop();
|
||||
}
|
||||
}
|
||||
|
||||
invalidate();
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,6 @@ import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.Process;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.util.Log;
|
||||
import android.util.Pair;
|
||||
|
||||
import com.hippo.app.StatsActivity;
|
||||
@@ -283,8 +282,6 @@ public class GalleryActivity extends StatsActivity implements TiledTexture.OnFre
|
||||
if (tiledTexture != null) {
|
||||
view.mImageView.setTiledTexture(null);
|
||||
tiledTexture.recycle();
|
||||
} else {
|
||||
Log.d("TAG", "tiledTexture == null");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -302,7 +299,7 @@ public class GalleryActivity extends StatsActivity implements TiledTexture.OnFre
|
||||
mUploader.addTexture(tiledTexture);
|
||||
} else if (obj instanceof Pair) {
|
||||
Pair pair = (Pair) obj;
|
||||
tiledTexture = new GifTexture((GifDecoder) pair.first, (Bitmap) pair.second, mGLRootView);
|
||||
tiledTexture = new GifTexture((GifDecoder) pair.first, (Bitmap) pair.second);
|
||||
mUploader.addTexture(tiledTexture);
|
||||
} else {
|
||||
bindBadImage(view);
|
||||
|
||||
Reference in new issue
Block a user