Update for video decoder API changes

This commit is contained in:
Cameron Gutman
2017-11-18 18:17:22 -08:00
parent 20a61dd9f4
commit 4b9bd8398b
4 changed files with 38 additions and 45 deletions
+16 -4
View File
@@ -55,6 +55,7 @@ int DrDecoderSetup(int videoFormat, int width, int height, int redrawRate, void*
int DrSubmitDecodeUnit(PDECODE_UNIT decodeUnit) int DrSubmitDecodeUnit(PDECODE_UNIT decodeUnit)
{ {
int offset = 0; int offset = 0;
int ret;
unsigned char* data = (unsigned char*) malloc(decodeUnit->fullLength); unsigned char* data = (unsigned char*) malloc(decodeUnit->fullLength);
if (data == NULL) { if (data == NULL) {
// A frame was lost due to OOM condition // A frame was lost due to OOM condition
@@ -63,13 +64,24 @@ int DrSubmitDecodeUnit(PDECODE_UNIT decodeUnit)
PLENTRY entry = decodeUnit->bufferList; PLENTRY entry = decodeUnit->bufferList;
while (entry != NULL) { while (entry != NULL) {
memcpy(&data[offset], entry->data, entry->length); // Submit parameter set NALUs directly since no copy is required by the decoder
offset += entry->length; if (entry->bufferType != BUFFER_TYPE_PICDATA) {
ret = [renderer submitDecodeBuffer:(unsigned char*)entry->data length:entry->length bufferType:entry->bufferType];
if (ret != DR_OK) {
free(data);
return ret;
}
}
else {
memcpy(&data[offset], entry->data, entry->length);
offset += entry->length;
}
entry = entry->next; entry = entry->next;
} }
// This function will take our buffer // This function will take our picture data buffer
return [renderer submitDecodeBuffer:data length:decodeUnit->fullLength]; return [renderer submitDecodeBuffer:data length:offset bufferType:BUFFER_TYPE_PICDATA];
} }
int ArInit(int audioConfiguration, POPUS_MULTISTREAM_CONFIGURATION opusConfig, void* context, int flags) int ArInit(int audioConfiguration, POPUS_MULTISTREAM_CONFIGURATION opusConfig, void* context, int flags)
+1 -1
View File
@@ -18,6 +18,6 @@
- (void)updateBufferForRange:(CMBlockBufferRef)existingBuffer data:(unsigned char *)data offset:(int)offset length:(int)nalLength; - (void)updateBufferForRange:(CMBlockBufferRef)existingBuffer data:(unsigned char *)data offset:(int)offset length:(int)nalLength;
- (int)submitDecodeBuffer:(unsigned char *)data length:(int)length; - (int)submitDecodeBuffer:(unsigned char *)data length:(int)length bufferType:(int)bufferType;
@end @end
+20 -39
View File
@@ -72,15 +72,6 @@
#define FRAME_START_PREFIX_SIZE 4 #define FRAME_START_PREFIX_SIZE 4
#define NALU_START_PREFIX_SIZE 3 #define NALU_START_PREFIX_SIZE 3
#define NAL_LENGTH_PREFIX_SIZE 4 #define NAL_LENGTH_PREFIX_SIZE 4
#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
#define IS_NAL_SPS(x) ((videoFormat == VIDEO_FORMAT_H264) ? ((x) == AVC_NAL_TYPE_SPS) : ((x) == HEVC_NAL_TYPE_SPS))
#define IS_NAL_PPS(x) ((videoFormat == VIDEO_FORMAT_H264) ? ((x) == AVC_NAL_TYPE_PPS) : ((x) == HEVC_NAL_TYPE_PPS))
#define IS_NAL_VPS(x) ((videoFormat == VIDEO_FORMAT_H265) && ((x) == HEVC_NAL_TYPE_VPS))
- (Boolean)readyForPictureData - (Boolean)readyForPictureData
{ {
@@ -114,16 +105,6 @@
} }
} }
- (Boolean)isNalPictureData:(unsigned char)nalType
{
if (videoFormat == VIDEO_FORMAT_H264) {
return !(nalType == AVC_NAL_TYPE_SPS || nalType == AVC_NAL_TYPE_PPS);
}
else {
return !(nalType == HEVC_NAL_TYPE_VPS || nalType == HEVC_NAL_TYPE_SPS || nalType == HEVC_NAL_TYPE_PPS);
}
}
- (void)updateBufferForRange:(CMBlockBufferRef)existingBuffer data:(unsigned char *)data offset:(int)offset length:(int)nalLength - (void)updateBufferForRange:(CMBlockBufferRef)existingBuffer data:(unsigned char *)data offset:(int)offset length:(int)nalLength
{ {
OSStatus status; OSStatus status;
@@ -190,25 +171,14 @@
} }
} }
// This function must free data // This function must free data for bufferType == BUFFER_TYPE_PICDATA
- (int)submitDecodeBuffer:(unsigned char *)data length:(int)length - (int)submitDecodeBuffer:(unsigned char *)data length:(int)length bufferType:(int)bufferType
{ {
unsigned char nalType = data[FRAME_START_PREFIX_SIZE]; unsigned char nalType = data[FRAME_START_PREFIX_SIZE];
OSStatus status; OSStatus status;
// Check for previous decoder errors before doing anything if (bufferType != BUFFER_TYPE_PICDATA) {
if (displayLayer.status == AVQueuedSampleBufferRenderingStatusFailed) { if (bufferType == BUFFER_TYPE_VPS) {
Log(LOG_E, @"Display layer rendering failed: %@", displayLayer.error);
// Recreate the display layer
[self reinitializeDisplayLayer];
// Request an IDR frame to initialize the new decoder
return DR_NEED_IDR;
}
if (![self isNalPictureData:nalType]) {
if (IS_NAL_VPS(nalType)) {
Log(LOG_I, @"Got VPS"); Log(LOG_I, @"Got VPS");
vpsData = [NSData dataWithBytes:&data[FRAME_START_PREFIX_SIZE] length:length - FRAME_START_PREFIX_SIZE]; vpsData = [NSData dataWithBytes:&data[FRAME_START_PREFIX_SIZE] length:length - FRAME_START_PREFIX_SIZE];
waitingForVps = false; waitingForVps = false;
@@ -216,14 +186,14 @@
// We got a new VPS so wait for a new SPS to match it // We got a new VPS so wait for a new SPS to match it
waitingForSps = true; waitingForSps = true;
} }
else if (IS_NAL_SPS(nalType)) { else if (bufferType == BUFFER_TYPE_SPS) {
Log(LOG_I, @"Got SPS"); Log(LOG_I, @"Got SPS");
spsData = [NSData dataWithBytes:&data[FRAME_START_PREFIX_SIZE] length:length - FRAME_START_PREFIX_SIZE]; spsData = [NSData dataWithBytes:&data[FRAME_START_PREFIX_SIZE] length:length - FRAME_START_PREFIX_SIZE];
waitingForSps = false; waitingForSps = false;
// We got a new SPS so wait for a new PPS to match it // We got a new SPS so wait for a new PPS to match it
waitingForPps = true; waitingForPps = true;
} else if (IS_NAL_PPS(nalType)) { } else if (bufferType == BUFFER_TYPE_PPS) {
Log(LOG_I, @"Got PPS"); Log(LOG_I, @"Got PPS");
ppsData = [NSData dataWithBytes:&data[FRAME_START_PREFIX_SIZE] length:length - FRAME_START_PREFIX_SIZE]; ppsData = [NSData dataWithBytes:&data[FRAME_START_PREFIX_SIZE] length:length - FRAME_START_PREFIX_SIZE];
waitingForPps = false; waitingForPps = false;
@@ -273,8 +243,7 @@
} }
} }
// Free the data buffer // Data is NOT to be freed here. It's a direct usage of the caller's buffer.
free(data);
// No frame data to submit for these NALUs // No frame data to submit for these NALUs
return DR_OK; return DR_OK;
@@ -283,7 +252,19 @@
if (formatDesc == NULL) { if (formatDesc == NULL) {
// Can't decode if we haven't gotten our parameter sets yet // Can't decode if we haven't gotten our parameter sets yet
free(data); free(data);
return DR_OK; return DR_NEED_IDR;
}
// Check for previous decoder errors before doing anything
if (displayLayer.status == AVQueuedSampleBufferRenderingStatusFailed) {
Log(LOG_E, @"Display layer rendering failed: %@", displayLayer.error);
// Recreate the display layer
[self reinitializeDisplayLayer];
// Request an IDR frame to initialize the new decoder
free(data);
return DR_NEED_IDR;
} }
// Now we're decoding actual frame data here // Now we're decoding actual frame data here