mirror of
https://github.com/moonlight-stream/moonlight-common-c.git
synced 2026-06-17 14:21:30 +00:00
Change NAL type parsing to match the spec and add AUD removal for H.264
This commit is contained in:
+84
-36
@@ -37,6 +37,17 @@ typedef struct _LENTRY_INTERNAL {
|
|||||||
void* allocPtr;
|
void* allocPtr;
|
||||||
} LENTRY_INTERNAL, *PLENTRY_INTERNAL;
|
} LENTRY_INTERNAL, *PLENTRY_INTERNAL;
|
||||||
|
|
||||||
|
#define H264_NAL_TYPE(x) ((x) & 0x1F)
|
||||||
|
#define HEVC_NAL_TYPE(x) (((x) & 0x7E) >> 1)
|
||||||
|
|
||||||
|
#define H264_NAL_TYPE_SPS 7
|
||||||
|
#define H264_NAL_TYPE_PPS 8
|
||||||
|
#define H264_NAL_TYPE_AUD 9
|
||||||
|
#define HEVC_NAL_TYPE_VPS 32
|
||||||
|
#define HEVC_NAL_TYPE_SPS 33
|
||||||
|
#define HEVC_NAL_TYPE_PPS 34
|
||||||
|
#define HEVC_NAL_TYPE_AUD 35
|
||||||
|
|
||||||
// Init
|
// Init
|
||||||
void initializeVideoDepacketizer(int pktSize) {
|
void initializeVideoDepacketizer(int pktSize) {
|
||||||
LbqInitializeLinkedBlockingQueue(&decodeUnitQueue, 15);
|
LbqInitializeLinkedBlockingQueue(&decodeUnitQueue, 15);
|
||||||
@@ -206,29 +217,46 @@ void completeQueuedDecodeUnit(PQUEUED_DECODE_UNIT qdu, int drStatus) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool isSeqReferenceFrameStart(PBUFFER_DESC specialSeq) {
|
static bool isSeqReferenceFrameStart(PBUFFER_DESC specialSeq) {
|
||||||
switch (specialSeq->data[specialSeq->offset + specialSeq->length]) {
|
if (NegotiatedVideoFormat & VIDEO_FORMAT_MASK_H264) {
|
||||||
case 0x20:
|
return H264_NAL_TYPE(specialSeq->data[specialSeq->offset + specialSeq->length]) == 5;
|
||||||
case 0x22:
|
}
|
||||||
case 0x24:
|
else if (NegotiatedVideoFormat & VIDEO_FORMAT_MASK_H265) {
|
||||||
case 0x26:
|
switch (HEVC_NAL_TYPE(specialSeq->data[specialSeq->offset + specialSeq->length])) {
|
||||||
case 0x28:
|
case 16:
|
||||||
case 0x2A:
|
case 17:
|
||||||
// H265
|
case 18:
|
||||||
return true;
|
case 19:
|
||||||
|
case 20:
|
||||||
|
case 21:
|
||||||
|
return true;
|
||||||
|
|
||||||
case 0x65:
|
default:
|
||||||
// H264
|
return false;
|
||||||
return true;
|
}
|
||||||
|
}
|
||||||
default:
|
else {
|
||||||
return false;
|
LC_ASSERT(false);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isAccessUnitDelimiter(PBUFFER_DESC buffer) {
|
static bool isAccessUnitDelimiter(PBUFFER_DESC buffer) {
|
||||||
BUFFER_DESC specialSeq;
|
BUFFER_DESC specialSeq;
|
||||||
return getSpecialSeq(buffer, &specialSeq) &&
|
|
||||||
specialSeq.data[specialSeq.offset + specialSeq.length] == 0x46; // HEVC AUD
|
if (!getSpecialSeq(buffer, &specialSeq)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NegotiatedVideoFormat & VIDEO_FORMAT_MASK_H264) {
|
||||||
|
return H264_NAL_TYPE(specialSeq.data[specialSeq.offset + specialSeq.length]) == H264_NAL_TYPE_AUD;
|
||||||
|
}
|
||||||
|
else if (NegotiatedVideoFormat & VIDEO_FORMAT_MASK_H265) {
|
||||||
|
return HEVC_NAL_TYPE(specialSeq.data[specialSeq.offset + specialSeq.length]) == HEVC_NAL_TYPE_AUD;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
LC_ASSERT(false);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Advance the buffer descriptor to the start of the next NAL
|
// Advance the buffer descriptor to the start of the next NAL
|
||||||
@@ -256,10 +284,21 @@ static void skipToNextNal(PBUFFER_DESC buffer) {
|
|||||||
|
|
||||||
static bool isIdrFrameStart(PBUFFER_DESC buffer) {
|
static bool isIdrFrameStart(PBUFFER_DESC buffer) {
|
||||||
BUFFER_DESC specialSeq;
|
BUFFER_DESC specialSeq;
|
||||||
return getSpecialSeq(buffer, &specialSeq) &&
|
|
||||||
isSeqFrameStart(&specialSeq) &&
|
if (!getSpecialSeq(buffer, &specialSeq) || !isSeqFrameStart(&specialSeq)) {
|
||||||
(specialSeq.data[specialSeq.offset + specialSeq.length] == 0x67 || // H264 SPS
|
return false;
|
||||||
specialSeq.data[specialSeq.offset + specialSeq.length] == 0x40); // H265 VPS
|
}
|
||||||
|
|
||||||
|
if (NegotiatedVideoFormat & VIDEO_FORMAT_MASK_H264) {
|
||||||
|
return H264_NAL_TYPE(specialSeq.data[specialSeq.offset + specialSeq.length]) == H264_NAL_TYPE_SPS;
|
||||||
|
}
|
||||||
|
else if (NegotiatedVideoFormat & VIDEO_FORMAT_MASK_H265) {
|
||||||
|
return HEVC_NAL_TYPE(specialSeq.data[specialSeq.offset + specialSeq.length]) == HEVC_NAL_TYPE_VPS;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
LC_ASSERT(false);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reassemble the frame with the given frame number
|
// Reassemble the frame with the given frame number
|
||||||
@@ -329,13 +368,6 @@ static void reassembleFrame(int frameNumber) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#define AVC_NAL_TYPE_SPS 0x67
|
|
||||||
#define AVC_NAL_TYPE_PPS 0x68
|
|
||||||
#define HEVC_NAL_TYPE_VPS 0x40
|
|
||||||
#define HEVC_NAL_TYPE_SPS 0x42
|
|
||||||
#define HEVC_NAL_TYPE_PPS 0x44
|
|
||||||
|
|
||||||
static int getBufferFlags(char* data, int length) {
|
static int getBufferFlags(char* data, int length) {
|
||||||
BUFFER_DESC buffer;
|
BUFFER_DESC buffer;
|
||||||
BUFFER_DESC candidate;
|
BUFFER_DESC candidate;
|
||||||
@@ -348,20 +380,36 @@ static int getBufferFlags(char* data, int length) {
|
|||||||
return BUFFER_TYPE_PICDATA;
|
return BUFFER_TYPE_PICDATA;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (candidate.data[candidate.offset + candidate.length]) {
|
if (NegotiatedVideoFormat & VIDEO_FORMAT_MASK_H264) {
|
||||||
case AVC_NAL_TYPE_SPS:
|
switch (H264_NAL_TYPE(candidate.data[candidate.offset + candidate.length])) {
|
||||||
case HEVC_NAL_TYPE_SPS:
|
case H264_NAL_TYPE_SPS:
|
||||||
return BUFFER_TYPE_SPS;
|
return BUFFER_TYPE_SPS;
|
||||||
|
|
||||||
case AVC_NAL_TYPE_PPS:
|
case H264_NAL_TYPE_PPS:
|
||||||
case HEVC_NAL_TYPE_PPS:
|
|
||||||
return BUFFER_TYPE_PPS;
|
return BUFFER_TYPE_PPS;
|
||||||
|
|
||||||
case HEVC_NAL_TYPE_VPS:
|
|
||||||
return BUFFER_TYPE_VPS;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return BUFFER_TYPE_PICDATA;
|
return BUFFER_TYPE_PICDATA;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (NegotiatedVideoFormat & VIDEO_FORMAT_MASK_H265) {
|
||||||
|
switch (HEVC_NAL_TYPE(candidate.data[candidate.offset + candidate.length])) {
|
||||||
|
case HEVC_NAL_TYPE_SPS:
|
||||||
|
return BUFFER_TYPE_SPS;
|
||||||
|
|
||||||
|
case HEVC_NAL_TYPE_PPS:
|
||||||
|
return BUFFER_TYPE_PPS;
|
||||||
|
|
||||||
|
case HEVC_NAL_TYPE_VPS:
|
||||||
|
return BUFFER_TYPE_VPS;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return BUFFER_TYPE_PICDATA;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
LC_ASSERT(false);
|
||||||
|
return BUFFER_TYPE_PICDATA;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user