Clean up BitmapFactoryVideoRenderer
This commit is contained in:
parent
b520b26f0f
commit
9d88db7119
@ -24,17 +24,22 @@ import java.nio.ByteBuffer;
|
|||||||
|
|
||||||
public class BitmapFactoryVideoRenderer extends BaseRenderer {
|
public class BitmapFactoryVideoRenderer extends BaseRenderer {
|
||||||
private static final String TAG = "BitmapFactoryRenderer";
|
private static final String TAG = "BitmapFactoryRenderer";
|
||||||
final VideoRendererEventListener.EventDispatcher eventDispatcher;
|
private static int threadId;
|
||||||
@Nullable
|
|
||||||
volatile Surface surface;
|
|
||||||
private final Rect rect = new Rect();
|
private final Rect rect = new Rect();
|
||||||
private final Point lastSurface = new Point();
|
private final Point lastSurface = new Point();
|
||||||
private final RenderRunnable renderRunnable = new RenderRunnable();
|
private final RenderRunnable renderRunnable = new RenderRunnable();
|
||||||
private final Thread thread = new Thread(renderRunnable, "BitmapFactoryVideoRenderer");
|
|
||||||
|
final VideoRendererEventListener.EventDispatcher eventDispatcher;
|
||||||
|
final Thread thread = new Thread(renderRunnable, getClass().getSimpleName() + threadId++);
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
volatile Surface surface;
|
||||||
|
|
||||||
private VideoSize lastVideoSize = VideoSize.UNKNOWN;
|
private VideoSize lastVideoSize = VideoSize.UNKNOWN;
|
||||||
private long currentTimeUs;
|
private long currentTimeUs;
|
||||||
private long frameUs;
|
private long frameUs;
|
||||||
boolean ended;
|
private boolean firstFrameRendered;
|
||||||
@Nullable
|
@Nullable
|
||||||
private DecoderCounters decoderCounters;
|
private DecoderCounters decoderCounters;
|
||||||
|
|
||||||
@ -60,8 +65,7 @@ public class BitmapFactoryVideoRenderer extends BaseRenderer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onDisabled() {
|
protected void onDisabled() {
|
||||||
renderRunnable.running = false;
|
renderRunnable.stop();
|
||||||
thread.interrupt();
|
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
final DecoderCounters decoderCounters = this.decoderCounters;
|
final DecoderCounters decoderCounters = this.decoderCounters;
|
||||||
@ -111,7 +115,7 @@ public class BitmapFactoryVideoRenderer extends BaseRenderer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isEnded() {
|
public boolean isEnded() {
|
||||||
return renderRunnable.ended;
|
return renderRunnable.isEnded();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -123,11 +127,67 @@ public class BitmapFactoryVideoRenderer extends BaseRenderer {
|
|||||||
return RendererCapabilities.create(C.FORMAT_UNSUPPORTED_TYPE);
|
return RendererCapabilities.create(C.FORMAT_UNSUPPORTED_TYPE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void renderBitmap(final Bitmap bitmap) {
|
||||||
|
@Nullable
|
||||||
|
final Surface surface = this.surface;
|
||||||
|
if (surface == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//Log.d(TAG, "Drawing: " + bitmap.getWidth() + "x" + bitmap.getHeight());
|
||||||
|
final Canvas canvas = surface.lockCanvas(null);
|
||||||
|
|
||||||
|
final Rect clipBounds = canvas.getClipBounds();
|
||||||
|
final VideoSize videoSize = new VideoSize(bitmap.getWidth(), bitmap.getHeight());
|
||||||
|
final boolean videoSizeChanged;
|
||||||
|
if (videoSize.equals(lastVideoSize)) {
|
||||||
|
videoSizeChanged = false;
|
||||||
|
} else {
|
||||||
|
lastVideoSize = videoSize;
|
||||||
|
eventDispatcher.videoSizeChanged(videoSize);
|
||||||
|
videoSizeChanged = true;
|
||||||
|
}
|
||||||
|
if (lastSurface.x != clipBounds.width() || lastSurface.y != clipBounds.height() ||
|
||||||
|
videoSizeChanged) {
|
||||||
|
lastSurface.x = clipBounds.width();
|
||||||
|
lastSurface.y = clipBounds.height();
|
||||||
|
final float scaleX = lastSurface.x / (float)videoSize.width;
|
||||||
|
final float scaleY = lastSurface.y / (float)videoSize.height;
|
||||||
|
final float scale = Math.min(scaleX, scaleY);
|
||||||
|
final float width = videoSize.width * scale;
|
||||||
|
final float height = videoSize.height * scale;
|
||||||
|
final int x = (int)(lastSurface.x - width) / 2;
|
||||||
|
final int y = (int)(lastSurface.y - height) / 2;
|
||||||
|
rect.set(x, y, x + (int)width, y + (int) height);
|
||||||
|
}
|
||||||
|
canvas.drawBitmap(bitmap, null, rect, null);
|
||||||
|
|
||||||
|
surface.unlockCanvasAndPost(canvas);
|
||||||
|
@Nullable
|
||||||
|
final DecoderCounters decoderCounters = BitmapFactoryVideoRenderer.this.decoderCounters;
|
||||||
|
if (decoderCounters != null) {
|
||||||
|
decoderCounters.renderedOutputBufferCount++;
|
||||||
|
}
|
||||||
|
if (!firstFrameRendered) {
|
||||||
|
firstFrameRendered = true;
|
||||||
|
eventDispatcher.renderedFirstFrame(surface);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class RenderRunnable implements Runnable {
|
class RenderRunnable implements Runnable {
|
||||||
private volatile boolean ended;
|
final DecoderInputBuffer decoderInputBuffer =
|
||||||
private boolean firstFrameRendered;
|
new DecoderInputBuffer(DecoderInputBuffer.BUFFER_REPLACEMENT_MODE_NORMAL);
|
||||||
|
|
||||||
private volatile boolean running = true;
|
private volatile boolean running = true;
|
||||||
|
|
||||||
|
void stop() {
|
||||||
|
running = false;
|
||||||
|
thread.interrupt();
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isEnded() {
|
||||||
|
return !running || decoderInputBuffer.isEndOfStream();
|
||||||
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private Bitmap decodeInputBuffer(final DecoderInputBuffer decoderInputBuffer) {
|
private Bitmap decodeInputBuffer(final DecoderInputBuffer decoderInputBuffer) {
|
||||||
@Nullable final ByteBuffer byteBuffer = decoderInputBuffer.data;
|
@Nullable final ByteBuffer byteBuffer = decoderInputBuffer.data;
|
||||||
@ -148,50 +208,6 @@ public class BitmapFactoryVideoRenderer extends BaseRenderer {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void renderBitmap(final Bitmap bitmap, @Nullable final Surface surface) {
|
|
||||||
if (surface == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
//Log.d(TAG, "Drawing: " + bitmap.getWidth() + "x" + bitmap.getHeight());
|
|
||||||
final Canvas canvas = surface.lockCanvas(null);
|
|
||||||
|
|
||||||
final Rect clipBounds = canvas.getClipBounds();
|
|
||||||
final VideoSize videoSize = new VideoSize(bitmap.getWidth(), bitmap.getHeight());
|
|
||||||
final boolean videoSizeChanged;
|
|
||||||
if (videoSize.equals(lastVideoSize)) {
|
|
||||||
videoSizeChanged = false;
|
|
||||||
} else {
|
|
||||||
lastVideoSize = videoSize;
|
|
||||||
eventDispatcher.videoSizeChanged(videoSize);
|
|
||||||
videoSizeChanged = true;
|
|
||||||
}
|
|
||||||
if (lastSurface.x != clipBounds.width() || lastSurface.y != clipBounds.height() ||
|
|
||||||
videoSizeChanged) {
|
|
||||||
lastSurface.x = clipBounds.width();
|
|
||||||
lastSurface.y = clipBounds.height();
|
|
||||||
final float scaleX = lastSurface.x / (float)videoSize.width;
|
|
||||||
final float scaleY = lastSurface.y / (float)videoSize.height;
|
|
||||||
final float scale = Math.min(scaleX, scaleY);
|
|
||||||
final float width = videoSize.width * scale;
|
|
||||||
final float height = videoSize.height * scale;
|
|
||||||
final int x = (int)(lastSurface.x - width) / 2;
|
|
||||||
final int y = (int)(lastSurface.y - height) / 2;
|
|
||||||
rect.set(x, y, x + (int)width, y + (int) height);
|
|
||||||
}
|
|
||||||
canvas.drawBitmap(bitmap, null, rect, null);
|
|
||||||
|
|
||||||
surface.unlockCanvasAndPost(canvas);
|
|
||||||
@Nullable
|
|
||||||
final DecoderCounters decoderCounters = BitmapFactoryVideoRenderer.this.decoderCounters;
|
|
||||||
if (decoderCounters != null) {
|
|
||||||
decoderCounters.renderedOutputBufferCount++;
|
|
||||||
}
|
|
||||||
if (!firstFrameRendered) {
|
|
||||||
firstFrameRendered = true;
|
|
||||||
eventDispatcher.renderedFirstFrame(surface);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @return true if interrupted
|
* @return true if interrupted
|
||||||
@ -210,9 +226,6 @@ public class BitmapFactoryVideoRenderer extends BaseRenderer {
|
|||||||
|
|
||||||
public void run() {
|
public void run() {
|
||||||
final FormatHolder formatHolder = getFormatHolder();
|
final FormatHolder formatHolder = getFormatHolder();
|
||||||
@NonNull
|
|
||||||
final DecoderInputBuffer decoderInputBuffer =
|
|
||||||
new DecoderInputBuffer(DecoderInputBuffer.BUFFER_REPLACEMENT_MODE_NORMAL);
|
|
||||||
long start = SystemClock.uptimeMillis();
|
long start = SystemClock.uptimeMillis();
|
||||||
main:
|
main:
|
||||||
while (running) {
|
while (running) {
|
||||||
@ -221,10 +234,8 @@ public class BitmapFactoryVideoRenderer extends BaseRenderer {
|
|||||||
formatHolder.format == null ? SampleStream.FLAG_REQUIRE_FORMAT : 0);
|
formatHolder.format == null ? SampleStream.FLAG_REQUIRE_FORMAT : 0);
|
||||||
if (result == C.RESULT_BUFFER_READ) {
|
if (result == C.RESULT_BUFFER_READ) {
|
||||||
if (decoderInputBuffer.isEndOfStream()) {
|
if (decoderInputBuffer.isEndOfStream()) {
|
||||||
ended = true;
|
//Wait for shutdown or stream to be changed
|
||||||
if (!sleep()) {
|
sleep();
|
||||||
ended = false;
|
|
||||||
}
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
final long leadUs = decoderInputBuffer.timeUs - currentTimeUs;
|
final long leadUs = decoderInputBuffer.timeUs - currentTimeUs;
|
||||||
@ -244,17 +255,17 @@ public class BitmapFactoryVideoRenderer extends BaseRenderer {
|
|||||||
while (currentTimeUs < decoderInputBuffer.timeUs) {
|
while (currentTimeUs < decoderInputBuffer.timeUs) {
|
||||||
//Log.d(TAG, "Sleep: us=" + currentTimeUs);
|
//Log.d(TAG, "Sleep: us=" + currentTimeUs);
|
||||||
if (sleep()) {
|
if (sleep()) {
|
||||||
|
//Sleep was interrupted, discard Bitmap
|
||||||
continue main;
|
continue main;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (running) {
|
if (running) {
|
||||||
renderBitmap(bitmap, surface);
|
renderBitmap(bitmap);
|
||||||
}
|
}
|
||||||
} else if (result == C.RESULT_FORMAT_READ) {
|
} else if (result == C.RESULT_FORMAT_READ) {
|
||||||
onFormatChanged(formatHolder);
|
onFormatChanged(formatHolder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ended = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user