Skip to content

Commit

Permalink
Merge pull request #212 from ksvc/v4.3.1-13346
Browse files Browse the repository at this point in the history
update to v4.3.1-13346
  • Loading branch information
chriszeng87 authored Jul 25, 2017
2 parents 6ed1621 + 80b4383 commit 9ae0b6d
Show file tree
Hide file tree
Showing 16 changed files with 749 additions and 28 deletions.
Binary file added demo/assets/ksyun.webp
Binary file not shown.
Binary file modified demo/libs/arm64-v8a/libksylive.so
Binary file not shown.
Binary file modified demo/libs/armeabi-v7a/libksylive.so
Binary file not shown.
Binary file modified demo/libs/armeabi/libksylive.so
Binary file not shown.
Binary file modified demo/libs/ksylive.jar
Binary file not shown.
Binary file modified demo/libs/x86/libksylive.so
Binary file not shown.
Binary file added demo/res/drawable-xhdpi/exposure.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 12 additions & 0 deletions demo/res/layout/camera_activity.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,18 @@
android:layout_alignParentBottom="true"
android:layout_alignParentTop="true" />

<com.ksyun.media.streamer.demo.VerticalSeekBar
android:id="@+id/exposure_seekBar"
android:layout_width="wrap_content"
android:layout_height="200dp"
android:layout_alignParentRight="true"
android:layout_marginRight="20dp"
android:layout_marginTop="100dp"
android:progressBackgroundTint="#9b9b9b"
android:progressTint="@color/font_color_35"
android:thumbTint="#C0303030"
android:visibility="gone"/>

<com.lht.paintview.PaintView
android:id="@+id/view_paint"
android:layout_width="match_parent"
Expand Down
11 changes: 11 additions & 0 deletions demo/res/layout/camera_titlebar.xml
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,15 @@
android:layout_toLeftOf="@id/flash"
android:background="@drawable/recorder_add_icon"/>

<ImageView
android:id="@+id/exposure"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:layout_gravity="center_vertical"
android:layout_marginRight="8dp"
android:layout_toLeftOf="@id/add"
android:background="@drawable/exposure">
</ImageView>

</RelativeLayout>
210 changes: 210 additions & 0 deletions demo/src/com/ksyun/media/streamer/demo/AnimatedImageCapture.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
package com.ksyun.media.streamer.demo;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Rect;
import android.net.Uri;
import android.util.Log;

import com.facebook.common.executors.CallerThreadExecutor;
import com.facebook.common.references.CloseableReference;
import com.facebook.datasource.BaseDataSubscriber;
import com.facebook.datasource.DataSource;
import com.facebook.datasource.DataSubscriber;
import com.facebook.drawee.backends.pipeline.Fresco;
import com.facebook.imagepipeline.animated.base.AnimatedDrawableFrameInfo;
import com.facebook.imagepipeline.animated.base.AnimatedImage;
import com.facebook.imagepipeline.animated.base.AnimatedImageFrame;
import com.facebook.imagepipeline.core.ImagePipeline;
import com.facebook.imagepipeline.image.CloseableAnimatedImage;
import com.facebook.imagepipeline.image.CloseableBitmap;
import com.facebook.imagepipeline.image.CloseableImage;
import com.facebook.imagepipeline.request.ImageRequest;
import com.facebook.imagepipeline.request.ImageRequestBuilder;
import com.ksyun.media.streamer.capture.ImgTexSrcPin;
import com.ksyun.media.streamer.framework.ImgTexFrame;
import com.ksyun.media.streamer.framework.SrcPin;
import com.ksyun.media.streamer.util.gles.GLRender;

import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

/**
* Class to decode animated GIF/WEBP.
*/

