зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1349883 - part 2: reveal more input buffer status to callbacks. r=esawin,jya
Promise based MediaDataDecoder expects one response per request, but ICodecCallbacks was not designed that way. onInputExhausted() is called only when there are none or just a few input buffers waiting to be queued, and onOutput() is called as soon as output buffers are available. It means these 2 kinds of events are usually interleaved and hard to align with pending promises. Reporting each input buffer status makes it easier for RemoteDataDecoder to resolve promise properly. MozReview-Commit-ID: K09txmHTtmX --HG-- extra : rebase_source : 9ad331c54a24eab6ce5e0195f354afce52247572
This commit is contained in:
Родитель
d1e7871c6f
Коммит
bef936525f
|
@ -9,7 +9,8 @@ import org.mozilla.gecko.media.FormatParam;
|
|||
import org.mozilla.gecko.media.Sample;
|
||||
|
||||
interface ICodecCallbacks {
|
||||
oneway void onInputExhausted();
|
||||
oneway void onInputQueued(long timestamp);
|
||||
oneway void onInputPending(long timestamp);
|
||||
oneway void onOutputFormatChanged(in FormatParam format);
|
||||
oneway void onOutput(in Sample sample);
|
||||
oneway void onError(boolean fatal);
|
||||
|
|
|
@ -50,12 +50,20 @@ import java.util.concurrent.ConcurrentLinkedQueue;
|
|||
}
|
||||
}
|
||||
|
||||
private static final class Input {
|
||||
public final Sample sample;
|
||||
public boolean reported;
|
||||
|
||||
public Input(final Sample sample) {
|
||||
this.sample = sample;
|
||||
}
|
||||
}
|
||||
|
||||
private final class InputProcessor {
|
||||
private static final int FEW_PENDING_INPUTS = 2;
|
||||
private boolean mHasInputCapacitySet;
|
||||
private Queue<Integer> mAvailableInputBuffers = new LinkedList<>();
|
||||
private Queue<Sample> mDequeuedSamples = new LinkedList<>();
|
||||
private Queue<Sample> mInputSamples = new LinkedList<>();
|
||||
private Queue<Input> mInputSamples = new LinkedList<>();
|
||||
private boolean mStopped;
|
||||
|
||||
private synchronized Sample onAllocate(int size) {
|
||||
|
@ -86,7 +94,7 @@ import java.util.concurrent.ConcurrentLinkedQueue;
|
|||
}
|
||||
|
||||
private void queueSample(Sample sample) {
|
||||
if (!mInputSamples.offer(sample)) {
|
||||
if (!mInputSamples.offer(new Input(sample))) {
|
||||
reportError(Error.FATAL, new Exception("FAIL: input sample queue is full"));
|
||||
return;
|
||||
}
|
||||
|
@ -123,7 +131,7 @@ import java.util.concurrent.ConcurrentLinkedQueue;
|
|||
while (!mAvailableInputBuffers.isEmpty() && !mInputSamples.isEmpty()) {
|
||||
int index = mAvailableInputBuffers.poll();
|
||||
int len = 0;
|
||||
Sample sample = mInputSamples.poll();
|
||||
final Sample sample = mInputSamples.poll().sample;
|
||||
long pts = sample.info.presentationTimeUs;
|
||||
int flags = sample.info.flags;
|
||||
MediaCodec.CryptoInfo cryptoInfo = sample.cryptoInfo;
|
||||
|
@ -144,22 +152,32 @@ import java.util.concurrent.ConcurrentLinkedQueue;
|
|||
} else {
|
||||
mCodec.queueInputBuffer(index, 0, len, pts, flags);
|
||||
}
|
||||
}
|
||||
// To avoid input queue flood, request more input samples only when
|
||||
// there are just a few waiting to be processed.
|
||||
if (mDequeuedSamples.size() + mInputSamples.size() <= FEW_PENDING_INPUTS) {
|
||||
try {
|
||||
mCallbacks.onInputExhausted();
|
||||
mCallbacks.onInputQueued(pts);
|
||||
} catch (RemoteException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
reportPendingInputs();
|
||||
}
|
||||
|
||||
private void reportPendingInputs() {
|
||||
try {
|
||||
for (Input i : mInputSamples) {
|
||||
if (!i.reported) {
|
||||
i.reported = true;
|
||||
mCallbacks.onInputPending(i.sample.info.presentationTimeUs);
|
||||
}
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized void reset() {
|
||||
for (Sample s : mInputSamples) {
|
||||
if (!s.isEOS()) {
|
||||
mSamplePool.recycleInput(s);
|
||||
for (Input i : mInputSamples) {
|
||||
if (!i.sample.isEOS()) {
|
||||
mSamplePool.recycleInput(i.sample);
|
||||
}
|
||||
}
|
||||
mInputSamples.clear();
|
||||
|
|
|
@ -63,7 +63,14 @@ public final class CodecProxy {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onInputExhausted() throws RemoteException {
|
||||
public synchronized void onInputQueued(long timestamp) throws RemoteException {
|
||||
if (!mEndOfInput) {
|
||||
mCallbacks.onInputExhausted();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void onInputPending(long timestamp) throws RemoteException {
|
||||
if (!mEndOfInput) {
|
||||
mCallbacks.onInputExhausted();
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче