@@ -486,6 +486,14 @@ static void* getObjectPtr(NVDriver *drv, ObjectType type, VAGenericID id) {
486486 return NULL ;
487487}
488488
489+ NVSurface * nvGetSurface (NVDriver * drv , VASurfaceID id ) {
490+ return getObjectPtr (drv , OBJECT_TYPE_SURFACE , id );
491+ }
492+
493+ NVBuffer * nvGetBuffer (NVDriver * drv , VABufferID id ) {
494+ return getObjectPtr (drv , OBJECT_TYPE_BUFFER , id );
495+ }
496+
489497static Object getObjectByPtr (NVDriver * drv , ObjectType type , void * ptr ) {
490498 Object ret = NULL ;
491499 if (ptr != NULL ) {
@@ -500,7 +508,6 @@ static Object getObjectByPtr(NVDriver *drv, ObjectType type, void *ptr) {
500508 }
501509 return ret ;
502510}
503-
504511static void setSurfaceResolving (NVSurface * surface , bool resolving );
505512
506513// Requires drv->objectCreationMutex to be held by the caller.
@@ -1650,6 +1657,10 @@ static void setSurfaceResolving(NVSurface *surface, bool resolving) {
16501657 pthread_mutex_unlock (& surface -> mutex );
16511658}
16521659
1660+ void nvSetSurfaceResolving (NVSurface * surface , bool resolving ) {
1661+ setSurfaceResolving (surface , resolving );
1662+ }
1663+
16531664static void waitSurfaceResolved (NVSurface * surface ) {
16541665 if (surface == NULL ) {
16551666 return ;
@@ -1883,11 +1894,8 @@ static VAStatus nvDestroySurfaces(
18831894 ARRAY_FOR_EACH (Object , o , & drv -> objects )
18841895 if (o -> type == OBJECT_TYPE_CONTEXT ) {
18851896 NVContext * nvCtx = (NVContext * ) o -> obj ;
1886- if (nvCtx -> cudaCodec == cudaVideoCodec_VC1 && nvCtx -> vc1FieldPending &&
1887- nvCtx -> vc1FieldSurface == surface_list [i ]) {
1888- nvCtx -> vc1FieldPending = false;
1889- surface -> decodeFailed = true;
1890- setSurfaceResolving (surface , false);
1897+ if (nvCtx -> codec != NULL && nvCtx -> codec -> surfaceDestroyed != NULL ) {
1898+ nvCtx -> codec -> surfaceDestroyed (nvCtx , surface_list [i ], surface );
18911899 }
18921900 // nvEndPicture may wait on the most recently queued surface before
18931901 // resizing the decoder's display area; don't let it point at a
@@ -3120,29 +3128,6 @@ static bool copySurfaceBackingImage(NVDriver *drv, NVSurface *src, NVSurface *ds
31203128 return true;
31213129}
31223130
3123- static void cancelVC1FieldLocked (NVDriver * drv , NVContext * ctx ) {
3124- if (!ctx -> vc1FieldPending ) return ;
3125- NVSurface * surface = getObjectPtr (drv , OBJECT_TYPE_SURFACE , ctx -> vc1FieldSurface );
3126- if (surface != NULL ) {
3127- surface -> decodeFailed = true;
3128- setSurfaceResolving (surface , false);
3129- }
3130- ctx -> vc1FieldPending = false;
3131- }
3132-
3133- static void abortVC1Picture (NVDriver * drv , NVContext * ctx ) {
3134- pthread_mutex_lock (& drv -> objectCreationMutex );
3135- cancelVC1FieldLocked (drv , ctx );
3136- NVSurface * surface = getObjectPtr (drv , OBJECT_TYPE_SURFACE , ctx -> vc1RenderSurface );
3137- if (surface != NULL ) {
3138- surface -> decodeFailed = true;
3139- setSurfaceResolving (surface , false);
3140- }
3141- pthread_mutex_unlock (& drv -> objectCreationMutex );
3142- ctx -> bitstreamBuffer .size = 0 ;
3143- ctx -> sliceOffsets .size = 0 ;
3144- }
3145-
31463131static VAStatus nvBeginPicture (
31473132 VADriverContextP ctx ,
31483133 VAContextID context ,
@@ -3194,9 +3179,12 @@ static VAStatus nvBeginPicture(
31943179 pthread_mutex_unlock (& drv -> objectCreationMutex );
31953180 return VA_STATUS_ERROR_INVALID_CONTEXT ;
31963181 }
3197- if (nvCtx -> cudaCodec == cudaVideoCodec_VC1 && nvCtx -> vc1PictureActive ) {
3198- pthread_mutex_unlock (& drv -> objectCreationMutex );
3199- return VA_STATUS_ERROR_OPERATION_FAILED ;
3182+ if (nvCtx -> codec -> checkPicture != NULL ) {
3183+ VAStatus status = nvCtx -> codec -> checkPicture (nvCtx , NV_PICTURE_BEGIN );
3184+ if (status != VA_STATUS_SUCCESS ) {
3185+ pthread_mutex_unlock (& drv -> objectCreationMutex );
3186+ return status ;
3187+ }
32003188 }
32013189 nvCtx -> activeDecodeCalls ++ ;
32023190 pthread_mutex_unlock (& drv -> objectCreationMutex );
@@ -3235,14 +3223,13 @@ static VAStatus nvBeginPicture(
32353223 setSurfaceResolving (surface , true);
32363224
32373225 memset (& nvCtx -> pPicParams , 0 , sizeof (CUVIDPICPARAMS ));
3238- nvCtx -> vc1RenderSurface = render_target ;
32393226 nvCtx -> renderTarget = surface ;
32403227 nvCtx -> displayTarget = surface ;
32413228 nvCtx -> renderTarget -> progressiveFrame = true; //assume we're producing progressive frame unless the codec says otherwise
32423229 nvSurfaceResetColorMetadata (nvCtx -> renderTarget );
32433230 nvCtx -> pPicParams .CurrPicIdx = nvCtx -> renderTarget -> pictureIdx ;
32443231 if (nvCtx -> codec != NULL && nvCtx -> codec -> beginPicture != NULL ) {
3245- nvCtx -> codec -> beginPicture (nvCtx );
3232+ nvCtx -> codec -> beginPicture (nvCtx , render_target );
32463233 }
32473234
32483235 endDecodeCall (drv , nvCtx );
@@ -3320,46 +3307,39 @@ static VAStatus nvRenderPicture(
33203307 pthread_mutex_unlock (& drv -> objectCreationMutex );
33213308 return VA_STATUS_ERROR_INVALID_CONTEXT ;
33223309 }
3323- if (nvCtx -> cudaCodec == cudaVideoCodec_VC1 && !nvCtx -> vc1PictureActive ) {
3324- pthread_mutex_unlock (& drv -> objectCreationMutex );
3325- return VA_STATUS_ERROR_OPERATION_FAILED ;
3310+ if (nvCtx -> codec -> checkPicture != NULL ) {
3311+ VAStatus status = nvCtx -> codec -> checkPicture (nvCtx , NV_PICTURE_RENDER );
3312+ if (status != VA_STATUS_SUCCESS ) {
3313+ pthread_mutex_unlock (& drv -> objectCreationMutex );
3314+ return status ;
3315+ }
33263316 }
33273317 nvCtx -> activeDecodeCalls ++ ;
33283318 pthread_mutex_unlock (& drv -> objectCreationMutex );
33293319
33303320 CUVIDPICPARAMS * picParams = & nvCtx -> pPicParams ;
33313321
3332- if (nvCtx -> cudaCodec == cudaVideoCodec_VC1 &&
3333- (num_buffers < 0 || (num_buffers != 0 && buffers == NULL ))) {
3334- nvCtx -> vc1PictureStatus = VA_STATUS_ERROR_INVALID_PARAMETER ;
3322+ if (nvCtx -> codec -> renderPicture != NULL ) {
3323+ VAStatus status = nvCtx -> codec -> renderPicture (nvCtx , buffers , num_buffers );
3324+ endDecodeCall (drv , nvCtx );
3325+ return status ;
33353326 }
33363327 for (int i = 0 ; i < num_buffers ; i ++ ) {
3337- if (nvCtx -> cudaCodec == cudaVideoCodec_VC1 && nvCtx -> vc1PictureStatus != VA_STATUS_SUCCESS ) break ;
33383328 NVBuffer * buf = (NVBuffer * ) getObjectPtr (drv , OBJECT_TYPE_BUFFER , buffers [i ]);
33393329 if (buf == NULL || buf -> ptr == NULL || (unsigned int ) buf -> bufferType >= VABufferTypeMax ) {
3340- if (nvCtx -> cudaCodec == cudaVideoCodec_VC1 ) {
3341- nvCtx -> vc1PictureStatus = VA_STATUS_ERROR_INVALID_BUFFER ;
3342- break ;
3343- }
33443330 LOG ("Invalid buffer detected, skipping: %d" , buffers [i ]);
33453331 continue ;
33463332 }
33473333 HandlerFunc func = nvCtx -> codec -> handlers [buf -> bufferType ];
33483334 if (func != NULL ) {
33493335 func (nvCtx , buf , picParams );
33503336 } else {
3351- if (nvCtx -> cudaCodec == cudaVideoCodec_VC1 ) {
3352- nvCtx -> vc1PictureStatus = VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE ;
3353- break ;
3354- }
33553337 LOG ("Unhandled buffer type: %d" , buf -> bufferType );
33563338 }
33573339 }
33583340
3359- VAStatus status = nvCtx -> cudaCodec == cudaVideoCodec_VC1 ? nvCtx -> vc1PictureStatus : VA_STATUS_SUCCESS ;
3360- if (status != VA_STATUS_SUCCESS ) abortVC1Picture (drv , nvCtx );
33613341 endDecodeCall (drv , nvCtx );
3362- return status ;
3342+ return VA_STATUS_SUCCESS ;
33633343}
33643344
33653345/* Whether the decoder's display area differs from the size of the frame that
@@ -3436,31 +3416,21 @@ static VAStatus nvEndPicture(
34363416 pthread_mutex_unlock (& drv -> objectCreationMutex );
34373417 return VA_STATUS_ERROR_INVALID_CONTEXT ;
34383418 }
3439- if (nvCtx -> cudaCodec == cudaVideoCodec_VC1 && !nvCtx -> vc1PictureActive ) {
3440- pthread_mutex_unlock (& drv -> objectCreationMutex );
3441- return VA_STATUS_ERROR_OPERATION_FAILED ;
3419+ if (nvCtx -> codec -> checkPicture != NULL ) {
3420+ VAStatus status = nvCtx -> codec -> checkPicture (nvCtx , NV_PICTURE_END );
3421+ if (status != VA_STATUS_SUCCESS ) {
3422+ pthread_mutex_unlock (& drv -> objectCreationMutex );
3423+ return status ;
3424+ }
34423425 }
3443- if (nvCtx -> cudaCodec == cudaVideoCodec_VC1 ) nvCtx -> vc1PictureActive = false;
34443426 nvCtx -> activeDecodeCalls ++ ;
34453427 pthread_mutex_unlock (& drv -> objectCreationMutex );
34463428
34473429 CUVIDPICPARAMS * picParams = & nvCtx -> pPicParams ;
34483430
3449- if (nvCtx -> cudaCodec == cudaVideoCodec_VC1 ) {
3450- VAStatus status = nvCtx -> vc1PictureStatus ;
3451- if (status == VA_STATUS_SUCCESS && (!nvCtx -> vc1PictureParameters || picParams -> nNumSlices == 0 ||
3452- nvCtx -> lastSliceParamsCount != 0 )) status = VA_STATUS_ERROR_INVALID_BUFFER ;
3453- pthread_mutex_lock (& drv -> objectCreationMutex );
3454- if (status == VA_STATUS_SUCCESS && picParams -> field_pic_flag && picParams -> second_field ) {
3455- if (!nvCtx -> vc1FieldPending || nvCtx -> vc1FieldSurface != nvCtx -> vc1RenderSurface )
3456- status = VA_STATUS_ERROR_INVALID_PARAMETER ;
3457- } else {
3458- cancelVC1FieldLocked (drv , nvCtx );
3459- if (status == VA_STATUS_SUCCESS ) setSurfaceResolving (nvCtx -> renderTarget , true);
3460- }
3461- pthread_mutex_unlock (& drv -> objectCreationMutex );
3431+ if (nvCtx -> codec -> prepareDecode != NULL ) {
3432+ VAStatus status = nvCtx -> codec -> prepareDecode (nvCtx );
34623433 if (status != VA_STATUS_SUCCESS ) {
3463- abortVC1Picture (drv , nvCtx );
34643434 endDecodeCall (drv , nvCtx );
34653435 return status ;
34663436 }
@@ -3472,7 +3442,7 @@ static VAStatus nvEndPicture(
34723442 nvCtx -> sliceOffsets .size = 0 ;
34733443
34743444 if (CHECK_CUDA_RESULT (cu -> cuCtxPushCurrent (drv -> cudaContext ))) {
3475- if (nvCtx -> cudaCodec == cudaVideoCodec_VC1 ) abortVC1Picture ( drv , nvCtx );
3445+ if (nvCtx -> codec -> abortPicture != NULL ) nvCtx -> codec -> abortPicture ( nvCtx );
34763446 endDecodeCall (drv , nvCtx );
34773447 return VA_STATUS_ERROR_OPERATION_FAILED ;
34783448 }
@@ -3492,7 +3462,7 @@ static VAStatus nvEndPicture(
34923462 nvCtx -> decoderHasDecoded = true;
34933463 }
34943464 if (CHECK_CUDA_RESULT (cu -> cuCtxPopCurrent (NULL ))) {
3495- if (nvCtx -> cudaCodec == cudaVideoCodec_VC1 ) abortVC1Picture ( drv , nvCtx );
3465+ if (nvCtx -> codec -> abortPicture != NULL ) nvCtx -> codec -> abortPicture ( nvCtx );
34963466 endDecodeCall (drv , nvCtx );
34973467 return VA_STATUS_ERROR_OPERATION_FAILED ;
34983468 }
@@ -3506,28 +3476,13 @@ static VAStatus nvEndPicture(
35063476 }
35073477 //LOG("Decoded frame successfully to idx: %d (%p)", picParams->CurrPicIdx, nvCtx->renderTarget);
35083478
3509- // A VC-1 field picture is not displayable until its second field finishes.
3510- // Queueing the first field lets the resolver publish the shared surface too early.
3511- if (nvCtx -> profile == VAProfileVC1Advanced &&
3512- picParams -> field_pic_flag && !picParams -> second_field ) {
3513- if (status != VA_STATUS_SUCCESS ) {
3514- abortVC1Picture (drv , nvCtx );
3515- } else {
3516- pthread_mutex_lock (& drv -> objectCreationMutex );
3517- nvCtx -> vc1FieldPending = true;
3518- nvCtx -> vc1FieldSurface = nvCtx -> vc1RenderSurface ;
3519- pthread_mutex_unlock (& drv -> objectCreationMutex );
3520- }
3479+ // Codecs can defer publication until a complete output picture is available.
3480+ NVSurface * surface = nvCtx -> displayTarget != NULL ? nvCtx -> displayTarget : nvCtx -> renderTarget ;
3481+ surface -> topFieldFirst = !picParams -> bottom_field_flag ;
3482+ if (nvCtx -> codec -> finishDecode != NULL && !nvCtx -> codec -> finishDecode (nvCtx , status )) {
35213483 endDecodeCall (drv , nvCtx );
35223484 return status ;
35233485 }
3524-
3525- if (nvCtx -> cudaCodec == cudaVideoCodec_VC1 ) {
3526- pthread_mutex_lock (& drv -> objectCreationMutex );
3527- nvCtx -> vc1FieldPending = false;
3528- pthread_mutex_unlock (& drv -> objectCreationMutex );
3529- }
3530- NVSurface * surface = nvCtx -> displayTarget != NULL ? nvCtx -> displayTarget : nvCtx -> renderTarget ;
35313486 if (surface != nvCtx -> renderTarget ) {
35323487 setSurfaceResolving (surface , true);
35333488 setSurfaceResolving (nvCtx -> renderTarget , false);
@@ -3538,8 +3493,6 @@ static VAStatus nvEndPicture(
35383493 pthread_mutex_lock (& drv -> objectCreationMutex );
35393494 surface -> contextId = context ;
35403495 pthread_mutex_unlock (& drv -> objectCreationMutex );
3541- if (nvCtx -> cudaCodec != cudaVideoCodec_VC1 )
3542- surface -> topFieldFirst = !picParams -> bottom_field_flag ;
35433496 surface -> secondField = picParams -> second_field ;
35443497 surface -> decodeFailed = status != VA_STATUS_SUCCESS ;
35453498
0 commit comments