public class AnimatedImageCapture {
private static final String TAG = "AnimatedImageCapture";
private static final boolean VERBOSE = false;

private int mIndex;
private Date mLastDate;
private int mRepeatCount; // TODO: handle gif/webp repeat count
private Bitmap mBitmap;
private Canvas mCanvas;
private Bitmap mTempBitmap;
private Timer mTimer;
private CloseableReference<? extends CloseableImage> mCloseableReference;

private ImgTexSrcPin mImgTexSrcPin;

public AnimatedImageCapture(GLRender glRender) {
mImgTexSrcPin = new ImgTexSrcPin(glRender);
}

public SrcPin<ImgTexFrame> getSrcPin() {
return mImgTexSrcPin;
}

public void start(Context context, String url) {
if (url == null) {
return;
}

Uri uri = Uri.parse(assets2Asset(url));
ImagePipeline imagePipeline = Fresco.getImagePipeline();
ImageRequest request = ImageRequestBuilder.newBuilderWithSource(uri).build();
DataSource<CloseableReference<CloseableImage>> dataSource =
imagePipeline.fetchDecodedImage(request, context);
dataSource.subscribe(mDataSubscriber, CallerThreadExecutor.getInstance());
}

private String assets2Asset(String url) {
if (url.startsWith("assets://")) {
url = url.replaceFirst("assets://", "asset:///");
}
return url;
}

public void stop() {
if (mTimer != null) {
mTimer.cancel();
mTimer = null;
}
if (mCloseableReference != null) {
CloseableReference.closeSafely(mCloseableReference);
mCloseableReference = null;
}
mImgTexSrcPin.updateFrame(null, false);
}

private void updateFrame() {
if (mCloseableReference == null) {
return;
}
try {
CloseableImage closeableImage = mCloseableReference.get();
if (closeableImage instanceof CloseableBitmap) {
Bitmap bitmap = ((CloseableBitmap) closeableImage).getUnderlyingBitmap();
if (bitmap != null && !bitmap.isRecycled()) {
mBitmap = Bitmap.createBitmap(bitmap);
mImgTexSrcPin.updateFrame(mBitmap, false);
}
return;
}

if (!(closeableImage instanceof CloseableAnimatedImage)) {
return;
}
AnimatedImage animatedImage = ((CloseableAnimatedImage) closeableImage).getImage();
int w = animatedImage.getWidth();
int h = animatedImage.getHeight();
if (mBitmap == null || mBitmap.isRecycled()) {
Log.d(TAG, "Got animated image " + w + "x" + h);
mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
mTempBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mBitmap);
}
if (mIndex >= animatedImage.getFrameCount()) {
mRepeatCount++;
mIndex = 0;
int loopCount = animatedImage.getLoopCount();
if (loopCount > 0 && mRepeatCount >= loopCount) {
Log.d(TAG, "repeat ended, repeat times: " + mRepeatCount);
return;
}
}

AnimatedImageFrame imageFrame = animatedImage.getFrame(mIndex);
int duration = imageFrame.getDurationMs();
AnimatedDrawableFrameInfo frameInfo = animatedImage.getFrameInfo(mIndex);
imageFrame.renderFrame(frameInfo.width, frameInfo.height, mTempBitmap);
if (VERBOSE) {
Log.d(TAG, "blend: " + frameInfo.blendOperation.name() +
" dispose: " + frameInfo.disposalMethod.name() +
" x=" + frameInfo.xOffset + " y=" + frameInfo.yOffset +
" " + frameInfo.width + "x" + frameInfo.height);
}
if (frameInfo.blendOperation == AnimatedDrawableFrameInfo.BlendOperation.NO_BLEND) {
mBitmap.eraseColor(Color.TRANSPARENT);
}
Rect srcRect = new Rect(0, 0, frameInfo.width, frameInfo.height);
Rect dstRect = new Rect(frameInfo.xOffset, frameInfo.yOffset,
frameInfo.xOffset + frameInfo.width, frameInfo.yOffset + frameInfo.height);
mCanvas.drawBitmap(mTempBitmap, srcRect, dstRect, null);
if (VERBOSE) {
Log.d(TAG, "frame " + mIndex + " got, duration=" + duration);
}
mImgTexSrcPin.updateFrame(mBitmap, false);
imageFrame.dispose();

mIndex++;
if (mLastDate == null) {
mLastDate = new Date();
}
mLastDate = new Date(mLastDate.getTime() + duration);
mTimer.schedule(new TimerTask() {
@Override
public void run() {
updateFrame();
}
}, mLastDate);
} catch (Exception e) {
e.printStackTrace();
}
}

private DataSubscriber mDataSubscriber =
new BaseDataSubscriber<CloseableReference<? extends CloseableImage>>() {

@Override
public void onNewResultImpl(
DataSource<CloseableReference<? extends CloseableImage>> dataSource) {
if (!dataSource.isFinished()) {
return;
}

// get ref
mCloseableReference = dataSource.getResult();

// reset
mIndex = 0;
mRepeatCount = 0;
mLastDate = null;
mBitmap = null;
mTempBitmap = null;
mCanvas = null;

// create timer
mTimer = new Timer("AnimatedImage");
mTimer.schedule(new TimerTask() {
@Override
public void run() {
updateFrame();
}
}, 0);
}

@Override
public void onFailureImpl(DataSource dataSource) {
Throwable throwable = dataSource.getFailureCause();
// handle failure
if (throwable != null) {
throwable.printStackTrace();
}
}
};
}
Loading

0 comments on commit 9ae0b6d

Please sign in to comment.