Methods Summary |
---|
private void | consumeCodecOutputLocked()
for (;;) {
final int index = mCodec.dequeueOutputBuffer(mCodecBufferInfo, 0);
if (index >= 0) {
mCodec.releaseOutputBuffer(index, true /*render*/);
} else if (index != MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED
&& index != MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
break;
}
}
|
private void | decode(java.nio.ByteBuffer content)
if (content == null) {
return;
}
synchronized (mSurfaceAndCodecLock) {
if (mCodec == null) {
return;
}
while (content.hasRemaining()) {
if (!provideCodecInputLocked(content)) {
getLogger().log("Dropping content because there are no available buffers.");
return;
}
consumeCodecOutputLocked();
}
}
|
public void | onMessageReceived(int service, int what, java.nio.ByteBuffer content)
switch (what) {
case Protocol.DisplaySinkService.MSG_QUERY: {
getLogger().log("Received MSG_QUERY.");
sendSinkStatus();
break;
}
case Protocol.DisplaySinkService.MSG_CONTENT: {
decode(content);
break;
}
}
|
private boolean | provideCodecInputLocked(java.nio.ByteBuffer content)
final int index = mCodec.dequeueInputBuffer(0);
if (index < 0) {
return false;
}
if (mCodecInputBuffers == null) {
mCodecInputBuffers = mCodec.getInputBuffers();
}
final ByteBuffer buffer = mCodecInputBuffers[index];
final int capacity = buffer.capacity();
buffer.clear();
if (content.remaining() <= capacity) {
buffer.put(content);
} else {
final int limit = content.limit();
content.limit(content.position() + capacity);
buffer.put(content);
content.limit(limit);
}
buffer.flip();
mCodec.queueInputBuffer(index, 0, buffer.limit(), 0, 0);
return true;
|
private void | sendSinkStatus()
synchronized (mSurfaceAndCodecLock) {
if (mCodec != null) {
mBuffer.clear();
mBuffer.putInt(mSurfaceWidth);
mBuffer.putInt(mSurfaceHeight);
mBuffer.putInt(mDensityDpi);
mBuffer.flip();
getTransport().sendMessage(Protocol.DisplaySourceService.ID,
Protocol.DisplaySourceService.MSG_SINK_AVAILABLE, mBuffer);
} else {
getTransport().sendMessage(Protocol.DisplaySourceService.ID,
Protocol.DisplaySourceService.MSG_SINK_NOT_AVAILABLE, null);
}
}
|
public void | setSurfaceView(android.view.SurfaceView surfaceView)
if (mSurfaceView != surfaceView) {
final SurfaceView oldSurfaceView = mSurfaceView;
mSurfaceView = surfaceView;
if (oldSurfaceView != null) {
oldSurfaceView.post(new Runnable() {
@Override
public void run() {
final SurfaceHolder holder = oldSurfaceView.getHolder();
holder.removeCallback(DisplaySinkService.this);
updateSurfaceFromUi(null);
}
});
}
if (surfaceView != null) {
surfaceView.post(new Runnable() {
@Override
public void run() {
final SurfaceHolder holder = surfaceView.getHolder();
holder.addCallback(DisplaySinkService.this);
updateSurfaceFromUi(holder);
}
});
}
}
|
public void | surfaceChanged(android.view.SurfaceHolder holder, int format, int width, int height)
updateSurfaceFromUi(holder);
|
public void | surfaceCreated(android.view.SurfaceHolder holder)
// Ignore. Wait for surface changed event that follows.
|
public void | surfaceDestroyed(android.view.SurfaceHolder holder)
updateSurfaceFromUi(null);
|
private void | updateSurfaceFromUi(android.view.SurfaceHolder holder)
Surface surface = null;
int width = 0, height = 0;
if (holder != null && !holder.isCreating()) {
surface = holder.getSurface();
if (surface.isValid()) {
final Rect frame = holder.getSurfaceFrame();
width = frame.width();
height = frame.height();
} else {
surface = null;
}
}
synchronized (mSurfaceAndCodecLock) {
if (mSurface == surface && mSurfaceWidth == width && mSurfaceHeight == height) {
return;
}
mSurface = surface;
mSurfaceWidth = width;
mSurfaceHeight = height;
if (mCodec != null) {
mCodec.stop();
mCodec = null;
mCodecInputBuffers = null;
mCodecBufferInfo = null;
}
if (mSurface != null) {
MediaFormat format = MediaFormat.createVideoFormat(
"video/avc", mSurfaceWidth, mSurfaceHeight);
try {
mCodec = MediaCodec.createDecoderByType("video/avc");
} catch (IOException e) {
throw new RuntimeException(
"failed to create video/avc decoder", e);
}
mCodec.configure(format, mSurface, null, 0);
mCodec.start();
mCodecBufferInfo = new BufferInfo();
}
mTransportHandler.post(new Runnable() {
@Override
public void run() {
sendSinkStatus();
}
});
}
|