mirror of
https://github.com/moonlight-stream/moonlight-android.git
synced 2025-07-21 03:52:48 +00:00
Fix IDR frame NALU drop race condition
This commit is contained in:
parent
42668b5699
commit
d0da5d3702
@ -7,7 +7,10 @@ public abstract class VideoDecoderRenderer {
|
|||||||
|
|
||||||
public abstract void stop();
|
public abstract void stop();
|
||||||
|
|
||||||
public abstract int submitDecodeUnit(byte[] frameData, int frameLength, int frameNumber, long receiveTimeMs);
|
// This is called once for each frame-start NALU. This means it will be called several times
|
||||||
|
// for an IDR frame which contains several parameter sets and the I-frame data.
|
||||||
|
public abstract int submitDecodeUnit(byte[] decodeUnitData, int decodeUnitLength, int decodeUnitType,
|
||||||
|
int frameNumber, long receiveTimeMs);
|
||||||
|
|
||||||
public abstract void cleanup();
|
public abstract void cleanup();
|
||||||
|
|
||||||
|
@ -13,6 +13,11 @@ public class MoonBridge {
|
|||||||
public static final int VIDEO_FORMAT_H264 = 1;
|
public static final int VIDEO_FORMAT_H264 = 1;
|
||||||
public static final int VIDEO_FORMAT_H265 = 2;
|
public static final int VIDEO_FORMAT_H265 = 2;
|
||||||
|
|
||||||
|
public static final int BUFFER_TYPE_PICDATA = 0;
|
||||||
|
public static final int BUFFER_TYPE_SPS = 1;
|
||||||
|
public static final int BUFFER_TYPE_PPS = 2;
|
||||||
|
public static final int BUFFER_TYPE_VPS = 3;
|
||||||
|
|
||||||
public static final int CAPABILITY_DIRECT_SUBMIT = 1;
|
public static final int CAPABILITY_DIRECT_SUBMIT = 1;
|
||||||
public static final int CAPABILITY_REFERENCE_FRAME_INVALIDATION_AVC = 2;
|
public static final int CAPABILITY_REFERENCE_FRAME_INVALIDATION_AVC = 2;
|
||||||
public static final int CAPABILITY_REFERENCE_FRAME_INVALIDATION_HEVC = 4;
|
public static final int CAPABILITY_REFERENCE_FRAME_INVALIDATION_HEVC = 4;
|
||||||
@ -60,9 +65,12 @@ public class MoonBridge {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int bridgeDrSubmitDecodeUnit(byte[] frameData, int frameLength, int frameNumber, long receiveTimeMs) {
|
public static int bridgeDrSubmitDecodeUnit(byte[] decodeUnitData, int decodeUnitLength,
|
||||||
|
int decodeUnitType,
|
||||||
|
int frameNumber, long receiveTimeMs) {
|
||||||
if (videoRenderer != null) {
|
if (videoRenderer != null) {
|
||||||
return videoRenderer.submitDecodeUnit(frameData, frameLength, frameNumber, receiveTimeMs);
|
return videoRenderer.submitDecodeUnit(decodeUnitData, decodeUnitLength,
|
||||||
|
decodeUnitType, frameNumber, receiveTimeMs);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return DR_OK;
|
return DR_OK;
|
||||||
|
@ -81,7 +81,7 @@ Java_com_limelight_nvstream_jni_MoonBridge_init(JNIEnv *env, jobject class) {
|
|||||||
BridgeDrStartMethod = (*env)->GetStaticMethodID(env, class, "bridgeDrStart", "()V");
|
BridgeDrStartMethod = (*env)->GetStaticMethodID(env, class, "bridgeDrStart", "()V");
|
||||||
BridgeDrStopMethod = (*env)->GetStaticMethodID(env, class, "bridgeDrStop", "()V");
|
BridgeDrStopMethod = (*env)->GetStaticMethodID(env, class, "bridgeDrStop", "()V");
|
||||||
BridgeDrCleanupMethod = (*env)->GetStaticMethodID(env, class, "bridgeDrCleanup", "()V");
|
BridgeDrCleanupMethod = (*env)->GetStaticMethodID(env, class, "bridgeDrCleanup", "()V");
|
||||||
BridgeDrSubmitDecodeUnitMethod = (*env)->GetStaticMethodID(env, class, "bridgeDrSubmitDecodeUnit", "([BIIJ)I");
|
BridgeDrSubmitDecodeUnitMethod = (*env)->GetStaticMethodID(env, class, "bridgeDrSubmitDecodeUnit", "([BIIIJ)I");
|
||||||
BridgeArInitMethod = (*env)->GetStaticMethodID(env, class, "bridgeArInit", "(I)I");
|
BridgeArInitMethod = (*env)->GetStaticMethodID(env, class, "bridgeArInit", "(I)I");
|
||||||
BridgeArStartMethod = (*env)->GetStaticMethodID(env, class, "bridgeArStart", "()V");
|
BridgeArStartMethod = (*env)->GetStaticMethodID(env, class, "bridgeArStart", "()V");
|
||||||
BridgeArStopMethod = (*env)->GetStaticMethodID(env, class, "bridgeArStop", "()V");
|
BridgeArStopMethod = (*env)->GetStaticMethodID(env, class, "bridgeArStop", "()V");
|
||||||
@ -152,6 +152,7 @@ void BridgeDrCleanup(void) {
|
|||||||
|
|
||||||
int BridgeDrSubmitDecodeUnit(PDECODE_UNIT decodeUnit) {
|
int BridgeDrSubmitDecodeUnit(PDECODE_UNIT decodeUnit) {
|
||||||
JNIEnv* env = GetThreadEnv();
|
JNIEnv* env = GetThreadEnv();
|
||||||
|
int ret;
|
||||||
|
|
||||||
if ((*env)->ExceptionCheck(env)) {
|
if ((*env)->ExceptionCheck(env)) {
|
||||||
return DR_OK;
|
return DR_OK;
|
||||||
@ -169,14 +170,33 @@ int BridgeDrSubmitDecodeUnit(PDECODE_UNIT decodeUnit) {
|
|||||||
currentEntry = decodeUnit->bufferList;
|
currentEntry = decodeUnit->bufferList;
|
||||||
offset = 0;
|
offset = 0;
|
||||||
while (currentEntry != NULL) {
|
while (currentEntry != NULL) {
|
||||||
|
// Submit parameter set NALUs separately from picture data
|
||||||
|
if (currentEntry->bufferType != BUFFER_TYPE_PICDATA) {
|
||||||
|
// Use the beginning of the buffer each time since this is a separate
|
||||||
|
// invocation of the decoder each time.
|
||||||
|
(*env)->SetByteArrayRegion(env, DecodedFrameBuffer, 0, currentEntry->length, (jbyte*)currentEntry->data);
|
||||||
|
|
||||||
|
ret = (*env)->CallStaticIntMethod(env, GlobalBridgeClass, BridgeDrSubmitDecodeUnitMethod,
|
||||||
|
DecodedFrameBuffer, currentEntry->length, currentEntry->bufferType,
|
||||||
|
decodeUnit->frameNumber, decodeUnit->receiveTimeMs);
|
||||||
|
if ((*env)->ExceptionCheck(env)) {
|
||||||
|
return DR_OK;
|
||||||
|
}
|
||||||
|
else if (ret != DR_OK) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
(*env)->SetByteArrayRegion(env, DecodedFrameBuffer, offset, currentEntry->length, (jbyte*)currentEntry->data);
|
(*env)->SetByteArrayRegion(env, DecodedFrameBuffer, offset, currentEntry->length, (jbyte*)currentEntry->data);
|
||||||
offset += currentEntry->length;
|
offset += currentEntry->length;
|
||||||
|
}
|
||||||
|
|
||||||
currentEntry = currentEntry->next;
|
currentEntry = currentEntry->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (*env)->CallStaticIntMethod(env, GlobalBridgeClass, BridgeDrSubmitDecodeUnitMethod,
|
return (*env)->CallStaticIntMethod(env, GlobalBridgeClass, BridgeDrSubmitDecodeUnitMethod,
|
||||||
DecodedFrameBuffer, decodeUnit->fullLength, decodeUnit->frameNumber,
|
DecodedFrameBuffer, offset, BUFFER_TYPE_PICDATA,
|
||||||
|
decodeUnit->frameNumber,
|
||||||
decodeUnit->receiveTimeMs);
|
decodeUnit->receiveTimeMs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit 314a5937f4c2f4a9299ab5a00dba3e73c7384161
|
Subproject commit 1c386a898731ae07168d52c835657409b54f7790
|
Loading…
x
Reference in New Issue
Block a user