Skip to content

Commit 9ae0b6d

Browse files
authored
Merge pull request #212 from ksvc/v4.3.1-13346
update to v4.3.1-13346
2 parents 6ed1621 + 80b4383 commit 9ae0b6d

File tree

16 files changed

+749
-28
lines changed

16 files changed

+749
-28
lines changed

demo/assets/ksyun.webp

59.8 KB
Binary file not shown.

demo/libs/arm64-v8a/libksylive.so

-12 KB
Binary file not shown.

demo/libs/armeabi-v7a/libksylive.so

4 KB
Binary file not shown.

demo/libs/armeabi/libksylive.so

0 Bytes
Binary file not shown.

demo/libs/ksylive.jar

400 Bytes
Binary file not shown.

demo/libs/x86/libksylive.so

0 Bytes
Binary file not shown.

demo/res/drawable-xhdpi/exposure.png

2.14 KB
Loading

demo/res/layout/camera_activity.xml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,18 @@
1919
android:layout_alignParentBottom="true"
2020
android:layout_alignParentTop="true" />
2121

22+
<com.ksyun.media.streamer.demo.VerticalSeekBar
23+
android:id="@+id/exposure_seekBar"
24+
android:layout_width="wrap_content"
25+
android:layout_height="200dp"
26+
android:layout_alignParentRight="true"
27+
android:layout_marginRight="20dp"
28+
android:layout_marginTop="100dp"
29+
android:progressBackgroundTint="#9b9b9b"
30+
android:progressTint="@color/font_color_35"
31+
android:thumbTint="#C0303030"
32+
android:visibility="gone"/>
33+
2234
<com.lht.paintview.PaintView
2335
android:id="@+id/view_paint"
2436
android:layout_width="match_parent"

demo/res/layout/camera_titlebar.xml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,15 @@
4242
android:layout_toLeftOf="@id/flash"
4343
android:background="@drawable/recorder_add_icon"/>
4444

45+
<ImageView
46+
android:id="@+id/exposure"
47+
android:layout_width="wrap_content"
48+
android:layout_height="wrap_content"
49+
android:layout_marginTop="3dp"
50+
android:layout_gravity="center_vertical"
51+
android:layout_marginRight="8dp"
52+
android:layout_toLeftOf="@id/add"
53+
android:background="@drawable/exposure">
54+
</ImageView>
55+
4556
</RelativeLayout>
Lines changed: 210 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
package com.ksyun.media.streamer.demo;
2+
3+
import android.content.Context;
4+
import android.graphics.Bitmap;
5+
import android.graphics.Canvas;
6+
import android.graphics.Color;
7+
import android.graphics.Rect;
8+
import android.net.Uri;
9+
import android.util.Log;
10+
11+
import com.facebook.common.executors.CallerThreadExecutor;
12+
import com.facebook.common.references.CloseableReference;
13+
import com.facebook.datasource.BaseDataSubscriber;
14+
import com.facebook.datasource.DataSource;
15+
import com.facebook.datasource.DataSubscriber;
16+
import com.facebook.drawee.backends.pipeline.Fresco;
17+
import com.facebook.imagepipeline.animated.base.AnimatedDrawableFrameInfo;
18+
import com.facebook.imagepipeline.animated.base.AnimatedImage;
19+
import com.facebook.imagepipeline.animated.base.AnimatedImageFrame;
20+
import com.facebook.imagepipeline.core.ImagePipeline;
21+
import com.facebook.imagepipeline.image.CloseableAnimatedImage;
22+
import com.facebook.imagepipeline.image.CloseableBitmap;
23+
import com.facebook.imagepipeline.image.CloseableImage;
24+
import com.facebook.imagepipeline.request.ImageRequest;
25+
import com.facebook.imagepipeline.request.ImageRequestBuilder;
26+
import com.ksyun.media.streamer.capture.ImgTexSrcPin;
27+
import com.ksyun.media.streamer.framework.ImgTexFrame;
28+
import com.ksyun.media.streamer.framework.SrcPin;
29+
import com.ksyun.media.streamer.util.gles.GLRender;
30+
31+
import java.util.Date;
32+
import java.util.Timer;
33+
import java.util.TimerTask;
34+
35+
/**
36+
* Class to decode animated GIF/WEBP.
37+
*/
38+
39+
public class AnimatedImageCapture {
40+
private static final String TAG = "AnimatedImageCapture";
41+
private static final boolean VERBOSE = false;
42+
43+
private int mIndex;
44+
private Date mLastDate;
45+
private int mRepeatCount; // TODO: handle gif/webp repeat count
46+
private Bitmap mBitmap;
47+
private Canvas mCanvas;
48+
private Bitmap mTempBitmap;
49+
private Timer mTimer;
50+
private CloseableReference<? extends CloseableImage> mCloseableReference;
51+
52+
private ImgTexSrcPin mImgTexSrcPin;
53+
54+
public AnimatedImageCapture(GLRender glRender) {
55+
mImgTexSrcPin = new ImgTexSrcPin(glRender);
56+
}
57+
58+
public SrcPin<ImgTexFrame> getSrcPin() {
59+
return mImgTexSrcPin;
60+
}
61+
62+
public void start(Context context, String url) {
63+
if (url == null) {
64+
return;
65+
}
66+
67+
Uri uri = Uri.parse(assets2Asset(url));
68+
ImagePipeline imagePipeline = Fresco.getImagePipeline();
69+
ImageRequest request = ImageRequestBuilder.newBuilderWithSource(uri).build();
70+
DataSource<CloseableReference<CloseableImage>> dataSource =
71+
imagePipeline.fetchDecodedImage(request, context);
72+
dataSource.subscribe(mDataSubscriber, CallerThreadExecutor.getInstance());
73+
}
74+
75+
private String assets2Asset(String url) {
76+
if (url.startsWith("assets://")) {
77+
url = url.replaceFirst("assets://", "asset:///");
78+
}
79+
return url;
80+
}
81+
82+
public void stop() {
83+
if (mTimer != null) {
84+
mTimer.cancel();
85+
mTimer = null;
86+
}
87+
if (mCloseableReference != null) {
88+
CloseableReference.closeSafely(mCloseableReference);
89+
mCloseableReference = null;
90+
}
91+
mImgTexSrcPin.updateFrame(null, false);
92+
}
93+
94+
private void updateFrame() {
95+
if (mCloseableReference == null) {
96+
return;
97+
}
98+
try {
99+
CloseableImage closeableImage = mCloseableReference.get();
100+
if (closeableImage instanceof CloseableBitmap) {
101+
Bitmap bitmap = ((CloseableBitmap) closeableImage).getUnderlyingBitmap();
102+
if (bitmap != null && !bitmap.isRecycled()) {
103+
mBitmap = Bitmap.createBitmap(bitmap);
104+
mImgTexSrcPin.updateFrame(mBitmap, false);
105+
}
106+
return;
107+
}
108+
109+
if (!(closeableImage instanceof CloseableAnimatedImage)) {
110+
return;
111+
}
112+
AnimatedImage animatedImage = ((CloseableAnimatedImage) closeableImage).getImage();
113+
int w = animatedImage.getWidth();
114+
int h = animatedImage.getHeight();
115+
if (mBitmap == null || mBitmap.isRecycled()) {
116+
Log.d(TAG, "Got animated image " + w + "x" + h);
117+
mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
118+
mTempBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
119+
mCanvas = new Canvas(mBitmap);
120+
}
121+
if (mIndex >= animatedImage.getFrameCount()) {
122+
mRepeatCount++;
123+
mIndex = 0;
124+
int loopCount = animatedImage.getLoopCount();
125+
if (loopCount > 0 && mRepeatCount >= loopCount) {
126+
Log.d(TAG, "repeat ended, repeat times: " + mRepeatCount);
127+
return;
128+
}
129+
}
130+
131+
AnimatedImageFrame imageFrame = animatedImage.getFrame(mIndex);
132+
int duration = imageFrame.getDurationMs();
133+
AnimatedDrawableFrameInfo frameInfo = animatedImage.getFrameInfo(mIndex);
134+
imageFrame.renderFrame(frameInfo.width, frameInfo.height, mTempBitmap);
135+
if (VERBOSE) {
136+
Log.d(TAG, "blend: " + frameInfo.blendOperation.name() +
137+
" dispose: " + frameInfo.disposalMethod.name() +
138+
" x=" + frameInfo.xOffset + " y=" + frameInfo.yOffset +
139+
" " + frameInfo.width + "x" + frameInfo.height);
140+
}
141+
if (frameInfo.blendOperation == AnimatedDrawableFrameInfo.BlendOperation.NO_BLEND) {
142+
mBitmap.eraseColor(Color.TRANSPARENT);
143+
}
144+
Rect srcRect = new Rect(0, 0, frameInfo.width, frameInfo.height);
145+
Rect dstRect = new Rect(frameInfo.xOffset, frameInfo.yOffset,
146+
frameInfo.xOffset + frameInfo.width, frameInfo.yOffset + frameInfo.height);
147+
mCanvas.drawBitmap(mTempBitmap, srcRect, dstRect, null);
148+
if (VERBOSE) {
149+
Log.d(TAG, "frame " + mIndex + " got, duration=" + duration);
150+
}
151+
mImgTexSrcPin.updateFrame(mBitmap, false);
152+
imageFrame.dispose();
153+
154+
mIndex++;
155+
if (mLastDate == null) {
156+
mLastDate = new Date();
157+
}
158+
mLastDate = new Date(mLastDate.getTime() + duration);
159+
mTimer.schedule(new TimerTask() {
160+
@Override
161+
public void run() {
162+
updateFrame();
163+
}
164+
}, mLastDate);
165+
} catch (Exception e) {
166+
e.printStackTrace();
167+
}
168+
}
169+
170+
private DataSubscriber mDataSubscriber =
171+
new BaseDataSubscriber<CloseableReference<? extends CloseableImage>>() {
172+
173+
@Override
174+
public void onNewResultImpl(
175+
DataSource<CloseableReference<? extends CloseableImage>> dataSource) {
176+
if (!dataSource.isFinished()) {
177+
return;
178+
}
179+
180+
// get ref
181+
mCloseableReference = dataSource.getResult();
182+
183+
// reset
184+
mIndex = 0;
185+
mRepeatCount = 0;
186+
mLastDate = null;
187+
mBitmap = null;
188+
mTempBitmap = null;
189+
mCanvas = null;
190+
191+
// create timer
192+
mTimer = new Timer("AnimatedImage");
193+
mTimer.schedule(new TimerTask() {
194+
@Override
195+
public void run() {
196+
updateFrame();
197+
}
198+
}, 0);
199+
}
200+
201+
@Override
202+
public void onFailureImpl(DataSource dataSource) {
203+
Throwable throwable = dataSource.getFailureCause();
204+
// handle failure
205+
if (throwable != null) {
206+
throwable.printStackTrace();
207+
}
208+
}
209+
};
210+
}

0 commit comments

Comments
 (0)