Improve gif play

This commit is contained in:
seven332 committed 2015-07-31 01:07:34 +08:00
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);