@@ -428,6 +428,14 @@ static void* resolveSurfaces(void *param) {
428
428
ctx -> surfaceQueueReadIdx = 0 ;
429
429
}
430
430
431
+ if (surface -> decodeFailed ) {
432
+ pthread_mutex_lock (& surface -> mutex );
433
+ surface -> resolving = 0 ;
434
+ pthread_cond_signal (& surface -> cond );
435
+ pthread_mutex_unlock (& surface -> mutex );
436
+ continue ;
437
+ }
438
+
431
439
CUdeviceptr deviceMemory = (CUdeviceptr ) NULL ;
432
440
unsigned int pitch = 0 ;
433
441
@@ -440,6 +448,10 @@ static void* resolveSurfaces(void *param) {
440
448
441
449
//LOG("Mapping surface %d", surface->pictureIdx);
442
450
if (CHECK_CUDA_RESULT (cv -> cuvidMapVideoFrame (ctx -> decoder , surface -> pictureIdx , & deviceMemory , & pitch , & procParams ))) {
451
+ pthread_mutex_lock (& surface -> mutex );
452
+ surface -> resolving = 0 ;
453
+ pthread_cond_signal (& surface -> cond );
454
+ pthread_mutex_unlock (& surface -> mutex );
443
455
continue ;
444
456
}
445
457
//LOG("Mapped surface %d to %p (%d)", surface->pictureIdx, (void*)deviceMemory, pitch);
@@ -1048,17 +1060,17 @@ static VAStatus nvCreateContext(
1048
1060
if (num_render_targets ) {
1049
1061
// Update the decoder configuration to match the passed in surfaces.
1050
1062
NVSurface * surface = (NVSurface * ) getObjectPtr (drv , render_targets [0 ]);
1063
+ if (!surface ) {
1064
+ return VA_STATUS_ERROR_INVALID_PARAMETER ;
1065
+ }
1051
1066
cfg -> surfaceFormat = surface -> format ;
1052
1067
cfg -> chromaFormat = surface -> chromaFormat ;
1053
1068
cfg -> bitDepth = surface -> bitDepth ;
1054
1069
}
1055
1070
1056
- if (drv -> surfaceCount <= 1 && num_render_targets == 0 ) {
1057
- LOG ("0/1 surfaces have been passed to vaCreateContext, this might cause errors. Setting surface count to 32" );
1058
- num_render_targets = 32 ;
1059
- }
1071
+ // Setting to maximun value if num_render_targets == 0 to prevent picture index overflow as additional surfaces can be created after calling nvCreateContext
1072
+ int surfaceCount = num_render_targets > 0 ? num_render_targets : 32 ;
1060
1073
1061
- int surfaceCount = drv -> surfaceCount > 1 ? drv -> surfaceCount : num_render_targets ;
1062
1074
if (surfaceCount > 32 ) {
1063
1075
LOG ("Application requested %d surface(s), limiting to 32. This may cause issues." , surfaceCount );
1064
1076
surfaceCount = 32 ;
@@ -1120,6 +1132,7 @@ static VAStatus nvCreateContext(
1120
1132
nvCtx -> width = picture_width ;
1121
1133
nvCtx -> height = picture_height ;
1122
1134
nvCtx -> codec = selectedCodec ;
1135
+ nvCtx -> surfaceCount = surfaceCount ;
1123
1136
1124
1137
pthread_mutexattr_t attrib ;
1125
1138
pthread_mutexattr_init (& attrib );
@@ -1297,6 +1310,9 @@ static VAStatus nvBeginPicture(
1297
1310
1298
1311
//if this surface hasn't been used before, give it a new picture index
1299
1312
if (surface -> pictureIdx == -1 ) {
1313
+ if (nvCtx -> currentPictureId == nvCtx -> surfaceCount ) {
1314
+ return VA_STATUS_ERROR_MAX_NUM_EXCEEDED ;
1315
+ }
1300
1316
surface -> pictureIdx = nvCtx -> currentPictureId ++ ;
1301
1317
}
1302
1318
@@ -1366,11 +1382,16 @@ static VAStatus nvEndPicture(
1366
1382
nvCtx -> bitstreamBuffer .size = 0 ;
1367
1383
nvCtx -> sliceOffsets .size = 0 ;
1368
1384
1385
+ CHECK_CUDA_RESULT_RETURN (cu -> cuCtxPushCurrent (drv -> cudaContext ), VA_STATUS_ERROR_OPERATION_FAILED );
1369
1386
CUresult result = cv -> cuvidDecodePicture (nvCtx -> decoder , picParams );
1387
+ CHECK_CUDA_RESULT_RETURN (cu -> cuCtxPopCurrent (NULL ), VA_STATUS_ERROR_OPERATION_FAILED );
1388
+
1389
+ VAStatus status = VA_STATUS_SUCCESS ;
1390
+
1370
1391
if (result != CUDA_SUCCESS )
1371
1392
{
1372
1393
LOG ("cuvidDecodePicture failed: %d" , result );
1373
- return VA_STATUS_ERROR_DECODING_ERROR ;
1394
+ status = VA_STATUS_ERROR_DECODING_ERROR ;
1374
1395
}
1375
1396
//LOG("Decoded frame successfully to idx: %d (%p)", picParams->CurrPicIdx, nvCtx->renderTarget);
1376
1397
@@ -1379,6 +1400,7 @@ static VAStatus nvEndPicture(
1379
1400
surface -> context = nvCtx ;
1380
1401
surface -> topFieldFirst = !picParams -> bottom_field_flag ;
1381
1402
surface -> secondField = picParams -> second_field ;
1403
+ surface -> decodeFailed = status != VA_STATUS_SUCCESS ;
1382
1404
1383
1405
//TODO check we're not overflowing the queue
1384
1406
pthread_mutex_lock (& nvCtx -> resolveMutex );
@@ -1391,7 +1413,7 @@ static VAStatus nvEndPicture(
1391
1413
//Wake up the resolve thread
1392
1414
pthread_cond_signal (& nvCtx -> resolveCondition );
1393
1415
1394
- return VA_STATUS_SUCCESS ;
1416
+ return status ;
1395
1417
}
1396
1418
1397
1419
static VAStatus nvSyncSurface (
0 commit comments